1use alloc::vec;
5use integer::Integer;
6use num_traits::{FromPrimitive, One, ToPrimitive, Zero};
7use once_cell::sync::Lazy;
8use rand::rngs::StdRng;
9use rand::SeedableRng;
10
11use crate::algorithms::jacobi;
12use crate::big_digit;
13use crate::bigrand::RandBigInt;
14use crate::Sign::Plus;
15use crate::{BigInt, BigUint, IntoBigUint};
16
17pub(crate) static BIG_1: Lazy<BigUint> = Lazy::new(|| BigUint::one());
18pub(crate) static BIG_2: Lazy<BigUint> = Lazy::new(|| BigUint::from_u64(2).unwrap());
19pub(crate) static BIG_64: Lazy<BigUint> = Lazy::new(|| BigUint::from_u64(64).unwrap());
20
21const PRIMES_A: u64 = 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 37;
22const PRIMES_B: u64 = 29 * 31 * 41 * 43 * 47 * 53;
23
24const PRIME_BIT_MASK: u64 = 1 << 2
26 | 1 << 3
27 | 1 << 5
28 | 1 << 7
29 | 1 << 11
30 | 1 << 13
31 | 1 << 17
32 | 1 << 19
33 | 1 << 23
34 | 1 << 29
35 | 1 << 31
36 | 1 << 37
37 | 1 << 41
38 | 1 << 43
39 | 1 << 47
40 | 1 << 53
41 | 1 << 59
42 | 1 << 61;
43
44pub fn probably_prime(x: &BigUint, n: usize) -> bool {
61 if x.is_zero() {
62 return false;
63 }
64
65 if x < &*BIG_64 {
66 return (PRIME_BIT_MASK & (1 << x.to_u64().unwrap())) != 0;
67 }
68
69 if x.is_even() {
70 return false;
71 }
72
73 let r_a = &(x % PRIMES_A);
74 let r_b = &(x % PRIMES_B);
75
76 if (r_a % 3u32).is_zero()
77 || (r_a % 5u32).is_zero()
78 || (r_a % 7u32).is_zero()
79 || (r_a % 11u32).is_zero()
80 || (r_a % 13u32).is_zero()
81 || (r_a % 17u32).is_zero()
82 || (r_a % 19u32).is_zero()
83 || (r_a % 23u32).is_zero()
84 || (r_a % 37u32).is_zero()
85 || (r_b % 29u32).is_zero()
86 || (r_b % 31u32).is_zero()
87 || (r_b % 41u32).is_zero()
88 || (r_b % 43u32).is_zero()
89 || (r_b % 47u32).is_zero()
90 || (r_b % 53u32).is_zero()
91 {
92 return false;
93 }
94
95 probably_prime_miller_rabin(x, n + 1, true) && probably_prime_lucas(x)
96}
97
98const NUMBER_OF_PRIMES: usize = 127;
99const PRIME_GAP: [u64; 167] = [
100 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,
101 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,
102 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,
103 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,
104 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,
105 14, 4, 2, 4, 20, 4, 8, 10, 8, 4, 6, 6, 14, 4, 6, 6, 8, 6, 12,
106];
107
108const INCR_LIMIT: usize = 0x10000;
109
110pub fn next_prime(n: &BigUint) -> BigUint {
112 if n < &*BIG_2 {
113 return 2u32.into_biguint().unwrap();
114 }
115
116 let mut res = n + &*BIG_1;
118
119 res |= &*BIG_1;
121
122 if let Some(val) = res.to_u64() {
124 if val < 7 {
125 return res;
126 }
127 }
128
129 let nbits = res.bits();
130 let prime_limit = if nbits / 2 >= NUMBER_OF_PRIMES {
131 NUMBER_OF_PRIMES - 1
132 } else {
133 nbits / 2
134 };
135
136 let mut moduli = vec![BigUint::zero(); prime_limit];
138
139 'outer: loop {
140 let mut prime = 3;
141 for i in 0..prime_limit {
142 moduli[i] = &res % prime;
143 prime += PRIME_GAP[i];
144 }
145
146 let mut difference: usize = 0;
148 for incr in (0..INCR_LIMIT as u64).step_by(2) {
149 let mut prime: u64 = 3;
150
151 let mut cancel = false;
152 for i in 0..prime_limit {
153 let r = (&moduli[i] + incr) % prime;
154 prime += PRIME_GAP[i];
155
156 if r.is_zero() {
157 cancel = true;
158 break;
159 }
160 }
161
162 if !cancel {
163 res += difference;
164 difference = 0;
165 if probably_prime(&res, 20) {
166 break 'outer;
167 }
168 }
169
170 difference += 2;
171 }
172
173 res += difference;
174 }
175
176 res
177}
178
179pub fn probably_prime_miller_rabin(n: &BigUint, reps: usize, force2: bool) -> bool {
184 let nm1 = n - &*BIG_1;
186 let k = nm1.trailing_zeros().unwrap() as usize;
188 let q = &nm1 >> k;
189
190 let nm3 = n - &*BIG_2;
191
192 let mut rng = StdRng::seed_from_u64(n.get_limb(0) as u64);
193
194 'nextrandom: for i in 0..reps {
195 let x = if i == reps - 1 && force2 {
196 BIG_2.clone()
197 } else {
198 rng.gen_biguint_below(&nm3) + &*BIG_2
199 };
200
201 let mut y = x.modpow(&q, n);
202 if y.is_one() || y == nm1 {
203 continue;
204 }
205
206 for _ in 1..k {
207 y = y.modpow(&*BIG_2, n);
208 if y == nm1 {
209 continue 'nextrandom;
210 }
211 if y.is_one() {
212 return false;
213 }
214 }
215 return false;
216 }
217
218 true
219}
220
221pub fn probably_prime_lucas(n: &BigUint) -> bool {
247 if n.is_zero() || n.is_one() {
250 return false;
251 }
252
253 if n.to_u64() == Some(2) {
255 return false;
256 }
257
258 let mut p = 3u64;
266 let n_int = BigInt::from_biguint(Plus, n.clone());
267
268 loop {
269 if p > 10000 {
270 panic!("internal error: cannot find (D/n) = -1 for {:?}", n)
273 }
274
275 let d_int = BigInt::from_u64(p * p - 4).unwrap();
276 let j = jacobi(&d_int, &n_int);
277
278 if j == -1 {
279 break;
280 }
281 if j == 0 {
282 return n_int.to_i64() == Some(p as i64 + 2);
288 }
289 if p == 40 {
290 let t1 = n.sqrt();
294 let t1 = &t1 * &t1;
295 if &t1 == n {
296 return false;
297 }
298 }
299
300 p += 1;
301 }
302
303 let mut s = n + &*BIG_1;
316 let r = s.trailing_zeros().unwrap() as usize;
317 s = &s >> r;
318 let nm2 = n - &*BIG_2; let mut vk = BIG_2.clone();
349 let mut vk1 = BigUint::from_u64(p).unwrap();
350
351 for i in (0..s.bits()).rev() {
352 if is_bit_set(&s, i) {
353 let t1 = (&vk * &vk1) + n - p;
356 vk = &t1 % n;
357 let t1 = (&vk1 * &vk1) + &nm2;
359 vk1 = &t1 % n;
360 } else {
361 let t1 = (&vk * &vk1) + n - p;
364 vk1 = &t1 % n;
365 let t1 = (&vk * &vk) + &nm2;
367 vk = &t1 % n;
368 }
369 }
370
371 if vk.to_u64() == Some(2) || vk == nm2 {
373 let mut t1 = &vk * p;
381 let mut t2 = &vk1 << 1;
382
383 if t1 < t2 {
384 core::mem::swap(&mut t1, &mut t2);
385 }
386
387 t1 -= t2;
388
389 if (t1 % n).is_zero() {
390 return true;
391 }
392 }
393
394 for _ in 0..r - 1 {
396 if vk.is_zero() {
397 return true;
398 }
399
400 if vk.to_u64() == Some(2) {
403 return false;
404 }
405
406 let t1 = (&vk * &vk) - &*BIG_2;
409 vk = &t1 % n;
410 }
411
412 false
413}
414
415#[inline]
417fn is_bit_set(x: &BigUint, i: usize) -> bool {
418 get_bit(x, i) == 1
419}
420
421#[inline]
423fn get_bit(x: &BigUint, i: usize) -> u8 {
424 let j = i / big_digit::BITS;
425 if i >= x.bits() {
427 return 0;
428 }
429
430 (x.get_limb(j) >> (i % big_digit::BITS) & 1) as u8
431}
432
433#[cfg(test)]
434mod tests {
435 use super::*;
436 use alloc::vec::Vec;
437 use crate::biguint::ToBigUint;
440
441 const PRIMES: &'static [&'static str] = &[
442 "2",
443 "3",
444 "5",
445 "7",
446 "11",
447
448 "13756265695458089029",
449 "13496181268022124907",
450 "10953742525620032441",
451 "17908251027575790097",
452
453 "18699199384836356663",
455
456 "98920366548084643601728869055592650835572950932266967461790948584315647051443",
457 "94560208308847015747498523884063394671606671904944666360068158221458669711639",
458
459 "449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163",
461 "230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593",
462 "5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993",
463 "203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123",
464 "3618502788666131106986593281521497120414687020801267626233049500247285301239", "57896044618658097711785492504343953926634992332820282019728792003956564819949", "9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599", "42307582002575910332922579714097346549017899709713998034217522897561970639123926132812109468141778230245837569601494931472367", "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", ];
471
472 const COMPOSITES: &'static [&'static str] = &[
473 "0",
474 "1",
475
476 "21284175091214687912771199898307297748211672914763848041968395774954376176754",
477 "6084766654921918907427900243509372380954290099172559290432744450051395395951",
478 "84594350493221918389213352992032324280367711247940675652888030554255915464401",
479 "82793403787388584738507275144194252681",
480
481 "1195068768795265792518361315725116351898245581", "8038374574536394912570796143419421081388376882875581458374889175222974273765333652186502336163960045457915042023603208766569966760987284043965408232928738791850869166857328267761771029389697739470167082304286871099974399765441448453411558724506334092790222752962294149842306881685404326457534018329786111298960644845216191652872597534901",
486
487 "989",
489 "3239",
490 "5777",
491 "10877",
492 "27971",
493 "29681",
494 "30739",
495 "31631",
496 "39059",
497 "72389",
498 "73919",
499 "75077",
500 "100127",
501 "113573",
502 "125249",
503 "137549",
504 "137801",
505 "153931",
506 "155819",
507 "161027",
508 "162133",
509 "189419",
510 "218321",
511 "231703",
512 "249331",
513 "370229",
514 "429479",
515 "430127",
516 "459191",
517 "473891",
518 "480689",
519 "600059",
520 "621781",
521 "632249",
522 "635627",
523
524 "3673744903",
525 "3281593591",
526 "2385076987",
527 "2738053141",
528 "2009621503",
529 "1502682721",
530 "255866131",
531 "117987841",
532 "587861",
533
534 "6368689",
535 "8725753",
536 "80579735209",
537 "105919633",
538 ];
539
540 const ISSUE_51: &'static [&'static str] =
542 &["1579751", "1884791", "3818929", "4080359", "4145951"];
543
544 #[test]
545 fn test_primes() {
546 for prime in PRIMES.iter() {
547 let p = BigUint::parse_bytes(prime.as_bytes(), 10).unwrap();
548 for i in [0, 1, 20].iter() {
549 assert!(
550 probably_prime(&p, *i as usize),
551 "{} is a prime ({})",
552 prime,
553 i,
554 );
555 }
556 }
557 }
558
559 #[test]
560 fn test_composites() {
561 for comp in COMPOSITES.iter() {
562 let p = BigUint::parse_bytes(comp.as_bytes(), 10).unwrap();
563 for i in [0, 1, 20].iter() {
564 assert!(
565 !probably_prime(&p, *i as usize),
566 "{} is a composite ({})",
567 comp,
568 i,
569 );
570 }
571 }
572 }
573
574 #[test]
575 fn test_issue_51() {
576 for num in ISSUE_51.iter() {
577 let p = BigUint::parse_bytes(num.as_bytes(), 10).unwrap();
578 assert!(probably_prime(&p, 20), "{} is a prime number", num);
579 }
580 }
581
582 macro_rules! test_pseudo_primes {
583 ($name:ident, $cond:expr, $want:expr) => {
584 #[test]
585 fn $name() {
586 let mut i = 3;
587 let mut want = $want;
588 while i < 100000 {
589 let n = BigUint::from_u64(i).unwrap();
590 let pseudo = $cond(&n);
591 if pseudo && (want.is_empty() || i != want[0]) {
592 panic!("cond({}) = true, want false", i);
593 } else if !pseudo && !want.is_empty() && i == want[0] {
594 panic!("cond({}) = false, want true", i);
595 }
596 if !want.is_empty() && i == want[0] {
597 want = want[1..].to_vec();
598 }
599 i += 2;
600 }
601
602 if !want.is_empty() {
603 panic!("forgot to test: {:?}", want);
604 }
605 }
606 };
607 }
608
609 test_pseudo_primes!(
610 test_probably_prime_miller_rabin,
611 |n| probably_prime_miller_rabin(n, 1, true) && !probably_prime_lucas(n),
612 vec![
613 2047, 3277, 4033, 4681, 8321, 15841, 29341, 42799, 49141, 52633, 65281, 74665, 80581,
614 85489, 88357, 90751,
615 ]
616 );
617
618 test_pseudo_primes!(
619 test_probably_prime_lucas,
620 |n| probably_prime_lucas(n) && !probably_prime_miller_rabin(n, 1, true),
621 vec![989, 3239, 5777, 10877, 27971, 29681, 30739, 31631, 39059, 72389, 73919, 75077,]
622 );
623
624 #[test]
625 fn test_bit_set() {
626 let v = &vec![0b10101001];
627 let num = BigUint::from_slice(&v);
628 assert!(is_bit_set(&num, 0));
629 assert!(!is_bit_set(&num, 1));
630 assert!(!is_bit_set(&num, 2));
631 assert!(is_bit_set(&num, 3));
632 assert!(!is_bit_set(&num, 4));
633 assert!(is_bit_set(&num, 5));
634 assert!(!is_bit_set(&num, 6));
635 assert!(is_bit_set(&num, 7));
636 }
637
638 #[test]
639 fn test_next_prime_basics() {
640 let primes1 = (0..2048u32)
641 .map(|i| next_prime(&i.to_biguint().unwrap()))
642 .collect::<Vec<_>>();
643 let primes2 = (0..2048u32)
644 .map(|i| {
645 let i = i.to_biguint().unwrap();
646 let p = next_prime(&i);
647 assert!(&p > &i);
648 p
649 })
650 .collect::<Vec<_>>();
651
652 for (p1, p2) in primes1.iter().zip(&primes2) {
653 assert_eq!(p1, p2);
654 assert!(probably_prime(p1, 25));
655 }
656 }
657
658 #[test]
659 fn test_next_prime_bug_44() {
660 let i = 1032989.to_biguint().unwrap();
661 let next = next_prime(&i);
662 assert_eq!(1033001.to_biguint().unwrap(), next);
663 }
664}