From 7e9dffdaff15969d4d15cc7e2fa0cd9153b92a85 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Fri, 31 Jan 2025 12:27:20 +0100 Subject: [PATCH] fix: implement ln fallback locally --- Cargo.lock | 7 ------- Cargo.toml | 1 - src/algorithms/generate.rs | 32 +++++++++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 86a58bb..042197b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,12 +315,6 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" -[[package]] -name = "libm" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -525,7 +519,6 @@ dependencies = [ "crypto-primes", "digest", "hex-literal", - "libm", "pkcs1", "pkcs8", "proptest", diff --git a/Cargo.toml b/Cargo.toml index 4fe1d14..9f73a31 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ spki = { version = "0.8.0-rc.1", default-features = false, features = ["alloc"] zeroize = { version = "1.5", features = ["alloc"] } crypto-bigint = { version = "0.6.0", default-features = false, features = ["zeroize", "alloc"] } crypto-primes = { version = "0.6.0", default-features = false } -libm = "0.2" # optional dependencies sha1 = { version = "=0.11.0-pre.4", optional = true, default-features = false, features = ["oid"] } diff --git a/src/algorithms/generate.rs b/src/algorithms/generate.rs index a03a230..7b28786 100644 --- a/src/algorithms/generate.rs +++ b/src/algorithms/generate.rs @@ -126,7 +126,21 @@ fn logf(val: f64) -> f64 { /// Natural logarithm for `f64`. #[cfg(not(feature = "std"))] fn logf(val: f64) -> f64 { - libm::logf(val as f32) as f64 + logf_approx(val as f32) as f64 +} + +/// Ln implementation based on +/// +#[cfg(any(not(feature = "std"), test))] +fn logf_approx(x: f32) -> f32 { + let bx: u32 = x.to_bits(); + let ex: u32 = bx >> 23; + let t: i32 = (ex as i32) - 127; + let s: u32 = if t < 0 { -t as u32 } else { t as u32 }; + let bx = 1065353216 | (bx & 8388607); + let x = f32::from_bits(bx); + + -1.49278 + (2.11263 + (-0.729104 + 0.10969 * x) * x) * x + core::f32::consts::LN_2 * (s as f32) } fn generate_prime_with_rng(rng: &mut R, bit_length: u32) -> BoxedUint { @@ -141,6 +155,7 @@ fn generate_prime_with_rng(rng: &mut R, bit_length: u32) -> Bo #[cfg(test)] mod tests { use super::*; + use rand::Rng; use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng}; const EXP: u64 = 65537; @@ -186,4 +201,19 @@ mod tests { key_generation!(key_generation_multi_8_576, 8, 576); // TODO: reenable, currently slow // key_generation!(key_generation_multi_16_1024, 16, 1024); + + #[test] + fn test_log_approx() { + let mut rng = ChaCha8Rng::from_seed([42; 32]); + + for i in 0..100 { + println!("round {i}"); + let prime_limit: f64 = rng.gen(); + let a = logf(prime_limit); + let b = logf_approx(prime_limit as f32); + + let diff = a - b as f64; + assert!(diff < 0.001, "{} != {}", a, b); + } + } }