crypto_bigint/uint/ref_type/
ct.rs1use super::UintRef;
4use crate::{Choice, CtAssign, CtEq, CtLt};
5
6impl CtAssign for UintRef {
7 #[inline]
8 fn ct_assign(&mut self, other: &Self, choice: Choice) {
9 debug_assert_eq!(self.bits_precision(), other.bits_precision());
10 self.limbs.ct_assign(&other.limbs, choice);
11 }
12}
13
14impl<Rhs: AsRef<UintRef> + ?Sized> CtEq<Rhs> for UintRef {
15 #[inline]
16 fn ct_eq(&self, other: &Rhs) -> Choice {
17 let rhs = other.as_ref();
18 let overlap = if self.nlimbs() < rhs.nlimbs() {
19 self.nlimbs()
20 } else {
21 rhs.nlimbs()
22 };
23 let (lhs, lhs_over) = self.split_at(overlap);
24 let (rhs, rhs_over) = rhs.split_at(overlap);
25 lhs.limbs
26 .ct_eq(&rhs.limbs)
27 .and(lhs_over.is_zero())
28 .and(rhs_over.is_zero())
29 }
30}
31
32impl CtLt for UintRef {
33 #[inline]
34 fn ct_lt(&self, other: &Self) -> Choice {
35 Self::lt(self, other)
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use ctutils::CtLt;
42
43 use super::UintRef;
44 use crate::{CtEq, Limb};
45
46 #[test]
47 fn ct_eq() {
48 let z_small = UintRef::new(&[Limb::ZERO, Limb::ZERO]);
49 let z_big = UintRef::new(&[Limb::ZERO, Limb::ZERO, Limb::ZERO]);
50 let a = UintRef::new(&[Limb::ZERO, Limb::ZERO, Limb::ONE]);
51
52 assert!(z_small.ct_eq(z_big).to_bool());
53 assert!(z_big.ct_eq(z_small).to_bool());
54 assert!(a.ct_eq(a).to_bool());
55 assert!(!z_small.ct_eq(a).to_bool());
56 assert!(!a.ct_eq(z_small).to_bool());
57 assert!(!z_big.ct_eq(a).to_bool());
58 assert!(!a.ct_eq(z_big).to_bool());
59 }
60
61 #[test]
62 fn ct_lt() {
63 let lesser = UintRef::new(&[Limb::ZERO, Limb::ZERO, Limb::ZERO]);
64 let greater = UintRef::new(&[Limb::ZERO, Limb::ONE, Limb::ZERO]);
65 assert!(lesser.ct_lt(greater).to_bool());
66 assert!(!greater.ct_lt(lesser).to_bool());
67
68 let smaller = UintRef::new(&[Limb::ZERO, Limb::ZERO]);
69 let bigger = UintRef::new(&[Limb::ZERO, Limb::ZERO, Limb::ONE]);
70 assert!(smaller.ct_lt(bigger).to_bool());
71 assert!(!bigger.ct_lt(smaller).to_bool());
72 }
73}