pub mod prime_utils { use num::{BigUint, One, Zero}; use crate::primality_test::primality_tests::is_probably_prime; #[must_use] pub fn log_2(x: &BigUint) -> u64 { x.bits() - 1 } #[must_use] pub fn is_prime(number: &BigUint, g_primes: &Vec) -> bool { if BigUint::from(1u8) == *number { return false; } if BigUint::from(4u8) > *number { return true; } if number.sqrt().pow(2) == *number { return false; } let two = BigUint::from(2u8); // number = 2^a - 1 // a = log2(number + 1) let a = log_2(&(number+1u8)); if BigUint::from(2u8).pow(a as u32)-BigUint::one() != *number { let mut i = BigUint::one(); let one = BigUint::one(); let zero = BigUint::zero(); let sqrtnum = number.sqrt()+&one; //fake ceil function if let Some(max_value) = g_primes.iter().max() { if max_value > &sqrtnum { for prime in g_primes { if prime<&sqrtnum && number%prime == zero { return false; } } } } if !is_probably_prime(number,5) { return false; } loop { i += &one; if number%&i == zero { return false; } if i == sqrtnum { return true; } } } // 4 12 194 let mut last = BigUint::from(4u8); for _i in 2..a { last = (last.pow(2)-&two)%number; } last == BigUint::from(0u8) } }