fullcodec_plonk/
bit_iterator.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7//! Code taken from zcash repo and generalised as we do not have access to the
8//! limbs
9use core::mem;
10
11macro_rules! bit_iterator {
12    ($sty : ty, $name : ident) => {
13        #[derive(Debug, Clone, Copy)]
14        pub struct $name<E> {
15            // scalar is the slice of integers that wish to iterate over
16            scalar: E,
17            // num_of_total_bits represents the sum of all of the bits of each
18            // integer If we have 2 u32s then the total number of bits will
19            // be 32 * 2 = 64 bits
20            num_of_total_bits: usize,
21            // bit_len represents the bit length of each integer.
22            // If we have a slice of u32s, then bit_len will be 32
23            bit_len: usize,
24        }
25
26        impl<E: AsRef<[$sty]>> $name<E> {
27            pub fn new(t: E) -> Self {
28                let num_of_integers = t.as_ref().len();
29                let num_of_total_bits = mem::size_of::<E>() * 8;
30                let bit_len_of_each_integer =
31                    num_of_total_bits / num_of_integers;
32                $name {
33                    scalar: t,
34                    num_of_total_bits,
35                    bit_len: bit_len_of_each_integer,
36                }
37            }
38        }
39        impl<E: AsRef<[$sty]>> Iterator for $name<E> {
40            type Item = bool;
41
42            fn next(&mut self) -> Option<bool> {
43                if self.num_of_total_bits == 0 {
44                    None
45                } else {
46                    self.num_of_total_bits -= 1;
47                    let element_index = self.num_of_total_bits / self.bit_len;
48                    let elements_bit = (self.num_of_total_bits % self.bit_len);
49                    let number = self.scalar.as_ref()[element_index];
50
51                    let bit = (number >> elements_bit) & 1;
52                    Some(bit > 0)
53                }
54            }
55        }
56    };
57}
58bit_iterator!(u8, BitIterator8);
59
60#[cfg(feature = "std")]
61#[cfg(test)]
62mod test {
63    use super::*;
64    use dusk_bls12_381::BlsScalar;
65    use dusk_bytes::Serializable;
66    use sp_std::vec::Vec;
67
68    #[test]
69    fn test_bit_iterator8() {
70        let mut a = BitIterator8::new(BlsScalar::one().to_bytes());
71        let expected = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001";
72        for e in expected.chars() {
73            assert_eq!(a.next().unwrap(), (e == '1'));
74        }
75        let _a_vec: Vec<_> = a.collect();
76    }
77}