1use crate::{BitOps, Choice, Uint};
2
3impl<const LIMBS: usize> Uint<LIMBS> {
4 #[must_use]
7 pub const fn bit(&self, index: u32) -> Choice {
8 self.as_uint_ref().bit(index)
9 }
10
11 #[inline(always)]
16 #[must_use]
17 pub const fn bit_vartime(&self, index: u32) -> bool {
18 self.as_uint_ref().bit_vartime(index)
19 }
20
21 #[inline]
23 #[must_use]
24 pub const fn bits(&self) -> u32 {
25 Self::BITS - self.leading_zeros()
26 }
27
28 #[must_use]
31 pub const fn bits_vartime(&self) -> u32 {
32 self.as_uint_ref().bits_vartime()
33 }
34
35 #[must_use]
37 pub const fn leading_zeros(&self) -> u32 {
38 self.as_uint_ref().leading_zeros()
39 }
40
41 #[must_use]
44 pub const fn leading_zeros_vartime(&self) -> u32 {
45 Self::BITS - self.bits_vartime()
46 }
47
48 #[must_use]
50 pub const fn trailing_zeros(&self) -> u32 {
51 self.as_uint_ref().trailing_zeros()
52 }
53
54 #[must_use]
57 pub const fn trailing_zeros_vartime(&self) -> u32 {
58 self.as_uint_ref().trailing_zeros_vartime()
59 }
60
61 #[must_use]
63 pub const fn trailing_ones(&self) -> u32 {
64 self.as_uint_ref().trailing_ones()
65 }
66
67 #[must_use]
70 pub const fn trailing_ones_vartime(&self) -> u32 {
71 self.as_uint_ref().trailing_ones_vartime()
72 }
73
74 pub(crate) const fn set_bit(self, index: u32, bit_value: Choice) -> Self {
76 let mut result = self;
77 result.as_mut_uint_ref().set_bit(index, bit_value);
78 result
79 }
80
81 pub(crate) const fn set_bit_vartime(self, index: u32, bit_value: bool) -> Self {
84 let mut result = self;
85 result.as_mut_uint_ref().set_bit_vartime(index, bit_value);
86 result
87 }
88
89 pub(crate) const fn restrict_bits(mut self, len: u32) -> Self {
91 self.as_mut_uint_ref().restrict_bits(len);
92 self
93 }
94}
95
96impl<const LIMBS: usize> BitOps for Uint<LIMBS> {
97 fn bits_precision(&self) -> u32 {
98 Self::BITS
99 }
100
101 fn bytes_precision(&self) -> usize {
102 Self::BYTES
103 }
104
105 fn leading_zeros(&self) -> u32 {
106 self.leading_zeros()
107 }
108
109 fn bit(&self, index: u32) -> Choice {
110 self.bit(index)
111 }
112
113 fn set_bit(&mut self, index: u32, bit_value: Choice) {
114 *self = Self::set_bit(*self, index, bit_value);
115 }
116
117 fn trailing_zeros(&self) -> u32 {
118 self.trailing_zeros()
119 }
120
121 fn trailing_ones(&self) -> u32 {
122 self.trailing_ones()
123 }
124
125 fn bit_vartime(&self, index: u32) -> bool {
126 self.bit_vartime(index)
127 }
128
129 fn bits_vartime(&self) -> u32 {
130 self.bits_vartime()
131 }
132
133 fn set_bit_vartime(&mut self, index: u32, bit_value: bool) {
134 *self = Self::set_bit_vartime(*self, index, bit_value);
135 }
136
137 fn trailing_zeros_vartime(&self) -> u32 {
138 self.trailing_zeros_vartime()
139 }
140
141 fn trailing_ones_vartime(&self) -> u32 {
142 self.trailing_ones_vartime()
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use crate::{Choice, U256};
149
150 fn uint_with_bits_at(positions: &[u32]) -> U256 {
151 let mut result = U256::ZERO;
152 for pos in positions {
153 result |= U256::ONE << *pos;
154 }
155 result
156 }
157
158 #[test]
159 fn bit_vartime() {
160 let u = uint_with_bits_at(&[16, 48, 112, 127, 255]);
161 assert!(!u.bit_vartime(0));
162 assert!(!u.bit_vartime(1));
163 assert!(u.bit_vartime(16));
164 assert!(u.bit_vartime(127));
165 assert!(u.bit_vartime(255));
166 assert!(!u.bit_vartime(256));
167 assert!(!u.bit_vartime(260));
168 }
169
170 #[test]
171 fn bit() {
172 let u = uint_with_bits_at(&[16, 48, 112, 127, 255]);
173 assert!(!u.bit(0).to_bool_vartime());
174 assert!(!u.bit(1).to_bool_vartime());
175 assert!(u.bit(16).to_bool_vartime());
176 assert!(u.bit(127).to_bool_vartime());
177 assert!(u.bit(255).to_bool_vartime());
178 assert!(!u.bit(256).to_bool_vartime());
179 assert!(!u.bit(260).to_bool_vartime());
180 }
181
182 #[test]
183 fn leading_zeros() {
184 let u = uint_with_bits_at(&[256 - 16, 256 - 79, 256 - 207]);
185 assert_eq!(u.leading_zeros(), 15);
186
187 let u = uint_with_bits_at(&[256 - 79, 256 - 207]);
188 assert_eq!(u.leading_zeros(), 78);
189
190 let u = uint_with_bits_at(&[256 - 207]);
191 assert_eq!(u.leading_zeros(), 206);
192
193 let u = uint_with_bits_at(&[256 - 1, 256 - 75, 256 - 150]);
194 assert_eq!(u.leading_zeros(), 0);
195
196 let u = U256::ZERO;
197 assert_eq!(u.leading_zeros(), 256);
198 }
199
200 #[test]
201 fn leading_zeros_vartime() {
202 let u = uint_with_bits_at(&[256 - 16, 256 - 79, 256 - 207]);
203 assert_eq!(u.leading_zeros_vartime(), 15);
204
205 let u = uint_with_bits_at(&[256 - 79, 256 - 207]);
206 assert_eq!(u.leading_zeros_vartime(), 78);
207
208 let u = uint_with_bits_at(&[256 - 207]);
209 assert_eq!(u.leading_zeros_vartime(), 206);
210
211 let u = uint_with_bits_at(&[256 - 1, 256 - 75, 256 - 150]);
212 assert_eq!(u.leading_zeros_vartime(), 0);
213
214 let u = U256::ZERO;
215 assert_eq!(u.leading_zeros_vartime(), 256);
216 }
217
218 #[test]
219 fn trailing_zeros() {
220 let u = uint_with_bits_at(&[16, 79, 150]);
221 assert_eq!(u.trailing_zeros(), 16);
222
223 let u = uint_with_bits_at(&[79, 150]);
224 assert_eq!(u.trailing_zeros(), 79);
225
226 let u = uint_with_bits_at(&[150, 207]);
227 assert_eq!(u.trailing_zeros(), 150);
228
229 let u = uint_with_bits_at(&[0, 150, 207]);
230 assert_eq!(u.trailing_zeros(), 0);
231
232 let u = U256::ZERO;
233 assert_eq!(u.trailing_zeros(), 256);
234 }
235
236 #[test]
237 fn trailing_zeros_vartime() {
238 let u = uint_with_bits_at(&[16, 79, 150]);
239 assert_eq!(u.trailing_zeros_vartime(), 16);
240
241 let u = uint_with_bits_at(&[79, 150]);
242 assert_eq!(u.trailing_zeros_vartime(), 79);
243
244 let u = uint_with_bits_at(&[150, 207]);
245 assert_eq!(u.trailing_zeros_vartime(), 150);
246
247 let u = uint_with_bits_at(&[0, 150, 207]);
248 assert_eq!(u.trailing_zeros_vartime(), 0);
249
250 let u = U256::ZERO;
251 assert_eq!(u.trailing_zeros_vartime(), 256);
252 }
253
254 #[test]
255 fn trailing_ones() {
256 let u = !uint_with_bits_at(&[16, 79, 150]);
257 assert_eq!(u.trailing_ones(), 16);
258
259 let u = !uint_with_bits_at(&[79, 150]);
260 assert_eq!(u.trailing_ones(), 79);
261
262 let u = !uint_with_bits_at(&[150, 207]);
263 assert_eq!(u.trailing_ones(), 150);
264
265 let u = !uint_with_bits_at(&[0, 150, 207]);
266 assert_eq!(u.trailing_ones(), 0);
267
268 let u = U256::MAX;
269 assert_eq!(u.trailing_ones(), 256);
270 }
271
272 #[test]
273 fn trailing_ones_vartime() {
274 let u = !uint_with_bits_at(&[16, 79, 150]);
275 assert_eq!(u.trailing_ones_vartime(), 16);
276
277 let u = !uint_with_bits_at(&[79, 150]);
278 assert_eq!(u.trailing_ones_vartime(), 79);
279
280 let u = !uint_with_bits_at(&[150, 207]);
281 assert_eq!(u.trailing_ones_vartime(), 150);
282
283 let u = !uint_with_bits_at(&[0, 150, 207]);
284 assert_eq!(u.trailing_ones_vartime(), 0);
285
286 let u = U256::MAX;
287 assert_eq!(u.trailing_ones_vartime(), 256);
288 }
289
290 #[test]
291 fn set_bit() {
292 let u = uint_with_bits_at(&[16, 79, 150]);
293 assert_eq!(
294 u.set_bit(127, Choice::TRUE),
295 uint_with_bits_at(&[16, 79, 127, 150])
296 );
297
298 let u = uint_with_bits_at(&[16, 79, 150]);
299 assert_eq!(
300 u.set_bit(150, Choice::TRUE),
301 uint_with_bits_at(&[16, 79, 150])
302 );
303
304 let u = uint_with_bits_at(&[16, 79, 150]);
305 assert_eq!(
306 u.set_bit(127, Choice::FALSE),
307 uint_with_bits_at(&[16, 79, 150])
308 );
309
310 let u = uint_with_bits_at(&[16, 79, 150]);
311 assert_eq!(u.set_bit(150, Choice::FALSE), uint_with_bits_at(&[16, 79]));
312 }
313}