minor optimizations of the modexp builtin
This commit is contained in:
parent
8d04dffe69
commit
ca27234a59
@ -288,9 +288,11 @@ impl Impl for ModexpImpl {
|
||||
let exp = read_num(exp_len);
|
||||
let modulus = read_num(mod_len);
|
||||
|
||||
// calculate modexp: exponentiation by squaring.
|
||||
// calculate modexp: exponentiation by squaring. the `num` crate has pow, but not modular.
|
||||
fn modexp(mut base: BigUint, mut exp: BigUint, modulus: BigUint) -> BigUint {
|
||||
match (base == BigUint::zero(), exp == BigUint::zero()) {
|
||||
use num::Integer;
|
||||
|
||||
match (base.is_zero(), exp.is_zero()) {
|
||||
(_, true) => return BigUint::one(), // n^0 % m
|
||||
(true, false) => return BigUint::zero(), // 0^n % m, n>0
|
||||
(false, false) if modulus <= BigUint::one() => return BigUint::zero(), // a^b % 1 = 0.
|
||||
@ -301,10 +303,9 @@ impl Impl for ModexpImpl {
|
||||
base = base % &modulus;
|
||||
|
||||
// fast path for base divisible by modulus.
|
||||
if base == BigUint::zero() { return result }
|
||||
while exp != BigUint::zero() {
|
||||
// exp has to be on the right here to avoid move.
|
||||
if BigUint::one() & &exp == BigUint::one() {
|
||||
if base.is_zero() { return result }
|
||||
while !exp.is_zero() {
|
||||
if exp.is_odd() {
|
||||
result = (result * &base) % &modulus;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user