1- use bitvec:: { self , BitVec } ;
21use ff:: PrimeFieldRepr ;
32use fil_sapling_crypto:: jubjub:: JubjubBls12 ;
43use fil_sapling_crypto:: pedersen_hash:: { pedersen_hash, Personalization } ;
@@ -20,64 +19,229 @@ pub const PEDERSEN_BLOCK_SIZE: usize = 256;
2019pub const PEDERSEN_BLOCK_BYTES : usize = PEDERSEN_BLOCK_SIZE / 8 ;
2120
2221pub fn pedersen ( data : & [ u8 ] ) -> Fr {
23- pedersen_hash :: < Bls12 , _ > (
24- Personalization :: None ,
25- BitVec :: < bitvec:: LittleEndian , u8 > :: from ( data)
26- . iter ( )
27- . take ( data. len ( ) * 8 ) ,
28- & JJ_PARAMS ,
29- )
30- . into_xy ( )
31- . 0
22+ pedersen_bits ( Bits :: new ( data) )
23+ }
24+
25+ pub fn pedersen_bits < ' a , S : Iterator < Item = & ' a [ u8 ] > > ( data : Bits < & ' a [ u8 ] , S > ) -> Fr {
26+ pedersen_hash :: < Bls12 , _ > ( Personalization :: None , data, & JJ_PARAMS )
27+ . into_xy ( )
28+ . 0
3229}
3330
3431/// Pedersen hashing for inputs that have length mulitple of the block size `256`. Based on pedersen hashes and a Merkle-Damgard construction.
3532pub fn pedersen_md_no_padding ( data : & [ u8 ] ) -> Fr {
36- assert ! (
37- data. len( ) >= 2 * PEDERSEN_BLOCK_BYTES ,
38- "must be at least 2 block sizes long, got {}bits" ,
39- data. len( )
40- ) ;
41- assert_eq ! (
42- data. len( ) % PEDERSEN_BLOCK_BYTES ,
43- 0 ,
44- "input must be a multiple of the blocksize"
45- ) ;
46- let mut chunks = data. chunks ( PEDERSEN_BLOCK_BYTES ) ;
47- let mut cur = Vec :: with_capacity ( 2 * PEDERSEN_BLOCK_BYTES ) ;
48- cur. resize ( PEDERSEN_BLOCK_BYTES , 0 ) ;
49- cur[ 0 ..PEDERSEN_BLOCK_BYTES ] . copy_from_slice ( chunks. nth ( 0 ) . unwrap ( ) ) ;
33+ pedersen_md_no_padding_bits ( Bits :: new ( data) )
34+ }
5035
51- for block in chunks {
52- cur. resize ( 2 * PEDERSEN_BLOCK_BYTES , 0 ) ;
53- cur[ PEDERSEN_BLOCK_BYTES ..] . copy_from_slice ( block) ;
54- pedersen_compression ( & mut cur) ;
36+ pub fn pedersen_md_no_padding_bits < T : AsRef < [ u8 ] > , S : Iterator < Item = T > > (
37+ mut data : Bits < T , S > ,
38+ ) -> Fr {
39+ let mut cur = Vec :: with_capacity ( PEDERSEN_BLOCK_SIZE ) ;
40+
41+ // hash the first two blocks
42+ let first = pedersen_compression_bits ( data. ref_take ( 2 * PEDERSEN_BLOCK_SIZE ) ) ;
43+ first
44+ . write_le ( & mut cur)
45+ . expect ( "failed to write result hash" ) ;
46+
47+ while !data. is_done ( ) {
48+ let r = data. ref_take ( PEDERSEN_BLOCK_SIZE ) ;
49+ let x = pedersen_compression_bits ( Bits :: new ( & cur) . chain ( r) ) ;
50+
51+ cur. truncate ( 0 ) ;
52+ x. write_le ( & mut cur) . expect ( "failed to write result hash" ) ;
5553 }
5654
57- let frs = bytes_into_frs :: < Bls12 > ( & cur[ 0 ..PEDERSEN_BLOCK_BYTES ] )
58- . expect ( "pedersen must generate valid fr elements" ) ;
55+ let frs = bytes_into_frs :: < Bls12 > ( & cur) . expect ( "pedersen must generate valid fr elements" ) ;
5956 assert_eq ! ( frs. len( ) , 1 ) ;
6057 frs[ 0 ]
6158}
6259
63- pub fn pedersen_compression ( bytes : & mut Vec < u8 > ) {
64- let bits = BitVec :: < bitvec:: LittleEndian , u8 > :: from ( & bytes[ ..] ) ;
65- let ( x, _) = pedersen_hash :: < Bls12 , _ > (
66- Personalization :: None ,
67- bits. iter ( ) . take ( bytes. len ( ) * 8 ) ,
68- & JJ_PARAMS ,
69- )
70- . into_xy ( ) ;
71- let x: FrRepr = x. into ( ) ;
60+ fn pedersen_compression_bits < T > ( bits : T ) -> FrRepr
61+ where
62+ T : IntoIterator < Item = bool > ,
63+ {
64+ let ( x, _) = pedersen_hash :: < Bls12 , _ > ( Personalization :: None , bits, & JJ_PARAMS ) . into_xy ( ) ;
65+ x. into ( )
66+ }
67+
68+ /// Creates an iterator over the byte slices in little endian format.
69+ #[ derive( Debug , Clone ) ]
70+ pub struct Bits < K : AsRef < [ u8 ] > , S : Iterator < Item = K > > {
71+ /// The individual parts that make up the data that is being iterated over.
72+ parts : ManyOrSingle < K , S > ,
73+ /// How many bytes we are into the `current_part`
74+ position_byte : usize ,
75+ /// How many bits we are into the `current_byte`.
76+ position_bit : u8 ,
77+ /// The current part we are reading from.
78+ current_part : Option < K > ,
79+ /// Track the first iteration.
80+ first : bool ,
81+ /// Are we done yet?
82+ done : bool ,
83+ }
84+
85+ /// Abstraction over either an iterator or a single element.
86+ #[ derive( Debug , Clone ) ]
87+ enum ManyOrSingle < T , S = <Vec < T > as IntoIterator >:: IntoIter >
88+ where
89+ S : Iterator < Item = T > ,
90+ {
91+ Many ( S ) ,
92+ Single ( Option < T > ) ,
93+ }
94+
95+ impl < T : AsRef < [ u8 ] > > Bits < T , <Vec < T > as IntoIterator >:: IntoIter > {
96+ pub fn new ( parts : T ) -> Self {
97+ Bits {
98+ parts : ManyOrSingle :: < T , <Vec < T > as IntoIterator >:: IntoIter > :: Single ( Some ( parts) ) ,
99+ position_byte : 0 ,
100+ position_bit : 0 ,
101+ current_part : None ,
102+ first : true ,
103+ done : false ,
104+ }
105+ }
106+ }
107+
108+ impl < T : AsRef < [ u8 ] > , S : Iterator < Item = T > > Bits < T , S > {
109+ pub fn new_many ( parts : S ) -> Self {
110+ Bits {
111+ parts : ManyOrSingle :: Many ( parts) ,
112+ position_byte : 0 ,
113+ position_bit : 0 ,
114+ current_part : None ,
115+ first : true ,
116+ done : false ,
117+ }
118+ }
119+
120+ pub fn is_done ( & self ) -> bool {
121+ self . done
122+ }
123+
124+ fn inc_part ( & mut self ) {
125+ self . current_part = match self . parts {
126+ ManyOrSingle :: Many ( ref mut parts) => {
127+ if self . first {
128+ self . first = false ;
129+ }
130+ parts. next ( )
131+ }
132+ ManyOrSingle :: Single ( ref mut part) => {
133+ if self . first {
134+ self . first = false ;
135+ part. take ( )
136+ } else {
137+ None
138+ }
139+ }
140+ }
141+ }
142+
143+ /// Increments the inner positions by 1 bit.
144+ fn inc ( & mut self ) {
145+ if self . position_bit < 7 {
146+ self . position_bit += 1 ;
147+ return ;
148+ }
149+
150+ self . position_bit = 0 ;
151+ if let Some ( ref part) = self . current_part {
152+ if self . position_byte + 1 < part. as_ref ( ) . len ( ) {
153+ self . position_byte += 1 ;
154+ return ;
155+ }
156+ }
157+
158+ self . inc_part ( ) ;
159+ self . position_byte = 0 ;
160+ self . done = self . current_part . is_none ( ) ;
161+ }
162+
163+ fn ref_take ( & mut self , take : usize ) -> BitsTake < ' _ , T , S > {
164+ BitsTake :: new ( self , take)
165+ }
166+ }
167+
168+ #[ derive( Debug ) ]
169+ struct BitsTake < ' a , T : AsRef < [ u8 ] > , S : Iterator < Item = T > > {
170+ iter : & ' a mut Bits < T , S > ,
171+ take : usize ,
172+ }
173+
174+ impl < ' a , T : AsRef < [ u8 ] > , S : Iterator < Item = T > > BitsTake < ' a , T , S > {
175+ pub fn new ( iter : & ' a mut Bits < T , S > , take : usize ) -> Self {
176+ BitsTake { iter, take }
177+ }
178+ }
179+
180+ impl < ' a , T : AsRef < [ u8 ] > , S : Iterator < Item = T > + std:: iter:: FusedIterator > std:: iter:: FusedIterator
181+ for BitsTake < ' a , T , S >
182+ {
183+ }
184+
185+ impl < ' a , T : AsRef < [ u8 ] > , S : Iterator < Item = T > > Iterator for BitsTake < ' a , T , S > {
186+ type Item = bool ;
187+
188+ fn next ( & mut self ) -> Option < Self :: Item > {
189+ if self . take == 0 {
190+ return None ;
191+ }
192+
193+ self . take -= 1 ;
194+ self . iter . next ( )
195+ }
196+ }
197+
198+ impl < T : AsRef < [ u8 ] > , S : Iterator < Item = T > + std:: iter:: FusedIterator > std:: iter:: FusedIterator
199+ for Bits < T , S >
200+ {
201+ }
202+
203+ impl < T : AsRef < [ u8 ] > , S : Iterator < Item = T > > Iterator for Bits < T , S > {
204+ type Item = bool ;
72205
73- bytes. truncate ( 0 ) ;
74- x. write_le ( bytes) . expect ( "failed to write result hash" ) ;
206+ fn next ( & mut self ) -> Option < Self :: Item > {
207+ if self . done {
208+ return None ;
209+ }
210+
211+ if self . first {
212+ // first time
213+ self . inc_part ( ) ;
214+ }
215+
216+ let byte = match self . current_part {
217+ Some ( ref part) => part. as_ref ( ) [ self . position_byte ] ,
218+ None => {
219+ self . done = true ;
220+ return None ;
221+ }
222+ } ;
223+
224+ let res = ( byte >> self . position_bit ) & 1u8 == 1u8 ;
225+ self . inc ( ) ;
226+
227+ Some ( res)
228+ }
229+
230+ // optimized nth method so we can use it to skip forward easily
231+ fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
232+ for _ in 0 ..n {
233+ // TODO: implement optimized inc for n bits.
234+ self . inc ( ) ;
235+ }
236+ self . next ( )
237+ }
75238}
76239
77240#[ cfg( test) ]
78241mod tests {
79242 use super :: * ;
80243 use crate :: util:: bytes_into_bits;
244+ use bitvec:: { self , BitVec } ;
81245 use ff:: Field ;
82246 use paired:: bls12_381:: Fr ;
83247 use rand:: { Rng , SeedableRng , XorShiftRng } ;
@@ -98,10 +262,12 @@ mod tests {
98262
99263 #[ test]
100264 fn test_pedersen_compression ( ) {
101- let bytes = b"some bytes" ;
102- let mut data = vec ! [ 0 ; bytes. len( ) ] ;
103- data. copy_from_slice ( & bytes[ ..] ) ;
104- pedersen_compression ( & mut data) ;
265+ let bytes = Bits :: new ( b"some bytes" ) ;
266+
267+ let x = pedersen_compression_bits ( bytes) ;
268+ let mut data = Vec :: new ( ) ;
269+ x. write_le ( & mut data) . unwrap ( ) ;
270+
105271 let expected = vec ! [
106272 237 , 70 , 41 , 231 , 39 , 180 , 131 , 120 , 36 , 36 , 119 , 199 , 200 , 225 , 153 , 242 , 106 , 116 ,
107273 70 , 9 , 12 , 249 , 169 , 84 , 105 , 38 , 225 , 115 , 165 , 188 , 98 , 25 ,
@@ -119,4 +285,45 @@ mod tests {
119285 assert_ne ! ( hashed, Fr :: zero( ) ) ;
120286 }
121287 }
288+
289+ #[ test]
290+ fn test_bits_collect ( ) {
291+ let bytes = b"hello" ;
292+ let bits = bytes_into_bits ( bytes) ;
293+
294+ let bits_iter = Bits :: new ( bytes) ;
295+ let bits_iter_collected: Vec < bool > = bits_iter. collect ( ) ;
296+
297+ assert_eq ! ( bits, bits_iter_collected) ;
298+
299+ let bytes = b"hello world these are some bytes" ;
300+ let bits = bytes_into_bits ( bytes) ;
301+
302+ let parts: Vec < & [ u8 ] > = vec ! [ b"hello " , b"world" , b" these are some bytes" ] ;
303+ let bits_iter = Bits :: new_many ( parts. into_iter ( ) ) ;
304+
305+ let bits_iter_collected: Vec < bool > = bits_iter. collect ( ) ;
306+
307+ assert_eq ! ( bits, bits_iter_collected) ;
308+ }
309+
310+ #[ test]
311+ fn test_bits_take ( ) {
312+ let bytes = b"hello world these are some bytes" ;
313+ let bits = bytes_into_bits ( bytes) ;
314+
315+ let parts: Vec < & [ u8 ] > = vec ! [ b"hello " , b"world" , b" these are some bytes" ] ;
316+ let mut bits_iter = Bits :: new_many ( parts. into_iter ( ) ) ;
317+
318+ let bits_collected: Vec < bool > = vec ! [
319+ bits_iter. ref_take( 8 ) . collect:: <Vec <bool >>( ) ,
320+ bits_iter. ref_take( 8 ) . collect:: <Vec <bool >>( ) ,
321+ bits_iter. ref_take( bits. len( ) - 16 ) . collect:: <Vec <bool >>( ) ,
322+ ]
323+ . into_iter ( )
324+ . flatten ( )
325+ . collect ( ) ;
326+
327+ assert_eq ! ( bits, bits_collected) ;
328+ }
122329}
0 commit comments