Skip to main content

oxicrypto_core/
ct.rs

1/// Constant-time byte-slice equality comparison.
2///
3/// Returns `true` if `a` and `b` are equal.  The comparison time depends only
4/// on the length of the shorter slice, never on the position of the first
5/// differing byte.
6#[must_use]
7pub fn ct_eq(a: &[u8], b: &[u8]) -> bool {
8    use subtle::ConstantTimeEq as _;
9    if a.len() != b.len() {
10        return false;
11    }
12    a.ct_eq(b).into()
13}
14
15/// Constant-time check whether every byte in `data` is zero.
16///
17/// Returns `true` only if all bytes are `0x00`.  The runtime is proportional
18/// to `data.len()`, regardless of the actual content.
19#[must_use]
20pub fn ct_is_zero(data: &[u8]) -> bool {
21    use subtle::ConstantTimeEq as _;
22    let mut acc: u8 = 0;
23    for &b in data {
24        acc |= b;
25    }
26    acc.ct_eq(&0u8).into()
27}
28
29/// Constant-time conditional select: returns `a` if `choice` is `0`,
30/// or `b` if `choice` is `1`.  Any other `choice` value is treated as `1`.
31#[must_use]
32pub fn ct_select(a: u8, b: u8, choice: u8) -> u8 {
33    use subtle::ConditionallySelectable;
34    let c = subtle::Choice::from(choice & 1);
35    u8::conditional_select(&a, &b, c)
36}