From 8315ae892f7d1983cbbbedc445152d9a0acf8038 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 21 Nov 2019 10:15:12 +1000 Subject: [PATCH 1/4] sp_div improved to handle when a has less digits than d --- wolfcrypt/src/sp_int.c | 67 +++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 422614e3d..d384375b2 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -402,13 +402,13 @@ int sp_copy(sp_int* a, sp_int* r) /* creates "a" then copies b into it */ int sp_init_copy (sp_int * a, sp_int * b) { - int res; - if ((res = sp_init(a)) == MP_OKAY) { - if((res = sp_copy (b, a)) != MP_OKAY) { + int err; + if ((err = sp_init(a)) == MP_OKAY) { + if((err = sp_copy (b, a)) != MP_OKAY) { sp_clear(a); } } - return res; + return err; } #endif @@ -635,6 +635,8 @@ static void _sp_mul_d(sp_int* a, sp_int_digit n, sp_int* r, int o) static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) { int err = MP_OKAY; + int ret; + int done = 0; int i; int s; sp_int_word w = 0; @@ -655,8 +657,24 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) if (sp_iszero(d)) err = MP_VAL; + ret = sp_cmp(a, d); + if (ret == MP_LT) { + sp_copy(a, rem); + if (r != NULL) { + sp_set(r, 0); + } + done = 1; + } + else if (ret == MP_EQ) { + sp_set(rem, 0); + if (r != NULL) { + sp_set(r, 1); + } + done = 1; + } + #ifdef WOLFSSL_SMALL_STACK - if (err == MP_OKAY) { + if (!done && err == MP_OKAY) { sa = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT); if (sa == NULL) err = MP_MEM; @@ -668,7 +686,7 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) } #endif - if (err == MP_OKAY) { + if (!done && err == MP_OKAY) { sp_init(sa); sp_init(sd); sp_init(tr); @@ -685,26 +703,29 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) } tr->used = sa->used - d->used; - if ((sa->dp[sa->used-1] >> (SP_WORD_SIZE - 1)) == 1) { - _sp_mul_d(d, 1, trial, sa->used - d->used); - if (sp_cmp(sa, trial) != MP_LT) { - tr->used++; - sp_sub(sa, trial, sa); - tr->dp[sa->used - d->used] = 1; - } - } - + sp_clear(tr); dt = d->dp[d->used-1]; for (i = sa->used - 1; i >= d->used; i--) { w = ((sp_int_word)sa->dp[i] << SP_WORD_SIZE) | sa->dp[i-1]; - t = (sp_int_digit)(w / dt); - _sp_mul_d(d, t, trial, i - d->used); - while (sp_cmp(trial, sa) == MP_GT) { - t--; - _sp_mul_d(d, t, trial, i - d->used); + w /= dt; + if (w > (sp_int_digit)-1) { + t = (sp_int_digit)-1; + } + else { + t = (sp_int_digit)w; + } + if (t > 0) { + _sp_mul_d(d, t, trial, i - d->used); + while (sp_cmp(trial, sa) == MP_GT) { + t--; + _sp_mul_d(d, t, trial, i - d->used); + } + sp_sub(sa, trial, sa); + tr->dp[i - d->used] += t; + if (w > (sp_int_digit)-1) { + i++; + } } - sp_sub(sa, trial, sa); - tr->dp[i - d->used] = t; } sp_clamp(tr); @@ -1882,7 +1903,7 @@ int sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng) } #ifndef NO_DH -int sp_exch (sp_int* a, sp_int* b) +int sp_exch(sp_int* a, sp_int* b) { int err = MP_OKAY; #ifndef WOLFSSL_SMALL_STACK From 2ac0ac8776140ea27300af0abefd8f03d8de1418 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 25 Nov 2019 09:14:14 +1000 Subject: [PATCH 2/4] Fix for sp_div when a > d but same bit length --- wolfcrypt/src/sp_int.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index d384375b2..137f75f16 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -672,6 +672,14 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) } done = 1; } + else if (sp_count_bits(a) == sp_count_bits(d)) { + /* a is greater than d but same bit length */ + sp_sub(a, d, rem); + if (r != NULL) { + sp_set(r, 1); + } + done = 1; + } #ifdef WOLFSSL_SMALL_STACK if (!done && err == MP_OKAY) { From dadbeff43375e586e42f614b548d4d2b5288b48e Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 26 Nov 2019 09:55:17 +1000 Subject: [PATCH 3/4] sp_int: When setting digit of 0, set used to 0 --- wolfcrypt/src/sp_int.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 137f75f16..1acda20a3 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -420,8 +420,14 @@ int sp_init_copy (sp_int * a, sp_int * b) */ int sp_set(sp_int* a, sp_int_digit d) { - a->dp[0] = d; - a->used = 1; + if (d == 0) { + a->dp[0] = d; + a->used = 0; + } + else { + a->dp[0] = d; + a->used = 1; + } return MP_OKAY; } From 245a2b7012b1800267eec121808464cece68ea98 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 26 Nov 2019 10:05:09 +1000 Subject: [PATCH 4/4] sp_int: clamp more results --- wolfcrypt/src/sp_int.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 1acda20a3..18d1615a6 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -179,6 +179,7 @@ int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz) for (j++; j < a->size; j++) a->dp[j] = 0; + sp_clamp(a); return MP_OKAY; } @@ -234,6 +235,7 @@ int sp_read_radix(sp_int* a, const char* in, int radix) for (k++; k < a->size; k++) a->dp[k] = 0; } + sp_clamp(a); return err; } @@ -485,6 +487,7 @@ int sp_sub_d(sp_int* a, sp_int_digit d, sp_int* r) } for (++i; i < a->used; i++) r->dp[i] = a->dp[i]; + sp_clamp(r); return MP_OKAY; } @@ -665,14 +668,18 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) ret = sp_cmp(a, d); if (ret == MP_LT) { - sp_copy(a, rem); + if (rem != NULL) { + sp_copy(a, rem); + } if (r != NULL) { sp_set(r, 0); } done = 1; } else if (ret == MP_EQ) { - sp_set(rem, 0); + if (rem != NULL) { + sp_set(rem, 0); + } if (r != NULL) { sp_set(r, 1); } @@ -680,7 +687,9 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) } else if (sp_count_bits(a) == sp_count_bits(d)) { /* a is greater than d but same bit length */ - sp_sub(a, d, rem); + if (rem != NULL) { + sp_sub(a, d, rem); + } if (r != NULL) { sp_set(r, 1); } @@ -718,6 +727,7 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) tr->used = sa->used - d->used; sp_clear(tr); + tr->used = sa->used - d->used; dt = d->dp[d->used-1]; for (i = sa->used - 1; i >= d->used; i--) { w = ((sp_int_word)sa->dp[i] << SP_WORD_SIZE) | sa->dp[i-1]; @@ -835,6 +845,7 @@ int sp_lshd(sp_int* a, int s) XMEMMOVE(a->dp + s, a->dp, a->used * sizeof(sp_int_digit)); a->used += s; XMEMSET(a->dp, 0, s * sizeof(sp_int_digit)); + sp_clamp(a); return MP_OKAY; } @@ -1303,8 +1314,9 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r) sp_int u[1], v[1], t[1], b[1], c[1]; #endif - if (sp_iszero(a) || sp_iszero(m)) + if (sp_iszero(a) || sp_iszero(m)) { err = MP_VAL; + } else if (sp_iseven(m)) { /* a^-1 mod m = m + (1 - m*(m^-1 % a)) / a * = m - (m*(m^-1 % a) - 1) / a