1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-01 21:47:46 +00:00

factor::miller_rabin: Generalise tests to 32 and 64b Montgomery

This commit is contained in:
nicoo 2020-07-04 21:56:03 +02:00
parent 9b149a759b
commit 3d6fdffe14

View file

@ -111,16 +111,22 @@ pub(crate) fn is_prime(n: u64) -> bool {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::is_prime; use super::*;
use crate::numeric::{Arithmetic, Montgomery};
use quickcheck::quickcheck; use quickcheck::quickcheck;
use std::iter;
const LARGEST_U64_PRIME: u64 = 0xFFFFFFFFFFFFFFC5; const LARGEST_U64_PRIME: u64 = 0xFFFFFFFFFFFFFFC5;
fn primes() -> impl Iterator<Item = u64> { fn primes() -> impl Iterator<Item = u64> {
iter::once(2).chain(odd_primes())
}
fn odd_primes() -> impl Iterator<Item = u64> {
use crate::table::{NEXT_PRIME, P_INVS_U64}; use crate::table::{NEXT_PRIME, P_INVS_U64};
use std::iter::once; P_INVS_U64
once(2) .iter()
.chain(P_INVS_U64.iter().map(|(p, _, _)| *p)) .map(|(p, _, _)| *p)
.chain(once(NEXT_PRIME)) .chain(iter::once(NEXT_PRIME))
} }
#[test] #[test]
@ -136,40 +142,79 @@ mod tests {
} }
#[test] #[test]
fn first_primes() { fn two() {
for p in primes() { assert!(is_prime(2));
assert!(is_prime(p), "{} reported composite", p); }
fn first_primes<A: Arithmetic + Basis>() {
for p in odd_primes() {
assert!(test(A::new(p)).is_prime(), "{} reported composite", p);
} }
} }
#[test] #[test]
fn first_composites() { fn first_primes_32() {
assert!(!is_prime(0)); first_primes::<Montgomery<u32>>()
assert!(!is_prime(1)); }
for (p, q) in primes().zip(primes().skip(1)) { #[test]
fn first_primes_64() {
first_primes::<Montgomery<u64>>()
}
#[test]
fn one() {
assert!(!is_prime(1));
}
#[test]
fn zero() {
assert!(!is_prime(0));
}
fn first_composites<A: Arithmetic + Basis>() {
for (p, q) in primes().zip(odd_primes()) {
for i in p + 1..q { for i in p + 1..q {
assert!(!is_prime(i), "{} reported prime", i); assert!(!is_prime(i), "{} reported prime", i);
} }
} }
} }
#[test]
fn first_composites_32() {
first_composites::<Montgomery<u32>>()
}
#[test]
fn first_composites_64() {
first_composites::<Montgomery<u64>>()
}
#[test] #[test]
fn issue_1556() { fn issue_1556() {
// 10 425 511 = 2441 × 4271 // 10 425 511 = 2441 × 4271
assert!(!is_prime(10_425_511)); assert!(!is_prime(10_425_511));
} }
#[test] fn small_semiprimes<A: Arithmetic + Basis>() {
fn small_semiprimes() { for p in odd_primes() {
for p in primes() { for q in odd_primes().take_while(|q| *q <= p) {
for q in primes().take_while(|q| *q <= p) {
let n = p * q; let n = p * q;
assert!(!is_prime(n), "{} = {} × {} reported prime", n, p, q); let m = A::new(n);
assert!(!test(m).is_prime(), "{} = {} × {} reported prime", n, p, q);
} }
} }
} }
#[test]
fn small_semiprimes_32() {
small_semiprimes::<Montgomery<u32>>()
}
#[test]
fn small_semiprimes_64() {
small_semiprimes::<Montgomery<u64>>()
}
quickcheck! { quickcheck! {
fn composites(i: u64, j: u64) -> bool { fn composites(i: u64, j: u64) -> bool {
i < 2 || j < 2 || !is_prime(i*j) i < 2 || j < 2 || !is_prime(i*j)