1
- use bitvec:: { self , BitVec } ;
2
1
use ff:: PrimeFieldRepr ;
3
2
use fil_sapling_crypto:: jubjub:: JubjubBls12 ;
4
3
use fil_sapling_crypto:: pedersen_hash:: { pedersen_hash, Personalization } ;
@@ -20,64 +19,229 @@ pub const PEDERSEN_BLOCK_SIZE: usize = 256;
20
19
pub const PEDERSEN_BLOCK_BYTES : usize = PEDERSEN_BLOCK_SIZE / 8 ;
21
20
22
21
pub 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
32
29
}
33
30
34
31
/// Pedersen hashing for inputs that have length mulitple of the block size `256`. Based on pedersen hashes and a Merkle-Damgard construction.
35
32
pub 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
+ }
50
35
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" ) ;
55
53
}
56
54
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" ) ;
59
56
assert_eq ! ( frs. len( ) , 1 ) ;
60
57
frs[ 0 ]
61
58
}
62
59
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 ;
72
205
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
+ }
75
238
}
76
239
77
240
#[ cfg( test) ]
78
241
mod tests {
79
242
use super :: * ;
80
243
use crate :: util:: bytes_into_bits;
244
+ use bitvec:: { self , BitVec } ;
81
245
use ff:: Field ;
82
246
use paired:: bls12_381:: Fr ;
83
247
use rand:: { Rng , SeedableRng , XorShiftRng } ;
@@ -98,10 +262,12 @@ mod tests {
98
262
99
263
#[ test]
100
264
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
+
105
271
let expected = vec ! [
106
272
237 , 70 , 41 , 231 , 39 , 180 , 131 , 120 , 36 , 36 , 119 , 199 , 200 , 225 , 153 , 242 , 106 , 116 ,
107
273
70 , 9 , 12 , 249 , 169 , 84 , 105 , 38 , 225 , 115 , 165 , 188 , 98 , 25 ,
@@ -119,4 +285,45 @@ mod tests {
119
285
assert_ne ! ( hashed, Fr :: zero( ) ) ;
120
286
}
121
287
}
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
+ }
122
329
}
0 commit comments