From 1a6dc56f1a67cda40da759abc1999022ec523f50 Mon Sep 17 00:00:00 2001 From: Markus Teich Date: Tue, 28 Jun 2016 17:24:59 +0200 Subject: [PATCH] add outcome decryption plus test --- crypto.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++- crypto.h | 7 ++++ test_crypto.c | 33 ++++++++++++++- 3 files changed, 147 insertions(+), 3 deletions(-) diff --git a/crypto.c b/crypto.c index bdc5842..f46c5df 100644 --- a/crypto.c +++ b/crypto.c @@ -820,7 +820,7 @@ smc_compute_outcome (struct AuctionData *ad, size_t *buflen) brandt_assert (ad && buflen); - *buflen = (ad->n * ad->k * /* nk * (gamma, delta, proof2) */ + *buflen = (ad->n * ad->k * /* nk * (gamma, delta, proof2) */ (sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2))); if (NULL == (cur = (ret = calloc (1, *buflen))) || NULL == (ad->gamma = smc_init3 (ad->n, ad->n, ad->k)) || @@ -963,7 +963,7 @@ smc_recv_outcome (struct AuctionData *ad, if (buflen != (ad->n * ad->k * (2 * sizeof (struct ec_mpi) + sizeof (*proof2)))) { - weprintf ("wrong size of received encrypted bid"); + weprintf ("wrong size of received outcome"); goto quit; } @@ -997,6 +997,112 @@ quit: } +/** + * smc_decrypt_outcome \todo + * + * @param ad TODO + * @param buflen TODO + */ +unsigned char * +smc_decrypt_outcome (struct AuctionData *ad, size_t *buflen) +{ + unsigned char *ret; + unsigned char *cur; + gcry_mpi_point_t tmp = gcry_mpi_point_new (0); + struct ec_mpi *phi; + struct proof_2dle *proof2; + + brandt_assert (ad && buflen); + + *buflen = (ad->n * ad->k * (sizeof (*phi) + sizeof (*proof2))); + if (NULL == (cur = (ret = calloc (1, *buflen))) || + NULL == (ad->phi = smc_init3 (ad->n, ad->n, ad->k))) + { + weprintf ("unable to alloc memory for first price outcome decryption"); + return NULL; + } + + for (uint16_t i = 0; i < ad->n; i++) + { + for (uint16_t j = 0; j < ad->k; j++) + { + phi = (struct ec_mpi *)cur; + proof2 = (struct proof_2dle *)(cur + sizeof (*phi)); + + smc_sum (tmp, &ad->delta[0][i][j], ad->n, 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++) + /**\todo: how to copy a point more efficiently? */ + gcry_mpi_ec_add (ad->phi[a][i][j], ec_zero, tmp, ec_ctx); + + /* decrypt outcome component and prove the correct key was used */ + smc_zkp_2dle (ad->phi[ad->i][i][j], + NULL, + tmp, + ec_gen, + ad->x, + proof2); + + ec_point_serialize (phi, ad->phi[ad->i][i][j]); + + cur += sizeof (*phi) + sizeof (*proof2); + } + } + + gcry_mpi_point_release (tmp); + return ret; +} + + +int +smc_recv_decryption (struct AuctionData *ad, + unsigned char *buf, + size_t buflen, + uint16_t sender) +{ + int ret = 0; + unsigned char *cur = buf; + struct proof_2dle *proof2; + gcry_mpi_point_t phi = gcry_mpi_point_new (0); + + brandt_assert (ad && buf); + + if (buflen != (ad->n * ad->k * (sizeof (struct ec_mpi) + sizeof (*proof2)))) + { + weprintf ("wrong size of received outcome decryption"); + goto quit; + } + + for (uint16_t i = 0; i < ad->n; i++) + { + for (uint16_t j = 0; j < ad->k; j++) + { + ec_point_parse (phi, (struct ec_mpi *)cur); + proof2 = (struct proof_2dle *)(cur + sizeof (struct ec_mpi)); + if (smc_zkp_2dle_check (phi, + ad->y[sender], + ad->phi[sender][i][j], + ec_gen, + proof2)) + { + weprintf ("wrong zkp2 for phi, y received"); + goto quit; + } + gcry_mpi_ec_add (ad->phi[sender][i][j], phi, ec_zero, ec_ctx); + cur += sizeof (struct ec_mpi) + sizeof (*proof2); + } + } + + ret = 1; +quit: + gcry_mpi_point_release (phi); + return ret; +} + + /** * smc_zkp_dl creates a proof of knowledge of @a x with \f$v = xg\f$ where * \f$g\f$ is the base point on Ed25519. diff --git a/crypto.h b/crypto.h index 4e93e03..cb1daea 100644 --- a/crypto.h +++ b/crypto.h @@ -128,4 +128,11 @@ int smc_recv_outcome (struct AuctionData *ad, unsigned char *buf, size_t buflen, uint16_t sender); + +unsigned char *smc_decrypt_outcome (struct AuctionData *ad, size_t *buflen); +int smc_recv_decryption (struct AuctionData *ad, + unsigned char *buf, + size_t buflen, + uint16_t sender); + #endif /* ifndef _BRANDT_CRYPTO_H */ diff --git a/test_crypto.c b/test_crypto.c index 52db0f3..7f6430e 100644 --- a/test_crypto.c +++ b/test_crypto.c @@ -267,7 +267,7 @@ test_round2 () for (i = 0; i < bidders; i++) { bufs[i] = smc_compute_outcome (&ad[i], &lens[i]); - check (bufs[i], "failed to encrypt bid"); + check (bufs[i], "failed to compute outcome"); } for (i = 0; i < bidders; i++) @@ -287,6 +287,36 @@ test_round2 () } +int +test_round3 () +{ + uint16_t i, s; + unsigned char *bufs[bidders]; + size_t lens[bidders]; + + for (i = 0; i < bidders; i++) + { + bufs[i] = smc_decrypt_outcome (&ad[i], &lens[i]); + check (bufs[i], "failed to decrypt outcome"); + } + + for (i = 0; i < bidders; i++) + { + for (s = 0; s < bidders; s++) + { + if (s == i) + continue; + check (smc_recv_decryption (&ad[i], bufs[s], lens[s], s), + "failed checking decrypted outcome"); + } + } + + for (i = 0; i < bidders; i++) + free (bufs[i]); + return 1; +} + + void cleanup_auction_data () { @@ -330,6 +360,7 @@ main (int argc, char *argv[]) run (test_prologue); run (test_round1); run (test_round2); + run (test_round3); cleanup_auction_data (); }