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 /crypto.c | |
parent | 2c63da0ed17dd5403a81c9b8462bd8c1f66ca3d5 (diff) | |
download | libbrandt-a49b2facee0242ebbeebe30e4f479afbaa381893.tar.gz libbrandt-a49b2facee0242ebbeebe30e4f479afbaa381893.zip |
add prologue and round1 including tests
Diffstat (limited to 'crypto.c')
-rw-r--r-- | crypto.c | 315 |
1 files changed, 235 insertions, 80 deletions
@@ -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 | */ | ||
382 | static void | ||
383 | smc_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 | */ |
383 | static gcry_mpi_point_t ** | 406 | static gcry_mpi_point_t ** |
384 | smc_init2 (uint16_t size1, uint16_t size2) | 407 | smc_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 | */ |
411 | static void | 446 | static void |
412 | smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) | 447 | smc_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 | */ |
432 | static gcry_mpi_point_t *** | 475 | static gcry_mpi_point_t *** |
433 | smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) | 476 | 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) | |||
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 | */ | ||
469 | static void | ||
470 | smc_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 | */ |
538 | void | 568 | unsigned char * |
539 | smc_gen_keyshare (struct AuctionData *ad, struct proof_dl *proof) | 569 | smc_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 | /** | 596 | int |
554 | * smc_compute_pkey calculates the shared public key | 597 | smc_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) |
558 | void | ||
559 | smc_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; | ||
626 | quit: | ||
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 | */ |
580 | void | 638 | unsigned char * |
581 | smc_encrypt_bid (struct AuctionData *ad, | 639 | smc_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 | |||
686 | int | ||
687 | smc_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 */ | ||
745 | quit: | ||
746 | gcry_mpi_point_release (alpha_sum); | ||
747 | gcry_mpi_point_release (beta_sum); | ||
748 | return ret; | ||
594 | } | 749 | } |
595 | 750 | ||
596 | 751 | ||