From 4e3afdac8d63ddc715ec4680d69706d5699b16ed Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 19 Dec 2023 18:42:42 -0700 Subject: [PATCH] Use `{Limb, Uint}::to_nz` to convert to `NonZero` Replaces the previous type-specific `NonZero::const_new` methods with more idiomatic `Limb::to_nz`/`Uint::to_nz` methods which can be called on a value and return `ConstCtChoice>`. --- src/limb.rs | 9 ++++++++- src/modular/residue/macros.rs | 4 ++-- src/non_zero.rs | 18 +----------------- src/uint.rs | 11 +++++++++-- src/uint/div.rs | 2 +- src/uint/sqrt.rs | 9 +++------ 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/limb.rs b/src/limb.rs index cc2119fe6..4e177e5cd 100644 --- a/src/limb.rs +++ b/src/limb.rs @@ -19,7 +19,7 @@ mod sub; #[cfg(feature = "rand_core")] mod rand; -use crate::{Bounded, Constants, ZeroConstant}; +use crate::{Bounded, ConstCtOption, Constants, NonZero, ZeroConstant}; use core::fmt; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; @@ -91,6 +91,13 @@ impl Limb { /// Size of the inner integer in bytes. #[cfg(target_pointer_width = "64")] pub const BYTES: usize = 8; + + /// Convert to a [`NonZero`]. + /// + /// Returns some if the original value is non-zero, and false otherwise. + pub const fn to_nz(self) -> ConstCtOption> { + ConstCtOption::new(NonZero(self), self.is_nonzero()) + } } impl Bounded for Limb { diff --git a/src/modular/residue/macros.rs b/src/modular/residue/macros.rs index 9a4e05849..07d0454c3 100644 --- a/src/modular/residue/macros.rs +++ b/src/modular/residue/macros.rs @@ -28,8 +28,8 @@ macro_rules! impl_modulus { panic!("modulus must be odd"); } - // Can unwrap `NonZero::const_new()` here since `res` was asserted to be odd. - $crate::NonZero::<$uint_type>::const_new(res).expect("modulus ensured non-zero") + // Can unwrap here since `res` was asserted to be odd. + res.to_nz().expect("modulus ensured non-zero") }; const R: $uint_type = $crate::Uint::MAX diff --git a/src/non_zero.rs b/src/non_zero.rs index 836476192..ebec82765 100644 --- a/src/non_zero.rs +++ b/src/non_zero.rs @@ -1,6 +1,6 @@ //! Wrapper type for non-zero integers. -use crate::{Bounded, ConstCtOption, Constants, Encoding, Limb, Uint, Zero}; +use crate::{Bounded, Constants, Encoding, Limb, Uint, Zero}; use core::{ fmt, num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8}, @@ -25,22 +25,6 @@ use serdect::serde::{ #[repr(transparent)] pub struct NonZero(pub(crate) T); -impl NonZero { - /// Creates a new non-zero limb in a const context. - /// The second return value is `FALSE` if `n` is zero, `TRUE` otherwise. - pub const fn const_new(n: Limb) -> ConstCtOption { - ConstCtOption::new(Self(n), n.is_nonzero()) - } -} - -impl NonZero> { - /// Creates a new non-zero integer in a const context. - /// The second return value is `FALSE` if `n` is zero, `TRUE` otherwise. - pub const fn const_new(n: Uint) -> ConstCtOption { - ConstCtOption::new(Self(n), n.is_nonzero()) - } -} - impl NonZero { /// Create a new non-zero integer. pub fn new(n: T) -> CtOption diff --git a/src/uint.rs b/src/uint.rs index 4da841f5f..b721742e1 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -40,8 +40,8 @@ pub(crate) mod boxed; mod rand; use crate::{ - modular::BernsteinYangInverter, Bounded, Constants, Encoding, FixedInteger, Integer, Limb, - PrecomputeInverter, PrecomputeInverterWithAdjuster, Word, ZeroConstant, + modular::BernsteinYangInverter, Bounded, ConstCtOption, Constants, Encoding, FixedInteger, + Integer, Limb, NonZero, PrecomputeInverter, PrecomputeInverterWithAdjuster, Word, ZeroConstant, }; use core::fmt; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; @@ -169,6 +169,13 @@ impl Uint { pub const fn to_limbs(self) -> [Limb; LIMBS] { self.limbs } + + /// Convert to a [`NonZero`]. + /// + /// Returns some if the original value is non-zero, and false otherwise. + pub const fn to_nz(self) -> ConstCtOption> { + ConstCtOption::new(NonZero(self), self.is_nonzero()) + } } impl AsRef<[Word; LIMBS]> for Uint { diff --git a/src/uint/div.rs b/src/uint/div.rs index c31f116e7..d650235d8 100644 --- a/src/uint/div.rs +++ b/src/uint/div.rs @@ -204,7 +204,7 @@ impl Uint { /// /// Panics if `rhs == 0`. pub const fn wrapping_rem(&self, rhs: &Self) -> Self { - let nz_rhs = NonZero::::const_new(*rhs).expect("non-zero divisor"); + let nz_rhs = rhs.to_nz().expect("non-zero divisor"); self.rem_vartime(&nz_rhs) } diff --git a/src/uint/sqrt.rs b/src/uint/sqrt.rs index 2b1cdb4d8..43dfd2f72 100644 --- a/src/uint/sqrt.rs +++ b/src/uint/sqrt.rs @@ -1,9 +1,8 @@ //! [`Uint`] square root operations. +use crate::Uint; use subtle::{ConstantTimeEq, CtOption}; -use crate::{NonZero, Uint}; - impl Uint { /// Computes √(`self`) in constant time. /// @@ -30,8 +29,7 @@ impl Uint { x_prev = x; // Calculate `x_{i+1} = floor((x_i + self / x_i) / 2)` - - let maybe_nz_x = NonZero::::const_new(x); + let maybe_nz_x = x.to_nz(); let (nz_x, is_some) = maybe_nz_x.components_ref(); let (q, _) = self.div_rem(nz_x); @@ -63,8 +61,7 @@ impl Uint { // Stop right away if `x` is zero to avoid divizion by zero. while !x.cmp_vartime(&Self::ZERO).is_eq() { // Calculate `x_{i+1} = floor((x_i + self / x_i) / 2)` - let q = self - .wrapping_div_vartime(&NonZero::::const_new(x).expect("ensured non-zero")); + let q = self.wrapping_div_vartime(&x.to_nz().expect("ensured non-zero")); let t = x.wrapping_add(&q); let next_x = t.shr1();