SP int: fix rework of sp_invmod

Simplify code and check for m mod a == 0 which means there is no
inverse.
This commit is contained in:
Sean Parkinson
2022-01-20 10:27:50 +10:00
parent d668037541
commit b767857abb

View File

@@ -8123,6 +8123,7 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r)
sp_int* v = NULL; sp_int* v = NULL;
sp_int* b = NULL; sp_int* b = NULL;
sp_int* c = NULL; sp_int* c = NULL;
sp_int* mm;
int used = ((m == NULL) || (a == NULL)) ? 1 : int used = ((m == NULL) || (a == NULL)) ? 1 :
((m->used >= a->used) ? m->used + 1 : a->used + 1); ((m->used >= a->used) ? m->used + 1 : a->used + 1);
int evenMod = 0; int evenMod = 0;
@@ -8182,19 +8183,19 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r)
sp_init_size(c, m->used + 1); sp_init_size(c, m->used + 1);
if (sp_iseven(m)) { if (sp_iseven(m)) {
sp_int* ts; /* a^-1 mod m = m + ((1 - m*(m^-1 % a)) / a) */
/* a^-1 mod m = m + (1 - m*(m^-1 % a)) / a mm = a;
* = m - (m*(m^-1 % a) - 1) / a sp_copy(a, u);
*/ sp_mod(m, a, v);
/* Reverse a and m and perform invmod. */ /* v == 0 when a divides m evenly - no inverse. */
ts = a; if (sp_iszero(v)) {
a = m; /* Force u to no inverse answer. */
m = ts; sp_set(u, 0);
sp_copy(m, u); }
sp_mod(a, m, v);
evenMod = 1; evenMod = 1;
} }
else { else {
mm = m;
sp_copy(m, u); sp_copy(m, u);
sp_copy(a, v); sp_copy(a, v);
} }
@@ -8205,28 +8206,28 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r)
if (sp_iseven(u)) { if (sp_iseven(u)) {
sp_div_2(u, u); sp_div_2(u, u);
if (sp_isodd(b)) { if (sp_isodd(b)) {
sp_add(b, m, b); sp_add(b, mm, b);
} }
sp_div_2(b, b); sp_div_2(b, b);
} }
else if (sp_iseven(v)) { else if (sp_iseven(v)) {
sp_div_2(v, v); sp_div_2(v, v);
if (sp_isodd(c)) { if (sp_isodd(c)) {
sp_add(c, m, c); sp_add(c, mm, c);
} }
sp_div_2(c, c); sp_div_2(c, c);
} }
else if (_sp_cmp(u, v) != MP_LT) { else if (_sp_cmp(u, v) != MP_LT) {
sp_sub(u, v, u); sp_sub(u, v, u);
if (_sp_cmp(b, c) == MP_LT) { if (_sp_cmp(b, c) == MP_LT) {
sp_add(b, m, b); sp_add(b, mm, b);
} }
sp_sub(b, c, b); sp_sub(b, c, b);
} }
else { else {
sp_sub(v, u, v); sp_sub(v, u, v);
if (_sp_cmp(c, b) == MP_LT) { if (_sp_cmp(c, b) == MP_LT) {
sp_add(c, m, c); sp_add(c, mm, c);
} }
sp_sub(c, b, c); sp_sub(c, b, c);
} }
@@ -8235,17 +8236,17 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r)
err = MP_VAL; err = MP_VAL;
} }
else if (evenMod) { else if (evenMod) {
/* a and m were reversed and now we need to finish operation. /* Finish operation.
* m - ((m*r - 1) / a) (reverse a and m) * a^-1 mod m = m + ((1 - m*c) / a)
* => a - ((a*r - 1) / m) * => a^-1 mod m = m - ((m*c - 1) / a)
*/ */
err = sp_mul(c, a, v); err = sp_mul(c, m, v);
if (err == MP_OKAY) { if (err == MP_OKAY) {
_sp_sub_d(v, 1, v); _sp_sub_d(v, 1, v);
err = sp_div(v, m, v, NULL); err = sp_div(v, a, v, NULL);
} }
if (err == MP_OKAY) { if (err == MP_OKAY) {
sp_sub(a, v, r); sp_sub(m, v, r);
} }
} }
else { else {