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