num_bigint_dig/
prime.rs

1// https://github.com/RustCrypto/RSA/blob/master/src/prime.rs
2//! Implements probabilistic prime checkers.
3
4use integer::Integer;
5use num_traits::{FromPrimitive, One, ToPrimitive, Zero};
6use rand::rngs::StdRng;
7use rand::SeedableRng;
8
9use crate::algorithms::jacobi;
10use crate::big_digit;
11use crate::bigrand::RandBigInt;
12use crate::Sign::Plus;
13use crate::{BigInt, BigUint, IntoBigUint};
14
15lazy_static! {
16    pub(crate) static ref BIG_1: BigUint = BigUint::one();
17    pub(crate) static ref BIG_2: BigUint = BigUint::from_u64(2).unwrap();
18    pub(crate) static ref BIG_3: BigUint = BigUint::from_u64(3).unwrap();
19    pub(crate) static ref BIG_64: BigUint = BigUint::from_u64(64).unwrap();
20}
21
22const PRIMES_A: u64 = 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 37;
23const PRIMES_B: u64 = 29 * 31 * 41 * 43 * 47 * 53;
24
25/// Records the primes < 64.
26const PRIME_BIT_MASK: u64 = 1 << 2
27    | 1 << 3
28    | 1 << 5
29    | 1 << 7
30    | 1 << 11
31    | 1 << 13
32    | 1 << 17
33    | 1 << 19
34    | 1 << 23
35    | 1 << 29
36    | 1 << 31
37    | 1 << 37
38    | 1 << 41
39    | 1 << 43
40    | 1 << 47
41    | 1 << 53
42    | 1 << 59
43    | 1 << 61;
44
45/// ProbablyPrime reports whether x is probably prime,
46/// applying the Miller-Rabin test with n pseudorandomly chosen bases
47/// as well as a Baillie-PSW test.
48///
49/// If x is prime, ProbablyPrime returns true.
50/// If x is chosen randomly and not prime, ProbablyPrime probably returns false.
51/// The probability of returning true for a randomly chosen non-prime is at most ¼ⁿ.
52///
53/// ProbablyPrime is 100% accurate for inputs less than 2⁶⁴.
54/// See Menezes et al., Handbook of Applied Cryptography, 1997, pp. 145-149,
55/// and FIPS 186-4 Appendix F for further discussion of the error probabilities.
56///
57/// ProbablyPrime is not suitable for judging primes that an adversary may
58/// have crafted to fool the test.
59///
60/// This is a port of `ProbablyPrime` from the go std lib.
61pub fn probably_prime(x: &BigUint, n: usize) -> bool {
62    if x.is_zero() {
63        return false;
64    }
65
66    if x < &*BIG_64 {
67        return (PRIME_BIT_MASK & (1 << x.to_u64().unwrap())) != 0;
68    }
69
70    if x.is_even() {
71        return false;
72    }
73
74    let r_a = &(x % PRIMES_A);
75    let r_b = &(x % PRIMES_B);
76
77    if (r_a % 3u32).is_zero()
78        || (r_a % 5u32).is_zero()
79        || (r_a % 7u32).is_zero()
80        || (r_a % 11u32).is_zero()
81        || (r_a % 13u32).is_zero()
82        || (r_a % 17u32).is_zero()
83        || (r_a % 19u32).is_zero()
84        || (r_a % 23u32).is_zero()
85        || (r_a % 37u32).is_zero()
86        || (r_b % 29u32).is_zero()
87        || (r_b % 31u32).is_zero()
88        || (r_b % 41u32).is_zero()
89        || (r_b % 43u32).is_zero()
90        || (r_b % 47u32).is_zero()
91        || (r_b % 53u32).is_zero()
92    {
93        return false;
94    }
95
96    probably_prime_miller_rabin(x, n + 1, true) && probably_prime_lucas(x)
97}
98
99const NUMBER_OF_PRIMES: usize = 127;
100const PRIME_GAP: [u64; 167] = [
101    2, 2, 4, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, 2, 4, 14, 4, 6,
102    2, 10, 2, 6, 6, 4, 6, 6, 2, 10, 2, 4, 2, 12, 12, 4, 2, 4, 6, 2, 10, 6, 6, 6, 2, 6, 4, 2, 10,
103    14, 4, 2, 4, 14, 6, 10, 2, 4, 6, 8, 6, 6, 4, 6, 8, 4, 8, 10, 2, 10, 2, 6, 4, 6, 8, 4, 2, 4, 12,
104    8, 4, 8, 4, 6, 12, 2, 18, 6, 10, 6, 6, 2, 6, 10, 6, 6, 2, 6, 6, 4, 2, 12, 10, 2, 4, 6, 6, 2,
105    12, 4, 6, 8, 10, 8, 10, 8, 6, 6, 4, 8, 6, 4, 8, 4, 14, 10, 12, 2, 10, 2, 4, 2, 10, 14, 4, 2, 4,
106    14, 4, 2, 4, 20, 4, 8, 10, 8, 4, 6, 6, 14, 4, 6, 6, 8, 6, 12,
107];
108
109const INCR_LIMIT: usize = 0x10000;
110
111/// Calculate the next larger prime, given a starting number `n`.
112pub fn next_prime(n: &BigUint) -> BigUint {
113    if n < &*BIG_2 {
114        return 2u32.into_biguint().unwrap();
115    }
116
117    // We want something larger than our current number.
118    let mut res = n + &*BIG_1;
119
120    // Ensure we are odd.
121    res |= &*BIG_1;
122
123    // Handle values up to 7.
124    if let Some(val) = res.to_u64() {
125        if val < 7 {
126            return res;
127        }
128    }
129
130    let nbits = res.bits();
131    let prime_limit = if nbits / 2 >= NUMBER_OF_PRIMES {
132        NUMBER_OF_PRIMES - 1
133    } else {
134        nbits / 2
135    };
136
137    // Compute the residues modulo small odd primes
138    let mut moduli = vec![BigUint::zero(); prime_limit];
139
140    'outer: loop {
141        let mut prime = 3;
142        for i in 0..prime_limit {
143            moduli[i] = &res % prime;
144            prime += PRIME_GAP[i];
145        }
146
147        // Check residues
148        let mut difference: usize = 0;
149        for incr in (0..INCR_LIMIT as u64).step_by(2) {
150            let mut prime: u64 = 3;
151
152            let mut cancel = false;
153            for i in 0..prime_limit {
154                let r = (&moduli[i] + incr) % prime;
155                prime += PRIME_GAP[i];
156
157                if r.is_zero() {
158                    cancel = true;
159                    break;
160                }
161            }
162
163            if !cancel {
164                res += difference;
165                difference = 0;
166                if probably_prime(&res, 20) {
167                    break 'outer;
168                }
169            }
170
171            difference += 2;
172        }
173
174        res += difference;
175    }
176
177    res
178}
179
180/// Reports whether n passes reps rounds of the Miller-Rabin primality test, using pseudo-randomly chosen bases.
181/// If `force2` is true, one of the rounds is forced to use base 2.
182///
183/// See Handbook of Applied Cryptography, p. 139, Algorithm 4.24.
184pub fn probably_prime_miller_rabin(n: &BigUint, reps: usize, force2: bool) -> bool {
185    // println!("miller-rabin: {}", n);
186    let nm1 = n - &*BIG_1;
187    // determine q, k such that nm1 = q << k
188    let k = nm1.trailing_zeros().unwrap() as usize;
189    let q = &nm1 >> k;
190
191    let nm3 = n - &*BIG_2;
192
193    let mut rng = StdRng::seed_from_u64(n.get_limb(0) as u64);
194
195    'nextrandom: for i in 0..reps {
196        let x = if i == reps - 1 && force2 {
197            BIG_2.clone()
198        } else {
199            rng.gen_biguint_below(&nm3) + &*BIG_2
200        };
201
202        let mut y = x.modpow(&q, n);
203        if y.is_one() || y == nm1 {
204            continue;
205        }
206
207        for _ in 1..k {
208            y = y.modpow(&*BIG_2, n);
209            if y == nm1 {
210                continue 'nextrandom;
211            }
212            if y.is_one() {
213                return false;
214            }
215        }
216        return false;
217    }
218
219    true
220}
221
222/// Reports whether n passes the "almost extra strong" Lucas probable prime test,
223/// using Baillie-OEIS parameter selection. This corresponds to "AESLPSP" on Jacobsen's tables (link below).
224/// The combination of this test and a Miller-Rabin/Fermat test with base 2 gives a Baillie-PSW test.
225///
226///
227/// References:
228///
229/// Baillie and Wagstaff, "Lucas Pseudoprimes", Mathematics of Computation 35(152),
230/// October 1980, pp. 1391-1417, especially page 1401.
231/// http://www.ams.org/journals/mcom/1980-35-152/S0025-5718-1980-0583518-6/S0025-5718-1980-0583518-6.pdf
232///
233/// Grantham, "Frobenius Pseudoprimes", Mathematics of Computation 70(234),
234/// March 2000, pp. 873-891.
235/// http://www.ams.org/journals/mcom/2001-70-234/S0025-5718-00-01197-2/S0025-5718-00-01197-2.pdf
236///
237/// Baillie, "Extra strong Lucas pseudoprimes", OEIS A217719, https://oeis.org/A217719.
238///
239/// Jacobsen, "Pseudoprime Statistics, Tables, and Data", http://ntheory.org/pseudoprimes.html.
240///
241/// Nicely, "The Baillie-PSW Primality Test", http://www.trnicely.net/misc/bpsw.html.
242/// (Note that Nicely's definition of the "extra strong" test gives the wrong Jacobi condition,
243/// as pointed out by Jacobsen.)
244///
245/// Crandall and Pomerance, Prime Numbers: A Computational Perspective, 2nd ed.
246/// Springer, 2005.
247pub fn probably_prime_lucas(n: &BigUint) -> bool {
248    // println!("lucas: {}", n);
249    // Discard 0, 1.
250    if n.is_zero() || n.is_one() {
251        return false;
252    }
253
254    // Two is the only even prime.
255    if n.to_u64() == Some(2) {
256        return false;
257    }
258
259    // Baillie-OEIS "method C" for choosing D, P, Q,
260    // as in https://oeis.org/A217719/a217719.txt:
261    // try increasing P ≥ 3 such that D = P² - 4 (so Q = 1)
262    // until Jacobi(D, n) = -1.
263    // The search is expected to succeed for non-square n after just a few trials.
264    // After more than expected failures, check whether n is square
265    // (which would cause Jacobi(D, n) = 1 for all D not dividing n).
266    let mut p = 3u64;
267    let n_int = BigInt::from_biguint(Plus, n.clone());
268
269    loop {
270        if p > 10000 {
271            // This is widely believed to be impossible.
272            // If we get a report, we'll want the exact number n.
273            panic!("internal error: cannot find (D/n) = -1 for {:?}", n)
274        }
275
276        let d_int = BigInt::from_u64(p * p - 4).unwrap();
277        let j = jacobi(&d_int, &n_int);
278
279        if j == -1 {
280            break;
281        }
282        if j == 0 {
283            // d = p²-4 = (p-2)(p+2).
284            // If (d/n) == 0 then d shares a prime factor with n.
285            // Since the loop proceeds in increasing p and starts with p-2==1,
286            // the shared prime factor must be p+2.
287            // If p+2 == n, then n is prime; otherwise p+2 is a proper factor of n.
288            return n_int.to_i64() == Some(p as i64 + 2);
289        }
290        if p == 40 {
291            // We'll never find (d/n) = -1 if n is a square.
292            // If n is a non-square we expect to find a d in just a few attempts on average.
293            // After 40 attempts, take a moment to check if n is indeed a square.
294            let t1 = n.sqrt();
295            let t1 = &t1 * &t1;
296            if &t1 == n {
297                return false;
298            }
299        }
300
301        p += 1;
302    }
303
304    // Grantham definition of "extra strong Lucas pseudoprime", after Thm 2.3 on p. 876
305    // (D, P, Q above have become Δ, b, 1):
306    //
307    // Let U_n = U_n(b, 1), V_n = V_n(b, 1), and Δ = b²-4.
308    // An extra strong Lucas pseudoprime to base b is a composite n = 2^r s + Jacobi(Δ, n),
309    // where s is odd and gcd(n, 2*Δ) = 1, such that either (i) U_s ≡ 0 mod n and V_s ≡ ±2 mod n,
310    // or (ii) V_{2^t s} ≡ 0 mod n for some 0 ≤ t < r-1.
311    //
312    // We know gcd(n, Δ) = 1 or else we'd have found Jacobi(d, n) == 0 above.
313    // We know gcd(n, 2) = 1 because n is odd.
314    //
315    // Arrange s = (n - Jacobi(Δ, n)) / 2^r = (n+1) / 2^r.
316    let mut s = n + &*BIG_1;
317    let r = s.trailing_zeros().unwrap() as usize;
318    s = &s >> r;
319    let nm2 = n - &*BIG_2; // n - 2
320
321    // We apply the "almost extra strong" test, which checks the above conditions
322    // except for U_s ≡ 0 mod n, which allows us to avoid computing any U_k values.
323    // Jacobsen points out that maybe we should just do the full extra strong test:
324    // "It is also possible to recover U_n using Crandall and Pomerance equation 3.13:
325    // U_n = D^-1 (2V_{n+1} - PV_n) allowing us to run the full extra-strong test
326    // at the cost of a single modular inversion. This computation is easy and fast in GMP,
327    // so we can get the full extra-strong test at essentially the same performance as the
328    // almost extra strong test."
329
330    // Compute Lucas sequence V_s(b, 1), where:
331    //
332    //	V(0) = 2
333    //	V(1) = P
334    //	V(k) = P V(k-1) - Q V(k-2).
335    //
336    // (Remember that due to method C above, P = b, Q = 1.)
337    //
338    // In general V(k) = α^k + β^k, where α and β are roots of x² - Px + Q.
339    // Crandall and Pomerance (p.147) observe that for 0 ≤ j ≤ k,
340    //
341    //	V(j+k) = V(j)V(k) - V(k-j).
342    //
343    // So in particular, to quickly double the subscript:
344    //
345    //	V(2k) = V(k)² - 2
346    //	V(2k+1) = V(k) V(k+1) - P
347    //
348    // We can therefore start with k=0 and build up to k=s in log₂(s) steps.
349    let mut vk = BIG_2.clone();
350    let mut vk1 = BigUint::from_u64(p).unwrap();
351
352    for i in (0..s.bits()).rev() {
353        if is_bit_set(&s, i) {
354            // k' = 2k+1
355            // V(k') = V(2k+1) = V(k) V(k+1) - P
356            let t1 = (&vk * &vk1) + n - p;
357            vk = &t1 % n;
358            // V(k'+1) = V(2k+2) = V(k+1)² - 2
359            let t1 = (&vk1 * &vk1) + &nm2;
360            vk1 = &t1 % n;
361        } else {
362            // k' = 2k
363            // V(k'+1) = V(2k+1) = V(k) V(k+1) - P
364            let t1 = (&vk * &vk1) + n - p;
365            vk1 = &t1 % n;
366            // V(k') = V(2k) = V(k)² - 2
367            let t1 = (&vk * &vk) + &nm2;
368            vk = &t1 % n;
369        }
370    }
371
372    // Now k=s, so vk = V(s). Check V(s) ≡ ±2 (mod n).
373    if vk.to_u64() == Some(2) || vk == nm2 {
374        // Check U(s) ≡ 0.
375        // As suggested by Jacobsen, apply Crandall and Pomerance equation 3.13:
376        //
377        //	U(k) = D⁻¹ (2 V(k+1) - P V(k))
378        //
379        // Since we are checking for U(k) == 0 it suffices to check 2 V(k+1) == P V(k) mod n,
380        // or P V(k) - 2 V(k+1) == 0 mod n.
381        let mut t1 = &vk * p;
382        let mut t2 = &vk1 << 1;
383
384        if t1 < t2 {
385            core::mem::swap(&mut t1, &mut t2);
386        }
387
388        t1 -= t2;
389
390        if (t1 % n).is_zero() {
391            return true;
392        }
393    }
394
395    // Check V(2^t s) ≡ 0 mod n for some 0 ≤ t < r-1.
396    for _ in 0..r - 1 {
397        if vk.is_zero() {
398            return true;
399        }
400
401        // Optimization: V(k) = 2 is a fixed point for V(k') = V(k)² - 2,
402        // so if V(k) = 2, we can stop: we will never find a future V(k) == 0.
403        if vk.to_u64() == Some(2) {
404            return false;
405        }
406
407        // k' = 2k
408        // V(k') = V(2k) = V(k)² - 2
409        let t1 = (&vk * &vk) - &*BIG_2;
410        vk = &t1 % n;
411    }
412
413    false
414}
415
416/// Checks if the i-th bit is set
417#[inline]
418fn is_bit_set(x: &BigUint, i: usize) -> bool {
419    get_bit(x, i) == 1
420}
421
422/// Returns the i-th bit.
423#[inline]
424fn get_bit(x: &BigUint, i: usize) -> u8 {
425    let j = i / big_digit::BITS;
426    // if is out of range of the set words, it is always false.
427    if i >= x.bits() {
428        return 0;
429    }
430
431    (x.get_limb(j) >> (i % big_digit::BITS) & 1) as u8
432}
433
434#[cfg(test)]
435mod tests {
436    use super::*;
437    use alloc::vec::Vec;
438    // use RandBigInt;
439
440    use crate::biguint::ToBigUint;
441
442    lazy_static! {
443        static ref PRIMES: Vec<&'static str> = vec![
444        "2",
445        "3",
446        "5",
447        "7",
448        "11",
449
450        "13756265695458089029",
451        "13496181268022124907",
452        "10953742525620032441",
453        "17908251027575790097",
454
455        // https://golang.org/issue/638
456        "18699199384836356663",
457
458        "98920366548084643601728869055592650835572950932266967461790948584315647051443",
459        "94560208308847015747498523884063394671606671904944666360068158221458669711639",
460
461        // http://primes.utm.edu/lists/small/small3.html
462        "449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163",
463        "230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593",
464        "5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993",
465        "203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123",
466        // ECC primes: http://tools.ietf.org/html/draft-ladd-safecurves-02
467        "3618502788666131106986593281521497120414687020801267626233049500247285301239",                                                                                  // Curve1174: 2^251-9
468        "57896044618658097711785492504343953926634992332820282019728792003956564819949",                                                                                 // Curve25519: 2^255-19
469        "9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599",                                           // E-382: 2^382-105
470        "42307582002575910332922579714097346549017899709713998034217522897561970639123926132812109468141778230245837569601494931472367",                                 // Curve41417: 2^414-17
471        "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", // E-521: 2^521-1
472        ];
473
474        static ref COMPOSITES: Vec<&'static str> = vec![
475            "0",
476            "1",
477
478            "21284175091214687912771199898307297748211672914763848041968395774954376176754",
479            "6084766654921918907427900243509372380954290099172559290432744450051395395951",
480            "84594350493221918389213352992032324280367711247940675652888030554255915464401",
481            "82793403787388584738507275144194252681",
482
483            // Arnault, "Rabin-Miller Primality Test: Composite Numbers Which Pass It",
484            // Mathematics of Computation, 64(209) (January 1995), pp. 335-361.
485            "1195068768795265792518361315725116351898245581", // strong pseudoprime to prime bases 2 through 29
486            // strong pseudoprime to all prime bases up to 200
487            "8038374574536394912570796143419421081388376882875581458374889175222974273765333652186502336163960045457915042023603208766569966760987284043965408232928738791850869166857328267761771029389697739470167082304286871099974399765441448453411558724506334092790222752962294149842306881685404326457534018329786111298960644845216191652872597534901",
488
489            // Extra-strong Lucas pseudoprimes. https://oeis.org/A217719
490            "989",
491            "3239",
492            "5777",
493            "10877",
494            "27971",
495            "29681",
496            "30739",
497            "31631",
498            "39059",
499            "72389",
500            "73919",
501            "75077",
502            "100127",
503            "113573",
504            "125249",
505            "137549",
506            "137801",
507            "153931",
508            "155819",
509            "161027",
510            "162133",
511            "189419",
512            "218321",
513            "231703",
514            "249331",
515            "370229",
516            "429479",
517            "430127",
518            "459191",
519            "473891",
520            "480689",
521            "600059",
522            "621781",
523            "632249",
524            "635627",
525
526            "3673744903",
527            "3281593591",
528            "2385076987",
529            "2738053141",
530            "2009621503",
531            "1502682721",
532            "255866131",
533            "117987841",
534            "587861",
535
536            "6368689",
537            "8725753",
538            "80579735209",
539            "105919633",
540        ];
541
542        // Test Cases from #51
543        static ref ISSUE_51: Vec<&'static str> = vec![
544            "1579751",
545            "1884791",
546            "3818929",
547            "4080359",
548            "4145951",
549        ];
550    }
551
552    #[test]
553    fn test_primes() {
554        for prime in PRIMES.iter() {
555            let p = BigUint::parse_bytes(prime.as_bytes(), 10).unwrap();
556            for i in [0, 1, 20].iter() {
557                assert!(
558                    probably_prime(&p, *i as usize),
559                    "{} is a prime ({})",
560                    prime,
561                    i,
562                );
563            }
564        }
565    }
566
567    #[test]
568    fn test_composites() {
569        for comp in COMPOSITES.iter() {
570            let p = BigUint::parse_bytes(comp.as_bytes(), 10).unwrap();
571            for i in [0, 1, 20].iter() {
572                assert!(
573                    !probably_prime(&p, *i as usize),
574                    "{} is a composite ({})",
575                    comp,
576                    i,
577                );
578            }
579        }
580    }
581
582    #[test]
583    fn test_issue_51() {
584        for num in ISSUE_51.iter() {
585            let p = BigUint::parse_bytes(num.as_bytes(), 10).unwrap();
586            assert!(probably_prime(&p, 20), "{} is a prime number", num);
587        }
588    }
589
590    macro_rules! test_pseudo_primes {
591        ($name:ident, $cond:expr, $want:expr) => {
592            #[test]
593            fn $name() {
594                let mut i = 3;
595                let mut want = $want;
596                while i < 100000 {
597                    let n = BigUint::from_u64(i).unwrap();
598                    let pseudo = $cond(&n);
599                    if pseudo && (want.is_empty() || i != want[0]) {
600                        panic!("cond({}) = true, want false", i);
601                    } else if !pseudo && !want.is_empty() && i == want[0] {
602                        panic!("cond({}) = false, want true", i);
603                    }
604                    if !want.is_empty() && i == want[0] {
605                        want = want[1..].to_vec();
606                    }
607                    i += 2;
608                }
609
610                if !want.is_empty() {
611                    panic!("forgot to test: {:?}", want);
612                }
613            }
614        };
615    }
616
617    test_pseudo_primes!(
618        test_probably_prime_miller_rabin,
619        |n| probably_prime_miller_rabin(n, 1, true) && !probably_prime_lucas(n),
620        vec![
621            2047, 3277, 4033, 4681, 8321, 15841, 29341, 42799, 49141, 52633, 65281, 74665, 80581,
622            85489, 88357, 90751,
623        ]
624    );
625
626    test_pseudo_primes!(
627        test_probably_prime_lucas,
628        |n| probably_prime_lucas(n) && !probably_prime_miller_rabin(n, 1, true),
629        vec![989, 3239, 5777, 10877, 27971, 29681, 30739, 31631, 39059, 72389, 73919, 75077,]
630    );
631
632    #[test]
633    fn test_bit_set() {
634        let v = &vec![0b10101001];
635        let num = BigUint::from_slice(&v);
636        assert!(is_bit_set(&num, 0));
637        assert!(!is_bit_set(&num, 1));
638        assert!(!is_bit_set(&num, 2));
639        assert!(is_bit_set(&num, 3));
640        assert!(!is_bit_set(&num, 4));
641        assert!(is_bit_set(&num, 5));
642        assert!(!is_bit_set(&num, 6));
643        assert!(is_bit_set(&num, 7));
644    }
645
646    #[test]
647    fn test_next_prime_basics() {
648        let primes1 = (0..2048u32)
649            .map(|i| next_prime(&i.to_biguint().unwrap()))
650            .collect::<Vec<_>>();
651        let primes2 = (0..2048u32)
652            .map(|i| {
653                let i = i.to_biguint().unwrap();
654                let p = next_prime(&i);
655                assert!(&p > &i);
656                p
657            })
658            .collect::<Vec<_>>();
659
660        for (p1, p2) in primes1.iter().zip(&primes2) {
661            assert_eq!(p1, p2);
662            assert!(probably_prime(p1, 25));
663        }
664    }
665
666    #[test]
667    fn test_next_prime_bug_44() {
668        let i = 1032989.to_biguint().unwrap();
669        let next = next_prime(&i);
670        assert_eq!(1033001.to_biguint().unwrap(), next);
671    }
672}