diff --git a/src/arithmetic/bigint.rs b/src/arithmetic/bigint.rs index f512f89c2..f32ca8c92 100644 --- a/src/arithmetic/bigint.rs +++ b/src/arithmetic/bigint.rs @@ -172,7 +172,8 @@ pub fn elem_reduced_once( assert_eq!(m.len_bits(), other_modulus_len_bits); let mut r = a.limbs.clone(); - limb::limbs_reduce_once_constant_time(&mut r, m.limbs()); + limb::limbs_reduce_once_constant_time(&mut r, m.limbs()) + .unwrap_or_else(unwrap_impossible_len_mismatch_error); Elem { limbs: BoxedLimbs::new_unchecked(r.into_limbs()), encoding: PhantomData, diff --git a/src/ec/suite_b/ops.rs b/src/ec/suite_b/ops.rs index f9a7514ff..baee45881 100644 --- a/src/ec/suite_b/ops.rs +++ b/src/ec/suite_b/ops.rs @@ -493,7 +493,8 @@ impl Modulus { pub fn elem_reduced_to_scalar(&self, elem: &Elem) -> Scalar { let num_limbs = self.num_limbs.into(); let mut r_limbs = elem.limbs; - limbs_reduce_once_constant_time(&mut r_limbs[..num_limbs], &self.limbs[..num_limbs]); + limbs_reduce_once_constant_time(&mut r_limbs[..num_limbs], &self.limbs[..num_limbs]) + .unwrap_or_else(unwrap_impossible_len_mismatch_error); Scalar { limbs: r_limbs, m: PhantomData, @@ -575,7 +576,8 @@ pub(super) fn scalar_parse_big_endian_partially_reduced_variable_consttime( { let r = &mut r.limbs[..num_limbs]; parse_big_endian_and_pad_consttime(bytes, r)?; - limbs_reduce_once_constant_time(r, &n.limbs[..num_limbs]); + limbs_reduce_once_constant_time(r, &n.limbs[..num_limbs]) + .unwrap_or_else(unwrap_impossible_len_mismatch_error); } Ok(r) diff --git a/src/limb.rs b/src/limb.rs index 6d042c1f7..e1e448f79 100644 --- a/src/limb.rs +++ b/src/limb.rs @@ -156,12 +156,15 @@ pub fn limbs_minimal_bits(a: &[Limb]) -> bits::BitLength { /// Equivalent to `if (r >= m) { r -= m; }` #[inline] -pub fn limbs_reduce_once_constant_time(r: &mut [Limb], m: &[Limb]) { +pub fn limbs_reduce_once_constant_time(r: &mut [Limb], m: &[Limb]) -> Result<(), LenMismatchError> { prefixed_extern! { - fn LIMBS_reduce_once(r: *mut Limb, m: *const Limb, num_limbs: c::size_t); + fn LIMBS_reduce_once(r: *mut Limb, m: *const Limb, num_limbs: c::NonZero_size_t); } - assert_eq!(r.len(), m.len()); - unsafe { LIMBS_reduce_once(r.as_mut_ptr(), m.as_ptr(), m.len()) }; + let num_limbs = NonZeroUsize::new(r.len()).ok_or_else(|| LenMismatchError::new(m.len()))?; + let r = r.as_mut_ptr(); // Non-dangling because num_limbs is non-zero. + let m = m.as_ptr(); // Non-dangling because num_limbs is non-zero. + unsafe { LIMBS_reduce_once(r, m, num_limbs) }; + Ok(()) } #[derive(Clone, Copy, PartialEq)]