@@ -173,7 +173,8 @@ pub struct ConstraintSystem<F: FftField> {
173
173
pub lookup_selectors : Vec < E < F , D < F > > > ,
174
174
}
175
175
176
- /// Shifts represent the shifts required in the permutation argument of PLONK
176
+ /// Shifts represent the shifts required in the permutation argument of PLONK.
177
+ /// It also caches the shifted powers of omega for optimization purposes.
177
178
pub struct Shifts < F > {
178
179
/// The coefficients k that create a coset when multiplied with the generator of our domain.
179
180
shifts : [ F ; PERMUTS ] ,
@@ -197,11 +198,12 @@ where
197
198
// sample the other shifts
198
199
let mut i: u32 = 7 ;
199
200
for idx in 1 ..( PERMUTS ) {
200
- let mut o = Self :: sample ( & domain, & mut i) ;
201
- while shifts. iter ( ) . filter ( |& r| o == * r) . count ( ) > 0 {
202
- o = Self :: sample ( & domain, & mut i) ;
201
+ let mut shift = Self :: sample ( & domain, & mut i) ;
202
+ // they have to be distincts
203
+ while shifts. contains ( & shift) {
204
+ shift = Self :: sample ( & domain, & mut i) ;
203
205
}
204
- shifts[ idx] = o ;
206
+ shifts[ idx] = shift ;
205
207
}
206
208
207
209
// create a map of cells to their shifted value
@@ -213,28 +215,23 @@ where
213
215
}
214
216
215
217
/// sample coordinate shifts deterministically
216
- fn sample ( domain : & D < F > , i : & mut u32 ) -> F {
218
+ fn sample ( domain : & D < F > , input : & mut u32 ) -> F {
217
219
let mut h = Blake2b :: new ( ) ;
218
- h. update (
219
- & {
220
- * i += 1 ;
221
- * i
222
- }
223
- . to_be_bytes ( ) ,
224
- ) ;
225
- let mut r = F :: from_random_bytes ( & h. finalize ( ) [ ..31 ] ) . unwrap ( ) ;
226
- while r. legendre ( ) . is_qnr ( ) == false || domain. evaluate_vanishing_polynomial ( r) . is_zero ( ) {
220
+
221
+ * input += 1 ;
222
+ h. update ( & input. to_be_bytes ( ) ) ;
223
+
224
+ let mut shift = F :: from_random_bytes ( & h. finalize ( ) [ ..31 ] )
225
+ . expect ( "our field elements fit in more than 31 bytes" ) ;
226
+
227
+ while !shift. legendre ( ) . is_qnr ( ) || domain. evaluate_vanishing_polynomial ( shift) . is_zero ( ) {
227
228
let mut h = Blake2b :: new ( ) ;
228
- h. update (
229
- & {
230
- * i += 1 ;
231
- * i
232
- }
233
- . to_be_bytes ( ) ,
234
- ) ;
235
- r = F :: from_random_bytes ( & h. finalize ( ) [ ..31 ] ) . unwrap ( ) ;
229
+ * input += 1 ;
230
+ h. update ( & input. to_be_bytes ( ) ) ;
231
+ shift = F :: from_random_bytes ( & h. finalize ( ) [ ..31 ] )
232
+ . expect ( "our field elements fit in more than 31 bytes" ) ;
236
233
}
237
- r
234
+ shift
238
235
}
239
236
240
237
/// Returns the field element that represents a position
@@ -347,7 +344,6 @@ impl<F: FftField + SquareRootField> ConstraintSystem<F> {
347
344
gates. append ( & mut padding) ;
348
345
349
346
// sample the coordinate shifts
350
- // TODO(mimoo): should we check that the shifts are all different?
351
347
let shifts = Shifts :: new ( & domain. d1 ) ;
352
348
353
349
// compute permutation polynomials
0 commit comments