Skip to content

Commit

Permalink
arithmetic internals: Iterate over slice in Rust for even/zero checks.
Browse files Browse the repository at this point in the history
  • Loading branch information
briansmith committed Jan 24, 2025
1 parent 3c5946f commit da0340b
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 23 deletions.
4 changes: 2 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -865,9 +865,9 @@ fn prefix_all_symbols(pp: char, prefix_prefix: &str, prefix: &str) -> String {
"ChaCha20_ctr32_nohw",
"ChaCha20_ctr32_ssse3",
"ChaCha20_ctr32_ssse3_4x",
"LIMB_is_zero",
"LIMB_is_even",
"LIMBS_add_mod",
"LIMBS_are_even",
"LIMBS_are_zero",
"LIMBS_equal",
"LIMBS_equal_limb",
"LIMBS_less_than",
Expand Down
23 changes: 10 additions & 13 deletions crypto/limbs/limbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,19 @@
* but we haven't verified that assumption. TODO: Fix it so we don't need to
* make that assumption. */

/* Returns 0xfff..f if |a| is zero, and zero otherwise. */
Limb LIMB_is_zero(const Limb a) {
return constant_time_is_zero_w(a);
}

/* Returns 0xfff..f if |a| is all zero limbs, and zero otherwise. |num_limbs|
* may be zero. */
Limb LIMBS_are_zero(const Limb a[], size_t num_limbs) {
Limb is_zero = CONSTTIME_TRUE_W;
Limb all = 0;
for (size_t i = 0; i < num_limbs; ++i) {
is_zero = constant_time_select_w(is_zero, constant_time_is_zero_w(a[i]),
is_zero);
all |= a[i];
}
return is_zero;
return LIMB_is_zero(all);
}

/* Returns 0xffff..f if |a == b|, and zero otherwise. |num_limbs| may be zero. */
Expand All @@ -54,15 +58,8 @@ Limb LIMBS_equal_limb(const Limb a[], Limb b, size_t num_limbs) {
return constant_time_select_w(lo_equal, hi_zero, 0);
}

/* Returns 0xfff..f if |a| is all zero limbs, and zero otherwise.
* |num_limbs| may be zero. */
Limb LIMBS_are_even(const Limb a[], size_t num_limbs) {
Limb lo;
if (num_limbs == 0) {
lo = 0;
} else {
lo = a[0];
}
/* Returns 0xfff..f if |a| is even, 0 otherwise. */
Limb LIMB_is_even(Limb lo) {
return constant_time_is_zero_w(lo & 1);
}

Expand Down
1 change: 0 additions & 1 deletion crypto/limbs/limbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ typedef crypto_word_t Limb;


Limb LIMBS_are_zero(const Limb a[], size_t num_limbs);
Limb LIMBS_are_even(const Limb a[], size_t num_limbs);
Limb LIMBS_equal(const Limb a[], const Limb b[], size_t num_limbs);
Limb LIMBS_equal_limb(const Limb a[], Limb b, size_t num_limbs);
void LIMBS_reduce_once(Limb r[], const Limb m[], size_t num_limbs);
Expand Down
18 changes: 11 additions & 7 deletions src/limb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ pub fn limbs_equal_limbs_consttime(a: &[Limb], b: &[Limb]) -> LimbMask {
prefixed_extern! {
fn LIMBS_equal(a: *const Limb, b: *const Limb, num_limbs: c::size_t) -> LimbMask;
}

assert_eq!(a.len(), b.len());
unsafe { LIMBS_equal(a.as_ptr(), b.as_ptr(), a.len()) }
}
Expand Down Expand Up @@ -89,11 +88,16 @@ pub fn limbs_less_than_limbs_vartime(a: &[Limb], b: &[Limb]) -> Result<bool, Len
}

#[inline]
pub fn limbs_are_zero_constant_time(limbs: &[Limb]) -> LimbMask {
fn limb_is_zero_constant_time(limb: Limb) -> LimbMask {
prefixed_extern! {
fn LIMBS_are_zero(a: *const Limb, num_limbs: c::size_t) -> LimbMask;
fn LIMB_is_zero(limb: Limb) -> LimbMask;
}
unsafe { LIMBS_are_zero(limbs.as_ptr(), limbs.len()) }
unsafe { LIMB_is_zero(limb) }
}

#[inline]
pub fn limbs_are_zero_constant_time(limbs: &[Limb]) -> LimbMask {
limb_is_zero_constant_time(limbs.iter().fold(0, |a, b| a | b))
}

/// Leaks one bit of information (other than the lengths of the inputs):
Expand All @@ -102,10 +106,10 @@ pub fn limbs_are_zero_constant_time(limbs: &[Limb]) -> LimbMask {
#[inline]
pub fn limbs_reject_even_leak_bit(limbs: &[Limb]) -> Result<(), error::Unspecified> {
prefixed_extern! {
fn LIMBS_are_even(a: *const Limb, num_limbs: c::NonZero_size_t) -> LimbMask;
fn LIMB_is_even(limb: Limb) -> LimbMask;
}
let len = NonZeroUsize::new(limbs.len()).ok_or(error::Unspecified)?;
let r = unsafe { LIMBS_are_even(limbs.as_ptr(), len) };
let bottom = *limbs.first().ok_or(error::Unspecified)?;
let r = unsafe { LIMB_is_even(bottom) };
if r.leak() {
return Err(error::Unspecified);
}
Expand Down

0 comments on commit da0340b

Please sign in to comment.