Skip to content

Commit 21f3a6b

Browse files
committed
Trailing ones
1 parent 0a664bc commit 21f3a6b

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

src/uint/boxed/bits.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Bit manipulation functions.
22
3-
use crate::{BoxedUint, Limb, Zero};
3+
use crate::{BoxedUint, ConstChoice, Limb, Zero};
44
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
55

66
impl BoxedUint {
@@ -68,6 +68,25 @@ impl BoxedUint {
6868
count
6969
}
7070

71+
/// Calculate the number of trailing ones in the binary representation of this number.
72+
pub fn trailing_ones(&self) -> u32 {
73+
let limbs = self.as_limbs();
74+
75+
let mut count = 0;
76+
let mut i = 0;
77+
let mut nonmax_limb_not_encountered = ConstChoice::TRUE;
78+
while i < limbs.len() {
79+
let l = limbs[i];
80+
let z = l.trailing_ones();
81+
count += nonmax_limb_not_encountered.if_true_u32(z);
82+
nonmax_limb_not_encountered =
83+
nonmax_limb_not_encountered.and(ConstChoice::from_word_eq(l.0, Limb::MAX.0));
84+
i += 1;
85+
}
86+
87+
count
88+
}
89+
7190
/// Sets the bit at `index` to 0 or 1 depending on the value of `bit_value`.
7291
pub(crate) fn set_bit(&mut self, index: u32, bit_value: Choice) {
7392
let limb_num = (index / Limb::BITS) as usize;
@@ -144,4 +163,22 @@ mod tests {
144163
assert!(!u.bit_vartime(256));
145164
assert!(!u.bit_vartime(260));
146165
}
166+
167+
#[test]
168+
fn trailing_ones() {
169+
let u = !uint_with_bits_at(&[16, 79, 150]);
170+
assert_eq!(u.trailing_ones(), 16);
171+
172+
let u = !uint_with_bits_at(&[79, 150]);
173+
assert_eq!(u.trailing_ones(), 79);
174+
175+
let u = !uint_with_bits_at(&[150, 207]);
176+
assert_eq!(u.trailing_ones(), 150);
177+
178+
let u = !uint_with_bits_at(&[0, 150, 207]);
179+
assert_eq!(u.trailing_ones(), 0);
180+
181+
let u = !BoxedUint::zero_with_precision(256);
182+
assert_eq!(u.trailing_ones(), 256);
183+
}
147184
}

0 commit comments

Comments
 (0)