函数源码 |
Source File:lib\crypto\curve25519-fiat32.c |
Create Date:2022-07-27 07:43:49 |
首页 | Copyright©Brick |
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | void curve25519_generic(u8 out[CURVE25519_KEY_SIZE], const u8 scalar[CURVE25519_KEY_SIZE], const u8 point[CURVE25519_KEY_SIZE]) { fe x1, x2, z2, x3, z3; fe_loose x2l, z2l, x3l; unsigned swap = 0; int pos; u8 e[32]; memcpy (e, scalar, 32); curve25519_clamp_secret(e); /* The following implementation was transcribed to Coq and proven to * correspond to unary scalar multiplication in affine coordinates given * that x1 != 0 is the x coordinate of some point on the curve. It was * also checked in Coq that doing a ladderstep with x1 = x3 = 0 gives * z2' = z3' = 0, and z2 = z3 = 0 gives z2' = z3' = 0. The statement was * quantified over the underlying field, so it applies to Curve25519 * itself and the quadratic twist of Curve25519. It was not proven in * Coq that prime-field arithmetic correctly simulates extension-field * arithmetic on prime-field values. The decoding of the byte array * representation of e was not considered. * * Specification of Montgomery curves in affine coordinates: * * Proof that these form a group that is isomorphic to a Weierstrass * curve: * * Coq transcription and correctness proof of the loop * (where scalarbits=255): * preconditions: 0 <= e < 2^255 (not necessarily e < order), * fe_invert(0) = 0 */ fe_frombytes(&x1, point); fe_1(&x2); fe_0(&z2); fe_copy(&x3, &x1); fe_1(&z3); for (pos = 254; pos >= 0; --pos) { fe tmp0, tmp1; fe_loose tmp0l, tmp1l; /* loop invariant as of right before the test, for the case * where x1 != 0: * pos >= -1; if z2 = 0 then x2 is nonzero; if z3 = 0 then x3 * is nonzero * let r := e >> (pos+1) in the following equalities of * projective points: * to_xz (r*P) === if swap then (x3, z3) else (x2, z2) * to_xz ((r+1)*P) === if swap then (x2, z2) else (x3, z3) * x1 is the nonzero x coordinate of the nonzero * point (r*P-(r+1)*P) */ unsigned b = 1 & (e[pos / 8] >> (pos & 7)); swap ^= b; fe_cswap(&x2, &x3, swap); fe_cswap(&z2, &z3, swap); swap = b; /* Coq transcription of ladderstep formula (called from * transcribed loop): * x1 != 0 <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Curves/Montgomery/XZProofs.v#L217> * x1 = 0 <https://github.com/mit-plv/fiat-crypto/blob/2456d821825521f7e03e65882cc3521795b0320f/src/Curves/Montgomery/XZProofs.v#L147> */ fe_sub(&tmp0l, &x3, &z3); fe_sub(&tmp1l, &x2, &z2); fe_add(&x2l, &x2, &z2); fe_add(&z2l, &x3, &z3); fe_mul_tll(&z3, &tmp0l, &x2l); fe_mul_tll(&z2, &z2l, &tmp1l); fe_sq_tl(&tmp0, &tmp1l); fe_sq_tl(&tmp1, &x2l); fe_add(&x3l, &z3, &z2); fe_sub(&z2l, &z3, &z2); fe_mul_ttt(&x2, &tmp1, &tmp0); fe_sub(&tmp1l, &tmp1, &tmp0); fe_sq_tl(&z2, &z2l); fe_mul121666(&z3, &tmp1l); fe_sq_tl(&x3, &x3l); fe_add(&tmp0l, &tmp0, &z3); fe_mul_ttt(&z3, &x1, &z2); fe_mul_tll(&z2, &tmp1l, &tmp0l); } /* here pos=-1, so r=e, so to_xz (e*P) === if swap then (x3, z3) * else (x2, z2) */ fe_cswap(&x2, &x3, swap); fe_cswap(&z2, &z3, swap); fe_invert(&z2, &z2); fe_mul_ttt(&x2, &x2, &z2); fe_tobytes(out, &x2); memzero_explicit(&x1, sizeof (x1)); memzero_explicit(&x2, sizeof (x2)); memzero_explicit(&z2, sizeof (z2)); memzero_explicit(&x3, sizeof (x3)); memzero_explicit(&z3, sizeof (z3)); memzero_explicit(&x2l, sizeof (x2l)); memzero_explicit(&z2l, sizeof (z2l)); memzero_explicit(&x3l, sizeof (x3l)); memzero_explicit(&e, sizeof (e)); } |