Support fast modular exponentiation for when your base is roughly the same order of magnitude as the modulo.

This commit is contained in:
2018-04-13 11:51:39 -04:00
parent 551ebeac3b
commit 109e23789a
4 changed files with 30066 additions and 46 deletions

View File

@@ -237,6 +237,25 @@ impl UCN {
eprime >>= 1;
}
}
pub fn fastmodexp(&self, e: &UCN, mu: &BarrettUCN) -> UCN {
let mut b = self.reduce(&mu);
let mut eprime = e.clone();
let mut result = UCN::from(1 as u8);
loop {
if eprime.is_zero() {
return result;
}
if eprime.is_odd() {
result = (result * &b).reduce(&mu);
}
b = (&b * &b).reduce(&mu);
eprime >>= 1;
}
}
}
fn miller_rabin<G: Rng>(g: &mut G, n: &UCN, iters: usize) -> bool {
@@ -1256,5 +1275,21 @@ mod test {
let barrett = b.barrett_u();
(&a % &b) == a.reduce(&barrett)
}
fn fastmodexp(ina: UCN, b: UCN, c: UCN) -> bool {
let mut a = ina.clone();
if c.contents.len() == 0 {
return true;
}
if a.contents.len() > c.contents.len() {
a.contents.resize(c.contents.len(), 0);
}
let cu = c.barrett_u();
let slow = a.modexp(&b, &c);
let fast = a.fastmodexp(&b, &cu);
slow == fast
}
}
}