1use crate::{
2 kzg10,
3 marlin::{marlin_pc, Marlin},
4 BatchLCProof, Error, Evaluations, LabeledCommitment, LabeledPolynomial, LinearCombination,
5 PCCommitmentState, PCUniversalParams, PolynomialCommitment, QuerySet, CHALLENGE_SIZE,
6};
7use ark_crypto_primitives::sponge::CryptographicSponge;
8use ark_ec::{
9 pairing::Pairing,
10 scalar_mul::{BatchMulPreprocessing, ScalarMul},
11 AffineRepr, CurveGroup, VariableBaseMSM,
12};
13use ark_ff::{One, PrimeField, UniformRand, Zero};
14use ark_poly::{multivariate::Term, DenseMVPolynomial};
15use ark_std::{marker::PhantomData, ops::Index, ops::Mul, rand::RngCore};
16#[cfg(not(feature = "std"))]
17use ark_std::{string::ToString, vec::Vec};
18#[cfg(feature = "parallel")]
19use rayon::prelude::*;
20
21mod data_structures;
22pub use data_structures::*;
23
24mod combinations;
25use combinations::*;
26
27pub struct MarlinPST13<E: Pairing, P: DenseMVPolynomial<E::ScalarField>> {
34 _engine: PhantomData<E>,
35 _poly: PhantomData<P>,
36}
37
38impl<E: Pairing, P: DenseMVPolynomial<E::ScalarField>> MarlinPST13<E, P> {
39 fn divide_at_point(p: &P, point: &P::Point) -> Vec<P>
45 where
46 P::Point: Index<usize, Output = E::ScalarField>,
47 {
48 let num_vars = p.num_vars();
49 if p.is_zero() {
50 return vec![P::zero(); num_vars];
51 }
52 let mut quotients = Vec::with_capacity(num_vars);
53 let mut cur = p.clone();
55 for i in 0..num_vars {
57 let mut quotient_terms = Vec::new();
58 let mut remainder_terms = Vec::new();
59 for (mut coeff, term) in cur.terms() {
60 if term.is_constant() {
63 continue;
64 }
65 let mut term_vec = (&*term).to_vec();
68 match term_vec.binary_search_by(|(var, _)| var.cmp(&i)) {
69 Ok(idx) => {
70 while term_vec[idx].1 > 1 {
73 term_vec[idx] = (i, term_vec[idx].1 - 1);
75 quotient_terms.push((coeff, P::Term::new(term_vec.clone())));
76 coeff *= &point[i];
78 }
79 term_vec.remove(idx);
81 quotient_terms.push((coeff, P::Term::new(term_vec.clone())));
82 remainder_terms.push((point[i] * &coeff, P::Term::new(term_vec)));
83 }
84 Err(_) => remainder_terms.push((coeff, term.clone())),
85 }
86 }
87 quotients.push(P::from_coefficients_vec(num_vars, quotient_terms));
88 cur = P::from_coefficients_vec(num_vars, remainder_terms);
90 }
91 quotients
92 }
93
94 fn check_hiding_bound(hiding_poly_degree: usize, num_powers: usize) -> Result<(), Error> {
96 if hiding_poly_degree == 0 {
97 Err(Error::HidingBoundIsZero)
98 } else if hiding_poly_degree >= num_powers {
99 Err(Error::HidingBoundToolarge {
103 hiding_poly_degree,
104 num_powers,
105 })
106 } else {
107 Ok(())
108 }
109 }
110
111 fn check_degrees_and_bounds<'a>(
113 supported_degree: usize,
114 p: &'a LabeledPolynomial<E::ScalarField, P>,
115 ) -> Result<(), Error>
116 where
117 P: 'a,
118 {
119 if p.degree() > supported_degree {
120 return Err(Error::PolynomialDegreeTooLarge {
121 poly_degree: p.degree(),
122 supported_degree,
123 label: p.label().to_string(),
124 });
125 } else {
126 Ok(())
127 }
128 }
129
130 fn convert_to_bigints(p: &P) -> Vec<<E::ScalarField as PrimeField>::BigInt> {
132 let plain_coeffs = ark_std::cfg_into_iter!(p.terms())
133 .map(|(coeff, _)| coeff.into_bigint())
134 .collect();
135 plain_coeffs
136 }
137}
138
139impl<E, P> PolynomialCommitment<E::ScalarField, P> for MarlinPST13<E, P>
140where
141 E: Pairing,
142 P: DenseMVPolynomial<E::ScalarField> + Sync,
143 P::Point: Index<usize, Output = E::ScalarField>,
144{
145 type UniversalParams = UniversalParams<E, P>;
146 type CommitterKey = CommitterKey<E, P>;
147 type VerifierKey = VerifierKey<E>;
148 type Commitment = marlin_pc::Commitment<E>;
149 type CommitmentState = Randomness<E, P>;
150 type Proof = Proof<E>;
151 type BatchProof = Vec<Self::Proof>;
152 type Error = Error;
153
154 fn setup<R: RngCore>(
157 max_degree: usize,
158 num_vars: Option<usize>,
159 rng: &mut R,
160 ) -> Result<UniversalParams<E, P>, Error> {
161 let num_vars = num_vars.ok_or(Error::InvalidNumberOfVariables)?;
162 if num_vars < 1 {
163 return Err(Error::InvalidNumberOfVariables);
164 }
165 if max_degree < 1 {
166 return Err(Error::DegreeIsZero);
167 }
168 let setup_time = start_timer!(|| format!(
169 "MarlinPST13::Setup with {} variables and max degree {}",
170 num_vars, max_degree
171 ));
172 let mut betas = Vec::with_capacity(num_vars);
174 for _ in 0..num_vars {
175 betas.push(E::ScalarField::rand(rng));
176 }
177 let g = E::G1::rand(rng);
179 let gamma_g = E::G1::rand(rng);
180 let h = E::G2::rand(rng);
181
182 let variable_set: Vec<_> = (0..num_vars)
184 .flat_map(|var| vec![var; max_degree])
185 .collect();
186 let (powers_of_beta, mut powers_of_beta_terms): (Vec<_>, Vec<_>) = (1..=max_degree)
188 .flat_map(|degree| {
189 let terms: Vec<Vec<usize>> = if variable_set.len() == degree {
191 vec![variable_set.clone()]
192 } else {
193 Combinations::new(variable_set.clone(), degree).collect()
194 };
195 ark_std::cfg_into_iter!(terms)
198 .map(|term| {
199 let value: E::ScalarField = term.iter().map(|e| betas[*e]).product();
200 let term = (0..num_vars)
201 .map(|var| (var, term.iter().filter(|e| **e == var).count()))
202 .collect();
203 (value, P::Term::new(term))
204 })
205 .collect::<Vec<_>>()
206 })
207 .unzip();
208
209 let g_time = start_timer!(|| "Generating powers of G");
210 let mut powers_of_g = g.batch_mul(&powers_of_beta);
211 powers_of_g.push(g.into_affine());
212 powers_of_beta_terms.push(P::Term::new(vec![]));
213 end_timer!(g_time);
214
215 let gamma_g_time = start_timer!(|| "Generating powers of gamma * G");
216 let mut powers_of_gamma_g = vec![Vec::new(); num_vars];
220 let gamma_g_table = BatchMulPreprocessing::new(gamma_g, max_degree + 1);
221
222 ark_std::cfg_iter_mut!(powers_of_gamma_g)
223 .enumerate()
224 .for_each(|(i, v)| {
225 let mut powers_of_beta = Vec::with_capacity(max_degree + 1);
226 let mut cur = E::ScalarField::one();
227 for _ in 0..=max_degree {
228 cur *= &betas[i];
229 powers_of_beta.push(cur);
230 }
231 *v = gamma_g_table.batch_mul(&powers_of_beta);
232 });
233 end_timer!(gamma_g_time);
234
235 let gamma_g = gamma_g.into_affine();
236 let beta_h: Vec<_> = betas.iter().map(|b| h.mul(b).into_affine()).collect();
237 let h = h.into_affine();
238 let prepared_h = h.into();
239 let prepared_beta_h = beta_h.iter().map(|bh| (*bh).into()).collect();
240
241 let powers_of_g = powers_of_beta_terms
243 .into_iter()
244 .zip(powers_of_g.into_iter())
245 .collect();
246
247 let pp = UniversalParams {
248 num_vars,
249 max_degree,
250 powers_of_g,
251 gamma_g,
252 powers_of_gamma_g,
253 h,
254 beta_h,
255 prepared_h,
256 prepared_beta_h,
257 };
258 end_timer!(setup_time);
259 Ok(pp)
260 }
261
262 fn trim(
267 pp: &Self::UniversalParams,
268 supported_degree: usize,
269 _supported_hiding_bound: usize,
270 _enforced_degree_bounds: Option<&[usize]>,
271 ) -> Result<(Self::CommitterKey, Self::VerifierKey), Self::Error> {
272 let max_degree = pp.max_degree();
273 if supported_degree > max_degree {
274 return Err(Error::TrimmingDegreeTooLarge);
275 }
276
277 let ck_time = start_timer!(|| format!(
278 "Constructing CommitterKey of size {} for unshifted polys",
279 supported_degree
280 ));
281 let powers_of_g = pp
284 .powers_of_g
285 .iter()
286 .filter(|(k, _)| k.degree() <= supported_degree)
287 .map(|(k, v)| (k.clone(), v.clone()))
288 .collect();
289 let powers_of_gamma_g = pp
290 .powers_of_gamma_g
291 .iter()
292 .map(|e| e[..=supported_degree].to_vec())
293 .collect();
294 end_timer!(ck_time);
295
296 let ck = CommitterKey {
297 powers_of_g,
298 gamma_g: pp.gamma_g,
299 powers_of_gamma_g,
300 num_vars: pp.num_vars,
301 supported_degree,
302 max_degree,
303 };
304
305 let vk = VerifierKey {
306 g: pp.powers_of_g[&P::Term::new(vec![])],
307 gamma_g: pp.gamma_g,
308 h: pp.h,
309 beta_h: pp.beta_h.clone(),
310 prepared_h: pp.prepared_h.clone(),
311 prepared_beta_h: pp.prepared_beta_h.clone(),
312 num_vars: pp.num_vars,
313 supported_degree,
314 max_degree,
315 };
316 Ok((ck, vk))
317 }
318
319 fn commit<'a>(
321 ck: &Self::CommitterKey,
322 polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<E::ScalarField, P>>,
323 rng: Option<&mut dyn RngCore>,
324 ) -> Result<
325 (
326 Vec<LabeledCommitment<Self::Commitment>>,
327 Vec<Self::CommitmentState>,
328 ),
329 Self::Error,
330 >
331 where
332 P: 'a,
333 {
334 let rng = &mut crate::optional_rng::OptionalRng(rng);
335 let commit_time = start_timer!(|| "Committing to polynomials");
336 let mut commitments = Vec::new();
337 let mut randomness = Vec::new();
338 for p in polynomials {
339 let label = p.label();
340 let hiding_bound = p.hiding_bound();
341 let polynomial: &P = p.polynomial();
342 Self::check_degrees_and_bounds(ck.supported_degree, &p)?;
343
344 let commit_time = start_timer!(|| {
345 format!(
346 "Polynomial {} with degree {} and hiding bound {:?}",
347 label,
348 polynomial.degree(),
349 hiding_bound,
350 )
351 });
352 let powers_of_g = ark_std::cfg_iter!(polynomial.terms())
354 .map(|(_, term)| *ck.powers_of_g.get(term).unwrap())
355 .collect::<Vec<_>>();
356 let to_bigint_time = start_timer!(|| "Converting polynomial coeffs to bigints");
358 let plain_ints = Self::convert_to_bigints(&polynomial);
359 end_timer!(to_bigint_time);
360
361 let msm_time = start_timer!(|| "MSM to compute commitment to plaintext poly");
362 let mut commitment = <E::G1 as VariableBaseMSM>::msm_bigint(&powers_of_g, &plain_ints);
363 end_timer!(msm_time);
364
365 let mut rand = Randomness::<E, P>::empty();
367 if let Some(hiding_degree) = hiding_bound {
368 let sample_random_poly_time = start_timer!(|| format!(
369 "Sampling a random polynomial of degree {}",
370 hiding_degree
371 ));
372 rand = Randomness::rand(hiding_degree, false, Some(ck.num_vars), rng);
373 Self::check_hiding_bound(hiding_degree, ck.supported_degree + 1)?;
374 end_timer!(sample_random_poly_time);
375 }
376
377 let powers_of_gamma_g = rand
379 .blinding_polynomial
380 .terms()
381 .iter()
382 .map(|(_, term)| {
383 let vars = term.vars();
385 match term.is_constant() {
386 true => ck.gamma_g,
387 false => ck.powers_of_gamma_g[vars[0]][term.degree() - 1],
388 }
389 })
390 .collect::<Vec<_>>();
391 let to_bigint_time = start_timer!(|| "Converting polynomial coeffs to bigints");
393 let random_ints = Self::convert_to_bigints(&rand.blinding_polynomial);
394 end_timer!(to_bigint_time);
395
396 let msm_time = start_timer!(|| "MSM to compute commitment to random poly");
397 let random_commitment =
398 <E::G1 as VariableBaseMSM>::msm_bigint(&powers_of_gamma_g, &random_ints)
399 .into_affine();
400 end_timer!(msm_time);
401
402 commitment += &random_commitment;
404
405 let comm = Self::Commitment {
406 comm: kzg10::Commitment(commitment.into()),
407 shifted_comm: None,
408 };
409
410 commitments.push(LabeledCommitment::new(label.to_string(), comm, None));
411 randomness.push(rand);
412 end_timer!(commit_time);
413 }
414 end_timer!(commit_time);
415 Ok((commitments, randomness))
416 }
417
418 fn open<'a>(
420 ck: &Self::CommitterKey,
421 labeled_polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<E::ScalarField, P>>,
422 _commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
423 point: &P::Point,
424 sponge: &mut impl CryptographicSponge,
425 states: impl IntoIterator<Item = &'a Self::CommitmentState>,
426 _rng: Option<&mut dyn RngCore>,
427 ) -> Result<Self::Proof, Self::Error>
428 where
429 P: 'a,
430 Self::CommitmentState: 'a,
431 Self::Commitment: 'a,
432 {
433 let mut p = P::zero();
435 let mut r = Randomness::empty();
436 for (polynomial, state) in labeled_polynomials.into_iter().zip(states) {
437 Self::check_degrees_and_bounds(ck.supported_degree, &polynomial)?;
438
439 let challenge_j = sponge.squeeze_field_elements_with_sizes(&[CHALLENGE_SIZE])[0];
441
442 p += (challenge_j, polynomial.polynomial());
443 r += (challenge_j, state);
444 }
445
446 let open_time = start_timer!(|| format!("Opening polynomial of degree {}", p.degree()));
447 let witness_time = start_timer!(|| "Computing witness polynomials");
448 let witnesses = Self::divide_at_point(&p, point);
449 let hiding_witnesses = if r.is_hiding() {
450 Some(Self::divide_at_point(&r.blinding_polynomial, point))
451 } else {
452 None
453 };
454 end_timer!(witness_time);
455
456 let witness_comm_time = start_timer!(|| "Computing commitment to witness polynomials");
457 let mut w = witnesses
458 .iter()
459 .map(|w| {
460 let powers_of_g = ark_std::cfg_iter!(w.terms())
462 .map(|(_, term)| *ck.powers_of_g.get(term).unwrap())
463 .collect::<Vec<_>>();
464 let witness_ints = Self::convert_to_bigints(&w);
466 <E::G1 as VariableBaseMSM>::msm_bigint(&powers_of_g, &witness_ints)
468 })
469 .collect::<Vec<_>>();
470 end_timer!(witness_comm_time);
471
472 let random_v = if let Some(hiding_witnesses) = hiding_witnesses {
475 let witness_comm_time =
476 start_timer!(|| "Computing commitment to hiding witness polynomials");
477 ark_std::cfg_iter_mut!(w)
478 .enumerate()
479 .for_each(|(i, witness)| {
480 let hiding_witness = &hiding_witnesses[i];
481 let powers_of_gamma_g = hiding_witness
483 .terms()
484 .iter()
485 .map(|(_, term)| {
486 let vars = term.vars();
488 match term.is_constant() {
489 true => ck.gamma_g,
490 false => ck.powers_of_gamma_g[vars[0]][term.degree() - 1],
491 }
492 })
493 .collect::<Vec<_>>();
494 let hiding_witness_ints = Self::convert_to_bigints(hiding_witness);
496 *witness += &<E::G1 as VariableBaseMSM>::msm_bigint(
498 &powers_of_gamma_g,
499 &hiding_witness_ints,
500 );
501 });
502 end_timer!(witness_comm_time);
503 Some(r.blinding_polynomial.evaluate(point))
504 } else {
505 None
506 };
507 end_timer!(open_time);
508 Ok(Proof {
509 w: w.into_iter().map(|w| w.into_affine()).collect(),
510 random_v,
511 })
512 }
513
514 fn check<'a>(
517 vk: &Self::VerifierKey,
518 commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
519 point: &'a P::Point,
520 values: impl IntoIterator<Item = E::ScalarField>,
521 proof: &Self::Proof,
522 sponge: &mut impl CryptographicSponge,
523 _rng: Option<&mut dyn RngCore>,
524 ) -> Result<bool, Self::Error>
525 where
526 Self::Commitment: 'a,
527 {
528 let check_time = start_timer!(|| "Checking evaluations");
529 let (combined_comm, combined_value) =
531 Marlin::<E, P, Self>::accumulate_commitments_and_values(
532 commitments,
533 values,
534 sponge,
535 None,
536 )?;
537 let mut inner = combined_comm.into().into_group() - &vk.g.mul(combined_value);
539 if let Some(random_v) = proof.random_v {
540 inner -= &vk.gamma_g.mul(random_v);
541 }
542 let lhs = E::pairing(inner, vk.h);
543
544 let (rhs_product_g1, rhs_product_g2): (Vec<E::G1Prepared>, Vec<E::G2Prepared>) =
546 ark_std::cfg_iter!(proof.w)
547 .enumerate()
548 .map(|(j, w_j)| {
549 let beta_minus_z: E::G2Affine =
550 (vk.beta_h[j].into_group() - &vk.h.mul(point[j])).into();
551 ((*w_j).into(), beta_minus_z.into())
552 })
553 .unzip();
554 let rhs = E::multi_pairing(rhs_product_g1, rhs_product_g2);
555 end_timer!(check_time);
556
557 Ok(lhs == rhs)
558 }
559
560 fn batch_check<'a, R: RngCore>(
561 vk: &Self::VerifierKey,
562 commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
563 query_set: &QuerySet<P::Point>,
564 values: &Evaluations<P::Point, E::ScalarField>,
565 proof: &Self::BatchProof,
566 sponge: &mut impl CryptographicSponge,
567 rng: &mut R,
568 ) -> Result<bool, Self::Error>
569 where
570 Self::Commitment: 'a,
571 {
572 let (combined_comms, combined_queries, combined_evals) =
573 Marlin::<E, P, Self>::combine_and_normalize(
574 commitments,
575 query_set,
576 values,
577 sponge,
578 None,
579 )?;
580 let check_time =
581 start_timer!(|| format!("Checking {} evaluation proofs", combined_comms.len()));
582 let g = vk.g.into_group();
583 let gamma_g = vk.gamma_g.into_group();
584 let mut total_c = <E::G1>::zero();
585 let mut total_w = vec![<E::G1>::zero(); vk.num_vars];
586 let combination_time = start_timer!(|| "Combining commitments and proofs");
587 let mut randomizer = E::ScalarField::one();
588 let mut g_multiplier = E::ScalarField::zero();
591 let mut gamma_g_multiplier = E::ScalarField::zero();
592 for (((c, z), v), proof) in combined_comms
593 .iter()
594 .zip(combined_queries)
595 .zip(combined_evals)
596 .zip(proof)
597 {
598 let w = &proof.w;
599 let mut temp: E::G1 = ark_std::cfg_iter!(w)
600 .enumerate()
601 .map(|(j, w_j)| w_j.mul(z[j]))
602 .sum();
603 temp += &c.0;
604 let c = temp;
605 g_multiplier += &(randomizer * &v);
606 if let Some(random_v) = proof.random_v {
607 gamma_g_multiplier += &(randomizer * &random_v);
608 }
609 total_c += &c.mul(&randomizer);
610 ark_std::cfg_iter_mut!(total_w)
611 .enumerate()
612 .for_each(|(i, w_i)| *w_i += &w[i].mul(randomizer));
613 randomizer = u128::rand(rng).into();
616 }
617 total_c -= &g.mul(&g_multiplier);
618 total_c -= &gamma_g.mul(&gamma_g_multiplier);
619 end_timer!(combination_time);
620
621 let to_affine_time = start_timer!(|| "Converting results to affine for pairing");
622 let (mut p1, mut p2): (Vec<E::G1Prepared>, Vec<E::G2Prepared>) = total_w
623 .into_iter()
624 .enumerate()
625 .map(|(j, w_j)| ((-w_j).into_affine().into(), vk.prepared_beta_h[j].clone()))
626 .unzip();
627 p1.push(total_c.into_affine().into());
628 p2.push(vk.prepared_h.clone());
629 end_timer!(to_affine_time);
630
631 let pairing_time = start_timer!(|| "Performing product of pairings");
632 let result = E::multi_pairing(p1, p2).0.is_one();
633 end_timer!(pairing_time);
634 end_timer!(check_time);
635 Ok(result)
636 }
637
638 fn open_combinations<'a>(
639 ck: &Self::CommitterKey,
640 linear_combinations: impl IntoIterator<Item = &'a LinearCombination<E::ScalarField>>,
641 polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<E::ScalarField, P>>,
642 commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
643 query_set: &QuerySet<P::Point>,
644 sponge: &mut impl CryptographicSponge,
645 states: impl IntoIterator<Item = &'a Self::CommitmentState>,
646 rng: Option<&mut dyn RngCore>,
647 ) -> Result<BatchLCProof<E::ScalarField, Self::BatchProof>, Self::Error>
648 where
649 P: 'a,
650 Self::CommitmentState: 'a,
651 Self::Commitment: 'a,
652 {
653 Marlin::<E, P, Self>::open_combinations(
654 ck,
655 linear_combinations,
656 polynomials,
657 commitments,
658 query_set,
659 sponge,
660 states,
661 rng,
662 )
663 }
664
665 fn check_combinations<'a, R: RngCore>(
668 vk: &Self::VerifierKey,
669 linear_combinations: impl IntoIterator<Item = &'a LinearCombination<E::ScalarField>>,
670 commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
671 eqn_query_set: &QuerySet<P::Point>,
672 eqn_evaluations: &Evaluations<P::Point, E::ScalarField>,
673 proof: &BatchLCProof<E::ScalarField, Self::BatchProof>,
674 sponge: &mut impl CryptographicSponge,
675 rng: &mut R,
676 ) -> Result<bool, Self::Error>
677 where
678 Self::Commitment: 'a,
679 {
680 Marlin::<E, P, Self>::check_combinations(
681 vk,
682 linear_combinations,
683 commitments,
684 eqn_query_set,
685 eqn_evaluations,
686 proof,
687 sponge,
688 rng,
689 )
690 }
691}
692
693#[cfg(test)]
694mod tests {
695 #![allow(non_camel_case_types)]
696 use super::MarlinPST13;
697 use ark_bls12_377::Bls12_377;
698 use ark_bls12_381::Bls12_381;
699 use ark_ec::pairing::Pairing;
700 use ark_ff::UniformRand;
701 use ark_poly::{
702 multivariate::{SparsePolynomial as SparsePoly, SparseTerm},
703 DenseMVPolynomial,
704 };
705 #[cfg(not(feature = "std"))]
706 use ark_std::vec::Vec;
707 use rand_chacha::ChaCha20Rng;
708
709 type MVPoly_381 = SparsePoly<<Bls12_381 as Pairing>::ScalarField, SparseTerm>;
710 type MVPoly_377 = SparsePoly<<Bls12_377 as Pairing>::ScalarField, SparseTerm>;
711
712 type PC<E, P> = MarlinPST13<E, P>;
713
714 type PC_Bls12_381 = PC<Bls12_381, MVPoly_381>;
715 type PC_Bls12_377 = PC<Bls12_377, MVPoly_377>;
716
717 fn rand_poly<E: Pairing>(
718 degree: usize,
719 num_vars: Option<usize>,
720 rng: &mut ChaCha20Rng,
721 ) -> SparsePoly<E::ScalarField, SparseTerm> {
722 SparsePoly::<E::ScalarField, SparseTerm>::rand(degree, num_vars.unwrap(), rng)
723 }
724
725 fn rand_point<E: Pairing>(
726 num_vars: Option<usize>,
727 rng: &mut ChaCha20Rng,
728 ) -> Vec<E::ScalarField> {
729 let num_vars = num_vars.unwrap();
730 let mut point = Vec::with_capacity(num_vars);
731 for _ in 0..num_vars {
732 point.push(E::ScalarField::rand(rng));
733 }
734 point
735 }
736
737 #[test]
738 fn single_poly_test() {
739 use crate::tests::*;
740 let num_vars = Some(10);
741 single_poly_test::<_, _, PC_Bls12_377, _>(
742 num_vars,
743 rand_poly::<Bls12_377>,
744 rand_point::<Bls12_377>,
745 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
746 )
747 .expect("test failed for bls12-377");
748 single_poly_test::<_, _, PC_Bls12_381, _>(
749 num_vars,
750 rand_poly::<Bls12_381>,
751 rand_point::<Bls12_381>,
752 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
753 )
754 .expect("test failed for bls12-381");
755 }
756
757 #[test]
758 fn full_end_to_end_test() {
759 use crate::tests::*;
760 let num_vars = Some(10);
761 full_end_to_end_test::<_, _, PC_Bls12_377, _>(
762 num_vars,
763 rand_poly::<Bls12_377>,
764 rand_point::<Bls12_377>,
765 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
766 )
767 .expect("test failed for bls12-377");
768 println!("Finished bls12-377");
769 full_end_to_end_test::<_, _, PC_Bls12_381, _>(
770 num_vars,
771 rand_poly::<Bls12_381>,
772 rand_point::<Bls12_381>,
773 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
774 )
775 .expect("test failed for bls12-381");
776 println!("Finished bls12-381");
777 }
778
779 #[test]
780 fn single_equation_test() {
781 use crate::tests::*;
782 let num_vars = Some(10);
783 single_equation_test::<_, _, PC_Bls12_377, _>(
784 num_vars,
785 rand_poly::<Bls12_377>,
786 rand_point::<Bls12_377>,
787 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
788 )
789 .expect("test failed for bls12-377");
790 println!("Finished bls12-377");
791 single_equation_test::<_, _, PC_Bls12_381, _>(
792 num_vars,
793 rand_poly::<Bls12_381>,
794 rand_point::<Bls12_381>,
795 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
796 )
797 .expect("test failed for bls12-381");
798 println!("Finished bls12-381");
799 }
800
801 #[test]
802 fn two_equation_test() {
803 use crate::tests::*;
804 let num_vars = Some(10);
805 two_equation_test::<_, _, PC_Bls12_377, _>(
806 num_vars,
807 rand_poly::<Bls12_377>,
808 rand_point::<Bls12_377>,
809 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
810 )
811 .expect("test failed for bls12-377");
812 println!("Finished bls12-377");
813 two_equation_test::<_, _, PC_Bls12_381, _>(
814 num_vars,
815 rand_poly::<Bls12_381>,
816 rand_point::<Bls12_381>,
817 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
818 )
819 .expect("test failed for bls12-381");
820 println!("Finished bls12-381");
821 }
822
823 #[test]
824 fn full_end_to_end_equation_test() {
825 use crate::tests::*;
826 let num_vars = Some(10);
827 full_end_to_end_equation_test::<_, _, PC_Bls12_377, _>(
828 num_vars,
829 rand_poly::<Bls12_377>,
830 rand_point::<Bls12_377>,
831 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
832 )
833 .expect("test failed for bls12-377");
834 println!("Finished bls12-377");
835 full_end_to_end_equation_test::<_, _, PC_Bls12_381, _>(
836 num_vars,
837 rand_poly::<Bls12_381>,
838 rand_point::<Bls12_381>,
839 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
840 )
841 .expect("test failed for bls12-381");
842 println!("Finished bls12-381");
843 }
844}