crypto_bigint/uint/boxed/
bits.rs1use crate::{BitOps, BoxedUint, Choice, Limb};
4
5impl BoxedUint {
6 #[must_use]
9 pub fn bit(&self, index: u32) -> Choice {
10 self.as_uint_ref().bit(index)
11 }
12
13 #[inline(always)]
18 #[must_use]
19 pub const fn bit_vartime(&self, index: u32) -> bool {
20 self.as_uint_ref().bit_vartime(index)
21 }
22
23 #[must_use]
28 pub fn bits(&self) -> u32 {
29 self.bits_precision() - self.leading_zeros()
30 }
31
32 #[must_use]
35 pub fn bits_vartime(&self) -> u32 {
36 self.as_uint_ref().bits_vartime()
37 }
38
39 #[must_use]
41 pub const fn leading_zeros(&self) -> u32 {
42 self.as_uint_ref().leading_zeros()
43 }
44
45 #[inline(always)]
47 #[must_use]
48 #[allow(clippy::cast_possible_truncation)]
49 pub fn bits_precision(&self) -> u32 {
50 self.limbs.len() as u32 * Limb::BITS
51 }
52
53 #[must_use]
55 pub fn trailing_zeros(&self) -> u32 {
56 self.as_uint_ref().trailing_zeros()
57 }
58
59 #[must_use]
61 pub fn trailing_ones(&self) -> u32 {
62 self.as_uint_ref().trailing_ones()
63 }
64
65 #[must_use]
68 pub fn trailing_zeros_vartime(&self) -> u32 {
69 self.as_uint_ref().trailing_zeros_vartime()
70 }
71
72 #[must_use]
75 pub fn trailing_ones_vartime(&self) -> u32 {
76 self.as_uint_ref().trailing_ones_vartime()
77 }
78
79 pub(crate) fn set_bit(&mut self, index: u32, bit_value: Choice) {
81 self.as_mut_uint_ref().set_bit(index, bit_value);
82 }
83
84 pub(crate) fn set_bit_vartime(&mut self, index: u32, bit_value: bool) {
85 self.as_mut_uint_ref().set_bit_vartime(index, bit_value);
86 }
87
88 pub(crate) const fn restrict_bits(&mut self, len: u32) {
90 self.as_mut_uint_ref().restrict_bits(len);
91 }
92}
93
94impl BitOps for BoxedUint {
95 fn bits_precision(&self) -> u32 {
96 self.bits_precision()
97 }
98
99 fn bytes_precision(&self) -> usize {
100 self.nlimbs() * Limb::BYTES
101 }
102
103 fn leading_zeros(&self) -> u32 {
104 self.leading_zeros()
105 }
106
107 fn bits(&self) -> u32 {
108 self.bits()
109 }
110
111 fn bit(&self, index: u32) -> Choice {
112 self.bit(index)
113 }
114
115 fn set_bit(&mut self, index: u32, bit_value: Choice) {
116 self.set_bit(index, bit_value);
117 }
118
119 fn trailing_zeros(&self) -> u32 {
120 self.trailing_zeros()
121 }
122
123 fn trailing_ones(&self) -> u32 {
124 self.trailing_ones()
125 }
126
127 fn bit_vartime(&self, index: u32) -> bool {
128 self.bit_vartime(index)
129 }
130
131 fn bits_vartime(&self) -> u32 {
132 self.bits_vartime()
133 }
134
135 fn set_bit_vartime(&mut self, index: u32, bit_value: bool) {
136 self.set_bit_vartime(index, bit_value);
137 }
138
139 fn trailing_zeros_vartime(&self) -> u32 {
140 self.trailing_zeros_vartime()
141 }
142
143 fn trailing_ones_vartime(&self) -> u32 {
144 self.trailing_ones_vartime()
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use super::BoxedUint;
151 use crate::Choice;
152 use hex_literal::hex;
153
154 fn uint_with_bits_at(positions: &[u32]) -> BoxedUint {
155 let mut result = BoxedUint::zero_with_precision(256);
156 for &pos in positions {
157 result |= BoxedUint::one_with_precision(256).shl_vartime(pos).unwrap();
158 }
159 result
160 }
161
162 #[test]
163 fn bit_vartime() {
164 let u = uint_with_bits_at(&[16, 48, 112, 127, 255]);
165 assert!(!u.bit_vartime(0));
166 assert!(!u.bit_vartime(1));
167 assert!(u.bit_vartime(16));
168 assert!(u.bit_vartime(127));
169 assert!(u.bit_vartime(255));
170 assert!(!u.bit_vartime(256));
171 assert!(!u.bit_vartime(260));
172 }
173
174 #[test]
175 fn bits() {
176 assert_eq!(0, BoxedUint::zero().bits());
177 assert_eq!(128, BoxedUint::max(128).bits());
178
179 let n1 = BoxedUint::from_be_slice(&hex!("000000000029ffffffffffffffffffff"), 128).unwrap();
180 assert_eq!(86, n1.bits());
181
182 let n2 = BoxedUint::from_be_slice(&hex!("00000000004000000000000000000000"), 128).unwrap();
183 assert_eq!(87, n2.bits());
184 }
185
186 #[test]
187 fn set_bit() {
188 let mut u = uint_with_bits_at(&[16, 79, 150]);
189 u.set_bit(127, Choice::TRUE);
190 assert_eq!(u, uint_with_bits_at(&[16, 79, 127, 150]));
191
192 let mut u = uint_with_bits_at(&[16, 79, 150]);
193 u.set_bit(150, Choice::TRUE);
194 assert_eq!(u, uint_with_bits_at(&[16, 79, 150]));
195
196 let mut u = uint_with_bits_at(&[16, 79, 150]);
197 u.set_bit(127, Choice::FALSE);
198 assert_eq!(u, uint_with_bits_at(&[16, 79, 150]));
199
200 let mut u = uint_with_bits_at(&[16, 79, 150]);
201 u.set_bit(150, Choice::FALSE);
202 assert_eq!(u, uint_with_bits_at(&[16, 79]));
203 }
204
205 #[test]
206 fn trailing_ones() {
207 let u = !uint_with_bits_at(&[16, 79, 150]);
208 assert_eq!(u.trailing_ones(), 16);
209
210 let u = !uint_with_bits_at(&[79, 150]);
211 assert_eq!(u.trailing_ones(), 79);
212
213 let u = !uint_with_bits_at(&[150, 207]);
214 assert_eq!(u.trailing_ones(), 150);
215
216 let u = !uint_with_bits_at(&[0, 150, 207]);
217 assert_eq!(u.trailing_ones(), 0);
218
219 let u = !BoxedUint::zero_with_precision(256);
220 assert_eq!(u.trailing_ones(), 256);
221 }
222
223 #[test]
224 fn trailing_ones_vartime() {
225 let u = !uint_with_bits_at(&[16, 79, 150]);
226 assert_eq!(u.trailing_ones_vartime(), 16);
227
228 let u = !uint_with_bits_at(&[79, 150]);
229 assert_eq!(u.trailing_ones_vartime(), 79);
230
231 let u = !uint_with_bits_at(&[150, 207]);
232 assert_eq!(u.trailing_ones_vartime(), 150);
233
234 let u = !uint_with_bits_at(&[0, 150, 207]);
235 assert_eq!(u.trailing_ones_vartime(), 0);
236
237 let u = !BoxedUint::zero_with_precision(256);
238 assert_eq!(u.trailing_ones_vartime(), 256);
239 }
240}