aboutsummaryrefslogtreecommitdiff
path: root/crypto.c
diff options
context:
space:
mode:
authorMarkus Teich <markus.teich@stusta.mhn.de>2016-06-28 16:29:18 +0200
committerMarkus Teich <markus.teich@stusta.mhn.de>2016-06-28 16:29:18 +0200
commitfb2bf04d382da6ec2f823dacaf4962aca713bac6 (patch)
tree61e798df4b817d7843a1e3dce6c01c3ffd4913c8 /crypto.c
parent5dbbef588dc7247570c9c5f9797b38d907313288 (diff)
downloadlibbrandt-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.c380
1 files changed, 304 insertions, 76 deletions
diff --git a/crypto.c b/crypto.c
index b8e995e..bdc5842 100644
--- a/crypto.c
+++ b/crypto.c
@@ -238,18 +238,13 @@ ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b)
238void 238void
239mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src) 239mpi_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 */
371static void
372smc_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 */
391static gcry_mpi_point_t *
392smc_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)
375static void 423static void
376smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) 424smc_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)
400static gcry_mpi_point_t ** 445static gcry_mpi_point_t **
401smc_init2 (uint16_t size1, uint16_t size2) 446smc_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,
472static gcry_mpi_point_t *** 511static gcry_mpi_point_t ***
473smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) 512smc_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 */
524static void 564static void
525smc_sums_partial (gcry_mpi_point_t out[], gcry_mpi_point_t in[], uint16_t len) 565smc_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 */
546static void 588static void
547smc_sum (gcry_mpi_point_t out, gcry_mpi_point_t in[], uint16_t len) 589smc_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)
567unsigned char * 610unsigned char *
568smc_gen_keyshare (struct AuctionData *ad, size_t *buflen) 611smc_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
596smc_recv_keyshare (struct AuctionData *ad, 638smc_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;
625quit: 667quit:
@@ -637,7 +679,6 @@ quit:
637unsigned char * 679unsigned char *
638smc_encrypt_bid (struct AuctionData *ad, size_t *buflen) 680smc_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
690smc_recv_encrypted_bid (struct AuctionData *ad, 731smc_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 */
763void 804unsigned char *
764smc_compute_outcome (struct AuctionData *ad) 805smc_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
949int
950smc_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;
993quit:
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);