Skip to content

Commit 3b6064e

Browse files
authored
word: delegate some ops to ctutils::Choice (#1042)
Conditionally calls certain `u32`/`u64`/`u128` bit twiddling operations defined on `ctutils::Choice` based on `target_pointer_width`, rather than duplicating non-trivial implementations in `ctutils`. This also goes ahead and bumps to the `ctutils` v0.1.2 crate release to pick up the relevant functions.
1 parent cce7cc7 commit 3b6064e

File tree

3 files changed

+61
-53
lines changed

3 files changed

+61
-53
lines changed

Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ edition = "2024"
1717
rust-version = "1.85"
1818

1919
[dependencies]
20-
ctutils = { version = "0.1.1", features = ["subtle"] }
20+
ctutils = { version = "0.1.2", features = ["subtle"] }
2121
subtle = { version = "2.6", default-features = false }
2222

2323
# optional dependencies
@@ -86,6 +86,3 @@ harness = false
8686

8787
[profile.dev]
8888
opt-level = 2
89-
90-
[patch.crates-io.ctutils]
91-
git = "https://github.com/RustCrypto/utils"

src/word.rs

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,70 @@ use crate::ConstChoice;
66
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
77
compile_error!("this crate builds on 32-bit and 64-bit platforms only");
88

9-
//
10-
// 32-bit definitions
11-
//
12-
13-
/// Inner integer type that the [`Limb`] newtype wraps.
9+
/// 32-bit definitions
1410
#[cfg(target_pointer_width = "32")]
15-
pub type Word = u32;
11+
mod word32 {
12+
use crate::ConstChoice;
1613

17-
/// Unsigned wide integer type: double the width of [`Word`].
18-
#[cfg(target_pointer_width = "32")]
19-
pub type WideWord = u64;
14+
/// Inner integer type that the [`Limb`] newtype wraps.
15+
pub type Word = u32;
16+
17+
/// Unsigned wide integer type: double the width of [`Word`].
18+
pub type WideWord = u64;
19+
20+
/// Returns the truthy value if `x <= y` and the falsy value otherwise.
21+
#[inline]
22+
pub(crate) const fn from_word_le(x: Word, y: Word) -> ConstChoice {
23+
ConstChoice::from_u32_le(x, y)
24+
}
2025

21-
//
22-
// 64-bit definitions
23-
//
26+
/// Returns the truthy value if `x < y`, and the falsy value otherwise.
27+
#[inline]
28+
pub(crate) const fn from_word_lt(x: Word, y: Word) -> ConstChoice {
29+
ConstChoice::from_u32_lt(x, y)
30+
}
31+
32+
/// Returns the truthy value if `x <= y` and the falsy value otherwise.
33+
#[inline]
34+
pub(crate) const fn from_wide_word_le(x: WideWord, y: WideWord) -> ConstChoice {
35+
ConstChoice::from_u64_le(x, y)
36+
}
37+
}
2438

25-
/// Unsigned integer type that the [`Limb`][`crate::Limb`] newtype wraps.
39+
/// 64-bit definitions
2640
#[cfg(target_pointer_width = "64")]
27-
pub type Word = u64;
41+
mod word64 {
42+
use crate::ConstChoice;
43+
44+
/// Unsigned integer type that the [`Limb`][`crate::Limb`] newtype wraps.
45+
pub type Word = u64;
46+
47+
/// Wide integer type: double the width of [`Word`].
48+
pub type WideWord = u128;
49+
50+
/// Returns the truthy value if `x <= y` and the falsy value otherwise.
51+
#[inline]
52+
pub(crate) const fn from_word_le(x: Word, y: Word) -> ConstChoice {
53+
ConstChoice::from_u64_le(x, y)
54+
}
55+
56+
/// Returns the truthy value if `x < y`, and the falsy value otherwise.
57+
#[inline]
58+
pub(crate) const fn from_word_lt(x: Word, y: Word) -> ConstChoice {
59+
ConstChoice::from_u64_lt(x, y)
60+
}
61+
62+
/// Returns the truthy value if `x <= y` and the falsy value otherwise.
63+
#[inline]
64+
pub(crate) const fn from_wide_word_le(x: WideWord, y: WideWord) -> ConstChoice {
65+
ConstChoice::from_u128_le(x, y)
66+
}
67+
}
2868

29-
/// Wide integer type: double the width of [`Word`].
69+
#[cfg(target_pointer_width = "32")]
70+
pub use word32::*;
3071
#[cfg(target_pointer_width = "64")]
31-
pub type WideWord = u128;
72+
pub use word64::*;
3273

3374
/// Returns the truthy value if `x == y`, and the falsy value otherwise.
3475
#[inline]
@@ -42,29 +83,13 @@ pub(crate) const fn from_word_gt(x: Word, y: Word) -> ConstChoice {
4283
from_word_lt(y, x)
4384
}
4485

45-
/// Returns the truthy value if `x <= y` and the falsy value otherwise.
46-
#[inline]
47-
pub(crate) const fn from_word_le(x: Word, y: Word) -> ConstChoice {
48-
// See "Hacker's Delight" 2nd ed, section 2-12 (Comparison predicates)
49-
let bit = (((!x) | y) & ((x ^ y) | !(y.wrapping_sub(x)))) >> (Word::BITS - 1);
50-
from_word_lsb(bit)
51-
}
52-
5386
/// Returns the truthy value if `value == 1`, and the falsy value if `value == 0`.
5487
/// Panics for other values.
5588
#[inline]
5689
pub(crate) const fn from_word_lsb(value: Word) -> ConstChoice {
5790
ConstChoice::new((value & 1) as u8)
5891
}
5992

60-
/// Returns the truthy value if `x < y`, and the falsy value otherwise.
61-
#[inline]
62-
pub(crate) const fn from_word_lt(x: Word, y: Word) -> ConstChoice {
63-
// See "Hacker's Delight" 2nd ed, section 2-12 (Comparison predicates)
64-
let bit = (((!x) & y) | (((!x) | y) & (x.wrapping_sub(y)))) >> (Word::BITS - 1);
65-
from_word_lsb(bit)
66-
}
67-
6893
/// Returns the truthy value if `value == Word::MAX`, and the falsy value if `value == 0`.
6994
/// Panics for other values.
7095
#[inline]
@@ -85,21 +110,6 @@ pub(crate) const fn from_word_nonzero(value: Word) -> ConstChoice {
85110
from_word_lsb((value | value.wrapping_neg()) >> (Word::BITS - 1))
86111
}
87112

88-
/// Returns the truthy value if `x <= y` and the falsy value otherwise.
89-
#[inline]
90-
pub(crate) const fn from_wide_word_le(x: WideWord, y: WideWord) -> ConstChoice {
91-
// See "Hacker's Delight" 2nd ed, section 2-12 (Comparison predicates)
92-
let bit = (((!x) | y) & ((x ^ y) | !(y.wrapping_sub(x)))) >> (WideWord::BITS - 1);
93-
from_wide_word_lsb(bit)
94-
}
95-
96-
/// Returns the truthy value if `value == 1`, and the falsy value if `value == 0`.
97-
/// Panics for other values.
98-
#[inline]
99-
pub(crate) const fn from_wide_word_lsb(value: WideWord) -> ConstChoice {
100-
ConstChoice::new((value & 1) as u8)
101-
}
102-
103113
/// Return `b` if `self` is truthy, otherwise return `a`.
104114
#[inline]
105115
pub(crate) const fn select_word(choice: ConstChoice, a: Word, b: Word) -> Word {

0 commit comments

Comments
 (0)