@@ -20,6 +20,7 @@ use super::Primality;
2020#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
2121pub struct MillerRabin < const L : usize > {
2222 candidate : Uint < L > ,
23+ bit_length : usize ,
2324 montgomery_params : DynResidueParams < L > ,
2425 one : DynResidue < L > ,
2526 minus_one : DynResidue < L > ,
@@ -47,6 +48,7 @@ impl<const L: usize> MillerRabin<L> {
4748
4849 Self {
4950 candidate : * candidate,
51+ bit_length : candidate. bits_vartime ( ) ,
5052 montgomery_params : params,
5153 one,
5254 minus_one,
@@ -61,7 +63,13 @@ impl<const L: usize> MillerRabin<L> {
6163 // otherwise we can return `Composite` right away.
6264
6365 let base = DynResidue :: < L > :: new ( base, self . montgomery_params ) ;
64- let mut test = base. pow ( & self . d ) ;
66+
67+ // Implementation detail: bounded exp gets faster every time we decrease the bound
68+ // by the window length it uses, which is currently 4 bits.
69+ // So even when the bound isn't low enough that the number can fit
70+ // in a smaller number of limbs, there is still a performance gain
71+ // from specifying the bound.
72+ let mut test = base. pow_bounded_exp ( & self . d , self . bit_length ) ;
6573
6674 if test == self . one || test == self . minus_one {
6775 return Primality :: ProbablyPrime ;
0 commit comments