aboutsummaryrefslogtreecommitdiff
path: root/crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto.c')
-rw-r--r--crypto.c280
1 files changed, 179 insertions, 101 deletions
diff --git a/crypto.c b/crypto.c
index 965f9cc..afa72d4 100644
--- a/crypto.c
+++ b/crypto.c
@@ -609,6 +609,14 @@ smc_sum (gcry_mpi_point_t out,
}
+void
+smc_prep_keyshare (struct BRANDT_Auction *ad)
+{
+ ad->y = smc_init1 (ad->n);
+ brandt_assert (ad->y);
+}
+
+
/**
* smc_gen_keyshare creates the private keyshare and computes the
* public key share
@@ -622,20 +630,15 @@ unsigned char *
smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen)
{
unsigned char *ret;
- struct proof_dl *proof1;
struct msg_head *head;
struct ec_mpi *pubkey_share;
+ struct proof_dl *proof1;
brandt_assert (ad && buflen);
*buflen = (sizeof (*head) +
sizeof (*pubkey_share) +
sizeof (*proof1));
ret = GNUNET_new_array (*buflen, unsigned char);
- if (NULL == (ad->y = smc_init1 (ad->n)))
- {
- weprintf ("unable to alloc memory for key shares");
- return NULL;
- }
head = (struct msg_head *)ret;
head->prot_version = htonl (0);
@@ -688,6 +691,22 @@ quit:
}
+void
+smc_prep_bid (struct BRANDT_Auction *ad)
+{
+ ad->alpha = smc_init2 (ad->n, ad->k);
+ brandt_assert (ad->alpha);
+
+ ad->beta = smc_init2 (ad->n, ad->k);
+ brandt_assert (ad->beta);
+
+ ad->Y = gcry_mpi_point_new (0);
+ brandt_assert (ad->Y);
+ smc_sum (ad->Y, ad->y, ad->n, 1);
+ brandt_assert (ad->Y);
+}
+
+
/**
* smc_encrypt_bid encrypts the own bid with the shared public key and packs it
* into a message together with proofs of correctnes.
@@ -702,33 +721,24 @@ smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen)
{
unsigned char *ret;
unsigned char *cur;
- struct proof_0og *proof3;
struct msg_head *head;
+ struct proof_0og *proof3;
gcry_mpi_t r_sum;
gcry_mpi_t r_part;
brandt_assert (ad && buflen);
*buflen = (sizeof (*head) + /* msg header */
ad->k * /* k * (alpha, beta, proof3) */
- (sizeof (struct ec_mpi) * 2 + /* alpha, beta */
+ (sizeof (struct ec_mpi) * 2 +
sizeof (*proof3)) +
- sizeof (struct proof_2dle));
+ sizeof (struct proof_2dle)); /* proof2 */
ret = GNUNET_new_array (*buflen, unsigned char);
- if (NULL == (ad->alpha = smc_init2 (ad->n, ad->k)) ||
- NULL == (ad->beta = smc_init2 (ad->n, ad->k)))
- {
- weprintf ("unable to alloc memory for encrypted bids");
- return NULL;
- }
head = (struct msg_head *)ret;
head->prot_version = htonl (0);
head->msg_type = htonl (msg_bid);
cur = ret + sizeof (*head);
- ad->Y = gcry_mpi_point_new (0);
- smc_sum (ad->Y, ad->y, ad->n, 1);
-
r_sum = gcry_mpi_new (256);
r_part = gcry_mpi_new (256);
@@ -822,52 +832,27 @@ quit:
}
-/**
- * fp_pub_compute_outcome computes the outcome for first price auctions with a
- * public outcome and packs it into a message buffer together with proofs of
- * correctnes.
- *
- * @param[in] ad Pointer to the BRANDT_Auction struct to operate on
- * @param[out] buflen Size of the returned message buffer in bytes
- * @return A buffer containing the encrypted outcome vectors
- * which needs to be broadcast
- */
-unsigned char *
-fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
+void
+fp_pub_prep_outcome (struct BRANDT_Auction *ad)
{
- unsigned char *ret;
- unsigned char *cur;
- struct msg_head *head;
gcry_mpi_t coeff = gcry_mpi_copy (GCRYMPI_CONST_ONE);
gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
gcry_mpi_point_t *tlta1;
gcry_mpi_point_t *tltb1;
gcry_mpi_point_t **tlta2;
gcry_mpi_point_t **tltb2;
- struct ec_mpi *gamma;
- struct ec_mpi *delta;
- struct proof_2dle *proof2;
- brandt_assert (ad && buflen);
+ ad->gamma2 = smc_init2 (ad->n, ad->k);
+ brandt_assert (ad->gamma2);
- *buflen = (sizeof (*head) +
- ad->k * (sizeof (*gamma) +
- sizeof (*delta) +
- sizeof (*proof2)));
- ret = GNUNET_new_array (*buflen, unsigned char);
- if (NULL == (ad->gamma2 = smc_init2 (ad->n, ad->k)) ||
- NULL == (ad->delta2 = smc_init2 (ad->n, ad->k)) ||
- NULL == (ad->tmpa1 = smc_init1 (ad->k)) ||
- NULL == (ad->tmpb1 = smc_init1 (ad->k)))
- {
- weprintf ("unable to alloc memory for first price outcome computation");
- return NULL;
- }
+ ad->delta2 = smc_init2 (ad->n, ad->k);
+ brandt_assert (ad->delta2);
- head = (struct msg_head *)ret;
- head->prot_version = htonl (0);
- head->msg_type = htonl (msg_outcome);
- cur = ret + sizeof (*head);
+ ad->tmpa1 = smc_init1 (ad->k);
+ brandt_assert (ad->tmpa1);
+
+ ad->tmpb1 = smc_init1 (ad->k);
+ brandt_assert (ad->tmpb1);
/* create temporary lookup tables with partial sums */
tlta1 = smc_init1 (ad->k);
@@ -927,10 +912,6 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
for (uint16_t j = 0; j < ad->k; j++)
{
- gamma = (struct ec_mpi *)cur;
- delta = &((struct ec_mpi *)cur)[1];
- proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi));
-
/* copy unmasked outcome to all other bidder layers so they don't
* have to be recomputed to check the ZK proof_2dle's from other
* bidders when receiving their outcome messages */
@@ -939,12 +920,64 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
ec_point_copy (ad->gamma2[a][j], tlta1[j]);
ec_point_copy (ad->delta2[a][j], tltb1[j]);
}
+ }
+
+ gcry_mpi_release (coeff);
+ gcry_mpi_point_release (tmp);
+ smc_free1 (tlta1, ad->k);
+ smc_free1 (tltb1, ad->k);
+}
+
+
+/**
+ * fp_pub_compute_outcome computes the outcome for first price auctions with a
+ * public outcome and packs it into a message buffer together with proofs of
+ * correctnes.
+ *
+ * @param[in] ad Pointer to the BRANDT_Auction struct to operate on
+ * @param[out] buflen Size of the returned message buffer in bytes
+ * @return A buffer containing the encrypted outcome vectors
+ * which needs to be broadcast
+ */
+unsigned char *
+fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
+{
+ unsigned char *ret;
+ unsigned char *cur;
+ gcry_mpi_point_t tmpa = gcry_mpi_point_new (0);
+ gcry_mpi_point_t tmpb = gcry_mpi_point_new (0);
+ struct msg_head *head;
+ struct ec_mpi *gamma;
+ struct ec_mpi *delta;
+ struct proof_2dle *proof2;
+
+ brandt_assert (ad && buflen);
+
+ *buflen = (sizeof (*head) +
+ ad->k * (sizeof (*gamma) +
+ sizeof (*delta) +
+ sizeof (*proof2)));
+ ret = GNUNET_new_array (*buflen, unsigned char);
+
+ head = (struct msg_head *)ret;
+ head->prot_version = htonl (0);
+ head->msg_type = htonl (msg_outcome);
+ cur = ret + sizeof (*head);
+
+ for (uint16_t j = 0; j < ad->k; j++)
+ {
+ gamma = (struct ec_mpi *)cur;
+ delta = &((struct ec_mpi *)cur)[1];
+ proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi));
+
+ ec_point_copy (tmpa, ad->gamma2[ad->i][j]);
+ ec_point_copy (tmpb, ad->delta2[ad->i][j]);
/* apply random masking for losing bidders */
smc_zkp_2dle (ad->gamma2[ad->i][j],
ad->delta2[ad->i][j],
- tlta1[j],
- tltb1[j],
+ tmpa,
+ tmpb,
NULL,
proof2);
@@ -964,10 +997,8 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2);
}
- gcry_mpi_release (coeff);
- gcry_mpi_point_release (tmp);
- smc_free1 (tlta1, ad->k);
- smc_free1 (tltb1, ad->k);
+ gcry_mpi_point_release (tmpa);
+ gcry_mpi_point_release (tmpb);
return ret;
}
@@ -1030,6 +1061,29 @@ quit:
}
+void
+fp_pub_prep_decryption (struct BRANDT_Auction *ad)
+{
+ gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
+
+ ad->phi2 = smc_init2 (ad->n, ad->k);
+ brandt_assert (ad->phi2);
+
+ for (uint16_t j = 0; j < ad->k; j++)
+ {
+ smc_sum (tmp, &ad->delta2[0][j], ad->n, ad->k);
+
+ /* copy still encrypted outcome to all other bidder layers so they
+ * don't have to be recomputed to check the ZK proof_2dle's from
+ * other bidders when receiving their outcome decryption messages */
+ for (uint16_t a = 0; a < ad->n; a++)
+ ec_point_copy (ad->phi2[a][j], tmp);
+ }
+
+ gcry_mpi_point_release (tmp);
+}
+
+
/**
* fp_pub_decrypt_outcome decrypts part of the outcome and packs it into a
* message buffer together with proofs of correctnes.
@@ -1044,8 +1098,8 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen)
{
unsigned char *ret;
unsigned char *cur;
- struct msg_head *head;
gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
+ struct msg_head *head;
struct ec_mpi *phi;
struct proof_2dle *proof2;
@@ -1053,11 +1107,6 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen)
*buflen = (sizeof (*head) + ad->k * (sizeof (*phi) + sizeof (*proof2)));
ret = GNUNET_new_array (*buflen, unsigned char);
- if (NULL == (ad->phi2 = smc_init2 (ad->n, ad->k)))
- {
- weprintf ("unable to alloc memory for first price outcome decryption");
- return NULL;
- }
head = (struct msg_head *)ret;
head->prot_version = htonl (0);
@@ -1069,13 +1118,7 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen)
phi = (struct ec_mpi *)cur;
proof2 = (struct proof_2dle *)(cur + sizeof (*phi));
- smc_sum (tmp, &ad->delta2[0][j], ad->n, ad->k);
-
- /* copy still encrypted outcome to all other bidder layers so they
- * don't have to be recomputed to check the ZK proof_2dle's from
- * other bidders when receiving their outcome decryption messages */
- for (uint16_t a = 0; a < ad->n; a++)
- ec_point_copy (ad->phi2[a][j], tmp);
+ ec_point_copy (tmp, ad->phi2[ad->i][j]);
/* decrypt outcome component and prove the correct key was used */
smc_zkp_2dle (ad->phi2[ad->i][j],
@@ -1138,12 +1181,13 @@ quit:
}
-int32_t
-fp_pub_determine_outcome (struct BRANDT_Auction *ad, uint16_t *winner)
+struct BRANDT_Result *fp_pub_determine_outcome (struct BRANDT_Auction *ad,
+ uint16_t *len)
{
- int32_t ret = -1;
+ struct BRANDT_Result *ret;
+ int32_t price = -1;
+ int32_t winner = -1;
int dlogi = -1;
- gcry_mpi_t dlog = gcry_mpi_new (256);
gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0);
gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0);
@@ -1157,28 +1201,38 @@ fp_pub_determine_outcome (struct BRANDT_Auction *ad, uint16_t *winner)
/* first non-zero component determines the price */
if (ec_point_cmp (sum_gamma, ec_zero))
{
- ret = j;
+ price = j;
break;
}
}
dlogi = GNUNET_CRYPTO_ecc_dlog (ec_dlogctx, sum_gamma);
brandt_assert (dlogi > 0);
- gcry_mpi_set_ui (dlog, (unsigned long)dlogi);
+ /* can only support up to bits(dlogi) bidders */
+ brandt_assert (sizeof (int) * 8 - 1 >= ad->n);
for (uint16_t i = 0; i < ad->n; i++)
{
- if (gcry_mpi_test_bit (dlog, i))
+ /* first set bit determines the winner */
+ if (dlogi & (1 << i))
{
- if (winner)
- *winner = i;
+ winner = i;
break;
}
}
- gcry_mpi_release (dlog);
gcry_mpi_point_release (sum_gamma);
gcry_mpi_point_release (sum_phi);
+
+ if (-1 == winner || -1 == price)
+ return NULL;
+
+ ret = GNUNET_new(struct BRANDT_Result);
+ ret->bidder = winner;
+ ret->price = price;
+ ret->status = BRANDT_bidder_won;
+ if (len)
+ *len = 1;
return ret;
}
@@ -1509,33 +1563,57 @@ quit:
}
-int32_t
-fp_priv_determine_outcome (struct BRANDT_Auction *ad)
+struct BRANDT_Result *fp_priv_determine_outcome (struct BRANDT_Auction *ad,
+ uint16_t *len)
{
- int32_t ret = -1;
- gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0);
- gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0);
+ struct BRANDT_Result *ret;
+ int32_t price = -1;
+ int32_t winner = -1;
+ gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0);
+ gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0);
brandt_assert (ad);
- for (uint16_t j = 0; j < ad->k; j++)
+ for (uint16_t i = 0; i < ad->n; i++)
{
- smc_sum (sum_gamma, &ad->gamma3[0][ad->i][j], ad->n, ad->n * ad->k);
- smc_sum (sum_phi, &ad->phi3[0][ad->i][j], ad->n, ad->n * ad->k);
- gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx);
- if (!ec_point_cmp (sum_gamma, ec_zero))
+ if (!ad->seller_mode && i != ad->i)
+ continue;
+
+ for (uint16_t j = 0; j < ad->k; j++)
{
- if (-1 != ret)
+ smc_sum (sum_gamma, &ad->gamma3[0][i][j], ad->n, ad->n * ad->k);
+ smc_sum (sum_phi, &ad->phi3[0][i][j], ad->n, ad->n * ad->k);
+ gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx);
+ if (!ec_point_cmp (sum_gamma, ec_zero))
{
- weprintf ("multiple winning prices detected");
- return -1;
+ if (-1 != price)
+ {
+ weprintf ("multiple winning prices detected");
+ return NULL;
+ }
+ if (-1 != winner)
+ {
+ weprintf ("multiple winners detected");
+ return NULL;
+ }
+ price = j;
+ winner = i;
}
- ret = j;
}
}
gcry_mpi_point_release (sum_gamma);
gcry_mpi_point_release (sum_phi);
+
+ if (-1 == winner || -1 == price)
+ return NULL;
+
+ ret = GNUNET_new(struct BRANDT_Result);
+ ret->bidder = winner;
+ ret->price = price;
+ ret->status = BRANDT_bidder_won;
+ if (len)
+ *len = 1;
return ret;
}