use machine_prime::{
is_prime,strong_fermat_128,
one_mont_128,two_mont_128,
to_mont_128,lucas_128,
mul_inv2_128,PRIME_TABLE_128
};
fn strong_test(x: u128) -> bool{
if x < 1u128<<64{
return is_prime(x as u64);
}
if x&1==0{
return false;
}
let mut idx = 0usize;
while idx < 256{
let prod = x.wrapping_mul(PRIME_TABLE_128[idx]);
if prod <= PRIME_TABLE_128[idx+1]{
return prod==1;
}
idx+=2;
}
let inv = mul_inv2_128(x);
let tzc = x.wrapping_sub(1).trailing_zeros();
let one = one_mont_128(x);
let oneinv = x.wrapping_sub(one);
let two = two_mont_128(one, x);
if !strong_fermat_128(x, tzc, two, one, oneinv, inv) {
return false;
}
for i in [3,5,7,11,13,17,19,23,29,31,37,41,43,47,511,659,679,8129,70157]{
let montwitness = to_mont_128(i,x);
if !strong_fermat_128(x,tzc,montwitness,one,oneinv,inv){
return false;
}
}
lucas_128(x,one,two,inv)
}
fn main(){
for i in 0..100_000{
if strong_test(u128::MAX-i){
println!("2^128-{} is definitely prime",i+1);
}
}
}