74 lines
1.8 KiB
Rust
74 lines
1.8 KiB
Rust
|
|
|
|
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<BigUint>) -> 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)
|
|
}
|
|
}
|
|
|