@@ -13,28 +13,32 @@ mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret)
1313{
1414 mp_err err ;
1515 int legendre ;
16- mp_int t1 , C , Q , S , Z , M , T , R , two ;
17- mp_digit i ;
16+ /* The type is "int" because of the types in the mp_int struct.
17+ Don't forget to change them here when you change them there! */
18+ int S , M , i ;
19+ mp_int t1 , C , Q , Z , T , R , two ;
1820
1921 /* first handle the simple cases */
2022 if (mp_cmp_d (n , 0uL ) == MP_EQ ) {
2123 mp_zero (ret );
2224 return MP_OKAY ;
2325 }
24- if (mp_cmp_d (prime , 2uL ) == MP_EQ ) return MP_VAL ; /* prime must be odd */
25- if ((err = mp_kronecker (n , prime , & legendre )) != MP_OKAY ) return err ;
26- if (legendre == -1 ) return MP_VAL ; /* quadratic non-residue mod prime */
26+ /* "prime" must be odd and > 2 */
27+ if (mp_iseven (prime ) || (mp_cmp_d (prime , 3uL ) == MP_LT )) return MP_VAL ;
28+ if ((err = mp_kronecker (n , prime , & legendre )) != MP_OKAY ) return err ;
29+ /* n \not\cong 0 (mod p) and n \cong r^2 (mod p) for some r \in N^+ */
30+ if (legendre != 1 ) return MP_VAL ;
2731
28- if ((err = mp_init_multi (& t1 , & C , & Q , & S , & Z , & M , & T , & R , & two , NULL )) != MP_OKAY ) {
32+ if ((err = mp_init_multi (& t1 , & C , & Q , & Z , & T , & R , & two , NULL )) != MP_OKAY ) {
2933 return err ;
3034 }
3135
3236 /* SPECIAL CASE: if prime mod 4 == 3
3337 * compute directly: err = n^(prime+1)/4 mod prime
3438 * Handbook of Applied Cryptography algorithm 3.36
3539 */
36- if (( err = mp_mod_d ( prime , 4uL , & i )) != MP_OKAY ) goto LBL_END ;
37- if (i == 3u ) {
40+ /* x%4 == x&3 for x in N and x>0 */
41+ if (( prime -> dp [ 0 ] & 3u ) == 3u ) {
3842 if ((err = mp_add_d (prime , 1uL , & t1 )) != MP_OKAY ) goto LBL_END ;
3943 if ((err = mp_div_2 (& t1 , & t1 )) != MP_OKAY ) goto LBL_END ;
4044 if ((err = mp_div_2 (& t1 , & t1 )) != MP_OKAY ) goto LBL_END ;
@@ -49,12 +53,12 @@ mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret)
4953 if ((err = mp_copy (prime , & Q )) != MP_OKAY ) goto LBL_END ;
5054 if ((err = mp_sub_d (& Q , 1uL , & Q )) != MP_OKAY ) goto LBL_END ;
5155 /* Q = prime - 1 */
52- mp_zero ( & S ) ;
56+ S = 0 ;
5357 /* S = 0 */
5458 while (mp_iseven (& Q )) {
5559 if ((err = mp_div_2 (& Q , & Q )) != MP_OKAY ) goto LBL_END ;
5660 /* Q = Q / 2 */
57- if (( err = mp_add_d ( & S , 1uL , & S )) != MP_OKAY ) goto LBL_END ;
61+ S ++ ;
5862 /* S = S + 1 */
5963 }
6064
@@ -63,6 +67,12 @@ mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret)
6367 /* Z = 2 */
6468 for (;;) {
6569 if ((err = mp_kronecker (& Z , prime , & legendre )) != MP_OKAY ) goto LBL_END ;
70+ /* If "prime" (p) is an odd prime Jacobi(k|p) = 0 for k \cong 0 (mod p) */
71+ /* but there is at least one non-quadratic residue before k>=p if p is an odd prime. */
72+ if (legendre == 0 ) {
73+ err = MP_VAL ;
74+ goto LBL_END ;
75+ }
6676 if (legendre == -1 ) break ;
6777 if ((err = mp_add_d (& Z , 1uL , & Z )) != MP_OKAY ) goto LBL_END ;
6878 /* Z = Z + 1 */
@@ -77,7 +87,7 @@ mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret)
7787 /* R = n ^ ((Q + 1) / 2) mod prime */
7888 if ((err = mp_exptmod (n , & Q , prime , & T )) != MP_OKAY ) goto LBL_END ;
7989 /* T = n ^ Q mod prime */
80- if (( err = mp_copy ( & S , & M )) != MP_OKAY ) goto LBL_END ;
90+ M = S ;
8191 /* M = S */
8292 mp_set (& two , 2uL );
8393
@@ -86,16 +96,21 @@ mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret)
8696 i = 0 ;
8797 for (;;) {
8898 if (mp_cmp_d (& t1 , 1uL ) == MP_EQ ) break ;
99+ /* No exponent in the range 0 < i < M found
100+ (M is at least 1 in the first round because "prime" > 2) */
101+ if (M == i ) {
102+ err = MP_VAL ;
103+ goto LBL_END ;
104+ }
89105 if ((err = mp_exptmod (& t1 , & two , prime , & t1 )) != MP_OKAY ) goto LBL_END ;
90106 i ++ ;
91107 }
92- if (i == 0u ) {
108+ if (i == 0 ) {
93109 if ((err = mp_copy (& R , ret )) != MP_OKAY ) goto LBL_END ;
94110 err = MP_OKAY ;
95111 goto LBL_END ;
96112 }
97- if ((err = mp_sub_d (& M , i , & t1 )) != MP_OKAY ) goto LBL_END ;
98- if ((err = mp_sub_d (& t1 , 1uL , & t1 )) != MP_OKAY ) goto LBL_END ;
113+ mp_set_i32 (& t1 , M - i - 1 );
99114 if ((err = mp_exptmod (& two , & t1 , prime , & t1 )) != MP_OKAY ) goto LBL_END ;
100115 /* t1 = 2 ^ (M - i - 1) */
101116 if ((err = mp_exptmod (& C , & t1 , prime , & t1 )) != MP_OKAY ) goto LBL_END ;
@@ -106,12 +121,12 @@ mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret)
106121 /* R = (R * t1) mod prime */
107122 if ((err = mp_mulmod (& T , & C , prime , & T )) != MP_OKAY ) goto LBL_END ;
108123 /* T = (T * C) mod prime */
109- mp_set ( & M , i ) ;
124+ M = i ;
110125 /* M = i */
111126 }
112127
113128LBL_END :
114- mp_clear_multi (& t1 , & C , & Q , & S , & Z , & M , & T , & R , & two , NULL );
129+ mp_clear_multi (& t1 , & C , & Q , & Z , & T , & R , & two , NULL );
115130 return err ;
116131}
117132
0 commit comments