diff --git a/crypto/bn.c b/crypto/bn.c index 3e3aead74d..e21368bab9 100644 --- a/crypto/bn.c +++ b/crypto/bn.c @@ -762,3 +762,35 @@ void bignum_assign(FAR struct bn *dst, FAR struct bn *src) dst->array[i] = src->array[i]; } } + +void pow_mod_faster(FAR struct bn *a, FAR struct bn *b, + FAR struct bn *n, FAR struct bn *res) +{ + struct bn tmpa; + struct bn tmpb; + struct bn tmp; + bignum_assign(&tmpa, a); + bignum_assign(&tmpb, b); + + bignum_from_int(res, 1); /* r = 1 */ + + while (1) + { + if (tmpb.array[0] & 1) /* if (b % 2) */ + { + bignum_mul(res, &tmpa, &tmp); /* r = r * a % m */ + bignum_mod(&tmp, n, res); + } + + bignum_rshift(&tmpb, &tmp, 1); /* b /= 2 */ + bignum_assign(&tmpb, &tmp); + + if (bignum_is_zero(&tmpb)) + { + break; + } + + bignum_mul(&tmpa, &tmpa, &tmp); + bignum_mod(&tmp, n, &tmpa); + } +} diff --git a/include/crypto/bn.h b/include/crypto/bn.h index 722c318efe..4c0e69a41f 100644 --- a/include/crypto/bn.h +++ b/include/crypto/bn.h @@ -204,4 +204,9 @@ void bignum_isqrt(FAR struct bn *a, FAR struct bn *b); void bignum_assign(FAR struct bn *dst, FAR struct bn *src); +/* CRK_EXP_MOD algorithm */ + +void pow_mod_faster(FAR struct bn *a, FAR struct bn *b, + FAR struct bn *n, FAR struct bn *res); + #endif /* __INCLUDE_CRYPTO_BIGNUM_H */