Merge pull request #4187 from SparkiDev/sp_math_mod_red_fix

SP math: montgomery reduction edge case
pull/4210/head
JacobBarthelmeh 2021-07-15 14:33:26 +07:00 committed by GitHub
commit 6458a8cedd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 4 deletions

View File

@ -11896,10 +11896,12 @@ static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp)
else if (m->used == 4) {
sp_int_digit l;
sp_int_digit h;
sp_int_digit o2;
l = 0;
h = 0;
o = 0;
o2 = 0;
for (i = 0; i < 4; i++) {
mu = mp * a->dp[i];
if ((i == 3) && (mask != 0)) {
@ -11919,15 +11921,17 @@ static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp)
SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[2]);
a->dp[i + 2] = l;
l = h;
h = 0;
h = o2;
o2 = 0;
SP_ASM_ADDC_REG(l, h, o);
SP_ASM_ADDC(l, h, a->dp[i + 3]);
SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[3]);
SP_ASM_MUL_ADD(l, h, o2, mu, m->dp[3]);
a->dp[i + 3] = l;
o = h;
l = h;
h = 0;
}
h = o2;
SP_ASM_ADDC(l, h, a->dp[7]);
a->dp[7] = l;
a->dp[8] = h;
@ -11936,10 +11940,12 @@ static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp)
else if (m->used == 6) {
sp_int_digit l;
sp_int_digit h;
sp_int_digit o2;
l = 0;
h = 0;
o = 0;
o2 = 0;
for (i = 0; i < 6; i++) {
mu = mp * a->dp[i];
if ((i == 5) && (mask != 0)) {
@ -11969,15 +11975,17 @@ static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp)
SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[4]);
a->dp[i + 4] = l;
l = h;
h = 0;
h = o2;
o2 = 0;
SP_ASM_ADDC_REG(l, h, o);
SP_ASM_ADDC(l, h, a->dp[i + 5]);
SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[5]);
SP_ASM_MUL_ADD(l, h, o2, mu, m->dp[5]);
a->dp[i + 5] = l;
o = h;
l = h;
h = 0;
}
h = o2;
SP_ASM_ADDC(l, h, a->dp[11]);
a->dp[11] = l;
a->dp[12] = h;

View File

@ -35851,6 +35851,7 @@ static int mp_test_mont(mp_int* a, mp_int* m, mp_int* n, mp_int* r, WC_RNG* rng)
0x01, 0x9f, 0x13, 0xbd,
0x1f, 0x13d, 0x45, 0x615
};
int bits[] = { 256, 384, 2048, 3072 };
int i;
int j;
@ -35908,6 +35909,31 @@ static int mp_test_mont(mp_int* a, mp_int* m, mp_int* n, mp_int* r, WC_RNG* rng)
}
}
/* Force carries. */
for (i = 0; i < (int)(sizeof(bits) / sizeof(*bits)); i++) {
/* a = 2^(bits*2) - 1 */
mp_zero(a);
mp_set_bit(a, bits[i] * 2);
mp_sub_d(a, 1, a);
/* m = 2^(bits) - 1 */
mp_zero(m);
mp_set_bit(m, bits[i]);
mp_sub_d(m, 1, m);
mp = 1;
/* result = r = 2^(bits) - 1 */
mp_zero(r);
mp_set_bit(r, bits[i]);
mp_sub_d(r, 1, r);
ret = mp_montgomery_reduce(a, m, mp);
if (ret != MP_OKAY)
return -13240;
/* Result is m or 0 if reduced to range of modulus. */
if (mp_cmp(a, r) != MP_EQ && mp_iszero(a) != MP_YES)
return -13241;
}
return 0;
}
#endif