Skip to content

Commit

Permalink
Merge pull request #5925 from SparkiDev/sp_mod_3_perf
Browse files Browse the repository at this point in the history
SP math: rework mod 3
  • Loading branch information
dgarske authored Dec 23, 2022
2 parents 18e04d1 + 162dca8 commit d686f0a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 24 deletions.
50 changes: 32 additions & 18 deletions wolfcrypt/src/sp_int.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
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
/* 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);
/* 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];
}
/* 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. */
Expand Down
26 changes: 20 additions & 6 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit d686f0a

Please sign in to comment.