@@ -86,9 +86,17 @@ fn is_prime(n: &BigUint) -> bool {
8686 }
8787 }
8888
89+ // Test a possible Miller-Rabin witness to the compositeness of n.
90+ //
91+ // Computes a**(n-1) (mod n), and checks if the result gives evidence that
92+ // n is composite. Returning false means that n is likely prime, but not
93+ // necessarily.
94+ let n_m1 = n - 1u32 ;
95+ let witness = move |a : & BigUint | !a. modpow ( & n_m1, n) . is_one ( ) ;
96+
8997 // try series of primes as witnesses
9098 for & ( p, u) in & A014233 {
91- if witness ( & BigUint :: from ( p) , n ) {
99+ if witness ( & BigUint :: from ( p) ) {
92100 return false ;
93101 }
94102 if let Some ( n) = n64 {
@@ -104,46 +112,9 @@ fn is_prime(n: &BigUint) -> bool {
104112 let max = n - 3u32 ;
105113 for _ in 0 ..10 {
106114 let w = rng. gen_biguint_below ( & max) + 2u32 ;
107- if witness ( & w, n) {
108- return false ;
109- }
110- }
111- true
112- }
113-
114- /// Test a possible witness to the compositeness of n.
115- ///
116- /// Computes a**(n-1) (mod n), and checks if the result gives evidence that
117- /// n is composite. Returning false means that n is likely prime, but not
118- /// necessarily.
119- #[ cfg( feature = "rand" ) ]
120- fn witness ( a : & BigUint , n : & BigUint ) -> bool {
121- // let n-1 = (2**t)*u, where t ≥ 1 and u is odd
122- // TODO `trailing_zeros` would make this trivial
123- let n_m1 = n - 1u32 ;
124- let ( t, u) = if n_m1. is_even ( ) {
125- let mut t = 1usize ;
126- let mut u = n_m1. clone ( ) >> 1 ;
127- while u. is_even ( ) {
128- t += 1 ;
129- u >>= 1 ;
130- }
131- ( t, u)
132- } else {
133- ( 0 , n_m1. clone ( ) )
134- } ;
135-
136- let mut x = a. modpow ( & u, n) ;
137- if x. is_one ( ) || x == n_m1 {
138- return false ;
139- }
140-
141- for _ in 1 ..t {
142- x = & x * & x % n;
143- if x == n_m1 {
115+ if witness ( & w) {
144116 return false ;
145117 }
146118 }
147-
148119 true
149120}
0 commit comments