diff --git a/rust/server/Cargo.lock b/rust/server/Cargo.lock index c1e9ff8..32ae00a 100644 --- a/rust/server/Cargo.lock +++ b/rust/server/Cargo.lock @@ -115,6 +115,7 @@ dependencies = [ "crc32fast", "lazy_static", "num", + "num-bigfloat", "num-bigint", "num-traits", "rand", @@ -155,6 +156,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigfloat" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56a51331d84e5827f5f875945e505f3c4e54a13fb31153449b1c994c159b883" + [[package]] name = "num-bigint" version = "0.4.3" diff --git a/rust/server/Cargo.toml b/rust/server/Cargo.toml index 2926ecd..af8e379 100644 --- a/rust/server/Cargo.toml +++ b/rust/server/Cargo.toml @@ -17,6 +17,7 @@ num-bigint = { default-features = true, version = "0.4.3" } num-traits = { default-features = true, version = "0.2.15" } num = { default-features = true, version = "0.4.0" } lazy_static = { default-features = false, version = "1.4.0" } +num-bigfloat = { default-features = false, version = "1.6.2" } [profile.release] lto = true # Enable link-time optimization diff --git a/rust/server/src/main.rs b/rust/server/src/main.rs index 94a4767..0394737 100644 --- a/rust/server/src/main.rs +++ b/rust/server/src/main.rs @@ -1,7 +1,6 @@ use bincode::{self, options, Options}; use crc32fast; use num_bigint::ToBigUint; -use num_traits::ToPrimitive; use rand::{rngs::StdRng, RngCore, SeedableRng}; use regex::Regex; use serde::{Deserialize, Serialize}; @@ -12,7 +11,9 @@ use std::{ net::{SocketAddr, UdpSocket}, }; -use num::{BigUint, NumCast, One, Zero}; +use num::{BigUint, One, Zero}; +use num_bigfloat::BigFloat; + mod big_array; mod primality_test; @@ -60,43 +61,54 @@ fn pow_mod(num: BigUint, pow: BigUint, modulo: BigUint) -> BigUint { result } -fn nth_prime_approx(n: f64) -> f64 { - let ln_n = n.ln(); - let ln_ln_n = ln_n.ln(); - let ln_ln_ln_n = ln_ln_n.ln(); +// fn nth_prime_approx(n: f64) -> f64 { +// let ln_n = n.ln(); +// let ln_ln_n = ln_n.ln(); +// let ln_ln_ln_n = ln_ln_n.ln(); - n * (ln_n + ln_ln_n - 1.0 + (ln_ln_ln_n - 2.0) / ln_n - - ((ln_ln_n).powi(2) - 6.0 * ln_ln_n + 11.0) / (2.0 * 2.0f64.log2() * ln_n) - + ((ln_ln_n / ln_n).powi(3)) * (1.0 / ln_n)) +// n * (ln_n + ln_ln_n - 1.0 + (ln_ln_ln_n - 2.0) / ln_n +// - ((ln_ln_n).powi(2) - 6.0 * ln_ln_n + 11.0) / (2.0 * 2.0f64.log2() * ln_n) +// + ((ln_ln_n / ln_n).powi(3)) * (1.0 / ln_n)) +// } + +fn nth_prime_approx(n: BigUint) -> BigUint { + ln(&n)/n } -fn ln(x: &BigUint) -> BigUint { - let mut sum = x.clone(); - let mut term = x.clone(); - let two = BigUint::from(2u32); - let ten = BigUint::from(10u32); - let precision = 100; +//approximate natural log of a BigUint +// fn ln(x: &BigUint) -> BigUint { +// let mut sum = BigUint::zero(); +// let mut i = BigUint::one(); +// while &i < x { +// sum += BigUint::one() / &i; +// i += BigUint::one(); +// } - for i in 1..precision { - term /= &two; - if i % 2 == 0 { - sum += &term; - } else { - sum -= &term; - } +// sum +// } + +fn ln(x: &BigUint) -> BigUint { + if x.is_zero() { + panic!("Cannot calculate the natural logarithm of zero"); } - sum *= &ten.pow(precision); - sum /= x.clone(); + // Convert BigUint to BigFloat + let x_float: BigFloat = x.to_string().parse().unwrap(); + + // Calculate the natural logarithm + let ln_x = x_float.ln(); - sum + println!("ln({};{}) = {} ~~ {}", x, x_float, ln_x, ln_x.to_string().split(".").take(1).next().unwrap()); + + // Convert BigFloat to BigUint + ln_x.to_string().split(".").take(1).next().unwrap().parse().unwrap() } //TODO: more precise approximation (Riemann R function?) -fn prime_approx(num: BigUint) -> BigUint { +fn prime_approx(num: &BigUint) -> BigUint { //x/log(x) - let ln_num = ln(&num); + let ln_num = ln(num); num / ln_num } @@ -107,12 +119,12 @@ fn new_p() -> BigUint { let mut rng = StdRng::from_entropy(); rng.fill_bytes(&mut private_key); let rand_num = BigUint::from_bytes_be(&private_key); - let mut num = nth_prime_approx(prime_approx(rand_num.clone()).to_f64().unwrap()) + let mut num = nth_prime_approx(prime_approx(&rand_num)) .to_biguint() .unwrap(); println!( "guesstimating {}th prime: {}", - prime_approx(rand_num.clone()).to_f64().unwrap(), + prime_approx(&rand_num), num ); if is_prime_default(&num) { @@ -164,7 +176,7 @@ fn main() { let missing_packet_request_regex = Regex::new(r"([\w.-_ ]+)(/\d{1,10})+").unwrap(); - let p_q_lookup: HashMap = HashMap::new(); + let _p_q_lookup: HashMap = HashMap::new(); // [ID: u128] = (p: [u8,64], q: [u8,64?]) // TODO: find fixed size for q diff --git a/rust/server/src/prime_utils.rs b/rust/server/src/prime_utils.rs index 9cbdd23..6c024d6 100644 --- a/rust/server/src/prime_utils.rs +++ b/rust/server/src/prime_utils.rs @@ -14,63 +14,13 @@ pub mod prime_utils { lazy_static! { static ref DEFAULTVEC: Vec = { let mut vec = Vec::new(); - vec.push(BigUint::from(2u8)); - vec.push(BigUint::from(3u8)); - vec.push(BigUint::from(5u8)); - vec.push(BigUint::from(7u8)); - vec.push(BigUint::from(11u8)); - vec.push(BigUint::from(13u8)); - vec.push(BigUint::from(17u8)); - vec.push(BigUint::from(19u8)); - vec.push(BigUint::from(23u8)); - vec.push(BigUint::from(29u8)); - vec.push(BigUint::from(31u8)); - vec.push(BigUint::from(37u8)); - vec.push(BigUint::from(41u8)); - vec.push(BigUint::from(43u8)); - vec.push(BigUint::from(47u8)); - vec.push(BigUint::from(53u8)); - vec.push(BigUint::from(59u8)); - vec.push(BigUint::from(61u8)); - vec.push(BigUint::from(67u8)); - vec.push(BigUint::from(71u8)); - vec.push(BigUint::from(73u8)); - vec.push(BigUint::from(79u8)); - vec.push(BigUint::from(83u8)); - vec.push(BigUint::from(89u8)); - vec.push(BigUint::from(97u8)); - vec.push(BigUint::from(101u8)); - vec.push(BigUint::from(103u8)); - vec.push(BigUint::from(107u8)); - vec.push(BigUint::from(109u8)); - vec.push(BigUint::from(113u8)); - vec.push(BigUint::from(127u8)); - vec.push(BigUint::from(131u8)); - vec.push(BigUint::from(137u8)); - vec.push(BigUint::from(139u8)); - vec.push(BigUint::from(149u8)); - vec.push(BigUint::from(151u8)); - vec.push(BigUint::from(157u8)); - vec.push(BigUint::from(163u8)); - vec.push(BigUint::from(167u8)); - vec.push(BigUint::from(173u8)); - vec.push(BigUint::from(179u8)); - vec.push(BigUint::from(181u8)); - vec.push(BigUint::from(191u8)); - vec.push(BigUint::from(193u8)); - vec.push(BigUint::from(197u8)); - vec.push(BigUint::from(199u8)); - vec.push(BigUint::from(211u8)); - vec.push(BigUint::from(223u8)); - vec.push(BigUint::from(227u8)); - vec.push(BigUint::from(229u8)); - vec.push(BigUint::from(233u8)); - vec.push(BigUint::from(239u8)); - vec.push(BigUint::from(241u8)); - vec.push(BigUint::from(251u8)); //all primes that fit in a u8 + for i in 2u16..1_000u16 { + if is_prime(&BigUint::from(i), &vec) { + vec.push(BigUint::from(i)); + } + } vec }; - } return is_prime(number, &DEFAULTVEC); @@ -78,7 +28,7 @@ pub mod prime_utils { #[must_use] pub fn is_prime(number: &BigUint, g_primes: &Vec) -> bool { - if BigUint::from(1u8) == *number { + if BigUint::from(1u8) == *number || BigUint::from(0u8) == *number { return false; } if BigUint::from(4u8) > *number {