diff options
Diffstat (limited to 'crypto.c')
-rw-r--r-- | crypto.c | 280 |
1 files changed, 179 insertions, 101 deletions
@@ -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; } |