1use 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
25const 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
45pub 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
111pub fn next_prime(n: &BigUint) -> BigUint {
113 if n < &*BIG_2 {
114 return 2u32.into_biguint().unwrap();
115 }
116
117 let mut res = n + &*BIG_1;
119
120 res |= &*BIG_1;
122
123 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 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 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
180pub fn probably_prime_miller_rabin(n: &BigUint, reps: usize, force2: bool) -> bool {
185 let nm1 = n - &*BIG_1;
187 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
222pub fn probably_prime_lucas(n: &BigUint) -> bool {
248 if n.is_zero() || n.is_one() {
251 return false;
252 }
253
254 if n.to_u64() == Some(2) {
256 return false;
257 }
258
259 let mut p = 3u64;
267 let n_int = BigInt::from_biguint(Plus, n.clone());
268
269 loop {
270 if p > 10000 {
271 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 return n_int.to_i64() == Some(p as i64 + 2);
289 }
290 if p == 40 {
291 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 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; 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 let t1 = (&vk * &vk1) + n - p;
357 vk = &t1 % n;
358 let t1 = (&vk1 * &vk1) + &nm2;
360 vk1 = &t1 % n;
361 } else {
362 let t1 = (&vk * &vk1) + n - p;
365 vk1 = &t1 % n;
366 let t1 = (&vk * &vk) + &nm2;
368 vk = &t1 % n;
369 }
370 }
371
372 if vk.to_u64() == Some(2) || vk == nm2 {
374 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 for _ in 0..r - 1 {
397 if vk.is_zero() {
398 return true;
399 }
400
401 if vk.to_u64() == Some(2) {
404 return false;
405 }
406
407 let t1 = (&vk * &vk) - &*BIG_2;
410 vk = &t1 % n;
411 }
412
413 false
414}
415
416#[inline]
418fn is_bit_set(x: &BigUint, i: usize) -> bool {
419 get_bit(x, i) == 1
420}
421
422#[inline]
424fn get_bit(x: &BigUint, i: usize) -> u8 {
425 let j = i / big_digit::BITS;
426 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 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 "18699199384836356663",
457
458 "98920366548084643601728869055592650835572950932266967461790948584315647051443",
459 "94560208308847015747498523884063394671606671904944666360068158221458669711639",
460
461 "449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163",
463 "230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593",
464 "5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993",
465 "203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123",
466 "3618502788666131106986593281521497120414687020801267626233049500247285301239", "57896044618658097711785492504343953926634992332820282019728792003956564819949", "9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599", "42307582002575910332922579714097346549017899709713998034217522897561970639123926132812109468141778230245837569601494931472367", "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", ];
473
474 static ref COMPOSITES: Vec<&'static str> = vec![
475 "0",
476 "1",
477
478 "21284175091214687912771199898307297748211672914763848041968395774954376176754",
479 "6084766654921918907427900243509372380954290099172559290432744450051395395951",
480 "84594350493221918389213352992032324280367711247940675652888030554255915464401",
481 "82793403787388584738507275144194252681",
482
483 "1195068768795265792518361315725116351898245581", "8038374574536394912570796143419421081388376882875581458374889175222974273765333652186502336163960045457915042023603208766569966760987284043965408232928738791850869166857328267761771029389697739470167082304286871099974399765441448453411558724506334092790222752962294149842306881685404326457534018329786111298960644845216191652872597534901",
488
489 "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 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}