1use crate::{
2 kzg10, BTreeMap, BTreeSet, BatchLCProof, DenseUVPolynomial, Error, Evaluations,
3 LabeledCommitment, LabeledPolynomial, LinearCombination, PCCommitmentState, PCCommitterKey,
4 PCUniversalParams, PolynomialCommitment, QuerySet, CHALLENGE_SIZE,
5};
6use ark_crypto_primitives::sponge::CryptographicSponge;
7use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup};
8use ark_ff::{One, UniformRand, Zero};
9use ark_std::{convert::TryInto, marker::PhantomData, ops::Div, ops::Mul, rand::RngCore};
10#[cfg(not(feature = "std"))]
11use ark_std::{
12 string::{String, ToString},
13 vec::Vec,
14};
15
16mod data_structures;
17pub use data_structures::*;
18
19pub struct SonicKZG10<E: Pairing, P: DenseUVPolynomial<E::ScalarField>> {
30 _engine: PhantomData<E>,
31 _poly: PhantomData<P>,
32}
33
34impl<E, P> SonicKZG10<E, P>
35where
36 E: Pairing,
37 P: DenseUVPolynomial<E::ScalarField>,
38{
39 fn accumulate_elems<'a>(
40 combined_comms: &mut BTreeMap<Option<usize>, E::G1>,
41 combined_witness: &mut E::G1,
42 combined_adjusted_witness: &mut E::G1,
43 vk: &VerifierKey<E>,
44 commitments: impl IntoIterator<Item = &'a LabeledCommitment<Commitment<E>>>,
45 point: P::Point,
46 values: impl IntoIterator<Item = E::ScalarField>,
47 proof: &kzg10::Proof<E>,
48 sponge: &mut impl CryptographicSponge,
49 randomizer: Option<E::ScalarField>,
50 ) {
51 let acc_time = start_timer!(|| "Accumulating elements");
52
53 let mut curr_challenge = sponge.squeeze_field_elements_with_sizes(&[CHALLENGE_SIZE])[0];
54
55 let mut combined_values = E::ScalarField::zero();
57
58 for (labeled_comm, value) in commitments.into_iter().zip(values) {
60 combined_values += &(value * &curr_challenge);
61
62 let comm = labeled_comm.commitment();
63 let degree_bound = labeled_comm.degree_bound();
64
65 let mut comm_with_challenge: E::G1 = comm.0.mul(curr_challenge);
67
68 if let Some(randomizer) = randomizer {
69 comm_with_challenge = comm_with_challenge.mul(&randomizer);
70 }
71
72 *combined_comms.entry(degree_bound).or_insert(E::G1::zero()) += &comm_with_challenge;
74 curr_challenge = sponge.squeeze_field_elements_with_sizes(&[CHALLENGE_SIZE])[0];
75 }
76
77 let mut witness: E::G1 = proof.w.into_group();
79 let mut adjusted_witness = vk.g.mul(combined_values) - &proof.w.mul(point);
80 if let Some(random_v) = proof.random_v {
81 adjusted_witness += &vk.gamma_g.mul(random_v);
82 }
83
84 if let Some(randomizer) = randomizer {
85 witness = proof.w.mul(randomizer);
86 adjusted_witness = adjusted_witness.mul(&randomizer);
87 }
88
89 *combined_witness += &witness;
90 *combined_adjusted_witness += &adjusted_witness;
91 end_timer!(acc_time);
92 }
93
94 fn check_elems(
95 combined_comms: BTreeMap<Option<usize>, E::G1>,
96 combined_witness: E::G1,
97 combined_adjusted_witness: E::G1,
98 vk: &VerifierKey<E>,
99 ) -> Result<bool, Error> {
100 let check_time = start_timer!(|| "Checking elems");
101 let mut g1_projective_elems: Vec<E::G1> = Vec::new();
102 let mut g2_prepared_elems: Vec<E::G2Prepared> = Vec::new();
103
104 for (degree_bound, comm) in combined_comms.into_iter() {
105 let shift_power = if let Some(degree_bound) = degree_bound {
106 vk.get_shift_power(degree_bound)
107 .ok_or(Error::UnsupportedDegreeBound(degree_bound))?
108 } else {
109 vk.prepared_h.clone()
110 };
111
112 g1_projective_elems.push(comm);
113 g2_prepared_elems.push(shift_power);
114 }
115
116 g1_projective_elems.push(-combined_adjusted_witness);
117 g2_prepared_elems.push(vk.prepared_h.clone());
118
119 g1_projective_elems.push(-combined_witness);
120 g2_prepared_elems.push(vk.prepared_beta_h.clone());
121
122 let g1_prepared_elems_iter: Vec<E::G1Prepared> =
123 E::G1::normalize_batch(g1_projective_elems.as_slice())
124 .into_iter()
125 .map(|a| a.into())
126 .collect::<Vec<_>>();
127
128 let is_one: bool = E::multi_pairing(g1_prepared_elems_iter, g2_prepared_elems)
129 .0
130 .is_one();
131 end_timer!(check_time);
132 Ok(is_one)
133 }
134}
135
136impl<E, P> PolynomialCommitment<E::ScalarField, P> for SonicKZG10<E, P>
137where
138 E: Pairing,
139 P: DenseUVPolynomial<E::ScalarField, Point = E::ScalarField>,
140 for<'a, 'b> &'a P: Div<&'b P, Output = P>,
141{
142 type UniversalParams = UniversalParams<E>;
143 type CommitterKey = CommitterKey<E>;
144 type VerifierKey = VerifierKey<E>;
145 type Commitment = Commitment<E>;
146 type CommitmentState = Randomness<E::ScalarField, P>;
147 type Proof = kzg10::Proof<E>;
148 type BatchProof = Vec<Self::Proof>;
149 type Error = Error;
150
151 fn setup<R: RngCore>(
152 max_degree: usize,
153 _: Option<usize>,
154 rng: &mut R,
155 ) -> Result<Self::UniversalParams, Self::Error> {
156 kzg10::KZG10::<E, P>::setup(max_degree, true, rng).map_err(Into::into)
157 }
158
159 fn trim(
160 pp: &Self::UniversalParams,
161 supported_degree: usize,
162 supported_hiding_bound: usize,
163 enforced_degree_bounds: Option<&[usize]>,
164 ) -> Result<(Self::CommitterKey, Self::VerifierKey), Self::Error> {
165 let trim_time = start_timer!(|| "Trimming public parameters");
166 let neg_powers_of_h = &pp.neg_powers_of_h;
167 let max_degree = pp.max_degree();
168 if supported_degree > max_degree {
169 return Err(Error::TrimmingDegreeTooLarge);
170 }
171
172 let enforced_degree_bounds = enforced_degree_bounds.map(|bounds| {
173 let mut v = bounds.to_vec();
174 v.sort();
175 v.dedup();
176 v
177 });
178
179 let (shifted_powers_of_g, shifted_powers_of_gamma_g, degree_bounds_and_neg_powers_of_h) =
180 if let Some(enforced_degree_bounds) = enforced_degree_bounds.as_ref() {
181 if enforced_degree_bounds.is_empty() {
182 (None, None, None)
183 } else {
184 let highest_enforced_degree_bound = *enforced_degree_bounds.last().unwrap();
185 if highest_enforced_degree_bound > supported_degree {
186 return Err(Error::UnsupportedDegreeBound(highest_enforced_degree_bound));
187 }
188
189 let lowest_shift_degree = max_degree - highest_enforced_degree_bound;
190
191 let shifted_ck_time = start_timer!(|| format!(
192 "Constructing `shifted_powers` of size {}",
193 max_degree - lowest_shift_degree + 1
194 ));
195
196 let shifted_powers_of_g = pp.powers_of_g[lowest_shift_degree..].to_vec();
197 let mut shifted_powers_of_gamma_g = BTreeMap::new();
198 for degree_bound in enforced_degree_bounds {
200 let shift_degree = max_degree - degree_bound;
201 let mut powers_for_degree_bound = vec![];
202 for i in 0..=(supported_hiding_bound + 1) {
203 if shift_degree + i < max_degree + 2 {
205 powers_for_degree_bound
206 .push(pp.powers_of_gamma_g[&(shift_degree + i)]);
207 }
208 }
209 shifted_powers_of_gamma_g.insert(*degree_bound, powers_for_degree_bound);
210 }
211
212 end_timer!(shifted_ck_time);
213
214 let neg_powers_of_h_time = start_timer!(|| format!(
215 "Constructing `neg_powers_of_h` of size {}",
216 enforced_degree_bounds.len()
217 ));
218
219 let degree_bounds_and_neg_powers_of_h = enforced_degree_bounds
220 .iter()
221 .map(|bound| (*bound, neg_powers_of_h[&(max_degree - *bound)].clone()))
222 .collect();
223
224 end_timer!(neg_powers_of_h_time);
225
226 (
227 Some(shifted_powers_of_g),
228 Some(shifted_powers_of_gamma_g),
229 Some(degree_bounds_and_neg_powers_of_h),
230 )
231 }
232 } else {
233 (None, None, None)
234 };
235
236 let powers_of_g = pp.powers_of_g[..=supported_degree].to_vec();
237 let powers_of_gamma_g = (0..=(supported_hiding_bound + 1))
238 .map(|i| pp.powers_of_gamma_g[&i])
239 .collect();
240
241 let ck = CommitterKey {
242 powers_of_g,
243 powers_of_gamma_g,
244 shifted_powers_of_g,
245 shifted_powers_of_gamma_g,
246 enforced_degree_bounds,
247 max_degree,
248 };
249
250 let g = pp.powers_of_g[0];
251 let h = pp.h;
252 let beta_h = pp.beta_h;
253 let gamma_g = pp.powers_of_gamma_g[&0];
254 let prepared_h = (&pp.prepared_h).clone();
255 let prepared_beta_h = (&pp.prepared_beta_h).clone();
256
257 let vk = VerifierKey {
258 g,
259 gamma_g,
260 h,
261 beta_h,
262 prepared_h,
263 prepared_beta_h,
264 degree_bounds_and_neg_powers_of_h,
265 supported_degree,
266 max_degree,
267 };
268
269 end_timer!(trim_time);
270 Ok((ck, vk))
271 }
272
273 fn commit<'a>(
275 ck: &Self::CommitterKey,
276 polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<E::ScalarField, P>>,
277 rng: Option<&mut dyn RngCore>,
278 ) -> Result<
279 (
280 Vec<LabeledCommitment<Self::Commitment>>,
281 Vec<Self::CommitmentState>,
282 ),
283 Self::Error,
284 >
285 where
286 P: 'a,
287 {
288 let rng = &mut crate::optional_rng::OptionalRng(rng);
289 let commit_time = start_timer!(|| "Committing to polynomials");
290 let mut labeled_comms: Vec<LabeledCommitment<Self::Commitment>> = Vec::new();
291 let mut randomness: Vec<Self::CommitmentState> = Vec::new();
292
293 for labeled_polynomial in polynomials {
294 let enforced_degree_bounds: Option<&[usize]> = ck
295 .enforced_degree_bounds
296 .as_ref()
297 .map(|bounds| bounds.as_slice());
298
299 kzg10::KZG10::<E, P>::check_degrees_and_bounds(
300 ck.supported_degree(),
301 ck.max_degree,
302 enforced_degree_bounds,
303 &labeled_polynomial,
304 )?;
305
306 let polynomial: &P = labeled_polynomial.polynomial();
307 let degree_bound = labeled_polynomial.degree_bound();
308 let hiding_bound = labeled_polynomial.hiding_bound();
309 let label = labeled_polynomial.label();
310
311 let commit_time = start_timer!(|| format!(
312 "Polynomial {} of degree {}, degree bound {:?}, and hiding bound {:?}",
313 label,
314 polynomial.degree(),
315 degree_bound,
316 hiding_bound,
317 ));
318
319 let powers = if let Some(degree_bound) = degree_bound {
320 ck.shifted_powers(degree_bound).unwrap()
321 } else {
322 ck.powers()
323 };
324
325 let (comm, rand) = kzg10::KZG10::commit(&powers, polynomial, hiding_bound, Some(rng))?;
326
327 labeled_comms.push(LabeledCommitment::new(
328 label.to_string(),
329 comm,
330 degree_bound,
331 ));
332 randomness.push(rand);
333 end_timer!(commit_time);
334 }
335
336 end_timer!(commit_time);
337 Ok((labeled_comms, randomness))
338 }
339
340 fn open<'a>(
341 ck: &Self::CommitterKey,
342 labeled_polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<E::ScalarField, P>>,
343 _commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
344 point: &'a P::Point,
345 sponge: &mut impl CryptographicSponge,
346 states: impl IntoIterator<Item = &'a Self::CommitmentState>,
347 _rng: Option<&mut dyn RngCore>,
348 ) -> Result<Self::Proof, Self::Error>
349 where
350 Self::CommitmentState: 'a,
351 Self::Commitment: 'a,
352 P: 'a,
353 {
354 let mut combined_polynomial = P::zero();
355 let mut combined_rand = kzg10::Randomness::empty();
356
357 let mut curr_challenge = sponge.squeeze_field_elements_with_sizes(&[CHALLENGE_SIZE])[0];
358
359 for (polynomial, state) in labeled_polynomials.into_iter().zip(states) {
360 let enforced_degree_bounds: Option<&[usize]> = ck
361 .enforced_degree_bounds
362 .as_ref()
363 .map(|bounds| bounds.as_slice());
364
365 kzg10::KZG10::<E, P>::check_degrees_and_bounds(
366 ck.supported_degree(),
367 ck.max_degree,
368 enforced_degree_bounds,
369 &polynomial,
370 )?;
371
372 combined_polynomial += (curr_challenge, polynomial.polynomial());
373 combined_rand += (curr_challenge, state);
374 curr_challenge = sponge.squeeze_field_elements_with_sizes(&[CHALLENGE_SIZE])[0];
375 }
376
377 let proof_time = start_timer!(|| "Creating proof for polynomials");
378 let proof = kzg10::KZG10::open(&ck.powers(), &combined_polynomial, *point, &combined_rand)?;
379 end_timer!(proof_time);
380
381 Ok(proof)
382 }
383
384 fn check<'a>(
385 vk: &Self::VerifierKey,
386 commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
387 point: &'a P::Point,
388 values: impl IntoIterator<Item = E::ScalarField>,
389 proof: &Self::Proof,
390 sponge: &mut impl CryptographicSponge,
391 _rng: Option<&mut dyn RngCore>,
392 ) -> Result<bool, Self::Error>
393 where
394 Self::Commitment: 'a,
395 {
396 let check_time = start_timer!(|| "Checking evaluations");
397 let mut combined_comms: BTreeMap<Option<usize>, E::G1> = BTreeMap::new();
398 let mut combined_witness: E::G1 = E::G1::zero();
399 let mut combined_adjusted_witness: E::G1 = E::G1::zero();
400
401 Self::accumulate_elems(
402 &mut combined_comms,
403 &mut combined_witness,
404 &mut combined_adjusted_witness,
405 vk,
406 commitments,
407 *point,
408 values,
409 proof,
410 sponge,
411 None,
412 );
413
414 let res = Self::check_elems(
415 combined_comms,
416 combined_witness,
417 combined_adjusted_witness,
418 vk,
419 );
420 end_timer!(check_time);
421 res
422 }
423
424 fn batch_check<'a, R: RngCore>(
425 vk: &Self::VerifierKey,
426 commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
427 query_set: &QuerySet<P::Point>,
428 values: &Evaluations<E::ScalarField, P::Point>,
429 proof: &Self::BatchProof,
430 sponge: &mut impl CryptographicSponge,
431 rng: &mut R,
432 ) -> Result<bool, Self::Error>
433 where
434 Self::Commitment: 'a,
435 {
436 let commitments: BTreeMap<_, _> = commitments.into_iter().map(|c| (c.label(), c)).collect();
437 let mut query_to_labels_map = BTreeMap::new();
438
439 for (label, (point_label, point)) in query_set.iter() {
440 let labels = query_to_labels_map
441 .entry(point_label)
442 .or_insert((point, BTreeSet::new()));
443 labels.1.insert(label);
444 }
445
446 assert_eq!(proof.len(), query_to_labels_map.len());
447
448 let mut randomizer = E::ScalarField::one();
449
450 let mut combined_comms: BTreeMap<Option<usize>, E::G1> = BTreeMap::new();
451 let mut combined_witness: E::G1 = E::G1::zero();
452 let mut combined_adjusted_witness: E::G1 = E::G1::zero();
453
454 for ((_point_label, (point, labels)), p) in query_to_labels_map.into_iter().zip(proof) {
455 let mut comms_to_combine: Vec<&'_ LabeledCommitment<_>> = Vec::new();
456 let mut values_to_combine = Vec::new();
457 for label in labels.into_iter() {
458 let commitment = commitments.get(label).ok_or(Error::MissingPolynomial {
459 label: label.to_string(),
460 })?;
461
462 let v_i = values
463 .get(&(label.clone(), *point))
464 .ok_or(Error::MissingEvaluation {
465 label: label.to_string(),
466 })?;
467
468 comms_to_combine.push(commitment);
469 values_to_combine.push(*v_i);
470 }
471
472 Self::accumulate_elems(
473 &mut combined_comms,
474 &mut combined_witness,
475 &mut combined_adjusted_witness,
476 vk,
477 comms_to_combine.into_iter(),
478 *point,
479 values_to_combine.into_iter(),
480 p,
481 sponge,
482 Some(randomizer),
483 );
484
485 randomizer = u128::rand(rng).into();
486 }
487
488 Self::check_elems(
489 combined_comms,
490 combined_witness,
491 combined_adjusted_witness,
492 vk,
493 )
494 }
495
496 fn open_combinations<'a>(
497 ck: &Self::CommitterKey,
498 linear_combinations: impl IntoIterator<Item = &'a LinearCombination<E::ScalarField>>,
499 polynomials: impl IntoIterator<Item = &'a LabeledPolynomial<E::ScalarField, P>>,
500 commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
501 query_set: &QuerySet<P::Point>,
502 sponge: &mut impl CryptographicSponge,
503 states: impl IntoIterator<Item = &'a Self::CommitmentState>,
504 rng: Option<&mut dyn RngCore>,
505 ) -> Result<BatchLCProof<E::ScalarField, Self::BatchProof>, Self::Error>
506 where
507 Self::CommitmentState: 'a,
508 Self::Commitment: 'a,
509 P: 'a,
510 {
511 let label_map = polynomials
512 .into_iter()
513 .zip(states)
514 .zip(commitments)
515 .map(|((p, s), c)| (p.label(), (p, s, c)))
516 .collect::<BTreeMap<_, _>>();
517
518 let mut lc_polynomials = Vec::new();
519 let mut lc_states = Vec::new();
520 let mut lc_commitments = Vec::new();
521 let mut lc_info = Vec::new();
522
523 for lc in linear_combinations {
524 let lc_label = lc.label().clone();
525 let mut poly = P::zero();
526 let mut degree_bound = None;
527 let mut hiding_bound = None;
528 let mut state = Self::CommitmentState::empty();
529 let mut comm = E::G1::zero();
530
531 let num_polys = lc.len();
532 for (coeff, label) in lc.iter().filter(|(_, l)| !l.is_one()) {
533 let label: &String = label.try_into().expect("cannot be one!");
534 let &(cur_poly, cur_state, curr_comm) =
535 label_map.get(label).ok_or(Error::MissingPolynomial {
536 label: label.to_string(),
537 })?;
538
539 if num_polys == 1 && cur_poly.degree_bound().is_some() {
540 assert!(
541 coeff.is_one(),
542 "Coefficient must be one for degree-bounded equations"
543 );
544 degree_bound = cur_poly.degree_bound();
545 } else if cur_poly.degree_bound().is_some() {
546 eprintln!("Degree bound when number of equations is non-zero");
547 return Err(Self::Error::EquationHasDegreeBounds(lc_label));
548 }
549
550 hiding_bound = core::cmp::max(hiding_bound, cur_poly.hiding_bound());
552 poly += (*coeff, cur_poly.polynomial());
553 state += (*coeff, cur_state);
554 comm += &curr_comm.commitment().0.mul(*coeff);
555 }
556
557 let lc_poly =
558 LabeledPolynomial::new(lc_label.clone(), poly, degree_bound, hiding_bound);
559 lc_polynomials.push(lc_poly);
560 lc_states.push(state);
561 lc_commitments.push(comm);
562 lc_info.push((lc_label, degree_bound));
563 }
564
565 let comms: Vec<Self::Commitment> = E::G1::normalize_batch(&lc_commitments)
566 .into_iter()
567 .map(|c| kzg10::Commitment::<E>(c))
568 .collect();
569
570 let lc_commitments = lc_info
571 .into_iter()
572 .zip(comms)
573 .map(|((label, d), c)| LabeledCommitment::new(label, c, d))
574 .collect::<Vec<_>>();
575
576 let proof = Self::batch_open(
577 ck,
578 lc_polynomials.iter(),
579 lc_commitments.iter(),
580 &query_set,
581 sponge,
582 lc_states.iter(),
583 rng,
584 )?;
585 Ok(BatchLCProof { proof, evals: None })
586 }
587
588 fn check_combinations<'a, R: RngCore>(
591 vk: &Self::VerifierKey,
592 linear_combinations: impl IntoIterator<Item = &'a LinearCombination<E::ScalarField>>,
593 commitments: impl IntoIterator<Item = &'a LabeledCommitment<Self::Commitment>>,
594 eqn_query_set: &QuerySet<P::Point>,
595 eqn_evaluations: &Evaluations<P::Point, E::ScalarField>,
596 proof: &BatchLCProof<E::ScalarField, Self::BatchProof>,
597 sponge: &mut impl CryptographicSponge,
598 rng: &mut R,
599 ) -> Result<bool, Self::Error>
600 where
601 Self::Commitment: 'a,
602 {
603 let BatchLCProof { proof, .. } = proof;
604 let label_comm_map = commitments
605 .into_iter()
606 .map(|c| (c.label(), c))
607 .collect::<BTreeMap<_, _>>();
608
609 let mut lc_commitments = Vec::new();
610 let mut lc_info = Vec::new();
611 let mut evaluations = eqn_evaluations.clone();
612 for lc in linear_combinations {
613 let lc_label = lc.label().clone();
614 let num_polys = lc.len();
615
616 let mut degree_bound = None;
617 let mut combined_comm = E::G1::zero();
618
619 for (coeff, label) in lc.iter() {
620 if label.is_one() {
621 for (&(ref label, _), ref mut eval) in evaluations.iter_mut() {
622 if label == &lc_label {
623 **eval -= coeff;
624 }
625 }
626 } else {
627 let label: &String = label.try_into().unwrap();
628 let &cur_comm = label_comm_map.get(label).ok_or(Error::MissingPolynomial {
629 label: label.to_string(),
630 })?;
631
632 if num_polys == 1 && cur_comm.degree_bound().is_some() {
633 assert!(
634 coeff.is_one(),
635 "Coefficient must be one for degree-bounded equations"
636 );
637 degree_bound = cur_comm.degree_bound();
638 } else if cur_comm.degree_bound().is_some() {
639 return Err(Self::Error::EquationHasDegreeBounds(lc_label));
640 }
641 combined_comm += &cur_comm.commitment().0.mul(*coeff);
642 }
643 }
644
645 lc_commitments.push(combined_comm);
646 lc_info.push((lc_label, degree_bound));
647 }
648
649 let comms: Vec<Self::Commitment> = E::G1::normalize_batch(&lc_commitments)
650 .into_iter()
651 .map(|c| kzg10::Commitment(c))
652 .collect();
653
654 let lc_commitments = lc_info
655 .into_iter()
656 .zip(comms)
657 .map(|((label, d), c)| LabeledCommitment::new(label, c, d))
658 .collect::<Vec<_>>();
659
660 Self::batch_check(
661 vk,
662 &lc_commitments,
663 &eqn_query_set,
664 &evaluations,
665 proof,
666 sponge,
667 rng,
668 )
669 }
670}
671
672#[cfg(test)]
673mod tests {
674 #![allow(non_camel_case_types)]
675 use super::SonicKZG10;
676 use ark_bls12_377::Bls12_377;
677 use ark_bls12_381::Bls12_381;
678 use ark_ec::pairing::Pairing;
679 use ark_ff::UniformRand;
680 use ark_poly::{univariate::DensePolynomial as DensePoly, DenseUVPolynomial};
681 use rand_chacha::ChaCha20Rng;
682
683 type UniPoly_381 = DensePoly<<Bls12_381 as Pairing>::ScalarField>;
684 type UniPoly_377 = DensePoly<<Bls12_377 as Pairing>::ScalarField>;
685
686 type PC<E, P> = SonicKZG10<E, P>;
687 type PC_Bls12_377 = PC<Bls12_377, UniPoly_377>;
688 type PC_Bls12_381 = PC<Bls12_381, UniPoly_381>;
689
690 fn rand_poly<E: Pairing>(
691 degree: usize,
692 _: Option<usize>,
693 rng: &mut ChaCha20Rng,
694 ) -> DensePoly<E::ScalarField> {
695 DensePoly::<E::ScalarField>::rand(degree, rng)
696 }
697
698 fn rand_point<E: Pairing>(_: Option<usize>, rng: &mut ChaCha20Rng) -> E::ScalarField {
699 E::ScalarField::rand(rng)
700 }
701
702 #[test]
703 fn single_poly_test() {
704 use crate::tests::*;
705 single_poly_test::<_, _, PC_Bls12_377, _>(
706 None,
707 rand_poly::<Bls12_377>,
708 rand_point::<Bls12_377>,
709 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
710 )
711 .expect("test failed for bls12-377");
712 single_poly_test::<_, _, PC_Bls12_381, _>(
713 None,
714 rand_poly::<Bls12_381>,
715 rand_point::<Bls12_381>,
716 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
717 )
718 .expect("test failed for bls12-381");
719 }
720
721 #[test]
722 fn quadratic_poly_degree_bound_multiple_queries_test() {
723 use crate::tests::*;
724 quadratic_poly_degree_bound_multiple_queries_test::<_, _, PC_Bls12_377, _>(
725 rand_poly::<Bls12_377>,
726 rand_point::<Bls12_377>,
727 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
728 )
729 .expect("test failed for bls12-377");
730 quadratic_poly_degree_bound_multiple_queries_test::<_, _, PC_Bls12_381, _>(
731 rand_poly::<Bls12_381>,
732 rand_point::<Bls12_381>,
733 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
734 )
735 .expect("test failed for bls12-381");
736 }
737
738 #[test]
739 fn linear_poly_degree_bound_test() {
740 use crate::tests::*;
741 linear_poly_degree_bound_test::<_, _, PC_Bls12_377, _>(
742 rand_poly::<Bls12_377>,
743 rand_point::<Bls12_377>,
744 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
745 )
746 .expect("test failed for bls12-377");
747 linear_poly_degree_bound_test::<_, _, PC_Bls12_381, _>(
748 rand_poly::<Bls12_381>,
749 rand_point::<Bls12_381>,
750 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
751 )
752 .expect("test failed for bls12-381");
753 }
754
755 #[test]
756 fn single_poly_degree_bound_test() {
757 use crate::tests::*;
758 single_poly_degree_bound_test::<_, _, PC_Bls12_377, _>(
759 rand_poly::<Bls12_377>,
760 rand_point::<Bls12_377>,
761 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
762 )
763 .expect("test failed for bls12-377");
764 single_poly_degree_bound_test::<_, _, PC_Bls12_381, _>(
765 rand_poly::<Bls12_381>,
766 rand_point::<Bls12_381>,
767 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
768 )
769 .expect("test failed for bls12-381");
770 }
771
772 #[test]
773 fn single_poly_degree_bound_multiple_queries_test() {
774 use crate::tests::*;
775 single_poly_degree_bound_multiple_queries_test::<_, _, PC_Bls12_377, _>(
776 rand_poly::<Bls12_377>,
777 rand_point::<Bls12_377>,
778 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
779 )
780 .expect("test failed for bls12-377");
781 single_poly_degree_bound_multiple_queries_test::<_, _, PC_Bls12_381, _>(
782 rand_poly::<Bls12_381>,
783 rand_point::<Bls12_381>,
784 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
785 )
786 .expect("test failed for bls12-381");
787 }
788
789 #[test]
790 fn two_polys_degree_bound_single_query_test() {
791 use crate::tests::*;
792 two_polys_degree_bound_single_query_test::<_, _, PC_Bls12_377, _>(
793 rand_poly::<Bls12_377>,
794 rand_point::<Bls12_377>,
795 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
796 )
797 .expect("test failed for bls12-377");
798 two_polys_degree_bound_single_query_test::<_, _, PC_Bls12_381, _>(
799 rand_poly::<Bls12_381>,
800 rand_point::<Bls12_381>,
801 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
802 )
803 .expect("test failed for bls12-381");
804 }
805
806 #[test]
807 fn full_end_to_end_test() {
808 use crate::tests::*;
809 full_end_to_end_test::<_, _, PC_Bls12_377, _>(
810 None,
811 rand_poly::<Bls12_377>,
812 rand_point::<Bls12_377>,
813 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
814 )
815 .expect("test failed for bls12-377");
816 println!("Finished bls12-377");
817 full_end_to_end_test::<_, _, PC_Bls12_381, _>(
818 None,
819 rand_poly::<Bls12_381>,
820 rand_point::<Bls12_381>,
821 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
822 )
823 .expect("test failed for bls12-381");
824 println!("Finished bls12-381");
825 }
826
827 #[test]
828 fn single_equation_test() {
829 use crate::tests::*;
830 single_equation_test::<_, _, PC_Bls12_377, _>(
831 None,
832 rand_poly::<Bls12_377>,
833 rand_point::<Bls12_377>,
834 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
835 )
836 .expect("test failed for bls12-377");
837 println!("Finished bls12-377");
838 single_equation_test::<_, _, PC_Bls12_381, _>(
839 None,
840 rand_poly::<Bls12_381>,
841 rand_point::<Bls12_381>,
842 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
843 )
844 .expect("test failed for bls12-381");
845 println!("Finished bls12-381");
846 }
847
848 #[test]
849 fn two_equation_test() {
850 use crate::tests::*;
851 two_equation_test::<_, _, PC_Bls12_377, _>(
852 None,
853 rand_poly::<Bls12_377>,
854 rand_point::<Bls12_377>,
855 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
856 )
857 .expect("test failed for bls12-377");
858 println!("Finished bls12-377");
859 two_equation_test::<_, _, PC_Bls12_381, _>(
860 None,
861 rand_poly::<Bls12_381>,
862 rand_point::<Bls12_381>,
863 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
864 )
865 .expect("test failed for bls12-381");
866 println!("Finished bls12-381");
867 }
868
869 #[test]
870 fn two_equation_degree_bound_test() {
871 use crate::tests::*;
872 two_equation_degree_bound_test::<_, _, PC_Bls12_377, _>(
873 rand_poly::<Bls12_377>,
874 rand_point::<Bls12_377>,
875 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
876 )
877 .expect("test failed for bls12-377");
878 println!("Finished bls12-377");
879 two_equation_degree_bound_test::<_, _, PC_Bls12_381, _>(
880 rand_poly::<Bls12_381>,
881 rand_point::<Bls12_381>,
882 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
883 )
884 .expect("test failed for bls12-381");
885 println!("Finished bls12-381");
886 }
887
888 #[test]
889 fn full_end_to_end_equation_test() {
890 use crate::tests::*;
891 full_end_to_end_equation_test::<_, _, PC_Bls12_377, _>(
892 None,
893 rand_poly::<Bls12_377>,
894 rand_point::<Bls12_377>,
895 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
896 )
897 .expect("test failed for bls12-377");
898 println!("Finished bls12-377");
899 full_end_to_end_equation_test::<_, _, PC_Bls12_381, _>(
900 None,
901 rand_poly::<Bls12_381>,
902 rand_point::<Bls12_381>,
903 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
904 )
905 .expect("test failed for bls12-381");
906 println!("Finished bls12-381");
907 }
908
909 #[test]
910 #[should_panic]
911 fn bad_degree_bound_test() {
912 use crate::tests::*;
913 bad_degree_bound_test::<_, _, PC_Bls12_377, _>(
914 rand_poly::<Bls12_377>,
915 rand_point::<Bls12_377>,
916 poseidon_sponge_for_test::<<Bls12_377 as Pairing>::ScalarField>,
917 )
918 .expect("test failed for bls12-377");
919 println!("Finished bls12-377");
920 bad_degree_bound_test::<_, _, PC_Bls12_381, _>(
921 rand_poly::<Bls12_381>,
922 rand_point::<Bls12_381>,
923 poseidon_sponge_for_test::<<Bls12_381 as Pairing>::ScalarField>,
924 )
925 .expect("test failed for bls12-381");
926 println!("Finished bls12-381");
927 }
928}