crypto_bigint/uint/boxed/
ct.rs1use super::BoxedUint;
4use crate::{Choice, CtAssign, CtEq, CtGt, CtLt, CtNeg, CtSelect, Limb, UintRef};
5use ctutils::{CtAssignSlice, CtEqSlice};
6
7impl CtAssign for BoxedUint {
8 #[inline]
9 fn ct_assign(&mut self, other: &Self, choice: Choice) {
10 assert_eq!(self.bits_precision(), other.bits_precision());
11 self.limbs.ct_assign(&other.limbs, choice);
12 }
13}
14impl CtAssignSlice for BoxedUint {}
15
16impl<Rhs: AsRef<UintRef> + ?Sized> CtEq<Rhs> for BoxedUint {
17 #[inline]
18 fn ct_eq(&self, other: &Rhs) -> Choice {
19 self.as_uint_ref().ct_eq(other)
20 }
21}
22impl CtEqSlice for BoxedUint {}
23
24impl CtGt for BoxedUint {
25 #[inline]
26 fn ct_gt(&self, other: &Self) -> Choice {
27 UintRef::lt(other.as_uint_ref(), self.as_uint_ref())
28 }
29}
30
31impl CtLt for BoxedUint {
32 #[inline]
33 fn ct_lt(&self, other: &Self) -> Choice {
34 UintRef::lt(self.as_uint_ref(), other.as_uint_ref())
35 }
36}
37
38impl CtNeg for BoxedUint {
39 fn ct_neg(&self, choice: Choice) -> Self {
40 let mut neg = self.clone();
41 neg.conditional_wrapping_neg_assign(choice);
42 neg
43 }
44
45 fn ct_neg_assign(&mut self, choice: Choice) {
46 self.conditional_wrapping_neg_assign(choice);
47 }
48}
49
50impl CtSelect for BoxedUint {
51 #[inline]
52 fn ct_select(&self, other: &Self, choice: Choice) -> Self {
53 assert_eq!(self.bits_precision(), other.bits_precision());
54 let mut limbs = vec![Limb::ZERO; self.nlimbs()].into_boxed_slice();
55
56 for i in 0..self.nlimbs() {
57 limbs[i] = self.limbs[i].ct_select(&other.limbs[i], choice);
58 }
59
60 Self { limbs }
61 }
62
63 #[inline]
64 fn ct_swap(&mut self, other: &mut Self, choice: Choice) {
65 assert_eq!(self.bits_precision(), other.bits_precision());
66
67 for i in 0..self.nlimbs() {
68 self.limbs[i].ct_swap(&mut other.limbs[i], choice);
69 }
70 }
71}
72
73#[cfg(feature = "subtle")]
74impl subtle::ConditionallyNegatable for BoxedUint {
75 #[inline]
76 fn conditional_negate(&mut self, choice: subtle::Choice) {
77 self.ct_neg_assign(choice.into());
78 }
79}
80
81#[cfg(feature = "subtle")]
82impl subtle::ConstantTimeEq for BoxedUint {
83 #[inline]
84 fn ct_eq(&self, other: &Self) -> subtle::Choice {
85 CtEq::ct_eq(self, other).into()
86 }
87}
88
89#[cfg(feature = "subtle")]
90impl subtle::ConstantTimeGreater for BoxedUint {
91 #[inline]
92 fn ct_gt(&self, other: &Self) -> subtle::Choice {
93 CtGt::ct_gt(self, other).into()
94 }
95}
96
97#[cfg(feature = "subtle")]
98impl subtle::ConstantTimeLess for BoxedUint {
99 #[inline]
100 fn ct_lt(&self, other: &Self) -> subtle::Choice {
101 CtLt::ct_lt(self, other).into()
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use crate::{BoxedUint, Choice, CtEq, CtGt, CtLt, CtSelect};
108
109 #[test]
110 fn ct_eq() {
111 let a = BoxedUint::zero();
112 let b = BoxedUint::one();
113
114 assert!(a.ct_eq(&a).to_bool());
115 assert!(!a.ct_eq(&b).to_bool());
116 assert!(!b.ct_eq(&a).to_bool());
117 assert!(b.ct_eq(&b).to_bool());
118 }
119
120 #[test]
121 fn ct_gt() {
122 let a = BoxedUint::zero();
123 let b = BoxedUint::one();
124 let c = BoxedUint::max(64);
125
126 assert!(b.ct_gt(&a).to_bool());
127 assert!(c.ct_gt(&a).to_bool());
128 assert!(c.ct_gt(&b).to_bool());
129
130 assert!(!a.ct_gt(&a).to_bool());
131 assert!(!b.ct_gt(&b).to_bool());
132 assert!(!c.ct_gt(&c).to_bool());
133
134 assert!(!a.ct_gt(&b).to_bool());
135 assert!(!a.ct_gt(&c).to_bool());
136 assert!(!b.ct_gt(&c).to_bool());
137 }
138
139 #[test]
140 fn ct_lt() {
141 let a = BoxedUint::zero();
142 let b = BoxedUint::one();
143 let c = BoxedUint::max(64);
144
145 assert!(a.ct_lt(&b).to_bool());
146 assert!(a.ct_lt(&c).to_bool());
147 assert!(b.ct_lt(&c).to_bool());
148
149 assert!(!a.ct_lt(&a).to_bool());
150 assert!(!b.ct_lt(&b).to_bool());
151 assert!(!c.ct_lt(&c).to_bool());
152
153 assert!(!b.ct_lt(&a).to_bool());
154 assert!(!c.ct_lt(&a).to_bool());
155 assert!(!c.ct_lt(&b).to_bool());
156 }
157
158 #[test]
159 fn ct_select() {
160 let a = BoxedUint::zero_with_precision(128);
161 let b = BoxedUint::max(128);
162
163 assert_eq!(a, BoxedUint::ct_select(&a, &b, Choice::FALSE));
164 assert_eq!(b, BoxedUint::ct_select(&a, &b, Choice::TRUE));
165 }
166}