diff options
author | Markus Teich <markus.teich@stusta.mhn.de> | 2016-06-22 14:22:52 +0200 |
---|---|---|
committer | Markus Teich <markus.teich@stusta.mhn.de> | 2016-06-22 14:22:52 +0200 |
commit | a49b2facee0242ebbeebe30e4f479afbaa381893 (patch) | |
tree | fa79e0c55b2f201d1e936d7852f021a0e87495d0 | |
parent | 2c63da0ed17dd5403a81c9b8462bd8c1f66ca3d5 (diff) |
add prologue and round1 including tests
-rw-r--r-- | crypto.c | 315 | ||||
-rw-r--r-- | crypto.h | 3 | ||||
-rw-r--r-- | test_crypto.c | 113 | ||||
-rw-r--r-- | uncrustify/conf | 2 |
4 files changed, 349 insertions, 84 deletions
@@ -373,12 +373,35 @@ ec_point_parse (gcry_mpi_point_t dst, const struct ec_mpi *src) /** + * smc_free2 releases all points in @a dst and frees the memory + * + * @param[in,out] dst The 2 dimensional array to clean up + * @param[in] size1 size of the first dimension + * @param[in] size2 size of the second dimension + */ +static void +smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) +{ + uint16_t i, j; + + if (NULL == dst) + return; + + for (i = 0; i < size1; i++) + for (j = 0; j < size2; j++) + if (NULL != dst[i][j]) + gcry_mpi_point_release (dst[i][j]); + free (dst); +} + + +/** * smc_init2 creates a 2 dimensional array of curve points * * @param[in] size1 size of the first dimension * @param[in] size2 size of the second dimension - * @return a pointer to the array. If not used anymore use smc_free2 to reclaim - * the memory. + * @return a pointer to the array or NULL on error. + * If not used anymore use smc_free2 to reclaim the memory. */ static gcry_mpi_point_t ** smc_init2 (uint16_t size1, uint16_t size2) @@ -387,35 +410,55 @@ smc_init2 (uint16_t size1, uint16_t size2) gcry_mpi_point_t **ret; gcry_mpi_point_t *data; - ret = calloc (size1, sizeof (*ret) + size2 * sizeof (**ret)); - brandt_assert (NULL != ret); + if (NULL == (ret = calloc (size1, sizeof (*ret) + size2 * sizeof (**ret)))) + { + weprintf ("could not alloc memory for 2 dimensional point array"); + return NULL; + } data = (gcry_mpi_point_t *)&ret[size1]; for (i = 0; i < size1; i++) { ret[i] = &data[i * size2]; for (j = 0; j < size2; j++) - ret[i][j] = gcry_mpi_point_new (0); + { + if (NULL == (ret[i][j] = gcry_mpi_point_new (0))) + { + weprintf ("could not init point in 2 dimensional array. " + "out of memory?"); + smc_free2 (ret, size1, size2); + return NULL; + } + } } return ret; } /** - * smc_free2 releases all points in @a dst and frees the memory + * smc_free3 releases all points in @a dst and frees the memory * - * @param[in,out] dst The 2 dimensional array to clean up + * @param[in,out] dst The 3 dimensional array to clean up * @param[in] size1 size of the first dimension * @param[in] size2 size of the second dimension + * @param[in] size3 size of the third dimension */ static void -smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) +smc_free3 (gcry_mpi_point_t ***dst, + uint16_t size1, + uint16_t size2, + uint16_t size3) { - uint16_t i, j; + uint16_t i, j, k; + + if (NULL == dst) + return; for (i = 0; i < size1; i++) for (j = 0; j < size2; j++) - gcry_mpi_point_release (dst[i][j]); + for (k = 0; k < size3; k++) + if (NULL != dst[i][j][k]) + gcry_mpi_point_release (dst[i][j][k]); free (dst); } @@ -426,8 +469,8 @@ smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) * @param[in] size1 size of the first dimension * @param[in] size2 size of the second dimension * @param[in] size3 size of the third dimension - * @return a pointer to the array. If not used anymore use smc_free3 to reclaim - * the memory. + * @return a pointer to the array or NULL on error. + * If not used anymore use smc_free3 to reclaim the memory. */ static gcry_mpi_point_t *** smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) @@ -437,10 +480,13 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) gcry_mpi_point_t **layer1; gcry_mpi_point_t *layer2; - ret = calloc (size1, sizeof (*ret) + - size2 * sizeof (**ret) + - size2 * size3 * sizeof (***ret)); - brandt_assert (NULL != ret); + if (NULL == (ret = calloc (size1, sizeof (*ret) + + size2 * sizeof (**ret) + + size2 * size3 * sizeof (***ret)))) + { + weprintf ("could not alloc memory for 3 dimensional point array"); + return NULL; + } layer1 = (gcry_mpi_point_t **)&ret[size1]; layer2 = (gcry_mpi_point_t *)&layer1[size1 * size2]; @@ -451,7 +497,15 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) { layer1[i * size2 + j] = &layer2[(i * size2 + j) * size3]; for (k = 0; k < size3; k++) - ret[i][j][k] = gcry_mpi_point_new (0); + { + if (NULL == (ret[i][j][k] = gcry_mpi_point_new (0))) + { + weprintf ("could not init point in 2 dimensional array. " + "out of memory?"); + smc_free3 (ret, size1, size2, size3); + return NULL; + } + } } } return ret; @@ -459,30 +513,6 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) /** - * smc_free3 releases all points in @a dst and frees the memory - * - * @param[in,out] dst The 3 dimensional array to clean up - * @param[in] size1 size of the first dimension - * @param[in] size2 size of the second dimension - * @param[in] size3 size of the third dimension - */ -static void -smc_free3 (gcry_mpi_point_t ***dst, - uint16_t size1, - uint16_t size2, - uint16_t size3) -{ - uint16_t i, j, k; - - for (i = 0; i < size1; i++) - for (j = 0; j < size2; j++) - for (k = 0; k < size3; k++) - gcry_mpi_point_release (dst[i][j][k]); - free (dst); -} - - -/** * smc_sums_partial calculates sums up until the current index and stores them * in @a out. \f$\forall i \leq len: out_i=\sum_{h=1}^iin_h\f$ * @@ -532,34 +562,70 @@ smc_sum (gcry_mpi_point_t out, gcry_mpi_point_t in[], uint16_t len) * public multiplicative key share * * @param[in,out] ad Pointer to the AuctionData struct to operate on - * @param[out] proof Pointer to where the proof of knowledge should be saved. - * Must be allocated memory with apropriate size for one proof struct. + * @param[out] buflen \todo + * @return \todo */ -void -smc_gen_keyshare (struct AuctionData *ad, struct proof_dl *proof) +unsigned char * +smc_gen_keyshare (struct AuctionData *ad, size_t *buflen) { - uint16_t i; + uint16_t i; + unsigned char *ret; + struct proof_dl *proof1; + + 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)))) + { + weprintf ("unable to alloc memory for key shares"); + return NULL; + } - ad->y = calloc (ad->n, sizeof (*ad->y)); + proof1 = (struct proof_dl *)(ret + sizeof (struct ec_mpi)); for (i = 0; i < ad->n; i++) - ad->y[0] = gcry_mpi_point_new (0); + ad->y[i] = gcry_mpi_point_new (0); ad->x = gcry_mpi_new (0); ec_skey_create (ad->x); - smc_zkp_dl (ad->y[ad->i], ad->x, proof); + smc_zkp_dl (ad->y[ad->i], ad->x, proof1); + ec_point_serialize ((struct ec_mpi *)ret, ad->y[ad->i]); + return ret; } -/** - * smc_compute_pkey calculates the shared public key - * - * @param[in,out] ad The struct AuctionData used - */ -void -smc_compute_pkey (struct AuctionData *ad) +int +smc_recv_keyshare (struct AuctionData *ad, + unsigned char *buf, + size_t buflen, + uint16_t sender_index) { - ad->Y = gcry_mpi_point_new (0); - smc_sum (ad->Y, ad->y, ad->n); + int ret = 0; + struct proof_dl *proof1; + gcry_mpi_point_t y = gcry_mpi_point_new (0); + + brandt_assert (ad && buf); + + if (buflen != (sizeof (struct ec_mpi) + sizeof (*proof1))) + { + weprintf ("wrong size of received key share"); + goto quit; + } + + proof1 = (struct proof_dl *)(buf + sizeof (struct ec_mpi)); + ec_point_parse (y, (struct ec_mpi *)buf); + if (smc_zkp_dl_check (y, proof1)) + { + weprintf ("wrong zkp1 for public key share received"); + goto quit; + } + + /**\todo: how to copy a point more efficiently? */ + gcry_mpi_ec_add (ad->y[sender_index], ec_zero, y, ec_ctx); + + ret = 1; +quit: + gcry_mpi_point_release (y); + return ret; } @@ -567,30 +633,119 @@ smc_compute_pkey (struct AuctionData *ad) * smc_encrypt_bid \todo * * @param ad TODO - * @param j TODO - * @param a1 TODO - * @param a2 TODO - * @param b1 TODO - * @param b2 TODO - * @param d1 TODO - * @param d2 TODO - * @param r1 TODO - * @param r2 TODO + * @param buflen TODO */ -void -smc_encrypt_bid (struct AuctionData *ad, - uint16_t j, - gcry_mpi_point_t a1, - gcry_mpi_point_t a2, - gcry_mpi_point_t b1, - gcry_mpi_point_t b2, - gcry_mpi_t d1, - gcry_mpi_t d2, - gcry_mpi_t r1, - gcry_mpi_t r2) +unsigned char * +smc_encrypt_bid (struct AuctionData *ad, size_t *buflen) +{ + uint16_t j; + unsigned char *ret; + unsigned char *cur; + struct proof_0og *proof3; + gcry_mpi_t r_sum; + gcry_mpi_t r_part; + + brandt_assert (ad && buflen); + *buflen = (ad->k * /* k * (alpha, beta, proof3) */ + (sizeof (struct ec_mpi) * 2 + /* alpha, beta */ + sizeof (*proof3)) + + sizeof (struct proof_2dle)); + if (NULL == (cur = (ret = calloc (1, *buflen))) || + 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; + } + + ad->Y = gcry_mpi_point_new (0); + smc_sum (ad->Y, ad->y, ad->n); + + r_sum = gcry_mpi_new (0); + r_part = gcry_mpi_new (0); + + for (j = 0; j < ad->k; j++) + { + proof3 = (struct proof_0og *)(cur + 2 * sizeof (struct ec_mpi)); + smc_zkp_0og (j == ad->b, ad->Y, r_part, + ad->alpha[ad->i][j], ad->beta[ad->i][j], proof3); + ec_point_serialize ((struct ec_mpi *)cur, ad->alpha[ad->i][j]); + ec_point_serialize (&((struct ec_mpi *)cur)[1], ad->beta[ad->i][j]); + gcry_mpi_addm (r_sum, r_sum, r_part, ec_n); + cur += 2 * sizeof (struct ec_mpi) + sizeof (struct proof_0og); + } + smc_zkp_2dle (NULL, NULL, ad->Y, ec_gen, r_sum, (struct proof_2dle *)cur); + + gcry_mpi_release (r_sum); + gcry_mpi_release (r_part); + + return ret; +} + + +int +smc_recv_encrypted_bid (struct AuctionData *ad, + unsigned char *buf, + size_t buflen, + uint16_t sender_index) { -// smc_zkp_0og (ad->alpha[ad->i][j], j == ad->b, ad->Y, -// ad->beta[ad->i][j], a1, a2, b1, b2, d1, d2, r1, r2); + int ret = 0; + uint16_t j; + unsigned char *cur = buf; + struct proof_0og *proof3; + gcry_mpi_point_t **ct; /* ciphertexts */ + gcry_mpi_point_t alpha_sum = gcry_mpi_point_new (0); + gcry_mpi_point_t beta_sum = gcry_mpi_point_new (0); + + brandt_assert (ad && buf); + + if (buflen != (ad->k * (sizeof (struct ec_mpi) * 2 + sizeof (*proof3)) + + sizeof (struct proof_2dle)) || + NULL == (ct = smc_init2 (2, ad->k))) + { + weprintf ("wrong size of received encrypted bid"); + goto quit; + } + + gcry_mpi_ec_mul (alpha_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx); + gcry_mpi_ec_mul (beta_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx); + + for (j = 0; j < ad->k; j++) + { + ec_point_parse (ct[0][j], (struct ec_mpi *)cur); + ec_point_parse (ct[1][j], &((struct ec_mpi *)cur)[1]); + proof3 = (struct proof_0og *)(cur + 2 * sizeof (struct ec_mpi)); + if (smc_zkp_0og_check (ad->Y, ct[0][j], ct[1][j], proof3)) + { + weprintf ("wrong zkp3 for alpha, beta received"); + goto quit; + } + gcry_mpi_ec_add (alpha_sum, alpha_sum, ct[0][j], ec_ctx); + gcry_mpi_ec_add (beta_sum, beta_sum, ct[1][j], ec_ctx); + cur += 2 * sizeof (struct ec_mpi) + sizeof (struct proof_0og); + } + + gcry_mpi_ec_sub (alpha_sum, alpha_sum, ec_gen, ec_ctx); + if (smc_zkp_2dle_check (alpha_sum, beta_sum, ad->Y, ec_gen, + (struct proof_2dle *)cur)) + { + weprintf ("wrong zkp2 for alpha, beta received"); + goto quit; + } + + for (j = 0; j < ad->k; j++) + { + /**\todo: how to copy a point more efficiently? */ + gcry_mpi_ec_add (ad->alpha[sender_index][j], ec_zero, ct[0][j], ec_ctx); + gcry_mpi_ec_add (ad->beta[sender_index][j], ec_zero, ct[1][j], ec_ctx); + } + smc_free2 (ct, 2, ad->k); + + ret = 1; /* finally success */ +quit: + gcry_mpi_point_release (alpha_sum); + gcry_mpi_point_release (beta_sum); + return ret; } @@ -115,7 +115,6 @@ int smc_zkp_0og_check (const gcry_mpi_point_t y, /* --- Protocol implementation --- */ -void smc_gen_keyshare (struct AuctionData *ad, struct proof_dl *proof); -void smc_compute_pkey (struct AuctionData *ad); +unsigned char *smc_gen_keyshare (struct AuctionData *ad, size_t *buflen); #endif /* ifndef _BRANDT_CRYPTO_H */ diff --git a/test_crypto.c b/test_crypto.c index 7e8fe2b..33b9a9b 100644 --- a/test_crypto.c +++ b/test_crypto.c @@ -27,6 +27,10 @@ #include "test.h" +static uint16_t bidders; +static uint16_t prizes; +static struct AuctionData *ad; + int test_smc_2d_array () { @@ -43,6 +47,7 @@ test_smc_2d_array () check (array[i][j], "point has not been initialized"); smc_free2 (array, size1, size2); + return 1; } @@ -64,6 +69,7 @@ test_smc_3d_array () check (array[i][j][k], "point has not been initialized"); smc_free3 (array, size1, size2, size3); + return 1; } @@ -96,6 +102,7 @@ test_serialization () gcry_mpi_point_release (newp); gcry_mpi_release (oldi); gcry_mpi_release (newi); + return 1; } @@ -114,6 +121,7 @@ test_smc_zkp_dl () gcry_mpi_release (x); gcry_mpi_point_release (v); + return 1; } @@ -142,6 +150,7 @@ test_smc_zkp_2dle () gcry_mpi_point_release (g2); gcry_mpi_point_release (v); gcry_mpi_point_release (w); + return 1; } @@ -165,13 +174,110 @@ test_smc_zkp_0og () gcry_mpi_point_release (y); gcry_mpi_point_release (alpha); gcry_mpi_point_release (beta); + return 1; +} + + +int +test_setup_auction_data () +{ + uint16_t i; + + ad = calloc (bidders, sizeof (struct AuctionData)); + + for (i = 0; i < bidders; i++) + { + ad[i].n = bidders; + ad[i].i = i; + ad[i].k = prizes; + ad[i].b = 2 * i; + } + return 1; +} + + +int +test_prologue () +{ + uint16_t i, s; + unsigned char *bufs[bidders]; + size_t lens[bidders]; + + for (i = 0; i < bidders; i++) + { + bufs[i] = smc_gen_keyshare (&ad[i], &lens[i]); + check (bufs[i], "failed to gen keyshare"); + } + + for (i = 0; i < bidders; i++) + { + for (s = 0; s < bidders; s++) + { + if (s == i) + continue; + check (smc_recv_keyshare (&ad[i], bufs[s], lens[s], s), + "failed checking keyshare"); + } + } + + for (i = 0; i < bidders; i++) + free (bufs[i]); + return 1; +} + + +int +test_round1 () +{ + uint16_t i, s; + unsigned char *bufs[bidders]; + size_t lens[bidders]; + + for (i = 0; i < bidders; i++) + { + bufs[i] = smc_encrypt_bid (&ad[i], &lens[i]); + check (bufs[i], "failed to encrypt bid"); + } + + for (i = 0; i < bidders; i++) + { + for (s = 0; s < bidders; s++) + { + if (s == i) + continue; + check (smc_recv_encrypted_bid (&ad[i], bufs[s], lens[s], s), + "failed checking encrypted bid"); + } + } + + for (i = 0; i < bidders; i++) + free (bufs[i]); + return 1; +} + + +void +cleanup_auction_data () +{ + uint16_t i; + + for (i = 0; i < bidders; i++) + { + free (ad[i].y); + smc_free2 (ad[i].alpha, ad[i].n, ad[i].k); + smc_free2 (ad[i].beta, ad[i].n, ad[i].k); + } + free (ad); } int main (int argc, char *argv[]) { - int repeat = 16; + int repeat = 8; + + bidders = 2; + prizes = 2 * bidders; BRANDT_init (); @@ -185,6 +291,11 @@ main (int argc, char *argv[]) run (test_smc_zkp_dl); run (test_smc_zkp_2dle); run (test_smc_zkp_0og); + + run (test_setup_auction_data); + run (test_prologue); + run (test_round1); + cleanup_auction_data (); } return ret; diff --git a/uncrustify/conf b/uncrustify/conf index 07a7816..b901341 100644 --- a/uncrustify/conf +++ b/uncrustify/conf @@ -276,7 +276,7 @@ sp_after_ptr_star = remove # ignore/add/remove/force sp_after_ptr_star_func = remove # ignore/add/remove/force # Add or remove space before a pointer star '*', if followed by a func proto/def. -sp_before_ptr_star_func = remove # ignore/add/remove/force +sp_before_ptr_star_func = force # ignore/add/remove/force # Add or remove space before a reference sign '&' sp_before_byref = ignore # ignore/add/remove/force |