SP int: sp_modinv fixes for sizes

sp_invmod with even modulus requires a multiplication by modulus. Don't
let modulus overflow result variable 'r'.
Fix allocation of temporary sp_ints to be correct size.
Add test for maximum modulus size in test.c.

Remove leading spaces on functions so git correctly determines which
function has changed.
Put in Thumb code for more sizes of _sp_mul_*().
This commit is contained in:
Sean Parkinson
2022-01-24 12:05:20 +10:00
parent 198843aa34
commit 3d63e41653
2 changed files with 4498 additions and 4466 deletions

View File

@ -6722,8 +6722,8 @@ int sp_mod(sp_int* a, sp_int* m, sp_int* r)
#endif
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * (a->used + b->used),
NULL, DYNAMIC_TYPE_BIGINT);
t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * (a->used + b->used), NULL,
DYNAMIC_TYPE_BIGINT);
if (t == NULL) {
err = MP_MEM;
}
@ -6800,8 +6800,8 @@ int sp_mod(sp_int* a, sp_int* m, sp_int* r)
#endif
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * (a->used + b->used),
NULL, DYNAMIC_TYPE_BIGINT);
t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * (a->used + b->used), NULL,
DYNAMIC_TYPE_BIGINT);
if (t == NULL) {
err = MP_MEM;
}
@ -9637,14 +9637,17 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r)
sp_int* u = NULL;
sp_int* v = NULL;
sp_int* b = NULL;
sp_int* c = NULL;
sp_int* mm;
int evenMod = 0;
DECL_SP_INT_ARRAY(t, (m == NULL) ? 1 : (m->used + 1), 4);
DECL_SP_INT_ARRAY(t, (m == NULL) ? 1 : (m->used + 1), 3);
DECL_SP_INT(c, (m == NULL) ? 1 : (2 * m->used + 1));
if ((a == NULL) || (m == NULL) || (r == NULL) || (r == m)) {
err = MP_VAL;
}
if ((err == MP_OKAY) && (m->used * 2 > r->size)) {
err = MP_VAL;
}
#ifdef WOLFSSL_SP_INT_NEGATIVE
if ((err == MP_OKAY) && (m->sign == MP_NEG)) {
@ -9652,12 +9655,13 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r)
}
#endif
ALLOC_SP_INT_ARRAY(t, m->used + 1, 4, err, NULL);
ALLOC_SP_INT_ARRAY(t, m->used + 1, 3, err, NULL);
ALLOC_SP_INT(c, 2 * m->used + 1, err, NULL);
if (err == MP_OKAY) {
u = t[0];
v = t[1];
b = t[2];
c = t[3];
/* c allocated separately and larger for even mod case. */
if (_sp_cmp_abs(a, m) != MP_LT) {
err = sp_mod(a, m, r);
@ -9690,9 +9694,9 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r)
}
else {
sp_init_size(u, m->used + 1);
sp_init_size(v, 2*m->used + 1);
sp_init_size(v, m->used + 1);
sp_init_size(b, m->used + 1);
sp_init_size(c, m->used + 1);
sp_init_size(c, 2 * m->used + 1);
if (sp_iseven(m)) {
/* a^-1 mod m = m + ((1 - m*(m^-1 % a)) / a) */
@ -9752,13 +9756,13 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r)
* a^-1 mod m = m + ((1 - m*c) / a)
* => a^-1 mod m = m - ((m*c - 1) / a)
*/
err = sp_mul(c, m, v);
err = sp_mul(c, m, c);
if (err == MP_OKAY) {
_sp_sub_d(v, 1, v);
err = sp_div(v, a, v, NULL);
_sp_sub_d(c, 1, c);
err = sp_div(c, a, c, NULL);
}
if (err == MP_OKAY) {
sp_sub(m, v, r);
sp_sub(m, c, r);
}
}
else {
@ -9766,6 +9770,7 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r)
}
}
FREE_SP_INT(c, NULL);
FREE_SP_INT_ARRAY(t, NULL);
return err;
}
@ -11542,6 +11547,10 @@ int sp_mul_2d(sp_int* a, int e, sp_int* r)
sp_int_digit o = 0;
sp_int_digit t[4];
#if defined(WOLFSSL_SP_ARM_THUMB) && SP_WORD_SIZE == 32
to = 0;
#endif
SP_ASM_SQR(h, l, a->dp[0]);
t[0] = h;
h = 0;
@ -11603,6 +11612,10 @@ int sp_mul_2d(sp_int* a, int e, sp_int* r)
sp_int_digit to;
sp_int_digit t[6];
#if defined(WOLFSSL_SP_ARM_THUMB) && SP_WORD_SIZE == 32
to = 0;
#endif
SP_ASM_SQR(h, l, a->dp[0]);
t[0] = h;
h = 0;

View File

@ -36889,11 +36889,30 @@ static int mp_test_invmod(mp_int* a, mp_int* m, mp_int* r)
if (ret != MP_OKAY)
return -13177;
#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
/* Maximum 'a' */
mp_set(a, 0);
mp_set_bit(a, (r->size / 2)* SP_WORD_SIZE - 1);
mp_sub_d(a, 1, a);
/* Modulus too big. */
mp_set(m, 0);
mp_set_bit(m, (r->size / 2) * SP_WORD_SIZE);
ret = mp_invmod(a, m, r);
if (ret != MP_VAL)
return -13178;
/* Maximum modulus - even. */
mp_set(m, 0);
mp_set_bit(m, (r->size / 2) * SP_WORD_SIZE - 1);
ret = mp_invmod(a, m, r);
if (ret != MP_OKAY)
return -13179;
#endif
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_INT_NEGATIVE)
mp_read_radix(a, "-3", 16);
ret = mp_invmod(a, m, r);
if (ret != MP_OKAY)
return -13178;
return -13180;
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
@ -36901,28 +36920,28 @@ static int mp_test_invmod(mp_int* a, mp_int* m, mp_int* r)
mp_set(m, 3);
ret = mp_invmod_mont_ct(a, m, r, 1);
if (ret != MP_VAL)
return -13179;
return -13190;
mp_set(a, 1);
mp_set(m, 0);
ret = mp_invmod_mont_ct(a, m, r, 1);
if (ret != MP_VAL)
return -13180;
return -13191;
mp_set(a, 1);
mp_set(m, 1);
ret = mp_invmod_mont_ct(a, m, r, 1);
if (ret != MP_VAL)
return -13181;
return -13192;
mp_set(a, 1);
mp_set(m, 2);
ret = mp_invmod_mont_ct(a, m, r, 1);
if (ret != MP_VAL)
return -13182;
return -13193;
mp_set(a, 1);
mp_set(m, 3);
ret = mp_invmod_mont_ct(a, m, r, 1);
if (ret != MP_OKAY)
return -13183;
return -13194;
#endif
return 0;