From 54c03862d8314f4befff1dc4aacba28dc833b6a6 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 19 Jan 2025 13:23:43 -0800 Subject: [PATCH] arithmetic: Have a single place where we define limb length limits. --- src/arithmetic.rs | 14 ++++++++++++-- src/arithmetic/bigint.rs | 8 ++++---- src/arithmetic/bigint/modulus.rs | 9 --------- src/arithmetic/bigint/modulusvalue.rs | 8 ++++---- src/arithmetic/montgomery.rs | 7 +++++-- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/arithmetic.rs b/src/arithmetic.rs index b240d9df2a..87ae90740f 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -12,6 +12,8 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +use crate::limb::LIMB_BITS; + mod constant; #[cfg(feature = "alloc")] @@ -22,7 +24,15 @@ pub mod montgomery; mod n0; -#[allow(dead_code)] -const BIGINT_MODULUS_MAX_LIMBS: usize = 8192 / crate::limb::LIMB_BITS; +// The minimum number of limbs allowed for any `&[Limb]` operation. +// +// This must be at least 4 for bn_mul_mont to work, at least on x86. +// +// TODO: Use `256 / LIMB_BITS` so that the limit is independent of limb size. +#[allow(dead_code)] // XXX: Presently only used by `bigint`. +pub const MIN_LIMBS: usize = 4; + +// The maximum number of limbs allowed for any `&[Limb]` operation. +pub const MAX_LIMBS: usize = 8192 / LIMB_BITS; pub use self::{constant::limbs_from_hex, inout::InOut}; diff --git a/src/arithmetic/bigint.rs b/src/arithmetic/bigint.rs index e0be21c8b4..7d68f2dbdf 100644 --- a/src/arithmetic/bigint.rs +++ b/src/arithmetic/bigint.rs @@ -38,11 +38,11 @@ use self::boxed_limbs::BoxedLimbs; pub(crate) use self::{ - modulus::{Modulus, OwnedModulus, MODULUS_MAX_LIMBS}, + modulus::{Modulus, OwnedModulus}, modulusvalue::OwnedModulusValue, private_exponent::PrivateExponent, }; -use super::{montgomery::*, InOut}; +use super::{montgomery::*, InOut, MAX_LIMBS}; use crate::{ bits::BitLength, c, error, @@ -96,7 +96,7 @@ fn from_montgomery_amm(limbs: BoxedLimbs, m: &Modulus) -> Elem( // `limbs_from_mont_in_place` requires this. assert_eq!(a.limbs.len(), m.limbs().len() * 2); - let mut tmp = [0; MODULUS_MAX_LIMBS]; + let mut tmp = [0; MAX_LIMBS]; let tmp = &mut tmp[..a.limbs.len()]; tmp.copy_from_slice(&a.limbs); diff --git a/src/arithmetic/bigint/modulus.rs b/src/arithmetic/bigint/modulus.rs index d4ce866745..053bfeb7f6 100644 --- a/src/arithmetic/bigint/modulus.rs +++ b/src/arithmetic/bigint/modulus.rs @@ -21,15 +21,6 @@ use crate::{ }; use core::marker::PhantomData; -/// The x86 implementation of `bn_mul_mont`, at least, requires at least 4 -/// limbs. For a long time we have required 4 limbs for all targets, though -/// this may be unnecessary. TODO: Replace this with -/// `n.len() < 256 / LIMB_BITS` so that 32-bit and 64-bit platforms behave the -/// same. -pub const MODULUS_MIN_LIMBS: usize = 4; - -pub const MODULUS_MAX_LIMBS: usize = super::super::BIGINT_MODULUS_MAX_LIMBS; - /// The modulus *m* for a ring ℤ/mℤ, along with the precomputed values needed /// for efficient Montgomery multiplication modulo *m*. The value must be odd /// and larger than 2. The larger-than-1 requirement is imposed, at least, by diff --git a/src/arithmetic/bigint/modulusvalue.rs b/src/arithmetic/bigint/modulusvalue.rs index 678f563f76..850a7b84e3 100644 --- a/src/arithmetic/bigint/modulusvalue.rs +++ b/src/arithmetic/bigint/modulusvalue.rs @@ -13,7 +13,7 @@ // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. use super::{ - modulus::{MODULUS_MAX_LIMBS, MODULUS_MIN_LIMBS}, + super::{MAX_LIMBS, MIN_LIMBS}, BoxedLimbs, Modulus, PublicModulus, }; use crate::{ @@ -41,11 +41,11 @@ impl Clone for OwnedModulusValue { impl OwnedModulusValue { pub(crate) fn from_be_bytes(input: untrusted::Input) -> Result { let n = BoxedLimbs::positive_minimal_width_from_be_bytes(input)?; - if n.len() > MODULUS_MAX_LIMBS { + if n.len() > MAX_LIMBS { return Err(error::KeyRejected::too_large()); } - const _MODULUS_MIN_LIMBS_AT_LEAST_2: () = assert!(MODULUS_MIN_LIMBS >= 2); - if n.len() < MODULUS_MIN_LIMBS { + const _MODULUS_MIN_LIMBS_AT_LEAST_2: () = assert!(MIN_LIMBS >= 2); + if n.len() < MIN_LIMBS { return Err(error::KeyRejected::unexpected_error()); } // The above implies n >= 3, so we don't need to check it. diff --git a/src/arithmetic/montgomery.rs b/src/arithmetic/montgomery.rs index b58b4ef090..7c115b5590 100644 --- a/src/arithmetic/montgomery.rs +++ b/src/arithmetic/montgomery.rs @@ -150,6 +150,8 @@ prefixed_export! { n0: &N0, num_limbs: c::size_t, ) { + use super::MAX_LIMBS; + // The mutable pointer `r` may alias `a` and/or `b`, so the lifetimes of // any slices for `a` or `b` must not overlap with the lifetime of any // mutable for `r`. @@ -157,7 +159,7 @@ prefixed_export! { // Nothing aliases `n` let n = unsafe { core::slice::from_raw_parts(n, num_limbs) }; - let mut tmp = [0; 2 * super::BIGINT_MODULUS_MAX_LIMBS]; + let mut tmp = [0; 2 * MAX_LIMBS]; let tmp = &mut tmp[..(2 * num_limbs)]; { let a: &[Limb] = unsafe { core::slice::from_raw_parts(a, num_limbs) }; @@ -269,6 +271,7 @@ pub(super) fn limbs_square_mont(r: &mut [Limb], n: &[Limb], n0: &N0, _cpu: cpu:: #[cfg(test)] mod tests { + use super::super::MAX_LIMBS; use super::*; use crate::limb::Limb; @@ -290,7 +293,7 @@ mod tests { ]; for (i, (r_input, a, w, expected_retval, expected_r)) in TEST_CASES.iter().enumerate() { - let mut r = [0; super::super::BIGINT_MODULUS_MAX_LIMBS]; + let mut r = [0; MAX_LIMBS]; let r = { let r = &mut r[..r_input.len()]; r.copy_from_slice(r_input);