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