aboutsummaryrefslogtreecommitdiff
path: root/crypto.c
diff options
context:
space:
mode:
authorMarkus Teich <markus.teich@stusta.mhn.de>2016-06-22 14:22:52 +0200
committerMarkus Teich <markus.teich@stusta.mhn.de>2016-06-22 14:22:52 +0200
commita49b2facee0242ebbeebe30e4f479afbaa381893 (patch)
treefa79e0c55b2f201d1e936d7852f021a0e87495d0 /crypto.c
parent2c63da0ed17dd5403a81c9b8462bd8c1f66ca3d5 (diff)
downloadlibbrandt-a49b2facee0242ebbeebe30e4f479afbaa381893.tar.gz
libbrandt-a49b2facee0242ebbeebe30e4f479afbaa381893.zip
add prologue and round1 including tests
Diffstat (limited to 'crypto.c')
-rw-r--r--crypto.c315
1 files changed, 235 insertions, 80 deletions
diff --git a/crypto.c b/crypto.c
index fa37f5e..d7aafef 100644
--- a/crypto.c
+++ b/crypto.c
@@ -373,12 +373,35 @@ ec_point_parse (gcry_mpi_point_t dst, const struct ec_mpi *src)
373 373
374 374
375/** 375/**
376 * smc_free2 releases all points in @a dst and frees the memory
377 *
378 * @param[in,out] dst The 2 dimensional array to clean up
379 * @param[in] size1 size of the first dimension
380 * @param[in] size2 size of the second dimension
381 */
382static void
383smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2)
384{
385 uint16_t i, j;
386
387 if (NULL == dst)
388 return;
389
390 for (i = 0; i < size1; i++)
391 for (j = 0; j < size2; j++)
392 if (NULL != dst[i][j])
393 gcry_mpi_point_release (dst[i][j]);
394 free (dst);
395}
396
397
398/**
376 * smc_init2 creates a 2 dimensional array of curve points 399 * smc_init2 creates a 2 dimensional array of curve points
377 * 400 *
378 * @param[in] size1 size of the first dimension 401 * @param[in] size1 size of the first dimension
379 * @param[in] size2 size of the second dimension 402 * @param[in] size2 size of the second dimension
380 * @return a pointer to the array. If not used anymore use smc_free2 to reclaim 403 * @return a pointer to the array or NULL on error.
381 * the memory. 404 * If not used anymore use smc_free2 to reclaim the memory.
382 */ 405 */
383static gcry_mpi_point_t ** 406static gcry_mpi_point_t **
384smc_init2 (uint16_t size1, uint16_t size2) 407smc_init2 (uint16_t size1, uint16_t size2)
@@ -387,35 +410,55 @@ smc_init2 (uint16_t size1, uint16_t size2)
387 gcry_mpi_point_t **ret; 410 gcry_mpi_point_t **ret;
388 gcry_mpi_point_t *data; 411 gcry_mpi_point_t *data;
389 412
390 ret = calloc (size1, sizeof (*ret) + size2 * sizeof (**ret)); 413 if (NULL == (ret = calloc (size1, sizeof (*ret) + size2 * sizeof (**ret))))
391 brandt_assert (NULL != ret); 414 {
415 weprintf ("could not alloc memory for 2 dimensional point array");
416 return NULL;
417 }
392 418
393 data = (gcry_mpi_point_t *)&ret[size1]; 419 data = (gcry_mpi_point_t *)&ret[size1];
394 for (i = 0; i < size1; i++) 420 for (i = 0; i < size1; i++)
395 { 421 {
396 ret[i] = &data[i * size2]; 422 ret[i] = &data[i * size2];
397 for (j = 0; j < size2; j++) 423 for (j = 0; j < size2; j++)
398 ret[i][j] = gcry_mpi_point_new (0); 424 {
425 if (NULL == (ret[i][j] = gcry_mpi_point_new (0)))
426 {
427 weprintf ("could not init point in 2 dimensional array. "
428 "out of memory?");
429 smc_free2 (ret, size1, size2);
430 return NULL;
431 }
432 }
399 } 433 }
400 return ret; 434 return ret;
401} 435}
402 436
403 437
404/** 438/**
405 * smc_free2 releases all points in @a dst and frees the memory 439 * smc_free3 releases all points in @a dst and frees the memory
406 * 440 *
407 * @param[in,out] dst The 2 dimensional array to clean up 441 * @param[in,out] dst The 3 dimensional array to clean up
408 * @param[in] size1 size of the first dimension 442 * @param[in] size1 size of the first dimension
409 * @param[in] size2 size of the second dimension 443 * @param[in] size2 size of the second dimension
444 * @param[in] size3 size of the third dimension
410 */ 445 */
411static void 446static void
412smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) 447smc_free3 (gcry_mpi_point_t ***dst,
448 uint16_t size1,
449 uint16_t size2,
450 uint16_t size3)
413{ 451{
414 uint16_t i, j; 452 uint16_t i, j, k;
453
454 if (NULL == dst)
455 return;
415 456
416 for (i = 0; i < size1; i++) 457 for (i = 0; i < size1; i++)
417 for (j = 0; j < size2; j++) 458 for (j = 0; j < size2; j++)
418 gcry_mpi_point_release (dst[i][j]); 459 for (k = 0; k < size3; k++)
460 if (NULL != dst[i][j][k])
461 gcry_mpi_point_release (dst[i][j][k]);
419 free (dst); 462 free (dst);
420} 463}
421 464
@@ -426,8 +469,8 @@ smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2)
426 * @param[in] size1 size of the first dimension 469 * @param[in] size1 size of the first dimension
427 * @param[in] size2 size of the second dimension 470 * @param[in] size2 size of the second dimension
428 * @param[in] size3 size of the third dimension 471 * @param[in] size3 size of the third dimension
429 * @return a pointer to the array. If not used anymore use smc_free3 to reclaim 472 * @return a pointer to the array or NULL on error.
430 * the memory. 473 * If not used anymore use smc_free3 to reclaim the memory.
431 */ 474 */
432static gcry_mpi_point_t *** 475static gcry_mpi_point_t ***
433smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) 476smc_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)
437 gcry_mpi_point_t **layer1; 480 gcry_mpi_point_t **layer1;
438 gcry_mpi_point_t *layer2; 481 gcry_mpi_point_t *layer2;
439 482
440 ret = calloc (size1, sizeof (*ret) + 483 if (NULL == (ret = calloc (size1, sizeof (*ret) +
441 size2 * sizeof (**ret) + 484 size2 * sizeof (**ret) +
442 size2 * size3 * sizeof (***ret)); 485 size2 * size3 * sizeof (***ret))))
443 brandt_assert (NULL != ret); 486 {
487 weprintf ("could not alloc memory for 3 dimensional point array");
488 return NULL;
489 }
444 490
445 layer1 = (gcry_mpi_point_t **)&ret[size1]; 491 layer1 = (gcry_mpi_point_t **)&ret[size1];
446 layer2 = (gcry_mpi_point_t *)&layer1[size1 * size2]; 492 layer2 = (gcry_mpi_point_t *)&layer1[size1 * size2];
@@ -451,7 +497,15 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3)
451 { 497 {
452 layer1[i * size2 + j] = &layer2[(i * size2 + j) * size3]; 498 layer1[i * size2 + j] = &layer2[(i * size2 + j) * size3];
453 for (k = 0; k < size3; k++) 499 for (k = 0; k < size3; k++)
454 ret[i][j][k] = gcry_mpi_point_new (0); 500 {
501 if (NULL == (ret[i][j][k] = gcry_mpi_point_new (0)))
502 {
503 weprintf ("could not init point in 2 dimensional array. "
504 "out of memory?");
505 smc_free3 (ret, size1, size2, size3);
506 return NULL;
507 }
508 }
455 } 509 }
456 } 510 }
457 return ret; 511 return ret;
@@ -459,30 +513,6 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3)
459 513
460 514
461/** 515/**
462 * smc_free3 releases all points in @a dst and frees the memory
463 *
464 * @param[in,out] dst The 3 dimensional array to clean up
465 * @param[in] size1 size of the first dimension
466 * @param[in] size2 size of the second dimension
467 * @param[in] size3 size of the third dimension
468 */
469static void
470smc_free3 (gcry_mpi_point_t ***dst,
471 uint16_t size1,
472 uint16_t size2,
473 uint16_t size3)
474{
475 uint16_t i, j, k;
476
477 for (i = 0; i < size1; i++)
478 for (j = 0; j < size2; j++)
479 for (k = 0; k < size3; k++)
480 gcry_mpi_point_release (dst[i][j][k]);
481 free (dst);
482}
483
484
485/**
486 * smc_sums_partial calculates sums up until the current index and stores them 516 * smc_sums_partial calculates sums up until the current index and stores them
487 * in @a out. \f$\forall i \leq len: out_i=\sum_{h=1}^iin_h\f$ 517 * in @a out. \f$\forall i \leq len: out_i=\sum_{h=1}^iin_h\f$
488 * 518 *
@@ -532,34 +562,70 @@ smc_sum (gcry_mpi_point_t out, gcry_mpi_point_t in[], uint16_t len)
532 * public multiplicative key share 562 * public multiplicative key share
533 * 563 *
534 * @param[in,out] ad Pointer to the AuctionData struct to operate on 564 * @param[in,out] ad Pointer to the AuctionData struct to operate on
535 * @param[out] proof Pointer to where the proof of knowledge should be saved. 565 * @param[out] buflen \todo
536 * Must be allocated memory with apropriate size for one proof struct. 566 * @return \todo
537 */ 567 */
538void 568unsigned char *
539smc_gen_keyshare (struct AuctionData *ad, struct proof_dl *proof) 569smc_gen_keyshare (struct AuctionData *ad, size_t *buflen)
540{ 570{
541 uint16_t i; 571 uint16_t i;
572 unsigned char *ret;
573 struct proof_dl *proof1;
574
575 brandt_assert (ad && buflen);
576 *buflen = (sizeof (struct ec_mpi) + sizeof (*proof1));
577 if (NULL == (ret = calloc (1, *buflen)) ||
578 NULL == (ad->y = calloc (ad->n, sizeof (*ad->y))))
579 {
580 weprintf ("unable to alloc memory for key shares");
581 return NULL;
582 }
542 583
543 ad->y = calloc (ad->n, sizeof (*ad->y)); 584 proof1 = (struct proof_dl *)(ret + sizeof (struct ec_mpi));
544 for (i = 0; i < ad->n; i++) 585 for (i = 0; i < ad->n; i++)
545 ad->y[0] = gcry_mpi_point_new (0); 586 ad->y[i] = gcry_mpi_point_new (0);
546 587
547 ad->x = gcry_mpi_new (0); 588 ad->x = gcry_mpi_new (0);
548 ec_skey_create (ad->x); 589 ec_skey_create (ad->x);
549 smc_zkp_dl (ad->y[ad->i], ad->x, proof); 590 smc_zkp_dl (ad->y[ad->i], ad->x, proof1);
591 ec_point_serialize ((struct ec_mpi *)ret, ad->y[ad->i]);
592 return ret;
550} 593}
551 594
552 595
553/** 596int
554 * smc_compute_pkey calculates the shared public key 597smc_recv_keyshare (struct AuctionData *ad,
555 * 598 unsigned char *buf,
556 * @param[in,out] ad The struct AuctionData used 599 size_t buflen,
557 */ 600 uint16_t sender_index)
558void
559smc_compute_pkey (struct AuctionData *ad)
560{ 601{
561 ad->Y = gcry_mpi_point_new (0); 602 int ret = 0;
562 smc_sum (ad->Y, ad->y, ad->n); 603 struct proof_dl *proof1;
604 gcry_mpi_point_t y = gcry_mpi_point_new (0);
605
606 brandt_assert (ad && buf);
607
608 if (buflen != (sizeof (struct ec_mpi) + sizeof (*proof1)))
609 {
610 weprintf ("wrong size of received key share");
611 goto quit;
612 }
613
614 proof1 = (struct proof_dl *)(buf + sizeof (struct ec_mpi));
615 ec_point_parse (y, (struct ec_mpi *)buf);
616 if (smc_zkp_dl_check (y, proof1))
617 {
618 weprintf ("wrong zkp1 for public key share received");
619 goto quit;
620 }
621
622 /**\todo: how to copy a point more efficiently? */
623 gcry_mpi_ec_add (ad->y[sender_index], ec_zero, y, ec_ctx);
624
625 ret = 1;
626quit:
627 gcry_mpi_point_release (y);
628 return ret;
563} 629}
564 630
565 631
@@ -567,30 +633,119 @@ smc_compute_pkey (struct AuctionData *ad)
567 * smc_encrypt_bid \todo 633 * smc_encrypt_bid \todo
568 * 634 *
569 * @param ad TODO 635 * @param ad TODO
570 * @param j TODO 636 * @param buflen TODO
571 * @param a1 TODO
572 * @param a2 TODO
573 * @param b1 TODO
574 * @param b2 TODO
575 * @param d1 TODO
576 * @param d2 TODO
577 * @param r1 TODO
578 * @param r2 TODO
579 */ 637 */
580void 638unsigned char *
581smc_encrypt_bid (struct AuctionData *ad, 639smc_encrypt_bid (struct AuctionData *ad, size_t *buflen)
582 uint16_t j, 640{
583 gcry_mpi_point_t a1, 641 uint16_t j;
584 gcry_mpi_point_t a2, 642 unsigned char *ret;
585 gcry_mpi_point_t b1, 643 unsigned char *cur;
586 gcry_mpi_point_t b2, 644 struct proof_0og *proof3;
587 gcry_mpi_t d1, 645 gcry_mpi_t r_sum;
588 gcry_mpi_t d2, 646 gcry_mpi_t r_part;
589 gcry_mpi_t r1, 647
590 gcry_mpi_t r2) 648 brandt_assert (ad && buflen);
649 *buflen = (ad->k * /* k * (alpha, beta, proof3) */
650 (sizeof (struct ec_mpi) * 2 + /* alpha, beta */
651 sizeof (*proof3)) +
652 sizeof (struct proof_2dle));
653 if (NULL == (cur = (ret = calloc (1, *buflen))) ||
654 NULL == (ad->alpha = smc_init2 (ad->n, ad->k)) ||
655 NULL == (ad->beta = smc_init2 (ad->n, ad->k)))
656 {
657 weprintf ("unable to alloc memory for encrypted bids");
658 return NULL;
659 }
660
661 ad->Y = gcry_mpi_point_new (0);
662 smc_sum (ad->Y, ad->y, ad->n);
663
664 r_sum = gcry_mpi_new (0);
665 r_part = gcry_mpi_new (0);
666
667 for (j = 0; j < ad->k; j++)
668 {
669 proof3 = (struct proof_0og *)(cur + 2 * sizeof (struct ec_mpi));
670 smc_zkp_0og (j == ad->b, ad->Y, r_part,
671 ad->alpha[ad->i][j], ad->beta[ad->i][j], proof3);
672 ec_point_serialize ((struct ec_mpi *)cur, ad->alpha[ad->i][j]);
673 ec_point_serialize (&((struct ec_mpi *)cur)[1], ad->beta[ad->i][j]);
674 gcry_mpi_addm (r_sum, r_sum, r_part, ec_n);
675 cur += 2 * sizeof (struct ec_mpi) + sizeof (struct proof_0og);
676 }
677 smc_zkp_2dle (NULL, NULL, ad->Y, ec_gen, r_sum, (struct proof_2dle *)cur);
678
679 gcry_mpi_release (r_sum);
680 gcry_mpi_release (r_part);
681
682 return ret;
683}
684
685
686int
687smc_recv_encrypted_bid (struct AuctionData *ad,
688 unsigned char *buf,
689 size_t buflen,
690 uint16_t sender_index)
591{ 691{
592// smc_zkp_0og (ad->alpha[ad->i][j], j == ad->b, ad->Y, 692 int ret = 0;
593// ad->beta[ad->i][j], a1, a2, b1, b2, d1, d2, r1, r2); 693 uint16_t j;
694 unsigned char *cur = buf;
695 struct proof_0og *proof3;
696 gcry_mpi_point_t **ct; /* ciphertexts */
697 gcry_mpi_point_t alpha_sum = gcry_mpi_point_new (0);
698 gcry_mpi_point_t beta_sum = gcry_mpi_point_new (0);
699
700 brandt_assert (ad && buf);
701
702 if (buflen != (ad->k * (sizeof (struct ec_mpi) * 2 + sizeof (*proof3)) +
703 sizeof (struct proof_2dle)) ||
704 NULL == (ct = smc_init2 (2, ad->k)))
705 {
706 weprintf ("wrong size of received encrypted bid");
707 goto quit;
708 }
709
710 gcry_mpi_ec_mul (alpha_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx);
711 gcry_mpi_ec_mul (beta_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx);
712
713 for (j = 0; j < ad->k; j++)
714 {
715 ec_point_parse (ct[0][j], (struct ec_mpi *)cur);
716 ec_point_parse (ct[1][j], &((struct ec_mpi *)cur)[1]);
717 proof3 = (struct proof_0og *)(cur + 2 * sizeof (struct ec_mpi));
718 if (smc_zkp_0og_check (ad->Y, ct[0][j], ct[1][j], proof3))
719 {
720 weprintf ("wrong zkp3 for alpha, beta received");
721 goto quit;
722 }
723 gcry_mpi_ec_add (alpha_sum, alpha_sum, ct[0][j], ec_ctx);
724 gcry_mpi_ec_add (beta_sum, beta_sum, ct[1][j], ec_ctx);
725 cur += 2 * sizeof (struct ec_mpi) + sizeof (struct proof_0og);
726 }
727
728 gcry_mpi_ec_sub (alpha_sum, alpha_sum, ec_gen, ec_ctx);
729 if (smc_zkp_2dle_check (alpha_sum, beta_sum, ad->Y, ec_gen,
730 (struct proof_2dle *)cur))
731 {
732 weprintf ("wrong zkp2 for alpha, beta received");
733 goto quit;
734 }
735
736 for (j = 0; j < ad->k; j++)
737 {
738 /**\todo: how to copy a point more efficiently? */
739 gcry_mpi_ec_add (ad->alpha[sender_index][j], ec_zero, ct[0][j], ec_ctx);
740 gcry_mpi_ec_add (ad->beta[sender_index][j], ec_zero, ct[1][j], ec_ctx);
741 }
742 smc_free2 (ct, 2, ad->k);
743
744 ret = 1; /* finally success */
745quit:
746 gcry_mpi_point_release (alpha_sum);
747 gcry_mpi_point_release (beta_sum);
748 return ret;
594} 749}
595 750
596 751