bellman_ce/plonk/verifier/
mod.rs

1use crate::pairing::ff::{Field, PrimeField};
2use crate::pairing::{Engine};
3
4use crate::{SynthesisError};
5use std::marker::PhantomData;
6
7use crate::plonk::cs::gates::*;
8use crate::plonk::cs::*;
9
10use crate::worker::*;
11use super::polynomials::*;
12use super::domains::*;
13use crate::plonk::commitments::*;
14use crate::plonk::commitments::transcript::*;
15use crate::plonk::utils::*;
16use crate::plonk::generator::*;
17use crate::plonk::prover::*;
18
19fn evaluate_inverse_vanishing_poly<E: Engine>(vahisning_size: usize, point: E::Fr) -> E::Fr {
20    assert!(vahisning_size.is_power_of_two());
21
22    // update from the paper - it should not hold for the last generator, omega^(n) in original notations
23
24    // Z(X) = (X^(n+1) - 1) / (X - omega^(n)) => Z^{-1}(X) = (X - omega^(n)) / (X^(n+1) - 1)
25
26    let domain = Domain::<E::Fr>::new_for_size(vahisning_size as u64).expect("should fit");
27    let n_domain_omega = domain.generator;
28    let root = n_domain_omega.pow([(vahisning_size - 1) as u64]);
29
30    let mut numerator = point;
31    numerator.sub_assign(&root);
32
33    let mut denominator = point.pow([vahisning_size as u64]);
34    denominator.sub_assign(&E::Fr::one());
35
36    let denominator = denominator.inverse().expect("must exist");
37
38    numerator.mul_assign(&denominator);
39
40    numerator
41}
42
43fn evaluate_lagrange_poly<E: Engine>(vahisning_size:usize, poly_number: usize, at: E::Fr) -> E::Fr {
44    assert!(vahisning_size.is_power_of_two());
45
46    let mut repr = E::Fr::zero().into_repr();
47    repr.as_mut()[0] = vahisning_size as u64;
48
49    let size_fe = E::Fr::from_repr(repr).expect("is a valid representation");
50    // let size_inv = n_fe.inverse().expect("must exist");
51
52    // L_0(X) = (Z_H(X) / (X - 1)).(1/n) and L_0(1) = 1
53    // L_1(omega) = 1 = L_0(omega * omega^-1)
54
55    let domain = Domain::<E::Fr>::new_for_size(vahisning_size as u64).expect("domain of this size should exist");
56    let omega = domain.generator;
57
58    let omega_inv = omega.inverse().expect("must exist");
59
60    let argument_multiplier = omega_inv.pow([poly_number as u64]);
61    let mut argument = at;
62    argument.mul_assign(&argument_multiplier);
63
64    let mut numerator = argument.pow([vahisning_size as u64]);
65    numerator.sub_assign(&E::Fr::one());
66
67    let mut denom = argument;
68    denom.sub_assign(&E::Fr::one());
69    denom.mul_assign(&size_fe);
70
71    let denom_inv = denom.inverse().expect("must exist");
72
73    numerator.mul_assign(&denom_inv);
74
75    numerator
76}
77
78pub fn verify_nonhomomorphic<E: Engine, S: CommitmentScheme<E::Fr, Prng = T>, T: Transcript<E::Fr, Input = S::Commitment>>(
79    setup: &PlonkSetup<E, S>,
80    proof: &PlonkNonhomomorphicProof<E, S>, 
81    meta: S::Meta,
82    large_meta: S::Meta
83) -> Result<bool, SynthesisError> {
84    assert!(S::IS_HOMOMORPHIC == false);
85
86    let num_gates = setup.n;
87
88    let committer = S::new_for_size(num_gates.next_power_of_two(), meta);
89    let large_committer = S::new_for_size(4 * num_gates.next_power_of_two(), large_meta);
90
91    let mut transcript = T::new();
92
93    // we need n+1 to be a power of two and can not have n to be power of two
94    let required_domain_size = setup.n + 1;
95    assert!(required_domain_size.is_power_of_two());
96
97    transcript.commit_input(&proof.a_commitment);
98    transcript.commit_input(&proof.b_commitment);
99    transcript.commit_input(&proof.c_commitment);
100
101    let beta = transcript.get_challenge();
102    let gamma = transcript.get_challenge();
103
104    transcript.commit_input(&proof.z_1_commitment);
105    transcript.commit_input(&proof.z_2_commitment);
106
107    // we do not commit those cause those are known already
108
109    let n_fe = E::Fr::from_str(&setup.n.to_string()).expect("must be valid field element");
110    let mut two_n_fe = n_fe;
111    two_n_fe.double();
112
113    let alpha = transcript.get_challenge();
114
115    transcript.commit_input(&proof.t_commitment);
116
117    let z = transcript.get_challenge();
118
119    // this is a sanity check
120
121    let a_at_z = proof.a_opening_value;
122    let b_at_z = proof.b_opening_value;
123    let c_at_z = proof.c_opening_value;
124
125    let q_l_at_z = proof.q_l_opening_value;
126    let q_r_at_z = proof.q_r_opening_value;
127    let q_o_at_z = proof.q_o_opening_value;
128    let q_m_at_z = proof.q_m_opening_value;
129    let q_c_at_z = proof.q_c_opening_value;
130
131    let s_id_at_z = proof.s_id_opening_value;
132    let sigma_1_at_z = proof.sigma_1_opening_value;
133    let sigma_2_at_z = proof.sigma_2_opening_value;
134    let sigma_3_at_z = proof.sigma_3_opening_value;
135
136    let mut inverse_vanishing_at_z = evaluate_inverse_vanishing_poly::<E>(required_domain_size.next_power_of_two(), z);
137
138    let z_1_at_z = proof.z_1_unshifted_opening_value;
139    let z_2_at_z = proof.z_2_unshifted_opening_value;
140
141    let z_1_shifted_at_z = proof.z_1_shifted_opening_value;
142    let z_2_shifted_at_z = proof.z_2_shifted_opening_value;
143
144    let l_0_at_z = evaluate_lagrange_poly::<E>(required_domain_size.next_power_of_two(), 0, z);
145    let l_n_minus_one_at_z = evaluate_lagrange_poly::<E>(required_domain_size.next_power_of_two(), setup.n - 1, z);
146
147    let t_at_z = proof.t_opening_value;
148
149    {
150        transcript.commit_field_element(&a_at_z);
151        transcript.commit_field_element(&b_at_z);
152        transcript.commit_field_element(&c_at_z);
153
154        transcript.commit_field_element(&q_l_at_z);
155        transcript.commit_field_element(&q_r_at_z);
156        transcript.commit_field_element(&q_o_at_z);
157        transcript.commit_field_element(&q_m_at_z);
158        transcript.commit_field_element(&q_c_at_z);
159
160        transcript.commit_field_element(&s_id_at_z);
161        transcript.commit_field_element(&sigma_1_at_z);
162        transcript.commit_field_element(&sigma_2_at_z);
163        transcript.commit_field_element(&sigma_3_at_z);
164
165        transcript.commit_field_element(&t_at_z);
166
167        transcript.commit_field_element(&z_1_at_z);
168        transcript.commit_field_element(&z_2_at_z);
169
170        transcript.commit_field_element(&z_1_shifted_at_z);
171        transcript.commit_field_element(&z_2_shifted_at_z);
172    }
173
174    let aggregation_challenge = transcript.get_challenge();
175
176    // let shifted_opening_aggregation_challenge = transcript.get_challenge();
177
178    // TODO: add public inputs
179
180    // verify by blindly assembling a t poly
181    let mut t_1 = {
182        let mut res = q_c_at_z;
183
184        let mut tmp = q_l_at_z;
185        tmp.mul_assign(&a_at_z);
186        res.add_assign(&tmp);
187
188        let mut tmp = q_r_at_z;
189        tmp.mul_assign(&b_at_z);
190        res.add_assign(&tmp);
191
192        let mut tmp = q_o_at_z;
193        tmp.mul_assign(&c_at_z);
194        res.add_assign(&tmp);
195
196        let mut tmp = q_m_at_z;
197        tmp.mul_assign(&a_at_z);
198        tmp.mul_assign(&b_at_z);
199        res.add_assign(&tmp);
200
201        inverse_vanishing_at_z.mul_assign(&alpha);
202
203        res.mul_assign(&inverse_vanishing_at_z);
204
205        res
206    };
207
208    {
209        let mut res = z_1_at_z;
210
211        let mut tmp = s_id_at_z;
212        tmp.mul_assign(&beta);
213        tmp.add_assign(&a_at_z);
214        tmp.add_assign(&gamma);
215        res.mul_assign(&tmp);
216
217        let mut tmp = s_id_at_z;
218        tmp.add_assign(&n_fe);
219        tmp.mul_assign(&beta);
220        tmp.add_assign(&b_at_z);
221        tmp.add_assign(&gamma);
222        res.mul_assign(&tmp);
223
224        let mut tmp = s_id_at_z;
225        tmp.add_assign(&two_n_fe);
226        tmp.mul_assign(&beta);
227        tmp.add_assign(&c_at_z);
228        tmp.add_assign(&gamma);
229        res.mul_assign(&tmp);
230
231        res.sub_assign(&z_1_shifted_at_z);
232
233        inverse_vanishing_at_z.mul_assign(&alpha);
234
235        res.mul_assign(&inverse_vanishing_at_z);
236
237        t_1.add_assign(&res);
238    }
239
240    {
241        let mut res = z_2_at_z;
242
243        let mut tmp = sigma_1_at_z;
244        tmp.mul_assign(&beta);
245        tmp.add_assign(&a_at_z);
246        tmp.add_assign(&gamma);
247        res.mul_assign(&tmp);
248
249        let mut tmp = sigma_2_at_z;
250        tmp.mul_assign(&beta);
251        tmp.add_assign(&b_at_z);
252        tmp.add_assign(&gamma);
253        res.mul_assign(&tmp);
254
255        let mut tmp = sigma_3_at_z;
256        tmp.mul_assign(&beta);
257        tmp.add_assign(&c_at_z);
258        tmp.add_assign(&gamma);
259        res.mul_assign(&tmp);
260
261        res.sub_assign(&z_2_shifted_at_z);
262
263        inverse_vanishing_at_z.mul_assign(&alpha);
264
265        res.mul_assign(&inverse_vanishing_at_z);
266
267        t_1.add_assign(&res);
268    }
269
270    {
271        let mut res = z_1_shifted_at_z;
272        res.sub_assign(&z_2_shifted_at_z);
273        res.mul_assign(&l_n_minus_one_at_z);
274
275        inverse_vanishing_at_z.mul_assign(&alpha);
276
277        res.mul_assign(&inverse_vanishing_at_z);
278
279        t_1.add_assign(&res);
280    }
281
282    {
283        let mut res = z_1_at_z;
284        res.sub_assign(&z_2_at_z);
285        res.mul_assign(&l_0_at_z);
286
287        inverse_vanishing_at_z.mul_assign(&alpha);
288
289        res.mul_assign(&inverse_vanishing_at_z);
290
291        t_1.add_assign(&res);
292    }
293
294    let domain = Domain::<E::Fr>::new_for_size(required_domain_size as u64)?;
295
296    let mut z_by_omega = z;
297    z_by_omega.mul_assign(&domain.generator);
298
299    let commitments = vec![
300        &proof.a_commitment,
301        &proof.b_commitment,
302        &proof.c_commitment,
303        &setup.q_l,
304        &setup.q_r,
305        &setup.q_o,
306        &setup.q_m,
307        &setup.q_c,
308        &setup.s_id,
309        &setup.sigma_1,
310        &setup.sigma_2,
311        &setup.sigma_3,
312        &proof.z_1_commitment,
313        &proof.z_2_commitment,
314        &proof.z_1_commitment,
315        &proof.z_2_commitment,
316    ];
317
318    let claimed_values = vec![
319        a_at_z,
320        b_at_z,
321        c_at_z,
322        q_l_at_z,
323        q_r_at_z,
324        q_o_at_z,
325        q_m_at_z,
326        q_c_at_z,
327        s_id_at_z,
328        sigma_1_at_z,
329        sigma_2_at_z,
330        sigma_3_at_z,
331        z_1_at_z,
332        z_2_at_z,
333        z_1_shifted_at_z,
334        z_2_shifted_at_z,
335    ];
336
337    let opening_points = vec![
338        z, 
339        z,
340        z,
341
342        z, 
343        z,
344        z,
345        z,
346        z,
347
348        z,
349        z,
350        z,
351        z,
352
353        z,
354        z,
355
356        z_by_omega,
357        z_by_omega
358    ];
359
360    if t_1 != t_at_z {
361        println!("Recalculated t(z) is not equal to the provided value");
362        return Ok(false);
363    }
364
365    let valid = committer.verify_multiple_openings(commitments, opening_points, &claimed_values, aggregation_challenge, &proof.openings_proof, &mut transcript);
366
367    if !valid {
368        println!("Multiopening is invalid");
369        return Ok(false);
370    }
371
372    let valid = large_committer.verify_single(&proof.t_commitment, z, proof.t_opening_value, &proof.t_opening_proof, &mut transcript);
373
374    if !valid {
375        println!("T commitment opening is invalid");
376        return Ok(false);
377    }
378
379
380
381    // let mut opening_point = z;
382    // opening_point.mul_assign(&domain.generator);
383
384    // let commitments = vec![
385    //     &proof.z_1_commitment,
386    //     &proof.z_2_commitment,
387    // ];
388
389    // let claimed_values = vec![
390    //     proof.z_1_shifted_opening_value,
391    //     proof.z_2_shifted_opening_value
392    // ];
393
394    // let valid = committer.verify_multiple_openings(commitments, opening_point, &claimed_values, shifted_opening_aggregation_challenge, &proof.shifted_openings_proof, &mut transcript);
395
396    Ok(valid)
397}
398
399#[track_caller]
400pub fn verify_nonhomomorphic_chunked<E: Engine, S: CommitmentScheme<E::Fr, Prng = T>, T: Transcript<E::Fr, Input = S::Commitment>>(
401    setup: &PlonkSetup<E, S>,
402    proof: &PlonkChunkedNonhomomorphicProof<E, S>, 
403    meta: S::Meta
404) -> Result<bool, SynthesisError> {
405    assert!(S::IS_HOMOMORPHIC == false);
406
407    let num_gates = setup.n;
408
409    let t = std::time::Instant::now();
410    let committer = S::new_for_size(num_gates.next_power_of_two(), meta);
411    println!("Committer creation taken {:?}", t.elapsed());
412
413    let t0 = std::time::Instant::now();
414
415    let mut transcript = T::new();
416
417    let t = std::time::Instant::now();
418
419    // we need n+1 to be a power of two and can not have n to be power of two
420    let required_domain_size = setup.n + 1;
421    assert!(required_domain_size.is_power_of_two());
422
423    transcript.commit_input(&proof.a_commitment);
424    transcript.commit_input(&proof.b_commitment);
425    transcript.commit_input(&proof.c_commitment);
426
427    let beta = transcript.get_challenge();
428    let gamma = transcript.get_challenge();
429
430    transcript.commit_input(&proof.z_1_commitment);
431    transcript.commit_input(&proof.z_2_commitment);
432
433    // we do not commit those cause those are known already
434
435    let n_fe = E::Fr::from_str(&setup.n.to_string()).expect("must be valid field element");
436    let mut two_n_fe = n_fe;
437    two_n_fe.double();
438
439    let alpha = transcript.get_challenge();
440
441    transcript.commit_input(&proof.t_low_commitment);
442    transcript.commit_input(&proof.t_mid_commitment);
443    transcript.commit_input(&proof.t_high_commitment);
444
445    let z = transcript.get_challenge();
446
447    // this is a sanity check
448
449    let a_at_z = proof.a_opening_value;
450    let b_at_z = proof.b_opening_value;
451    let c_at_z = proof.c_opening_value;
452
453    let q_l_at_z = proof.q_l_opening_value;
454    let q_r_at_z = proof.q_r_opening_value;
455    let q_o_at_z = proof.q_o_opening_value;
456    let q_m_at_z = proof.q_m_opening_value;
457    let q_c_at_z = proof.q_c_opening_value;
458
459    let s_id_at_z = proof.s_id_opening_value;
460    let sigma_1_at_z = proof.sigma_1_opening_value;
461    let sigma_2_at_z = proof.sigma_2_opening_value;
462    let sigma_3_at_z = proof.sigma_3_opening_value;
463
464    let mut inverse_vanishing_at_z = evaluate_inverse_vanishing_poly::<E>(required_domain_size, z);
465
466    let z_1_at_z = proof.z_1_unshifted_opening_value;
467    let z_2_at_z = proof.z_2_unshifted_opening_value;
468
469    let z_1_shifted_at_z = proof.z_1_shifted_opening_value;
470    let z_2_shifted_at_z = proof.z_2_shifted_opening_value;
471
472    let l_0_at_z = evaluate_lagrange_poly::<E>(required_domain_size, 0, z);
473    let l_n_minus_one_at_z = evaluate_lagrange_poly::<E>(required_domain_size, setup.n - 1, z);
474
475    let t_low_at_z = proof.t_low_opening_value;
476    let t_mid_at_z = proof.t_mid_opening_value;
477    let t_high_at_z = proof.t_high_opening_value;
478
479    let z_in_pow_of_domain_size = z.pow([required_domain_size as u64]);
480
481    let mut t_at_z = E::Fr::zero();
482    t_at_z.add_assign(&t_low_at_z);
483
484    let mut tmp = z_in_pow_of_domain_size;
485    tmp.mul_assign(&t_mid_at_z);
486    t_at_z.add_assign(&tmp);
487
488    let mut tmp = z_in_pow_of_domain_size;
489    tmp.mul_assign(&z_in_pow_of_domain_size);
490    tmp.mul_assign(&t_high_at_z);
491    t_at_z.add_assign(&tmp);
492
493    {
494        transcript.commit_field_element(&a_at_z);
495        transcript.commit_field_element(&b_at_z);
496        transcript.commit_field_element(&c_at_z);
497
498        transcript.commit_field_element(&q_l_at_z);
499        transcript.commit_field_element(&q_r_at_z);
500        transcript.commit_field_element(&q_o_at_z);
501        transcript.commit_field_element(&q_m_at_z);
502        transcript.commit_field_element(&q_c_at_z);
503
504        transcript.commit_field_element(&s_id_at_z);
505        transcript.commit_field_element(&sigma_1_at_z);
506        transcript.commit_field_element(&sigma_2_at_z);
507        transcript.commit_field_element(&sigma_3_at_z);
508
509        transcript.commit_field_element(&t_low_at_z);
510        transcript.commit_field_element(&t_mid_at_z);
511        transcript.commit_field_element(&t_high_at_z);
512
513        transcript.commit_field_element(&z_1_at_z);
514        transcript.commit_field_element(&z_2_at_z);
515
516        transcript.commit_field_element(&z_1_shifted_at_z);
517        transcript.commit_field_element(&z_2_shifted_at_z);
518    }
519
520    let aggregation_challenge = transcript.get_challenge();
521
522    // TODO: add public inputs
523
524    // verify by blindly assembling a t poly
525    let mut t_1 = {
526        let mut res = q_c_at_z;
527
528        let mut tmp = q_l_at_z;
529        tmp.mul_assign(&a_at_z);
530        res.add_assign(&tmp);
531
532        let mut tmp = q_r_at_z;
533        tmp.mul_assign(&b_at_z);
534        res.add_assign(&tmp);
535
536        let mut tmp = q_o_at_z;
537        tmp.mul_assign(&c_at_z);
538        res.add_assign(&tmp);
539
540        let mut tmp = q_m_at_z;
541        tmp.mul_assign(&a_at_z);
542        tmp.mul_assign(&b_at_z);
543        res.add_assign(&tmp);
544
545        inverse_vanishing_at_z.mul_assign(&alpha);
546
547        res.mul_assign(&inverse_vanishing_at_z);
548
549        res
550    };
551
552    {
553        let mut res = z_1_at_z;
554
555        let mut tmp = s_id_at_z;
556        tmp.mul_assign(&beta);
557        tmp.add_assign(&a_at_z);
558        tmp.add_assign(&gamma);
559        res.mul_assign(&tmp);
560
561        let mut tmp = s_id_at_z;
562        tmp.add_assign(&n_fe);
563        tmp.mul_assign(&beta);
564        tmp.add_assign(&b_at_z);
565        tmp.add_assign(&gamma);
566        res.mul_assign(&tmp);
567
568        let mut tmp = s_id_at_z;
569        tmp.add_assign(&two_n_fe);
570        tmp.mul_assign(&beta);
571        tmp.add_assign(&c_at_z);
572        tmp.add_assign(&gamma);
573        res.mul_assign(&tmp);
574
575        res.sub_assign(&z_1_shifted_at_z);
576
577        inverse_vanishing_at_z.mul_assign(&alpha);
578
579        res.mul_assign(&inverse_vanishing_at_z);
580
581        t_1.add_assign(&res);
582    }
583
584    {
585        let mut res = z_2_at_z;
586
587        let mut tmp = sigma_1_at_z;
588        tmp.mul_assign(&beta);
589        tmp.add_assign(&a_at_z);
590        tmp.add_assign(&gamma);
591        res.mul_assign(&tmp);
592
593        let mut tmp = sigma_2_at_z;
594        tmp.mul_assign(&beta);
595        tmp.add_assign(&b_at_z);
596        tmp.add_assign(&gamma);
597        res.mul_assign(&tmp);
598
599        let mut tmp = sigma_3_at_z;
600        tmp.mul_assign(&beta);
601        tmp.add_assign(&c_at_z);
602        tmp.add_assign(&gamma);
603        res.mul_assign(&tmp);
604
605        res.sub_assign(&z_2_shifted_at_z);
606
607        inverse_vanishing_at_z.mul_assign(&alpha);
608
609        res.mul_assign(&inverse_vanishing_at_z);
610
611        t_1.add_assign(&res);
612    }
613
614    {
615        let mut res = z_1_shifted_at_z;
616        res.sub_assign(&z_2_shifted_at_z);
617        res.mul_assign(&l_n_minus_one_at_z);
618
619        inverse_vanishing_at_z.mul_assign(&alpha);
620
621        res.mul_assign(&inverse_vanishing_at_z);
622
623        t_1.add_assign(&res);
624    }
625
626    {
627        let mut res = z_1_at_z;
628        res.sub_assign(&z_2_at_z);
629        res.mul_assign(&l_0_at_z);
630
631        inverse_vanishing_at_z.mul_assign(&alpha);
632
633        res.mul_assign(&inverse_vanishing_at_z);
634
635        t_1.add_assign(&res);
636    }
637
638    let domain = Domain::<E::Fr>::new_for_size(required_domain_size as u64)?;
639
640    let mut z_by_omega = z;
641    z_by_omega.mul_assign(&domain.generator);
642
643    let commitments = vec![
644        &proof.a_commitment,
645        &proof.b_commitment,
646        &proof.c_commitment,
647
648        &setup.q_l,
649        &setup.q_r,
650        &setup.q_o,
651        &setup.q_m,
652        &setup.q_c,
653
654        &setup.s_id,
655        &setup.sigma_1,
656        &setup.sigma_2,
657        &setup.sigma_3,
658
659        &proof.z_1_commitment,
660        &proof.z_2_commitment,
661
662        &proof.z_1_commitment,
663        &proof.z_2_commitment,
664
665        &proof.t_low_commitment,
666        &proof.t_mid_commitment,
667        &proof.t_high_commitment,
668    ];
669
670    let claimed_values = vec![
671        a_at_z,
672        b_at_z,
673        c_at_z,
674
675        q_l_at_z,
676        q_r_at_z,
677        q_o_at_z,
678        q_m_at_z,
679        q_c_at_z,
680
681        s_id_at_z,
682        sigma_1_at_z,
683        sigma_2_at_z,
684        sigma_3_at_z,
685
686        z_1_at_z,
687        z_2_at_z,
688
689        z_1_shifted_at_z,
690        z_2_shifted_at_z,
691
692        t_low_at_z,
693        t_mid_at_z,
694        t_high_at_z,
695    ];
696
697    let opening_points = vec![
698        z, 
699        z,
700        z,
701
702        z, 
703        z,
704        z,
705        z,
706        z,
707
708        z,
709        z,
710        z,
711        z,
712
713        z,
714        z,
715
716        z_by_omega,
717        z_by_omega,
718
719        z,
720        z,
721        z,
722    ];
723
724    if t_1 != t_at_z {
725        println!("Recalculated t(z) is not equal to the provided value");
726        return Ok(false);
727    }
728
729    println!("Initial verification taken {:?}", t.elapsed());
730
731    let t = std::time::Instant::now();
732
733    let valid = committer.verify_multiple_openings(
734        commitments, 
735        opening_points, 
736        &claimed_values, 
737        aggregation_challenge, 
738        &proof.openings_proof, 
739        &mut transcript
740    );
741
742    println!("Verification of multiple openings taken {:?}", t.elapsed());
743
744    if !valid {
745        println!("Multiopening is invalid");
746        return Ok(false);
747    }
748
749    println!("Verification without overhead taken {:?}", t0.elapsed());
750
751    Ok(valid)
752}
753
754#[cfg(test)]
755mod test {
756
757    use super::*;
758    use crate::pairing::ff::{Field, PrimeField};
759    use crate::pairing::{Engine};
760
761    use crate::{SynthesisError};
762    use std::marker::PhantomData;
763
764    use crate::plonk::cs::gates::*;
765    use crate::plonk::cs::*;
766
767    struct TestCircuit<E:Engine>{
768        _marker: PhantomData<E>
769    }
770
771    impl<E: Engine> Circuit<E> for TestCircuit<E> {
772        fn synthesize<CS: ConstraintSystem<E>>(&self, cs: &mut CS) -> Result<(), SynthesisError> {
773            let a = cs.alloc(|| {
774                Ok(E::Fr::from_str("10").unwrap())
775            })?;
776
777            let b = cs.alloc(|| {
778                Ok(E::Fr::from_str("20").unwrap())
779            })?;
780
781            let c = cs.alloc(|| {
782                Ok(E::Fr::from_str("200").unwrap())
783            })?;
784
785            let one = E::Fr::one();
786
787            let mut two = one;
788            two.double();
789
790            let mut negative_one = one;
791            negative_one.negate();
792
793            cs.enforce_zero_2((a, b), (two, negative_one))?;
794
795            let ten = E::Fr::from_str("10").unwrap();
796            cs.enforce_zero_2((b, c), (ten, negative_one))?;
797
798            cs.enforce_mul_3((a, b, c))?;
799
800            Ok(())
801        }
802    }
803
804    struct InvalidTestCircuit<E:Engine>{
805        _marker: PhantomData<E>
806    }
807
808    impl<E: Engine> Circuit<E> for InvalidTestCircuit<E> {
809        fn synthesize<CS: ConstraintSystem<E>>(&self, cs: &mut CS) -> Result<(), SynthesisError> {
810            let a = cs.alloc(|| {
811                Ok(E::Fr::from_str("11").unwrap())
812            })?;
813
814            let b = cs.alloc(|| {
815                Ok(E::Fr::from_str("20").unwrap())
816            })?;
817
818            let c = cs.alloc(|| {
819                Ok(E::Fr::from_str("200").unwrap())
820            })?;
821
822            let one = E::Fr::one();
823
824            let mut two = one;
825            two.double();
826
827            let mut negative_one = one;
828            negative_one.negate();
829
830            cs.enforce_zero_2((a, b), (two, negative_one))?;
831
832            let ten = E::Fr::from_str("10").unwrap();
833            cs.enforce_zero_2((b, c), (ten, negative_one))?;
834
835            cs.enforce_mul_3((a, b, c))?;
836
837            Ok(())
838        }
839    }
840
841    #[test]
842    fn test_small_circuit_transparent_verification() {
843        use crate::pairing::bn256::{Bn256, Fr};
844        use crate::plonk::utils::*;
845        use crate::plonk::commitments::transparent::fri::*;
846        use crate::plonk::commitments::transparent::iop::*;
847        use crate::plonk::commitments::transcript::*;
848        use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*;
849        use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*;
850        use crate::plonk::commitments::*;
851        use crate::plonk::commitments::transparent::*;
852
853        type Iop = TrivialBlake2sIOP<Fr>;
854        type Fri = NaiveFriIop<Fr, Iop>;
855        type Committer = StatelessTransparentCommitter<Fr, Fri, Blake2sTranscript<Fr>>;
856
857        let meta = TransparentCommitterParameters {
858            lde_factor: 16,
859            num_queries: 2,
860            output_coeffs_at_degree_plus_one: 1,
861            fri_params: ()
862        };
863
864        let meta_large = TransparentCommitterParameters {
865            lde_factor: 16,
866            num_queries: 2,
867            output_coeffs_at_degree_plus_one: 1,
868            fri_params: ()
869        };
870
871        let circuit = TestCircuit::<Bn256> {
872            _marker: PhantomData
873        };
874
875        let (setup, aux) = setup::<Bn256, Committer, _>(&circuit, meta).unwrap();
876
877        let meta = TransparentCommitterParameters {
878            lde_factor: 16,
879            num_queries: 2,
880            output_coeffs_at_degree_plus_one: 1,
881            fri_params: ()
882        };
883
884        println!("Proving");
885
886        let proof = prove_nonhomomorphic::<Bn256, Committer, Blake2sTranscript::<Fr>, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap();
887
888
889        println!("Verifying");
890
891        let valid = verify_nonhomomorphic::<Bn256, Committer, Blake2sTranscript::<Fr>>(&setup, &proof, meta, meta_large).unwrap();
892
893        assert!(valid);
894    }
895
896    #[test]
897    fn test_small_circuit_invalid_witness_transparent_verification() {
898        use crate::pairing::bn256::{Bn256, Fr};
899        use crate::plonk::utils::*;
900        use crate::plonk::commitments::transparent::fri::*;
901        use crate::plonk::commitments::transparent::iop::*;
902        use crate::plonk::commitments::transcript::*;
903        use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*;
904        use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*;
905        use crate::plonk::commitments::*;
906        use crate::plonk::commitments::transparent::*;
907
908        type Iop = TrivialBlake2sIOP<Fr>;
909        type Fri = NaiveFriIop<Fr, Iop>;
910        type Committer = StatelessTransparentCommitter<Fr, Fri, Blake2sTranscript<Fr>>;
911
912        let meta = TransparentCommitterParameters {
913            lde_factor: 16,
914            num_queries: 2,
915            output_coeffs_at_degree_plus_one: 1,
916            fri_params: ()
917        };
918
919        let meta_large = TransparentCommitterParameters {
920            lde_factor: 16,
921            num_queries: 2,
922            output_coeffs_at_degree_plus_one: 1,
923            fri_params: ()
924        };
925
926        let circuit = InvalidTestCircuit::<Bn256> {
927            _marker: PhantomData
928        };
929
930        let (setup, aux) = setup::<Bn256, Committer, _>(&circuit, meta.clone()).unwrap();
931
932        println!("Proving");
933
934        let proof = prove_nonhomomorphic::<Bn256, Committer, Blake2sTranscript::<Fr>, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap();
935
936        println!("Verifying");
937
938        let valid = verify_nonhomomorphic::<Bn256, Committer, Blake2sTranscript::<Fr>>(&setup, &proof, meta, meta_large).unwrap();
939
940        assert!(!valid);
941    }
942
943    #[derive(Clone)]
944    struct BenchmarkCircuit<E:Engine>{
945        num_steps: usize,
946        _marker: PhantomData<E>
947    }
948
949    impl<E: Engine> Circuit<E> for BenchmarkCircuit<E> {
950        fn synthesize<CS: ConstraintSystem<E>>(&self, cs: &mut CS) -> Result<(), SynthesisError> {
951            // yeah, fibonacci...
952
953            let one = E::Fr::one();
954            let mut negative_one = one;
955            negative_one.negate();
956
957            let mut two = one;
958            two.double();
959            
960            let mut a = cs.alloc(|| {
961                Ok(E::Fr::one())
962            })?;
963
964            let mut b = cs.alloc(|| {
965                Ok(E::Fr::one())
966            })?;
967
968            cs.enforce_constant(a, E::Fr::one())?;
969            cs.enforce_constant(b, E::Fr::one())?;
970
971            let mut c = cs.alloc(|| {
972                Ok(two)
973            })?;
974
975            cs.enforce_zero_3((a, b, c), (one, one, negative_one))?;
976
977            let mut a_value = one;
978            let mut b_value = one;
979            let mut c_value = two;
980
981            for _ in 0..self.num_steps {
982                a = b;
983                b = c;
984
985                a_value = b_value;
986                b_value = c_value;
987                c_value.add_assign(&a_value);
988
989                c = cs.alloc(|| {
990                    Ok(c_value)
991                })?;
992
993                cs.enforce_zero_3((a, b, c), (one, one, negative_one))?;
994            }
995
996            Ok(())
997        }
998    }
999
1000    #[test]
1001    fn test_bench_fibonacci_circuit() {
1002        use crate::pairing::bn256::{Bn256, Fr};
1003        use crate::plonk::utils::*;
1004        use crate::plonk::commitments::transparent::fri::*;
1005        use crate::plonk::commitments::transparent::iop::*;
1006        use crate::plonk::commitments::transcript::*;
1007        use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*;
1008        use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*;
1009        use crate::plonk::commitments::*;
1010        use crate::plonk::commitments::transparent::*;
1011        use crate::plonk::tester::*;
1012
1013        use std::time::Instant;
1014
1015        type Iop = TrivialBlake2sIOP<Fr>;
1016        type Fri = NaiveFriIop<Fr, Iop>;
1017        type Committer = StatelessTransparentCommitter<Fr, Fri, Blake2sTranscript<Fr>>;
1018
1019        let meta = TransparentCommitterParameters {
1020            lde_factor: 16,
1021            num_queries: 10,
1022            output_coeffs_at_degree_plus_one: 16,
1023            fri_params: ()
1024        };
1025
1026        let meta_large = TransparentCommitterParameters {
1027            lde_factor: 16,
1028            num_queries: 10,
1029            output_coeffs_at_degree_plus_one: 16,
1030            fri_params: ()
1031        };
1032
1033        let circuit = BenchmarkCircuit::<Bn256> {
1034            num_steps: 1_000_000,
1035            _marker: PhantomData
1036        };
1037
1038        {
1039            let mut tester = TestingAssembly::<Bn256>::new();
1040
1041            circuit.synthesize(&mut tester).expect("must synthesize");
1042
1043            let satisfied = tester.is_satisfied();
1044
1045            assert!(satisfied);
1046
1047            println!("Circuit is satisfied");
1048        }
1049
1050        println!("Start setup");
1051        let start = Instant::now();
1052        let (setup, aux) = setup::<Bn256, Committer, _>(&circuit, meta).unwrap();
1053        println!("Setup taken {:?}", start.elapsed());
1054
1055        println!("Using circuit with N = {}", setup.n);
1056
1057        let meta = TransparentCommitterParameters {
1058            lde_factor: 16,
1059            num_queries: 10,
1060            output_coeffs_at_degree_plus_one: 16,
1061            fri_params: ()
1062        };
1063
1064        println!("Start proving");
1065        let start = Instant::now();
1066        let proof = prove_nonhomomorphic::<Bn256, Committer, Blake2sTranscript::<Fr>, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap();
1067        println!("Proof taken {:?}", start.elapsed());
1068
1069        println!("Start verifying");
1070        let start = Instant::now();
1071        let valid = verify_nonhomomorphic::<Bn256, Committer, Blake2sTranscript::<Fr>>(&setup, &proof, meta, meta_large).unwrap();
1072        println!("Verification with unnecessary precomputation taken {:?}", start.elapsed());
1073
1074        assert!(valid);
1075    }
1076
1077    // #[test]
1078    // fn test_bench_keccak_for_fibonacci_circuit() {
1079    //     use crate::pairing::bn256::{Bn256, Fr};
1080    //     use crate::plonk::utils::*;
1081    //     use crate::plonk::commitments::transparent::fri::*;
1082    //     use crate::plonk::commitments::transparent::iop::*;
1083    //     use crate::plonk::commitments::transcript::*;
1084    //     use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*;
1085    //     use crate::plonk::commitments::transparent::iop::keccak_trivial_iop::*;
1086    //     use crate::plonk::commitments::*;
1087    //     use crate::plonk::commitments::transparent::*;
1088
1089    //     use std::time::Instant;
1090
1091    //     type Iop = TrivialKeccakIOP<Fr>;
1092    //     type Fri = NaiveFriIop<Fr, Iop>;
1093    //     type Committer = StatelessTransparentCommitter<Fr, Fri, Blake2sTranscript<Fr>>;
1094
1095    //     let meta = TransparentCommitterParameters {
1096    //         lde_factor: 16,
1097    //         num_queries: 10,
1098    //         output_coeffs_at_degree_plus_one: 16,
1099    //     };
1100
1101    //     let meta_large = TransparentCommitterParameters {
1102    //         lde_factor: 16,
1103    //         num_queries: 10,
1104    //         output_coeffs_at_degree_plus_one: 16,
1105    //     };
1106
1107    //     let circuit = BenchmarkCircuit::<Bn256> {
1108    //         num_steps: 1_000_000,
1109    //         _marker: PhantomData
1110    //     };
1111
1112    //     println!("Start setup");
1113    //     let start = Instant::now();
1114    //     let setup = setup::<Bn256, Committer, _>(&circuit, meta).unwrap();
1115    //     println!("Setup taken {:?}", start.elapsed());
1116
1117    //     println!("Using circuit with N = {}", setup.n);
1118
1119    //     let meta = TransparentCommitterParameters {
1120    //         lde_factor: 16,
1121    //         num_queries: 10,
1122    //         output_coeffs_at_degree_plus_one: 16,
1123    //     };
1124
1125    //     println!("Start proving");
1126    //     let start = Instant::now();
1127    //     let proof = prove_nonhomomorphic::<Bn256, Committer, Blake2sTranscript::<Fr>, _>(&circuit, meta, meta_large).unwrap();
1128    //     println!("Proof taken {:?}", start.elapsed());
1129
1130    //     let meta = TransparentCommitterParameters {
1131    //         lde_factor: 16,
1132    //         num_queries: 10,
1133    //         output_coeffs_at_degree_plus_one: 16,
1134    //     };
1135
1136    //     let meta_large = TransparentCommitterParameters {
1137    //         lde_factor: 16,
1138    //         num_queries: 10,
1139    //         output_coeffs_at_degree_plus_one: 16,
1140    //     };
1141
1142    //     println!("Start verifying");
1143    //     let start = Instant::now();
1144    //     let valid = verify_nonhomomorphic::<Bn256, Committer, Blake2sTranscript::<Fr>>(&setup, &proof, meta, meta_large).unwrap();
1145    //     println!("Verification with unnecessary precomputation taken {:?}", start.elapsed());
1146
1147    //     assert!(!valid);
1148    // }
1149
1150    #[test]
1151    fn test_bench_homomorphic_plonk() {
1152        use rand::{XorShiftRng, SeedableRng, Rand, Rng};
1153        use crate::pairing::bn256::Bn256;
1154        use num_cpus;
1155        use crate::pairing::ff::ScalarEngine;
1156        use crate::pairing::CurveProjective;
1157        use crate::multiexp::*;
1158        use crate::worker::*;
1159        use crate::source::*;
1160        use std::sync::Arc;
1161        use futures::{Future};
1162
1163        const SAMPLES: usize = 1 << 20;
1164        let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1165
1166        let v = (0..SAMPLES).map(|_| <Bn256 as ScalarEngine>::Fr::rand(rng).into_repr()).collect::<Vec<_>>();
1167        let g = (0..SAMPLES).map(|_| <Bn256 as Engine>::G1::rand(rng).into_affine()).collect::<Vec<_>>();
1168
1169        println!("Done generating test points and scalars");
1170
1171        let pool = Worker::new();
1172        let start = std::time::Instant::now();
1173
1174        let _sparse = multiexp(
1175            &pool,
1176            (Arc::new(g), 0),
1177            FullDensity,
1178            Arc::new(v)
1179        ).wait().unwrap();
1180
1181        let per_one_poly = start.elapsed().as_micros();
1182        // a, b, c, z_1, z_2, t, opening at z (of length t), opening at z*omega(of length a)
1183        let total_expected_plonk = per_one_poly * (5 + 1 + 3 + 3 + 1); 
1184        println!("{} ms for expected plonk with ~ {} gates", total_expected_plonk/1000u128, SAMPLES);
1185    }
1186
1187    #[test]
1188    fn test_bench_transparent_engine() {
1189        use crate::plonk::transparent_engine::proth_engine::*;
1190        use crate::plonk::utils::*;
1191        use crate::plonk::commitments::transparent::fri::*;
1192        use crate::plonk::commitments::transparent::iop::*;
1193        use crate::plonk::commitments::transcript::*;
1194        use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*;
1195        use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*;
1196        use crate::plonk::commitments::*;
1197        use crate::plonk::commitments::transparent::*;
1198        use crate::plonk::tester::*;
1199
1200        use std::time::Instant;
1201
1202        type Iop = TrivialBlake2sIOP<Fr>;
1203        type Fri = NaiveFriIop<Fr, Iop>;
1204        type Committer = StatelessTransparentCommitter<Fr, Fri, Blake2sTranscript<Fr>>;
1205
1206        let mut negative_one = Fr::one();
1207        negative_one.negate();
1208        println!("-1 = {}", negative_one);
1209
1210        let meta = TransparentCommitterParameters {
1211            lde_factor: 16,
1212            num_queries: 10,
1213            output_coeffs_at_degree_plus_one: 16,
1214            fri_params: ()
1215        };
1216
1217        let meta_large = TransparentCommitterParameters {
1218            lde_factor: 16,
1219            num_queries: 10,
1220            output_coeffs_at_degree_plus_one: 16,
1221            fri_params: ()
1222        };
1223
1224        let circuit = BenchmarkCircuit::<Transparent252> {
1225            num_steps: 20,
1226            _marker: PhantomData
1227        };
1228
1229        {
1230            let mut tester = TestingAssembly::<Transparent252>::new();
1231
1232            circuit.synthesize(&mut tester).expect("must synthesize");
1233
1234            let satisfied = tester.is_satisfied();
1235
1236            assert!(satisfied);
1237
1238            println!("Circuit is satisfied");
1239        }
1240
1241        println!("Start setup");
1242        let start = Instant::now();
1243        let (setup, aux) = setup::<Transparent252, Committer, _>(&circuit, meta).unwrap();
1244        println!("Setup taken {:?}", start.elapsed());
1245
1246        println!("Using circuit with N = {}", setup.n);
1247
1248        let meta = TransparentCommitterParameters {
1249            lde_factor: 16,
1250            num_queries: 10,
1251            output_coeffs_at_degree_plus_one: 16,
1252            fri_params: ()
1253        };
1254
1255        println!("Start proving");
1256        let start = Instant::now();
1257        let proof = prove_nonhomomorphic::<Transparent252, Committer, Blake2sTranscript::<Fr>, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap();
1258        println!("Proof taken {:?}", start.elapsed());
1259
1260        println!("Start verifying");
1261        let start = Instant::now();
1262        let valid = verify_nonhomomorphic::<Transparent252, Committer, Blake2sTranscript::<Fr>>(&setup, &proof, meta, meta_large).unwrap();
1263        println!("Verification with unnecessary precomputation taken {:?}", start.elapsed());
1264
1265        assert!(valid);
1266    }
1267
1268    #[test]
1269    fn test_bench_chunked_proof_on_transparent_engine() {
1270        use crate::plonk::transparent_engine::proth_engine::*;
1271        use crate::plonk::utils::*;
1272        use crate::plonk::commitments::transparent::fri::*;
1273        use crate::plonk::commitments::transparent::iop::*;
1274        use crate::plonk::commitments::transcript::*;
1275        use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*;
1276        use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*;
1277        use crate::plonk::commitments::*;
1278        use crate::plonk::commitments::transparent::*;
1279        use crate::plonk::tester::*;
1280
1281        use std::time::Instant;
1282
1283        type Iop = TrivialBlake2sIOP<Fr>;
1284        type Fri = NaiveFriIop<Fr, Iop>;
1285        type Committer = StatelessTransparentCommitter<Fr, Fri, Blake2sTranscript<Fr>>;
1286        let params = ();
1287
1288        let mut negative_one = Fr::one();
1289        negative_one.negate();
1290        println!("-1 = {}", negative_one);
1291
1292        let meta = TransparentCommitterParameters {
1293            lde_factor: 16,
1294            num_queries: 10,
1295            output_coeffs_at_degree_plus_one: 2,
1296            fri_params: params
1297        };
1298
1299        let circuit = BenchmarkCircuit::<Transparent252> {
1300            num_steps: 20,
1301            _marker: PhantomData
1302        };
1303
1304        {
1305            let mut tester = TestingAssembly::<Transparent252>::new();
1306
1307            circuit.synthesize(&mut tester).expect("must synthesize");
1308
1309            let satisfied = tester.is_satisfied();
1310
1311            assert!(satisfied);
1312
1313            println!("Circuit is satisfied");
1314        }
1315
1316        println!("Start setup");
1317        let start = Instant::now();
1318        let (setup, aux) = setup::<Transparent252, Committer, _>(&circuit, meta.clone()).unwrap();
1319        println!("Setup taken {:?}", start.elapsed());
1320
1321        println!("Using circuit with N = {}", setup.n);
1322
1323        println!("Start proving");
1324        let start = Instant::now();
1325        let proof = prove_nonhomomorphic_chunked::<Transparent252, Committer, Blake2sTranscript::<Fr>, _>(&circuit, &aux, meta.clone()).unwrap();
1326        println!("Proof taken {:?}", start.elapsed());
1327
1328        let proof_size = proof.estimate_proof_size();
1329        dbg!(&proof_size);
1330
1331        println!("Start verifying");
1332        let start = Instant::now();
1333        let valid = verify_nonhomomorphic_chunked::<Transparent252, Committer, Blake2sTranscript::<Fr>>(&setup, &proof, meta).unwrap();
1334        println!("Verification with unnecessary precomputation taken {:?}", start.elapsed());
1335
1336        assert!(valid);
1337    }
1338
1339
1340    #[test]
1341    fn test_bench_chunked_proof_on_transparent_engine_over_sizes() {
1342        use crate::plonk::transparent_engine::proth_engine::*;
1343        use crate::plonk::utils::*;
1344        use crate::plonk::commitments::transparent::fri::*;
1345        use crate::plonk::commitments::transparent::iop::*;
1346        use crate::plonk::commitments::transcript::*;
1347        use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*;
1348        use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*;
1349        use crate::plonk::commitments::*;
1350        use crate::plonk::commitments::transparent::*;
1351        use crate::plonk::tester::*;
1352
1353        use std::time::Instant;
1354
1355        type Iop = TrivialBlake2sIOP<Fr>;
1356        type Fri = NaiveFriIop<Fr, Iop>;
1357        type Committer = StatelessTransparentCommitter<Fr, Fri, Blake2sTranscript<Fr>>;
1358        let params = ();
1359
1360        let mut negative_one = Fr::one();
1361        negative_one.negate();
1362        println!("-1 = {}", negative_one);
1363
1364        let num_queries = 20;
1365
1366        for log2 in 10..=20 {
1367            let size = (1<<log2) - 10;
1368
1369            let meta = TransparentCommitterParameters {
1370                lde_factor: 16,
1371                num_queries: num_queries,
1372                output_coeffs_at_degree_plus_one: 16,
1373                fri_params: params
1374            };
1375
1376            let circuit = BenchmarkCircuit::<Transparent252> {
1377                num_steps: size,
1378                _marker: PhantomData
1379            };
1380
1381            {
1382                let mut tester = TestingAssembly::<Transparent252>::new();
1383
1384                circuit.synthesize(&mut tester).expect("must synthesize");
1385
1386                let satisfied = tester.is_satisfied();
1387
1388                assert!(satisfied);
1389
1390                println!("Circuit is satisfied");
1391            }
1392
1393            println!("Start setup");
1394            let start = Instant::now();
1395            let (setup, aux) = setup::<Transparent252, Committer, _>(&circuit, meta.clone()).unwrap();
1396            println!("Setup taken {:?}", start.elapsed());
1397
1398            let size_log_2 = setup.n.next_power_of_two().trailing_zeros();
1399
1400            println!("Using circuit with N = {}", setup.n);
1401
1402            println!("Start proving");
1403            let start = Instant::now();
1404            let proof = prove_nonhomomorphic_chunked::<Transparent252, Committer, Blake2sTranscript::<Fr>, _>(&circuit, &aux, meta.clone()).unwrap();
1405            println!("Proof taken {:?} for 2^{}", start.elapsed(), size_log_2);
1406
1407            let proof_size = proof.estimate_proof_size();
1408            println!("Proof size is {} for 2^{} for {} queries", proof_size, size_log_2, num_queries);
1409
1410            println!("Start verifying");
1411            let start = Instant::now();
1412            let valid = verify_nonhomomorphic_chunked::<Transparent252, Committer, Blake2sTranscript::<Fr>>(&setup, &proof, meta).unwrap();
1413            println!("Verification with unnecessary precomputation taken {:?} for 2^{}", start.elapsed(), size_log_2);
1414
1415            assert!(valid);
1416        }
1417    }
1418
1419
1420    #[test]
1421    fn test_poly_eval_correctness() {
1422        use rand::{XorShiftRng, SeedableRng, Rand, Rng};
1423        use crate::pairing::bn256::Fr;
1424        use num_cpus;
1425        use crate::pairing::ff::ScalarEngine;
1426        use crate::pairing::CurveProjective;
1427        use crate::multiexp::*;
1428        use crate::worker::*;
1429        use crate::source::*;
1430        use std::sync::Arc;
1431        use futures::{Future};
1432
1433        let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1434
1435        let poly_sizes = vec![1, 10, 100, 1000, 10_000, 1_000_000];
1436
1437        let x: Fr = rng.gen();
1438
1439        let worker = Worker::new();
1440
1441        for poly_size in poly_sizes.into_iter() {
1442            let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
1443            let mut point = Fr::one();
1444            let mut result = Fr::zero();
1445            for c in coeffs.iter() {
1446                let mut tmp = point;
1447                tmp.mul_assign(&c);
1448                result.add_assign(&tmp);
1449
1450                point.mul_assign(&x);
1451            }
1452
1453            let poly = Polynomial::<Fr, _>::from_coeffs(coeffs).unwrap();
1454            let eval_result = poly.evaluate_at(&worker, x);
1455            assert!(eval_result == result, "failed for size {}", poly_size);
1456        }
1457    }
1458
1459    #[test]
1460    fn test_poly_grand_product_correctness() {
1461        use rand::{XorShiftRng, SeedableRng, Rand, Rng};
1462        use crate::pairing::bn256::Fr;
1463        use num_cpus;
1464        use crate::pairing::ff::ScalarEngine;
1465        use crate::pairing::CurveProjective;
1466        use crate::multiexp::*;
1467        use crate::worker::*;
1468        use crate::source::*;
1469        use std::sync::Arc;
1470        use futures::{Future};
1471
1472        let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1473
1474        let poly_sizes = vec![1, 10, 100, 1000, 10_000, 1_000_000];
1475
1476        let worker = Worker::new();
1477
1478        for poly_size in poly_sizes.into_iter() {
1479            let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).filter(|el| !el.is_zero()).collect::<Vec<_>>();
1480            let poly = Polynomial::<Fr, _>::from_values_unpadded(coeffs).unwrap();
1481            let palallel_result = poly.calculate_grand_product(&worker).unwrap();
1482            let serial_result = poly.calculate_grand_product_serial().unwrap();
1483
1484            if palallel_result != serial_result {
1485                for (i, (c0, c1)) in palallel_result.as_ref().iter()
1486                                .zip(serial_result.as_ref().iter())
1487                                .enumerate() 
1488                {
1489                    assert!(c0 == c1, "failed at value number {} for size {}", i, poly_size);
1490                }
1491            }
1492        }
1493    }
1494
1495    #[test]
1496    fn test_bench_lde() {
1497        use rand::{XorShiftRng, SeedableRng, Rand, Rng};
1498        use crate::pairing::bn256::Fr;
1499        use crate::pairing::ff::ScalarEngine;
1500        use crate::pairing::CurveProjective;
1501        use std::time::Instant;
1502        use crate::worker::*;
1503        use crate::plonk::commitments::transparent::utils::*;
1504
1505        let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1506
1507        let poly_sizes = vec![1, 10, 100, 1000, 10_000, 1_000_000, 2_000_000];
1508
1509        let worker = Worker::new();
1510
1511        for poly_size in poly_sizes.into_iter() {
1512            let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
1513        
1514            let poly = Polynomial::<Fr, _>::from_coeffs(coeffs).unwrap();
1515            let start = Instant::now();
1516            let _eval_result = poly.lde(&worker, 16);
1517            println!("LDE with factor 16 for size {} taken {:?}", poly_size, start.elapsed());
1518
1519            let coeffs = (0..(16*poly_size)).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
1520        
1521            let poly = Polynomial::<Fr, _>::from_coeffs(coeffs).unwrap();
1522            let start = Instant::now();
1523            let eval_result = poly.clone().fft(&worker);
1524            println!("FFT of the same size taken {:?}", start.elapsed());
1525
1526            if log2_floor(poly.size()) % 2 == 0 {
1527                let log_n = log2_floor(poly.size());
1528                let omega = poly.omega;
1529                let mut coeffs = poly.into_coeffs();
1530                let start = Instant::now();
1531                crate::plonk::fft::radix_4::best_fft(&mut coeffs, &worker, &omega, log_n as u32);
1532                println!("Radix-4 FFT of the same size taken {:?}", start.elapsed());
1533                let to_compare = eval_result.into_coeffs();
1534                assert!(to_compare == coeffs);
1535            }
1536
1537
1538        }
1539    }
1540}