diff --git a/src/nt_funcs.rs b/src/nt_funcs.rs index efdb013..c67705f 100644 --- a/src/nt_funcs.rs +++ b/src/nt_funcs.rs @@ -16,7 +16,7 @@ use crate::factor::{one_line, pollard_rho, squfof, SQUFOF_MULTIPLIERS}; use crate::mint::SmallMint; use crate::primality::{PrimalityBase, PrimalityRefBase}; use crate::tables::{ - MILLER_RABIN_BASE32, MOEBIUS_ODD, SMALL_PRIMES, SMALL_PRIMES_NEXT, WHEEL_NEXT, WHEEL_PREV, + MOEBIUS_ODD, SMALL_PRIMES, SMALL_PRIMES_NEXT, WHEEL_NEXT, WHEEL_PREV, WHEEL_SIZE, }; #[cfg(feature = "big-table")] @@ -33,7 +33,7 @@ use std::collections::BTreeMap; use std::convert::TryFrom; #[cfg(feature = "big-table")] -use crate::tables::MILLER_RABIN_BASE64; +use crate::tables::{MILLER_RABIN_BASE64, MILLER_RABIN_BASE32}; /// Fast primality test on a u64 integer. It's based on /// deterministic Miller-rabin tests. If target is larger than 2^64 or more @@ -93,6 +93,23 @@ pub fn is_prime64(target: u64) -> bool { is_prime64_miller(target) } +// Primality test for u64 with only miller-rabin tests, used during factorization. +// It assumes the target is odd, not too small and cannot be divided small primes +#[cfg(not(feature = "big-table"))] +fn is_prime64_miller(target: u64) -> bool { + // The collection of witnesses are from http://miller-rabin.appspot.com/ + if let Ok(u) = u32::try_from(target) { + const WITNESS32: [u32; 3] = [2, 7, 61]; + let u = SmallMint::from(u); + WITNESS32.iter().all(|&x| u.is_sprp(SmallMint::from(x))) + } else { + const WITNESS64: [u64; 7] = [2, 325, 9375, 28178, 450775, 9780504, 1795265022]; + let u = SmallMint::from(target); + WITNESS64.iter().all(|&x| u.is_sprp(SmallMint::from(x))) + } +} + +#[cfg(feature = "big-table")] fn is_prime32_miller(target: u32) -> bool { let h = target as u64; let h = ((h >> 16) ^ h).wrapping_mul(0x45d9f3b); @@ -102,20 +119,6 @@ fn is_prime32_miller(target: u32) -> bool { return u.is_sprp(SmallMint::from(MILLER_RABIN_BASE32[h as usize] as u32)); } -// Primality test for u64 with only miller-rabin tests, used during factorization. -// It assumes the target is odd, not too small and cannot be divided small primes -#[cfg(not(feature = "big-table"))] -fn is_prime64_miller(target: u64) -> bool { - if let Ok(u) = u32::try_from(target) { - return is_prime32_miller(u); - } - - // The collection of witnesses are from http://miller-rabin.appspot.com/ - const WITNESS64: [u64; 7] = [2, 325, 9375, 28178, 450775, 9780504, 1795265022]; - let u = SmallMint::from(target); - WITNESS64.iter().all(|&x| u.is_sprp(SmallMint::from(x))) -} - // Primality test for u64 with only miller-rabin tests, used during factorization. // It assumes the target is odd, not too small and cannot be divided small primes #[cfg(feature = "big-table")] diff --git a/src/tables.rs b/src/tables.rs index 8dd41d0..c43acb8 100644 --- a/src/tables.rs +++ b/src/tables.rs @@ -1131,6 +1131,7 @@ pub const SMALL_PRIMES_INV: [P64; 1024] = [ * https://people.ksp.sk/~misof/primes/ */ +#[cfg(feature = "big-table")] pub const MILLER_RABIN_BASE32: [u16; 256] = [ 0x3ce7, 0x07e2, 0x00a6, 0x1d05, 0x1f80, 0x3ead, 0x2907, 0x112f, 0x079d, 0x050f, 0x0ad8, 0x0e24, 0x0230, 0x0c38, 0x145c, 0x0a61, 0x08fc, 0x07e5, 0x122c, 0x05bf, 0x2478, 0x0fb2, 0x095e, 0x4fee,