Merge pull request #5925 from SparkiDev/sp_mod_3_perf
SP math: rework mod 3
This commit is contained in:
commit
d686f0a5de
@ -6095,27 +6095,41 @@ static void _sp_div_3(const sp_int* a, sp_int* r, sp_int_digit* rem)
|
||||
|
||||
/* Check whether only mod value needed. */
|
||||
if (r == NULL) {
|
||||
/* Divide starting at most significant word down to least. */
|
||||
for (i = a->used - 1; i >= 0; i--) {
|
||||
/* 2^2 mod 3 = 4 mod 3 = 1.
|
||||
* => 2^(2*n) mod 3 = (2^2 mod 3)^n mod 3 = 1^n mod 3 = 1
|
||||
* => (2^(2*n) * x) mod 3 = (2^(2*n) mod 3) * (x mod 3) = x mod 3
|
||||
*
|
||||
* Calculate mod 3 on sum of digits as SP_WORD_SIZE is a multiple of 2.
|
||||
*/
|
||||
#ifndef SQR_MUL_ASM
|
||||
/* Combine remainder from last operation with this word. */
|
||||
t = ((sp_int_word)tr << SP_WORD_SIZE) | a->dp[i];
|
||||
/* Get top digit after multipling by (2^SP_WORD_SIZE) / 3. */
|
||||
tt = (t * SP_DIV_3_CONST) >> SP_WORD_SIZE;
|
||||
/* Subtract trail division. */
|
||||
tr = (sp_int_digit)(t - (sp_int_word)tt * 3);
|
||||
#else
|
||||
/* Multiply digit by (2^SP_WORD_SIZE) / 3. */
|
||||
SP_ASM_MUL(l, tt, a->dp[i], t);
|
||||
/* Add remainder multiplied by (2^SP_WORD_SIZE) / 3 to top digit. */
|
||||
tt += tr * SP_DIV_3_CONST;
|
||||
/* Subtract trail division from digit. */
|
||||
tr = a->dp[i] - (tt * 3);
|
||||
#endif
|
||||
/* tr is 0..5 but need 0..2 */
|
||||
/* Fix up remainder. */
|
||||
tr = sp_rem6[tr];
|
||||
t = 0;
|
||||
/* Sum the digits. */
|
||||
for (i = 0; i < a->used; i++) {
|
||||
t += a->dp[i];
|
||||
}
|
||||
/* Sum digits of sum. */
|
||||
t = (t >> SP_WORD_SIZE) + (t & SP_MASK);
|
||||
/* Get top digit after multipling by (2^SP_WORD_SIZE) / 3. */
|
||||
tt = (t * SP_DIV_3_CONST) >> SP_WORD_SIZE;
|
||||
/* Subtract trail division. */
|
||||
tr = (sp_int_digit)(t - (sp_int_word)tt * 3);
|
||||
#else
|
||||
/* Sum the digits. */
|
||||
for (i = 0; i < a->used; i++) {
|
||||
SP_ASM_ADDC_REG(l, tr, a->dp[i]);
|
||||
}
|
||||
/* Sum digits of sum - can get carry. */
|
||||
SP_ASM_ADDC_REG(l, tt, tr);
|
||||
/* Multiply digit by (2^SP_WORD_SIZE) / 3. */
|
||||
SP_ASM_MUL(t, tr, l, t);
|
||||
/* Add remainder multiplied by (2^SP_WORD_SIZE) / 3 to top digit. */
|
||||
tr += tt * SP_DIV_3_CONST;
|
||||
/* Subtract trail division from digit. */
|
||||
tr = l - (tr * 3);
|
||||
#endif
|
||||
/* tr is 0..5 but need 0..2 */
|
||||
/* Fix up remainder. */
|
||||
tr = sp_rem6[tr];
|
||||
*rem = tr;
|
||||
}
|
||||
/* At least result needed - remainder is calculated anyway. */
|
||||
|
@ -41295,12 +41295,13 @@ static int mp_test_mod_2d(mp_int* a, mp_int* r, mp_int* t, WC_RNG* rng)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || \
|
||||
(defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN))
|
||||
static int mp_test_mod_d(mp_int* a)
|
||||
#if (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || defined(WOLFSSL_KEY_GEN)
|
||||
static int mp_test_mod_d(mp_int* a, WC_RNG* rng)
|
||||
{
|
||||
int ret;
|
||||
mp_digit r;
|
||||
mp_digit rem;
|
||||
int i;
|
||||
|
||||
if (mp_set(a, 1) != MP_OKAY)
|
||||
return -13130;
|
||||
@ -41319,6 +41320,20 @@ static int mp_test_mod_d(mp_int* a)
|
||||
if (ret != MP_OKAY)
|
||||
return -13134;
|
||||
|
||||
for (i = MP_MAX_TEST_BYTE_LEN - 16; i <= MP_MAX_TEST_BYTE_LEN; i++) {
|
||||
ret = randNum(a, i, rng, NULL);
|
||||
if (ret != MP_OKAY)
|
||||
return -13135;
|
||||
ret = mp_mod_d(a, 3, &r);
|
||||
if (ret != MP_OKAY)
|
||||
return -13136;
|
||||
ret = mp_div_d(a, 3, a, &rem);
|
||||
if (ret != MP_OKAY)
|
||||
return -13137;
|
||||
if (r != rem)
|
||||
return -13138;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -42006,9 +42021,8 @@ WOLFSSL_TEST_SUBROUTINE int mp_test(void)
|
||||
if ((ret = mp_test_mod_2d(&a, &r1, &p, &rng)) != 0)
|
||||
return ret;
|
||||
#endif
|
||||
#if (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || \
|
||||
(defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN))
|
||||
if ((ret = mp_test_mod_d(&a)) != 0)
|
||||
#if (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || defined(WOLFSSL_KEY_GEN)
|
||||
if ((ret = mp_test_mod_d(&a, &rng)) != 0)
|
||||
return ret;
|
||||
#endif
|
||||
if ((ret = mp_test_mul_sqr(&a, &b, &r1, &r2, &rng)) != 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user