From 03309d2657dace1f2337d09fa1e95ca8a1256ad0 Mon Sep 17 00:00:00 2001 From: David Palm Date: Wed, 6 Nov 2024 15:37:09 +0100 Subject: [PATCH] Prefer core::num::NonZero over crypto_bigint::NonZero where possible --- benches/bench.rs | 18 +++++++++--------- src/hazmat/gcd.rs | 8 +++++--- src/hazmat/jacobi.rs | 4 ++-- src/hazmat/lucas.rs | 3 ++- src/hazmat/miller_rabin.rs | 11 +++++------ src/hazmat/sieve.rs | 26 +++++++++++++------------- src/presets.rs | 16 ++++++++-------- 7 files changed, 44 insertions(+), 42 deletions(-) diff --git a/benches/bench.rs b/benches/bench.rs index 271ad4a..a415d13 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -1,4 +1,4 @@ -use core::num::NonZeroU32; +use core::num::NonZero; use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use crypto_bigint::{nlimbs, BoxedUint, Integer, Odd, RandomBits, Uint, U1024, U128, U256}; @@ -24,12 +24,12 @@ fn make_rng() -> ChaCha8Rng { } fn random_odd_uint(rng: &mut impl CryptoRngCore, bit_length: u32) -> Odd { - random_odd_integer::(rng, NonZeroU32::new(bit_length).unwrap()) + random_odd_integer::(rng, NonZero::new(bit_length).unwrap()) } fn make_sieve(rng: &mut impl CryptoRngCore) -> Sieve> { let start = random_odd_uint::>(rng, Uint::::BITS); - Sieve::new(start.get(), NonZeroU32::new(Uint::::BITS).unwrap(), false) + Sieve::new(start.get(), NonZero::new(Uint::::BITS).unwrap(), false) } fn make_presieved_num(rng: &mut impl CryptoRngCore) -> Odd> { @@ -47,7 +47,7 @@ fn bench_sieve(c: &mut Criterion) { group.bench_function("(U128) creation", |b| { b.iter_batched( || random_odd_uint::(&mut OsRng, 128), - |start| Sieve::new(start.get(), NonZeroU32::new(128).unwrap(), false), + |start| Sieve::new(start.get(), NonZero::new(128).unwrap(), false), BatchSize::SmallInput, ) }); @@ -68,7 +68,7 @@ fn bench_sieve(c: &mut Criterion) { group.bench_function("(U1024) creation", |b| { b.iter_batched( || random_odd_uint::(&mut OsRng, 1024), - |start| Sieve::new(start.get(), NonZeroU32::new(1024).unwrap(), false), + |start| Sieve::new(start.get(), NonZero::new(1024).unwrap(), false), BatchSize::SmallInput, ) }); @@ -378,8 +378,8 @@ fn bench_glass_pumpkin(c: &mut Criterion) { // Mimics the sequence of checks `glass-pumpkin` does to find a prime. fn prime_like_gp(bit_length: u32, rng: &mut impl CryptoRngCore) -> BoxedUint { loop { - let start = random_odd_integer::(rng, NonZeroU32::new(bit_length).unwrap()).get(); - let sieve = Sieve::new(start, NonZeroU32::new(bit_length).unwrap(), false); + let start = random_odd_integer::(rng, NonZero::new(bit_length).unwrap()).get(); + let sieve = Sieve::new(start, NonZero::new(bit_length).unwrap(), false); for num in sieve { let odd_num = Odd::new(num.clone()).unwrap(); @@ -402,8 +402,8 @@ fn bench_glass_pumpkin(c: &mut Criterion) { // Mimics the sequence of checks `glass-pumpkin` does to find a safe prime. fn safe_prime_like_gp(bit_length: u32, rng: &mut impl CryptoRngCore) -> BoxedUint { loop { - let start = random_odd_integer::(rng, NonZeroU32::new(bit_length).unwrap()).get(); - let sieve = Sieve::new(start, NonZeroU32::new(bit_length).unwrap(), true); + let start = random_odd_integer::(rng, NonZero::new(bit_length).unwrap()).get(); + let sieve = Sieve::new(start, NonZero::new(bit_length).unwrap(), true); for num in sieve { let odd_num = Odd::new(num.clone()).unwrap(); diff --git a/src/hazmat/gcd.rs b/src/hazmat/gcd.rs index 1fce5f1..a58cb70 100644 --- a/src/hazmat/gcd.rs +++ b/src/hazmat/gcd.rs @@ -1,4 +1,5 @@ -use crypto_bigint::{Integer, Limb, NonZero, Word}; +use core::num::NonZero; +use crypto_bigint::{Integer, Limb, NonZero as CTNonZero, Word}; /// Calculates the greatest common divisor of `n` and `m`. /// By definition, `gcd(0, m) == m`. @@ -14,7 +15,7 @@ pub(crate) fn gcd_vartime(n: &T, m: NonZero) -> Word { // Normalize input: the resulting (a, b) are both small, a >= b, and b != 0. let (a, b): (Word, Word) = if n.bits() > Word::BITS { // `m` is non-zero, so we can unwrap. - let r = n.rem_limb(NonZero::new(Limb::from(m)).expect("divisor should be non-zero here")); + let r = n.rem_limb(CTNonZero::new(Limb::from(m)).expect("divisor should be non-zero here")); (m, r.0) } else { // In this branch `n` is `Word::BITS` bits or shorter, @@ -74,7 +75,8 @@ fn binary_gcd(mut n: Word, mut m: Word) -> Word { #[cfg(test)] mod tests { - use crypto_bigint::{NonZero, Word, U128}; + use core::num::NonZero; + use crypto_bigint::{Word, U128}; use num_bigint::BigUint; use num_integer::Integer; use proptest::prelude::*; diff --git a/src/hazmat/jacobi.rs b/src/hazmat/jacobi.rs index 3040ae5..84eeba3 100644 --- a/src/hazmat/jacobi.rs +++ b/src/hazmat/jacobi.rs @@ -1,6 +1,6 @@ //! Jacobi symbol calculation. -use crypto_bigint::{Integer, Limb, NonZero, Odd, Word}; +use crypto_bigint::{Integer, Limb, NonZero as CTNonZero, Odd, Word}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub(crate) enum JacobiSymbol { @@ -99,7 +99,7 @@ pub(crate) fn jacobi_symbol_vartime(abs_a: Word, a_is_negative: bool let (result, a_long, p) = swap_long(result, a, p_long); // Can unwrap here, since `p` is swapped with `a`, // and `a` would be odd after `reduce_numerator()`. - let a = a_long.rem_limb(NonZero::new(Limb::from(p)).expect("divisor should be non-zero here")); + let a = a_long.rem_limb(CTNonZero::new(Limb::from(p)).expect("divisor should be non-zero here")); (result, a.0, p) }; diff --git a/src/hazmat/lucas.rs b/src/hazmat/lucas.rs index 93fb95a..15784a5 100644 --- a/src/hazmat/lucas.rs +++ b/src/hazmat/lucas.rs @@ -1,5 +1,6 @@ //! Lucas primality test. -use crypto_bigint::{Integer, Limb, Monty, NonZero, Odd, Square, Word}; +use core::num::NonZero; +use crypto_bigint::{Integer, Limb, Monty, Odd, Square, Word}; use super::{ gcd::gcd_vartime, diff --git a/src/hazmat/miller_rabin.rs b/src/hazmat/miller_rabin.rs index 9471d45..42ca5e8 100644 --- a/src/hazmat/miller_rabin.rs +++ b/src/hazmat/miller_rabin.rs @@ -1,6 +1,6 @@ //! Miller-Rabin primality test. -use crypto_bigint::{Integer, Limb, Monty, NonZero, Odd, PowBoundedExp, RandomMod, Square}; +use crypto_bigint::{Integer, Limb, Monty, NonZero as CTNonZero, Odd, PowBoundedExp, RandomMod, Square}; use rand_core::CryptoRngCore; use super::Primality; @@ -115,7 +115,7 @@ impl MillerRabin { let range = self.candidate.wrapping_sub(&T::from(4u32)); // Can unwrap here since `candidate` is odd, and `candidate >= 4` (as checked above) - let range_nonzero = NonZero::new(range).expect("the range should be non-zero by construction"); + let range_nonzero = CTNonZero::new(range).expect("the range should be non-zero by construction"); // This should not overflow as long as `random_mod()` behaves according to the contract // (that is, returns a number within the given range). let random = T::random_mod(rng, &range_nonzero) @@ -136,9 +136,8 @@ impl MillerRabin { #[cfg(test)] mod tests { - use alloc::format; - use core::num::NonZeroU32; + use core::num::NonZero; use crypto_bigint::{Integer, Odd, RandomMod, Uint, U1024, U128, U1536, U64}; use rand_chacha::ChaCha8Rng; @@ -197,8 +196,8 @@ mod tests { #[test] fn trivial() { let mut rng = ChaCha8Rng::from_seed(*b"01234567890123456789012345678901"); - let start = random_odd_integer::(&mut rng, NonZeroU32::new(1024).unwrap()); - for num in Sieve::new(start.get(), NonZeroU32::new(1024).unwrap(), false).take(10) { + let start = random_odd_integer::(&mut rng, NonZero::new(1024).unwrap()); + for num in Sieve::new(start.get(), NonZero::new(1024).unwrap(), false).take(10) { let mr = MillerRabin::new(Odd::new(num).unwrap()); // Trivial tests, must always be true. diff --git a/src/hazmat/sieve.rs b/src/hazmat/sieve.rs index 2625547..e3eb253 100644 --- a/src/hazmat/sieve.rs +++ b/src/hazmat/sieve.rs @@ -249,7 +249,7 @@ mod tests { use alloc::format; use alloc::vec::Vec; - use core::num::NonZeroU32; + use core::num::NonZero; use crypto_bigint::U64; use num_prime::nt_funcs::factorize64; @@ -264,8 +264,8 @@ mod tests { let max_prime = SMALL_PRIMES[SMALL_PRIMES.len() - 1]; let mut rng = ChaCha8Rng::from_seed(*b"01234567890123456789012345678901"); - let start = random_odd_integer::(&mut rng, NonZeroU32::new(32).unwrap()).get(); - for num in Sieve::new(start, NonZeroU32::new(32).unwrap(), false).take(100) { + let start = random_odd_integer::(&mut rng, NonZero::new(32).unwrap()).get(); + for num in Sieve::new(start, NonZero::new(32).unwrap(), false).take(100) { let num_u64 = u64::from(num); assert!(num_u64.leading_zeros() == 32); @@ -280,9 +280,9 @@ mod tests { let max_prime = SMALL_PRIMES[SMALL_PRIMES.len() - 1]; let mut rng = ChaCha8Rng::from_seed(*b"01234567890123456789012345678901"); - let start = random_odd_integer::(&mut rng, NonZeroU32::new(32).unwrap()).get(); + let start = random_odd_integer::(&mut rng, NonZero::new(32).unwrap()).get(); - for num in Sieve::new(start, NonZeroU32::new(32).unwrap(), false).take(100) { + for num in Sieve::new(start, NonZero::new(32).unwrap(), false).take(100) { // For 32-bit targets #[allow(clippy::useless_conversion)] let num_u64: u64 = num.as_words()[0].into(); @@ -296,7 +296,7 @@ mod tests { } fn check_sieve(start: u32, bit_length: u32, safe_prime: bool, reference: &[u32]) { - let test = Sieve::new(U64::from(start), NonZeroU32::new(bit_length).unwrap(), safe_prime).collect::>(); + let test = Sieve::new(U64::from(start), NonZero::new(bit_length).unwrap(), safe_prime).collect::>(); assert_eq!(test.len(), reference.len()); for (x, y) in test.iter().zip(reference.iter()) { assert_eq!(x, &U64::from(*y)); @@ -351,13 +351,13 @@ mod tests { #[test] #[should_panic(expected = "The requested bit length (65) is larger than the precision of `start`")] fn sieve_too_many_bits() { - let _sieve = Sieve::new(U64::ONE, NonZeroU32::new(65).unwrap(), false); + let _sieve = Sieve::new(U64::ONE, NonZero::new(65).unwrap(), false); } #[test] fn random_below_max_length() { for _ in 0..10 { - let r = random_odd_integer::(&mut OsRng, NonZeroU32::new(50).unwrap()).get(); + let r = random_odd_integer::(&mut OsRng, NonZero::new(50).unwrap()).get(); assert_eq!(r.bits(), 50); } } @@ -365,28 +365,28 @@ mod tests { #[test] #[should_panic(expected = "try_random_bits() failed: BitLengthTooLarge { bit_length: 65, bits_precision: 64 }")] fn random_odd_uint_too_many_bits() { - let _p = random_odd_integer::(&mut OsRng, NonZeroU32::new(65).unwrap()); + let _p = random_odd_integer::(&mut OsRng, NonZero::new(65).unwrap()); } #[test] fn sieve_derived_traits() { - let s = Sieve::new(U64::ONE, NonZeroU32::new(10).unwrap(), false); + let s = Sieve::new(U64::ONE, NonZero::new(10).unwrap(), false); // Debug assert!(format!("{s:?}").starts_with("Sieve")); // Clone assert_eq!(s.clone(), s); // PartialEq - let s2 = Sieve::new(U64::ONE, NonZeroU32::new(10).unwrap(), false); + let s2 = Sieve::new(U64::ONE, NonZero::new(10).unwrap(), false); assert_eq!(s, s2); - let s3 = Sieve::new(U64::ONE, NonZeroU32::new(12).unwrap(), false); + let s3 = Sieve::new(U64::ONE, NonZero::new(12).unwrap(), false); assert_ne!(s, s3); } #[test] fn sieve_with_max_start() { let start = U64::MAX; - let mut sieve = Sieve::new(start, NonZeroU32::new(U64::BITS).unwrap(), false); + let mut sieve = Sieve::new(start, NonZero::new(U64::BITS).unwrap(), false); assert!(sieve.next().is_none()); } } diff --git a/src/presets.rs b/src/presets.rs index 7ead461..6bf015e 100644 --- a/src/presets.rs +++ b/src/presets.rs @@ -1,4 +1,4 @@ -use core::num::NonZeroU32; +use core::num::NonZero; use crypto_bigint::{Integer, Limb, Odd, RandomBits, RandomMod}; use rand_core::CryptoRngCore; @@ -54,7 +54,7 @@ pub fn generate_prime_with_rng( if bit_length < 2 { panic!("`bit_length` must be 2 or greater."); } - let bit_length = NonZeroU32::new(bit_length).expect("`bit_length` should be non-zero"); + let bit_length = NonZero::new(bit_length).expect("`bit_length` should be non-zero"); // Empirically, this loop is traversed 1 time. loop { let start = random_odd_integer::(rng, bit_length); @@ -78,7 +78,7 @@ pub fn generate_safe_prime_with_rng( if bit_length < 3 { panic!("`bit_length` must be 3 or greater."); } - let bit_length = NonZeroU32::new(bit_length).expect("`bit_length` should be non-zero"); + let bit_length = NonZero::new(bit_length).expect("`bit_length` should be non-zero"); loop { let start = random_odd_integer::(rng, bit_length); let sieve = Sieve::new(start.get(), bit_length, true); @@ -371,7 +371,7 @@ mod tests { #[cfg(feature = "tests-openssl")] mod tests_openssl { use alloc::format; - use core::num::NonZeroU32; + use core::num::NonZero; use crypto_bigint::U128; use openssl::bn::{BigNum, BigNumContext}; @@ -413,7 +413,7 @@ mod tests_openssl { // Generate random numbers, check if our test agrees with OpenSSL for _ in 0..100 { - let p = random_odd_integer::(&mut OsRng, NonZeroU32::new(128).unwrap()); + let p = random_odd_integer::(&mut OsRng, NonZero::new(128).unwrap()); let actual = is_prime(p.as_ref()); let p_bn = to_openssl(&p); let expected = openssl_is_prime(&p_bn, &mut ctx); @@ -428,7 +428,7 @@ mod tests_openssl { #[cfg(test)] #[cfg(feature = "tests-gmp")] mod tests_gmp { - use core::num::NonZeroU32; + use core::num::NonZero; use crypto_bigint::U128; use rand_core::OsRng; @@ -463,7 +463,7 @@ mod tests_gmp { // Generate primes with GMP, check them for _ in 0..100 { - let start = random_odd_integer::(&mut OsRng, NonZeroU32::new(128).unwrap()); + let start = random_odd_integer::(&mut OsRng, NonZero::new(128).unwrap()); let start_bn = to_gmp(&start); let p_bn = start_bn.next_prime(); let p = from_gmp(&p_bn); @@ -472,7 +472,7 @@ mod tests_gmp { // Generate random numbers, check if our test agrees with GMP for _ in 0..100 { - let p = random_odd_integer::(&mut OsRng, NonZeroU32::new(128).unwrap()); + let p = random_odd_integer::(&mut OsRng, NonZero::new(128).unwrap()); let actual = is_prime(p.as_ref()); let p_bn = to_gmp(&p); let expected = gmp_is_prime(&p_bn);