efficient implementation of GetBitsFixed for Fr
-use ff::{Field, PrimeField, PrimeFieldRepr};
+use ff::{Field, PrimeField, PrimeFieldRepr, BitIterator};
// TODO: replace Vec with Iterator?
@@ -7,19 +7,23 @@ pub trait GetBits {
}
pub trait GetBitsFixed {
+
+ /// Get exactly `n` bits from the value in little endian order
+ /// If `n` is larger than value bit length, it is padded with `false`
+ /// for the result to exactly match `n`
fn get_bits_le_fixed(&self, n: usize) -> Vec<bool>;
}
impl<Fr: PrimeField> GetBitsFixed for Fr {
fn get_bits_le_fixed(&self, n: usize) -> Vec<bool> {
- let mut acc = Vec::with_capacity(n);
- let mut t = self.into_repr().clone();
- for i in 0..n {
- acc.push(t.is_odd());
- t.shr(1);
- }
- acc
+ let mut r: Vec<bool> = Vec::with_capacity(n);
+ r.extend(BitIterator::new(self.into_repr()));
+ r.reverse();
+ r.truncate(n);
+ let len = r.len();
+ r.extend((len..n).map(|_| false));
+ r
}
}
@@ -30,4 +34,7 @@ fn test_get_bits() {
// 12 = b1100, 3 lowest bits in little endian encoding are: 0, 0, 1.
let bits = Fr::from_str("12").unwrap().get_bits_le_fixed(3);
assert_eq!(bits, vec![false, false, true]);
+
+ let bits = Fr::from_str("0").unwrap().get_bits_le_fixed(512);
+ assert_eq!(bits, vec!(false; 512));
}
\ No newline at end of file
