isPrime/src/is_prime.rs
2024-07-11 02:37:44 +02:00

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)
}
}