diff --git a/crypto.c b/crypto.c index f46c5df..099d3dd 100644 --- a/crypto.c +++ b/crypto.c @@ -594,7 +594,7 @@ smc_sum (gcry_mpi_point_t out, brandt_assert (NULL != out); /**\todo: how to copy a point more efficiently? */ gcry_mpi_ec_add (out, ec_zero, ec_zero, ec_ctx); - for (uint16_t i = 0; i < len; i += step) + for (uint16_t i = 0; i < len * step; i += step) gcry_mpi_ec_add (out, out, in[i], ec_ctx); } @@ -616,7 +616,7 @@ smc_gen_keyshare (struct AuctionData *ad, size_t *buflen) brandt_assert (ad && buflen); *buflen = (sizeof (struct ec_mpi) + sizeof (*proof1)); if (NULL == (ret = calloc (1, *buflen)) || - NULL == (ad->y = calloc (ad->n, sizeof (*ad->y)))) + NULL == (ad->y = smc_init1 (ad->n))) { weprintf ("unable to alloc memory for key shares"); return NULL; @@ -1103,6 +1103,37 @@ quit: } +int32_t +smc_determine_outcome (struct AuctionData *ad) +{ + 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); + + brandt_assert (ad); + + for (uint16_t j = 0; j < ad->k; j++) + { + smc_sum (sum_gamma, &ad->gamma[0][ad->i][j], ad->n, ad->n * ad->k); + smc_sum (sum_phi, &ad->phi[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 (-1 != ret) + { + weprintf ("multiple winning prices detected"); + return -1; + } + ret = j; + } + } + + gcry_mpi_point_release (sum_gamma); + gcry_mpi_point_release (sum_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 cb1daea..8d2983c 100644 --- a/crypto.h +++ b/crypto.h @@ -135,4 +135,6 @@ int smc_recv_decryption (struct AuctionData *ad, size_t buflen, uint16_t sender); +int32_t smc_determine_outcome (struct AuctionData *ad); + #endif /* ifndef _BRANDT_CRYPTO_H */ diff --git a/test_crypto.c b/test_crypto.c index 7f6430e..c1774e4 100644 --- a/test_crypto.c +++ b/test_crypto.c @@ -317,19 +317,38 @@ test_round3 () } +int +test_outcome () +{ + int32_t ret = -1; + + for (uint16_t i = 0; i < ad->n; i++) + { + if (-1 != smc_determine_outcome (&ad[i])) + { + check (-1 == ret, "multiple winners detected"); + ret = i; + } + } + check (-1 != ret, "no winner detected"); + fputs ("winner detected", stderr); + return 1; +} + + void cleanup_auction_data () { for (uint16_t i = 0; i < bidders; i++) { - for (uint16_t h = 0; h < bidders; h++) - gcry_mpi_point_release (ad[i].y[h]); - gcry_mpi_point_release (ad[i].Y); gcry_mpi_release (ad[i].x); - free (ad[i].y); + smc_free1 (ad[i].y, ad[i].n); smc_free2 (ad[i].alpha, ad[i].n, ad[i].k); smc_free2 (ad[i].beta, ad[i].n, ad[i].k); + smc_free3 (ad[i].gamma, ad[i].n, ad[i].n, ad[i].k); + smc_free3 (ad[i].delta, ad[i].n, ad[i].n, ad[i].k); + smc_free3 (ad[i].phi, ad[i].n, ad[i].n, ad[i].k); } free (ad); } @@ -361,6 +380,7 @@ main (int argc, char *argv[]) run (test_round1); run (test_round2); run (test_round3); + run (test_outcome); cleanup_auction_data (); }