crypto_bigint/uint/
cmp.rs1use core::cmp::Ordering;
6
7use super::Uint;
8use crate::{Choice, CtEq, Limb, UintRef};
9
10impl<const LIMBS: usize> Uint<LIMBS> {
11 #[inline]
13 #[must_use]
14 pub const fn is_nonzero(&self) -> Choice {
15 self.as_uint_ref().is_nonzero()
16 }
17
18 #[inline]
20 #[must_use]
21 pub const fn is_zero_vartime(&self) -> bool {
22 self.as_uint_ref().is_zero_vartime()
23 }
24
25 #[inline]
27 #[must_use]
28 pub const fn is_odd(&self) -> Choice {
29 self.as_uint_ref().is_odd()
30 }
31
32 #[inline]
34 pub(crate) const fn eq(lhs: &Self, rhs: &Self) -> Choice {
35 let mut acc = 0;
36 let mut i = 0;
37
38 while i < LIMBS {
39 acc |= lhs.limbs[i].0 ^ rhs.limbs[i].0;
40 i += 1;
41 }
42
43 Limb(acc).is_nonzero().not()
45 }
46
47 #[inline]
49 pub(crate) const fn lt(lhs: &Self, rhs: &Self) -> Choice {
50 UintRef::lt(lhs.as_uint_ref(), rhs.as_uint_ref())
51 }
52
53 #[inline]
55 pub(crate) const fn lte(lhs: &Self, rhs: &Self) -> Choice {
56 Self::gt(lhs, rhs).not()
57 }
58
59 #[inline]
61 pub(crate) const fn gt(lhs: &Self, rhs: &Self) -> Choice {
62 UintRef::lt(rhs.as_uint_ref(), lhs.as_uint_ref())
63 }
64
65 #[inline]
67 pub(crate) const fn cmp(lhs: &Self, rhs: &Self) -> Ordering {
68 UintRef::cmp(lhs.as_uint_ref(), rhs.as_uint_ref())
69 }
70
71 #[must_use]
73 pub const fn cmp_vartime(&self, rhs: &Self) -> Ordering {
74 UintRef::cmp_vartime(self.as_uint_ref(), rhs.as_uint_ref())
75 }
76}
77
78impl<const LIMBS: usize> Eq for Uint<LIMBS> {}
79
80impl<const LIMBS: usize> Ord for Uint<LIMBS> {
81 fn cmp(&self, other: &Self) -> Ordering {
82 Self::cmp(self, other)
83 }
84}
85
86impl<const LIMBS: usize> PartialOrd for Uint<LIMBS> {
87 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
88 Some(self.cmp(other))
89 }
90}
91
92impl<const LIMBS: usize> PartialEq for Uint<LIMBS> {
93 fn eq(&self, other: &Self) -> bool {
94 self.ct_eq(other).into()
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use crate::{Choice, Integer, U128, Uint};
101 use core::cmp::Ordering;
102
103 #[test]
104 fn is_zero() {
105 assert!(U128::ZERO.is_zero().to_bool());
106 assert!(!U128::ONE.is_zero().to_bool());
107 assert!(!U128::MAX.is_zero().to_bool());
108 }
109
110 #[test]
111 fn is_odd() {
112 assert!(!U128::ZERO.is_odd().to_bool());
114 assert!(U128::ONE.is_odd().to_bool());
115 assert!(U128::MAX.is_odd().to_bool());
116
117 assert!(!<U128 as Integer>::is_odd(&U128::ZERO).to_bool());
119 assert!(<U128 as Integer>::is_odd(&U128::ONE).to_bool());
120 assert!(<U128 as Integer>::is_odd(&U128::MAX).to_bool());
121 }
122
123 #[test]
124 fn lte() {
125 let a = U128::ZERO;
126 let b = U128::ONE;
127 let c = U128::MAX;
128
129 assert!(Uint::lte(&a, &b).to_bool());
130 assert!(Uint::lte(&a, &c).to_bool());
131 assert!(Uint::lte(&b, &c).to_bool());
132
133 assert!(Uint::lte(&a, &a).to_bool());
134 assert!(Uint::lte(&b, &b).to_bool());
135 assert!(Uint::lte(&c, &c).to_bool());
136
137 assert!(!Uint::lte(&b, &a).to_bool());
138 assert!(!Uint::lte(&c, &a).to_bool());
139 assert!(!Uint::lte(&c, &b).to_bool());
140 }
141
142 #[test]
143 fn cmp() {
144 let a = U128::ZERO;
145 let b = U128::ONE;
146 let c = U128::MAX;
147
148 assert_eq!(a.cmp(&b), Ordering::Less);
149 assert_eq!(a.cmp(&c), Ordering::Less);
150 assert_eq!(b.cmp(&c), Ordering::Less);
151
152 assert_eq!(a.cmp(&a), Ordering::Equal);
153 assert_eq!(b.cmp(&b), Ordering::Equal);
154 assert_eq!(c.cmp(&c), Ordering::Equal);
155
156 assert_eq!(b.cmp(&a), Ordering::Greater);
157 assert_eq!(c.cmp(&a), Ordering::Greater);
158 assert_eq!(c.cmp(&b), Ordering::Greater);
159 }
160
161 #[test]
162 fn cmp_vartime() {
163 let a = U128::ZERO;
164 let b = U128::ONE;
165 let c = U128::MAX;
166
167 assert_eq!(a.cmp_vartime(&b), Ordering::Less);
168 assert_eq!(a.cmp_vartime(&c), Ordering::Less);
169 assert_eq!(b.cmp_vartime(&c), Ordering::Less);
170
171 assert_eq!(a.cmp_vartime(&a), Ordering::Equal);
172 assert_eq!(b.cmp_vartime(&b), Ordering::Equal);
173 assert_eq!(c.cmp_vartime(&c), Ordering::Equal);
174
175 assert_eq!(b.cmp_vartime(&a), Ordering::Greater);
176 assert_eq!(c.cmp_vartime(&a), Ordering::Greater);
177 assert_eq!(c.cmp_vartime(&b), Ordering::Greater);
178 }
179
180 #[test]
181 fn conditional_swap() {
182 let mut a = U128::ZERO;
183 let mut b = U128::MAX;
184
185 Uint::conditional_swap(&mut a, &mut b, Choice::FALSE);
186 assert_eq!(a, Uint::ZERO);
187 assert_eq!(b, Uint::MAX);
188
189 Uint::conditional_swap(&mut a, &mut b, Choice::TRUE);
190 assert_eq!(a, Uint::MAX);
191 assert_eq!(b, Uint::ZERO);
192 }
193}