Skip to content

Commit fde8086

Browse files
committed
Use the Hacker's Delight integer comparison for Limb's subtle impls
1 parent 6b6e22c commit fde8086

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

src/const_choice.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,19 @@ impl ConstChoice {
7171
/// Returns the truthy value if `x < y`, and the falsy value otherwise.
7272
#[inline]
7373
pub(crate) const fn from_word_lt(x: Word, y: Word) -> Self {
74+
// See "Hacker's Delight" 2nd ed, section 2-12 (Comparison predicates)
7475
let bit = (((!x) & y) | (((!x) | y) & (x.wrapping_sub(y)))) >> (Word::BITS - 1);
7576
Self::from_word_lsb(bit)
7677
}
7778

79+
/// Returns the truthy value if `x > y`, and the falsy value otherwise.
80+
#[inline]
81+
pub(crate) const fn from_word_gt(x: Word, y: Word) -> Self {
82+
// See "Hacker's Delight" 2nd ed, section 2-12 (Comparison predicates)
83+
let bit = (((!y) & x) | (((!y) | x) & (y.wrapping_sub(x)))) >> (Word::BITS - 1);
84+
Self::from_word_lsb(bit)
85+
}
86+
7887
/// Returns the truthy value if `x < y`, and the falsy value otherwise.
7988
#[inline]
8089
pub(crate) const fn from_u32_lt(x: u32, y: u32) -> Self {
@@ -169,6 +178,20 @@ mod tests {
169178
use super::ConstChoice;
170179
use crate::Word;
171180

181+
#[test]
182+
fn from_word_lt() {
183+
assert_eq!(ConstChoice::from_word_lt(4, 5), ConstChoice::TRUE);
184+
assert_eq!(ConstChoice::from_word_lt(5, 5), ConstChoice::FALSE);
185+
assert_eq!(ConstChoice::from_word_lt(6, 5), ConstChoice::FALSE);
186+
}
187+
188+
#[test]
189+
fn from_word_gt() {
190+
assert_eq!(ConstChoice::from_word_gt(4, 5), ConstChoice::FALSE);
191+
assert_eq!(ConstChoice::from_word_gt(5, 5), ConstChoice::FALSE);
192+
assert_eq!(ConstChoice::from_word_gt(6, 5), ConstChoice::TRUE);
193+
}
194+
172195
#[test]
173196
fn select() {
174197
let a: Word = 1;

src/limb/cmp.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,14 @@ impl ConstantTimeEq for Limb {
5454
impl ConstantTimeGreater for Limb {
5555
#[inline]
5656
fn ct_gt(&self, other: &Self) -> Choice {
57-
let borrow = other.sbb(*self, Limb::ZERO).1;
58-
Choice::from(borrow.0 as u8 & 1)
57+
ConstChoice::from_word_gt(self.0, other.0).into()
5958
}
6059
}
6160

6261
impl ConstantTimeLess for Limb {
6362
#[inline]
6463
fn ct_lt(&self, other: &Self) -> Choice {
65-
let borrow = self.sbb(*other, Limb::ZERO).1;
66-
Choice::from(borrow.0 as u8 & 1)
64+
ConstChoice::from_word_lt(self.0, other.0).into()
6765
}
6866
}
6967

src/modular/boxed_residue/mul.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ fn sub_vv(z: &mut [Limb], x: &[Limb], y: &[Limb]) -> Limb {
247247
for (i, (&xi, &yi)) in x.iter().zip(y.iter()).enumerate().take(z.len()) {
248248
let zi = xi.wrapping_sub(yi).wrapping_sub(c);
249249
z[i] = zi;
250-
// see "Hacker's Delight", section 2-12 (overflow detection)
250+
// See "Hacker's Delight" 2nd ed, section 2-13 (Overflow detection)
251251
c = ((yi & !xi) | ((yi | !xi) & zi)) >> (Word::BITS - 1)
252252
}
253253

0 commit comments

Comments
 (0)