Coverage Report

Created: 2026-11-12 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/crypto-bigint-0.7.10/src/limb/cmp.rs
Line
Count
Source
1
//! Limb comparisons
2
3
use crate::{Choice, CtAssign, CtEq, CtGt, CtLt, Limb, word};
4
use core::cmp::Ordering;
5
6
impl Limb {
7
    /// Is this limb an odd number?
8
    #[inline]
9
    #[must_use]
10
0
    pub fn is_odd(self) -> Choice {
11
0
        word::choice_from_lsb(self.0 & 1)
12
0
    }
13
14
    /// Perform a comparison of the inner value in variable-time.
15
    ///
16
    /// Note that the [`PartialOrd`] and [`Ord`] impls wrap constant-time
17
    /// comparisons using the `subtle` crate.
18
    #[must_use]
19
0
    pub fn cmp_vartime(self, other: Self) -> Ordering {
20
0
        self.0.cmp(&other.0)
21
0
    }
22
23
    /// Performs an equality check in variable-time.
24
    #[must_use]
25
0
    pub const fn eq_vartime(self, other: Self) -> bool {
26
0
        self.0 == other.0
27
0
    }
28
29
    /// Returns the truthy value if `self != 0` and the falsy value otherwise.
30
    #[inline]
31
672k
    pub(crate) const fn is_nonzero(self) -> Choice {
32
672k
        word::choice_from_nz(self.0)
33
672k
    }
<crypto_bigint::limb::Limb>::is_nonzero
Line
Count
Source
31
672k
    pub(crate) const fn is_nonzero(self) -> Choice {
32
672k
        word::choice_from_nz(self.0)
33
672k
    }
Unexecuted instantiation: <crypto_bigint::limb::Limb>::is_nonzero
34
}
35
36
impl Eq for Limb {}
37
38
impl Ord for Limb {
39
0
    fn cmp(&self, other: &Self) -> Ordering {
40
0
        let mut ret = Ordering::Less;
41
0
        ret.ct_assign(&Ordering::Equal, self.ct_eq(other));
42
0
        ret.ct_assign(&Ordering::Greater, self.ct_gt(other));
43
0
        debug_assert_eq!(ret == Ordering::Less, bool::from(self.ct_lt(other)));
44
0
        ret
45
0
    }
46
}
47
48
impl PartialOrd for Limb {
49
    #[inline]
50
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
51
0
        Some(self.cmp(other))
52
0
    }
53
}
54
55
impl PartialEq for Limb {
56
    #[inline]
57
0
    fn eq(&self, other: &Self) -> bool {
58
0
        self.ct_eq(other).into()
59
0
    }
60
}
61
62
#[cfg(test)]
63
mod tests {
64
    use crate::{Choice, Limb};
65
    use core::cmp::Ordering;
66
67
    #[test]
68
    fn is_zero() {
69
        assert!(bool::from(Limb::ZERO.is_zero()));
70
        assert!(!bool::from(Limb::ONE.is_zero()));
71
        assert!(!bool::from(Limb::MAX.is_zero()));
72
    }
73
74
    #[test]
75
    fn is_odd() {
76
        assert!(!bool::from(Limb::ZERO.is_odd()));
77
        assert!(bool::from(Limb::ONE.is_odd()));
78
        assert!(bool::from(Limb::MAX.is_odd()));
79
    }
80
81
    #[test]
82
    fn cmp() {
83
        assert_eq!(Limb::ZERO.cmp(&Limb::ONE), Ordering::Less);
84
        assert_eq!(Limb::ONE.cmp(&Limb::ONE), Ordering::Equal);
85
        assert_eq!(Limb::MAX.cmp(&Limb::ONE), Ordering::Greater);
86
    }
87
88
    #[test]
89
    fn ct_conditional_swap() {
90
        let mut a = Limb::MAX;
91
        let mut b = Limb::ZERO;
92
93
        Limb::ct_conditional_swap(&mut a, &mut b, Choice::FALSE);
94
        assert_eq!(a, Limb::MAX);
95
        assert_eq!(b, Limb::ZERO);
96
97
        Limb::ct_conditional_swap(&mut a, &mut b, Choice::TRUE);
98
        assert_eq!(a, Limb::ZERO);
99
        assert_eq!(b, Limb::MAX);
100
    }
101
}