67 lines
1.6 KiB
Rust
67 lines
1.6 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
|
|
|
|
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)
|
|
}
|
|
}
|