diff options
author | Markus Teich <markus.teich@stusta.mhn.de> | 2016-06-21 23:06:15 +0200 |
---|---|---|
committer | Markus Teich <markus.teich@stusta.mhn.de> | 2016-06-21 23:06:15 +0200 |
commit | 8d717c4b3d126104929aeb5e3a2176dd534e25ea (patch) | |
tree | 65fb80bd331e8ce5991aa723502e7a023cc0b8f6 /crypto.c | |
parent | 584423199339cff2e0ad348df60148672a562fe4 (diff) | |
download | libbrandt-8d717c4b3d126104929aeb5e3a2176dd534e25ea.tar.gz libbrandt-8d717c4b3d126104929aeb5e3a2176dd534e25ea.zip |
use proof structs. fix bug in mpi_serialize
Diffstat (limited to 'crypto.c')
-rw-r--r-- | crypto.c | 340 |
1 files changed, 216 insertions, 124 deletions
@@ -157,19 +157,26 @@ ec_skey_create (gcry_mpi_t skey) | |||
157 | 157 | ||
158 | 158 | ||
159 | /** | 159 | /** |
160 | * ec_keypair_create | 160 | * ec_keypair_create creates a new keypair by creating a random secret key first |
161 | * and multipyling the base point with it to get the public key. | ||
161 | * | 162 | * |
162 | * @param[out] pkey where to store the generated public key | 163 | * @param[out] pkey where to store the generated public key |
163 | * @param[out] skey where to store the generated secret key | 164 | * @param[out] skey where to store the generated secret key. May be NULL if |
165 | * you're not interested in the secret key and just need a random point. | ||
164 | */ | 166 | */ |
165 | void | 167 | void |
166 | ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey) | 168 | ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey) |
167 | { | 169 | { |
170 | gcry_mpi_t sk; | ||
171 | |||
168 | brandt_assert (NULL != pkey); | 172 | brandt_assert (NULL != pkey); |
169 | brandt_assert (NULL != skey); | 173 | sk = (NULL == skey) ? gcry_mpi_new (0) : skey; |
170 | 174 | ||
171 | ec_skey_create (skey); | 175 | ec_skey_create (sk); |
172 | gcry_mpi_ec_mul (pkey, skey, ec_gen, ec_ctx); | 176 | gcry_mpi_ec_mul (pkey, sk, ec_gen, ec_ctx); |
177 | |||
178 | if (NULL == skey) | ||
179 | gcry_mpi_release (sk); | ||
173 | } | 180 | } |
174 | 181 | ||
175 | 182 | ||
@@ -244,19 +251,21 @@ mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src) | |||
244 | { | 251 | { |
245 | size_t rsize = 0; | 252 | size_t rsize = 0; |
246 | unsigned int nbits; | 253 | unsigned int nbits; |
247 | const void *p; | 254 | const void *vp; |
255 | char *cp = (char *)dst; | ||
248 | gcry_error_t rc; | 256 | gcry_error_t rc; |
249 | 257 | ||
258 | |||
250 | if (gcry_mpi_get_flag (src, GCRYMPI_FLAG_OPAQUE)) | 259 | if (gcry_mpi_get_flag (src, GCRYMPI_FLAG_OPAQUE)) |
251 | { | 260 | { |
252 | /* Store opaque MPIs left aligned into the buffer. Used by Ed25519 point | 261 | /* Store opaque MPIs left aligned into the buffer. Used by Ed25519 point |
253 | * compression */ | 262 | * compression */ |
254 | p = gcry_mpi_get_opaque (src, &nbits); | 263 | vp = gcry_mpi_get_opaque (src, &nbits); |
255 | brandt_assert (p); | 264 | brandt_assert (vp); |
256 | rsize = (nbits + 7) / 8; | 265 | rsize = (nbits + 7) / 8; |
257 | if (rsize > sizeof (struct ec_mpi)) | 266 | if (rsize > sizeof (struct ec_mpi)) |
258 | rsize = sizeof (struct ec_mpi); | 267 | rsize = sizeof (struct ec_mpi); |
259 | memcpy (dst, p, rsize); | 268 | memcpy (dst, vp, rsize); |
260 | if (rsize < sizeof (struct ec_mpi)) | 269 | if (rsize < sizeof (struct ec_mpi)) |
261 | memset (((char *)dst) + rsize, 0, sizeof (struct ec_mpi) - rsize); | 270 | memset (((char *)dst) + rsize, 0, sizeof (struct ec_mpi) - rsize); |
262 | } | 271 | } |
@@ -270,7 +279,7 @@ mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src) | |||
270 | /* Shift the output to the right, if shorter than available space */ | 279 | /* Shift the output to the right, if shorter than available space */ |
271 | if (rsize && rsize < sizeof (struct ec_mpi)) | 280 | if (rsize && rsize < sizeof (struct ec_mpi)) |
272 | { | 281 | { |
273 | memmove (&dst[sizeof (struct ec_mpi) - rsize], dst, rsize); | 282 | memmove (&cp[sizeof (struct ec_mpi) - rsize], dst, rsize); |
274 | memset (dst, 0, sizeof (struct ec_mpi) - rsize); | 283 | memset (dst, 0, sizeof (struct ec_mpi) - rsize); |
275 | } | 284 | } |
276 | } | 285 | } |
@@ -577,8 +586,8 @@ smc_encrypt_bid (struct AuctionData *ad, | |||
577 | gcry_mpi_t r1, | 586 | gcry_mpi_t r1, |
578 | gcry_mpi_t r2) | 587 | gcry_mpi_t r2) |
579 | { | 588 | { |
580 | smc_zkp_0og (ad->alpha[ad->i][j], (j == ad->b ? ec_gen : ec_zero), ad->Y, | 589 | // smc_zkp_0og (ad->alpha[ad->i][j], j == ad->b, ad->Y, |
581 | ad->beta[ad->i][j], a1, a2, b1, b2, d1, d2, r1, r2); | 590 | // ad->beta[ad->i][j], a1, a2, b1, b2, d1, d2, r1, r2); |
582 | } | 591 | } |
583 | 592 | ||
584 | 593 | ||
@@ -604,27 +613,28 @@ smc_compute_outcome (struct AuctionData *ad) | |||
604 | 613 | ||
605 | 614 | ||
606 | /** | 615 | /** |
607 | * smc_zkp_dl | 616 | * smc_zkp_dl creates a proof of knowledge of @a x with \f$v = xg\f$ where |
617 | * \f$g\f$ is the base point on Ed25519. | ||
608 | * | 618 | * |
609 | * @param v \todo | 619 | * @param[in] v input point. Must be known to the verifier. |
610 | * @param g \todo | 620 | * @param[in] x private key. Knowledge of this number is certified in the proof |
611 | * @param x \todo | 621 | * @param[out] proof pointer where to save the output proof structure. Must be |
612 | * @param a \todo | 622 | * shared with the verifier. |
613 | * @param r \todo | ||
614 | */ | 623 | */ |
615 | void | 624 | void |
616 | smc_zkp_dl (const gcry_mpi_point_t v, | 625 | smc_zkp_dl (const gcry_mpi_point_t v, |
617 | const gcry_mpi_point_t g, | ||
618 | const gcry_mpi_t x, | 626 | const gcry_mpi_t x, |
619 | const gcry_mpi_point_t a, | 627 | struct proof_dl *proof) |
620 | gcry_mpi_t r) | ||
621 | { | 628 | { |
622 | struct zkp_challenge_dl challenge; | 629 | struct zkp_challenge_dl challenge; |
623 | struct brandt_hash_code challhash; | 630 | struct brandt_hash_code challhash; |
631 | gcry_mpi_point_t a = gcry_mpi_point_new (0); | ||
632 | gcry_mpi_t r = gcry_mpi_new (0); | ||
624 | gcry_mpi_t c = gcry_mpi_new (0); | 633 | gcry_mpi_t c = gcry_mpi_new (0); |
625 | gcry_mpi_t z = gcry_mpi_new (0); | 634 | gcry_mpi_t z = gcry_mpi_new (0); |
626 | 635 | ||
627 | ec_keypair_create_base (a, z, g); | 636 | /* a = zg */ |
637 | ec_keypair_create (a, z); | ||
628 | 638 | ||
629 | /* compute challenge c */ | 639 | /* compute challenge c */ |
630 | ec_point_serialize (&challenge.g, ec_gen); | 640 | ec_point_serialize (&challenge.g, ec_gen); |
@@ -634,36 +644,44 @@ smc_zkp_dl (const gcry_mpi_point_t v, | |||
634 | mpi_parse (c, (struct ec_mpi *)&challhash); | 644 | mpi_parse (c, (struct ec_mpi *)&challhash); |
635 | gcry_mpi_mod (c, c, ec_n); | 645 | gcry_mpi_mod (c, c, ec_n); |
636 | 646 | ||
647 | /* r = z + cx */ | ||
637 | gcry_mpi_mulm (r, c, x, ec_n); | 648 | gcry_mpi_mulm (r, c, x, ec_n); |
638 | gcry_mpi_addm (r, r, z, ec_n); | 649 | gcry_mpi_addm (r, r, z, ec_n); |
639 | 650 | ||
651 | ec_point_serialize (&proof->a, a); | ||
652 | mpi_serialize (&proof->r, r); | ||
653 | |||
654 | gcry_mpi_point_release (a); | ||
655 | gcry_mpi_release (r); | ||
640 | gcry_mpi_release (c); | 656 | gcry_mpi_release (c); |
641 | gcry_mpi_release (z); | 657 | gcry_mpi_release (z); |
642 | } | 658 | } |
643 | 659 | ||
644 | 660 | ||
645 | /** | 661 | /** |
646 | * smc_zkp_dl_check | 662 | * smc_zkp_dl_check verifies a proof of knowledge of \f$x = ECDL_g(v)\f$ where |
663 | * \f$g\f$ is the base point on Ed25519. | ||
647 | * | 664 | * |
648 | * @param v \todo | 665 | * @param[in] v input point. Received from the prover. |
649 | * @param g \todo | 666 | * @param[in] proof pointer to the proof structure. Received from the prover. |
650 | * @param a \todo | ||
651 | * @param r \todo | ||
652 | * @return 0 if the proof is correct, something else otherwise | 667 | * @return 0 if the proof is correct, something else otherwise |
653 | */ | 668 | */ |
654 | int | 669 | int |
655 | smc_zkp_dl_check (const gcry_mpi_point_t v, | 670 | smc_zkp_dl_check (const gcry_mpi_point_t v, |
656 | const gcry_mpi_point_t g, | 671 | const struct proof_dl *proof) |
657 | const gcry_mpi_point_t a, | ||
658 | const gcry_mpi_t r) | ||
659 | { | 672 | { |
660 | int ret; | 673 | int ret; |
661 | struct zkp_challenge_dl challenge; | 674 | struct zkp_challenge_dl challenge; |
662 | struct brandt_hash_code challhash; | 675 | struct brandt_hash_code challhash; |
676 | gcry_mpi_point_t a = gcry_mpi_point_new (0); | ||
677 | gcry_mpi_t r = gcry_mpi_new (0); | ||
663 | gcry_mpi_t c = gcry_mpi_new (0); | 678 | gcry_mpi_t c = gcry_mpi_new (0); |
664 | gcry_mpi_point_t left = gcry_mpi_point_new (0); | 679 | gcry_mpi_point_t left = gcry_mpi_point_new (0); |
665 | gcry_mpi_point_t right = gcry_mpi_point_new (0); | 680 | gcry_mpi_point_t right = gcry_mpi_point_new (0); |
666 | 681 | ||
682 | ec_point_parse (a, &proof->a); | ||
683 | mpi_parse (r, &proof->r); | ||
684 | |||
667 | /* compute challenge c */ | 685 | /* compute challenge c */ |
668 | ec_point_serialize (&challenge.g, ec_gen); | 686 | ec_point_serialize (&challenge.g, ec_gen); |
669 | ec_point_serialize (&challenge.v, v); | 687 | ec_point_serialize (&challenge.v, v); |
@@ -672,11 +690,14 @@ smc_zkp_dl_check (const gcry_mpi_point_t v, | |||
672 | mpi_parse (c, (struct ec_mpi *)&challhash); | 690 | mpi_parse (c, (struct ec_mpi *)&challhash); |
673 | gcry_mpi_mod (c, c, ec_n); | 691 | gcry_mpi_mod (c, c, ec_n); |
674 | 692 | ||
675 | gcry_mpi_ec_mul (left, r, g, ec_ctx); | 693 | /* rg =? a + cv */ |
694 | gcry_mpi_ec_mul (left, r, ec_gen, ec_ctx); | ||
676 | gcry_mpi_ec_mul (right, c, v, ec_ctx); | 695 | gcry_mpi_ec_mul (right, c, v, ec_ctx); |
677 | gcry_mpi_ec_add (right, a, right, ec_ctx); | 696 | gcry_mpi_ec_add (right, a, right, ec_ctx); |
678 | |||
679 | ret = ec_point_cmp (left, right); | 697 | ret = ec_point_cmp (left, right); |
698 | |||
699 | gcry_mpi_point_release (a); | ||
700 | gcry_mpi_release (r); | ||
680 | gcry_mpi_release (c); | 701 | gcry_mpi_release (c); |
681 | gcry_mpi_point_release (left); | 702 | gcry_mpi_point_release (left); |
682 | gcry_mpi_point_release (right); | 703 | gcry_mpi_point_release (right); |
@@ -686,82 +707,116 @@ smc_zkp_dl_check (const gcry_mpi_point_t v, | |||
686 | 707 | ||
687 | 708 | ||
688 | /** | 709 | /** |
689 | * smc_zkp_2dle \todo | 710 | * smc_zkp_2dle creates a proof that two ECDLs are equal without revealing the |
711 | * ECDL. \f$v=xg_1, w=xg_2\f$ are calculated as well and can be returned to the | ||
712 | * caller if needed. | ||
690 | * | 713 | * |
691 | * @param v TODO | 714 | * @param[out] v first output point. May be NULL if not needed by the caller. |
692 | * @param w TODO | 715 | * Must be known to the verifier. |
693 | * @param g1 TODO | 716 | * @param[out] w second output point. May be NULL if not needed by the caller. |
694 | * @param g2 TODO | 717 | * Must be known to the verifier. |
695 | * @param x TODO | 718 | * @param[in] g1 first base point. Must be known to the verifier. |
696 | * @param a TODO | 719 | * @param[in] g2 second base point. Must be known to the verifier. |
697 | * @param b TODO | 720 | * @param[in] x private number to prove knowledge of. |
698 | * @param r TODO | 721 | * @param[out] proof pointer where to save the output proof structure. Must be |
722 | * shared with the verifier. | ||
699 | */ | 723 | */ |
700 | void | 724 | void |
701 | smc_zkp_2dle (const gcry_mpi_point_t v, | 725 | smc_zkp_2dle (gcry_mpi_point_t v, |
702 | const gcry_mpi_point_t w, | 726 | gcry_mpi_point_t w, |
703 | const gcry_mpi_point_t g1, | 727 | const gcry_mpi_point_t g1, |
704 | const gcry_mpi_point_t g2, | 728 | const gcry_mpi_point_t g2, |
705 | const gcry_mpi_t x, | 729 | const gcry_mpi_t x, |
706 | gcry_mpi_point_t a, | 730 | struct proof_2dle *proof) |
707 | gcry_mpi_point_t b, | ||
708 | gcry_mpi_t r) | ||
709 | { | 731 | { |
710 | struct zkp_challenge_2dle challenge; | 732 | struct zkp_challenge_2dle challenge; |
711 | struct brandt_hash_code challhash; | 733 | struct brandt_hash_code challhash; |
734 | gcry_mpi_point_t rv; | ||
735 | gcry_mpi_point_t rw; | ||
736 | gcry_mpi_point_t a = gcry_mpi_point_new (0); | ||
737 | gcry_mpi_point_t b = gcry_mpi_point_new (0); | ||
738 | gcry_mpi_t r = gcry_mpi_new (0); | ||
712 | gcry_mpi_t c = gcry_mpi_new (0); | 739 | gcry_mpi_t c = gcry_mpi_new (0); |
713 | gcry_mpi_t z = gcry_mpi_new (0); | 740 | gcry_mpi_t z = gcry_mpi_new (0); |
714 | 741 | ||
742 | rv = (NULL == v) ? rv = gcry_mpi_point_new (0) : v; | ||
743 | rw = (NULL == w) ? rw = gcry_mpi_point_new (0) : w; | ||
744 | |||
745 | /* v = x*g1 */ | ||
746 | gcry_mpi_ec_mul (rv, x, g1, ec_ctx); | ||
747 | |||
748 | /* w = x*g2 */ | ||
749 | gcry_mpi_ec_mul (rw, x, g2, ec_ctx); | ||
750 | |||
751 | /* a = z*g1 */ | ||
715 | ec_keypair_create_base (a, z, g1); | 752 | ec_keypair_create_base (a, z, g1); |
753 | |||
754 | /* b = z*g2 */ | ||
716 | gcry_mpi_ec_mul (b, z, g2, ec_ctx); | 755 | gcry_mpi_ec_mul (b, z, g2, ec_ctx); |
717 | 756 | ||
718 | /* compute challenge c */ | 757 | /* compute challenge c */ |
719 | ec_point_serialize (&challenge.g1, g1); | 758 | ec_point_serialize (&challenge.g1, g1); |
720 | ec_point_serialize (&challenge.g2, g2); | 759 | ec_point_serialize (&challenge.g2, g2); |
721 | ec_point_serialize (&challenge.v, v); | 760 | ec_point_serialize (&challenge.v, rv); |
722 | ec_point_serialize (&challenge.w, w); | 761 | ec_point_serialize (&challenge.w, rw); |
723 | ec_point_serialize (&challenge.a, a); | 762 | ec_point_serialize (&challenge.a, a); |
724 | ec_point_serialize (&challenge.b, b); | 763 | ec_point_serialize (&challenge.b, b); |
725 | brandt_hash (&challenge, sizeof (struct zkp_challenge_dl), &challhash); | 764 | brandt_hash (&challenge, sizeof (struct zkp_challenge_dl), &challhash); |
726 | mpi_parse (c, (struct ec_mpi *)&challhash); | 765 | mpi_parse (c, (struct ec_mpi *)&challhash); |
727 | gcry_mpi_mod (c, c, ec_n); | 766 | gcry_mpi_mod (c, c, ec_n); |
728 | 767 | ||
768 | /* r = z + cx */ | ||
729 | gcry_mpi_mulm (r, c, x, ec_n); | 769 | gcry_mpi_mulm (r, c, x, ec_n); |
730 | gcry_mpi_addm (r, r, z, ec_n); | 770 | gcry_mpi_addm (r, r, z, ec_n); |
731 | 771 | ||
772 | mpi_serialize (&proof->r, r); | ||
773 | ec_point_serialize (&proof->a, a); | ||
774 | ec_point_serialize (&proof->b, b); | ||
775 | |||
776 | if (NULL == v) | ||
777 | gcry_mpi_point_release (rv); | ||
778 | if (NULL == w) | ||
779 | gcry_mpi_point_release (rw); | ||
780 | gcry_mpi_point_release (a); | ||
781 | gcry_mpi_point_release (b); | ||
782 | gcry_mpi_release (r); | ||
732 | gcry_mpi_release (c); | 783 | gcry_mpi_release (c); |
733 | gcry_mpi_release (z); | 784 | gcry_mpi_release (z); |
734 | } | 785 | } |
735 | 786 | ||
736 | 787 | ||
737 | /** | 788 | /** |
738 | * smc_zkp_2dle_check \todo | 789 | * smc_zkp_2dle_check verifies a proof of knowledge of \f$x\f$ with \f$v=xg_1\f$ |
790 | * and \f$w=xg_2\f$. | ||
739 | * | 791 | * |
740 | * @param v TODO | 792 | * @param[in] v first input point. |
741 | * @param w TODO | 793 | * @param[in] w second input point. |
742 | * @param g1 TODO | 794 | * @param[in] g1 first base point. |
743 | * @param g2 TODO | 795 | * @param[in] g2 second base point. |
744 | * @param a TODO | 796 | * @param[in] proof pointer to the proof structure. Received from the prover. |
745 | * @param b TODO | 797 | * @return 0 if the proof is correct, something else otherwise |
746 | * @param r TODO | ||
747 | * @return TODO | ||
748 | */ | 798 | */ |
749 | int | 799 | int |
750 | smc_zkp_2dle_check (const gcry_mpi_point_t v, | 800 | smc_zkp_2dle_check (const gcry_mpi_point_t v, |
751 | const gcry_mpi_point_t w, | 801 | const gcry_mpi_point_t w, |
752 | const gcry_mpi_point_t g1, | 802 | const gcry_mpi_point_t g1, |
753 | const gcry_mpi_point_t g2, | 803 | const gcry_mpi_point_t g2, |
754 | const gcry_mpi_point_t a, | 804 | const struct proof_2dle *proof) |
755 | const gcry_mpi_point_t b, | ||
756 | const gcry_mpi_t r) | ||
757 | { | 805 | { |
758 | int ret; | 806 | int ret; |
759 | struct zkp_challenge_2dle challenge; | 807 | struct zkp_challenge_2dle challenge; |
760 | struct brandt_hash_code challhash; | 808 | struct brandt_hash_code challhash; |
809 | gcry_mpi_point_t a = gcry_mpi_point_new (0); | ||
810 | gcry_mpi_point_t b = gcry_mpi_point_new (0); | ||
811 | gcry_mpi_t r = gcry_mpi_new (0); | ||
761 | gcry_mpi_t c = gcry_mpi_new (0); | 812 | gcry_mpi_t c = gcry_mpi_new (0); |
762 | gcry_mpi_point_t left = gcry_mpi_point_new (0); | 813 | gcry_mpi_point_t left = gcry_mpi_point_new (0); |
763 | gcry_mpi_point_t right = gcry_mpi_point_new (0); | 814 | gcry_mpi_point_t right = gcry_mpi_point_new (0); |
764 | 815 | ||
816 | mpi_parse (r, &proof->r); | ||
817 | ec_point_parse (a, &proof->a); | ||
818 | ec_point_parse (b, &proof->b); | ||
819 | |||
765 | /* compute challenge c */ | 820 | /* compute challenge c */ |
766 | ec_point_serialize (&challenge.g1, g1); | 821 | ec_point_serialize (&challenge.g1, g1); |
767 | ec_point_serialize (&challenge.g2, g2); | 822 | ec_point_serialize (&challenge.g2, g2); |
@@ -773,16 +828,21 @@ smc_zkp_2dle_check (const gcry_mpi_point_t v, | |||
773 | mpi_parse (c, (struct ec_mpi *)&challhash); | 828 | mpi_parse (c, (struct ec_mpi *)&challhash); |
774 | gcry_mpi_mod (c, c, ec_n); | 829 | gcry_mpi_mod (c, c, ec_n); |
775 | 830 | ||
831 | /* r*g1 =? a + cv */ | ||
776 | gcry_mpi_ec_mul (left, r, g1, ec_ctx); | 832 | gcry_mpi_ec_mul (left, r, g1, ec_ctx); |
777 | gcry_mpi_ec_mul (right, c, v, ec_ctx); | 833 | gcry_mpi_ec_mul (right, c, v, ec_ctx); |
778 | gcry_mpi_ec_add (right, a, right, ec_ctx); | 834 | gcry_mpi_ec_add (right, a, right, ec_ctx); |
779 | ret = ec_point_cmp (left, right); | 835 | ret = ec_point_cmp (left, right); |
780 | 836 | ||
837 | /* r*g2 =? b + cw */ | ||
781 | gcry_mpi_ec_mul (left, r, g2, ec_ctx); | 838 | gcry_mpi_ec_mul (left, r, g2, ec_ctx); |
782 | gcry_mpi_ec_mul (right, c, w, ec_ctx); | 839 | gcry_mpi_ec_mul (right, c, w, ec_ctx); |
783 | gcry_mpi_ec_add (right, b, right, ec_ctx); | 840 | gcry_mpi_ec_add (right, b, right, ec_ctx); |
784 | ret |= ec_point_cmp (left, right); | 841 | ret |= ec_point_cmp (left, right); |
785 | 842 | ||
843 | gcry_mpi_point_release (a); | ||
844 | gcry_mpi_point_release (b); | ||
845 | gcry_mpi_release (r); | ||
786 | gcry_mpi_release (c); | 846 | gcry_mpi_release (c); |
787 | gcry_mpi_point_release (left); | 847 | gcry_mpi_point_release (left); |
788 | gcry_mpi_point_release (right); | 848 | gcry_mpi_point_release (right); |
@@ -792,55 +852,57 @@ smc_zkp_2dle_check (const gcry_mpi_point_t v, | |||
792 | 852 | ||
793 | 853 | ||
794 | /** | 854 | /** |
795 | * smc_zkp_0og \todo | 855 | * smc_zkp_0og encrypts one of two values and creates a proof that the |
856 | * ciphertext decrypts to either one of those two values without revealing which | ||
857 | * one was encrypted. The two values are the zero point or the base point of the | ||
858 | * Ed25519 curve. Encryption is done via ElGamal: \f$(\alpha,\beta)=(m+ry,rg)\f$ | ||
859 | * where \f$m\f$ is the value to encrypt, \f$y\f$ is the public key and \f$g\f$ | ||
860 | * is the base point. The nonce \f$r\f$ is generated as well and can be returned | ||
861 | * to the caller if he needs it (e.g. for another proof). | ||
796 | * | 862 | * |
797 | * @param alpha TODO | 863 | * @param[in] m_is_gen if true, the base point is encrypted, else the zero point |
798 | * @param m TODO | 864 | * is encrypted. |
799 | * @param y TODO | 865 | * @param[in] y public key to use for encryption. |
800 | * @param beta TODO | 866 | * @param[out] r random number used for encryption. May be NULL if caller |
801 | * @param a1 TODO | 867 | * doesn't need it. |
802 | * @param a2 TODO | 868 | * @param[out] alpha first part of the ciphertext output |
803 | * @param b1 TODO | 869 | * @param[out] beta second part of the ciphertext output |
804 | * @param b2 TODO | 870 | * @param[out] proof pointer where to save the output proof structure. Must be |
805 | * @param d1 TODO | 871 | * shared with the verifier. |
806 | * @param d2 TODO | ||
807 | * @param r1 TODO | ||
808 | * @param r2 TODO | ||
809 | */ | 872 | */ |
810 | void | 873 | void |
811 | smc_zkp_0og (gcry_mpi_point_t alpha, | 874 | smc_zkp_0og (int m_is_gen, |
812 | const gcry_mpi_point_t m, | ||
813 | const gcry_mpi_point_t y, | 875 | const gcry_mpi_point_t y, |
876 | gcry_mpi_t r, | ||
877 | gcry_mpi_point_t alpha, | ||
814 | gcry_mpi_point_t beta, | 878 | gcry_mpi_point_t beta, |
815 | gcry_mpi_point_t a1, | 879 | struct proof_0og *proof) |
816 | gcry_mpi_point_t a2, | ||
817 | gcry_mpi_point_t b1, | ||
818 | gcry_mpi_point_t b2, | ||
819 | gcry_mpi_t d1, | ||
820 | gcry_mpi_t d2, | ||
821 | gcry_mpi_t r1, | ||
822 | gcry_mpi_t r2) | ||
823 | { | 880 | { |
824 | struct zkp_challenge_0og challenge; | 881 | struct zkp_challenge_0og challenge; |
825 | struct brandt_hash_code challhash; | 882 | struct brandt_hash_code challhash; |
883 | gcry_mpi_point_t a1 = gcry_mpi_point_new (0); | ||
884 | gcry_mpi_point_t a2 = gcry_mpi_point_new (0); | ||
885 | gcry_mpi_point_t b1 = gcry_mpi_point_new (0); | ||
886 | gcry_mpi_point_t b2 = gcry_mpi_point_new (0); | ||
887 | gcry_mpi_t d1 = gcry_mpi_new (0); | ||
888 | gcry_mpi_t d2 = gcry_mpi_new (0); | ||
889 | gcry_mpi_t r1 = gcry_mpi_new (0); | ||
890 | gcry_mpi_t r2 = gcry_mpi_new (0); | ||
826 | gcry_mpi_t c = gcry_mpi_new (0); | 891 | gcry_mpi_t c = gcry_mpi_new (0); |
827 | gcry_mpi_t r = gcry_mpi_new (0); | 892 | gcry_mpi_t rr; |
828 | gcry_mpi_t w = gcry_mpi_new (0); | 893 | gcry_mpi_t w = gcry_mpi_new (0); |
829 | int eq0 = !ec_point_cmp (m, ec_zero); | ||
830 | int eqg = !ec_point_cmp (m, ec_gen); | ||
831 | 894 | ||
832 | if (!(eq0 ^ eqg)) | 895 | rr = (NULL == r) ? gcry_mpi_new (0) : r; |
833 | eprintf ("zero knowledge proof: m is neither 0 nor g"); | ||
834 | 896 | ||
835 | /* beta = r*g */ | 897 | /* beta = r*g */ |
836 | ec_keypair_create (beta, r); | 898 | ec_keypair_create (beta, rr); |
837 | gcry_mpi_mod (r, r, ec_n); | 899 | gcry_mpi_mod (rr, rr, ec_n); |
838 | 900 | ||
839 | /* alpha = m + r*y */ | 901 | /* alpha = m + r*y */ |
840 | gcry_mpi_ec_mul (alpha, r, y, ec_ctx); | 902 | gcry_mpi_ec_mul (alpha, rr, y, ec_ctx); |
841 | gcry_mpi_ec_add (alpha, m, alpha, ec_ctx); | 903 | gcry_mpi_ec_add (alpha, m_is_gen ? ec_gen : ec_zero, alpha, ec_ctx); |
842 | 904 | ||
843 | if (eq0) | 905 | if (!m_is_gen) |
844 | { /* m == 0 */ | 906 | { /* m == 0 */ |
845 | ec_keypair_create_base (a1, d1, beta); | 907 | ec_keypair_create_base (a1, d1, beta); |
846 | gcry_mpi_mod (d1, d1, ec_n); | 908 | gcry_mpi_mod (d1, d1, ec_n); |
@@ -900,13 +962,13 @@ smc_zkp_0og (gcry_mpi_point_t alpha, | |||
900 | mpi_parse (c, (struct ec_mpi *)&challhash); | 962 | mpi_parse (c, (struct ec_mpi *)&challhash); |
901 | gcry_mpi_mod (c, c, ec_n); | 963 | gcry_mpi_mod (c, c, ec_n); |
902 | 964 | ||
903 | if (eq0) | 965 | if (!m_is_gen) |
904 | { /* m == 0 */ | 966 | { /* m == 0 */ |
905 | /* d2 = c - d1 */ | 967 | /* d2 = c - d1 */ |
906 | gcry_mpi_subm (d2, c, d1, ec_n); | 968 | gcry_mpi_subm (d2, c, d1, ec_n); |
907 | 969 | ||
908 | /* r2 = w - r*d2 */ | 970 | /* r2 = w - r*d2 */ |
909 | gcry_mpi_mulm (r2, r, d2, ec_n); | 971 | gcry_mpi_mulm (r2, rr, d2, ec_n); |
910 | gcry_mpi_subm (r2, w, r2, ec_n); | 972 | gcry_mpi_subm (r2, w, r2, ec_n); |
911 | } | 973 | } |
912 | else | 974 | else |
@@ -915,53 +977,75 @@ smc_zkp_0og (gcry_mpi_point_t alpha, | |||
915 | gcry_mpi_subm (d1, c, d2, ec_n); | 977 | gcry_mpi_subm (d1, c, d2, ec_n); |
916 | 978 | ||
917 | /* r1 = w - r*d1 */ | 979 | /* r1 = w - r*d1 */ |
918 | gcry_mpi_mulm (r1, r, d1, ec_n); | 980 | gcry_mpi_mulm (r1, rr, d1, ec_n); |
919 | gcry_mpi_subm (r1, w, r1, ec_n); | 981 | gcry_mpi_subm (r1, w, r1, ec_n); |
920 | } | 982 | } |
921 | 983 | ||
984 | ec_point_serialize (&proof->a1, a1); | ||
985 | ec_point_serialize (&proof->a2, a2); | ||
986 | ec_point_serialize (&proof->b1, b1); | ||
987 | ec_point_serialize (&proof->b2, b2); | ||
988 | mpi_serialize (&proof->d1, d1); | ||
989 | mpi_serialize (&proof->d2, d2); | ||
990 | mpi_serialize (&proof->r1, r1); | ||
991 | mpi_serialize (&proof->r2, r2); | ||
992 | |||
993 | gcry_mpi_point_release (a1); | ||
994 | gcry_mpi_point_release (a2); | ||
995 | gcry_mpi_point_release (b1); | ||
996 | gcry_mpi_point_release (b2); | ||
997 | gcry_mpi_release (d1); | ||
998 | gcry_mpi_release (d2); | ||
999 | gcry_mpi_release (r1); | ||
1000 | gcry_mpi_release (r2); | ||
922 | gcry_mpi_release (c); | 1001 | gcry_mpi_release (c); |
923 | gcry_mpi_release (r); | 1002 | if (NULL == r) |
1003 | gcry_mpi_release (rr); | ||
924 | gcry_mpi_release (w); | 1004 | gcry_mpi_release (w); |
925 | } | 1005 | } |
926 | 1006 | ||
927 | 1007 | ||
928 | /** | 1008 | /** |
929 | * smc_zkp_0og_check \todo | 1009 | * smc_zkp_0og_check verifies a proof that \f$(\alpha,\beta\f$ decrypts either |
1010 | * to the base point \f$g\f$ or the zero point. | ||
930 | * | 1011 | * |
931 | * @param alpha TODO | 1012 | * @param[in] y the public key used for encryption |
932 | * @param y TODO | 1013 | * @param[in] alpha first part of the ciphertext |
933 | * @param beta TODO | 1014 | * @param[in] beta second part of the ciphertext |
934 | * @param a1 TODO | 1015 | * @param[in] proof pointer to the proof structure. Received from the prover. |
935 | * @param a2 TODO | 1016 | * @return 0 if the proof is correct, something else otherwise |
936 | * @param b1 TODO | ||
937 | * @param b2 TODO | ||
938 | * @param d1 TODO | ||
939 | * @param d2 TODO | ||
940 | * @param r1 TODO | ||
941 | * @param r2 TODO | ||
942 | * @return TODO | ||
943 | */ | 1017 | */ |
944 | int | 1018 | int |
945 | smc_zkp_0og_check (const gcry_mpi_point_t alpha, | 1019 | smc_zkp_0og_check (const gcry_mpi_point_t y, |
946 | const gcry_mpi_point_t y, | 1020 | const gcry_mpi_point_t alpha, |
947 | const gcry_mpi_point_t beta, | 1021 | const gcry_mpi_point_t beta, |
948 | const gcry_mpi_point_t a1, | 1022 | const struct proof_0og *proof) |
949 | const gcry_mpi_point_t a2, | ||
950 | const gcry_mpi_point_t b1, | ||
951 | const gcry_mpi_point_t b2, | ||
952 | const gcry_mpi_t d1, | ||
953 | const gcry_mpi_t d2, | ||
954 | const gcry_mpi_t r1, | ||
955 | const gcry_mpi_t r2) | ||
956 | { | 1023 | { |
957 | int ret; | 1024 | int ret; |
958 | struct zkp_challenge_0og challenge; | 1025 | struct zkp_challenge_0og challenge; |
959 | struct brandt_hash_code challhash; | 1026 | struct brandt_hash_code challhash; |
1027 | gcry_mpi_point_t a1 = gcry_mpi_point_new (0); | ||
1028 | gcry_mpi_point_t a2 = gcry_mpi_point_new (0); | ||
1029 | gcry_mpi_point_t b1 = gcry_mpi_point_new (0); | ||
1030 | gcry_mpi_point_t b2 = gcry_mpi_point_new (0); | ||
1031 | gcry_mpi_t d1 = gcry_mpi_new (0); | ||
1032 | gcry_mpi_t d2 = gcry_mpi_new (0); | ||
1033 | gcry_mpi_t r1 = gcry_mpi_new (0); | ||
1034 | gcry_mpi_t r2 = gcry_mpi_new (0); | ||
960 | gcry_mpi_t c = gcry_mpi_new (0); | 1035 | gcry_mpi_t c = gcry_mpi_new (0); |
961 | gcry_mpi_t sum = gcry_mpi_new (0); | 1036 | gcry_mpi_t sum = gcry_mpi_new (0); |
962 | gcry_mpi_point_t right = gcry_mpi_point_new (0); | 1037 | gcry_mpi_point_t right = gcry_mpi_point_new (0); |
963 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); | 1038 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); |
964 | 1039 | ||
1040 | ec_point_parse (a1, &proof->a1); | ||
1041 | ec_point_parse (a2, &proof->a2); | ||
1042 | ec_point_parse (b1, &proof->b1); | ||
1043 | ec_point_parse (b2, &proof->b2); | ||
1044 | mpi_parse (d1, &proof->d1); | ||
1045 | mpi_parse (d2, &proof->d2); | ||
1046 | mpi_parse (r1, &proof->r1); | ||
1047 | mpi_parse (r2, &proof->r2); | ||
1048 | |||
965 | /* compute challenge c */ | 1049 | /* compute challenge c */ |
966 | ec_point_serialize (&challenge.g, ec_gen); | 1050 | ec_point_serialize (&challenge.g, ec_gen); |
967 | ec_point_serialize (&challenge.alpha, alpha); | 1051 | ec_point_serialize (&challenge.alpha, alpha); |
@@ -1003,6 +1087,14 @@ smc_zkp_0og_check (const gcry_mpi_point_t alpha, | |||
1003 | gcry_mpi_ec_add (right, right, tmp, ec_ctx); | 1087 | gcry_mpi_ec_add (right, right, tmp, ec_ctx); |
1004 | ret |= ec_point_cmp (b2, right) << 4; | 1088 | ret |= ec_point_cmp (b2, right) << 4; |
1005 | 1089 | ||
1090 | gcry_mpi_point_release (a1); | ||
1091 | gcry_mpi_point_release (a2); | ||
1092 | gcry_mpi_point_release (b1); | ||
1093 | gcry_mpi_point_release (b2); | ||
1094 | gcry_mpi_release (d1); | ||
1095 | gcry_mpi_release (d2); | ||
1096 | gcry_mpi_release (r1); | ||
1097 | gcry_mpi_release (r2); | ||
1006 | gcry_mpi_release (c); | 1098 | gcry_mpi_release (c); |
1007 | gcry_mpi_release (sum); | 1099 | gcry_mpi_release (sum); |
1008 | gcry_mpi_point_release (right); | 1100 | gcry_mpi_point_release (right); |