Skip to main content

crypto_bigint/uint/boxed/
cmp.rs

1//! [`BoxedUint`] comparisons.
2//!
3//! By default these are all constant-time and use the `subtle` crate.
4
5pub(super) use core::cmp::{Ordering, max};
6
7use super::BoxedUint;
8use crate::{CtEq, UintRef};
9
10impl BoxedUint {
11    /// Returns the Ordering between `self` and `rhs` in variable time.
12    #[must_use]
13    pub fn cmp_vartime(&self, rhs: impl AsRef<UintRef>) -> Ordering {
14        self.as_uint_ref().cmp_vartime(rhs.as_ref())
15    }
16
17    /// Determine in variable time whether the `self` is zero.
18    pub(crate) fn is_zero_vartime(&self) -> bool {
19        !self.limbs.iter().any(|l| l.0 != 0)
20    }
21}
22
23impl Eq for BoxedUint {}
24
25impl<Rhs: AsRef<UintRef> + ?Sized> PartialEq<Rhs> for BoxedUint {
26    fn eq(&self, other: &Rhs) -> bool {
27        self.ct_eq(other).into()
28    }
29}
30
31impl Ord for BoxedUint {
32    fn cmp(&self, other: &Self) -> Ordering {
33        UintRef::cmp(self.as_uint_ref(), other.as_ref())
34    }
35}
36
37impl<Rhs: AsRef<UintRef> + ?Sized> PartialOrd<Rhs> for BoxedUint {
38    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
39        Some(UintRef::cmp(self.as_uint_ref(), other.as_ref()))
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::BoxedUint;
46    use core::cmp::Ordering;
47
48    #[test]
49    fn cmp() {
50        let a = BoxedUint::zero();
51        let b = BoxedUint::one();
52        let c = BoxedUint::max(128);
53
54        assert_eq!(a.cmp(&b), Ordering::Less);
55        assert_eq!(a.cmp(&c), Ordering::Less);
56        assert_eq!(b.cmp(&c), Ordering::Less);
57
58        assert_eq!(a.cmp(&a), Ordering::Equal);
59        assert_eq!(b.cmp(&b), Ordering::Equal);
60        assert_eq!(c.cmp(&c), Ordering::Equal);
61
62        assert_eq!(b.cmp(&a), Ordering::Greater);
63        assert_eq!(c.cmp(&a), Ordering::Greater);
64        assert_eq!(c.cmp(&b), Ordering::Greater);
65    }
66
67    #[test]
68    fn cmp_uintref() {
69        let a = BoxedUint::zero();
70        let b = BoxedUint::one();
71        let c = BoxedUint::max(128);
72
73        assert_eq!(a.partial_cmp(b.as_uint_ref()), Some(Ordering::Less));
74        assert_eq!(a.partial_cmp(c.as_uint_ref()), Some(Ordering::Less));
75        assert_eq!(b.partial_cmp(c.as_uint_ref()), Some(Ordering::Less));
76
77        assert_eq!(a.partial_cmp(a.as_uint_ref()), Some(Ordering::Equal));
78        assert_eq!(b.partial_cmp(b.as_uint_ref()), Some(Ordering::Equal));
79        assert_eq!(c.partial_cmp(c.as_uint_ref()), Some(Ordering::Equal));
80
81        assert_eq!(b.partial_cmp(a.as_uint_ref()), Some(Ordering::Greater));
82        assert_eq!(c.partial_cmp(a.as_uint_ref()), Some(Ordering::Greater));
83        assert_eq!(c.partial_cmp(b.as_uint_ref()), Some(Ordering::Greater));
84    }
85}