diff options
author | Markus Teich <markus.teich@stusta.mhn.de> | 2016-06-28 16:29:18 +0200 |
---|---|---|
committer | Markus Teich <markus.teich@stusta.mhn.de> | 2016-06-28 16:29:18 +0200 |
commit | fb2bf04d382da6ec2f823dacaf4962aca713bac6 (patch) | |
tree | 61e798df4b817d7843a1e3dce6c01c3ffd4913c8 /crypto.c | |
parent | 5dbbef588dc7247570c9c5f9797b38d907313288 (diff) | |
download | libbrandt-fb2bf04d382da6ec2f823dacaf4962aca713bac6.tar.gz libbrandt-fb2bf04d382da6ec2f823dacaf4962aca713bac6.zip |
add outcome computation with test
also:
- enhance smc_zkp_2dle: secret can now be auto generated.
- enhance sum functions: can now use custom step advancing.
- add init1 and free1 for 1-dimensional point arrays.
- declare loop variables inside loop header.
- narrow some variable scopes.
Diffstat (limited to 'crypto.c')
-rw-r--r-- | crypto.c | 380 |
1 files changed, 304 insertions, 76 deletions
@@ -238,18 +238,13 @@ ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) | |||
238 | void | 238 | void |
239 | mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src) | 239 | mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src) |
240 | { | 240 | { |
241 | size_t rsize = 0; | 241 | size_t rsize = 0; |
242 | unsigned int nbits; | ||
243 | const void *vp; | ||
244 | char *cp = (char *)dst; | ||
245 | gcry_error_t rc; | ||
246 | |||
247 | 242 | ||
248 | if (gcry_mpi_get_flag (src, GCRYMPI_FLAG_OPAQUE)) | 243 | if (gcry_mpi_get_flag (src, GCRYMPI_FLAG_OPAQUE)) |
249 | { | 244 | { /* Store opaque MPIs left aligned. Used by Ed25519 point compression */ |
250 | /* Store opaque MPIs left aligned into the buffer. Used by Ed25519 point | 245 | unsigned int nbits; |
251 | * compression */ | 246 | const void *vp = gcry_mpi_get_opaque (src, &nbits); |
252 | vp = gcry_mpi_get_opaque (src, &nbits); | 247 | |
253 | brandt_assert (vp); | 248 | brandt_assert (vp); |
254 | rsize = (nbits + 7) / 8; | 249 | rsize = (nbits + 7) / 8; |
255 | if (rsize > sizeof (struct ec_mpi)) | 250 | if (rsize > sizeof (struct ec_mpi)) |
@@ -259,8 +254,10 @@ mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src) | |||
259 | memset (((char *)dst) + rsize, 0, sizeof (struct ec_mpi) - rsize); | 254 | memset (((char *)dst) + rsize, 0, sizeof (struct ec_mpi) - rsize); |
260 | } | 255 | } |
261 | else | 256 | else |
262 | { | 257 | { /* Store regular MPIs as unsigned ints right aligned into the buffer. */ |
263 | /* Store regular MPIs as unsigned ints right aligned into the buffer. */ | 258 | char *cp = (char *)dst; |
259 | gcry_error_t rc; | ||
260 | |||
264 | rc = gcry_mpi_print (GCRYMPI_FMT_USG, (void *)dst, | 261 | rc = gcry_mpi_print (GCRYMPI_FMT_USG, (void *)dst, |
265 | sizeof (struct ec_mpi), &rsize, src); | 262 | sizeof (struct ec_mpi), &rsize, src); |
266 | brandt_assert_gpgerr (rc); | 263 | brandt_assert_gpgerr (rc); |
@@ -366,6 +363,57 @@ ec_point_parse (gcry_mpi_point_t dst, const struct ec_mpi *src) | |||
366 | 363 | ||
367 | 364 | ||
368 | /** | 365 | /** |
366 | * smc_free1 releases all points in @a dst and frees the memory | ||
367 | * | ||
368 | * @param[in,out] dst The 1 dimensional array to clean up | ||
369 | * @param[in] size1 size of the first dimension | ||
370 | */ | ||
371 | static void | ||
372 | smc_free1 (gcry_mpi_point_t *dst, uint16_t size1) | ||
373 | { | ||
374 | if (NULL == dst) | ||
375 | return; | ||
376 | |||
377 | for (uint16_t i = 0; i < size1; i++) | ||
378 | if (NULL != dst[i]) | ||
379 | gcry_mpi_point_release (dst[i]); | ||
380 | free (dst); | ||
381 | } | ||
382 | |||
383 | |||
384 | /** | ||
385 | * smc_init1 creates a 1 dimensional array of curve points | ||
386 | * | ||
387 | * @param[in] size1 size of the first dimension | ||
388 | * @return a pointer to the array or NULL on error. | ||
389 | * If not used anymore use smc_free2 to reclaim the memory. | ||
390 | */ | ||
391 | static gcry_mpi_point_t * | ||
392 | smc_init1 (uint16_t size1) | ||
393 | { | ||
394 | gcry_mpi_point_t *ret; | ||
395 | |||
396 | if (NULL == (ret = calloc (size1, sizeof (*ret)))) | ||
397 | { | ||
398 | weprintf ("could not alloc memory for 1 dimensional point array"); | ||
399 | return NULL; | ||
400 | } | ||
401 | |||
402 | for (uint16_t i = 0; i < size1; i++) | ||
403 | { | ||
404 | if (NULL == (ret[i] = gcry_mpi_point_new (0))) | ||
405 | { | ||
406 | weprintf ("could not init point in 1 dimensional array. " | ||
407 | "out of memory?"); | ||
408 | smc_free1 (ret, size1); | ||
409 | return NULL; | ||
410 | } | ||
411 | } | ||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | |||
416 | /** | ||
369 | * smc_free2 releases all points in @a dst and frees the memory | 417 | * smc_free2 releases all points in @a dst and frees the memory |
370 | * | 418 | * |
371 | * @param[in,out] dst The 2 dimensional array to clean up | 419 | * @param[in,out] dst The 2 dimensional array to clean up |
@@ -375,14 +423,11 @@ ec_point_parse (gcry_mpi_point_t dst, const struct ec_mpi *src) | |||
375 | static void | 423 | static void |
376 | smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) | 424 | smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) |
377 | { | 425 | { |
378 | uint16_t i; | ||
379 | uint16_t j; | ||
380 | |||
381 | if (NULL == dst) | 426 | if (NULL == dst) |
382 | return; | 427 | return; |
383 | 428 | ||
384 | for (i = 0; i < size1; i++) | 429 | for (uint16_t i = 0; i < size1; i++) |
385 | for (j = 0; j < size2; j++) | 430 | for (uint16_t j = 0; j < size2; j++) |
386 | if (NULL != dst[i][j]) | 431 | if (NULL != dst[i][j]) |
387 | gcry_mpi_point_release (dst[i][j]); | 432 | gcry_mpi_point_release (dst[i][j]); |
388 | free (dst); | 433 | free (dst); |
@@ -400,8 +445,6 @@ smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) | |||
400 | static gcry_mpi_point_t ** | 445 | static gcry_mpi_point_t ** |
401 | smc_init2 (uint16_t size1, uint16_t size2) | 446 | smc_init2 (uint16_t size1, uint16_t size2) |
402 | { | 447 | { |
403 | uint16_t i; | ||
404 | uint16_t j; | ||
405 | gcry_mpi_point_t **ret; | 448 | gcry_mpi_point_t **ret; |
406 | gcry_mpi_point_t *data; | 449 | gcry_mpi_point_t *data; |
407 | 450 | ||
@@ -412,10 +455,10 @@ smc_init2 (uint16_t size1, uint16_t size2) | |||
412 | } | 455 | } |
413 | 456 | ||
414 | data = (gcry_mpi_point_t *)&ret[size1]; | 457 | data = (gcry_mpi_point_t *)&ret[size1]; |
415 | for (i = 0; i < size1; i++) | 458 | for (uint16_t i = 0; i < size1; i++) |
416 | { | 459 | { |
417 | ret[i] = &data[i * size2]; | 460 | ret[i] = &data[i * size2]; |
418 | for (j = 0; j < size2; j++) | 461 | for (uint16_t j = 0; j < size2; j++) |
419 | { | 462 | { |
420 | if (NULL == (ret[i][j] = gcry_mpi_point_new (0))) | 463 | if (NULL == (ret[i][j] = gcry_mpi_point_new (0))) |
421 | { | 464 | { |
@@ -444,16 +487,12 @@ smc_free3 (gcry_mpi_point_t ***dst, | |||
444 | uint16_t size2, | 487 | uint16_t size2, |
445 | uint16_t size3) | 488 | uint16_t size3) |
446 | { | 489 | { |
447 | uint16_t i; | ||
448 | uint16_t j; | ||
449 | uint16_t k; | ||
450 | |||
451 | if (NULL == dst) | 490 | if (NULL == dst) |
452 | return; | 491 | return; |
453 | 492 | ||
454 | for (i = 0; i < size1; i++) | 493 | for (uint16_t i = 0; i < size1; i++) |
455 | for (j = 0; j < size2; j++) | 494 | for (uint16_t j = 0; j < size2; j++) |
456 | for (k = 0; k < size3; k++) | 495 | for (uint16_t k = 0; k < size3; k++) |
457 | if (NULL != dst[i][j][k]) | 496 | if (NULL != dst[i][j][k]) |
458 | gcry_mpi_point_release (dst[i][j][k]); | 497 | gcry_mpi_point_release (dst[i][j][k]); |
459 | free (dst); | 498 | free (dst); |
@@ -472,9 +511,6 @@ smc_free3 (gcry_mpi_point_t ***dst, | |||
472 | static gcry_mpi_point_t *** | 511 | static gcry_mpi_point_t *** |
473 | smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) | 512 | smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) |
474 | { | 513 | { |
475 | uint16_t i; | ||
476 | uint16_t j; | ||
477 | uint16_t k; | ||
478 | gcry_mpi_point_t ***ret; | 514 | gcry_mpi_point_t ***ret; |
479 | gcry_mpi_point_t **layer1; | 515 | gcry_mpi_point_t **layer1; |
480 | gcry_mpi_point_t *layer2; | 516 | gcry_mpi_point_t *layer2; |
@@ -489,13 +525,13 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) | |||
489 | 525 | ||
490 | layer1 = (gcry_mpi_point_t **)&ret[size1]; | 526 | layer1 = (gcry_mpi_point_t **)&ret[size1]; |
491 | layer2 = (gcry_mpi_point_t *)&layer1[size1 * size2]; | 527 | layer2 = (gcry_mpi_point_t *)&layer1[size1 * size2]; |
492 | for (i = 0; i < size1; i++) | 528 | for (uint16_t i = 0; i < size1; i++) |
493 | { | 529 | { |
494 | ret[i] = &layer1[i * size2]; | 530 | ret[i] = &layer1[i * size2]; |
495 | for (j = 0; j < size2; j++) | 531 | for (uint16_t j = 0; j < size2; j++) |
496 | { | 532 | { |
497 | layer1[i * size2 + j] = &layer2[(i * size2 + j) * size3]; | 533 | layer1[i * size2 + j] = &layer2[(i * size2 + j) * size3]; |
498 | for (k = 0; k < size3; k++) | 534 | for (uint16_t k = 0; k < size3; k++) |
499 | { | 535 | { |
500 | if (NULL == (ret[i][j][k] = gcry_mpi_point_new (0))) | 536 | if (NULL == (ret[i][j][k] = gcry_mpi_point_new (0))) |
501 | { | 537 | { |
@@ -515,23 +551,26 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) | |||
515 | * smc_sums_partial calculates sums up until the current index and stores them | 551 | * smc_sums_partial calculates sums up until the current index and stores them |
516 | * in @a out. \f$\forall i \leq len: out_i=\sum_{h=1}^iin_h\f$ | 552 | * in @a out. \f$\forall i \leq len: out_i=\sum_{h=1}^iin_h\f$ |
517 | * | 553 | * |
518 | * @param[out] out Where to store the resulting sums. Points may be given | 554 | * @param[out] out Where to store the resulting sums. Points must already be |
519 | * uninitialized, but the appropriate amount of memory has to be allocated | 555 | * initialized beforehand. |
520 | * beforehand. | ||
521 | * @param[in] in Input points. | 556 | * @param[in] in Input points. |
522 | * @param[in] len The length of both @a out and @a in. | 557 | * @param[in] len The length of @a out. @a in must be at least @a step times @a |
558 | * len elements long. | ||
559 | * @param[in] stepi The amount of items to advance in @a in each step. Can be | ||
560 | * used to sum over multi-dimensional arrays. | ||
561 | * @param[in] stepo The amount of items to advance in @a out each step. Can be | ||
562 | * used to store the sum in multi-dimensional arrays. | ||
523 | */ | 563 | */ |
524 | static void | 564 | static void |
525 | smc_sums_partial (gcry_mpi_point_t out[], gcry_mpi_point_t in[], uint16_t len) | 565 | smc_sums_partial (gcry_mpi_point_t out[], |
566 | gcry_mpi_point_t in[], | ||
567 | uint16_t len, | ||
568 | uint16_t stepi, | ||
569 | uint16_t stepo) | ||
526 | { | 570 | { |
527 | uint16_t i; | 571 | brandt_assert (NULL != out); |
528 | 572 | for (uint16_t i = 0, o = 0; o < len * stepo; i += stepi, o += stepo) | |
529 | for (i = 0; i < len; i++) | 573 | gcry_mpi_ec_add (out[o], (o ? out[o - stepo] : ec_zero), in[i], ec_ctx); |
530 | { | ||
531 | out[i] = gcry_mpi_point_new (0); | ||
532 | gcry_mpi_ec_add (out[i], in[i], (i ? out[i - 1] : ec_zero), ec_ctx); | ||
533 | brandt_assert (NULL != out[i]); | ||
534 | } | ||
535 | } | 574 | } |
536 | 575 | ||
537 | 576 | ||
@@ -541,17 +580,21 @@ smc_sums_partial (gcry_mpi_point_t out[], gcry_mpi_point_t in[], uint16_t len) | |||
541 | * | 580 | * |
542 | * @param[out] out Where to store the result | 581 | * @param[out] out Where to store the result |
543 | * @param[in] in Input points. | 582 | * @param[in] in Input points. |
544 | * @param[in] len The length of @a in. | 583 | * @param[in] len The amount of summands to use from @a in. @a in must be at |
584 | * least @a step times @a len elements long. | ||
585 | * @param[in] step The amount of items to advance in @a in each step. Can be | ||
586 | * used to sum over multi-dimensional arrays. | ||
545 | */ | 587 | */ |
546 | static void | 588 | static void |
547 | smc_sum (gcry_mpi_point_t out, gcry_mpi_point_t in[], uint16_t len) | 589 | smc_sum (gcry_mpi_point_t out, |
590 | gcry_mpi_point_t in[], | ||
591 | uint16_t len, | ||
592 | uint16_t step) | ||
548 | { | 593 | { |
549 | uint16_t i; | ||
550 | |||
551 | brandt_assert (NULL != out); | 594 | brandt_assert (NULL != out); |
552 | /**\todo: how to copy a point more efficiently? */ | 595 | /**\todo: how to copy a point more efficiently? */ |
553 | gcry_mpi_ec_add (out, ec_zero, ec_zero, ec_ctx); | 596 | gcry_mpi_ec_add (out, ec_zero, ec_zero, ec_ctx); |
554 | for (i = 0; i < len; i++) | 597 | for (uint16_t i = 0; i < len; i += step) |
555 | gcry_mpi_ec_add (out, out, in[i], ec_ctx); | 598 | gcry_mpi_ec_add (out, out, in[i], ec_ctx); |
556 | } | 599 | } |
557 | 600 | ||
@@ -567,7 +610,6 @@ smc_sum (gcry_mpi_point_t out, gcry_mpi_point_t in[], uint16_t len) | |||
567 | unsigned char * | 610 | unsigned char * |
568 | smc_gen_keyshare (struct AuctionData *ad, size_t *buflen) | 611 | smc_gen_keyshare (struct AuctionData *ad, size_t *buflen) |
569 | { | 612 | { |
570 | uint16_t i; | ||
571 | unsigned char *ret; | 613 | unsigned char *ret; |
572 | struct proof_dl *proof1; | 614 | struct proof_dl *proof1; |
573 | 615 | ||
@@ -581,7 +623,7 @@ smc_gen_keyshare (struct AuctionData *ad, size_t *buflen) | |||
581 | } | 623 | } |
582 | 624 | ||
583 | proof1 = (struct proof_dl *)(ret + sizeof (struct ec_mpi)); | 625 | proof1 = (struct proof_dl *)(ret + sizeof (struct ec_mpi)); |
584 | for (i = 0; i < ad->n; i++) | 626 | for (uint16_t i = 0; i < ad->n; i++) |
585 | ad->y[i] = gcry_mpi_point_new (0); | 627 | ad->y[i] = gcry_mpi_point_new (0); |
586 | 628 | ||
587 | ad->x = gcry_mpi_new (0); | 629 | ad->x = gcry_mpi_new (0); |
@@ -596,7 +638,7 @@ int | |||
596 | smc_recv_keyshare (struct AuctionData *ad, | 638 | smc_recv_keyshare (struct AuctionData *ad, |
597 | unsigned char *buf, | 639 | unsigned char *buf, |
598 | size_t buflen, | 640 | size_t buflen, |
599 | uint16_t sender_index) | 641 | uint16_t sender) |
600 | { | 642 | { |
601 | int ret = 0; | 643 | int ret = 0; |
602 | struct proof_dl *proof1; | 644 | struct proof_dl *proof1; |
@@ -619,7 +661,7 @@ smc_recv_keyshare (struct AuctionData *ad, | |||
619 | } | 661 | } |
620 | 662 | ||
621 | /**\todo: how to copy a point more efficiently? */ | 663 | /**\todo: how to copy a point more efficiently? */ |
622 | gcry_mpi_ec_add (ad->y[sender_index], ec_zero, y, ec_ctx); | 664 | gcry_mpi_ec_add (ad->y[sender], ec_zero, y, ec_ctx); |
623 | 665 | ||
624 | ret = 1; | 666 | ret = 1; |
625 | quit: | 667 | quit: |
@@ -637,7 +679,6 @@ quit: | |||
637 | unsigned char * | 679 | unsigned char * |
638 | smc_encrypt_bid (struct AuctionData *ad, size_t *buflen) | 680 | smc_encrypt_bid (struct AuctionData *ad, size_t *buflen) |
639 | { | 681 | { |
640 | uint16_t j; | ||
641 | unsigned char *ret; | 682 | unsigned char *ret; |
642 | unsigned char *cur; | 683 | unsigned char *cur; |
643 | struct proof_0og *proof3; | 684 | struct proof_0og *proof3; |
@@ -658,12 +699,12 @@ smc_encrypt_bid (struct AuctionData *ad, size_t *buflen) | |||
658 | } | 699 | } |
659 | 700 | ||
660 | ad->Y = gcry_mpi_point_new (0); | 701 | ad->Y = gcry_mpi_point_new (0); |
661 | smc_sum (ad->Y, ad->y, ad->n); | 702 | smc_sum (ad->Y, ad->y, ad->n, 1); |
662 | 703 | ||
663 | r_sum = gcry_mpi_new (0); | 704 | r_sum = gcry_mpi_new (0); |
664 | r_part = gcry_mpi_new (0); | 705 | r_part = gcry_mpi_new (0); |
665 | 706 | ||
666 | for (j = 0; j < ad->k; j++) | 707 | for (uint16_t j = 0; j < ad->k; j++) |
667 | { | 708 | { |
668 | proof3 = (struct proof_0og *)(cur + 2 * sizeof (struct ec_mpi)); | 709 | proof3 = (struct proof_0og *)(cur + 2 * sizeof (struct ec_mpi)); |
669 | smc_zkp_0og (j == ad->b, | 710 | smc_zkp_0og (j == ad->b, |
@@ -690,10 +731,9 @@ int | |||
690 | smc_recv_encrypted_bid (struct AuctionData *ad, | 731 | smc_recv_encrypted_bid (struct AuctionData *ad, |
691 | unsigned char *buf, | 732 | unsigned char *buf, |
692 | size_t buflen, | 733 | size_t buflen, |
693 | uint16_t sender_index) | 734 | uint16_t sender) |
694 | { | 735 | { |
695 | int ret = 0; | 736 | int ret = 0; |
696 | uint16_t j; | ||
697 | unsigned char *cur = buf; | 737 | unsigned char *cur = buf; |
698 | struct proof_0og *proof3; | 738 | struct proof_0og *proof3; |
699 | gcry_mpi_point_t **ct; /* ciphertexts */ | 739 | gcry_mpi_point_t **ct; /* ciphertexts */ |
@@ -713,7 +753,7 @@ smc_recv_encrypted_bid (struct AuctionData *ad, | |||
713 | gcry_mpi_ec_mul (alpha_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx); | 753 | gcry_mpi_ec_mul (alpha_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx); |
714 | gcry_mpi_ec_mul (beta_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx); | 754 | gcry_mpi_ec_mul (beta_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx); |
715 | 755 | ||
716 | for (j = 0; j < ad->k; j++) | 756 | for (uint16_t j = 0; j < ad->k; j++) |
717 | { | 757 | { |
718 | ec_point_parse (ct[0][j], (struct ec_mpi *)cur); | 758 | ec_point_parse (ct[0][j], (struct ec_mpi *)cur); |
719 | ec_point_parse (ct[1][j], &((struct ec_mpi *)cur)[1]); | 759 | ec_point_parse (ct[1][j], &((struct ec_mpi *)cur)[1]); |
@@ -739,11 +779,11 @@ smc_recv_encrypted_bid (struct AuctionData *ad, | |||
739 | goto quit; | 779 | goto quit; |
740 | } | 780 | } |
741 | 781 | ||
742 | for (j = 0; j < ad->k; j++) | 782 | for (uint16_t j = 0; j < ad->k; j++) |
743 | { | 783 | { |
744 | /**\todo: how to copy a point more efficiently? */ | 784 | /**\todo: how to copy a point more efficiently? */ |
745 | gcry_mpi_ec_add (ad->alpha[sender_index][j], ec_zero, ct[0][j], ec_ctx); | 785 | gcry_mpi_ec_add (ad->alpha[sender][j], ec_zero, ct[0][j], ec_ctx); |
746 | gcry_mpi_ec_add (ad->beta[sender_index][j], ec_zero, ct[1][j], ec_ctx); | 786 | gcry_mpi_ec_add (ad->beta[sender][j], ec_zero, ct[1][j], ec_ctx); |
747 | } | 787 | } |
748 | smc_free2 (ct, 2, ad->k); | 788 | smc_free2 (ct, 2, ad->k); |
749 | 789 | ||
@@ -759,21 +799,201 @@ quit: | |||
759 | * smc_compute_outcome \todo | 799 | * smc_compute_outcome \todo |
760 | * | 800 | * |
761 | * @param ad TODO | 801 | * @param ad TODO |
802 | * @param buflen TODO | ||
762 | */ | 803 | */ |
763 | void | 804 | unsigned char * |
764 | smc_compute_outcome (struct AuctionData *ad) | 805 | smc_compute_outcome (struct AuctionData *ad, size_t *buflen) |
765 | { | 806 | { |
766 | uint16_t i; | 807 | unsigned char *ret; |
767 | uint16_t j; | 808 | unsigned char *cur; |
809 | gcry_mpi_point_t tmpa = gcry_mpi_point_new (0); | ||
810 | gcry_mpi_point_t tmpb = gcry_mpi_point_new (0); | ||
811 | gcry_mpi_point_t *tlta1; | ||
812 | gcry_mpi_point_t *tltb1; | ||
813 | gcry_mpi_point_t **tlta2; | ||
814 | gcry_mpi_point_t **tltb2; | ||
815 | gcry_mpi_point_t **tlta3; | ||
816 | gcry_mpi_point_t **tltb3; | ||
817 | struct ec_mpi *gamma; | ||
818 | struct ec_mpi *delta; | ||
819 | struct proof_2dle *proof2; | ||
768 | 820 | ||
769 | // create temporary table with partial sums | 821 | brandt_assert (ad && buflen); |
770 | 822 | ||
823 | *buflen = (ad->n * ad->k * /* nk * (gamma, delta, proof2) */ | ||
824 | (sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2))); | ||
825 | if (NULL == (cur = (ret = calloc (1, *buflen))) || | ||
826 | NULL == (ad->gamma = smc_init3 (ad->n, ad->n, ad->k)) || | ||
827 | NULL == (ad->delta = smc_init3 (ad->n, ad->n, ad->k))) | ||
828 | { | ||
829 | weprintf ("unable to alloc memory for first price outcome computation"); | ||
830 | return NULL; | ||
831 | } | ||
832 | |||
833 | /* create temporary lookup tables with partial sums */ | ||
834 | tlta1 = smc_init1 (ad->k); | ||
835 | tltb1 = smc_init1 (ad->k); | ||
836 | tlta2 = smc_init2 (ad->n, ad->k); | ||
837 | tltb2 = smc_init2 (ad->n, ad->k); | ||
838 | tlta3 = smc_init2 (ad->n, ad->k); | ||
839 | tltb3 = smc_init2 (ad->n, ad->k); | ||
840 | |||
841 | /* temporary lookup table for first summand (no one has a higher bid) */ | ||
842 | for (uint16_t i = 0; i < ad->n; i++) | ||
843 | { | ||
844 | smc_sums_partial (tlta2[i], ad->alpha[i], ad->k, 1, 1); | ||
845 | smc_sums_partial (tltb2[i], ad->beta[i], ad->k, 1, 1); | ||
846 | for (uint16_t j = 0; j < ad->k; j++) | ||
847 | { | ||
848 | gcry_mpi_ec_sub (tlta3[i][j], | ||
849 | tlta2[i][ad->k - 1], | ||
850 | tlta2[i][j], | ||
851 | ec_ctx); | ||
852 | gcry_mpi_ec_sub (tltb3[i][j], | ||
853 | tltb2[i][ad->k - 1], | ||
854 | tltb2[i][j], | ||
855 | ec_ctx); | ||
856 | } | ||
857 | brandt_assert (!ec_point_cmp (ec_zero, tlta3[i][ad->k - 1])); | ||
858 | brandt_assert (!ec_point_cmp (ec_zero, tltb3[i][ad->k - 1])); | ||
859 | } | ||
860 | for (uint16_t j = 0; j < ad->k; j++) | ||
861 | { | ||
862 | smc_sum (tlta1[j], &tlta3[0][j], ad->n, ad->k); | ||
863 | smc_sum (tltb1[j], &tltb3[0][j], ad->n, ad->k); | ||
864 | } | ||
865 | brandt_assert (!ec_point_cmp (ec_zero, tlta1[ad->k - 1])); | ||
866 | brandt_assert (!ec_point_cmp (ec_zero, tltb1[ad->k - 1])); | ||
867 | /* \todo: merge into one nested i,j loop and one nested j,i loop? */ | ||
868 | |||
869 | /* temporary lookup table for second summand (my bid is not lower) */ | ||
870 | for (uint16_t i = 0; i < ad->n; i++) | ||
871 | { | ||
872 | for (uint16_t j = 0; j < ad->k; j++) | ||
873 | { | ||
874 | gcry_mpi_ec_sub (tlta2[i][j], tlta2[i][j], ad->alpha[i][j], ec_ctx); | ||
875 | gcry_mpi_ec_sub (tltb2[i][j], tltb2[i][j], ad->beta[i][j], ec_ctx); | ||
876 | } | ||
877 | brandt_assert (!ec_point_cmp (ec_zero, tlta2[i][0])); | ||
878 | brandt_assert (!ec_point_cmp (ec_zero, tltb2[i][0])); | ||
879 | } | ||
880 | |||
881 | /* temporary lookup table for third summand (no one with a lower index has | ||
882 | * the same bid) */ | ||
883 | for (uint16_t j = 0; j < ad->k; j++) | ||
884 | { | ||
885 | smc_sums_partial (&tlta3[0][j], &ad->alpha[0][j], ad->n, ad->k, ad->k); | ||
886 | smc_sums_partial (&tltb3[0][j], &ad->beta[0][j], ad->n, ad->k, ad->k); | ||
887 | for (uint16_t i = 0; i < ad->n; i++) | ||
888 | { | ||
889 | gcry_mpi_ec_sub (tlta3[i][j], tlta3[i][j], ad->alpha[i][j], ec_ctx); | ||
890 | gcry_mpi_ec_sub (tltb3[i][j], tltb3[i][j], ad->beta[i][j], ec_ctx); | ||
891 | } | ||
892 | brandt_assert (!ec_point_cmp (ec_zero, tlta3[0][j])); | ||
893 | brandt_assert (!ec_point_cmp (ec_zero, tltb3[0][j])); | ||
894 | } | ||
895 | |||
896 | for (uint16_t i = 0; i < ad->n; i++) | ||
897 | { | ||
898 | for (uint16_t j = 0; j < ad->k; j++) | ||
899 | { | ||
900 | gamma = (struct ec_mpi *)cur; | ||
901 | delta = &((struct ec_mpi *)cur)[1]; | ||
902 | proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi)); | ||
903 | |||
904 | /* compute inner gamma */ | ||
905 | gcry_mpi_ec_add (tmpa, tlta1[j], tlta2[i][j], ec_ctx); | ||
906 | gcry_mpi_ec_add (tmpa, tmpa, tlta3[i][j], ec_ctx); | ||
907 | |||
908 | /* compute inner delta */ | ||
909 | gcry_mpi_ec_add (tmpb, tltb1[j], tltb2[i][j], ec_ctx); | ||
910 | gcry_mpi_ec_add (tmpb, tmpb, tltb3[i][j], ec_ctx); | ||
911 | |||
912 | /* copy unmasked outcome to all other bidder layers so they don't | ||
913 | * have to be recomputed to check the ZK proof_2dle's from other | ||
914 | * bidders when receiving their outcome messages */ | ||
915 | for (uint16_t a = 0; a < ad->n; a++) | ||
916 | { | ||
917 | /**\todo: how to copy a point more efficiently? */ | ||
918 | gcry_mpi_ec_add (ad->gamma[a][i][j], ec_zero, tmpa, ec_ctx); | ||
919 | gcry_mpi_ec_add (ad->delta[a][i][j], ec_zero, tmpb, ec_ctx); | ||
920 | } | ||
921 | |||
922 | /* apply random masking for losing bidders */ | ||
923 | smc_zkp_2dle (ad->gamma[ad->i][i][j], | ||
924 | ad->delta[ad->i][i][j], | ||
925 | tmpa, | ||
926 | tmpb, | ||
927 | NULL, | ||
928 | proof2); | ||
929 | |||
930 | ec_point_serialize (gamma, ad->gamma[ad->i][i][j]); | ||
931 | ec_point_serialize (delta, ad->delta[ad->i][i][j]); | ||
771 | 932 | ||
772 | for (i = 0; i < ad->n; i++) | 933 | cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2); |
934 | } | ||
935 | } | ||
936 | |||
937 | gcry_mpi_point_release (tmpa); | ||
938 | gcry_mpi_point_release (tmpb); | ||
939 | smc_free1 (tlta1, ad->n); | ||
940 | smc_free1 (tltb1, ad->n); | ||
941 | smc_free2 (tlta2, ad->n, ad->k); | ||
942 | smc_free2 (tltb2, ad->n, ad->k); | ||
943 | smc_free2 (tlta3, ad->n, ad->k); | ||
944 | smc_free2 (tltb3, ad->n, ad->k); | ||
945 | return ret; | ||
946 | } | ||
947 | |||
948 | |||
949 | int | ||
950 | smc_recv_outcome (struct AuctionData *ad, | ||
951 | unsigned char *buf, | ||
952 | size_t buflen, | ||
953 | uint16_t sender) | ||
954 | { | ||
955 | int ret = 0; | ||
956 | unsigned char *cur = buf; | ||
957 | struct proof_2dle *proof2; | ||
958 | gcry_mpi_point_t gamma = gcry_mpi_point_new (0); | ||
959 | gcry_mpi_point_t delta = gcry_mpi_point_new (0); | ||
960 | |||
961 | brandt_assert (ad && buf); | ||
962 | |||
963 | if (buflen != (ad->n * ad->k * | ||
964 | (2 * sizeof (struct ec_mpi) + sizeof (*proof2)))) | ||
773 | { | 965 | { |
966 | weprintf ("wrong size of received encrypted bid"); | ||
967 | goto quit; | ||
968 | } | ||
774 | 969 | ||
970 | for (uint16_t i = 0; i < ad->n; i++) | ||
971 | { | ||
972 | for (uint16_t j = 0; j < ad->k; j++) | ||
973 | { | ||
974 | ec_point_parse (gamma, (struct ec_mpi *)cur); | ||
975 | ec_point_parse (delta, &((struct ec_mpi *)cur)[1]); | ||
976 | proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi)); | ||
977 | if (smc_zkp_2dle_check (gamma, | ||
978 | delta, | ||
979 | ad->gamma[sender][i][j], | ||
980 | ad->delta[sender][i][j], | ||
981 | proof2)) | ||
982 | { | ||
983 | weprintf ("wrong zkp2 for gamma, delta received"); | ||
984 | goto quit; | ||
985 | } | ||
986 | gcry_mpi_ec_add (ad->gamma[sender][i][j], gamma, ec_zero, ec_ctx); | ||
987 | gcry_mpi_ec_add (ad->delta[sender][i][j], delta, ec_zero, ec_ctx); | ||
988 | cur += 2 * sizeof (struct ec_mpi) + sizeof (*proof2); | ||
989 | } | ||
775 | } | 990 | } |
776 | /*\todo ZKP*/ | 991 | |
992 | ret = 1; | ||
993 | quit: | ||
994 | gcry_mpi_point_release (gamma); | ||
995 | gcry_mpi_point_release (delta); | ||
996 | return ret; | ||
777 | } | 997 | } |
778 | 998 | ||
779 | 999 | ||
@@ -885,7 +1105,8 @@ smc_zkp_dl_check (const gcry_mpi_point_t v, | |||
885 | * Must be known to the verifier. | 1105 | * Must be known to the verifier. |
886 | * @param[in] g1 first base point. Must be known to the verifier. | 1106 | * @param[in] g1 first base point. Must be known to the verifier. |
887 | * @param[in] g2 second base point. Must be known to the verifier. | 1107 | * @param[in] g2 second base point. Must be known to the verifier. |
888 | * @param[in] x private number to prove knowledge of. | 1108 | * @param[in] x private number to prove knowledge of. May be NULL if not used by |
1109 | * the caller. | ||
889 | * @param[out] proof pointer where to save the output proof structure. Must be | 1110 | * @param[out] proof pointer where to save the output proof structure. Must be |
890 | * shared with the verifier. | 1111 | * shared with the verifier. |
891 | */ | 1112 | */ |
@@ -901,6 +1122,7 @@ smc_zkp_2dle (gcry_mpi_point_t v, | |||
901 | struct brandt_hash_code challhash; | 1122 | struct brandt_hash_code challhash; |
902 | gcry_mpi_point_t rv; | 1123 | gcry_mpi_point_t rv; |
903 | gcry_mpi_point_t rw; | 1124 | gcry_mpi_point_t rw; |
1125 | gcry_mpi_t rx; | ||
904 | gcry_mpi_point_t a = gcry_mpi_point_new (0); | 1126 | gcry_mpi_point_t a = gcry_mpi_point_new (0); |
905 | gcry_mpi_point_t b = gcry_mpi_point_new (0); | 1127 | gcry_mpi_point_t b = gcry_mpi_point_new (0); |
906 | gcry_mpi_t r = gcry_mpi_new (0); | 1128 | gcry_mpi_t r = gcry_mpi_new (0); |
@@ -909,12 +1131,16 @@ smc_zkp_2dle (gcry_mpi_point_t v, | |||
909 | 1131 | ||
910 | rv = (NULL == v) ? gcry_mpi_point_new (0) : v; | 1132 | rv = (NULL == v) ? gcry_mpi_point_new (0) : v; |
911 | rw = (NULL == w) ? gcry_mpi_point_new (0) : w; | 1133 | rw = (NULL == w) ? gcry_mpi_point_new (0) : w; |
1134 | rx = (NULL == x) ? gcry_mpi_new (0) : x; | ||
1135 | |||
1136 | if (NULL == x) | ||
1137 | ec_skey_create (rx); | ||
912 | 1138 | ||
913 | /* v = x*g1 */ | 1139 | /* v = x*g1 */ |
914 | gcry_mpi_ec_mul (rv, x, g1, ec_ctx); | 1140 | gcry_mpi_ec_mul (rv, rx, g1, ec_ctx); |
915 | 1141 | ||
916 | /* w = x*g2 */ | 1142 | /* w = x*g2 */ |
917 | gcry_mpi_ec_mul (rw, x, g2, ec_ctx); | 1143 | gcry_mpi_ec_mul (rw, rx, g2, ec_ctx); |
918 | 1144 | ||
919 | /* a = z*g1 */ | 1145 | /* a = z*g1 */ |
920 | ec_keypair_create_base (a, z, g1); | 1146 | ec_keypair_create_base (a, z, g1); |
@@ -934,7 +1160,7 @@ smc_zkp_2dle (gcry_mpi_point_t v, | |||
934 | gcry_mpi_mod (c, c, ec_n); | 1160 | gcry_mpi_mod (c, c, ec_n); |
935 | 1161 | ||
936 | /* r = z + cx */ | 1162 | /* r = z + cx */ |
937 | gcry_mpi_mulm (r, c, x, ec_n); | 1163 | gcry_mpi_mulm (r, c, rx, ec_n); |
938 | gcry_mpi_addm (r, r, z, ec_n); | 1164 | gcry_mpi_addm (r, r, z, ec_n); |
939 | 1165 | ||
940 | mpi_serialize (&proof->r, r); | 1166 | mpi_serialize (&proof->r, r); |
@@ -945,6 +1171,8 @@ smc_zkp_2dle (gcry_mpi_point_t v, | |||
945 | gcry_mpi_point_release (rv); | 1171 | gcry_mpi_point_release (rv); |
946 | if (NULL == w) | 1172 | if (NULL == w) |
947 | gcry_mpi_point_release (rw); | 1173 | gcry_mpi_point_release (rw); |
1174 | if (NULL == x) | ||
1175 | gcry_mpi_release (rx); | ||
948 | gcry_mpi_point_release (a); | 1176 | gcry_mpi_point_release (a); |
949 | gcry_mpi_point_release (b); | 1177 | gcry_mpi_point_release (b); |
950 | gcry_mpi_release (r); | 1178 | gcry_mpi_release (r); |