@@ -86,6 +86,48 @@ fn eval<E: Engine>(
86
86
acc
87
87
}
88
88
89
+ pub ( crate ) fn field_elements_into_representations < E : Engine > (
90
+ worker : & Worker ,
91
+ scalars : Vec < E :: Fr >
92
+ ) -> Result < Vec < <E :: Fr as PrimeField >:: Repr > , SynthesisError >
93
+ {
94
+ let mut representations = vec ! [ <E :: Fr as PrimeField >:: Repr :: default ( ) ; scalars. len( ) ] ;
95
+ worker. scope ( scalars. len ( ) , |scope, chunk| {
96
+ for ( scalar, repr) in scalars. chunks ( chunk)
97
+ . zip ( representations. chunks_mut ( chunk) ) {
98
+ scope. spawn ( move |_| {
99
+ for ( scalar, repr) in scalar. iter ( )
100
+ . zip ( repr. iter_mut ( ) ) {
101
+ * repr = scalar. into_repr ( ) ;
102
+ }
103
+ } ) ;
104
+ }
105
+ } ) ;
106
+
107
+ Ok ( representations)
108
+ }
109
+
110
+ pub ( crate ) fn scalars_into_representations < E : Engine > (
111
+ worker : & Worker ,
112
+ scalars : Vec < Scalar < E > >
113
+ ) -> Result < Vec < <E :: Fr as PrimeField >:: Repr > , SynthesisError >
114
+ {
115
+ let mut representations = vec ! [ <E :: Fr as PrimeField >:: Repr :: default ( ) ; scalars. len( ) ] ;
116
+ worker. scope ( scalars. len ( ) , |scope, chunk| {
117
+ for ( scalar, repr) in scalars. chunks ( chunk)
118
+ . zip ( representations. chunks_mut ( chunk) ) {
119
+ scope. spawn ( move |_| {
120
+ for ( scalar, repr) in scalar. iter ( )
121
+ . zip ( repr. iter_mut ( ) ) {
122
+ * repr = scalar. 0 . into_repr ( ) ;
123
+ }
124
+ } ) ;
125
+ }
126
+ } ) ;
127
+
128
+ Ok ( representations)
129
+ }
130
+
89
131
// This is a proving assignment with densities precalculated
90
132
pub struct PreparedProver < E : Engine > {
91
133
assignment : ProvingAssignment < E > ,
@@ -145,7 +187,7 @@ pub fn prepare_prover<E, C>(
145
187
146
188
impl < E : Engine > PreparedProver < E > {
147
189
pub fn create_random_proof < R , P : ParameterSource < E > > (
148
- & self ,
190
+ self ,
149
191
params : P ,
150
192
rng : & mut R
151
193
) -> Result < Proof < E > , SynthesisError >
@@ -158,16 +200,16 @@ impl<E:Engine> PreparedProver<E> {
158
200
}
159
201
160
202
pub fn create_proof < P : ParameterSource < E > > (
161
- & self ,
203
+ self ,
162
204
mut params : P ,
163
205
r : E :: Fr ,
164
206
s : E :: Fr
165
207
) -> Result < Proof < E > , SynthesisError >
166
208
{
167
- let prover = self . assignment . clone ( ) ;
209
+ let prover = self . assignment ;
168
210
let worker = Worker :: new ( ) ;
169
211
170
- let vk = params. get_vk ( self . assignment . input_assignment . len ( ) ) ?;
212
+ let vk = params. get_vk ( prover . input_assignment . len ( ) ) ?;
171
213
172
214
let stopwatch = Stopwatch :: new ( ) ;
173
215
@@ -202,7 +244,8 @@ impl<E:Engine> PreparedProver<E> {
202
244
a. truncate ( a_len) ;
203
245
// TODO: parallelize if it's even helpful
204
246
// TODO: in large settings it may worth to parallelize
205
- let a = Arc :: new ( a. into_iter ( ) . map ( |s| s. 0 . into_repr ( ) ) . collect :: < Vec < _ > > ( ) ) ;
247
+ let a = Arc :: new ( scalars_into_representations :: < E > ( & worker, a) ?) ;
248
+ // let a = Arc::new(a.into_iter().map(|s| s.0.into_repr()).collect::<Vec<_>>());
206
249
207
250
multiexp ( & worker, params. get_h ( a. len ( ) ) ?, FullDensity , a)
208
251
} ;
@@ -213,13 +256,19 @@ impl<E:Engine> PreparedProver<E> {
213
256
214
257
// TODO: Check that difference in operations for different chunks is small
215
258
259
+ let input_len = prover. input_assignment . len ( ) ;
260
+ let aux_len = prover. aux_assignment . len ( ) ;
261
+
262
+ let input_assignment = Arc :: new ( field_elements_into_representations :: < E > ( & worker, prover. input_assignment ) ?) ;
263
+ let aux_assignment = Arc :: new ( field_elements_into_representations :: < E > ( & worker, prover. aux_assignment ) ?) ;
264
+
216
265
// TODO: parallelize if it's even helpful
217
266
// TODO: in large settings it may worth to parallelize
218
- let input_assignment = Arc :: new ( prover. input_assignment . into_iter ( ) . map ( |s| s. into_repr ( ) ) . collect :: < Vec < _ > > ( ) ) ;
219
- let aux_assignment = Arc :: new ( prover. aux_assignment . into_iter ( ) . map ( |s| s. into_repr ( ) ) . collect :: < Vec < _ > > ( ) ) ;
267
+ // let input_assignment = Arc::new(prover.input_assignment.into_iter().map(|s| s.into_repr()).collect::<Vec<_>>());
268
+ // let aux_assignment = Arc::new(prover.aux_assignment.into_iter().map(|s| s.into_repr()).collect::<Vec<_>>());
220
269
221
- let input_len = input_assignment. len ( ) ;
222
- let aux_len = aux_assignment. len ( ) ;
270
+ // let input_len = input_assignment.len();
271
+ // let aux_len = aux_assignment.len();
223
272
elog_verbose ! ( "H query is dense in G1,\n Other queries are {} elements in G1 and {} elements in G2" ,
224
273
2 * ( input_len + aux_len) + aux_len, input_len + aux_len) ;
225
274
@@ -402,153 +451,13 @@ pub fn create_random_proof<E, C, R, P: ParameterSource<E>>(
402
451
403
452
pub fn create_proof < E , C , P : ParameterSource < E > > (
404
453
circuit : C ,
405
- mut params : P ,
454
+ params : P ,
406
455
r : E :: Fr ,
407
456
s : E :: Fr
408
457
) -> Result < Proof < E > , SynthesisError >
409
458
where E : Engine , C : Circuit < E >
410
459
{
411
- let mut prover = ProvingAssignment {
412
- a_aux_density : DensityTracker :: new ( ) ,
413
- b_input_density : DensityTracker :: new ( ) ,
414
- b_aux_density : DensityTracker :: new ( ) ,
415
- a : vec ! [ ] ,
416
- b : vec ! [ ] ,
417
- c : vec ! [ ] ,
418
- input_assignment : vec ! [ ] ,
419
- aux_assignment : vec ! [ ]
420
- } ;
421
-
422
- prover. alloc_input ( || "" , || Ok ( E :: Fr :: one ( ) ) ) ?;
460
+ let prover = prepare_prover ( circuit) ?;
423
461
424
- circuit. synthesize ( & mut prover) ?;
425
-
426
- for i in 0 ..prover. input_assignment . len ( ) {
427
- prover. enforce ( || "" ,
428
- |lc| lc + Variable ( Index :: Input ( i) ) ,
429
- |lc| lc,
430
- |lc| lc,
431
- ) ;
432
- }
433
-
434
- let worker = Worker :: new ( ) ;
435
-
436
- let vk = params. get_vk ( prover. input_assignment . len ( ) ) ?;
437
-
438
- let stopwatch = Stopwatch :: new ( ) ;
439
-
440
- let h = {
441
- let mut a = EvaluationDomain :: from_coeffs ( prover. a ) ?;
442
- let mut b = EvaluationDomain :: from_coeffs ( prover. b ) ?;
443
- let mut c = EvaluationDomain :: from_coeffs ( prover. c ) ?;
444
- elog_verbose ! ( "H query domain size is {}" , a. as_ref( ) . len( ) ) ;
445
- // here a coset is a domain where denominator (z) does not vanish
446
- // inverse FFT is an interpolation
447
- a. ifft ( & worker) ;
448
- // evaluate in coset
449
- a. coset_fft ( & worker) ;
450
- // same is for B and C
451
- b. ifft ( & worker) ;
452
- b. coset_fft ( & worker) ;
453
- c. ifft ( & worker) ;
454
- c. coset_fft ( & worker) ;
455
-
456
- // do A*B-C in coset
457
- a. mul_assign ( & worker, & b) ;
458
- drop ( b) ;
459
- a. sub_assign ( & worker, & c) ;
460
- drop ( c) ;
461
- // z does not vanish in coset, so we divide by non-zero
462
- a. divide_by_z_on_coset ( & worker) ;
463
- // interpolate back in coset
464
- a. icoset_fft ( & worker) ;
465
- let mut a = a. into_coeffs ( ) ;
466
- let a_len = a. len ( ) - 1 ;
467
- a. truncate ( a_len) ;
468
- // TODO: parallelize if it's even helpful
469
- // TODO: in large settings it may worth to parallelize
470
- let a = Arc :: new ( a. into_iter ( ) . map ( |s| s. 0 . into_repr ( ) ) . collect :: < Vec < _ > > ( ) ) ;
471
-
472
- multiexp ( & worker, params. get_h ( a. len ( ) ) ?, FullDensity , a)
473
- } ;
474
-
475
- elog_verbose ! ( "{} seconds for prover for H evaluation (mostly FFT)" , stopwatch. elapsed( ) ) ;
476
-
477
- let stopwatch = Stopwatch :: new ( ) ;
478
-
479
- // TODO: Check that difference in operations for different chunks is small
480
-
481
- // TODO: parallelize if it's even helpful
482
- // TODO: in large settings it may worth to parallelize
483
- let input_assignment = Arc :: new ( prover. input_assignment . into_iter ( ) . map ( |s| s. into_repr ( ) ) . collect :: < Vec < _ > > ( ) ) ;
484
- let aux_assignment = Arc :: new ( prover. aux_assignment . into_iter ( ) . map ( |s| s. into_repr ( ) ) . collect :: < Vec < _ > > ( ) ) ;
485
-
486
- // Run a dedicated process for dense vector
487
- let l = multiexp ( & worker, params. get_l ( aux_assignment. len ( ) ) ?, FullDensity , aux_assignment. clone ( ) ) ;
488
-
489
- let a_aux_density_total = prover. a_aux_density . get_total_density ( ) ;
490
-
491
- let ( a_inputs_source, a_aux_source) = params. get_a ( input_assignment. len ( ) , a_aux_density_total) ?;
492
-
493
- let a_inputs = multiexp ( & worker, a_inputs_source, FullDensity , input_assignment. clone ( ) ) ;
494
- let a_aux = multiexp ( & worker, a_aux_source, Arc :: new ( prover. a_aux_density ) , aux_assignment. clone ( ) ) ;
495
-
496
- let b_input_density = Arc :: new ( prover. b_input_density ) ;
497
- let b_input_density_total = b_input_density. get_total_density ( ) ;
498
- let b_aux_density = Arc :: new ( prover. b_aux_density ) ;
499
- let b_aux_density_total = b_aux_density. get_total_density ( ) ;
500
-
501
- let ( b_g1_inputs_source, b_g1_aux_source) = params. get_b_g1 ( b_input_density_total, b_aux_density_total) ?;
502
-
503
- let b_g1_inputs = multiexp ( & worker, b_g1_inputs_source, b_input_density. clone ( ) , input_assignment. clone ( ) ) ;
504
- let b_g1_aux = multiexp ( & worker, b_g1_aux_source, b_aux_density. clone ( ) , aux_assignment. clone ( ) ) ;
505
-
506
- let ( b_g2_inputs_source, b_g2_aux_source) = params. get_b_g2 ( b_input_density_total, b_aux_density_total) ?;
507
-
508
- let b_g2_inputs = multiexp ( & worker, b_g2_inputs_source, b_input_density, input_assignment) ;
509
- let b_g2_aux = multiexp ( & worker, b_g2_aux_source, b_aux_density, aux_assignment) ;
510
-
511
- if vk. delta_g1 . is_zero ( ) || vk. delta_g2 . is_zero ( ) {
512
- // If this element is zero, someone is trying to perform a
513
- // subversion-CRS attack.
514
- return Err ( SynthesisError :: UnexpectedIdentity ) ;
515
- }
516
-
517
- let mut g_a = vk. delta_g1 . mul ( r) ;
518
- g_a. add_assign_mixed ( & vk. alpha_g1 ) ;
519
- let mut g_b = vk. delta_g2 . mul ( s) ;
520
- g_b. add_assign_mixed ( & vk. beta_g2 ) ;
521
- let mut g_c;
522
- {
523
- let mut rs = r;
524
- rs. mul_assign ( & s) ;
525
-
526
- g_c = vk. delta_g1 . mul ( rs) ;
527
- g_c. add_assign ( & vk. alpha_g1 . mul ( s) ) ;
528
- g_c. add_assign ( & vk. beta_g1 . mul ( r) ) ;
529
- }
530
- let mut a_answer = a_inputs. wait ( ) ?;
531
- a_answer. add_assign ( & a_aux. wait ( ) ?) ;
532
- g_a. add_assign ( & a_answer) ;
533
- a_answer. mul_assign ( s) ;
534
- g_c. add_assign ( & a_answer) ;
535
-
536
- let mut b1_answer = b_g1_inputs. wait ( ) ?;
537
- b1_answer. add_assign ( & b_g1_aux. wait ( ) ?) ;
538
- let mut b2_answer = b_g2_inputs. wait ( ) ?;
539
- b2_answer. add_assign ( & b_g2_aux. wait ( ) ?) ;
540
-
541
- g_b. add_assign ( & b2_answer) ;
542
- b1_answer. mul_assign ( r) ;
543
- g_c. add_assign ( & b1_answer) ;
544
- g_c. add_assign ( & h. wait ( ) ?) ;
545
- g_c. add_assign ( & l. wait ( ) ?) ;
546
-
547
- elog_verbose ! ( "{} seconds for prover for point multiplication" , stopwatch. elapsed( ) ) ;
548
-
549
- Ok ( Proof {
550
- a : g_a. into_affine ( ) ,
551
- b : g_b. into_affine ( ) ,
552
- c : g_c. into_affine ( )
553
- } )
462
+ prover. create_proof ( params, r, s)
554
463
}
0 commit comments