Skip to content

Commit

Permalink
arithmetic: Clarify memory safety of some binary-ish ops.
Browse files Browse the repository at this point in the history
  • Loading branch information
briansmith committed Jan 26, 2025
1 parent 66882b3 commit 5077021
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
28 changes: 15 additions & 13 deletions src/arithmetic/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,18 @@ pub(crate) use self::{
modulusvalue::OwnedModulusValue,
private_exponent::PrivateExponent,
};
use super::{montgomery::*, LimbSliceError, MAX_LIMBS};
use super::{inout::AliasingSlices3, montgomery::*, LimbSliceError, MAX_LIMBS};
use crate::{
bits::BitLength,
c,
error::{self, LenMismatchError},
limb::{self, Limb, LIMB_BITS},
};
use alloc::vec;
use core::{marker::PhantomData, num::NonZeroU64};
use core::{
marker::PhantomData,
num::{NonZeroU64, NonZeroUsize},
};

mod boxed_limbs;
mod modulus;
Expand Down Expand Up @@ -233,7 +236,8 @@ pub fn elem_widen<Larger, Smaller>(

// TODO: Document why this works for all Montgomery factors.
pub fn elem_add<M, E>(mut a: Elem<M, E>, b: Elem<M, E>, m: &Modulus<M>) -> Elem<M, E> {
limb::limbs_add_assign_mod(&mut a.limbs, &b.limbs, m.limbs());
limb::limbs_add_assign_mod(&mut a.limbs, &b.limbs, m.limbs())
.unwrap_or_else(unwrap_impossible_len_mismatch_error);
a
}

Expand All @@ -246,18 +250,16 @@ pub fn elem_sub<M, E>(mut a: Elem<M, E>, b: &Elem<M, E>, m: &Modulus<M>) -> Elem
a: *const Limb,
b: *const Limb,
m: *const Limb,
num_limbs: c::size_t,
);
}
unsafe {
LIMBS_sub_mod(
a.limbs.as_mut_ptr(),
a.limbs.as_ptr(),
b.limbs.as_ptr(),
m.limbs().as_ptr(),
m.limbs().len(),
num_limbs: c::NonZero_size_t,
);
}
let num_limbs = NonZeroUsize::new(m.limbs().len()).unwrap();
(a.limbs.as_mut(), b.limbs.as_ref())
.with_non_dangling_non_null_pointers_rab(num_limbs, |r, a, b| {
let m = m.limbs().as_ptr(); // Also non-dangling because num_limbs is non-zero.
unsafe { LIMBS_sub_mod(r, a, b, m, num_limbs) }
})
.unwrap_or_else(unwrap_impossible_len_mismatch_error);
a
}

Expand Down
3 changes: 2 additions & 1 deletion src/ec/suite_b/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ impl<M> Modulus<M> {
&mut a.limbs[..num_limbs],
&b.limbs[..num_limbs],
&self.limbs[..num_limbs],
);
)
.unwrap_or_else(unwrap_impossible_len_mismatch_error)
}
}

Expand Down
17 changes: 12 additions & 5 deletions src/limb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
//! limbs use the native endianness.
use crate::{
arithmetic::inout::AliasingSlices3,
c, constant_time,
error::{self, LenMismatchError},
polyfill::{sliceutil, usize_from_u32, ArrayFlatMap},
Expand Down Expand Up @@ -325,20 +326,26 @@ pub fn fold_5_bit_windows<R, I: FnOnce(Window) -> R, F: Fn(R, Window) -> R>(
}

#[inline]
pub(crate) fn limbs_add_assign_mod(a: &mut [Limb], b: &[Limb], m: &[Limb]) {
debug_assert_eq!(a.len(), m.len());
debug_assert_eq!(b.len(), m.len());
pub(crate) fn limbs_add_assign_mod(
a: &mut [Limb],
b: &[Limb],
m: &[Limb],
) -> Result<(), LenMismatchError> {
prefixed_extern! {
// `r` and `a` may alias.
fn LIMBS_add_mod(
r: *mut Limb,
a: *const Limb,
b: *const Limb,
m: *const Limb,
num_limbs: c::size_t,
num_limbs: c::NonZero_size_t,
);
}
unsafe { LIMBS_add_mod(a.as_mut_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), m.len()) }
let num_limbs = NonZeroUsize::new(m.len()).ok_or_else(|| LenMismatchError::new(m.len()))?;
(a, b).with_non_dangling_non_null_pointers_rab(num_limbs, |r, a, b| {
let m = m.as_ptr(); // Also non-dangling because `num_limbs` is non-zero.
unsafe { LIMBS_add_mod(r, a, b, m, num_limbs) }
})
}

// r *= 2 (mod m).
Expand Down

0 comments on commit 5077021

Please sign in to comment.