Skip to content

Commit e55e679

Browse files
committed
mp_sqrtmod_prime: bail early on the check for small values
When using custom curves, only use the first 22 values with the prime to calculate Legendre symbol. The known curves work and defeats long running times when non-prime values are passed in.
1 parent ecf666a commit e55e679

1 file changed

Lines changed: 43 additions & 4 deletions

File tree

wolfcrypt/src/ecc.c

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,9 @@ static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
13461346
!defined(WOLFSSL_CRYPTOCELL)
13471347

13481348
#ifndef WOLFSSL_SP_MATH
1349+
#if !defined(SQRTMOD_USE_MOD_EXP)
13491350
static int mp_jacobi(mp_int* a, mp_int* n, int* c);
1351+
#endif
13501352
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
13511353
#endif
13521354
#endif
@@ -14480,6 +14482,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
1448014482
!defined(WOLFSSL_CRYPTOCELL)
1448114483

1448214484
#ifndef WOLFSSL_SP_MATH
14485+
#if !defined(SQRTMOD_USE_MOD_EXP)
1448314486
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
1448414487
*/
1448514488
static int mp_jacobi(mp_int* a, mp_int* n, int* c)
@@ -14599,6 +14602,7 @@ static int mp_jacobi(mp_int* a, mp_int* n, int* c)
1459914602

1460014603
return res;
1460114604
}
14605+
#endif /* !SQRTMOD_USE_MOD_EXP */
1460214606

1460314607

1460414608
/* Solves the modular equation x^2 = n (mod p)
@@ -14608,18 +14612,44 @@ static int mp_jacobi(mp_int* a, mp_int* n, int* c)
1460814612
*/
1460914613
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
1461014614
{
14611-
#ifdef SQRTMOD_USE_MOD_EXP
14615+
#if defined(SQRTMOD_USE_MOD_EXP)
1461214616
int res;
14613-
14617+
mp_digit i;
1461414618
mp_int e;
1461514619

14620+
/* first handle the simple cases n = 0 or n = 1 */
14621+
if (mp_cmp_d(n, 0) == MP_EQ) {
14622+
mp_zero(ret);
14623+
return MP_OKAY;
14624+
}
14625+
if (mp_cmp_d(n, 1) == MP_EQ) {
14626+
return mp_set(ret, 1);
14627+
}
14628+
14629+
if (mp_iseven(prime)) {
14630+
return MP_VAL;
14631+
}
14632+
1461614633
SAVE_VECTOR_REGISTERS(return _svr_ret;);
1461714634

1461814635
res = mp_init(&e);
1461914636
if (res == MP_OKAY)
14637+
res = mp_mod_d(prime, 8, &i);
14638+
if (res == MP_OKAY && i == 1) {
14639+
return MP_VAL;
14640+
}
14641+
/* prime mod 8 = 5 */
14642+
else if (res == MP_OKAY && i == 5) {
14643+
res = mp_sub_d(prime, 1, &e);
14644+
if (res == MP_OKAY)
14645+
res = mp_div_2d(&e, 2, &e, NULL);
14646+
}
14647+
/* prime mod 4 = 3 */
14648+
else if (res == MP_OKAY && ((i == 3) || (i == 7))) {
1462014649
res = mp_add_d(prime, 1, &e);
14621-
if (res == MP_OKAY)
14622-
res = mp_div_2d(&e, 2, &e, NULL);
14650+
if (res == MP_OKAY)
14651+
res = mp_div_2d(&e, 2, &e, NULL);
14652+
}
1462314653
if (res == MP_OKAY)
1462414654
res = mp_exptmod(n, &e, prime, ret);
1462514655

@@ -14758,6 +14788,15 @@ static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
1475814788
if (res == MP_OKAY && legendre == -1)
1475914789
break;
1476014790

14791+
#if defined(WOLFSSL_CUSTOM_CURVES)
14792+
/* P224R1 succeeds with a value of 11. */
14793+
if (mp_cmp_d(Z, 22) == MP_EQ) {
14794+
/* This is to clamp the loop in case 'prime' is not really prime */
14795+
res = MP_VAL;
14796+
break;
14797+
}
14798+
#endif
14799+
1476114800
/* Z = Z + 1 */
1476214801
if (res == MP_OKAY)
1476314802
res = mp_add_d(Z, 1, Z);

0 commit comments

Comments
 (0)