Skip to content

Commit

Permalink
montgomery: Enforce maximum limb length with a runtime check.
Browse files Browse the repository at this point in the history
Further clarify the memory safety.
  • Loading branch information
briansmith committed Dec 6, 2023
1 parent 034ac09 commit 1068786
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 13 deletions.
4 changes: 0 additions & 4 deletions src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,4 @@ pub mod bigint;
pub mod montgomery;

mod n0;

#[allow(dead_code)]
const BIGINT_MODULUS_MAX_LIMBS: usize = 8192 / crate::limb::LIMB_BITS;

pub use constant::limbs_from_hex;
4 changes: 2 additions & 2 deletions src/arithmetic/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn from_montgomery_amm<M>(limbs: BoxedLimbs<M>, m: &Modulus<M>) -> Elem<M, Unenc
debug_assert_eq!(limbs.len(), m.limbs().len());

let mut limbs = limbs;
let mut one = [0; MODULUS_MAX_LIMBS];
let mut one = [0; MAX_LIMBS];
one[0] = 1;
let one = &one[..m.limbs().len()];
limbs_mont_mul(&mut limbs, one, m.limbs(), m.n0(), m.cpu_features()).unwrap();
Expand Down Expand Up @@ -187,7 +187,7 @@ pub fn elem_reduced<Larger, Smaller>(
// `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);

Expand Down
4 changes: 2 additions & 2 deletions src/arithmetic/bigint/modulus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
};
use core::marker::PhantomData;

pub const MODULUS_MAX_LIMBS: usize = super::super::BIGINT_MODULUS_MAX_LIMBS;
pub const MODULUS_MAX_LIMBS: usize = montgomery::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
Expand Down Expand Up @@ -89,7 +89,7 @@ impl<M> OwnedModulus<M> {
cpu_features: cpu::Features,
) -> Result<Self, error::KeyRejected> {
let n = BoxedLimbs::positive_minimal_width_from_be_bytes(input)?;
if n.len() > MODULUS_MAX_LIMBS {
if n.len() > montgomery::MAX_LIMBS {
return Err(error::KeyRejected::too_large());
}
if n.len() < montgomery::MIN_LIMBS {
Expand Down
12 changes: 9 additions & 3 deletions src/arithmetic/montgomery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ use crate::{bssl, c, limb::Limb};
/// same.
pub const MIN_LIMBS: usize = 4;

/// Many functions, including assembly functions, will stack allocate
/// `n * MAX_LIMBS` (for some `n`) limbs to store temporary values. Reduce the
/// chance of stack overflows by limiting these functions according to the
/// maximum size of modulus we wish to support.
pub const MAX_LIMBS: usize = 8192 / crate::limb::LIMB_BITS;

#[inline(always)]
unsafe fn mul_mont(
r: *mut Limb,
Expand All @@ -128,7 +134,7 @@ unsafe fn mul_mont(
n0: &N0,
_: cpu::Features,
) -> Result<(), error::Unspecified> {
if m.len() < MIN_LIMBS {
if m.len() < MIN_LIMBS || m.len() > MAX_LIMBS {
return Err(error::Unspecified);
}
bn_mul_mont(r, a, b, m.as_ptr(), n0, m.len());
Expand Down Expand Up @@ -159,7 +165,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) };
Expand Down Expand Up @@ -326,7 +332,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);
Expand Down
7 changes: 6 additions & 1 deletion src/ec/suite_b/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

use crate::{arithmetic::limbs_from_hex, arithmetic::montgomery::*, error, limb::*};
use crate::{
arithmetic::limbs_from_hex,
arithmetic::montgomery::{Encoding, ProductEncoding, Unencoded, R, RR},
error,
limb::*,
};
use core::marker::PhantomData;

pub use self::elem::*;
Expand Down
5 changes: 4 additions & 1 deletion src/ec/suite_b/ops/elem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use crate::{
arithmetic::{
limbs_from_hex,
montgomery::{Encoding, ProductEncoding},
montgomery::{self, Encoding, ProductEncoding},
},
limb::{Limb, LIMB_BITS},
};
Expand Down Expand Up @@ -129,3 +129,6 @@ pub fn unary_op_from_binary_op_assign<M, E: Encoding>(
}

pub const MAX_LIMBS: usize = (384 + (LIMB_BITS - 1)) / LIMB_BITS;

#[allow(clippy::assertions_on_constants)]
const _MAX_LIMBS_IS_LESS_THAN_MAX_LIMBS: () = assert!(MAX_LIMBS <= montgomery::MAX_LIMBS);

0 comments on commit 1068786

Please sign in to comment.