From 2d6340688c5e30b62d449b67231ab51ce114eb69 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 22 Oct 2020 10:31:21 -0700 Subject: [PATCH 01/56] prepared vk/commitment types, and individual opening challenges --- src/data_structures.rs | 4 +- src/kzg10/data_structures.rs | 2 +- src/lib.rs | 161 ++++++++++++++------------- src/marlin_pc/data_structures.rs | 7 +- src/marlin_pc/mod.rs | 182 +++++++++++++++++++++++++++++-- 5 files changed, 265 insertions(+), 91 deletions(-) diff --git a/src/data_structures.rs b/src/data_structures.rs index 2e8e4fdb..2dc0cdfd 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -39,9 +39,9 @@ pub trait PCVerifierKey: Clone + core::fmt::Debug { /// Defines the minimal interface of prepared verifier keys for any polynomial /// commitment scheme. -pub trait PCPreparedVerifierKey { +pub trait PCPreparedVerifierKey { /// prepare - fn prepare(vk: &Unprepared) -> Self; + fn prepare(vk: &UNPREPARED) -> Self; } /// Defines the minimal interface of commitments for any polynomial diff --git a/src/kzg10/data_structures.rs b/src/kzg10/data_structures.rs index 62eb2dff..2da865c0 100644 --- a/src/kzg10/data_structures.rs +++ b/src/kzg10/data_structures.rs @@ -92,7 +92,7 @@ impl ToBytes for VerifierKey { #[derive(Derivative)] #[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))] pub struct PreparedVerifierKey { - /// The generator of G1, prepared for power series. + /// The generator of G1. pub prepared_g: Vec, /// The generator of G2, prepared for use in pairings. pub prepared_h: E::G2Prepared, diff --git a/src/lib.rs b/src/lib.rs index 4be0f24f..dda70569 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,11 +16,24 @@ extern crate derivative; extern crate bench_utils; use ark_ff::Field; -pub use ark_poly::DensePolynomial as Polynomial; use core::iter::FromIterator; +pub use ark_poly::DensePolynomial as Polynomial; use rand_core::RngCore; -use ark_std::{ +#[cfg(not(feature = "std"))] +#[macro_use] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::{ + collections::{BTreeMap, BTreeSet}, + rc::Rc, + string::{String, ToString}, + vec::Vec, +}; + +#[cfg(feature = "std")] +use std::{ collections::{BTreeMap, BTreeSet}, rc::Rc, string::{String, ToString}, @@ -60,6 +73,7 @@ pub mod kzg10; /// /// [kzg]: http://cacr.uwaterloo.ca/techreports/2010/cacr2010-10.pdf /// [marlin]: https://eprint.iacr.org/2019/1047 +// TODO: add "Prepared" to marlin_pc pub mod marlin_pc; /// Polynomial commitment scheme based on the construction in [[KZG10]][kzg], @@ -79,6 +93,7 @@ pub mod sonic_pc; /// The construction is detailed in [[BCMS20]][pcdas]. /// /// [pcdas]: https://eprint.iacr.org/2020/499 +// TODO: add "Prepared" to marlin_pc pub mod ipa_pc; /// `QuerySet` is the set of queries that are to be made to a set of labeled polynomials/equations @@ -115,9 +130,9 @@ pub trait PolynomialCommitment: Sized { /// open the commitment to produce an evaluation proof. type CommitterKey: PCCommitterKey; /// The verifier key for the scheme; used to check an evaluation proof. - type VerifierKey: PCVerifierKey; + type VerifierKey: PCVerifierKey + Default; /// The prepared verifier key for the scheme; used to check an evaluation proof. - type PreparedVerifierKey: PCPreparedVerifierKey + Clone; + type PreparedVerifierKey: PCPreparedVerifierKey + Default + Clone; /// The commitment to a polynomial. type Commitment: PCCommitment + Default; /// The prepared commitment to a polynomial. @@ -210,16 +225,64 @@ pub trait PolynomialCommitment: Sized { Self::Randomness: 'a, Self::Commitment: 'a, { - let opening_challenges = |pow| opening_challenge.pow(&[pow]); - Self::batch_open_individual_opening_challenges( - ck, - labeled_polynomials, - commitments, - query_set, - &opening_challenges, - rands, - rng, - ) + let rng = &mut crate::optional_rng::OptionalRng(rng); + let poly_rand_comm: BTreeMap<_, _> = labeled_polynomials + .into_iter() + .zip(rands) + .zip(commitments.into_iter()) + .map(|((poly, r), comm)| (poly.label(), (poly, r, comm))) + .collect(); + + let open_time = start_timer!(|| format!( + "Opening {} polynomials at query set of size {}", + poly_rand_comm.len(), + query_set.len(), + )); + + let mut query_to_labels_map = BTreeMap::new(); + + for (label, (point_label, point)) in query_set.iter() { + let labels = query_to_labels_map + .entry(point_label) + .or_insert((point, BTreeSet::new())); + labels.1.insert(label); + } + + let mut proofs = Vec::new(); + for (_point_label, (point, labels)) in query_to_labels_map.into_iter() { + let mut query_polys: Vec<&'a LabeledPolynomial<_>> = Vec::new(); + let mut query_rands: Vec<&'a Self::Randomness> = Vec::new(); + let mut query_comms: Vec<&'a LabeledCommitment> = Vec::new(); + + for label in labels { + let (polynomial, rand, comm) = + poly_rand_comm.get(label).ok_or(Error::MissingPolynomial { + label: label.to_string(), + })?; + + query_polys.push(polynomial); + query_rands.push(rand); + query_comms.push(comm); + } + + let proof_time = start_timer!(|| "Creating proof"); + let proof = Self::open( + ck, + query_polys, + query_comms, + *point, + opening_challenge, + query_rands, + Some(rng), + )?; + + end_timer!(proof_time); + + proofs.push(proof); + } + end_timer!(open_time); + + Ok(proofs.into()) } /// Verifies that `values` are the evaluations at `point` of the polynomials @@ -528,7 +591,8 @@ pub trait PolynomialCommitment: Sized { Ok(true) } - /// batch_open with individual challenges + /// batch_open but with individual challenges + /// By default, we downgrade them to only use the first individual opening challenges fn batch_open_individual_opening_challenges<'a>( ck: &Self::CommitterKey, labeled_polynomials: impl IntoIterator>, @@ -542,64 +606,15 @@ pub trait PolynomialCommitment: Sized { Self::Randomness: 'a, Self::Commitment: 'a, { - let rng = &mut crate::optional_rng::OptionalRng(rng); - let poly_rand_comm: BTreeMap<_, _> = labeled_polynomials - .into_iter() - .zip(rands) - .zip(commitments.into_iter()) - .map(|((poly, r), comm)| (poly.label(), (poly, r, comm))) - .collect(); - - let open_time = start_timer!(|| format!( - "Opening {} polynomials at query set of size {}", - poly_rand_comm.len(), - query_set.len(), - )); - - let mut query_to_labels_map = BTreeMap::new(); - - for (label, (point_label, point)) in query_set.iter() { - let labels = query_to_labels_map - .entry(point_label) - .or_insert((point, BTreeSet::new())); - labels.1.insert(label); - } - - let mut proofs = Vec::new(); - for (_point_label, (point, labels)) in query_to_labels_map.into_iter() { - let mut query_polys: Vec<&'a LabeledPolynomial<_>> = Vec::new(); - let mut query_rands: Vec<&'a Self::Randomness> = Vec::new(); - let mut query_comms: Vec<&'a LabeledCommitment> = Vec::new(); - - for label in labels { - let (polynomial, rand, comm) = - poly_rand_comm.get(label).ok_or(Error::MissingPolynomial { - label: label.to_string(), - })?; - - query_polys.push(polynomial); - query_rands.push(rand); - query_comms.push(comm); - } - - let proof_time = start_timer!(|| "Creating proof"); - let proof = Self::open_individual_opening_challenges( - ck, - query_polys, - query_comms, - *point, - opening_challenges, - query_rands, - Some(rng), - )?; - - end_timer!(proof_time); - - proofs.push(proof); - } - end_timer!(open_time); - - Ok(proofs.into()) + Self::batch_open( + ck, + labeled_polynomials, + commitments, + query_set, + opening_challenges(0), + rands, + rng, + ) } } diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index c2ae690c..56dfcfaf 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -1,6 +1,6 @@ use crate::{ - PCCommitment, PCCommitterKey, PCPreparedCommitment, PCPreparedVerifierKey, PCRandomness, - PCVerifierKey, Vec, + PCCommitment, PCPreparedCommitment, PCCommitterKey, PCRandomness, PCVerifierKey, + PCPreparedVerifierKey, Vec, }; use ark_ec::{PairingEngine, ProjectiveCurve}; use ark_ff::{PrimeField, ToBytes}; @@ -148,7 +148,7 @@ impl ToBytes for VerifierKey { /// `PreparedVerifierKey` is used to check evaluation proofs for a given commitment. #[derive(Derivative)] -#[derivative(Clone(bound = ""), Debug(bound = ""))] +#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))] pub struct PreparedVerifierKey { /// The verification key for the underlying KZG10 scheme. pub prepared_vk: kzg10::PreparedVerifierKey, @@ -259,6 +259,7 @@ impl PCCommitment for Commitment { /// Prepared commitment to a polynomial that optionally enforces a degree bound. #[derive(Derivative)] #[derivative( + Default(bound = ""), Hash(bound = ""), Clone(bound = ""), Debug(bound = ""), diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index 301acea6..3f345eaa 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -5,7 +5,7 @@ use crate::{LabeledCommitment, LabeledPolynomial, LinearCombination}; use crate::{PCRandomness, PCUniversalParams, Polynomial, PolynomialCommitment}; use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{One, Zero}; +use ark_ff::{One, Zero, Field}; use ark_std::vec; use core::{convert::TryInto, marker::PhantomData}; use rand_core::RngCore; @@ -218,7 +218,7 @@ impl PolynomialCommitment for MarlinKZG10 { v.sort(); v.dedup(); v - }); + }); // Check whether we have some degree bounds to enforce let (shifted_powers, degree_bounds_and_shift_powers) = @@ -339,6 +339,164 @@ impl PolynomialCommitment for MarlinKZG10 { Ok((commitments, randomness)) } + /// On input a polynomial `p` and a point `point`, outputs a proof for the same. + fn open<'a>( + ck: &Self::CommitterKey, + labeled_polynomials: impl IntoIterator>, + commitments: impl IntoIterator>, + point: E::Fr, + opening_challenge: E::Fr, + rands: impl IntoIterator, + rng: Option<&mut dyn RngCore>, + ) -> Result + where + Randomness: 'a, + Commitment: 'a, + { + let opening_challenges = |j| opening_challenge.pow([j]); + Self::open_individual_opening_challenges( + ck, + labeled_polynomials, + commitments, + point, + &opening_challenges, + rands, + rng, + ) + } + + /// Verifies that `value` is the evaluation at `x` of the polynomial + /// committed inside `comm`. + fn check<'a>( + vk: &Self::VerifierKey, + commitments: impl IntoIterator>, + point: E::Fr, + values: impl IntoIterator, + proof: &Self::Proof, + opening_challenge: E::Fr, + rng: Option<&mut dyn RngCore>, + ) -> Result + where + Self::Commitment: 'a, + { + let opening_challenges = |j| opening_challenge.pow([j]); + Self::check_individual_opening_challenges( + vk, + commitments, + point, + values, + proof, + &opening_challenges, + rng, + ) + } + + fn batch_check<'a, R: RngCore>( + vk: &Self::VerifierKey, + commitments: impl IntoIterator>, + query_set: &QuerySet, + evaluations: &Evaluations, + proof: &Self::BatchProof, + opening_challenge: E::Fr, + rng: &mut R, + ) -> Result + where + Self::Commitment: 'a, + { + let opening_challenges = |j| opening_challenge.pow([j]); + Self::batch_check_individual_opening_challenges( + vk, + commitments, + query_set, + evaluations, + proof, + &opening_challenges, + rng, + ) + } + + fn open_combinations<'a>( + ck: &Self::CommitterKey, + lc_s: impl IntoIterator>, + polynomials: impl IntoIterator>, + commitments: impl IntoIterator>, + query_set: &QuerySet, + opening_challenge: E::Fr, + rands: impl IntoIterator, + rng: Option<&mut dyn RngCore>, + ) -> Result, Self::Error> + where + Self::Randomness: 'a, + Self::Commitment: 'a, + { + let opening_challenges = |j| opening_challenge.pow([j]); + Self::open_combinations_individual_opening_challenges( + ck, + lc_s, + polynomials, + commitments, + query_set, + &opening_challenges, + rands, + rng, + ) + } + + /// Checks that `values` are the true evaluations at `query_set` of the polynomials + /// committed in `labeled_commitments`. + fn check_combinations<'a, R: RngCore>( + vk: &Self::VerifierKey, + lc_s: impl IntoIterator>, + commitments: impl IntoIterator>, + query_set: &QuerySet, + evaluations: &Evaluations, + proof: &BatchLCProof, + opening_challenge: E::Fr, + rng: &mut R, + ) -> Result + where + Self::Commitment: 'a, + { + let opening_challenges = |j| opening_challenge.pow([j]); + Self::check_combinations_individual_opening_challenges( + vk, + lc_s, + commitments, + query_set, + evaluations, + proof, + &opening_challenges, + rng, + ) + } + + // On input a list of labeled polynomials and a query set, `open` outputs a proof of evaluation + /// of the polynomials at the points in the query set. + fn batch_open<'a>( + ck: &Self::CommitterKey, + labeled_polynomials: impl IntoIterator>, + commitments: impl IntoIterator>, + query_set: &QuerySet, + opening_challenge: E::Fr, + rands: impl IntoIterator, + rng: Option<&mut dyn RngCore>, + ) -> Result + where + Self::Randomness: 'a, + Self::Commitment: 'a, + { + let opening_challenges = |j| opening_challenge.pow([j]); + Self::batch_open_individual_opening_challenges( + ck, + labeled_polynomials, + commitments, + query_set, + &opening_challenges, + rands, + rng, + ) + } + /// On input a polynomial `p` and a point `point`, outputs a proof for the same. fn open_individual_opening_challenges<'a>( ck: &CommitterKey, @@ -381,15 +539,15 @@ impl PolynomialCommitment for MarlinKZG10 { assert_eq!(degree_bound.is_some(), rand.shifted_rand.is_some()); - p += (challenge_j, polynomial.polynomial()); - r += (challenge_j, &rand.rand); + p += (challenge_j.clone(), polynomial.polynomial()); + r += (challenge_j.clone(), &rand.rand); if let Some(degree_bound) = degree_bound { enforce_degree_bound = true; let shifted_rand = rand.shifted_rand.as_ref().unwrap(); let (witness, shifted_rand_witness) = kzg10::KZG10::compute_witness_polynomial( polynomial.polynomial(), - point, + point.clone(), &shifted_rand, )?; let challenge_j_1 = opening_challenges(opening_challenge_counter); @@ -397,15 +555,15 @@ impl PolynomialCommitment for MarlinKZG10 { let shifted_witness = shift_polynomial(ck, &witness, degree_bound); - shifted_w += (challenge_j_1, &shifted_witness); - shifted_r += (challenge_j_1, shifted_rand); + shifted_w += (challenge_j_1.clone(), &shifted_witness); + shifted_r += (challenge_j_1.clone(), shifted_rand); if let Some(shifted_rand_witness) = shifted_rand_witness { - shifted_r_witness += (challenge_j_1, &shifted_rand_witness); + shifted_r_witness += (challenge_j_1.clone(), &shifted_rand_witness); } } } let proof_time = start_timer!(|| "Creating proof for unshifted polynomials"); - let proof = kzg10::KZG10::open(&ck.powers(), &p, point, &r)?; + let proof = kzg10::KZG10::open(&ck.powers(), &p, point.clone(), &r)?; let mut w = proof.w.into_projective(); let mut random_v = proof.random_v; end_timer!(proof_time); @@ -603,9 +761,9 @@ impl PolynomialCommitment for MarlinKZG10 { // Some(_) > None, always. hiding_bound = core::cmp::max(hiding_bound, cur_poly.hiding_bound()); - poly += (*coeff, cur_poly.polynomial()); - randomness += (*coeff, cur_rand); - coeffs_and_comms.push((*coeff, cur_comm.commitment())); + poly += (coeff.clone(), cur_poly.polynomial()); + randomness += (coeff.clone(), cur_rand); + coeffs_and_comms.push((coeff.clone(), cur_comm.commitment())); if degree_bound.is_none() { assert!(randomness.shifted_rand.is_none()); From 895e27408aa88e31e4f4909d6d018761c194cc26 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 23 Oct 2020 14:26:51 -0700 Subject: [PATCH 02/56] addressed comments --- Cargo.toml | 7 ++++++- src/lib.rs | 20 ++++---------------- src/marlin_pc/mod.rs | 11 +++++++---- src/sonic_pc/mod.rs | 2 +- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 988c86b9..803c48d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,13 @@ ark-poly = { git = "https://github.com/arkworks-rs/algebra", default-features = ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false } -bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } +ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features = false } +ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" } + +ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative" } + +bench-utils = { git = "https://github.com/arkworks-rs/utils" } rand_core = { version = "0.5", default-features = false } digest = "0.8" rayon = { version = "1", optional = true } diff --git a/src/lib.rs b/src/lib.rs index dda70569..419eaa56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,20 +20,7 @@ use core::iter::FromIterator; pub use ark_poly::DensePolynomial as Polynomial; use rand_core::RngCore; -#[cfg(not(feature = "std"))] -#[macro_use] -extern crate alloc; - -#[cfg(not(feature = "std"))] -use alloc::{ - collections::{BTreeMap, BTreeSet}, - rc::Rc, - string::{String, ToString}, - vec::Vec, -}; - -#[cfg(feature = "std")] -use std::{ +use ark_std::{ collections::{BTreeMap, BTreeSet}, rc::Rc, string::{String, ToString}, @@ -44,6 +31,9 @@ use std::{ pub mod data_structures; pub use data_structures::*; +mod pc_constraints; +pub use pc_constraints::*; + /// Errors pertaining to query sets. pub mod error; pub use error::*; @@ -73,7 +63,6 @@ pub mod kzg10; /// /// [kzg]: http://cacr.uwaterloo.ca/techreports/2010/cacr2010-10.pdf /// [marlin]: https://eprint.iacr.org/2019/1047 -// TODO: add "Prepared" to marlin_pc pub mod marlin_pc; /// Polynomial commitment scheme based on the construction in [[KZG10]][kzg], @@ -93,7 +82,6 @@ pub mod sonic_pc; /// The construction is detailed in [[BCMS20]][pcdas]. /// /// [pcdas]: https://eprint.iacr.org/2020/499 -// TODO: add "Prepared" to marlin_pc pub mod ipa_pc; /// `QuerySet` is the set of queries that are to be made to a set of labeled polynomials/equations diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index 3f345eaa..417d52c0 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -13,6 +13,9 @@ use rand_core::RngCore; mod data_structures; pub use data_structures::*; +mod constraints; +pub use constraints::*; + /// Polynomial commitment based on [[KZG10]][kzg], with degree enforcement, batching, /// and (optional) hiding property taken from [[CHMMVW20, “Marlin”]][marlin]. /// @@ -563,7 +566,7 @@ impl PolynomialCommitment for MarlinKZG10 { } } let proof_time = start_timer!(|| "Creating proof for unshifted polynomials"); - let proof = kzg10::KZG10::open(&ck.powers(), &p, point.clone(), &r)?; + let proof = kzg10::KZG10::open(&ck.powers(), &p, point, &r)?; let mut w = proof.w.into_projective(); let mut random_v = proof.random_v; end_timer!(proof_time); @@ -761,9 +764,9 @@ impl PolynomialCommitment for MarlinKZG10 { // Some(_) > None, always. hiding_bound = core::cmp::max(hiding_bound, cur_poly.hiding_bound()); - poly += (coeff.clone(), cur_poly.polynomial()); - randomness += (coeff.clone(), cur_rand); - coeffs_and_comms.push((coeff.clone(), cur_comm.commitment())); + poly += (*coeff, cur_poly.polynomial()); + randomness += (*coeff, cur_rand); + coeffs_and_comms.push((*coeff, cur_comm.commitment())); if degree_bound.is_none() { assert!(randomness.shifted_rand.is_none()); diff --git a/src/sonic_pc/mod.rs b/src/sonic_pc/mod.rs index 4cd90306..f01a3390 100644 --- a/src/sonic_pc/mod.rs +++ b/src/sonic_pc/mod.rs @@ -480,7 +480,7 @@ impl PolynomialCommitment for SonicKZG10 { opening_challenges, Some(randomizer), ); - + randomizer = u128::rand(rng).into(); } From 084b4b93028ff8a579041c9ae31995a8ca72f046 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 23 Oct 2020 15:45:54 -0700 Subject: [PATCH 03/56] removed constraints from this PR --- src/lib.rs | 3 --- src/marlin_pc/mod.rs | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 419eaa56..d652d327 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,9 +31,6 @@ use ark_std::{ pub mod data_structures; pub use data_structures::*; -mod pc_constraints; -pub use pc_constraints::*; - /// Errors pertaining to query sets. pub mod error; pub use error::*; diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index 417d52c0..df9de0bb 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -13,9 +13,6 @@ use rand_core::RngCore; mod data_structures; pub use data_structures::*; -mod constraints; -pub use constraints::*; - /// Polynomial commitment based on [[KZG10]][kzg], with degree enforcement, batching, /// and (optional) hiding property taken from [[CHMMVW20, “Marlin”]][marlin]. /// From b3ac0479ec18276b9064be119c04baf9a0391181 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 23 Oct 2020 15:46:07 -0700 Subject: [PATCH 04/56] cargo fmt --- src/lib.rs | 2 +- src/marlin_pc/data_structures.rs | 4 ++-- src/marlin_pc/mod.rs | 2 +- src/sonic_pc/mod.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d652d327..e11587c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,8 +16,8 @@ extern crate derivative; extern crate bench_utils; use ark_ff::Field; -use core::iter::FromIterator; pub use ark_poly::DensePolynomial as Polynomial; +use core::iter::FromIterator; use rand_core::RngCore; use ark_std::{ diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index 56dfcfaf..6c2d1a1b 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -1,6 +1,6 @@ use crate::{ - PCCommitment, PCPreparedCommitment, PCCommitterKey, PCRandomness, PCVerifierKey, - PCPreparedVerifierKey, Vec, + PCCommitment, PCCommitterKey, PCPreparedCommitment, PCPreparedVerifierKey, PCRandomness, + PCVerifierKey, Vec, }; use ark_ec::{PairingEngine, ProjectiveCurve}; use ark_ff::{PrimeField, ToBytes}; diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index df9de0bb..167b2136 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -218,7 +218,7 @@ impl PolynomialCommitment for MarlinKZG10 { v.sort(); v.dedup(); v - }); + }); // Check whether we have some degree bounds to enforce let (shifted_powers, degree_bounds_and_shift_powers) = diff --git a/src/sonic_pc/mod.rs b/src/sonic_pc/mod.rs index f01a3390..4cd90306 100644 --- a/src/sonic_pc/mod.rs +++ b/src/sonic_pc/mod.rs @@ -480,7 +480,7 @@ impl PolynomialCommitment for SonicKZG10 { opening_challenges, Some(randomizer), ); - + randomizer = u128::rand(rng).into(); } From 85cc7892a08127f0a9e108ead926048481be6492 Mon Sep 17 00:00:00 2001 From: weikeng Date: Sat, 24 Oct 2020 16:56:16 -0700 Subject: [PATCH 05/56] finish some final changes --- src/kzg10/data_structures.rs | 2 +- src/lib.rs | 149 ++++++++++++++++++++++++++++++- src/marlin_pc/data_structures.rs | 3 +- 3 files changed, 148 insertions(+), 6 deletions(-) diff --git a/src/kzg10/data_structures.rs b/src/kzg10/data_structures.rs index 2da865c0..62eb2dff 100644 --- a/src/kzg10/data_structures.rs +++ b/src/kzg10/data_structures.rs @@ -92,7 +92,7 @@ impl ToBytes for VerifierKey { #[derive(Derivative)] #[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))] pub struct PreparedVerifierKey { - /// The generator of G1. + /// The generator of G1, prepared for power series. pub prepared_g: Vec, /// The generator of G2, prepared for use in pairings. pub prepared_h: E::G2Prepared, diff --git a/src/lib.rs b/src/lib.rs index e11587c9..b56b6dbf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -115,9 +115,9 @@ pub trait PolynomialCommitment: Sized { /// open the commitment to produce an evaluation proof. type CommitterKey: PCCommitterKey; /// The verifier key for the scheme; used to check an evaluation proof. - type VerifierKey: PCVerifierKey + Default; + type VerifierKey: PCVerifierKey; /// The prepared verifier key for the scheme; used to check an evaluation proof. - type PreparedVerifierKey: PCPreparedVerifierKey + Default + Clone; + type PreparedVerifierKey: PCPreparedVerifierKey + Clone; /// The commitment to a polynomial. type Commitment: PCCommitment + Default; /// The prepared commitment to a polynomial. @@ -576,8 +576,151 @@ pub trait PolynomialCommitment: Sized { Ok(true) } + /// open but with individual challenges + /// the non-individual version `open` should call this method with + /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, + /// i.e., the same impl as in MarlinKZG. + fn open_individual_opening_challenges<'a>( + ck: &Self::CommitterKey, + labeled_polynomials: impl IntoIterator>, + commitments: impl IntoIterator>, + point: F, + opening_challenges: &dyn Fn(usize) -> F, + rands: impl IntoIterator, + rng: Option<&mut dyn RngCore>, + ) -> Result + where + Self::Randomness: 'a, + Self::Commitment: 'a, + { + Self::open( + ck, + labeled_polynomials, + commitments, + point, + opening_challenges(0), + rands, + rng, + ) + } + + /// check but with individual challenges + /// The non-individual version `check` should call this method with + /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, + /// i.e., the same impl as in MarlinKZG. + fn check_individual_opening_challenges<'a>( + vk: &Self::VerifierKey, + commitments: impl IntoIterator>, + point: F, + values: impl IntoIterator, + proof: &Self::Proof, + opening_challenges: &dyn Fn(usize) -> F, + rng: Option<&mut dyn RngCore>, + ) -> Result + where + Self::Commitment: 'a, + { + Self::check( + vk, + commitments, + point, + values, + proof, + opening_challenges(0), + rng, + ) + } + + /// batch_check but with individual challenges + /// The non-individual version `batch_check` should call this method with + /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, + /// i.e., the same impl as in MarlinKZG. + fn batch_check_individual_opening_challenges<'a, R: RngCore>( + vk: &Self::VerifierKey, + commitments: impl IntoIterator>, + query_set: &QuerySet, + evaluations: &Evaluations, + proof: &Self::BatchProof, + opening_challenges: &dyn Fn(usize) -> F, + rng: &mut R, + ) -> Result + where + Self::Commitment: 'a, + { + Self::batch_check( + vk, + commitments, + query_set, + evaluations, + proof, + opening_challenges(0), + rng, + ) + } + + /// open_combinations but with individual challenges + /// The non-individual version `open_combinations` should call this method with + /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, + /// i.e., the same impl as in MarlinKZG. + fn open_combinations_individual_opening_challenges<'a>( + ck: &Self::CommitterKey, + lc_s: impl IntoIterator>, + polynomials: impl IntoIterator>, + commitments: impl IntoIterator>, + query_set: &QuerySet, + opening_challenges: &dyn Fn(usize) -> F, + rands: impl IntoIterator, + rng: Option<&mut dyn RngCore>, + ) -> Result, Self::Error> + where + Self::Randomness: 'a, + Self::Commitment: 'a, + { + Self::open_combinations( + ck, + lc_s, + polynomials, + commitments, + query_set, + opening_challenges(0), + rands, + rng, + ) + } + + /// check_combinations but with individual challenges + /// The non-individual version `check_combinations` should call this method with + /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, + /// i.e., the same impl as in MarlinKZG. + fn check_combinations_individual_opening_challenges<'a, R: RngCore>( + vk: &Self::VerifierKey, + lc_s: impl IntoIterator>, + commitments: impl IntoIterator>, + query_set: &QuerySet, + evaluations: &Evaluations, + proof: &BatchLCProof, + opening_challenges: &dyn Fn(usize) -> F, + rng: &mut R, + ) -> Result + where + Self::Commitment: 'a, + { + Self::check_combinations( + vk, + lc_s, + commitments, + query_set, + evaluations, + proof, + opening_challenges(0), + rng, + ) + } + /// batch_open but with individual challenges - /// By default, we downgrade them to only use the first individual opening challenges + /// The non-individual version `batch_open` should call this method with + /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, + /// i.e., the same impl as in MarlinKZG. fn batch_open_individual_opening_challenges<'a>( ck: &Self::CommitterKey, labeled_polynomials: impl IntoIterator>, diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index 6c2d1a1b..c2ae690c 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -148,7 +148,7 @@ impl ToBytes for VerifierKey { /// `PreparedVerifierKey` is used to check evaluation proofs for a given commitment. #[derive(Derivative)] -#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))] +#[derivative(Clone(bound = ""), Debug(bound = ""))] pub struct PreparedVerifierKey { /// The verification key for the underlying KZG10 scheme. pub prepared_vk: kzg10::PreparedVerifierKey, @@ -259,7 +259,6 @@ impl PCCommitment for Commitment { /// Prepared commitment to a polynomial that optionally enforces a degree bound. #[derive(Derivative)] #[derivative( - Default(bound = ""), Hash(bound = ""), Clone(bound = ""), Debug(bound = ""), From 8c259817f1876afca6d9cf0e6f3a808a38d2b7c0 Mon Sep 17 00:00:00 2001 From: weikeng Date: Sat, 24 Oct 2020 17:00:54 -0700 Subject: [PATCH 06/56] some other comments --- src/marlin_pc/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index 167b2136..501a5f62 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -539,15 +539,15 @@ impl PolynomialCommitment for MarlinKZG10 { assert_eq!(degree_bound.is_some(), rand.shifted_rand.is_some()); - p += (challenge_j.clone(), polynomial.polynomial()); - r += (challenge_j.clone(), &rand.rand); + p += (challenge_j, polynomial.polynomial()); + r += (challenge_j, &rand.rand); if let Some(degree_bound) = degree_bound { enforce_degree_bound = true; let shifted_rand = rand.shifted_rand.as_ref().unwrap(); let (witness, shifted_rand_witness) = kzg10::KZG10::compute_witness_polynomial( polynomial.polynomial(), - point.clone(), + point, &shifted_rand, )?; let challenge_j_1 = opening_challenges(opening_challenge_counter); @@ -555,10 +555,10 @@ impl PolynomialCommitment for MarlinKZG10 { let shifted_witness = shift_polynomial(ck, &witness, degree_bound); - shifted_w += (challenge_j_1.clone(), &shifted_witness); - shifted_r += (challenge_j_1.clone(), shifted_rand); + shifted_w += (challenge_j_1, &shifted_witness); + shifted_r += (challenge_j_1, shifted_rand); if let Some(shifted_rand_witness) = shifted_rand_witness { - shifted_r_witness += (challenge_j_1.clone(), &shifted_rand_witness); + shifted_r_witness += (challenge_j_1, &shifted_rand_witness); } } } From 6a7bc6acbd9048ea9a026a82737091a2d4cfcc14 Mon Sep 17 00:00:00 2001 From: weikeng Date: Sat, 24 Oct 2020 17:03:27 -0700 Subject: [PATCH 07/56] remove the dependency of nonnative for now --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 803c48d6..2c1fd339 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,8 +32,11 @@ ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" } +<<<<<<< HEAD ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative" } +======= +>>>>>>> remove the dependency of nonnative for now bench-utils = { git = "https://github.com/arkworks-rs/utils" } rand_core = { version = "0.5", default-features = false } digest = "0.8" From ee106850904fdfc20457392a4b26286c9ae4c5ca Mon Sep 17 00:00:00 2001 From: weikeng Date: Sat, 24 Oct 2020 17:08:54 -0700 Subject: [PATCH 08/56] try to fix nostd --- Cargo.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2c1fd339..0543f1e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,11 +32,6 @@ ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" } -<<<<<<< HEAD -ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative" } - -======= ->>>>>>> remove the dependency of nonnative for now bench-utils = { git = "https://github.com/arkworks-rs/utils" } rand_core = { version = "0.5", default-features = false } digest = "0.8" From 24fd572c61ad9bd3fcfb7467dcbc7adcea3ced09 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Sun, 25 Oct 2020 10:24:37 -0700 Subject: [PATCH 09/56] fix --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 0543f1e2..f4a516dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,8 @@ ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" } -bench-utils = { git = "https://github.com/arkworks-rs/utils" } +bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } + rand_core = { version = "0.5", default-features = false } digest = "0.8" rayon = { version = "1", optional = true } From a467a524c3f87059ceb8e41bdb12ac60adc5a5ec Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 27 Oct 2020 10:31:46 -0700 Subject: [PATCH 10/56] constraints --- src/lib.rs | 4 + src/marlin_pc/constraints.rs | 1927 ++++++++++++++++++++++++++++++++++ src/marlin_pc/mod.rs | 3 + src/pc_constraints.rs | 185 ++++ 4 files changed, 2119 insertions(+) create mode 100644 src/marlin_pc/constraints.rs create mode 100644 src/pc_constraints.rs diff --git a/src/lib.rs b/src/lib.rs index b56b6dbf..6728902d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,10 @@ use ark_std::{ pub mod data_structures; pub use data_structures::*; +/// Constraints for recursion. +mod pc_constraints; +pub use pc_constraints::*; + /// Errors pertaining to query sets. pub mod error; pub use error::*; diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs new file mode 100644 index 00000000..2c5a22ec --- /dev/null +++ b/src/marlin_pc/constraints.rs @@ -0,0 +1,1927 @@ +use crate::{ + data_structures::LabeledCommitment, + kzg10::{Proof, VerifierKey as KZG10VerifierKey}, + marlin_pc::{ + data_structures::{Commitment, VerifierKey}, + MarlinKZG10, PreparedCommitment, PreparedVerifierKey, + }, + pc_constraints::{EvaluationsVar, PCCheckVar, QuerySetVar}, + BTreeMap, BTreeSet, BatchLCProof, LinearCombinationVar, PrepareVar, String, ToString, Vec, +}; +use ark_ec::{CycleEngine, PairingEngine}; +use ark_ff::{fields::Field, PrimeField, ToConstraintField}; +use core::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::MulAssign}; +use ark_nonnative_field::{NonNativeFieldMulResultVar, NonNativeFieldVar}; +use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; +use ark_r1cs_std::{ + alloc::{AllocVar, AllocationMode}, + bits::{boolean::Boolean, uint8::UInt8, ToBitsGadget}, + eq::EqGadget, + fields::{fp::FpVar, FieldVar}, + groups::CurveVar, + pairing::PairingVar, + select::CondSelectGadget, + R1CSVar, ToBytesGadget, ToConstraintFieldGadget, +}; + +/// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. +pub struct VerifierKeyVar< + CycleE: CycleEngine, + PG: PairingVar::Fr>, +> where + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + /// Generator of G1. + pub g: PG::G1Var, + /// Generator of G2. + pub h: PG::G2Var, + /// Generator of G1, times first monomial. + pub beta_h: PG::G2Var, + /// Used for the shift powers associated with different degree bounds. + pub degree_bounds_and_shift_powers: + Option::Fr>, PG::G1Var)>>, +} + +impl VerifierKeyVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + /// Find the appropriate shift for the degree bound. + pub fn get_shift_power( + &self, + cs: impl Into::Fr>>, + bound: &FpVar<::Fr>, + ) -> Option { + // Search the bound using PIR + if self.degree_bounds_and_shift_powers.is_none() { + None + } else { + let ns = cs.into(); + let cs = ns.cs(); + + let degree_bounds_and_shift_powers = + self.degree_bounds_and_shift_powers.clone().unwrap(); + + let mut pir_vector = vec![false; degree_bounds_and_shift_powers.len()]; + + let desired_bound_value = bound.value().unwrap_or_default(); + + for (i, (_, this_bound, _)) in degree_bounds_and_shift_powers.iter().enumerate() { + if this_bound + .value() + .unwrap_or_default() + .eq(&desired_bound_value) + { + pir_vector[i] = true; + break; + } + } + + let mut pir_vector_gadgets = Vec::new(); + for bit in pir_vector.iter() { + pir_vector_gadgets.push( + Boolean::new_witness(ark_relations::ns!(cs, "alloc_pir"), || Ok(bit)).unwrap(), + ); + } + + // Sum of the PIR values are equal to one + let mut sum = FpVar::<::Fr>::zero(); + let one = FpVar::<::Fr>::one(); + for pir_gadget in pir_vector_gadgets.iter() { + sum = sum + &FpVar::<::Fr>::from(pir_gadget.clone()); + } + sum.enforce_equal(&one).unwrap(); + + // PIR the value + let mut found_bound = FpVar::<::Fr>::zero(); + + let mut found_shift_power = PG::G1Var::zero(); + + for (pir_gadget, (_, degree, shift_power)) in pir_vector_gadgets + .iter() + .zip(degree_bounds_and_shift_powers.iter()) + { + found_bound = FpVar::<::Fr>::conditionally_select( + pir_gadget, + degree, + &found_bound, + ) + .unwrap(); + + found_shift_power = + PG::G1Var::conditionally_select(pir_gadget, shift_power, &found_shift_power) + .unwrap(); + } + + found_bound.enforce_equal(&bound).unwrap(); + + Some(found_shift_power) + } + } +} + +impl Clone for VerifierKeyVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn clone(&self) -> Self { + VerifierKeyVar { + g: self.g.clone(), + h: self.h.clone(), + beta_h: self.beta_h.clone(), + degree_bounds_and_shift_powers: self.degree_bounds_and_shift_powers.clone(), + } + } +} + +impl AllocVar, ::Fr> + for VerifierKeyVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn new_variable( + cs: impl Into::Fr>>, + val: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result + where + T: Borrow>, + { + let vk_orig = val()?.borrow().clone(); + + let ns = cs.into(); + let cs = ns.cs(); + + let VerifierKey { + vk, + degree_bounds_and_shift_powers, + .. + } = vk_orig; + + let degree_bounds_and_shift_powers = degree_bounds_and_shift_powers.and_then(|vec| { + Some( + vec.iter() + .map(|(s, g)| { + ( + *s, + FpVar::<::Fr>::new_variable( + ark_relations::ns!(cs, "degree bound"), + || { + Ok(<::Fr as From>::from( + *s as u128, + )) + }, + mode, + ) + .unwrap(), + PG::G1Var::new_variable( + ark_relations::ns!(cs, "pow"), + || Ok(g.clone()), + mode, + ) + .unwrap(), + ) + }) + .collect(), + ) + }); + + let KZG10VerifierKey { g, h, beta_h, .. } = vk; + + let g = PG::G1Var::new_variable(ark_relations::ns!(cs, "g"), || Ok(g.clone()), mode)?; + let h = PG::G2Var::new_variable(ark_relations::ns!(cs, "h"), || Ok(h.clone()), mode)?; + let beta_h = PG::G2Var::new_variable(ark_relations::ns!(cs, "beta_h"), || Ok(beta_h), mode)?; + + Ok(Self { + g, + h, + beta_h, + degree_bounds_and_shift_powers, + }) + } +} + +impl ToBytesGadget<::Fr> for VerifierKeyVar +where + CycleE: CycleEngine, + + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + #[inline] + fn to_bytes(&self) -> Result::Fr>>, SynthesisError> { + let mut bytes = Vec::new(); + + bytes.extend_from_slice(&self.g.to_bytes()?); + bytes.extend_from_slice(&self.h.to_bytes()?); + bytes.extend_from_slice(&self.beta_h.to_bytes()?); + + if self.degree_bounds_and_shift_powers.is_some() { + let degree_bounds_and_shift_powers = + self.degree_bounds_and_shift_powers.as_ref().unwrap(); + for (_, degree_bound, shift_power) in degree_bounds_and_shift_powers.iter() { + bytes.extend_from_slice(°ree_bound.to_bytes()?); + bytes.extend_from_slice(&shift_power.to_bytes()?); + } + } + + Ok(bytes) + } +} + +impl ToConstraintFieldGadget<::Fr> + for VerifierKeyVar +where + CycleE: CycleEngine, + + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + PG::G1Var: ToConstraintFieldGadget<::Fr>, + PG::G2Var: ToConstraintFieldGadget<::Fr>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn to_constraint_field( + &self, + ) -> Result::Fr>>, SynthesisError> { + let mut res = Vec::new(); + + let mut g_gadget = self.g.to_constraint_field()?; + let mut h_gadget = self.h.to_constraint_field()?; + let mut beta_h_gadget = self.beta_h.to_constraint_field()?; + + res.append(&mut g_gadget); + res.append(&mut h_gadget); + res.append(&mut beta_h_gadget); + + if self.degree_bounds_and_shift_powers.as_ref().is_some() { + let list = self.degree_bounds_and_shift_powers.as_ref().unwrap(); + for (_, d_gadget, shift_power) in list.iter() { + let mut d_elems = d_gadget.to_constraint_field()?; + let mut shift_power_elems = shift_power.to_constraint_field()?; + + res.append(&mut d_elems); + res.append(&mut shift_power_elems); + } + } + + Ok(res) + } +} + +/// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. +pub struct PreparedVerifierKeyVar< + CycleE: CycleEngine, + PG: PairingVar::Fr>, +> where + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + /// Generator of G1. + pub prepared_g: Vec, + /// Generator of G2. + pub prepared_h: PG::G2PreparedVar, + /// Generator of G1, times first monomial. + pub prepared_beta_h: PG::G2PreparedVar, + /// Used for the shift powers associated with different degree bounds. + pub prepared_degree_bounds_and_shift_powers: Option< + Vec<( + usize, + FpVar<::Fr>, + Vec, + )>, + >, + /// Indicate whether or not it is a constant allocation (which decides whether or not shift powers are precomputed) + pub constant_allocation: bool, + /// If not a constant allocation, the original vk is attached (for computing the shift power series) + pub origin_vk: Option>, +} + +impl PreparedVerifierKeyVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + /// Find the appropriate shift for the degree bound. + pub fn get_shift_power( + &self, + cs: impl Into::Fr>>, + bound: &FpVar<::Fr>, + ) -> Option> { + if self.constant_allocation { + if self.prepared_degree_bounds_and_shift_powers.is_none() { + None + } else { + let prepared_degree_bounds_and_shift_powers = self + .prepared_degree_bounds_and_shift_powers + .as_ref() + .unwrap(); + let bound_value = bound.value().unwrap_or_default(); + + for (_, bound, prepared_shift_powers) in + prepared_degree_bounds_and_shift_powers.iter() + { + if bound.value().unwrap_or_default() == bound_value { + return Some((*prepared_shift_powers).clone()); + } + } + + None + } + } else { + let shift_power = self.origin_vk.as_ref().unwrap().get_shift_power(cs, bound); + + if shift_power.is_none() { + None + } else { + let mut prepared_shift_gadgets = Vec::::new(); + + let supported_bits = ::Fr::size_in_bits(); + + let mut cur: PG::G1Var = shift_power.unwrap().clone(); + for _ in 0..supported_bits { + prepared_shift_gadgets.push(cur.clone()); + cur.double_in_place().unwrap(); + } + + Some(prepared_shift_gadgets) + } + } + } +} + +impl PrepareVar, ::Fr> + for PreparedVerifierKeyVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn prepare(unprepared: &VerifierKeyVar) -> Result { + let supported_bits = ::Fr::size_in_bits(); + let mut prepared_g = Vec::::new(); + + let mut g: PG::G1Var = unprepared.g.clone(); + for _ in 0..supported_bits { + prepared_g.push(g.clone()); + g.double_in_place()?; + } + + let prepared_h = PG::prepare_g2(&unprepared.h)?; + let prepared_beta_h = PG::prepare_g2(&unprepared.beta_h)?; + + let prepared_degree_bounds_and_shift_powers = + if unprepared.degree_bounds_and_shift_powers.is_some() { + let mut res = Vec::<( + usize, + FpVar<::Fr>, + Vec, + )>::new(); + + for (d, d_gadget, shift_power) in unprepared + .degree_bounds_and_shift_powers + .as_ref() + .unwrap() + .iter() + { + res.push((d.clone(), (*d_gadget).clone(), vec![shift_power.clone()])); + } + + Some(res) + } else { + None + }; + + Ok(Self { + prepared_g, + prepared_h, + prepared_beta_h, + prepared_degree_bounds_and_shift_powers, + constant_allocation: false, + origin_vk: Some(unprepared.clone()), + }) + } +} + +impl Clone for PreparedVerifierKeyVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn clone(&self) -> Self { + PreparedVerifierKeyVar { + prepared_g: self.prepared_g.clone(), + prepared_h: self.prepared_h.clone(), + prepared_beta_h: self.prepared_beta_h.clone(), + prepared_degree_bounds_and_shift_powers: self + .prepared_degree_bounds_and_shift_powers + .clone(), + constant_allocation: self.constant_allocation.clone(), + origin_vk: self.origin_vk.clone(), + } + } +} + +impl AllocVar, ::Fr> + for PreparedVerifierKeyVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn new_variable( + cs: impl Into::Fr>>, + f: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result + where + T: Borrow>, + { + let t = f()?; + let obj = t.borrow(); + + let ns = cs.into(); + let cs = ns.cs(); + + let mut prepared_g = Vec::::new(); + for g in obj.prepared_vk.prepared_g.iter() { + prepared_g.push(::G1Affine, + ::Fr, + >>::new_variable( + ark_relations::ns!(cs, "g"), || Ok(g.clone()), mode + )?); + } + + let prepared_h = PG::G2PreparedVar::new_variable( + ark_relations::ns!(cs, "h"), + || Ok(&obj.prepared_vk.prepared_h), + mode, + )?; + let prepared_beta_h = PG::G2PreparedVar::new_variable( + ark_relations::ns!(cs, "beta_h"), + || Ok(&obj.prepared_vk.prepared_beta_h), + mode, + )?; + + let prepared_degree_bounds_and_shift_powers = + if obj.prepared_degree_bounds_and_shift_powers.is_some() { + let mut res = Vec::<( + usize, + FpVar<::Fr>, + Vec, + )>::new(); + + for (d, shift_power_elems) in obj + .prepared_degree_bounds_and_shift_powers + .as_ref() + .unwrap() + .iter() + { + let mut gadgets = Vec::::new(); + for shift_power_elem in shift_power_elems.iter() { + gadgets.push(::G1Affine, + ::Fr, + >>::new_variable( + cs.clone(), || Ok(shift_power_elem.clone()), mode + )?); + } + + let d_gadget = FpVar::<::Fr>::new_variable( + cs.clone(), + || { + Ok(<::Fr as From>::from( + *d as u128, + )) + }, + mode, + )?; + + res.push((d.clone(), d_gadget, gadgets)); + } + Some(res) + } else { + None + }; + + Ok(Self { + prepared_g, + prepared_h, + prepared_beta_h, + prepared_degree_bounds_and_shift_powers, + constant_allocation: true, + origin_vk: None, + }) + } +} + +/// Var for an optionally hiding Marlin-KZG10 commitment. +pub struct CommitmentVar< + CycleE: CycleEngine, + PG: PairingVar::Fr>, +> where + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + comm: PG::G1Var, + shifted_comm: Option, +} + +impl Clone for CommitmentVar +where + CycleE: CycleEngine, + + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn clone(&self) -> Self { + CommitmentVar { + comm: self.comm.clone(), + shifted_comm: self.shifted_comm.clone(), + } + } +} + +impl AllocVar, ::Fr> + for CommitmentVar +where + CycleE: CycleEngine, + + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + #[inline] + fn new_variable( + cs: impl Into::Fr>>, + value_gen: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result + where + T: Borrow>, + { + value_gen().and_then(|commitment| { + let ns = cs.into(); + let cs = ns.cs(); + + let commitment = (*commitment.borrow()).clone(); + let comm = commitment.comm; + let comm_gadget = PG::G1Var::new_variable(cs.clone(), || Ok(comm.0), mode)?; + + let shifted_comm = commitment.shifted_comm; + let shifted_comm_gadget = if let Some(shifted_comm) = shifted_comm { + Some(PG::G1Var::new_variable( + cs.clone(), + || Ok(shifted_comm.0), + mode, + )?) + } else { + None + }; + + Ok(Self { + comm: comm_gadget, + shifted_comm: shifted_comm_gadget, + }) + }) + } +} + +impl ToConstraintFieldGadget<::Fr> + for CommitmentVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + PG::G1Var: ToConstraintFieldGadget<::Fr>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn to_constraint_field( + &self, + ) -> Result::Fr>>, SynthesisError> { + let mut res = Vec::new(); + + let mut comm_gadget = self.comm.to_constraint_field()?; + + res.append(&mut comm_gadget); + + if self.shifted_comm.as_ref().is_some() { + let mut shifted_comm_gadget = + self.shifted_comm.as_ref().unwrap().to_constraint_field()?; + res.append(&mut shifted_comm_gadget); + } + + Ok(res) + } +} + +impl ToBytesGadget<::Fr> for CommitmentVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn to_bytes(&self) -> Result::Fr>>, SynthesisError> { + let zero_shifted_comm = PG::G1Var::zero(); + + let mut bytes = Vec::new(); + bytes.extend_from_slice(&self.comm.to_bytes()?); + + let shifted_comm = self.shifted_comm.clone().unwrap_or(zero_shifted_comm); + bytes.extend_from_slice(&shifted_comm.to_bytes()?); + Ok(bytes) + } +} + +/// Prepared gadget for an optionally hiding Marlin-KZG10 commitment. +/// shifted_comm is not prepared, due to the specific use case. +pub struct PreparedCommitmentVar< + CycleE: CycleEngine, + PG: PairingVar::Fr>, +> where + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + prepared_comm: Vec, + shifted_comm: Option, +} + +impl Clone for PreparedCommitmentVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn clone(&self) -> Self { + PreparedCommitmentVar { + prepared_comm: self.prepared_comm.clone(), + shifted_comm: self.shifted_comm.clone(), + } + } +} + +impl PrepareVar, ::Fr> + for PreparedCommitmentVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn prepare(unprepared: &CommitmentVar) -> Result { + let mut prepared_comm = Vec::::new(); + let supported_bits = ::Fr::size_in_bits(); + + let mut cur: PG::G1Var = unprepared.comm.clone(); + for _ in 0..supported_bits { + prepared_comm.push(cur.clone()); + cur.double_in_place()?; + } + + Ok(Self { + prepared_comm, + shifted_comm: unprepared.shifted_comm.clone(), + }) + } + + fn prepare_small(unprepared: &CommitmentVar) -> Result { + let mut prepared_comm = Vec::::new(); + let supported_bits = 128; + + let mut cur: PG::G1Var = unprepared.comm.clone(); + for _ in 0..supported_bits { + prepared_comm.push(cur.clone()); + cur.double_in_place()?; + } + + Ok(Self { + prepared_comm, + shifted_comm: unprepared.shifted_comm.clone(), + }) + } +} + +impl AllocVar, ::Fr> + for PreparedCommitmentVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn new_variable( + cs: impl Into::Fr>>, + f: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result + where + T: Borrow>, + { + let t = f()?; + let obj = t.borrow(); + + let ns = cs.into(); + let cs = ns.cs(); + + let mut prepared_comm = Vec::::new(); + + for comm_elem in obj.prepared_comm.0.iter() { + prepared_comm.push(::G1Projective, + ::Fr, + >>::new_variable( + ark_relations::ns!(cs, "comm_elem"), + || { + Ok(::G1Projective::from( + comm_elem.clone(), + )) + }, + mode, + )?); + } + + let shifted_comm = if obj.shifted_comm.is_some() { + Some(::G1Projective, + ::Fr, + >>::new_variable( + ark_relations::ns!(cs, "shifted_comm"), + || { + Ok(::G1Projective::from( + obj.shifted_comm.unwrap().0.clone(), + )) + }, + mode, + )?) + } else { + None + }; + + Ok(Self { + prepared_comm, + shifted_comm, + }) + } +} + +/// Var for a Marlin-KZG10 commitment, with a string label and degree bound. +pub struct LabeledCommitmentVar< + CycleE: CycleEngine, + PG: PairingVar::Fr>, +> where + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + /// A text label for the commitment. + pub label: String, + /// The plain commitment. + pub commitment: CommitmentVar, + /// Optionally, a bound on the polynomial degree. + pub degree_bound: Option::Fr>>, +} + +impl Clone for LabeledCommitmentVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn clone(&self) -> Self { + LabeledCommitmentVar { + label: self.label.clone(), + commitment: self.commitment.clone(), + degree_bound: self.degree_bound.clone(), + } + } +} + +impl + AllocVar>, ::Fr> + for LabeledCommitmentVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + #[inline] + fn new_variable( + cs: impl Into::Fr>>, + value_gen: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result + where + T: Borrow>>, + { + value_gen().and_then(|labeled_commitment| { + let ns = cs.into(); + let cs = ns.cs(); + + let labeled_commitment = labeled_commitment.borrow().clone(); + let label = labeled_commitment.label().to_string(); + let commitment = labeled_commitment.commitment(); + let degree_bound = labeled_commitment.degree_bound(); + + let commitment = CommitmentVar::new_variable( + ark_relations::ns!(cs, "commitment"), + || Ok(commitment), + mode, + )?; + + let degree_bound = if degree_bound.is_some() { + FpVar::<::Fr>::new_variable( + ark_relations::ns!(cs, "degree_bound"), + || { + Ok(<::Fr as From>::from( + degree_bound.unwrap() as u128, + )) + }, + mode, + ) + .ok() + } else { + None + }; + + Ok(Self { + label, + commitment, + degree_bound, + }) + }) + } +} + +/// Var for a Marlin-KZG10 commitment, with a string label and degree bound. +pub struct PreparedLabeledCommitmentVar< + CycleE: CycleEngine, + PG: PairingVar::Fr>, +> where + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + /// A text label for the commitment. + pub label: String, + /// The plain commitment. + pub prepared_commitment: PreparedCommitmentVar, + /// Optionally, a bound on the polynomial degree. + pub degree_bound: Option::Fr>>, +} + +impl Clone for PreparedLabeledCommitmentVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn clone(&self) -> Self { + PreparedLabeledCommitmentVar { + label: self.label.clone(), + prepared_commitment: self.prepared_commitment.clone(), + degree_bound: self.degree_bound.clone(), + } + } +} + +impl PrepareVar, ::Fr> + for PreparedLabeledCommitmentVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn prepare(unprepared: &LabeledCommitmentVar) -> Result { + let prepared_commitment = PreparedCommitmentVar::prepare(&unprepared.commitment)?; + + Ok(Self { + label: unprepared.label.clone(), + prepared_commitment, + degree_bound: unprepared.degree_bound.clone(), + }) + } +} + +/// Var for a Marlin-KZG10 proof. +pub struct ProofVar< + CycleE: CycleEngine, + PG: PairingVar::Fr>, +> where + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + /// The commitment to the witness polynomial. + pub w: PG::G1Var, + /// The evaluation of the random hiding polynomial. + pub random_v: Option< + NonNativeFieldVar<::Fr, ::Fr>, + >, +} + +impl Clone for ProofVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn clone(&self) -> Self { + ProofVar { + w: self.w.clone(), + random_v: self.random_v.clone(), + } + } +} + +impl AllocVar, ::Fr> + for ProofVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + #[inline] + fn new_variable( + cs: impl Into::Fr>>, + value_gen: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result + where + T: Borrow>, + { + value_gen().and_then(|proof| { + let ns = cs.into(); + let cs = ns.cs(); + + let Proof { w, random_v } = proof.borrow().clone(); + let w = PG::G1Var::new_variable(ark_relations::ns!(cs, "w"), || Ok(w), mode)?; + + let random_v = match random_v { + None => None, + Some(random_v_inner) => Some(NonNativeFieldVar::new_variable( + ark_relations::ns!(cs, "random_v"), + || Ok(random_v_inner.clone()), + mode, + )?), + }; + + Ok(Self { w, random_v }) + }) + } +} + +/// An allocated version of `BatchLCProof`. +pub struct BatchLCProofVar< + CycleE: CycleEngine, + PG: PairingVar::Fr>, +> where + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + /// Evaluation proofs. + pub proofs: Vec>, + /// Evaluations required to verify the proof. + pub evals: Option< + Vec< + NonNativeFieldVar<::Fr, ::Fr>, + >, + >, +} + +impl Clone for BatchLCProofVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn clone(&self) -> Self { + BatchLCProofVar { + proofs: self.proofs.clone(), + evals: self.evals.clone(), + } + } +} + +impl + AllocVar< + BatchLCProof<::Fr, MarlinKZG10>, + ::Fr, + > for BatchLCProofVar +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + #[inline] + fn new_variable( + cs: impl Into::Fr>>, + value_gen: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result + where + T: Borrow::Fr, MarlinKZG10>>, + { + value_gen().and_then(|proof| { + let ns = cs.into(); + let cs = ns.cs(); + + let BatchLCProof { proof, evals } = proof.borrow().clone(); + + let proofs: Vec> = proof.clone().into(); + let proofs: Vec> = proofs + .iter() + .map(|p| { + ProofVar::new_variable(ark_relations::ns!(cs, "proof"), || Ok(p), mode).unwrap() + }) + .collect(); + + let evals: Option< + Vec< + NonNativeFieldVar< + ::Fr, + ::Fr, + >, + >, + > = match evals { + None => None, + Some(evals_inner) => Some( + evals_inner + .iter() + .map(|e| { + NonNativeFieldVar::new_variable( + ark_relations::ns!(cs, "evaluation"), + || Ok(e), + mode, + ) + .unwrap() + }) + .collect(), + ), + }; + + Ok(Self { proofs, evals }) + }) + } +} + +/// Var for the Marlin-KZG10 polynomial commitment verifier. +pub struct MarlinKZG10Gadget +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + _cycle_engine: PhantomData, + _pairing_gadget: PhantomData, +} + +impl Clone for MarlinKZG10Gadget +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn clone(&self) -> Self { + MarlinKZG10Gadget { + _cycle_engine: PhantomData, + _pairing_gadget: PhantomData, + } + } +} + +impl MarlinKZG10Gadget +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + fn prepared_batch_check_evaluations( + cs: ConstraintSystemRef<::Fr>, + prepared_verification_key: &::Fr, + MarlinKZG10, + ::Fr, + >>::PreparedVerifierKeyVar, + lc_info: &Vec<( + String, + Vec<( + Option< + NonNativeFieldVar< + ::Fr, + ::Fr, + >, + >, + Option::Fr>>, + PreparedCommitmentVar, + bool, + )>, + )>, + query_set: &QuerySetVar< + ::Fr, + ::Fr, + >, + evaluations: &EvaluationsVar< + ::Fr, + ::Fr, + >, + proofs: &Vec< + ::Fr, + MarlinKZG10, + ::Fr, + >>::ProofVar, + >, + opening_challenges: &Vec< + NonNativeFieldVar<::Fr, ::Fr>, + >, + opening_challenges_bits: &Vec::Fr>>>, + batching_rands: &Vec< + NonNativeFieldVar<::Fr, ::Fr>, + >, + batching_rands_bits: &Vec::Fr>>>, + ) -> Result::Fr>, SynthesisError> { + let mut batching_rands = batching_rands.clone(); + let mut batching_rands_bits = batching_rands_bits.clone(); + + let commitment_lcs: BTreeMap< + String, + ( + String, + Vec<( + Option< + NonNativeFieldVar< + ::Fr, + ::Fr, + >, + >, + Option::Fr>>, + PreparedCommitmentVar, + bool, + )>, + ), + > = lc_info.iter().map(|c| (c.0.clone(), c.clone())).collect(); + + let mut query_to_labels_map = BTreeMap::new(); + + for (label, (point_label, point)) in query_set.0.iter() { + let labels = query_to_labels_map + .entry((*point_label).clone()) + .or_insert((point, BTreeSet::new())); + labels.1.insert(label); + } + + println!( + "before PC combining commitments: constraints: {}", + cs.num_constraints() + ); + + // Accumulate commitments and evaluations for each query. + let mut combined_queries = Vec::new(); + let mut combined_comms = Vec::new(); + let mut combined_evals = Vec::new(); + for (_point_label, (point, labels)) in query_to_labels_map.into_iter() { + let mut comms_to_combine = Vec::< + Vec<( + Option< + NonNativeFieldVar< + ::Fr, + ::Fr, + >, + >, + Option::Fr>>, + PreparedCommitmentVar, + bool, + )>, + >::new(); + let mut values_to_combine = Vec::new(); + for label in labels.into_iter() { + let commitment_lc = commitment_lcs.get(label).unwrap().clone(); + + let v_i = evaluations.0.get(&(label.clone(), point.clone())).unwrap(); + + comms_to_combine.push(commitment_lc.1.clone()); + values_to_combine.push(v_i.clone()); + } + + // Accumulate the commitments and evaluations corresponding to `query`. + let mut combined_comm = PG::G1Var::zero(); + let mut combined_eval = NonNativeFieldMulResultVar::< + ::Fr, + ::Fr, + >::zero(); + + let mut opening_challenges_counter = 0; + + for (commitment_lcs, value) in comms_to_combine.into_iter().zip(values_to_combine) { + let challenge = opening_challenges[opening_challenges_counter].clone(); + + let challenge_bits = opening_challenges_bits[opening_challenges_counter].clone(); + opening_challenges_counter += 1; + + for (coeff, degree_bound, comm, negate) in commitment_lcs.iter() { + let PreparedCommitmentVar { shifted_comm, .. } = comm; + + if coeff.is_none() { + // To combine the commitments, we multiply each by one of the random challenges, and sum. + let mut comm_times_challenge = PG::G1Var::zero(); + { + for (bit, base_power) in + challenge_bits.iter().zip(comm.prepared_comm.iter()) + { + let mut new_encoded = base_power.clone(); + new_encoded += comm_times_challenge.clone(); + comm_times_challenge = PG::G1Var::conditionally_select( + bit, + &new_encoded, + &comm_times_challenge, + )?; + } + } + + if negate.eq(&true) { + comm_times_challenge = comm_times_challenge.negate()?; + } + + combined_comm += comm_times_challenge.clone(); + + // If the degree bound is specified, we include the adjusted degree-shifted commitment + // (that is, c_i' - v_i beta^{D - d_i} G), where d_i is the specific degree bound and + // v_i is the evaluation, in the combined commitment, + if let Some(degree_bound) = degree_bound { + let challenge_shifted_bits = + opening_challenges_bits[opening_challenges_counter].clone(); + opening_challenges_counter += 1; + + let mut shifted_comm = shifted_comm.clone().unwrap(); + + if negate.eq(&true) { + shifted_comm = shifted_comm.negate()?; + } + + let value_bits = value.to_bits_le()?; + let shift_power = prepared_verification_key + .get_shift_power(cs.clone(), degree_bound) + .unwrap(); + + let mut shift_power_times_value = PG::G1Var::zero(); + { + for (bit, base_power) in value_bits.iter().zip(&shift_power) { + let mut new_encoded = base_power.clone(); + new_encoded += shift_power_times_value.clone(); + shift_power_times_value = PG::G1Var::conditionally_select( + bit, + &new_encoded, + &shift_power_times_value, + )?; + } + } + let mut adjusted_comm = shifted_comm; + adjusted_comm -= shift_power_times_value; + let adjusted_comm_times_challenge = + adjusted_comm.scalar_mul_le(challenge_shifted_bits.iter())?; + combined_comm += adjusted_comm_times_challenge; + } + } else { + assert!(degree_bound.is_none()); + + let mut comm_times_challenge = PG::G1Var::zero(); + let coeff = coeff.clone().unwrap(); + + let challenge_times_coeff = &challenge * &coeff; + let challenge_times_coeff_bits = challenge_times_coeff.to_bits_le()?; + + { + for (bit, base_power) in + challenge_times_coeff_bits.iter().zip(&comm.prepared_comm) + { + let mut new_encoded = comm_times_challenge.clone(); + new_encoded += base_power.clone(); + comm_times_challenge = PG::G1Var::conditionally_select( + bit, + &new_encoded, + &comm_times_challenge, + )?; + } + } + + if negate.eq(&true) { + comm_times_challenge = comm_times_challenge.negate()?; + } + + combined_comm += comm_times_challenge; + } + } + // Similarly, we add up the evaluations, multiplied with random challenges. + let value_times_challenge_unreduced = value.mul_without_reduce(&challenge)?; + + combined_eval = combined_eval + &value_times_challenge_unreduced; + } + + let combined_eval_reduced = combined_eval.reduce()?; + + combined_queries.push(point.clone()); + combined_comms.push(combined_comm); + combined_evals.push(combined_eval_reduced); + } + + println!( + "before PC batch check: constraints: {}", + cs.num_constraints() + ); + + // Perform the batch check. + { + let mut total_c = PG::G1Var::zero(); + let mut total_w = PG::G1Var::zero(); + + let mut g_multiplier = NonNativeFieldMulResultVar::< + ::Fr, + ::Fr, + >::zero(); + let mut g_multiplier_reduced = NonNativeFieldVar::< + ::Fr, + ::Fr, + >::zero(); + for (i, (((c, z), v), proof)) in combined_comms + .iter() + .zip(combined_queries) + .zip(combined_evals) + .zip(proofs) + .enumerate() + { + let z_bits = z.to_bits_le()?; + + let w_times_z = proof.w.scalar_mul_le(z_bits.iter())?; + + let mut c_plus_w_times_z = c.clone(); + c_plus_w_times_z += w_times_z; + + if i != 0 { + let randomizer = batching_rands.remove(0); + let randomizer_bits = batching_rands_bits.remove(0); + + let randomizer_times_v = randomizer.mul_without_reduce(&v)?; + + g_multiplier = g_multiplier + &randomizer_times_v; + + let c_times_randomizer = + c_plus_w_times_z.scalar_mul_le(randomizer_bits.iter())?; + let w_times_randomizer = proof.w.scalar_mul_le(randomizer_bits.iter())?; + total_c += c_times_randomizer; + total_w += w_times_randomizer; + } else { + g_multiplier_reduced += v; + total_c += c_plus_w_times_z; + total_w += proof.w.clone(); + } + } + + // Prepare each input to the pairing. + let (prepared_total_w, prepared_beta_h, prepared_total_c, prepared_h) = { + let g_multiplier_reduced = g_multiplier.reduce()? + &g_multiplier_reduced; + let g_multiplier_bits = g_multiplier_reduced.to_bits_le()?; + + let mut g_times_mul = PG::G1Var::zero(); + { + for (bit, base_power) in g_multiplier_bits + .iter() + .zip(&prepared_verification_key.prepared_g) + { + let mut new_encoded = g_times_mul.clone(); + new_encoded += base_power.clone(); + g_times_mul = + PG::G1Var::conditionally_select(bit, &new_encoded, &g_times_mul)?; + } + } + total_c -= g_times_mul; + total_w = total_w.negate()?; + + let prepared_total_w = PG::prepare_g1(&total_w)?; + let prepared_beta_h = prepared_verification_key.prepared_beta_h.clone(); + let prepared_total_c = PG::prepare_g1(&total_c)?; + let prepared_h = prepared_verification_key.prepared_h.clone(); + + ( + prepared_total_w, + prepared_beta_h, + prepared_total_c, + prepared_h, + ) + }; + + let lhs = PG::product_of_pairings( + &[prepared_total_w, prepared_total_c], + &[prepared_beta_h, prepared_h], + )?; + + println!( + "after PC batch check: constraints: {}", + cs.num_constraints() + ); + + let rhs = &PG::GTVar::one(); + lhs.is_eq(&rhs) + } + } +} + +impl + PCCheckVar< + ::Fr, + MarlinKZG10, + ::Fr, + > for MarlinKZG10Gadget +where + CycleE: CycleEngine, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, +{ + type VerifierKeyVar = VerifierKeyVar; + type PreparedVerifierKeyVar = PreparedVerifierKeyVar; + type CommitmentVar = CommitmentVar; + type PreparedCommitmentVar = PreparedCommitmentVar; + type LabeledCommitmentVar = LabeledCommitmentVar; + type PreparedLabeledCommitmentVar = PreparedLabeledCommitmentVar; + type ProofVar = ProofVar; + type BatchLCProofVar = BatchLCProofVar; + + fn batch_check_evaluations( + _cs: ConstraintSystemRef<::Fr>, + verification_key: &Self::VerifierKeyVar, + commitments: &Vec, + query_set: &QuerySetVar< + ::Fr, + ::Fr, + >, + evaluations: &EvaluationsVar< + ::Fr, + ::Fr, + >, + proofs: &Vec, + opening_challenges: &Vec< + NonNativeFieldVar<::Fr, ::Fr>, + >, + opening_challenges_bits: &Vec::Fr>>>, + batching_rands: &Vec< + NonNativeFieldVar<::Fr, ::Fr>, + >, + batching_rands_bits: &Vec::Fr>>>, + ) -> Result::Fr>, SynthesisError> { + let mut batching_rands = batching_rands.clone(); + let mut batching_rands_bits = batching_rands_bits.clone(); + + let commitments: BTreeMap<_, _> = + commitments.iter().map(|c| (c.label.clone(), c)).collect(); + let mut query_to_labels_map = BTreeMap::new(); + + for (label, (point_label, point)) in query_set.0.iter() { + let labels = query_to_labels_map + .entry((*point_label).clone()) + .or_insert((point, BTreeSet::new())); + labels.1.insert(label); + } + + // Accumulate commitments and evaluations for each query. + let mut combined_queries = Vec::new(); + let mut combined_comms = Vec::new(); + let mut combined_evals = Vec::new(); + for (_point_label, (point, labels)) in query_to_labels_map.into_iter() { + let mut comms_to_combine: Vec = Vec::new(); + let mut values_to_combine = Vec::new(); + for label in labels.into_iter() { + let commitment = commitments.get(label).unwrap().clone(); + let degree_bound = commitment.degree_bound.clone(); + assert_eq!( + degree_bound.is_some(), + commitment.commitment.shifted_comm.is_some() + ); + + let v_i = evaluations.0.get(&(label.clone(), point.clone())).unwrap(); + + comms_to_combine.push(commitment.clone()); + values_to_combine.push(v_i.clone()); + } + + // Accumulate the commitments and evaluations corresponding to `query`. + let mut combined_comm = PG::G1Var::zero(); + let mut combined_eval = NonNativeFieldMulResultVar::< + ::Fr, + ::Fr, + >::zero(); + + let mut opening_challenges_counter = 0; + + for (labeled_commitment, value) in + comms_to_combine.into_iter().zip(values_to_combine.iter()) + { + let challenge = opening_challenges[opening_challenges_counter].clone(); + let challenge_bits = opening_challenges_bits[opening_challenges_counter].clone(); + opening_challenges_counter += 1; + + let LabeledCommitmentVar { + commitment, + degree_bound, + .. + } = labeled_commitment; + let CommitmentVar { shifted_comm, .. } = commitment; + + // To combine the commitments, we multiply each by one of the random challenges, and sum. + combined_comm += commitment.comm.scalar_mul_le(challenge_bits.iter())?; + + // Similarly, we add up the evaluations, multiplied with random challenges. + let value_times_challenge_unreduced = value.mul_without_reduce(&challenge)?; + combined_eval = combined_eval + &value_times_challenge_unreduced; + + // If the degree bound is specified, we include the adjusted degree-shifted commitment + // (that is, c_i' - v_i beta^{D - d_i} G), where d_i is the specific degree bound and + // v_i is the evaluation, in the cocmbined commitment, + if let Some(degree_bound) = degree_bound { + let challenge_shifted_bits = + opening_challenges_bits[opening_challenges_counter].clone(); + opening_challenges_counter += 1; + + let shifted_comm = shifted_comm.as_ref().unwrap().clone(); + + let value_bits = value.to_bits_le()?; + let shift_power = verification_key + .get_shift_power(verification_key.g.cs(), °ree_bound) + .unwrap(); + + let shift_power_times_value = shift_power.scalar_mul_le(value_bits.iter())?; + let mut adjusted_comm = shifted_comm; + adjusted_comm -= shift_power_times_value; + + let adjusted_comm_times_challenge = + adjusted_comm.scalar_mul_le(challenge_shifted_bits.iter())?; + + combined_comm += adjusted_comm_times_challenge; + } + } + + combined_queries.push(point.clone()); + combined_comms.push(combined_comm); + combined_evals.push(combined_eval); + } + + // Perform the batch check. + { + let mut total_c = PG::G1Var::zero(); + let mut total_w = PG::G1Var::zero(); + + let mut g_multiplier = NonNativeFieldMulResultVar::< + ::Fr, + ::Fr, + >::zero(); + for (((c, z), v), proof) in combined_comms + .iter() + .zip(combined_queries) + .zip(combined_evals) + .zip(proofs) + { + let z_bits = z.to_bits_le()?; + + let w_times_z = proof.w.scalar_mul_le(z_bits.iter())?; + let mut c_plus_w_times_z = c.clone(); + c_plus_w_times_z += w_times_z; + + let randomizer = batching_rands.remove(0); + let randomizer_bits = batching_rands_bits.remove(0); + + let v_reduced = v.reduce()?; + let randomizer_times_v = randomizer.mul_without_reduce(&v_reduced)?; + + g_multiplier += randomizer_times_v; + + let c_times_randomizer = c_plus_w_times_z.scalar_mul_le(randomizer_bits.iter())?; + let w_times_randomizer = proof.w.scalar_mul_le(randomizer_bits.iter())?; + total_c += c_times_randomizer; + total_w += w_times_randomizer; + } + + // Prepare each input to the pairing. + let (prepared_total_w, prepared_beta_h, prepared_total_c, prepared_h) = { + let g_multiplier_reduced = g_multiplier.reduce()?; + let g_multiplier_bits = g_multiplier_reduced.to_bits_le()?; + + let g_times_mul = verification_key.g.scalar_mul_le(g_multiplier_bits.iter())?; + total_c -= g_times_mul; + total_w = total_w.negate()?; + + let prepared_total_w = PG::prepare_g1(&total_w)?; + let prepared_beta_h = PG::prepare_g2(&verification_key.beta_h)?; + let prepared_total_c = PG::prepare_g1(&total_c)?; + let prepared_h = PG::prepare_g2(&verification_key.h)?; + + ( + prepared_total_w, + prepared_beta_h, + prepared_total_c, + prepared_h, + ) + }; + + let lhs = PG::product_of_pairings( + &[prepared_total_w, prepared_total_c], + &[prepared_beta_h, prepared_h], + )?; + + let rhs = &PG::GTVar::one(); + + lhs.is_eq(rhs) + } + } + + fn prepared_check_combinations( + cs: ConstraintSystemRef<::Fr>, + prepared_verification_key: &Self::PreparedVerifierKeyVar, + linear_combinations: &Vec< + LinearCombinationVar< + ::Fr, + ::Fr, + >, + >, + prepared_commitments: &Vec, + query_set: &QuerySetVar< + ::Fr, + ::Fr, + >, + evaluations: &EvaluationsVar< + ::Fr, + ::Fr, + >, + proof: &Self::BatchLCProofVar, + opening_challenges: &Vec< + NonNativeFieldVar<::Fr, ::Fr>, + >, + opening_challenges_bits: &Vec::Fr>>>, + batching_rands: &Vec< + NonNativeFieldVar<::Fr, ::Fr>, + >, + batching_rands_bits: &Vec::Fr>>>, + ) -> Result::Fr>, SynthesisError> { + let BatchLCProofVar { proofs, .. } = proof; + + let label_comm_map = prepared_commitments + .iter() + .map(|c| (c.label.clone(), c)) + .collect::>(); + + let mut lc_info = Vec::new(); + let mut evaluations = evaluations.clone(); + + // For each linear combination, we sum up the relevant commitments, multiplied + // with their corresponding coefficients; these combined commitments are then + // the inputs to the normal batch check. + for lc in linear_combinations.iter() { + let lc_label = lc.label.clone(); + let num_polys = lc.terms.len(); + + let mut coeffs_and_comms = Vec::new(); + + for (coeff, label, negate) in lc.terms.iter() { + if label.is_one() { + assert!(coeff.is_some()); + + let coeff = coeff.clone().unwrap(); + + for (&(ref label, _), ref mut eval) in evaluations.0.iter_mut() { + if label == &lc_label { + if negate.eq(&true) { + **eval = (**eval).clone() + &coeff; + } else { + **eval = (**eval).clone() - &coeff; + } + } + } + } else { + let label: &String = label.try_into().unwrap(); + let &cur_comm = label_comm_map.get(label).unwrap(); + + if num_polys == 1 && cur_comm.degree_bound.is_some() { + assert!(coeff.is_none()); + assert!(negate.eq(&false)); + } + + coeffs_and_comms.push(( + coeff.clone(), + cur_comm.degree_bound.clone(), + cur_comm.prepared_commitment.clone(), + negate.clone(), + )); + } + } + + lc_info.push((lc_label, coeffs_and_comms)); + } + + Self::prepared_batch_check_evaluations( + cs, + prepared_verification_key, + &lc_info, + &query_set, + &evaluations, + proofs, + opening_challenges, + opening_challenges_bits, + batching_rands, + batching_rands_bits, + ) + } + + fn create_labeled_commitment_gadget( + label: String, + commitment: Self::CommitmentVar, + degree_bound: Option::Fr>>, + ) -> Self::LabeledCommitmentVar { + Self::LabeledCommitmentVar { + label, + commitment, + degree_bound, + } + } + + fn create_prepared_labeled_commitment_gadget( + label: String, + prepared_commitment: Self::PreparedCommitmentVar, + degree_bound: Option::Fr>>, + ) -> Self::PreparedLabeledCommitmentVar { + Self::PreparedLabeledCommitmentVar { + label, + prepared_commitment, + degree_bound, + } + } +} diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index 501a5f62..38ebaad7 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -13,6 +13,9 @@ use rand_core::RngCore; mod data_structures; pub use data_structures::*; +mod constraints; +pub use constraints::*; + /// Polynomial commitment based on [[KZG10]][kzg], with degree enforcement, batching, /// and (optional) hiding property taken from [[CHMMVW20, “Marlin”]][marlin]. /// diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs new file mode 100644 index 00000000..63c2afd1 --- /dev/null +++ b/src/pc_constraints.rs @@ -0,0 +1,185 @@ +use ark_ff::PrimeField; +use core::marker::Sized; +use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; +use ark_r1cs_std::prelude::*; + +use crate::data_structures::LabeledCommitment; +use crate::{BTreeMap, BTreeSet, LCTerm, LinearCombination, String, Vec}; +use crate::{BatchLCProof, PolynomialCommitment}; +use ark_nonnative_field::NonNativeFieldVar; +use ark_r1cs_std::fields::fp::FpVar; +use std::borrow::Borrow; + +/// A generic gadget for the prepared* structures +pub trait PrepareVar: Sized { + /// prepare from an unprepared element + fn prepare(unprepared: &UNPREPARED) -> Result; + + /// prepare for a smaller field + fn prepare_small(_unprepared: &UNPREPARED) -> Result { + unimplemented!(); + } +} + +/// An allocated version of `LinearCombination`. +pub struct LinearCombinationVar { + /// The label. + pub label: String, + /// The linear combination of `(coeff, poly_label)` pairs. + pub terms: Vec<( + Option>, + LCTerm, + bool, + )>, +} + +impl Clone + for LinearCombinationVar +{ + fn clone(&self) -> Self { + LinearCombinationVar { + label: self.label.clone(), + terms: self.terms.clone(), + } + } +} + +impl + AllocVar, BaseField> + for LinearCombinationVar +{ + fn new_variable( + cs: impl Into>, + val: impl FnOnce() -> Result, + mode: AllocationMode, + ) -> Result + where + T: Borrow>, + { + let LinearCombination { label, terms } = val()?.borrow().clone(); + + let ns = cs.into(); + let cs = ns.cs(); + + let new_terms: Vec<( + Option>, + LCTerm, + bool, + )> = terms + .iter() + .map(|term| { + let (f, lc_term) = term; + + let fg = + NonNativeFieldVar::new_variable(ark_relations::ns!(cs, "term"), || Ok(f), mode) + .unwrap(); + + (Some(fg), lc_term.clone(), false) + }) + .collect(); + + Ok(Self { + label: label.clone(), + terms: new_terms, + }) + } +} + +/// Describes the interface for a gadget for a `PolynomialCommitment` +/// verifier. +pub trait PCCheckVar, ConstraintF: PrimeField>: + Clone +{ + /// An allocated version of `PC::VerifierKey`. + type VerifierKeyVar: AllocVar + Clone + ToBytesGadget; + /// An allocated version of `PC::PreparedVerifierKey`. + type PreparedVerifierKeyVar: AllocVar + + Clone + + PrepareVar; + /// An allocated version of `PC::Commitment`. + type CommitmentVar: AllocVar + Clone + ToBytesGadget; + /// An allocated version of `PC::PreparedCommitment`. + type PreparedCommitmentVar: AllocVar + + PrepareVar + + Clone; + /// An allocated version of `LabeledCommitment`. + type LabeledCommitmentVar: AllocVar, ConstraintF> + Clone; + /// A prepared, allocated version of `LabeledCommitment`. + type PreparedLabeledCommitmentVar: Clone; + /// An allocated version of `PC::Proof`. + type ProofVar: AllocVar + Clone; + + /// An allocated version of `PC::BatchLCProof`. + type BatchLCProofVar: AllocVar, ConstraintF> + Clone; + + /// Add to `ConstraintSystemRef` new constraints that check that `proof_i` is a valid evaluation + /// proof at `point_i` for the polynomial in `commitment_i`. + fn batch_check_evaluations( + cs: ConstraintSystemRef, + verification_key: &Self::VerifierKeyVar, + commitments: &Vec, + query_set: &QuerySetVar, + evaluations: &EvaluationsVar, + proofs: &Vec, + opening_challenges: &Vec>, + opening_challenges_bits: &Vec>>, + batching_rands: &Vec>, + batching_rands_bits: &Vec>>, + ) -> Result, SynthesisError>; + + /// Add to `ConstraintSystemRef` new constraints that conditionally check that `proof` is a valid evaluation + /// proof at the points in `query_set` for the combinations `linear_combinations`. + fn prepared_check_combinations( + cs: ConstraintSystemRef, + prepared_verification_key: &Self::PreparedVerifierKeyVar, + linear_combinations: &Vec>, + prepared_commitments: &Vec, + query_set: &QuerySetVar, + evaluations: &EvaluationsVar, + proof: &Self::BatchLCProofVar, + opening_challenges: &Vec>, + opening_challenges_bits: &Vec>>, + batching_rands: &Vec>, + batching_rands_bits: &Vec>>, + ) -> Result, SynthesisError>; + + /// Create the labeled commitment gadget from the commitment gadget + fn create_labeled_commitment_gadget( + label: String, + commitment: Self::CommitmentVar, + degree_bound: Option>, + ) -> Self::LabeledCommitmentVar; + + /// Create the prepared labeled commitment gadget from the commitment gadget + fn create_prepared_labeled_commitment_gadget( + label: String, + commitment: Self::PreparedCommitmentVar, + degree_bound: Option>, + ) -> Self::PreparedLabeledCommitmentVar; +} + +/// An allocated version of `QuerySet`. +pub struct QuerySetVar( + pub BTreeSet<(String, (String, NonNativeFieldVar))>, +); + +/// An allocated version of `Evaluations`. +#[derive(Clone)] +pub struct EvaluationsVar( + pub BTreeMap< + (String, NonNativeFieldVar), + NonNativeFieldVar, + >, +); + +impl EvaluationsVar { + /// find the evaluation result + pub fn get_lc_eval( + &self, + lc_string: &String, + point: &NonNativeFieldVar, + ) -> Result, SynthesisError> { + let key = (lc_string.clone(), point.clone()); + Ok(self.0.get(&key).map(|v| (*v).clone()).unwrap()) + } +} From 37298abbf52246925a512148d917b16b2fe6f422 Mon Sep 17 00:00:00 2001 From: weikeng Date: Tue, 27 Oct 2020 10:47:18 -0700 Subject: [PATCH 11/56] fix Cargo toml --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f4a516dc..f00ead7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,7 @@ incremental = true debug = true [features] -default = [ "std", "parallel" ] -std = [ "ark-ff/std", "ark-ec/std", "ark-poly/std", "ark-std/std", "ark-serialize/std" ] +default = ["std", "parallel"] +std = [ "ark-ff/std", "ark-ec/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std" ] print-trace = [ "bench-utils/print-trace" ] parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ] From beee357e3b125b441fc3ee5d81d888b7327782f7 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 27 Oct 2020 14:02:36 -0700 Subject: [PATCH 12/56] Default, Clone, ToConstraintField impls --- src/data_structures.rs | 10 +++++++++- src/lib.rs | 14 +++++++++++--- src/marlin_pc/data_structures.rs | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/data_structures.rs b/src/data_structures.rs index 2dc0cdfd..27a28981 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -1,5 +1,5 @@ use crate::{Rc, String, Vec}; -use ark_ff::Field; +use ark_ff::{Field, ToConstraintField}; pub use ark_poly::DensePolynomial as Polynomial; use core::borrow::Borrow; use core::ops::{AddAssign, MulAssign, SubAssign}; @@ -184,6 +184,14 @@ impl LabeledCommitment { } } +impl> ToConstraintField + for LabeledCommitment +{ + fn to_field_elements(&self) -> Option> { + self.commitment.to_field_elements() + } +} + impl ark_ff::ToBytes for LabeledCommitment { #[inline] fn write(&self, writer: W) -> ark_std::io::Result<()> { diff --git a/src/lib.rs b/src/lib.rs index 6728902d..9208a2eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -99,7 +99,6 @@ pub type QuerySet<'a, F> = BTreeSet<(String, (String, F))>; pub type Evaluations<'a, F> = BTreeMap<(String, F), F>; /// A proof of satisfaction of linear combinations. -#[derive(Clone)] pub struct BatchLCProof> { /// Evaluation proof. pub proof: PC::BatchProof, @@ -107,6 +106,15 @@ pub struct BatchLCProof> { pub evals: Option>, } +impl> Clone for BatchLCProof { + fn clone(&self) -> Self { + BatchLCProof { + proof: self.proof.clone(), + evals: self.evals.clone(), + } + } +} + /// Describes the interface for a polynomial commitment scheme that allows /// a sender to commit to multiple polynomials and later provide a succinct proof /// of evaluation for the corresponding commitments at a query set `Q`, while @@ -119,9 +127,9 @@ pub trait PolynomialCommitment: Sized { /// open the commitment to produce an evaluation proof. type CommitterKey: PCCommitterKey; /// The verifier key for the scheme; used to check an evaluation proof. - type VerifierKey: PCVerifierKey; + type VerifierKey: PCVerifierKey + Default; /// The prepared verifier key for the scheme; used to check an evaluation proof. - type PreparedVerifierKey: PCPreparedVerifierKey + Clone; + type PreparedVerifierKey: PCPreparedVerifierKey + Default + Clone; /// The commitment to a polynomial. type Commitment: PCCommitment + Default; /// The prepared commitment to a polynomial. diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index c2ae690c..9ad24123 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -148,7 +148,7 @@ impl ToBytes for VerifierKey { /// `PreparedVerifierKey` is used to check evaluation proofs for a given commitment. #[derive(Derivative)] -#[derivative(Clone(bound = ""), Debug(bound = ""))] +#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))] pub struct PreparedVerifierKey { /// The verification key for the underlying KZG10 scheme. pub prepared_vk: kzg10::PreparedVerifierKey, From fdf166862b518ccb9dec04c0831605784d442689 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 27 Oct 2020 14:07:40 -0700 Subject: [PATCH 13/56] cargo fmt --- src/marlin_pc/constraints.rs | 7 ++++--- src/pc_constraints.rs | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index 2c5a22ec..4ae74214 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -10,9 +10,7 @@ use crate::{ }; use ark_ec::{CycleEngine, PairingEngine}; use ark_ff::{fields::Field, PrimeField, ToConstraintField}; -use core::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::MulAssign}; use ark_nonnative_field::{NonNativeFieldMulResultVar, NonNativeFieldVar}; -use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; use ark_r1cs_std::{ alloc::{AllocVar, AllocationMode}, bits::{boolean::Boolean, uint8::UInt8, ToBitsGadget}, @@ -23,6 +21,8 @@ use ark_r1cs_std::{ select::CondSelectGadget, R1CSVar, ToBytesGadget, ToConstraintFieldGadget, }; +use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; +use core::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::MulAssign}; /// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. pub struct VerifierKeyVar< @@ -216,7 +216,8 @@ where let g = PG::G1Var::new_variable(ark_relations::ns!(cs, "g"), || Ok(g.clone()), mode)?; let h = PG::G2Var::new_variable(ark_relations::ns!(cs, "h"), || Ok(h.clone()), mode)?; - let beta_h = PG::G2Var::new_variable(ark_relations::ns!(cs, "beta_h"), || Ok(beta_h), mode)?; + let beta_h = + PG::G2Var::new_variable(ark_relations::ns!(cs, "beta_h"), || Ok(beta_h), mode)?; Ok(Self { g, diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs index 63c2afd1..288b086c 100644 --- a/src/pc_constraints.rs +++ b/src/pc_constraints.rs @@ -1,7 +1,7 @@ use ark_ff::PrimeField; -use core::marker::Sized; -use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; use ark_r1cs_std::prelude::*; +use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; +use core::marker::Sized; use crate::data_structures::LabeledCommitment; use crate::{BTreeMap, BTreeSet, LCTerm, LinearCombination, String, Vec}; From d04a9e9e7f7b71c79d90f035fa11a7396b098ff1 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 3 Nov 2020 10:55:28 -0800 Subject: [PATCH 14/56] cargo fmt --- src/marlin_pc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index 38ebaad7..cb11256e 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -5,7 +5,7 @@ use crate::{LabeledCommitment, LabeledPolynomial, LinearCombination}; use crate::{PCRandomness, PCUniversalParams, Polynomial, PolynomialCommitment}; use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{One, Zero, Field}; +use ark_ff::{Field, One, Zero}; use ark_std::vec; use core::{convert::TryInto, marker::PhantomData}; use rand_core::RngCore; From 8f17d500fe708a5c16b7dab2b06463ce53b4faef Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 3 Nov 2020 11:38:54 -0800 Subject: [PATCH 15/56] fixes --- Cargo.toml | 2 + src/lib.rs | 211 ++++++++++------------------------- src/marlin_pc/constraints.rs | 14 ++- src/pc_constraints.rs | 9 +- 4 files changed, 73 insertions(+), 163 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f00ead7f..9f486f33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,8 @@ ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" } +ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative" } + bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } rand_core = { version = "0.5", default-features = false } diff --git a/src/lib.rs b/src/lib.rs index 9208a2eb..657659ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -588,173 +588,78 @@ pub trait PolynomialCommitment: Sized { Ok(true) } - /// open but with individual challenges - /// the non-individual version `open` should call this method with - /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, - /// i.e., the same impl as in MarlinKZG. - fn open_individual_opening_challenges<'a>( + /// batch_open with individual challenges + fn batch_open_individual_opening_challenges<'a>( ck: &Self::CommitterKey, labeled_polynomials: impl IntoIterator>, commitments: impl IntoIterator>, - point: F, - opening_challenges: &dyn Fn(usize) -> F, + query_set: &QuerySet, + opening_challenges: &dyn Fn(u64) -> F, rands: impl IntoIterator, rng: Option<&mut dyn RngCore>, - ) -> Result + ) -> Result where Self::Randomness: 'a, Self::Commitment: 'a, { - Self::open( - ck, - labeled_polynomials, - commitments, - point, - opening_challenges(0), - rands, - rng, - ) - } + let rng = &mut crate::optional_rng::OptionalRng(rng); + let poly_rand_comm: BTreeMap<_, _> = labeled_polynomials + .into_iter() + .zip(rands) + .zip(commitments.into_iter()) + .map(|((poly, r), comm)| (poly.label(), (poly, r, comm))) + .collect(); - /// check but with individual challenges - /// The non-individual version `check` should call this method with - /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, - /// i.e., the same impl as in MarlinKZG. - fn check_individual_opening_challenges<'a>( - vk: &Self::VerifierKey, - commitments: impl IntoIterator>, - point: F, - values: impl IntoIterator, - proof: &Self::Proof, - opening_challenges: &dyn Fn(usize) -> F, - rng: Option<&mut dyn RngCore>, - ) -> Result - where - Self::Commitment: 'a, - { - Self::check( - vk, - commitments, - point, - values, - proof, - opening_challenges(0), - rng, - ) - } + let open_time = start_timer!(|| format!( + "Opening {} polynomials at query set of size {}", + poly_rand_comm.len(), + query_set.len(), + )); - /// batch_check but with individual challenges - /// The non-individual version `batch_check` should call this method with - /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, - /// i.e., the same impl as in MarlinKZG. - fn batch_check_individual_opening_challenges<'a, R: RngCore>( - vk: &Self::VerifierKey, - commitments: impl IntoIterator>, - query_set: &QuerySet, - evaluations: &Evaluations, - proof: &Self::BatchProof, - opening_challenges: &dyn Fn(usize) -> F, - rng: &mut R, - ) -> Result - where - Self::Commitment: 'a, - { - Self::batch_check( - vk, - commitments, - query_set, - evaluations, - proof, - opening_challenges(0), - rng, - ) - } + let mut query_to_labels_map = BTreeMap::new(); - /// open_combinations but with individual challenges - /// The non-individual version `open_combinations` should call this method with - /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, - /// i.e., the same impl as in MarlinKZG. - fn open_combinations_individual_opening_challenges<'a>( - ck: &Self::CommitterKey, - lc_s: impl IntoIterator>, - polynomials: impl IntoIterator>, - commitments: impl IntoIterator>, - query_set: &QuerySet, - opening_challenges: &dyn Fn(usize) -> F, - rands: impl IntoIterator, - rng: Option<&mut dyn RngCore>, - ) -> Result, Self::Error> - where - Self::Randomness: 'a, - Self::Commitment: 'a, - { - Self::open_combinations( - ck, - lc_s, - polynomials, - commitments, - query_set, - opening_challenges(0), - rands, - rng, - ) - } + for (label, (point_label, point)) in query_set.iter() { + let labels = query_to_labels_map + .entry(point_label) + .or_insert((point, BTreeSet::new())); + labels.1.insert(label); + } - /// check_combinations but with individual challenges - /// The non-individual version `check_combinations` should call this method with - /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, - /// i.e., the same impl as in MarlinKZG. - fn check_combinations_individual_opening_challenges<'a, R: RngCore>( - vk: &Self::VerifierKey, - lc_s: impl IntoIterator>, - commitments: impl IntoIterator>, - query_set: &QuerySet, - evaluations: &Evaluations, - proof: &BatchLCProof, - opening_challenges: &dyn Fn(usize) -> F, - rng: &mut R, - ) -> Result - where - Self::Commitment: 'a, - { - Self::check_combinations( - vk, - lc_s, - commitments, - query_set, - evaluations, - proof, - opening_challenges(0), - rng, - ) - } + let mut proofs = Vec::new(); + for (_point_label, (point, labels)) in query_to_labels_map.into_iter() { + let mut query_polys: Vec<&'a LabeledPolynomial<_>> = Vec::new(); + let mut query_rands: Vec<&'a Self::Randomness> = Vec::new(); + let mut query_comms: Vec<&'a LabeledCommitment> = Vec::new(); - /// batch_open but with individual challenges - /// The non-individual version `batch_open` should call this method with - /// `opening_challenges = |pow| opening_challenge.pow(&[pow]);`, - /// i.e., the same impl as in MarlinKZG. - fn batch_open_individual_opening_challenges<'a>( - ck: &Self::CommitterKey, - labeled_polynomials: impl IntoIterator>, - commitments: impl IntoIterator>, - query_set: &QuerySet, - opening_challenges: &dyn Fn(u64) -> F, - rands: impl IntoIterator, - rng: Option<&mut dyn RngCore>, - ) -> Result - where - Self::Randomness: 'a, - Self::Commitment: 'a, - { - Self::batch_open( - ck, - labeled_polynomials, - commitments, - query_set, - opening_challenges(0), - rands, - rng, - ) + for label in labels { + let (polynomial, rand, comm) = + poly_rand_comm.get(label).ok_or(Error::MissingPolynomial { + label: label.to_string(), + })?; + + query_polys.push(polynomial); + query_rands.push(rand); + query_comms.push(comm); + } + + let proof_time = start_timer!(|| "Creating proof"); + let proof = Self::open_individual_opening_challenges( + ck, + query_polys, + query_comms, + *point, + opening_challenges, + query_rands, + Some(rng), + )?; + + end_timer!(proof_time); + + proofs.push(proof); + } + end_timer!(open_time); + + Ok(proofs.into()) } } diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index 4ae74214..e56d62a4 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -1348,7 +1348,7 @@ where let mut combined_queries = Vec::new(); let mut combined_comms = Vec::new(); let mut combined_evals = Vec::new(); - for (_point_label, (point, labels)) in query_to_labels_map.into_iter() { + for (point_label, (point, labels)) in query_to_labels_map.into_iter() { let mut comms_to_combine = Vec::< Vec<( Option< @@ -1366,7 +1366,10 @@ where for label in labels.into_iter() { let commitment_lc = commitment_lcs.get(label).unwrap().clone(); - let v_i = evaluations.0.get(&(label.clone(), point.clone())).unwrap(); + let v_i = evaluations + .0 + .get(&(label.clone(), point_label.clone())) + .unwrap(); comms_to_combine.push(commitment_lc.1.clone()); values_to_combine.push(v_i.clone()); @@ -1659,7 +1662,7 @@ where let mut combined_queries = Vec::new(); let mut combined_comms = Vec::new(); let mut combined_evals = Vec::new(); - for (_point_label, (point, labels)) in query_to_labels_map.into_iter() { + for (point_label, (point, labels)) in query_to_labels_map.into_iter() { let mut comms_to_combine: Vec = Vec::new(); let mut values_to_combine = Vec::new(); for label in labels.into_iter() { @@ -1670,7 +1673,10 @@ where commitment.commitment.shifted_comm.is_some() ); - let v_i = evaluations.0.get(&(label.clone(), point.clone())).unwrap(); + let v_i = evaluations + .0 + .get(&(label.clone(), point_label.clone())) + .unwrap(); comms_to_combine.push(commitment.clone()); values_to_combine.push(v_i.clone()); diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs index 288b086c..72023a64 100644 --- a/src/pc_constraints.rs +++ b/src/pc_constraints.rs @@ -166,10 +166,7 @@ pub struct QuerySetVar( /// An allocated version of `Evaluations`. #[derive(Clone)] pub struct EvaluationsVar( - pub BTreeMap< - (String, NonNativeFieldVar), - NonNativeFieldVar, - >, + pub BTreeMap<(String, String), NonNativeFieldVar>, ); impl EvaluationsVar { @@ -177,9 +174,9 @@ impl EvaluationsVar, + point_label: &String, ) -> Result, SynthesisError> { - let key = (lc_string.clone(), point.clone()); + let key = (lc_string.clone(), point_label.clone()); Ok(self.0.get(&key).map(|v| (*v).clone()).unwrap()) } } From 5e2ac2ed3790ccf0b85d8061b9f2c94a77966b4a Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 4 Nov 2020 13:27:35 -0800 Subject: [PATCH 16/56] used HashMap instead of BTreeMap --- Cargo.toml | 1 + src/lib.rs | 3 ++- src/marlin_pc/constraints.rs | 14 ++++---------- src/pc_constraints.rs | 12 ++++++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9f486f33..45f3080c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ rand_core = { version = "0.5", default-features = false } digest = "0.8" rayon = { version = "1", optional = true } derivative = { version = "2", features = [ "use_core" ] } +hashbrown = "0.9" [dev-dependencies] rand = { version = "0.7", default-features = false } diff --git a/src/lib.rs b/src/lib.rs index 657659ae..87f98bb5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,7 @@ use ark_std::{ string::{String, ToString}, vec::Vec, }; +use hashbrown::HashMap; /// Data structures used by a polynomial commitment scheme. pub mod data_structures; @@ -96,7 +97,7 @@ pub type QuerySet<'a, F> = BTreeSet<(String, (String, F))>; /// `p` at a `QuerySet` `Q`. It maps each element of `Q` to the resulting evaluation. /// That is, if `(label, query)` is an element of `Q`, then `evaluation.get((label, query))` /// should equal `p[label].evaluate(query)`. -pub type Evaluations<'a, F> = BTreeMap<(String, F), F>; +pub type Evaluations<'a, F> = HashMap<(String, F), F>; /// A proof of satisfaction of linear combinations. pub struct BatchLCProof> { diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index e56d62a4..720b3eab 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -1348,7 +1348,7 @@ where let mut combined_queries = Vec::new(); let mut combined_comms = Vec::new(); let mut combined_evals = Vec::new(); - for (point_label, (point, labels)) in query_to_labels_map.into_iter() { + for (_, (point, labels)) in query_to_labels_map.into_iter() { let mut comms_to_combine = Vec::< Vec<( Option< @@ -1366,10 +1366,7 @@ where for label in labels.into_iter() { let commitment_lc = commitment_lcs.get(label).unwrap().clone(); - let v_i = evaluations - .0 - .get(&(label.clone(), point_label.clone())) - .unwrap(); + let v_i = evaluations.0.get(&(label.clone(), point.clone())).unwrap(); comms_to_combine.push(commitment_lc.1.clone()); values_to_combine.push(v_i.clone()); @@ -1662,7 +1659,7 @@ where let mut combined_queries = Vec::new(); let mut combined_comms = Vec::new(); let mut combined_evals = Vec::new(); - for (point_label, (point, labels)) in query_to_labels_map.into_iter() { + for (_, (point, labels)) in query_to_labels_map.into_iter() { let mut comms_to_combine: Vec = Vec::new(); let mut values_to_combine = Vec::new(); for label in labels.into_iter() { @@ -1673,10 +1670,7 @@ where commitment.commitment.shifted_comm.is_some() ); - let v_i = evaluations - .0 - .get(&(label.clone(), point_label.clone())) - .unwrap(); + let v_i = evaluations.0.get(&(label.clone(), point.clone())).unwrap(); comms_to_combine.push(commitment.clone()); values_to_combine.push(v_i.clone()); diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs index 72023a64..b0081c6a 100644 --- a/src/pc_constraints.rs +++ b/src/pc_constraints.rs @@ -4,10 +4,11 @@ use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; use core::marker::Sized; use crate::data_structures::LabeledCommitment; -use crate::{BTreeMap, BTreeSet, LCTerm, LinearCombination, String, Vec}; +use crate::{BTreeSet, LCTerm, LinearCombination, String, Vec}; use crate::{BatchLCProof, PolynomialCommitment}; use ark_nonnative_field::NonNativeFieldVar; use ark_r1cs_std::fields::fp::FpVar; +use hashbrown::HashMap; use std::borrow::Borrow; /// A generic gadget for the prepared* structures @@ -166,7 +167,10 @@ pub struct QuerySetVar( /// An allocated version of `Evaluations`. #[derive(Clone)] pub struct EvaluationsVar( - pub BTreeMap<(String, String), NonNativeFieldVar>, + pub HashMap< + (String, NonNativeFieldVar), + NonNativeFieldVar, + >, ); impl EvaluationsVar { @@ -174,9 +178,9 @@ impl EvaluationsVar, ) -> Result, SynthesisError> { - let key = (lc_string.clone(), point_label.clone()); + let key = (lc_string.clone(), point.clone()); Ok(self.0.get(&key).map(|v| (*v).clone()).unwrap()) } } From 1b7617f65dfbbd224fb016a9c81bc7b5fee23579 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 4 Nov 2020 14:04:29 -0800 Subject: [PATCH 17/56] using HashMap and HashSet --- src/lib.rs | 4 ++-- src/pc_constraints.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 87f98bb5..6a28bc8d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,7 +26,7 @@ use ark_std::{ string::{String, ToString}, vec::Vec, }; -use hashbrown::HashMap; +use hashbrown::{HashMap, HashSet}; /// Data structures used by a polynomial commitment scheme. pub mod data_structures; @@ -91,7 +91,7 @@ pub mod ipa_pc; /// `(label, (point_label, point))`, where `label` is the label of a polynomial in `p`, /// `point_label` is the label for the point (e.g., "beta"), and and `point` is the field element /// that `p[label]` is to be queried at. -pub type QuerySet<'a, F> = BTreeSet<(String, (String, F))>; +pub type QuerySet<'a, F> = HashSet<(String, (String, F))>; /// `Evaluations` is the result of querying a set of labeled polynomials or equations /// `p` at a `QuerySet` `Q`. It maps each element of `Q` to the resulting evaluation. diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs index b0081c6a..e34f9be1 100644 --- a/src/pc_constraints.rs +++ b/src/pc_constraints.rs @@ -4,11 +4,11 @@ use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; use core::marker::Sized; use crate::data_structures::LabeledCommitment; -use crate::{BTreeSet, LCTerm, LinearCombination, String, Vec}; use crate::{BatchLCProof, PolynomialCommitment}; +use crate::{LCTerm, LinearCombination, String, Vec}; use ark_nonnative_field::NonNativeFieldVar; use ark_r1cs_std::fields::fp::FpVar; -use hashbrown::HashMap; +use hashbrown::{HashMap, HashSet}; use std::borrow::Borrow; /// A generic gadget for the prepared* structures @@ -161,7 +161,7 @@ pub trait PCCheckVar, ConstraintF /// An allocated version of `QuerySet`. pub struct QuerySetVar( - pub BTreeSet<(String, (String, NonNativeFieldVar))>, + pub HashSet<(String, (String, NonNativeFieldVar))>, ); /// An allocated version of `Evaluations`. From e17ce7de50bc06a41d8801a9659407de588b1026 Mon Sep 17 00:00:00 2001 From: Weikeng Chen Date: Wed, 4 Nov 2020 14:22:29 -0800 Subject: [PATCH 18/56] Update Cargo.toml --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 45f3080c..623ae5dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,9 +30,9 @@ ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = fal ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features = false } -ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" } +ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std", default-features = false } -ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative" } +ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative", default-features = false } bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } @@ -63,6 +63,6 @@ debug = true [features] default = ["std", "parallel"] -std = [ "ark-ff/std", "ark-ec/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std" ] +std = [ "ark-ff/std", "ark-ec/std", "ark-nonnative-field/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std" ] print-trace = [ "bench-utils/print-trace" ] parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ] From 13c2ca0b9ed4a3ffd73343865fc419d6cfbffed6 Mon Sep 17 00:00:00 2001 From: Weikeng Chen Date: Wed, 4 Nov 2020 14:26:06 -0800 Subject: [PATCH 19/56] Update pc_constraints.rs --- src/pc_constraints.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs index e34f9be1..d6407a4d 100644 --- a/src/pc_constraints.rs +++ b/src/pc_constraints.rs @@ -1,7 +1,7 @@ use ark_ff::PrimeField; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; -use core::marker::Sized; +use core::{borrow::Borrow, marker::Sized}; use crate::data_structures::LabeledCommitment; use crate::{BatchLCProof, PolynomialCommitment}; @@ -9,7 +9,6 @@ use crate::{LCTerm, LinearCombination, String, Vec}; use ark_nonnative_field::NonNativeFieldVar; use ark_r1cs_std::fields::fp::FpVar; use hashbrown::{HashMap, HashSet}; -use std::borrow::Borrow; /// A generic gadget for the prepared* structures pub trait PrepareVar: Sized { From f080e51d722ff6784890b29ecf6159697d51f5ca Mon Sep 17 00:00:00 2001 From: weikeng Date: Wed, 4 Nov 2020 14:35:36 -0800 Subject: [PATCH 20/56] fix nostd --- src/lib.rs | 1 + src/marlin_pc/constraints.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 6a28bc8d..f9cf087a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,7 @@ use ark_std::{ collections::{BTreeMap, BTreeSet}, rc::Rc, string::{String, ToString}, + vec, vec::Vec, }; use hashbrown::{HashMap, HashSet}; diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index 720b3eab..570e2624 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -6,7 +6,7 @@ use crate::{ MarlinKZG10, PreparedCommitment, PreparedVerifierKey, }, pc_constraints::{EvaluationsVar, PCCheckVar, QuerySetVar}, - BTreeMap, BTreeSet, BatchLCProof, LinearCombinationVar, PrepareVar, String, ToString, Vec, + vec, BTreeMap, BTreeSet, BatchLCProof, LinearCombinationVar, PrepareVar, String, ToString, Vec, }; use ark_ec::{CycleEngine, PairingEngine}; use ark_ff::{fields::Field, PrimeField, ToConstraintField}; From 88306f9195e5a7a09659a1bd7dcbb464cfa14a53 Mon Sep 17 00:00:00 2001 From: weikeng Date: Wed, 11 Nov 2020 23:05:05 -0800 Subject: [PATCH 21/56] add density-optimized; clippy --- Cargo.toml | 4 +- src/data_structures.rs | 10 +- src/ipa_pc/data_structures.rs | 2 +- src/ipa_pc/mod.rs | 49 +++--- src/kzg10/data_structures.rs | 4 +- src/kzg10/mod.rs | 9 +- src/lib.rs | 12 +- src/marlin_pc/constraints.rs | 248 +++++++++++++++---------------- src/marlin_pc/data_structures.rs | 18 +-- src/marlin_pc/mod.rs | 35 ++--- src/pc_constraints.rs | 47 +++--- src/sonic_pc/data_structures.rs | 4 +- src/sonic_pc/mod.rs | 20 +-- 13 files changed, 230 insertions(+), 232 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 623ae5dc..b5e886e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,11 +27,8 @@ ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = fa ark-poly = { git = "https://github.com/arkworks-rs/algebra", default-features = false } ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false } - ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features = false } - ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std", default-features = false } - ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative", default-features = false } bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } @@ -66,3 +63,4 @@ default = ["std", "parallel"] std = [ "ark-ff/std", "ark-ec/std", "ark-nonnative-field/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std" ] print-trace = [ "bench-utils/print-trace" ] parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ] +density-optimized = [ "ark-nonnative-field/density-optimized" ] diff --git a/src/data_structures.rs b/src/data_structures.rs index 27a28981..75739172 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -212,11 +212,7 @@ impl LCTerm { /// Returns `true` if `self == LCTerm::One` #[inline] pub fn is_one(&self) -> bool { - if let LCTerm::One = self { - true - } else { - false - } + matches!(self, LCTerm::One) } } @@ -286,7 +282,7 @@ impl LinearCombination { let terms = terms.into_iter().map(|(c, t)| (c, t.into())).collect(); Self { label: label.into(), - terms: terms, + terms, } } @@ -308,6 +304,7 @@ impl LinearCombination { } impl<'a, F: Field> AddAssign<(F, &'a LinearCombination)> for LinearCombination { + #[allow(clippy::suspicious_op_assign_impl)] fn add_assign(&mut self, (coeff, other): (F, &'a LinearCombination)) { self.terms .extend(other.terms.iter().map(|(c, t)| (coeff * c, t.clone()))); @@ -315,6 +312,7 @@ impl<'a, F: Field> AddAssign<(F, &'a LinearCombination)> for LinearCombinatio } impl<'a, F: Field> SubAssign<(F, &'a LinearCombination)> for LinearCombination { + #[allow(clippy::suspicious_op_assign_impl)] fn sub_assign(&mut self, (coeff, other): (F, &'a LinearCombination)) { self.terms .extend(other.terms.iter().map(|(c, t)| (-coeff * c, t.clone()))); diff --git a/src/ipa_pc/data_structures.rs b/src/ipa_pc/data_structures.rs index 2e1b5c01..aadcf990 100644 --- a/src/ipa_pc/data_structures.rs +++ b/src/ipa_pc/data_structures.rs @@ -140,7 +140,7 @@ pub type PreparedCommitment = Commitment; impl PCPreparedCommitment> for PreparedCommitment { /// prepare `PreparedCommitment` from `Commitment` fn prepare(vk: &Commitment) -> Self { - vk.clone() + *vk } } diff --git a/src/ipa_pc/mod.rs b/src/ipa_pc/mod.rs index 36c1285d..054d6acf 100644 --- a/src/ipa_pc/mod.rs +++ b/src/ipa_pc/mod.rs @@ -53,9 +53,9 @@ impl InnerProductArgPC { let mut comm = VariableBaseMSM::multi_scalar_mul(comm_key, &scalars_bigint); - if randomizer.is_some() { + if let Some(randomizer) = randomizer { assert!(hiding_generator.is_some()); - comm += &hiding_generator.unwrap().mul(randomizer.unwrap()); + comm += &hiding_generator.unwrap().mul(randomizer); } comm @@ -168,8 +168,8 @@ impl InnerProductArgPC { let h_prime = h_prime.into_affine(); let check_commitment_elem: G::Projective = Self::cm_commit( - &[proof.final_comm_key.clone(), h_prime], - &[proof.c.clone(), v_prime], + &[proof.final_comm_key, h_prime], + &[proof.c, v_prime], None, None, ); @@ -259,21 +259,21 @@ impl InnerProductArgPC { let mut commitments = Vec::new(); let mut i = 0; - for info in lc_info.into_iter() { + for info in lc_info.iter() { let commitment; let label = info.0.clone(); let degree_bound = info.1; if degree_bound.is_some() { commitment = Commitment { - comm: comms[i].clone(), - shifted_comm: Some(comms[i + 1].clone()), + comm: comms[i], + shifted_comm: Some(comms[i + 1]), }; i += 2; } else { commitment = Commitment { - comm: comms[i].clone(), + comm: comms[i], shifted_comm: None, }; @@ -283,7 +283,7 @@ impl InnerProductArgPC { commitments.push(LabeledCommitment::new(label, commitment, degree_bound)); } - return commitments; + commitments } fn sample_generators(num_generators: usize) -> Vec { @@ -359,15 +359,15 @@ impl PolynomialCommitment for InnerPr let ck = CommitterKey { comm_key: pp.comm_key[0..(supported_degree + 1)].to_vec(), - h: pp.h.clone(), - s: pp.s.clone(), + h: pp.h, + s: pp.s, max_degree: pp.max_degree(), }; let vk = VerifierKey { comm_key: pp.comm_key[0..(supported_degree + 1)].to_vec(), - h: pp.h.clone(), - s: pp.s.clone(), + h: pp.h, + s: pp.s, max_degree: pp.max_degree(), }; @@ -377,6 +377,7 @@ impl PolynomialCommitment for InnerPr } /// Outputs a commitment to `polynomial`. + #[allow(clippy::type_complexity)] fn commit<'a>( ck: &Self::CommitterKey, polynomials: impl IntoIterator>, @@ -538,10 +539,10 @@ impl PolynomialCommitment for InnerPr let combined_v = combined_polynomial.evaluate(point); // Pad the coefficients to the appropriate vector size - let d = ck.supported_degree(); + let degree = ck.supported_degree(); // `log_d` is ceil(log2 (d + 1)), which is the number of steps to compute all of the challenges - let log_d = ark_std::log2(d + 1) as usize; + let log_d = ark_std::log2(degree + 1) as usize; let mut combined_commitment; let mut hiding_commitment = None; @@ -549,7 +550,7 @@ impl PolynomialCommitment for InnerPr if has_hiding { let mut rng = rng.expect("hiding commitments require randomness"); let hiding_time = start_timer!(|| "Applying hiding."); - let mut hiding_polynomial = Polynomial::rand(d, &mut rng); + let mut hiding_polynomial = Polynomial::rand(degree, &mut rng); hiding_polynomial -= &Polynomial::from_coefficients_slice(&[hiding_polynomial.evaluate(point)]); @@ -591,8 +592,10 @@ impl PolynomialCommitment for InnerPr None }; - let proof_time = - start_timer!(|| format!("Generating proof for degree {} combined polynomial", d + 1)); + let proof_time = start_timer!(|| format!( + "Generating proof for degree {} combined polynomial", + degree + 1 + )); combined_commitment = combined_commitment_proj.into_affine(); @@ -605,17 +608,17 @@ impl PolynomialCommitment for InnerPr // Pads the coefficients with zeroes to get the number of coeff to be d+1 let mut coeffs = combined_polynomial.coeffs; - if coeffs.len() < d + 1 { - for _ in coeffs.len()..(d + 1) { + if coeffs.len() < degree + 1 { + for _ in coeffs.len()..(degree + 1) { coeffs.push(G::ScalarField::zero()); } } let mut coeffs = coeffs.as_mut_slice(); // Powers of z - let mut z: Vec = Vec::with_capacity(d + 1); + let mut z: Vec = Vec::with_capacity(degree + 1); let mut cur_z: G::ScalarField = G::ScalarField::one(); - for _ in 0..(d + 1) { + for _ in 0..(degree + 1) { z.push(cur_z); cur_z *= &point; } @@ -634,7 +637,7 @@ impl PolynomialCommitment for InnerPr let mut l_vec = Vec::with_capacity(log_d); let mut r_vec = Vec::with_capacity(log_d); - let mut n = d + 1; + let mut n = degree + 1; while n > 1 { let (coeffs_l, coeffs_r) = coeffs.split_at_mut(n / 2); let (z_l, z_r) = z.split_at_mut(n / 2); diff --git a/src/kzg10/data_structures.rs b/src/kzg10/data_structures.rs index 62eb2dff..35d5f838 100644 --- a/src/kzg10/data_structures.rs +++ b/src/kzg10/data_structures.rs @@ -106,7 +106,7 @@ impl PreparedVerifierKey { let supported_bits = E::Fr::size_in_bits(); let mut prepared_g = Vec::::new(); - let mut g = E::G1Projective::from(vk.g.clone()); + let mut g = E::G1Projective::from(vk.g); for _ in 0..supported_bits { prepared_g.push(g.clone().into()); g.double_in_place(); @@ -186,7 +186,7 @@ impl PreparedCommitment { /// prepare `PreparedCommitment` from `Commitment` pub fn prepare(comm: &Commitment) -> Self { let mut prepared_comm = Vec::::new(); - let mut cur = E::G1Projective::from(comm.0.clone()); + let mut cur = E::G1Projective::from(comm.0); let supported_bits = E::Fr::size_in_bits(); diff --git a/src/kzg10/mod.rs b/src/kzg10/mod.rs index f07c65e7..6a8b1bce 100644 --- a/src/kzg10/mod.rs +++ b/src/kzg10/mod.rs @@ -196,6 +196,7 @@ impl KZG10 { /// The witness polynomial w(x) the quotient of the division (p(x) - p(z)) / (x - z) /// Observe that this quotient does not change with z because /// p(z) is the remainder term. We can therefore omit p(z) when computing the quotient. + #[allow(clippy::type_complexity)] pub fn compute_witness_polynomial( p: &Polynomial, point: E::Fr, @@ -221,7 +222,7 @@ impl KZG10 { Ok((witness_polynomial, random_witness_polynomial)) } - pub(crate) fn open_with_witness_polynomial<'a>( + pub(crate) fn open_with_witness_polynomial( powers: &Powers, point: E::Fr, randomness: &Randomness, @@ -265,7 +266,7 @@ impl KZG10 { } /// On input a polynomial `p` and a point `point`, outputs a proof for the same. - pub(crate) fn open<'a>( + pub(crate) fn open( powers: &Powers, p: &Polynomial, point: E::Fr, @@ -430,12 +431,12 @@ impl KZG10 { if enforced_degree_bounds.binary_search(&bound).is_err() { Err(Error::UnsupportedDegreeBound(bound)) } else if bound < p.degree() || bound > max_degree { - return Err(Error::IncorrectDegreeBound { + Err(Error::IncorrectDegreeBound { poly_degree: p.degree(), degree_bound: p.degree_bound().unwrap(), supported_degree, label: p.label().to_string(), - }); + }) } else { Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index f9cf087a..1211fc4f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ #![deny(renamed_and_removed_lints, stable_features, unused_allocation)] #![deny(unused_comparisons, bare_trait_objects, unused_must_use, const_err)] #![forbid(unsafe_code)] +#![allow(clippy::op_ref)] #[macro_use] extern crate derivative; @@ -129,9 +130,9 @@ pub trait PolynomialCommitment: Sized { /// open the commitment to produce an evaluation proof. type CommitterKey: PCCommitterKey; /// The verifier key for the scheme; used to check an evaluation proof. - type VerifierKey: PCVerifierKey + Default; + type VerifierKey: PCVerifierKey; /// The prepared verifier key for the scheme; used to check an evaluation proof. - type PreparedVerifierKey: PCPreparedVerifierKey + Default + Clone; + type PreparedVerifierKey: PCPreparedVerifierKey + Clone; /// The commitment to a polynomial. type Commitment: PCCommitment + Default; /// The prepared commitment to a polynomial. @@ -170,6 +171,7 @@ pub trait PolynomialCommitment: Sized { /// /// If for some `i`, `polynomials[i].degree_bound().is_some()`, then that /// polynomial will have the corresponding degree bound enforced. + #[allow(clippy::type_complexity)] fn commit<'a>( ck: &Self::CommitterKey, polynomials: impl IntoIterator>, @@ -339,6 +341,7 @@ pub trait PolynomialCommitment: Sized { /// On input a list of polynomials, linear combinations of those polynomials, /// and a query set, `open_combination` outputs a proof of evaluation of /// the combinations at the points in the query set. + #[allow(clippy::too_many_arguments)] fn open_combinations<'a>( ck: &Self::CommitterKey, linear_combinations: impl IntoIterator>, @@ -368,6 +371,7 @@ pub trait PolynomialCommitment: Sized { /// Checks that `evaluations` are the true evaluations at `query_set` of the /// linear combinations of polynomials committed in `commitments`. + #[allow(clippy::too_many_arguments)] fn check_combinations<'a, R: RngCore>( vk: &Self::VerifierKey, linear_combinations: impl IntoIterator>, @@ -485,6 +489,7 @@ pub trait PolynomialCommitment: Sized { } /// open_combinations but with individual challenges + #[allow(clippy::too_many_arguments)] fn open_combinations_individual_opening_challenges<'a>( ck: &Self::CommitterKey, linear_combinations: impl IntoIterator>, @@ -520,6 +525,7 @@ pub trait PolynomialCommitment: Sized { } /// check_combinations with individual challenges + #[allow(clippy::too_many_arguments)] fn check_combinations_individual_opening_challenges<'a, R: RngCore>( vk: &Self::VerifierKey, linear_combinations: impl IntoIterator>, @@ -560,7 +566,7 @@ pub trait PolynomialCommitment: Sized { let eval = match label { LCTerm::One => F::one(), LCTerm::PolyLabel(l) => *poly_evals - .get(&(l.clone().into(), point)) + .get(&(l.into(), point)) .ok_or(Error::MissingEvaluation { label: l.clone() })?, }; diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index 570e2624..6b7f3a78 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -21,10 +21,11 @@ use ark_r1cs_std::{ select::CondSelectGadget, R1CSVar, ToBytesGadget, ToConstraintFieldGadget, }; -use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; +use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError}; use core::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::MulAssign}; /// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. +#[allow(clippy::type_complexity)] pub struct VerifierKeyVar< CycleE: CycleEngine, PG: PairingVar::Fr>, @@ -100,7 +101,7 @@ where let mut sum = FpVar::<::Fr>::zero(); let one = FpVar::<::Fr>::one(); for pir_gadget in pir_vector_gadgets.iter() { - sum = sum + &FpVar::<::Fr>::from(pir_gadget.clone()); + sum += &FpVar::<::Fr>::from(pir_gadget.clone()); } sum.enforce_equal(&one).unwrap(); @@ -169,7 +170,7 @@ where cs: impl Into::Fr>>, val: impl FnOnce() -> Result, mode: AllocationMode, - ) -> Result + ) -> R1CSResult where T: Borrow>, { @@ -184,38 +185,32 @@ where .. } = vk_orig; - let degree_bounds_and_shift_powers = degree_bounds_and_shift_powers.and_then(|vec| { - Some( - vec.iter() - .map(|(s, g)| { - ( - *s, - FpVar::<::Fr>::new_variable( - ark_relations::ns!(cs, "degree bound"), - || { - Ok(<::Fr as From>::from( - *s as u128, - )) - }, - mode, - ) - .unwrap(), - PG::G1Var::new_variable( - ark_relations::ns!(cs, "pow"), - || Ok(g.clone()), - mode, - ) - .unwrap(), + let degree_bounds_and_shift_powers = degree_bounds_and_shift_powers.map(|vec| { + vec.iter() + .map(|(s, g)| { + ( + *s, + FpVar::<::Fr>::new_variable( + ark_relations::ns!(cs, "degree bound"), + || { + Ok(<::Fr as From>::from( + *s as u128, + )) + }, + mode, ) - }) - .collect(), - ) + .unwrap(), + PG::G1Var::new_variable(ark_relations::ns!(cs, "pow"), || Ok(*g), mode) + .unwrap(), + ) + }) + .collect() }); let KZG10VerifierKey { g, h, beta_h, .. } = vk; - let g = PG::G1Var::new_variable(ark_relations::ns!(cs, "g"), || Ok(g.clone()), mode)?; - let h = PG::G2Var::new_variable(ark_relations::ns!(cs, "h"), || Ok(h.clone()), mode)?; + let g = PG::G1Var::new_variable(ark_relations::ns!(cs, "g"), || Ok(g), mode)?; + let h = PG::G2Var::new_variable(ark_relations::ns!(cs, "h"), || Ok(h), mode)?; let beta_h = PG::G2Var::new_variable(ark_relations::ns!(cs, "beta_h"), || Ok(beta_h), mode)?; @@ -241,7 +236,7 @@ where ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[inline] - fn to_bytes(&self) -> Result::Fr>>, SynthesisError> { + fn to_bytes(&self) -> R1CSResult::Fr>>> { let mut bytes = Vec::new(); bytes.extend_from_slice(&self.g.to_bytes()?); @@ -276,9 +271,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - fn to_constraint_field( - &self, - ) -> Result::Fr>>, SynthesisError> { + fn to_constraint_field(&self) -> R1CSResult::Fr>>> { let mut res = Vec::new(); let mut g_gadget = self.g.to_constraint_field()?; @@ -305,6 +298,7 @@ where } /// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. +#[allow(clippy::type_complexity)] pub struct PreparedVerifierKeyVar< CycleE: CycleEngine, PG: PairingVar::Fr>, @@ -376,20 +370,20 @@ where } else { let shift_power = self.origin_vk.as_ref().unwrap().get_shift_power(cs, bound); - if shift_power.is_none() { - None - } else { + if let Some(shift_power) = shift_power { let mut prepared_shift_gadgets = Vec::::new(); let supported_bits = ::Fr::size_in_bits(); - let mut cur: PG::G1Var = shift_power.unwrap().clone(); + let mut cur: PG::G1Var = shift_power; for _ in 0..supported_bits { prepared_shift_gadgets.push(cur.clone()); cur.double_in_place().unwrap(); } Some(prepared_shift_gadgets) + } else { + None } } } @@ -407,7 +401,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - fn prepare(unprepared: &VerifierKeyVar) -> Result { + fn prepare(unprepared: &VerifierKeyVar) -> R1CSResult { let supported_bits = ::Fr::size_in_bits(); let mut prepared_g = Vec::::new(); @@ -434,7 +428,7 @@ where .unwrap() .iter() { - res.push((d.clone(), (*d_gadget).clone(), vec![shift_power.clone()])); + res.push((*d, (*d_gadget).clone(), vec![shift_power.clone()])); } Some(res) @@ -472,7 +466,7 @@ where prepared_degree_bounds_and_shift_powers: self .prepared_degree_bounds_and_shift_powers .clone(), - constant_allocation: self.constant_allocation.clone(), + constant_allocation: self.constant_allocation, origin_vk: self.origin_vk.clone(), } } @@ -494,7 +488,7 @@ where cs: impl Into::Fr>>, f: impl FnOnce() -> Result, mode: AllocationMode, - ) -> Result + ) -> R1CSResult where T: Borrow>, { @@ -510,7 +504,7 @@ where ::G1Affine, ::Fr, >>::new_variable( - ark_relations::ns!(cs, "g"), || Ok(g.clone()), mode + ark_relations::ns!(cs, "g"), || Ok(*g), mode )?); } @@ -545,7 +539,7 @@ where ::G1Affine, ::Fr, >>::new_variable( - cs.clone(), || Ok(shift_power_elem.clone()), mode + cs.clone(), || Ok(shift_power_elem), mode )?); } @@ -559,7 +553,7 @@ where mode, )?; - res.push((d.clone(), d_gadget, gadgets)); + res.push((*d, d_gadget, gadgets)); } Some(res) } else { @@ -631,7 +625,7 @@ where cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, - ) -> Result + ) -> R1CSResult where T: Borrow>, { @@ -639,17 +633,13 @@ where let ns = cs.into(); let cs = ns.cs(); - let commitment = (*commitment.borrow()).clone(); + let commitment = *commitment.borrow(); let comm = commitment.comm; let comm_gadget = PG::G1Var::new_variable(cs.clone(), || Ok(comm.0), mode)?; let shifted_comm = commitment.shifted_comm; let shifted_comm_gadget = if let Some(shifted_comm) = shifted_comm { - Some(PG::G1Var::new_variable( - cs.clone(), - || Ok(shifted_comm.0), - mode, - )?) + Some(PG::G1Var::new_variable(cs, || Ok(shifted_comm.0), mode)?) } else { None }; @@ -675,9 +665,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - fn to_constraint_field( - &self, - ) -> Result::Fr>>, SynthesisError> { + fn to_constraint_field(&self) -> R1CSResult::Fr>>> { let mut res = Vec::new(); let mut comm_gadget = self.comm.to_constraint_field()?; @@ -705,7 +693,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - fn to_bytes(&self) -> Result::Fr>>, SynthesisError> { + fn to_bytes(&self) -> R1CSResult::Fr>>> { let zero_shifted_comm = PG::G1Var::zero(); let mut bytes = Vec::new(); @@ -765,7 +753,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - fn prepare(unprepared: &CommitmentVar) -> Result { + fn prepare(unprepared: &CommitmentVar) -> R1CSResult { let mut prepared_comm = Vec::::new(); let supported_bits = ::Fr::size_in_bits(); @@ -781,7 +769,7 @@ where }) } - fn prepare_small(unprepared: &CommitmentVar) -> Result { + fn prepare_small(unprepared: &CommitmentVar) -> R1CSResult { let mut prepared_comm = Vec::::new(); let supported_bits = 128; @@ -814,7 +802,7 @@ where cs: impl Into::Fr>>, f: impl FnOnce() -> Result, mode: AllocationMode, - ) -> Result + ) -> R1CSResult where T: Borrow>, { @@ -834,7 +822,7 @@ where ark_relations::ns!(cs, "comm_elem"), || { Ok(::G1Projective::from( - comm_elem.clone(), + *comm_elem, )) }, mode, @@ -849,7 +837,7 @@ where ark_relations::ns!(cs, "shifted_comm"), || { Ok(::G1Projective::from( - obj.shifted_comm.unwrap().0.clone(), + obj.shifted_comm.unwrap().0, )) }, mode, @@ -923,7 +911,7 @@ where cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, - ) -> Result + ) -> R1CSResult where T: Borrow>>, { @@ -942,12 +930,12 @@ where mode, )?; - let degree_bound = if degree_bound.is_some() { + let degree_bound = if let Some(degree_bound) = degree_bound { FpVar::<::Fr>::new_variable( ark_relations::ns!(cs, "degree_bound"), || { Ok(<::Fr as From>::from( - degree_bound.unwrap() as u128, + degree_bound as u128, )) }, mode, @@ -1018,7 +1006,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - fn prepare(unprepared: &LabeledCommitmentVar) -> Result { + fn prepare(unprepared: &LabeledCommitmentVar) -> R1CSResult { let prepared_commitment = PreparedCommitmentVar::prepare(&unprepared.commitment)?; Ok(Self { @@ -1030,6 +1018,7 @@ where } /// Var for a Marlin-KZG10 proof. +#[allow(clippy::type_complexity)] pub struct ProofVar< CycleE: CycleEngine, PG: PairingVar::Fr>, @@ -1085,7 +1074,7 @@ where cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, - ) -> Result + ) -> R1CSResult where T: Borrow>, { @@ -1093,14 +1082,14 @@ where let ns = cs.into(); let cs = ns.cs(); - let Proof { w, random_v } = proof.borrow().clone(); + let Proof { w, random_v } = *proof.borrow(); let w = PG::G1Var::new_variable(ark_relations::ns!(cs, "w"), || Ok(w), mode)?; let random_v = match random_v { None => None, Some(random_v_inner) => Some(NonNativeFieldVar::new_variable( ark_relations::ns!(cs, "random_v"), - || Ok(random_v_inner.clone()), + || Ok(random_v_inner), mode, )?), }; @@ -1111,6 +1100,7 @@ where } /// An allocated version of `BatchLCProof`. +#[allow(clippy::type_complexity)] pub struct BatchLCProofVar< CycleE: CycleEngine, PG: PairingVar::Fr>, @@ -1171,17 +1161,17 @@ where cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, - ) -> Result + ) -> R1CSResult where T: Borrow::Fr, MarlinKZG10>>, { - value_gen().and_then(|proof| { + value_gen().map(|proof| { let ns = cs.into(); let cs = ns.cs(); let BatchLCProof { proof, evals } = proof.borrow().clone(); - let proofs: Vec> = proof.clone().into(); + let proofs: Vec> = proof; let proofs: Vec> = proofs .iter() .map(|p| { @@ -1189,6 +1179,7 @@ where }) .collect(); + #[allow(clippy::type_complexity)] let evals: Option< Vec< NonNativeFieldVar< @@ -1213,7 +1204,7 @@ where ), }; - Ok(Self { proofs, evals }) + Self { proofs, evals } }) } } @@ -1264,6 +1255,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[allow(clippy::type_complexity, clippy::too_many_arguments)] fn prepared_batch_check_evaluations( cs: ConstraintSystemRef<::Fr>, prepared_verification_key: &, ::Fr, >>::PreparedVerifierKeyVar, - lc_info: &Vec<( + lc_info: &[( String, Vec<( Option< @@ -1284,7 +1276,7 @@ where PreparedCommitmentVar, bool, )>, - )>, + )], query_set: &QuerySetVar< ::Fr, ::Fr, @@ -1293,24 +1285,24 @@ where ::Fr, ::Fr, >, - proofs: &Vec< - ::Fr, - MarlinKZG10, - ::Fr, - >>::ProofVar, - >, - opening_challenges: &Vec< - NonNativeFieldVar<::Fr, ::Fr>, - >, - opening_challenges_bits: &Vec::Fr>>>, - batching_rands: &Vec< - NonNativeFieldVar<::Fr, ::Fr>, - >, - batching_rands_bits: &Vec::Fr>>>, - ) -> Result::Fr>, SynthesisError> { - let mut batching_rands = batching_rands.clone(); - let mut batching_rands_bits = batching_rands_bits.clone(); + proofs: &[::Fr, + MarlinKZG10, + ::Fr, + >>::ProofVar], + opening_challenges: &[NonNativeFieldVar< + ::Fr, + ::Fr, + >], + opening_challenges_bits: &[Vec::Fr>>], + batching_rands: &[NonNativeFieldVar< + ::Fr, + ::Fr, + >], + batching_rands_bits: &[Vec::Fr>>], + ) -> R1CSResult::Fr>> { + let mut batching_rands = batching_rands.to_vec(); + let mut batching_rands_bits = batching_rands_bits.to_vec(); let commitment_lcs: BTreeMap< String, @@ -1483,7 +1475,7 @@ where // Similarly, we add up the evaluations, multiplied with random challenges. let value_times_challenge_unreduced = value.mul_without_reduce(&challenge)?; - combined_eval = combined_eval + &value_times_challenge_unreduced; + combined_eval += &value_times_challenge_unreduced; } let combined_eval_reduced = combined_eval.reduce()?; @@ -1531,7 +1523,7 @@ where let randomizer_times_v = randomizer.mul_without_reduce(&v)?; - g_multiplier = g_multiplier + &randomizer_times_v; + g_multiplier += &randomizer_times_v; let c_times_randomizer = c_plus_w_times_z.scalar_mul_le(randomizer_bits.iter())?; @@ -1619,10 +1611,11 @@ where type ProofVar = ProofVar; type BatchLCProofVar = BatchLCProofVar; + #[allow(clippy::type_complexity)] fn batch_check_evaluations( _cs: ConstraintSystemRef<::Fr>, verification_key: &Self::VerifierKeyVar, - commitments: &Vec, + commitments: &[Self::LabeledCommitmentVar], query_set: &QuerySetVar< ::Fr, ::Fr, @@ -1631,18 +1624,20 @@ where ::Fr, ::Fr, >, - proofs: &Vec, - opening_challenges: &Vec< - NonNativeFieldVar<::Fr, ::Fr>, - >, - opening_challenges_bits: &Vec::Fr>>>, - batching_rands: &Vec< - NonNativeFieldVar<::Fr, ::Fr>, - >, - batching_rands_bits: &Vec::Fr>>>, - ) -> Result::Fr>, SynthesisError> { - let mut batching_rands = batching_rands.clone(); - let mut batching_rands_bits = batching_rands_bits.clone(); + proofs: &[Self::ProofVar], + opening_challenges: &[NonNativeFieldVar< + ::Fr, + ::Fr, + >], + opening_challenges_bits: &[Vec::Fr>>], + batching_rands: &[NonNativeFieldVar< + ::Fr, + ::Fr, + >], + batching_rands_bits: &[Vec::Fr>>], + ) -> R1CSResult::Fr>> { + let mut batching_rands = batching_rands.to_vec(); + let mut batching_rands_bits = batching_rands_bits.to_vec(); let commitments: BTreeMap<_, _> = commitments.iter().map(|c| (c.label.clone(), c)).collect(); @@ -1663,7 +1658,7 @@ where let mut comms_to_combine: Vec = Vec::new(); let mut values_to_combine = Vec::new(); for label in labels.into_iter() { - let commitment = commitments.get(label).unwrap().clone(); + let commitment = &(*commitments.get(label).unwrap()).clone(); let degree_bound = commitment.degree_bound.clone(); assert_eq!( degree_bound.is_some(), @@ -1704,7 +1699,7 @@ where // Similarly, we add up the evaluations, multiplied with random challenges. let value_times_challenge_unreduced = value.mul_without_reduce(&challenge)?; - combined_eval = combined_eval + &value_times_challenge_unreduced; + combined_eval += &value_times_challenge_unreduced; // If the degree bound is specified, we include the adjusted degree-shifted commitment // (that is, c_i' - v_i beta^{D - d_i} G), where d_i is the specific degree bound and @@ -1805,16 +1800,15 @@ where } } + #[allow(clippy::type_complexity)] fn prepared_check_combinations( cs: ConstraintSystemRef<::Fr>, prepared_verification_key: &Self::PreparedVerifierKeyVar, - linear_combinations: &Vec< - LinearCombinationVar< - ::Fr, - ::Fr, - >, - >, - prepared_commitments: &Vec, + linear_combinations: &[LinearCombinationVar< + ::Fr, + ::Fr, + >], + prepared_commitments: &[Self::PreparedLabeledCommitmentVar], query_set: &QuerySetVar< ::Fr, ::Fr, @@ -1824,15 +1818,17 @@ where ::Fr, >, proof: &Self::BatchLCProofVar, - opening_challenges: &Vec< - NonNativeFieldVar<::Fr, ::Fr>, - >, - opening_challenges_bits: &Vec::Fr>>>, - batching_rands: &Vec< - NonNativeFieldVar<::Fr, ::Fr>, - >, - batching_rands_bits: &Vec::Fr>>>, - ) -> Result::Fr>, SynthesisError> { + opening_challenges: &[NonNativeFieldVar< + ::Fr, + ::Fr, + >], + opening_challenges_bits: &[Vec::Fr>>], + batching_rands: &[NonNativeFieldVar< + ::Fr, + ::Fr, + >], + batching_rands_bits: &[Vec::Fr>>], + ) -> R1CSResult::Fr>> { let BatchLCProofVar { proofs, .. } = proof; let label_comm_map = prepared_commitments @@ -1880,7 +1876,7 @@ where coeff.clone(), cur_comm.degree_bound.clone(), cur_comm.prepared_commitment.clone(), - negate.clone(), + *negate, )); } } diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index 9ad24123..0688cfb9 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -42,7 +42,7 @@ pub struct CommitterKey { impl CommitterKey { /// Obtain powers for the underlying KZG10 construction - pub fn powers<'a>(&'a self) -> kzg10::Powers<'a, E> { + pub fn powers(&self) -> kzg10::Powers { kzg10::Powers { powers_of_g: self.powers.as_slice().into(), powers_of_gamma_g: self.powers_of_gamma_g.as_slice().into(), @@ -50,10 +50,10 @@ impl CommitterKey { } /// Obtain powers for committing to shifted polynomials. - pub fn shifted_powers<'a>( - &'a self, + pub fn shifted_powers( + &self, degree_bound: impl Into>, - ) -> Option> { + ) -> Option> { self.shifted_powers.as_ref().map(|shifted_powers| { let powers_range = if let Some(degree_bound) = degree_bound.into() { assert!(self @@ -148,7 +148,7 @@ impl ToBytes for VerifierKey { /// `PreparedVerifierKey` is used to check evaluation proofs for a given commitment. #[derive(Derivative)] -#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))] +#[derivative(Clone(bound = ""), Debug(bound = ""))] pub struct PreparedVerifierKey { /// The verification key for the underlying KZG10 scheme. pub prepared_vk: kzg10::PreparedVerifierKey, @@ -181,13 +181,13 @@ impl PCPreparedVerifierKey> for PreparedVerifie for (d, shift_power) in degree_bounds_and_shift_powers { let mut prepared_shift_power = Vec::::new(); - let mut cur = E::G1Projective::from(shift_power.clone()); + let mut cur = E::G1Projective::from(*shift_power); for _ in 0..supported_bits { prepared_shift_power.push(cur.clone().into()); cur.double_in_place(); } - res.push((d.clone(), prepared_shift_power)); + res.push((*d, prepared_shift_power)); } Some(res) @@ -275,7 +275,7 @@ impl PCPreparedCommitment> for PreparedCommitmen fn prepare(comm: &Commitment) -> Self { let prepared_comm = kzg10::PreparedCommitment::::prepare(&comm.comm); - let shifted_comm = comm.shifted_comm.clone(); + let shifted_comm = comm.shifted_comm; Self { prepared_comm, @@ -318,7 +318,7 @@ impl<'a, E: PairingEngine> AddAssign<&'a Self> for Randomness { .as_ref() .unwrap_or(&kzg10::Randomness::empty()); } else { - self.shifted_rand = other.shifted_rand.as_ref().map(|r| r.clone()); + self.shifted_rand = other.shifted_rand.as_ref().cloned() } } } diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index cb11256e..2328eb3e 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -75,7 +75,7 @@ impl MarlinKZG10 { (combined_comm, combined_shifted_comm) } - fn normalize_commitments<'a>( + fn normalize_commitments( commitments: Vec<(E::G1Projective, Option)>, ) -> Vec> { let mut comms = Vec::with_capacity(commitments.len()); @@ -92,7 +92,7 @@ impl MarlinKZG10 { } } let comms = E::G1Projective::batch_normalization_into_affine(&comms); - let s_comms = E::G1Projective::batch_normalization_into_affine(&mut s_comms); + let s_comms = E::G1Projective::batch_normalization_into_affine(&s_comms); comms .into_iter() .zip(s_comms) @@ -148,7 +148,7 @@ impl MarlinKZG10 { .get_shift_power(degree_bound) .ok_or(Error::UnsupportedDegreeBound(degree_bound))?; - let mut adjusted_comm = shifted_comm - &shift_power.mul(value.clone()); + let mut adjusted_comm = shifted_comm - &shift_power.mul(value); adjusted_comm *= challenge_i_1; combined_comm += &adjusted_comm; @@ -208,17 +208,17 @@ impl PolynomialCommitment for MarlinKZG10 { // Construct the core KZG10 verifier key. let vk = kzg10::VerifierKey { - g: pp.powers_of_g[0].clone(), + g: pp.powers_of_g[0], gamma_g: pp.powers_of_gamma_g[&0], - h: pp.h.clone(), - beta_h: pp.beta_h.clone(), + h: pp.h, + beta_h: pp.beta_h, prepared_h: pp.prepared_h.clone(), prepared_beta_h: pp.prepared_beta_h.clone(), }; let enforced_degree_bounds = enforced_degree_bounds.map(|v| { let mut v = v.to_vec(); - v.sort(); + v.sort_unstable(); v.dedup(); v }); @@ -230,7 +230,7 @@ impl PolynomialCommitment for MarlinKZG10 { (None, None) } else { let mut sorted_enforced_degree_bounds = enforced_degree_bounds.clone(); - sorted_enforced_degree_bounds.sort(); + sorted_enforced_degree_bounds.sort_unstable(); let lowest_shifted_power = max_degree - sorted_enforced_degree_bounds @@ -259,7 +259,7 @@ impl PolynomialCommitment for MarlinKZG10 { powers, shifted_powers, powers_of_gamma_g, - enforced_degree_bounds: enforced_degree_bounds, + enforced_degree_bounds, max_degree, }; @@ -273,6 +273,7 @@ impl PolynomialCommitment for MarlinKZG10 { } /// Outputs a commitment to `polynomial`. + #[allow(clippy::type_complexity)] fn commit<'a>( ck: &Self::CommitterKey, polynomials: impl IntoIterator>, @@ -296,10 +297,7 @@ impl PolynomialCommitment for MarlinKZG10 { let hiding_bound = p.hiding_bound(); let polynomial = p.polynomial(); - let enforced_degree_bounds: Option<&[usize]> = ck - .enforced_degree_bounds - .as_ref() - .map(|bounds| bounds.as_slice()); + let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), ck.max_degree, @@ -525,10 +523,7 @@ impl PolynomialCommitment for MarlinKZG10 { for (polynomial, rand) in labeled_polynomials.into_iter().zip(rands) { let degree_bound = polynomial.degree_bound(); - let enforced_degree_bounds: Option<&[usize]> = ck - .enforced_degree_bounds - .as_ref() - .map(|bounds| bounds.as_slice()); + let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), ck.max_degree, @@ -856,7 +851,7 @@ impl PolynomialCommitment for MarlinKZG10 { } else if cur_comm.degree_bound().is_some() { return Err(Error::EquationHasDegreeBounds(lc_label)); } - coeffs_and_comms.push((coeff.clone(), cur_comm.commitment())); + coeffs_and_comms.push((*coeff, cur_comm.commitment())); } } let lc_time = @@ -946,7 +941,7 @@ impl PolynomialCommitment for MarlinKZG10 { ck, query_polys, query_comms, - point.clone(), + *point, opening_challenges, query_rands, Some(rng), @@ -958,7 +953,7 @@ impl PolynomialCommitment for MarlinKZG10 { } end_timer!(open_time); - Ok(proofs.into()) + Ok(proofs) } } diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs index d6407a4d..a2befb85 100644 --- a/src/pc_constraints.rs +++ b/src/pc_constraints.rs @@ -1,6 +1,6 @@ use ark_ff::PrimeField; use ark_r1cs_std::prelude::*; -use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; +use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError}; use core::{borrow::Borrow, marker::Sized}; use crate::data_structures::LabeledCommitment; @@ -13,15 +13,16 @@ use hashbrown::{HashMap, HashSet}; /// A generic gadget for the prepared* structures pub trait PrepareVar: Sized { /// prepare from an unprepared element - fn prepare(unprepared: &UNPREPARED) -> Result; + fn prepare(unprepared: &UNPREPARED) -> R1CSResult; /// prepare for a smaller field - fn prepare_small(_unprepared: &UNPREPARED) -> Result { + fn prepare_small(_unprepared: &UNPREPARED) -> R1CSResult { unimplemented!(); } } /// An allocated version of `LinearCombination`. +#[allow(clippy::type_complexity)] pub struct LinearCombinationVar { /// The label. pub label: String, @@ -52,7 +53,7 @@ impl cs: impl Into>, val: impl FnOnce() -> Result, mode: AllocationMode, - ) -> Result + ) -> R1CSResult where T: Borrow>, { @@ -61,6 +62,7 @@ impl let ns = cs.into(); let cs = ns.cs(); + #[allow(clippy::type_complexity)] let new_terms: Vec<( Option>, LCTerm, @@ -79,7 +81,7 @@ impl .collect(); Ok(Self { - label: label.clone(), + label, terms: new_terms, }) } @@ -114,34 +116,36 @@ pub trait PCCheckVar, ConstraintF /// Add to `ConstraintSystemRef` new constraints that check that `proof_i` is a valid evaluation /// proof at `point_i` for the polynomial in `commitment_i`. + #[allow(clippy::too_many_arguments)] fn batch_check_evaluations( cs: ConstraintSystemRef, verification_key: &Self::VerifierKeyVar, - commitments: &Vec, + commitments: &[Self::LabeledCommitmentVar], query_set: &QuerySetVar, evaluations: &EvaluationsVar, - proofs: &Vec, - opening_challenges: &Vec>, - opening_challenges_bits: &Vec>>, - batching_rands: &Vec>, - batching_rands_bits: &Vec>>, - ) -> Result, SynthesisError>; + proofs: &[Self::ProofVar], + opening_challenges: &[NonNativeFieldVar], + opening_challenges_bits: &[Vec>], + batching_rands: &[NonNativeFieldVar], + batching_rands_bits: &[Vec>], + ) -> R1CSResult>; /// Add to `ConstraintSystemRef` new constraints that conditionally check that `proof` is a valid evaluation /// proof at the points in `query_set` for the combinations `linear_combinations`. + #[allow(clippy::too_many_arguments)] fn prepared_check_combinations( cs: ConstraintSystemRef, prepared_verification_key: &Self::PreparedVerifierKeyVar, - linear_combinations: &Vec>, - prepared_commitments: &Vec, + linear_combinations: &[LinearCombinationVar], + prepared_commitments: &[Self::PreparedLabeledCommitmentVar], query_set: &QuerySetVar, evaluations: &EvaluationsVar, proof: &Self::BatchLCProofVar, - opening_challenges: &Vec>, - opening_challenges_bits: &Vec>>, - batching_rands: &Vec>, - batching_rands_bits: &Vec>>, - ) -> Result, SynthesisError>; + opening_challenges: &[NonNativeFieldVar], + opening_challenges_bits: &[Vec>], + batching_rands: &[NonNativeFieldVar], + batching_rands_bits: &[Vec>], + ) -> R1CSResult>; /// Create the labeled commitment gadget from the commitment gadget fn create_labeled_commitment_gadget( @@ -159,6 +163,7 @@ pub trait PCCheckVar, ConstraintF } /// An allocated version of `QuerySet`. +#[allow(clippy::type_complexity)] pub struct QuerySetVar( pub HashSet<(String, (String, NonNativeFieldVar))>, ); @@ -176,10 +181,10 @@ impl EvaluationsVar, ) -> Result, SynthesisError> { - let key = (lc_string.clone(), point.clone()); + let key = (String::from(lc_string), point.clone()); Ok(self.0.get(&key).map(|v| (*v).clone()).unwrap()) } } diff --git a/src/sonic_pc/data_structures.rs b/src/sonic_pc/data_structures.rs index 41dacd29..d5d1d34d 100644 --- a/src/sonic_pc/data_structures.rs +++ b/src/sonic_pc/data_structures.rs @@ -20,7 +20,7 @@ impl PCPreparedCommitment> for PreparedCommitmen /// prepare `PreparedCommitment` from `Commitment` fn prepare(comm: &Commitment) -> Self { let mut prepared_comm = Vec::::new(); - let mut cur = E::G1Projective::from(comm.0.clone()); + let mut cur = E::G1Projective::from(comm.0); for _ in 0..128 { prepared_comm.push(cur.clone().into()); cur.double_in_place(); @@ -97,7 +97,7 @@ impl CommitterKey { }; let ck = kzg10::Powers { - powers_of_g: shifted_powers_of_g[powers_range.clone()].into(), + powers_of_g: shifted_powers_of_g[powers_range].into(), powers_of_gamma_g: shifted_powers_of_gamma_g[&bound].clone().into(), }; diff --git a/src/sonic_pc/mod.rs b/src/sonic_pc/mod.rs index 4cd90306..1ba7c687 100644 --- a/src/sonic_pc/mod.rs +++ b/src/sonic_pc/mod.rs @@ -28,6 +28,7 @@ pub struct SonicKZG10 { } impl SonicKZG10 { + #[allow(clippy::too_many_arguments)] fn accumulate_elems_individual_opening_challenges<'a>( combined_comms: &mut BTreeMap, E::G1Projective>, combined_witness: &mut E::G1Projective, @@ -66,7 +67,7 @@ impl SonicKZG10 { // Accumulate values in the BTreeMap *combined_comms .entry(degree_bound) - .or_insert(E::G1Projective::zero()) += &comm_with_challenge; + .or_insert_with(E::G1Projective::zero) += &comm_with_challenge; curr_challenge = opening_challenges(opening_challenge_counter); opening_challenge_counter += 1; } @@ -163,7 +164,7 @@ impl PolynomialCommitment for SonicKZG10 { let enforced_degree_bounds = enforced_degree_bounds.map(|bounds| { let mut v = bounds.to_vec(); - v.sort(); + v.sort_unstable(); v.dedup(); v }); @@ -270,6 +271,7 @@ impl PolynomialCommitment for SonicKZG10 { } /// Outputs a commitment to `polynomial`. + #[allow(clippy::type_complexity)] fn commit<'a>( ck: &Self::CommitterKey, polynomials: impl IntoIterator>, @@ -287,10 +289,7 @@ impl PolynomialCommitment for SonicKZG10 { let mut randomness: Vec = Vec::new(); for labeled_polynomial in polynomials { - let enforced_degree_bounds: Option<&[usize]> = ck - .enforced_degree_bounds - .as_ref() - .map(|bounds| bounds.as_slice()); + let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), @@ -355,10 +354,7 @@ impl PolynomialCommitment for SonicKZG10 { opening_challenge_counter += 1; for (polynomial, rand) in labeled_polynomials.into_iter().zip(rands) { - let enforced_degree_bounds: Option<&[usize]> = ck - .enforced_degree_bounds - .as_ref() - .map(|bounds| bounds.as_slice()); + let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), @@ -563,7 +559,7 @@ impl PolynomialCommitment for SonicKZG10 { let comms: Vec = E::G1Projective::batch_normalization_into_affine(&lc_commitments) .into_iter() - .map(|c| kzg10::Commitment::(c)) + .map(kzg10::Commitment::) .collect(); let lc_commitments = lc_info @@ -648,7 +644,7 @@ impl PolynomialCommitment for SonicKZG10 { let comms: Vec = E::G1Projective::batch_normalization_into_affine(&lc_commitments) .into_iter() - .map(|c| kzg10::Commitment(c)) + .map(kzg10::Commitment) .collect(); let lc_commitments = lc_info From cf79c6b003a428a23ea83b26e7662eb5481e27b3 Mon Sep 17 00:00:00 2001 From: weikeng Date: Thu, 12 Nov 2020 00:43:38 -0800 Subject: [PATCH 22/56] add ToConstraintField --- src/kzg10/data_structures.rs | 29 ++++++++++++++++++++++- src/marlin_pc/data_structures.rs | 40 +++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/kzg10/data_structures.rs b/src/kzg10/data_structures.rs index 35d5f838..15e9e615 100644 --- a/src/kzg10/data_structures.rs +++ b/src/kzg10/data_structures.rs @@ -1,6 +1,6 @@ use crate::*; use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{PrimeField, ToBytes, Zero}; +use ark_ff::{PrimeField, ToBytes, ToConstraintField, Zero}; use ark_std::borrow::Cow; use core::ops::{Add, AddAssign}; @@ -87,6 +87,24 @@ impl ToBytes for VerifierKey { } } +impl ToConstraintField<::BasePrimeField> for VerifierKey +where + E::G1Affine: ToConstraintField<::BasePrimeField>, + E::G2Affine: ToConstraintField<::BasePrimeField>, +{ + fn to_field_elements(&self) -> Option::BasePrimeField>> { + // TODO: gamma_g is omitted because our constraint system does not use. This is a little bit problematic + // The order should accommodate the one in the constraints.rs, which takes g, h, and beta_h. + let mut res = Vec::new(); + + res.extend_from_slice(&self.g.to_field_elements().unwrap()); + res.extend_from_slice(&self.h.to_field_elements().unwrap()); + res.extend_from_slice(&self.beta_h.to_field_elements().unwrap()); + + Some(res) + } +} + /// `PreparedVerifierKey` is the fully prepared version for checking evaluation proofs for a given commitment. /// We omit gamma here for simplicity. #[derive(Derivative)] @@ -167,6 +185,15 @@ impl<'a, E: PairingEngine> AddAssign<(E::Fr, &'a Commitment)> for Commitment< } } +impl ToConstraintField<::BasePrimeField> for Commitment +where + E::G1Affine: ToConstraintField<::BasePrimeField>, +{ + fn to_field_elements(&self) -> Option::BasePrimeField>> { + self.0.to_field_elements() + } +} + /// `PreparedCommitment` commits to a polynomial and prepares for mul_bits. #[derive(Derivative)] #[derivative( diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index 0688cfb9..eaccc6ca 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -3,7 +3,7 @@ use crate::{ PCVerifierKey, Vec, }; use ark_ec::{PairingEngine, ProjectiveCurve}; -use ark_ff::{PrimeField, ToBytes}; +use ark_ff::{Field, PrimeField, ToBytes, ToConstraintField}; use core::ops::{Add, AddAssign}; use rand_core::RngCore; @@ -146,6 +146,28 @@ impl ToBytes for VerifierKey { } } +impl ToConstraintField<::BasePrimeField> for VerifierKey +where + E::G1Affine: ToConstraintField<::BasePrimeField>, + E::G2Affine: ToConstraintField<::BasePrimeField>, +{ + fn to_field_elements(&self) -> Option::BasePrimeField>> { + let mut res = Vec::new(); + res.extend_from_slice(&self.vk.to_field_elements().unwrap()); + + if let Some(degree_bounds_and_shift_powers) = &self.degree_bounds_and_shift_powers { + for (d, shift_power) in degree_bounds_and_shift_powers.iter() { + let d_elem: ::BasePrimeField = (d.clone() as u64).into(); + + res.push(d_elem); + res.extend_from_slice(&shift_power.to_field_elements().unwrap()); + } + } + + Some(res) + } +} + /// `PreparedVerifierKey` is used to check evaluation proofs for a given commitment. #[derive(Derivative)] #[derivative(Clone(bound = ""), Debug(bound = ""))] @@ -256,6 +278,22 @@ impl PCCommitment for Commitment { } } +impl ToConstraintField<::BasePrimeField> for Commitment +where + E::G1Affine: ToConstraintField<::BasePrimeField>, +{ + fn to_field_elements(&self) -> Option::BasePrimeField>> { + let mut res = Vec::new(); + res.extend_from_slice(&self.comm.to_field_elements().unwrap()); + + if let Some(shifted_comm) = &self.shifted_comm { + res.extend_from_slice(&shifted_comm.to_field_elements().unwrap()); + } + + Some(res) + } +} + /// Prepared commitment to a polynomial that optionally enforces a degree bound. #[derive(Derivative)] #[derivative( From 87084be077ae164207138683c7cbae1175cbafe9 Mon Sep 17 00:00:00 2001 From: weikeng Date: Thu, 12 Nov 2020 09:12:42 -0800 Subject: [PATCH 23/56] tracing --- Cargo.toml | 1 + src/marlin_pc/constraints.rs | 56 ++++++++++++++++++++++++-------- src/marlin_pc/data_structures.rs | 2 +- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b5e886e7..84c7018b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std", default-featur ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative", default-features = false } bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } +tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } rand_core = { version = "0.5", default-features = false } digest = "0.8" diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index 6b7f3a78..6e940fbc 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -60,6 +60,7 @@ where ToConstraintField<<::Fr as Field>::BasePrimeField>, { /// Find the appropriate shift for the degree bound. + #[tracing::instrument(target = "r1cs", skip(self, cs))] pub fn get_shift_power( &self, cs: impl Into::Fr>>, @@ -166,6 +167,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[tracing::instrument(target = "r1cs", skip(cs, val))] fn new_variable( cs: impl Into::Fr>>, val: impl FnOnce() -> Result, @@ -235,7 +237,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - #[inline] + #[tracing::instrument(target = "r1cs", skip(self))] fn to_bytes(&self) -> R1CSResult::Fr>>> { let mut bytes = Vec::new(); @@ -271,6 +273,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[tracing::instrument(target = "r1cs", skip(self))] fn to_constraint_field(&self) -> R1CSResult::Fr>>> { let mut res = Vec::new(); @@ -401,8 +404,9 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare(unprepared: &VerifierKeyVar) -> R1CSResult { - let supported_bits = ::Fr::size_in_bits(); + let supported_bits = <::Fr as PrimeField>::size_in_bits(); let mut prepared_g = Vec::::new(); let mut g: PG::G1Var = unprepared.g.clone(); @@ -484,6 +488,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[tracing::instrument(target = "r1cs", skip(cs, f))] fn new_variable( cs: impl Into::Fr>>, f: impl FnOnce() -> Result, @@ -620,7 +625,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - #[inline] + #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, @@ -665,6 +670,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[tracing::instrument(target = "r1cs", skip(self))] fn to_constraint_field(&self) -> R1CSResult::Fr>>> { let mut res = Vec::new(); @@ -693,6 +699,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[tracing::instrument(target = "r1cs", skip(self))] fn to_bytes(&self) -> R1CSResult::Fr>>> { let zero_shifted_comm = PG::G1Var::zero(); @@ -753,9 +760,10 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare(unprepared: &CommitmentVar) -> R1CSResult { let mut prepared_comm = Vec::::new(); - let supported_bits = ::Fr::size_in_bits(); + let supported_bits = <::Fr as PrimeField>::size_in_bits(); let mut cur: PG::G1Var = unprepared.comm.clone(); for _ in 0..supported_bits { @@ -769,6 +777,7 @@ where }) } + #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare_small(unprepared: &CommitmentVar) -> R1CSResult { let mut prepared_comm = Vec::::new(); let supported_bits = 128; @@ -798,6 +807,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[tracing::instrument(target = "r1cs", skip(cs, f))] fn new_variable( cs: impl Into::Fr>>, f: impl FnOnce() -> Result, @@ -821,9 +831,9 @@ where >>::new_variable( ark_relations::ns!(cs, "comm_elem"), || { - Ok(::G1Projective::from( - *comm_elem, - )) + Ok(<::G1Projective as From< + ::G1Affine, + >>::from(*comm_elem)) }, mode, )?); @@ -836,9 +846,9 @@ where >>::new_variable( ark_relations::ns!(cs, "shifted_comm"), || { - Ok(::G1Projective::from( - obj.shifted_comm.unwrap().0, - )) + Ok(<::G1Projective as From< + ::G1Affine, + >>::from(obj.shifted_comm.unwrap().0)) }, mode, )?) @@ -906,7 +916,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - #[inline] + #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, @@ -1006,6 +1016,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { + #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare(unprepared: &LabeledCommitmentVar) -> R1CSResult { let prepared_commitment = PreparedCommitmentVar::prepare(&unprepared.commitment)?; @@ -1069,7 +1080,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - #[inline] + #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, @@ -1156,7 +1167,7 @@ where ::G2Affine: ToConstraintField<<::Fr as Field>::BasePrimeField>, { - #[inline] + #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, @@ -1256,6 +1267,10 @@ where ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[allow(clippy::type_complexity, clippy::too_many_arguments)] + #[tracing::instrument( + target = "r1cs", + skip(prepared_verification_key, lc_info, query_set, evaluations, proofs) + )] fn prepared_batch_check_evaluations( cs: ConstraintSystemRef<::Fr>, prepared_verification_key: &; #[allow(clippy::type_complexity)] + #[tracing::instrument( + target = "r1cs", + skip(verification_key, commitments, query_set, evaluations, proofs) + )] fn batch_check_evaluations( _cs: ConstraintSystemRef<::Fr>, verification_key: &Self::VerifierKeyVar, @@ -1801,6 +1820,17 @@ where } #[allow(clippy::type_complexity)] + #[tracing::instrument( + target = "r1cs", + skip( + prepared_verification_key, + linear_combinations, + prepared_commitments, + query_set, + proof, + evaluations + ) + )] fn prepared_check_combinations( cs: ConstraintSystemRef<::Fr>, prepared_verification_key: &Self::PreparedVerifierKeyVar, diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index eaccc6ca..4a93fcab 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -157,7 +157,7 @@ where if let Some(degree_bounds_and_shift_powers) = &self.degree_bounds_and_shift_powers { for (d, shift_power) in degree_bounds_and_shift_powers.iter() { - let d_elem: ::BasePrimeField = (d.clone() as u64).into(); + let d_elem: ::BasePrimeField = (*d as u64).into(); res.push(d_elem); res.extend_from_slice(&shift_power.to_field_elements().unwrap()); From 9baed3e1cb4c94350434df2c3dfcfb2f655254d8 Mon Sep 17 00:00:00 2001 From: weikeng Date: Thu, 12 Nov 2020 14:51:26 -0800 Subject: [PATCH 24/56] done --- src/ipa_pc/mod.rs | 2 +- src/kzg10/mod.rs | 1 + src/lib.rs | 17 ++++++------ src/marlin_pc/constraints.rs | 54 ++++++++++++++++++++++++++---------- src/marlin_pc/mod.rs | 32 +++++++++++---------- src/pc_constraints.rs | 11 ++++++-- 6 files changed, 75 insertions(+), 42 deletions(-) diff --git a/src/ipa_pc/mod.rs b/src/ipa_pc/mod.rs index 822b88fa..f4fe8c9b 100644 --- a/src/ipa_pc/mod.rs +++ b/src/ipa_pc/mod.rs @@ -557,7 +557,7 @@ where if has_hiding { let mut rng = rng.expect("hiding commitments require randomness"); let hiding_time = start_timer!(|| "Applying hiding."); - + let mut hiding_polynomial = P::rand(degree, &mut rng); hiding_polynomial -= &P::from_coefficients_slice(&[hiding_polynomial.evaluate(point)]); diff --git a/src/kzg10/mod.rs b/src/kzg10/mod.rs index 9029a8ca..9ae92a4e 100644 --- a/src/kzg10/mod.rs +++ b/src/kzg10/mod.rs @@ -143,6 +143,7 @@ where } /// Outputs a commitment to `polynomial`. + #[allow(clippy::type_complexity)] pub fn commit( powers: &Powers, polynomial: &P, diff --git a/src/lib.rs b/src/lib.rs index cf9f6fba..ecc21e06 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,6 +41,7 @@ pub use pc_constraints::*; /// Errors pertaining to query sets. pub mod error; +use ark_std::hash::Hash; pub use error::*; /// A random number generator that bypasses some limitations of the Rust borrow @@ -94,13 +95,13 @@ pub mod ipa_pc; /// `(label, (point_label, point))`, where `label` is the label of a polynomial in `p`, /// `point_label` is the label for the point (e.g., "beta"), and and `point` is the location /// that `p[label]` is to be queried at. -pub type QuerySet<'a, T> = HashSet<(String, (String, T))>; +pub type QuerySet = HashSet<(String, (String, T))>; /// `Evaluations` is the result of querying a set of labeled polynomials or equations /// `p` at a `QuerySet` `Q`. It maps each element of `Q` to the resulting evaluation. /// That is, if `(label, query)` is an element of `Q`, then `evaluation.get((label, query))` /// should equal `p[label].evaluate(query)`. -pub type Evaluations<'a, T, F> = HashMap<(String, T), F>; +pub type Evaluations = HashMap<(String, T), F>; /// A proof of satisfaction of linear combinations. pub struct BatchLCProof, PC: PolynomialCommitment> { @@ -110,7 +111,7 @@ pub struct BatchLCProof, PC: PolynomialCommitment>, } -impl> Clone for BatchLCProof { +impl, PC: PolynomialCommitment> Clone for BatchLCProof { fn clone(&self) -> Self { BatchLCProof { proof: self.proof.clone(), @@ -258,7 +259,7 @@ pub trait PolynomialCommitment>: Sized { let mut proofs = Vec::new(); for (_point_label, (point, labels)) in query_to_labels_map.into_iter() { - let mut query_polys: Vec<&'a LabeledPolynomial<_>> = Vec::new(); + let mut query_polys: Vec<&'a LabeledPolynomial<_, P>> = Vec::new(); let mut query_rands: Vec<&'a Self::Randomness> = Vec::new(); let mut query_comms: Vec<&'a LabeledCommitment> = Vec::new(); @@ -278,7 +279,7 @@ pub trait PolynomialCommitment>: Sized { ck, query_polys, query_comms, - *point, + point, opening_challenge, query_rands, Some(rng), @@ -575,7 +576,7 @@ pub trait PolynomialCommitment>: Sized { let eval = match label { LCTerm::One => F::one(), LCTerm::PolyLabel(l) => *poly_evals - .get(&(l.into(), point)) + .get(&(l.into(), point.clone())) .ok_or(Error::MissingEvaluation { label: l.clone() })?, }; @@ -689,7 +690,7 @@ pub fn evaluate_query_set<'a, F, P, T>( where F: Field, P: 'a + Polynomial, - T: Clone + Debug + Ord + Sync, + T: Clone + Debug + Ord + Sync + Hash, { let polys = BTreeMap::from_iter(polys.into_iter().map(|p| (p.label(), p))); let mut evaluations = Evaluations::new(); @@ -703,7 +704,7 @@ where evaluations } -fn lc_query_set_to_poly_query_set<'a, F: Field, T: Clone + Ord>( +fn lc_query_set_to_poly_query_set<'a, F: Field, T: Clone + Ord + Hash>( linear_combinations: impl IntoIterator>, query_set: &QuerySet, ) -> QuerySet { diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index 6e940fbc..126e48bc 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -11,6 +11,7 @@ use crate::{ use ark_ec::{CycleEngine, PairingEngine}; use ark_ff::{fields::Field, PrimeField, ToConstraintField}; use ark_nonnative_field::{NonNativeFieldMulResultVar, NonNativeFieldVar}; +use ark_poly::UVPolynomial; use ark_r1cs_std::{ alloc::{AllocVar, AllocationMode}, bits::{boolean::Boolean, uint8::UInt8, ToBitsGadget}, @@ -22,6 +23,7 @@ use ark_r1cs_std::{ R1CSVar, ToBytesGadget, ToConstraintFieldGadget, }; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError}; +use ark_std::ops::Div; use core::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::MulAssign}; /// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. @@ -1114,6 +1116,7 @@ where #[allow(clippy::type_complexity)] pub struct BatchLCProofVar< CycleE: CycleEngine, + P: UVPolynomial<::Fr, Point = ::Fr>, PG: PairingVar::Fr>, > where ::G1Projective: MulAssign<::Fq>, @@ -1131,11 +1134,14 @@ pub struct BatchLCProofVar< NonNativeFieldVar<::Fr, ::Fr>, >, >, + #[doc(hidden)] + pub polynomial: PhantomData

, } -impl Clone for BatchLCProofVar +impl Clone for BatchLCProofVar where CycleE: CycleEngine, + P: UVPolynomial<::Fr, Point = ::Fr>, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -1148,17 +1154,20 @@ where BatchLCProofVar { proofs: self.proofs.clone(), evals: self.evals.clone(), + polynomial: PhantomData, } } } -impl +impl AllocVar< - BatchLCProof<::Fr, MarlinKZG10>, + BatchLCProof<::Fr, P, MarlinKZG10>, ::Fr, - > for BatchLCProofVar + > for BatchLCProofVar where CycleE: CycleEngine, + P: UVPolynomial<::Fr, Point = ::Fr>, + for<'a, 'b> &'a P: Div<&'b P, Output = P>, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -1174,7 +1183,7 @@ where mode: AllocationMode, ) -> R1CSResult where - T: Borrow::Fr, MarlinKZG10>>, + T: Borrow::Fr, P, MarlinKZG10>>, { value_gen().map(|proof| { let ns = cs.into(); @@ -1215,15 +1224,20 @@ where ), }; - Self { proofs, evals } + Self { + proofs, + evals, + polynomial: PhantomData, + } }) } } /// Var for the Marlin-KZG10 polynomial commitment verifier. -pub struct MarlinKZG10Gadget +pub struct MarlinKZG10Gadget where CycleE: CycleEngine, + P: UVPolynomial<::Fr, Point = ::Fr>, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -1234,11 +1248,13 @@ where { _cycle_engine: PhantomData, _pairing_gadget: PhantomData, + _polynomial: PhantomData

, } -impl Clone for MarlinKZG10Gadget +impl Clone for MarlinKZG10Gadget where CycleE: CycleEngine, + P: UVPolynomial<::Fr, Point = ::Fr>, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -1251,13 +1267,16 @@ where MarlinKZG10Gadget { _cycle_engine: PhantomData, _pairing_gadget: PhantomData, + _polynomial: PhantomData, } } } -impl MarlinKZG10Gadget +impl MarlinKZG10Gadget where CycleE: CycleEngine, + P: UVPolynomial<::Fr, Point = ::Fr>, + for<'a, 'b> &'a P: Div<&'b P, Output = P>, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -1275,7 +1294,8 @@ where cs: ConstraintSystemRef<::Fr>, prepared_verification_key: &::Fr, - MarlinKZG10, + P, + MarlinKZG10, ::Fr, >>::PreparedVerifierKeyVar, lc_info: &[( @@ -1302,7 +1322,8 @@ where >, proofs: &[::Fr, - MarlinKZG10, + P, + MarlinKZG10, ::Fr, >>::ProofVar], opening_challenges: &[NonNativeFieldVar< @@ -1601,14 +1622,17 @@ where } } -impl +impl PCCheckVar< ::Fr, - MarlinKZG10, + P, + MarlinKZG10, ::Fr, - > for MarlinKZG10Gadget + > for MarlinKZG10Gadget where CycleE: CycleEngine, + P: UVPolynomial<::Fr, Point = ::Fr>, + for<'a, 'b> &'a P: Div<&'b P, Output = P>, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -1624,7 +1648,7 @@ where type LabeledCommitmentVar = LabeledCommitmentVar; type PreparedLabeledCommitmentVar = PreparedLabeledCommitmentVar; type ProofVar = ProofVar; - type BatchLCProofVar = BatchLCProofVar; + type BatchLCProofVar = BatchLCProofVar; #[allow(clippy::type_complexity)] #[tracing::instrument( diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index 232ec5af..ccc13de9 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -307,7 +307,7 @@ where let polynomial: &P = p.polynomial(); let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); - kzg10::KZG10::::check_degrees_and_bounds( + kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), ck.max_degree, enforced_degree_bounds, @@ -352,15 +352,15 @@ where /// On input a polynomial `p` and a point `point`, outputs a proof for the same. fn open<'a>( ck: &Self::CommitterKey, - labeled_polynomials: impl IntoIterator>, + labeled_polynomials: impl IntoIterator>, commitments: impl IntoIterator>, - point: E::Fr, + point: &'a P::Point, opening_challenge: E::Fr, rands: impl IntoIterator, rng: Option<&mut dyn RngCore>, ) -> Result where - Randomness: 'a, + Randomness: 'a, Commitment: 'a, { let opening_challenges = |j| opening_challenge.pow([j]); @@ -368,7 +368,7 @@ where ck, labeled_polynomials, commitments, - point, + &point, &opening_challenges, rands, rng, @@ -380,7 +380,7 @@ where fn check<'a>( vk: &Self::VerifierKey, commitments: impl IntoIterator>, - point: E::Fr, + point: &'a P::Point, values: impl IntoIterator, proof: &Self::Proof, opening_challenge: E::Fr, @@ -393,7 +393,7 @@ where Self::check_individual_opening_challenges( vk, commitments, - point, + &point, values, proof, &opening_challenges, @@ -405,7 +405,7 @@ where vk: &Self::VerifierKey, commitments: impl IntoIterator>, query_set: &QuerySet, - evaluations: &Evaluations, + evaluations: &Evaluations, proof: &Self::BatchProof, opening_challenge: E::Fr, rng: &mut R, @@ -428,14 +428,15 @@ where fn open_combinations<'a>( ck: &Self::CommitterKey, lc_s: impl IntoIterator>, - polynomials: impl IntoIterator>, + polynomials: impl IntoIterator>, commitments: impl IntoIterator>, query_set: &QuerySet, opening_challenge: E::Fr, rands: impl IntoIterator, rng: Option<&mut dyn RngCore>, - ) -> Result, Self::Error> + ) -> Result, Self::Error> where + P: 'a, Self::Randomness: 'a, Self::Commitment: 'a, { @@ -459,8 +460,8 @@ where lc_s: impl IntoIterator>, commitments: impl IntoIterator>, query_set: &QuerySet, - evaluations: &Evaluations, - proof: &BatchLCProof, + evaluations: &Evaluations, + proof: &BatchLCProof, opening_challenge: E::Fr, rng: &mut R, ) -> Result @@ -484,7 +485,7 @@ where /// of the polynomials at the points in the query set. fn batch_open<'a>( ck: &Self::CommitterKey, - labeled_polynomials: impl IntoIterator>, + labeled_polynomials: impl IntoIterator>, commitments: impl IntoIterator>, query_set: &QuerySet, opening_challenge: E::Fr, @@ -492,6 +493,7 @@ where rng: Option<&mut dyn RngCore>, ) -> Result where + P: 'a, Self::Randomness: 'a, Self::Commitment: 'a, { @@ -535,7 +537,7 @@ where assert_eq!(degree_bound.is_some(), rand.shifted_rand.is_some()); let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); - kzg10::KZG10::::check_degrees_and_bounds( + kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), ck.max_degree, enforced_degree_bounds, @@ -955,7 +957,7 @@ where ck, query_polys, query_comms, - *point, + point, opening_challenges, query_rands, Some(rng), diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs index a2befb85..fee3c535 100644 --- a/src/pc_constraints.rs +++ b/src/pc_constraints.rs @@ -7,6 +7,7 @@ use crate::data_structures::LabeledCommitment; use crate::{BatchLCProof, PolynomialCommitment}; use crate::{LCTerm, LinearCombination, String, Vec}; use ark_nonnative_field::NonNativeFieldVar; +use ark_poly::Polynomial; use ark_r1cs_std::fields::fp::FpVar; use hashbrown::{HashMap, HashSet}; @@ -89,8 +90,12 @@ impl /// Describes the interface for a gadget for a `PolynomialCommitment` /// verifier. -pub trait PCCheckVar, ConstraintF: PrimeField>: - Clone +pub trait PCCheckVar< + PCF: PrimeField, + P: Polynomial, + PC: PolynomialCommitment, + ConstraintF: PrimeField, +>: Clone { /// An allocated version of `PC::VerifierKey`. type VerifierKeyVar: AllocVar + Clone + ToBytesGadget; @@ -112,7 +117,7 @@ pub trait PCCheckVar, ConstraintF type ProofVar: AllocVar + Clone; /// An allocated version of `PC::BatchLCProof`. - type BatchLCProofVar: AllocVar, ConstraintF> + Clone; + type BatchLCProofVar: AllocVar, ConstraintF> + Clone; /// Add to `ConstraintSystemRef` new constraints that check that `proof_i` is a valid evaluation /// proof at `point_i` for the polynomial in `commitment_i`. From 132842a3cf8243df50684241ad6866e57f131dc9 Mon Sep 17 00:00:00 2001 From: Weikeng Chen Date: Thu, 12 Nov 2020 17:09:17 -0800 Subject: [PATCH 25/56] Update pc_constraints.rs --- src/pc_constraints.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs index fee3c535..c0454f57 100644 --- a/src/pc_constraints.rs +++ b/src/pc_constraints.rs @@ -176,7 +176,7 @@ pub struct QuerySetVar( /// An allocated version of `Evaluations`. #[derive(Clone)] pub struct EvaluationsVar( - pub HashMap< + pub HashMap< (String, NonNativeFieldVar), NonNativeFieldVar, >, From 56e481a17b4401a3184f2d73d90128ec019c35e9 Mon Sep 17 00:00:00 2001 From: weikeng Date: Thu, 12 Nov 2020 18:22:47 -0800 Subject: [PATCH 26/56] fmt --- src/pc_constraints.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc_constraints.rs b/src/pc_constraints.rs index c0454f57..fee3c535 100644 --- a/src/pc_constraints.rs +++ b/src/pc_constraints.rs @@ -176,7 +176,7 @@ pub struct QuerySetVar( /// An allocated version of `Evaluations`. #[derive(Clone)] pub struct EvaluationsVar( - pub HashMap< + pub HashMap< (String, NonNativeFieldVar), NonNativeFieldVar, >, From 8d4a9647f83705c536caf49f263307bcce4fb198 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 17 Nov 2020 13:49:57 -0800 Subject: [PATCH 27/56] Apply suggestions from code review Co-authored-by: Pratyush Mishra --- Cargo.toml | 10 ++++++---- src/data_structures.rs | 4 ++-- src/ipa_pc/mod.rs | 2 +- src/lib.rs | 8 +++++--- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 84c7018b..40e8e5c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,9 +27,9 @@ ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = fa ark-poly = { git = "https://github.com/arkworks-rs/algebra", default-features = false } ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false } -ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features = false } -ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std", default-features = false } -ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative", default-features = false } +ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features = false, optional = true } +ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std", default-features = false, optional = true } +ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative", default-features = false, optional = true } bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } @@ -62,6 +62,8 @@ debug = true [features] default = ["std", "parallel"] std = [ "ark-ff/std", "ark-ec/std", "ark-nonnative-field/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std" ] + +r1cs = [ "ark-relations/std", "ark-r1cs-std", "ark-nonnative-field" ] print-trace = [ "bench-utils/print-trace" ] parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ] -density-optimized = [ "ark-nonnative-field/density-optimized" ] +density-optimized = [ "r1cs", "ark-nonnative-field/density-optimized" ] diff --git a/src/data_structures.rs b/src/data_structures.rs index b91586d3..4f52bdea 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -41,9 +41,9 @@ pub trait PCVerifierKey: Clone + core::fmt::Debug { /// Defines the minimal interface of prepared verifier keys for any polynomial /// commitment scheme. -pub trait PCPreparedVerifierKey { +pub trait PCPreparedVerifierKey { /// prepare - fn prepare(vk: &UNPREPARED) -> Self; + fn prepare(vk: &Unprepared) -> Self; } /// Defines the minimal interface of commitments for any polynomial diff --git a/src/ipa_pc/mod.rs b/src/ipa_pc/mod.rs index f4fe8c9b..060f2b31 100644 --- a/src/ipa_pc/mod.rs +++ b/src/ipa_pc/mod.rs @@ -256,7 +256,7 @@ impl> InnerProductArg let mut commitments = Vec::new(); let mut i = 0; - for info in lc_info.iter() { + for info in &lc_info { let commitment; let label = info.0.clone(); let degree_bound = info.1; diff --git a/src/lib.rs b/src/lib.rs index ecc21e06..eddd8470 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,9 +35,11 @@ use hashbrown::{HashMap, HashSet}; pub mod data_structures; pub use data_structures::*; -/// Constraints for recursion. -mod pc_constraints; -pub use pc_constraints::*; +/// R1CS constraints for polynomial constraints. +#[cfg(feature = "r1cs")] +mod constraints; +#[cfg(feature = "r1cs")] +pub use constraints::*; /// Errors pertaining to query sets. pub mod error; From 2eaed72ebc12c6f63d02f59681d050031f5ca124 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 17 Nov 2020 13:55:05 -0800 Subject: [PATCH 28/56] small fixes --- src/ipa_pc/mod.rs | 2 +- src/lib.rs | 1 - src/marlin_pc/mod.rs | 3 +++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ipa_pc/mod.rs b/src/ipa_pc/mod.rs index 060f2b31..30f12d58 100644 --- a/src/ipa_pc/mod.rs +++ b/src/ipa_pc/mod.rs @@ -256,7 +256,7 @@ impl> InnerProductArg let mut commitments = Vec::new(); let mut i = 0; - for info in &lc_info { + for info in lc_info { let commitment; let label = info.0.clone(); let degree_bound = info.1; diff --git a/src/lib.rs b/src/lib.rs index eddd8470..3c94a8ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,7 +26,6 @@ use ark_std::{ iter::FromIterator, rc::Rc, string::{String, ToString}, - vec, vec::Vec, }; use hashbrown::{HashMap, HashSet}; diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index ccc13de9..443b250f 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -12,7 +12,10 @@ use rand_core::RngCore; mod data_structures; pub use data_structures::*; +/// R1CS constraints for the commitment scheme. +#[cfg(feature = "r1cs")] mod constraints; +#[cfg(feature = "r1cs")] pub use constraints::*; /// Polynomial commitment based on [[KZG10]][kzg], with degree enforcement, batching, From 7bc0da17be298de2533f547c23de91db0dfacdfc Mon Sep 17 00:00:00 2001 From: weikeng Date: Tue, 17 Nov 2020 14:49:41 -0800 Subject: [PATCH 29/56] cleaning --- src/{pc_constraints.rs => constraints.rs} | 0 src/lib.rs | 1 - src/marlin_pc/constraints.rs | 9 +++++---- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/{pc_constraints.rs => constraints.rs} (100%) diff --git a/src/pc_constraints.rs b/src/constraints.rs similarity index 100% rename from src/pc_constraints.rs rename to src/constraints.rs diff --git a/src/lib.rs b/src/lib.rs index 40880dcf..66eac969 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,6 @@ pub use constraints::*; /// Errors pertaining to query sets. pub mod error; -use ark_std::hash::Hash; pub use error::*; /// A random number generator that bypasses some limitations of the Rust borrow diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index 126e48bc..a801402a 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -1,12 +1,12 @@ use crate::{ + constraints::{EvaluationsVar, PCCheckVar, QuerySetVar}, data_structures::LabeledCommitment, kzg10::{Proof, VerifierKey as KZG10VerifierKey}, marlin_pc::{ data_structures::{Commitment, VerifierKey}, MarlinKZG10, PreparedCommitment, PreparedVerifierKey, }, - pc_constraints::{EvaluationsVar, PCCheckVar, QuerySetVar}, - vec, BTreeMap, BTreeSet, BatchLCProof, LinearCombinationVar, PrepareVar, String, ToString, Vec, + BTreeMap, BTreeSet, BatchLCProof, LinearCombinationVar, PrepareVar, String, ToString, Vec, }; use ark_ec::{CycleEngine, PairingEngine}; use ark_ff::{fields::Field, PrimeField, ToConstraintField}; @@ -23,8 +23,9 @@ use ark_r1cs_std::{ R1CSVar, ToBytesGadget, ToConstraintFieldGadget, }; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError}; -use ark_std::ops::Div; -use core::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::MulAssign}; +use ark_std::{ + borrow::Borrow, convert::TryInto, marker::PhantomData, ops::Div, ops::MulAssign, vec, +}; /// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. #[allow(clippy::type_complexity)] From 58896f20a431d4e2561d87f3433a0abae6421570 Mon Sep 17 00:00:00 2001 From: weikeng Date: Tue, 17 Nov 2020 15:09:48 -0800 Subject: [PATCH 30/56] fix nostd --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 40e8e5c1..d98a300e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ debug = true default = ["std", "parallel"] std = [ "ark-ff/std", "ark-ec/std", "ark-nonnative-field/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std" ] -r1cs = [ "ark-relations/std", "ark-r1cs-std", "ark-nonnative-field" ] +r1cs = [ "ark-relations", "ark-r1cs-std", "ark-nonnative-field" ] print-trace = [ "bench-utils/print-trace" ] parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ] density-optimized = [ "r1cs", "ark-nonnative-field/density-optimized" ] From 77c456a64483d88449adf4db3cc926417d03f4a1 Mon Sep 17 00:00:00 2001 From: oblivious-app <55861861+oblivious-app@users.noreply.github.com> Date: Fri, 25 Dec 2020 23:21:59 -0800 Subject: [PATCH 31/56] reduce the PR size --- Cargo.toml | 2 -- src/data_structures.rs | 12 ++++---- src/ipa_pc/data_structures.rs | 2 +- src/ipa_pc/mod.rs | 49 +++++++++++++++----------------- src/kzg10/data_structures.rs | 2 +- src/lib.rs | 5 ++-- src/marlin_pc/data_structures.rs | 2 +- 7 files changed, 35 insertions(+), 39 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 69b4896f..d4bf4d0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,13 +33,11 @@ ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative", defaul hashbrown = { version = "0.9", optional = true } bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } -tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } rand_core = { version = "0.5", default-features = false } digest = "0.8" rayon = { version = "1", optional = true } derivative = { version = "2", features = [ "use_core" ] } -hashbrown = "0.9" [dev-dependencies] rand = { version = "0.7", default-features = false } diff --git a/src/data_structures.rs b/src/data_structures.rs index 07fc096d..6478a8a4 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -1,5 +1,5 @@ use crate::{Polynomial, PolynomialCommitment, Rc, String, Vec}; -use ark_ff::Field; +use ark_ff::{Field, ToConstraintField}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; use ark_std::{ borrow::Borrow, @@ -340,7 +340,11 @@ impl LCTerm { /// Returns `true` if `self == LCTerm::One` #[inline] pub fn is_one(&self) -> bool { - matches!(self, LCTerm::One) + if let LCTerm::One = self { + true + } else { + false + } } } @@ -410,7 +414,7 @@ impl LinearCombination { let terms = terms.into_iter().map(|(c, t)| (c, t.into())).collect(); Self { label: label.into(), - terms, + terms: terms, } } @@ -432,7 +436,6 @@ impl LinearCombination { } impl<'a, F: Field> AddAssign<(F, &'a LinearCombination)> for LinearCombination { - #[allow(clippy::suspicious_op_assign_impl)] fn add_assign(&mut self, (coeff, other): (F, &'a LinearCombination)) { self.terms .extend(other.terms.iter().map(|(c, t)| (coeff * c, t.clone()))); @@ -440,7 +443,6 @@ impl<'a, F: Field> AddAssign<(F, &'a LinearCombination)> for LinearCombinatio } impl<'a, F: Field> SubAssign<(F, &'a LinearCombination)> for LinearCombination { - #[allow(clippy::suspicious_op_assign_impl)] fn sub_assign(&mut self, (coeff, other): (F, &'a LinearCombination)) { self.terms .extend(other.terms.iter().map(|(c, t)| (-coeff * c, t.clone()))); diff --git a/src/ipa_pc/data_structures.rs b/src/ipa_pc/data_structures.rs index e50b6c66..10c79eeb 100644 --- a/src/ipa_pc/data_structures.rs +++ b/src/ipa_pc/data_structures.rs @@ -144,7 +144,7 @@ pub type PreparedCommitment = Commitment; impl PCPreparedCommitment> for PreparedCommitment { /// prepare `PreparedCommitment` from `Commitment` fn prepare(vk: &Commitment) -> Self { - *vk + vk.clone() } } diff --git a/src/ipa_pc/mod.rs b/src/ipa_pc/mod.rs index 0be1d363..f287c221 100644 --- a/src/ipa_pc/mod.rs +++ b/src/ipa_pc/mod.rs @@ -53,9 +53,9 @@ impl> InnerProductArg let mut comm = VariableBaseMSM::multi_scalar_mul(comm_key, &scalars_bigint); - if let Some(randomizer) = randomizer { + if randomizer.is_some() { assert!(hiding_generator.is_some()); - comm += &hiding_generator.unwrap().mul(randomizer); + comm += &hiding_generator.unwrap().mul(randomizer.unwrap()); } comm @@ -168,8 +168,8 @@ impl> InnerProductArg let h_prime = h_prime.into_affine(); let check_commitment_elem: G::Projective = Self::cm_commit( - &[proof.final_comm_key, h_prime], - &[proof.c, v_prime], + &[proof.final_comm_key.clone(), h_prime], + &[proof.c.clone(), v_prime], None, None, ); @@ -253,21 +253,21 @@ impl> InnerProductArg let mut commitments = Vec::new(); let mut i = 0; - for info in lc_info { + for info in lc_info.into_iter() { let commitment; let label = info.0.clone(); let degree_bound = info.1; if degree_bound.is_some() { commitment = Commitment { - comm: comms[i], - shifted_comm: Some(comms[i + 1]), + comm: comms[i].clone(), + shifted_comm: Some(comms[i + 1]).clone(), }; i += 2; } else { commitment = Commitment { - comm: comms[i], + comm: comms[i].clone(), shifted_comm: None, }; @@ -277,7 +277,7 @@ impl> InnerProductArg commitments.push(LabeledCommitment::new(label, commitment, degree_bound)); } - commitments + return commitments; } fn sample_generators(num_generators: usize) -> Vec { @@ -359,15 +359,15 @@ where let ck = CommitterKey { comm_key: pp.comm_key[0..(supported_degree + 1)].to_vec(), - h: pp.h, - s: pp.s, + h: pp.h.clone(), + s: pp.s.clone(), max_degree: pp.max_degree(), }; let vk = VerifierKey { comm_key: pp.comm_key[0..(supported_degree + 1)].to_vec(), - h: pp.h, - s: pp.s, + h: pp.h.clone(), + s: pp.s.clone(), max_degree: pp.max_degree(), }; @@ -377,7 +377,6 @@ where } /// Outputs a commitment to `polynomial`. - #[allow(clippy::type_complexity)] fn commit<'a>( ck: &Self::CommitterKey, polynomials: impl IntoIterator>, @@ -543,10 +542,10 @@ where let combined_v = combined_polynomial.evaluate(point); // Pad the coefficients to the appropriate vector size - let degree = ck.supported_degree(); + let d = ck.supported_degree(); // `log_d` is ceil(log2 (d + 1)), which is the number of steps to compute all of the challenges - let log_d = ark_std::log2(degree + 1) as usize; + let log_d = ark_std::log2(d + 1) as usize; let mut combined_commitment; let mut hiding_commitment = None; @@ -555,7 +554,7 @@ where let mut rng = rng.expect("hiding commitments require randomness"); let hiding_time = start_timer!(|| "Applying hiding."); - let mut hiding_polynomial = P::rand(degree, &mut rng); + let mut hiding_polynomial = P::rand(d, &mut rng); hiding_polynomial -= &P::from_coefficients_slice(&[hiding_polynomial.evaluate(point)]); let hiding_rand = G::ScalarField::rand(rng); @@ -596,10 +595,8 @@ where None }; - let proof_time = start_timer!(|| format!( - "Generating proof for degree {} combined polynomial", - degree + 1 - )); + let proof_time = + start_timer!(|| format!("Generating proof for degree {} combined polynomial", d + 1)); combined_commitment = combined_commitment_proj.into_affine(); @@ -613,17 +610,17 @@ where // Pads the coefficients with zeroes to get the number of coeff to be d+1 let mut coeffs = combined_polynomial.coeffs().to_vec(); - if coeffs.len() < degree + 1 { - for _ in coeffs.len()..(degree + 1) { + if coeffs.len() < d + 1 { + for _ in coeffs.len()..(d + 1) { coeffs.push(G::ScalarField::zero()); } } let mut coeffs = coeffs.as_mut_slice(); // Powers of z - let mut z: Vec = Vec::with_capacity(degree + 1); + let mut z: Vec = Vec::with_capacity(d + 1); let mut cur_z: G::ScalarField = G::ScalarField::one(); - for _ in 0..(degree + 1) { + for _ in 0..(d + 1) { z.push(cur_z); cur_z *= point; } @@ -642,7 +639,7 @@ where let mut l_vec = Vec::with_capacity(log_d); let mut r_vec = Vec::with_capacity(log_d); - let mut n = degree + 1; + let mut n = d + 1; while n > 1 { let (coeffs_l, coeffs_r) = coeffs.split_at_mut(n / 2); let (z_l, z_r) = z.split_at_mut(n / 2); diff --git a/src/kzg10/data_structures.rs b/src/kzg10/data_structures.rs index 258e98b9..372f651e 100644 --- a/src/kzg10/data_structures.rs +++ b/src/kzg10/data_structures.rs @@ -1,6 +1,6 @@ use crate::*; use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{PrimeField, ToBytes, Zero}; +use ark_ff::{PrimeField, ToBytes, ToConstraintField, Zero}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; use ark_std::{ borrow::Cow, diff --git a/src/lib.rs b/src/lib.rs index 767b6efb..b9fc13c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,6 @@ use ark_std::{ string::{String, ToString}, vec::Vec, }; -use hashbrown::{HashMap, HashSet}; /// Data structures used by a polynomial commitment scheme. pub mod data_structures; @@ -97,13 +96,13 @@ pub mod ipa_pc; /// `(label, (point_label, point))`, where `label` is the label of a polynomial in `p`, /// `point_label` is the label for the point (e.g., "beta"), and and `point` is the location /// that `p[label]` is to be queried at. -pub type QuerySet = HashSet<(String, (String, T))>; +pub type QuerySet = BTreeSet<(String, (String, T))>; /// `Evaluations` is the result of querying a set of labeled polynomials or equations /// `p` at a `QuerySet` `Q`. It maps each element of `Q` to the resulting evaluation. /// That is, if `(label, query)` is an element of `Q`, then `evaluation.get((label, query))` /// should equal `p[label].evaluate(query)`. -pub type Evaluations = HashMap<(String, T), F>; +pub type Evaluations = BTreeMap<(String, T), F>; /// Describes the interface for a polynomial commitment scheme that allows /// a sender to commit to multiple polynomials and later provide a succinct proof diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index c690227f..e13e5276 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -3,7 +3,7 @@ use crate::{ PCVerifierKey, UVPolynomial, Vec, }; use ark_ec::{PairingEngine, ProjectiveCurve}; -use ark_ff::{PrimeField, ToBytes}; +use ark_ff::{Field, PrimeField, ToBytes, ToConstraintField}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; use ark_std::io::{Read, Write}; use ark_std::ops::{Add, AddAssign}; From ac23b82fd9b1538d61ed49db944c9ff2b5850356 Mon Sep 17 00:00:00 2001 From: oblivious-app <55861861+oblivious-app@users.noreply.github.com> Date: Fri, 25 Dec 2020 23:25:45 -0800 Subject: [PATCH 32/56] reduce the PR size --- src/lib.rs | 7 +------ src/sonic_pc/data_structures.rs | 4 ++-- src/sonic_pc/mod.rs | 5 ++--- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b9fc13c4..320cbb04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -163,7 +163,6 @@ pub trait PolynomialCommitment>: Sized { /// /// If for some `i`, `polynomials[i].degree_bound().is_some()`, then that /// polynomial will have the corresponding degree bound enforced. - #[allow(clippy::type_complexity)] fn commit<'a>( ck: &Self::CommitterKey, polynomials: impl IntoIterator>, @@ -337,7 +336,6 @@ pub trait PolynomialCommitment>: Sized { /// On input a list of polynomials, linear combinations of those polynomials, /// and a query set, `open_combination` outputs a proof of evaluation of /// the combinations at the points in the query set. - #[allow(clippy::too_many_arguments)] fn open_combinations<'a>( ck: &Self::CommitterKey, linear_combinations: impl IntoIterator>, @@ -368,7 +366,6 @@ pub trait PolynomialCommitment>: Sized { /// Checks that `evaluations` are the true evaluations at `query_set` of the /// linear combinations of polynomials committed in `commitments`. - #[allow(clippy::too_many_arguments)] fn check_combinations<'a, R: RngCore>( vk: &Self::VerifierKey, linear_combinations: impl IntoIterator>, @@ -486,7 +483,6 @@ pub trait PolynomialCommitment>: Sized { } /// open_combinations but with individual challenges - #[allow(clippy::too_many_arguments)] fn open_combinations_individual_opening_challenges<'a>( ck: &Self::CommitterKey, linear_combinations: impl IntoIterator>, @@ -523,7 +519,6 @@ pub trait PolynomialCommitment>: Sized { } /// check_combinations with individual challenges - #[allow(clippy::too_many_arguments)] fn check_combinations_individual_opening_challenges<'a, R: RngCore>( vk: &Self::VerifierKey, linear_combinations: impl IntoIterator>, @@ -692,7 +687,7 @@ where evaluations } -fn lc_query_set_to_poly_query_set<'a, F: Field, T: Clone + Ord + Hash>( +fn lc_query_set_to_poly_query_set<'a, F: Field, T: Clone + Ord>( linear_combinations: impl IntoIterator>, query_set: &QuerySet, ) -> QuerySet { diff --git a/src/sonic_pc/data_structures.rs b/src/sonic_pc/data_structures.rs index 54127083..07a9b777 100644 --- a/src/sonic_pc/data_structures.rs +++ b/src/sonic_pc/data_structures.rs @@ -22,7 +22,7 @@ impl PCPreparedCommitment> for PreparedCommitmen /// prepare `PreparedCommitment` from `Commitment` fn prepare(comm: &Commitment) -> Self { let mut prepared_comm = Vec::::new(); - let mut cur = E::G1Projective::from(comm.0); + let mut cur = E::G1Projective::from(comm.0.clone()); for _ in 0..128 { prepared_comm.push(cur.clone().into()); cur.double_in_place(); @@ -99,7 +99,7 @@ impl CommitterKey { }; let ck = kzg10::Powers { - powers_of_g: shifted_powers_of_g[powers_range].into(), + powers_of_g: shifted_powers_of_g[powers_range.clone()].into(), powers_of_gamma_g: shifted_powers_of_gamma_g[&bound].clone().into(), }; diff --git a/src/sonic_pc/mod.rs b/src/sonic_pc/mod.rs index 87fb956c..d30804d3 100644 --- a/src/sonic_pc/mod.rs +++ b/src/sonic_pc/mod.rs @@ -28,7 +28,6 @@ pub struct SonicKZG10> { } impl> SonicKZG10 { - #[allow(clippy::too_many_arguments)] fn accumulate_elems_individual_opening_challenges<'a>( combined_comms: &mut BTreeMap, E::G1Projective>, combined_witness: &mut E::G1Projective, @@ -67,7 +66,7 @@ impl> SonicKZG10 { // Accumulate values in the BTreeMap *combined_comms .entry(degree_bound) - .or_insert_with(E::G1Projective::zero) += &comm_with_challenge; + .or_insert(E::G1Projective::zero()) += &comm_with_challenge; curr_challenge = opening_challenges(opening_challenge_counter); opening_challenge_counter += 1; } @@ -170,7 +169,7 @@ where let enforced_degree_bounds = enforced_degree_bounds.map(|bounds| { let mut v = bounds.to_vec(); - v.sort_unstable(); + v.sort(); v.dedup(); v }); From ee7318ce144f1b6107857fb0c7faffd9a85ca688 Mon Sep 17 00:00:00 2001 From: oblivious-app <55861861+oblivious-app@users.noreply.github.com> Date: Fri, 25 Dec 2020 23:29:30 -0800 Subject: [PATCH 33/56] reduce the PR size --- Cargo.toml | 2 +- src/ipa_pc/mod.rs | 4 +--- src/kzg10/data_structures.rs | 4 ++-- src/kzg10/mod.rs | 6 ++---- src/lib.rs | 1 - 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d4bf4d0e..79a6ac09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,7 @@ incremental = true debug = true [features] -default = ["std", "parallel"] +default = [ "std", "parallel" ] std = [ "ark-ff/std", "ark-ec/std", "ark-nonnative-field/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std" ] r1cs = [ "ark-relations", "ark-r1cs-std", "ark-nonnative-field", "hashbrown" ] print-trace = [ "bench-utils/print-trace" ] diff --git a/src/ipa_pc/mod.rs b/src/ipa_pc/mod.rs index f287c221..c7091525 100644 --- a/src/ipa_pc/mod.rs +++ b/src/ipa_pc/mod.rs @@ -261,7 +261,7 @@ impl> InnerProductArg if degree_bound.is_some() { commitment = Commitment { comm: comms[i].clone(), - shifted_comm: Some(comms[i + 1]).clone(), + shifted_comm: Some(comms[i + 1].clone()), }; i += 2; @@ -553,7 +553,6 @@ where if has_hiding { let mut rng = rng.expect("hiding commitments require randomness"); let hiding_time = start_timer!(|| "Applying hiding."); - let mut hiding_polynomial = P::rand(d, &mut rng); hiding_polynomial -= &P::from_coefficients_slice(&[hiding_polynomial.evaluate(point)]); @@ -608,7 +607,6 @@ where let h_prime = ck.h.mul(round_challenge).into_affine(); // Pads the coefficients with zeroes to get the number of coeff to be d+1 - let mut coeffs = combined_polynomial.coeffs().to_vec(); if coeffs.len() < d + 1 { for _ in coeffs.len()..(d + 1) { diff --git a/src/kzg10/data_structures.rs b/src/kzg10/data_structures.rs index 372f651e..90bb7d2b 100644 --- a/src/kzg10/data_structures.rs +++ b/src/kzg10/data_structures.rs @@ -334,7 +334,7 @@ impl PreparedVerifierKey { let supported_bits = E::Fr::size_in_bits(); let mut prepared_g = Vec::::new(); - let mut g = E::G1Projective::from(vk.g); + let mut g = E::G1Projective::from(vk.g.clone()); for _ in 0..supported_bits { prepared_g.push(g.clone().into()); g.double_in_place(); @@ -423,7 +423,7 @@ impl PreparedCommitment { /// prepare `PreparedCommitment` from `Commitment` pub fn prepare(comm: &Commitment) -> Self { let mut prepared_comm = Vec::::new(); - let mut cur = E::G1Projective::from(comm.0); + let mut cur = E::G1Projective::from(comm.0.clone()); let supported_bits = E::Fr::size_in_bits(); diff --git a/src/kzg10/mod.rs b/src/kzg10/mod.rs index 349e1200..797747c3 100644 --- a/src/kzg10/mod.rs +++ b/src/kzg10/mod.rs @@ -138,7 +138,6 @@ where } /// Outputs a commitment to `polynomial`. - #[allow(clippy::type_complexity)] pub fn commit( powers: &Powers, polynomial: &P, @@ -197,7 +196,6 @@ where /// The witness polynomial w(x) the quotient of the division (p(x) - p(z)) / (x - z) /// Observe that this quotient does not change with z because /// p(z) is the remainder term. We can therefore omit p(z) when computing the quotient. - #[allow(clippy::type_complexity)] pub fn compute_witness_polynomial( p: &P, point: P::Point, @@ -418,12 +416,12 @@ where if enforced_degree_bounds.binary_search(&bound).is_err() { Err(Error::UnsupportedDegreeBound(bound)) } else if bound < p.degree() || bound > max_degree { - Err(Error::IncorrectDegreeBound { + return Err(Error::IncorrectDegreeBound { poly_degree: p.degree(), degree_bound: p.degree_bound().unwrap(), supported_degree, label: p.label().to_string(), - }) + }); } else { Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 320cbb04..1f4c1f20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,6 @@ #![deny(renamed_and_removed_lints, stable_features, unused_allocation)] #![deny(unused_comparisons, bare_trait_objects, unused_must_use, const_err)] #![forbid(unsafe_code)] -#![allow(clippy::op_ref)] #[macro_use] extern crate derivative; From f9baf704960281613148bb47f77e57a402359152 Mon Sep 17 00:00:00 2001 From: oblivious-app <55861861+oblivious-app@users.noreply.github.com> Date: Fri, 25 Dec 2020 23:33:42 -0800 Subject: [PATCH 34/56] reduce the PR size --- src/lib.rs | 68 +++++++-------------------------------------- src/sonic_pc/mod.rs | 15 ++++++---- 2 files changed, 20 insertions(+), 63 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1f4c1f20..d29843fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -220,64 +220,16 @@ pub trait PolynomialCommitment>: Sized { Self::Commitment: 'a, P: 'a, { - let rng = &mut crate::optional_rng::OptionalRng(rng); - let poly_rand_comm: BTreeMap<_, _> = labeled_polynomials - .into_iter() - .zip(rands) - .zip(commitments.into_iter()) - .map(|((poly, r), comm)| (poly.label(), (poly, r, comm))) - .collect(); - - let open_time = start_timer!(|| format!( - "Opening {} polynomials at query set of size {}", - poly_rand_comm.len(), - query_set.len(), - )); - - let mut query_to_labels_map = BTreeMap::new(); - - for (label, (point_label, point)) in query_set.iter() { - let labels = query_to_labels_map - .entry(point_label) - .or_insert((point, BTreeSet::new())); - labels.1.insert(label); - } - - let mut proofs = Vec::new(); - for (_point_label, (point, labels)) in query_to_labels_map.into_iter() { - let mut query_polys: Vec<&'a LabeledPolynomial<_, P>> = Vec::new(); - let mut query_rands: Vec<&'a Self::Randomness> = Vec::new(); - let mut query_comms: Vec<&'a LabeledCommitment> = Vec::new(); - - for label in labels { - let (polynomial, rand, comm) = - poly_rand_comm.get(label).ok_or(Error::MissingPolynomial { - label: label.to_string(), - })?; - - query_polys.push(polynomial); - query_rands.push(rand); - query_comms.push(comm); - } - - let proof_time = start_timer!(|| "Creating proof"); - let proof = Self::open( - ck, - query_polys, - query_comms, - point, - opening_challenge, - query_rands, - Some(rng), - )?; - - end_timer!(proof_time); - - proofs.push(proof); - } - end_timer!(open_time); - - Ok(proofs.into()) + let opening_challenges = |pow| opening_challenge.pow(&[pow]); + Self::batch_open_individual_opening_challenges( + ck, + labeled_polynomials, + commitments, + query_set, + &opening_challenges, + rands, + rng, + ) } /// Verifies that `values` are the evaluations at `point` of the polynomials diff --git a/src/sonic_pc/mod.rs b/src/sonic_pc/mod.rs index d30804d3..54390047 100644 --- a/src/sonic_pc/mod.rs +++ b/src/sonic_pc/mod.rs @@ -269,7 +269,6 @@ where } /// Outputs a commitment to `polynomial`. - #[allow(clippy::type_complexity)] fn commit<'a>( ck: &Self::CommitterKey, polynomials: impl IntoIterator>, @@ -290,7 +289,10 @@ where let mut randomness: Vec = Vec::new(); for labeled_polynomial in polynomials { - let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); + let enforced_degree_bounds: Option<&[usize]> = ck + .enforced_degree_bounds + .as_ref() + .map(|bounds| bounds.as_slice()); kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), @@ -356,7 +358,10 @@ where opening_challenge_counter += 1; for (polynomial, rand) in labeled_polynomials.into_iter().zip(rands) { - let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); + let enforced_degree_bounds: Option<&[usize]> = ck + .enforced_degree_bounds + .as_ref() + .map(|bounds| bounds.as_slice()); kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), @@ -562,7 +567,7 @@ where let comms: Vec = E::G1Projective::batch_normalization_into_affine(&lc_commitments) .into_iter() - .map(kzg10::Commitment::) + .map(|c| kzg10::Commitment::(c)) .collect(); let lc_commitments = lc_info @@ -647,7 +652,7 @@ where let comms: Vec = E::G1Projective::batch_normalization_into_affine(&lc_commitments) .into_iter() - .map(kzg10::Commitment) + .map(|c| kzg10::Commitment(c)) .collect(); let lc_commitments = lc_info From cc2cfc06ac17f1ef6a3733c29099f324adc407aa Mon Sep 17 00:00:00 2001 From: oblivious-app <55861861+oblivious-app@users.noreply.github.com> Date: Fri, 25 Dec 2020 23:38:02 -0800 Subject: [PATCH 35/56] reduce the PR size --- src/marlin_pc/mod.rs | 171 ++----------------------------------------- 1 file changed, 7 insertions(+), 164 deletions(-) diff --git a/src/marlin_pc/mod.rs b/src/marlin_pc/mod.rs index 72cb5215..aa742865 100644 --- a/src/marlin_pc/mod.rs +++ b/src/marlin_pc/mod.rs @@ -5,7 +5,7 @@ use crate::{LabeledCommitment, LabeledPolynomial, LinearCombination}; use crate::{PCRandomness, PCUniversalParams, PolynomialCommitment, UVPolynomial}; use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; -use ark_ff::{Field, One, Zero}; +use ark_ff::{One, Zero}; use ark_std::{convert::TryInto, marker::PhantomData, ops::Div, vec}; use rand_core::RngCore; @@ -352,166 +352,6 @@ where Ok((commitments, randomness)) } - /// On input a polynomial `p` and a point `point`, outputs a proof for the same. - fn open<'a>( - ck: &Self::CommitterKey, - labeled_polynomials: impl IntoIterator>, - commitments: impl IntoIterator>, - point: &'a P::Point, - opening_challenge: E::Fr, - rands: impl IntoIterator, - rng: Option<&mut dyn RngCore>, - ) -> Result - where - Randomness: 'a, - Commitment: 'a, - { - let opening_challenges = |j| opening_challenge.pow([j]); - Self::open_individual_opening_challenges( - ck, - labeled_polynomials, - commitments, - &point, - &opening_challenges, - rands, - rng, - ) - } - - /// Verifies that `value` is the evaluation at `x` of the polynomial - /// committed inside `comm`. - fn check<'a>( - vk: &Self::VerifierKey, - commitments: impl IntoIterator>, - point: &'a P::Point, - values: impl IntoIterator, - proof: &Self::Proof, - opening_challenge: E::Fr, - rng: Option<&mut dyn RngCore>, - ) -> Result - where - Self::Commitment: 'a, - { - let opening_challenges = |j| opening_challenge.pow([j]); - Self::check_individual_opening_challenges( - vk, - commitments, - &point, - values, - proof, - &opening_challenges, - rng, - ) - } - - fn batch_check<'a, R: RngCore>( - vk: &Self::VerifierKey, - commitments: impl IntoIterator>, - query_set: &QuerySet, - evaluations: &Evaluations, - proof: &Self::BatchProof, - opening_challenge: E::Fr, - rng: &mut R, - ) -> Result - where - Self::Commitment: 'a, - { - let opening_challenges = |j| opening_challenge.pow([j]); - Self::batch_check_individual_opening_challenges( - vk, - commitments, - query_set, - evaluations, - proof, - &opening_challenges, - rng, - ) - } - - fn open_combinations<'a>( - ck: &Self::CommitterKey, - lc_s: impl IntoIterator>, - polynomials: impl IntoIterator>, - commitments: impl IntoIterator>, - query_set: &QuerySet, - opening_challenge: E::Fr, - rands: impl IntoIterator, - rng: Option<&mut dyn RngCore>, - ) -> Result, Self::Error> - where - P: 'a, - Self::Randomness: 'a, - Self::Commitment: 'a, - { - let opening_challenges = |j| opening_challenge.pow([j]); - Self::open_combinations_individual_opening_challenges( - ck, - lc_s, - polynomials, - commitments, - query_set, - &opening_challenges, - rands, - rng, - ) - } - - /// Checks that `values` are the true evaluations at `query_set` of the polynomials - /// committed in `labeled_commitments`. - fn check_combinations<'a, R: RngCore>( - vk: &Self::VerifierKey, - lc_s: impl IntoIterator>, - commitments: impl IntoIterator>, - query_set: &QuerySet, - evaluations: &Evaluations, - proof: &BatchLCProof, - opening_challenge: E::Fr, - rng: &mut R, - ) -> Result - where - Self::Commitment: 'a, - { - let opening_challenges = |j| opening_challenge.pow([j]); - Self::check_combinations_individual_opening_challenges( - vk, - lc_s, - commitments, - query_set, - evaluations, - proof, - &opening_challenges, - rng, - ) - } - - // On input a list of labeled polynomials and a query set, `open` outputs a proof of evaluation - /// of the polynomials at the points in the query set. - fn batch_open<'a>( - ck: &Self::CommitterKey, - labeled_polynomials: impl IntoIterator>, - commitments: impl IntoIterator>, - query_set: &QuerySet, - opening_challenge: E::Fr, - rands: impl IntoIterator, - rng: Option<&mut dyn RngCore>, - ) -> Result - where - P: 'a, - Self::Randomness: 'a, - Self::Commitment: 'a, - { - let opening_challenges = |j| opening_challenge.pow([j]); - Self::batch_open_individual_opening_challenges( - ck, - labeled_polynomials, - commitments, - query_set, - &opening_challenges, - rands, - rng, - ) - } - /// On input a polynomial `p` and a point `point`, outputs a proof for the same. fn open_individual_opening_challenges<'a>( ck: &CommitterKey, @@ -539,7 +379,10 @@ where let degree_bound = polynomial.degree_bound(); assert_eq!(degree_bound.is_some(), rand.shifted_rand.is_some()); - let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); + let enforced_degree_bounds: Option<&[usize]> = ck + .enforced_degree_bounds + .as_ref() + .map(|bounds| bounds.as_slice()); kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), ck.max_degree, @@ -869,7 +712,7 @@ where } else if cur_comm.degree_bound().is_some() { return Err(Error::EquationHasDegreeBounds(lc_label)); } - coeffs_and_comms.push((*coeff, cur_comm.commitment())); + coeffs_and_comms.push((coeff.clone(), cur_comm.commitment())); } } let lc_time = @@ -972,7 +815,7 @@ where } end_timer!(open_time); - Ok(proofs) + Ok(proofs.into()) } } From a005c2d028f1f935cfa4f2985f613eb700b4ffef Mon Sep 17 00:00:00 2001 From: oblivious-app <55861861+oblivious-app@users.noreply.github.com> Date: Fri, 25 Dec 2020 23:44:59 -0800 Subject: [PATCH 36/56] minimize the PR size --- src/kzg10/mod.rs | 4 ++-- src/lib.rs | 2 +- src/marlin_pc/data_structures.rs | 16 ++++++++-------- src/marlin_pc/mod.rs | 24 +++++++++++++----------- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/kzg10/mod.rs b/src/kzg10/mod.rs index 797747c3..cbf5c81c 100644 --- a/src/kzg10/mod.rs +++ b/src/kzg10/mod.rs @@ -221,7 +221,7 @@ where Ok((witness_polynomial, random_witness_polynomial)) } - pub(crate) fn open_with_witness_polynomial( + pub(crate) fn open_with_witness_polynomial<'a>( powers: &Powers, point: P::Point, randomness: &Randomness, @@ -265,7 +265,7 @@ where } /// On input a polynomial `p` and a point `point`, outputs a proof for the same. - pub(crate) fn open( + pub(crate) fn open<'a>( powers: &Powers, p: &P, point: P::Point, diff --git a/src/lib.rs b/src/lib.rs index d29843fc..03ee5f5d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -510,7 +510,7 @@ pub trait PolynomialCommitment>: Sized { let eval = match label { LCTerm::One => F::one(), LCTerm::PolyLabel(l) => *poly_evals - .get(&(l.into(), point.clone())) + .get(&(l.clone().into(), point.clone())) .ok_or(Error::MissingEvaluation { label: l.clone() })?, }; diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index e13e5276..74fade18 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -44,7 +44,7 @@ pub struct CommitterKey { impl CommitterKey { /// Obtain powers for the underlying KZG10 construction - pub fn powers(&self) -> kzg10::Powers { + pub fn powers<'a>(&self) -> kzg10::Powers<'a, E> { kzg10::Powers { powers_of_g: self.powers.as_slice().into(), powers_of_gamma_g: self.powers_of_gamma_g.as_slice().into(), @@ -52,10 +52,10 @@ impl CommitterKey { } /// Obtain powers for committing to shifted polynomials. - pub fn shifted_powers( - &self, + pub fn shifted_powers<'a>( + &'a self, degree_bound: impl Into>, - ) -> Option> { + ) -> Option> { self.shifted_powers.as_ref().map(|shifted_powers| { let powers_range = if let Some(degree_bound) = degree_bound.into() { assert!(self @@ -205,13 +205,13 @@ impl PCPreparedVerifierKey> for PreparedVerifie for (d, shift_power) in degree_bounds_and_shift_powers { let mut prepared_shift_power = Vec::::new(); - let mut cur = E::G1Projective::from(*shift_power); + let mut cur = E::G1Projective::from(shift_power.clone()); for _ in 0..supported_bits { prepared_shift_power.push(cur.clone().into()); cur.double_in_place(); } - res.push((*d, prepared_shift_power)); + res.push((d.clone(), prepared_shift_power)); } Some(res) @@ -315,7 +315,7 @@ impl PCPreparedCommitment> for PreparedCommitmen fn prepare(comm: &Commitment) -> Self { let prepared_comm = kzg10::PreparedCommitment::::prepare(&comm.comm); - let shifted_comm = comm.shifted_comm; + let shifted_comm = comm.shifted_comm.clone(); Self { prepared_comm, @@ -361,7 +361,7 @@ impl<'a, F: PrimeField, P: UVPolynomial> AddAssign<&'a Self> for Randomness> MarlinKZG10 { (combined_comm, combined_shifted_comm) } - fn normalize_commitments( + fn normalize_commitments<'a>( commitments: Vec<(E::G1Projective, Option)>, ) -> Vec> { let mut comms = Vec::with_capacity(commitments.len()); @@ -95,7 +95,7 @@ impl> MarlinKZG10 { } } let comms = E::G1Projective::batch_normalization_into_affine(&comms); - let s_comms = E::G1Projective::batch_normalization_into_affine(&s_comms); + let s_comms = E::G1Projective::batch_normalization_into_affine(&mut s_comms); comms .into_iter() .zip(s_comms) @@ -151,7 +151,7 @@ impl> MarlinKZG10 { .get_shift_power(degree_bound) .ok_or(Error::UnsupportedDegreeBound(degree_bound))?; - let mut adjusted_comm = shifted_comm - &shift_power.mul(value); + let mut adjusted_comm = shifted_comm - &shift_power.mul(value.clone()); adjusted_comm *= challenge_i_1; combined_comm += &adjusted_comm; @@ -217,17 +217,17 @@ where // Construct the core KZG10 verifier key. let vk = kzg10::VerifierKey { - g: pp.powers_of_g[0], + g: pp.powers_of_g[0].clone(), gamma_g: pp.powers_of_gamma_g[&0], - h: pp.h, - beta_h: pp.beta_h, + h: pp.h.clone(), + beta_h: pp.beta_h.clone(), prepared_h: pp.prepared_h.clone(), prepared_beta_h: pp.prepared_beta_h.clone(), }; let enforced_degree_bounds = enforced_degree_bounds.map(|v| { let mut v = v.to_vec(); - v.sort_unstable(); + v.sort(); v.dedup(); v }); @@ -239,7 +239,7 @@ where (None, None) } else { let mut sorted_enforced_degree_bounds = enforced_degree_bounds.clone(); - sorted_enforced_degree_bounds.sort_unstable(); + sorted_enforced_degree_bounds.sort(); let lowest_shifted_power = max_degree - sorted_enforced_degree_bounds @@ -268,7 +268,7 @@ where powers, shifted_powers, powers_of_gamma_g, - enforced_degree_bounds, + enforced_degree_bounds: enforced_degree_bounds, max_degree, }; @@ -282,7 +282,6 @@ where } /// Outputs a commitment to `polynomial`. - #[allow(clippy::type_complexity)] fn commit<'a>( ck: &Self::CommitterKey, polynomials: impl IntoIterator>, @@ -309,7 +308,10 @@ where let hiding_bound = p.hiding_bound(); let polynomial: &P = p.polynomial(); - let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); + let enforced_degree_bounds: Option<&[usize]> = ck + .enforced_degree_bounds + .as_ref() + .map(|bounds| bounds.as_slice()); kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), ck.max_degree, From 5a2ef01db8e7768f83d801736787dcc4548a35a6 Mon Sep 17 00:00:00 2001 From: Howard Wu <9260812+howardwu@users.noreply.github.com> Date: Fri, 29 Jan 2021 08:57:19 -0800 Subject: [PATCH 37/56] Updates Marlin constraints to latest LC representation (#68) * Updates marlin constraints to latest LC representation * Cargo fmt --- Cargo.toml | 1 + src/constraints.rs | 2 +- src/marlin_pc/constraints.rs | 146 +++++++++++++++---------------- src/marlin_pc/data_structures.rs | 4 +- 4 files changed, 76 insertions(+), 77 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 79a6ac09..cf3add1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ rand_core = { version = "0.5", default-features = false } digest = "0.8" rayon = { version = "1", optional = true } derivative = { version = "2", features = [ "use_core" ] } +tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } [dev-dependencies] rand = { version = "0.7", default-features = false } diff --git a/src/constraints.rs b/src/constraints.rs index 57f74d19..41fe3582 100644 --- a/src/constraints.rs +++ b/src/constraints.rs @@ -73,7 +73,7 @@ impl } } -#[derive(Clone)] +#[derive(Clone, Debug)] /// A collection of random data used in the polynomial commitment checking. pub struct PCCheckRandomDataVar { /// Opening challenges. diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index a801402a..877003ff 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -1,12 +1,13 @@ use crate::{ - constraints::{EvaluationsVar, PCCheckVar, QuerySetVar}, + constraints::{EvaluationsVar, LabeledPointVar, PCCheckRandomDataVar, PCCheckVar, QuerySetVar}, data_structures::LabeledCommitment, kzg10::{Proof, VerifierKey as KZG10VerifierKey}, marlin_pc::{ data_structures::{Commitment, VerifierKey}, MarlinKZG10, PreparedCommitment, PreparedVerifierKey, }, - BTreeMap, BTreeSet, BatchLCProof, LinearCombinationVar, PrepareVar, String, ToString, Vec, + BTreeMap, BTreeSet, BatchLCProof, LinearCombinationCoeffVar, LinearCombinationVar, + PrepareGadget, String, ToString, Vec, }; use ark_ec::{CycleEngine, PairingEngine}; use ark_ff::{fields::Field, PrimeField, ToConstraintField}; @@ -395,7 +396,7 @@ where } } -impl PrepareVar, ::Fr> +impl PrepareGadget, ::Fr> for PreparedVerifierKeyVar where CycleE: CycleEngine, @@ -751,7 +752,7 @@ where } } -impl PrepareVar, ::Fr> +impl PrepareGadget, ::Fr> for PreparedCommitmentVar where CycleE: CycleEngine, @@ -779,23 +780,6 @@ where shifted_comm: unprepared.shifted_comm.clone(), }) } - - #[tracing::instrument(target = "r1cs", skip(unprepared))] - fn prepare_small(unprepared: &CommitmentVar) -> R1CSResult { - let mut prepared_comm = Vec::::new(); - let supported_bits = 128; - - let mut cur: PG::G1Var = unprepared.comm.clone(); - for _ in 0..supported_bits { - prepared_comm.push(cur.clone()); - cur.double_in_place()?; - } - - Ok(Self { - prepared_comm, - shifted_comm: unprepared.shifted_comm.clone(), - }) - } } impl AllocVar, ::Fr> @@ -1007,7 +991,7 @@ where } } -impl PrepareVar, ::Fr> +impl PrepareGadget, ::Fr> for PreparedLabeledCommitmentVar where CycleE: CycleEngine, @@ -1192,7 +1176,7 @@ where let BatchLCProof { proof, evals } = proof.borrow().clone(); - let proofs: Vec> = proof; + let proofs: Vec> = proof.to_vec(); let proofs: Vec> = proofs .iter() .map(|p| { @@ -1361,10 +1345,10 @@ where let mut query_to_labels_map = BTreeMap::new(); - for (label, (point_label, point)) in query_set.0.iter() { + for (label, point) in query_set.0.iter() { let labels = query_to_labels_map - .entry((*point_label).clone()) - .or_insert((point, BTreeSet::new())); + .entry(point.name.clone()) + .or_insert((point.value.clone(), BTreeSet::new())); labels.1.insert(label); } @@ -1395,7 +1379,13 @@ where for label in labels.into_iter() { let commitment_lc = commitment_lcs.get(label).unwrap().clone(); - let v_i = evaluations.0.get(&(label.clone(), point.clone())).unwrap(); + let v_i = evaluations + .0 + .get(&LabeledPointVar { + name: label.clone(), + value: point.clone(), + }) + .unwrap(); comms_to_combine.push(commitment_lc.1.clone()); values_to_combine.push(v_i.clone()); @@ -1669,28 +1659,22 @@ where ::Fr, >, proofs: &[Self::ProofVar], - opening_challenges: &[NonNativeFieldVar< - ::Fr, - ::Fr, - >], - opening_challenges_bits: &[Vec::Fr>>], - batching_rands: &[NonNativeFieldVar< + rand_data: &PCCheckRandomDataVar< ::Fr, ::Fr, - >], - batching_rands_bits: &[Vec::Fr>>], + >, ) -> R1CSResult::Fr>> { - let mut batching_rands = batching_rands.to_vec(); - let mut batching_rands_bits = batching_rands_bits.to_vec(); + let mut batching_rands = rand_data.batching_rands.to_vec(); + let mut batching_rands_bits = rand_data.batching_rands_bits.to_vec(); let commitments: BTreeMap<_, _> = commitments.iter().map(|c| (c.label.clone(), c)).collect(); let mut query_to_labels_map = BTreeMap::new(); - for (label, (point_label, point)) in query_set.0.iter() { + for (label, point) in query_set.0.iter() { let labels = query_to_labels_map - .entry((*point_label).clone()) - .or_insert((point, BTreeSet::new())); + .entry(point.name.clone()) + .or_insert((point.value.clone(), BTreeSet::new())); labels.1.insert(label); } @@ -1709,7 +1693,13 @@ where commitment.commitment.shifted_comm.is_some() ); - let v_i = evaluations.0.get(&(label.clone(), point.clone())).unwrap(); + let v_i = evaluations + .0 + .get(&LabeledPointVar { + name: label.clone(), + value: point.clone(), + }) + .unwrap(); comms_to_combine.push(commitment.clone()); values_to_combine.push(v_i.clone()); @@ -1727,8 +1717,9 @@ where for (labeled_commitment, value) in comms_to_combine.into_iter().zip(values_to_combine.iter()) { - let challenge = opening_challenges[opening_challenges_counter].clone(); - let challenge_bits = opening_challenges_bits[opening_challenges_counter].clone(); + let challenge = rand_data.opening_challenges[opening_challenges_counter].clone(); + let challenge_bits = + rand_data.opening_challenges_bits[opening_challenges_counter].clone(); opening_challenges_counter += 1; let LabeledCommitmentVar { @@ -1750,7 +1741,7 @@ where // v_i is the evaluation, in the cocmbined commitment, if let Some(degree_bound) = degree_bound { let challenge_shifted_bits = - opening_challenges_bits[opening_challenges_counter].clone(); + rand_data.opening_challenges_bits[opening_challenges_counter].clone(); opening_challenges_counter += 1; let shifted_comm = shifted_comm.as_ref().unwrap().clone(); @@ -1873,16 +1864,10 @@ where ::Fr, >, proof: &Self::BatchLCProofVar, - opening_challenges: &[NonNativeFieldVar< - ::Fr, - ::Fr, - >], - opening_challenges_bits: &[Vec::Fr>>], - batching_rands: &[NonNativeFieldVar< + rand_data: &PCCheckRandomDataVar< ::Fr, ::Fr, - >], - batching_rands_bits: &[Vec::Fr>>], + >, ) -> R1CSResult::Fr>> { let BatchLCProofVar { proofs, .. } = proof; @@ -1903,35 +1888,48 @@ where let mut coeffs_and_comms = Vec::new(); - for (coeff, label, negate) in lc.terms.iter() { + for (coeff, label) in lc.terms.iter() { if label.is_one() { - assert!(coeff.is_some()); - - let coeff = coeff.clone().unwrap(); - - for (&(ref label, _), ref mut eval) in evaluations.0.iter_mut() { - if label == &lc_label { - if negate.eq(&true) { - **eval = (**eval).clone() + &coeff; - } else { - **eval = (**eval).clone() - &coeff; - } + for (label, ref mut eval) in evaluations.0.iter_mut() { + if label.name == lc_label { + match coeff.clone() { + LinearCombinationCoeffVar::One => { + **eval = (**eval).clone() - &NonNativeFieldVar::one() + } + LinearCombinationCoeffVar::MinusOne => { + **eval = (**eval).clone() + &NonNativeFieldVar::one() + } + LinearCombinationCoeffVar::Var(variable) => { + **eval = (**eval).clone() - &variable + } + }; } } } else { let label: &String = label.try_into().unwrap(); let &cur_comm = label_comm_map.get(label).unwrap(); + let negate = match coeff { + LinearCombinationCoeffVar::One | LinearCombinationCoeffVar::Var(_) => false, + LinearCombinationCoeffVar::MinusOne => true, + }; if num_polys == 1 && cur_comm.degree_bound.is_some() { - assert!(coeff.is_none()); - assert!(negate.eq(&false)); + assert!(!negate); } + let coeff = match coeff { + LinearCombinationCoeffVar::One => Some(NonNativeFieldVar::one()), + LinearCombinationCoeffVar::MinusOne => { + Some(NonNativeFieldVar::zero() - NonNativeFieldVar::one()) + } + LinearCombinationCoeffVar::Var(variable) => Some(variable.clone()), + }; + coeffs_and_comms.push(( coeff.clone(), cur_comm.degree_bound.clone(), cur_comm.prepared_commitment.clone(), - *negate, + negate, )); } } @@ -1942,18 +1940,18 @@ where Self::prepared_batch_check_evaluations( cs, prepared_verification_key, - &lc_info, + lc_info.as_slice(), &query_set, &evaluations, proofs, - opening_challenges, - opening_challenges_bits, - batching_rands, - batching_rands_bits, + &rand_data.opening_challenges, + &rand_data.opening_challenges_bits, + &rand_data.batching_rands, + &rand_data.batching_rands_bits, ) } - fn create_labeled_commitment_gadget( + fn create_labeled_commitment( label: String, commitment: Self::CommitmentVar, degree_bound: Option::Fr>>, @@ -1965,7 +1963,7 @@ where } } - fn create_prepared_labeled_commitment_gadget( + fn create_prepared_labeled_commitment( label: String, prepared_commitment: Self::PreparedCommitmentVar, degree_bound: Option::Fr>>, diff --git a/src/marlin_pc/data_structures.rs b/src/marlin_pc/data_structures.rs index 74fade18..95d664d7 100644 --- a/src/marlin_pc/data_structures.rs +++ b/src/marlin_pc/data_structures.rs @@ -46,8 +46,8 @@ impl CommitterKey { /// Obtain powers for the underlying KZG10 construction pub fn powers<'a>(&self) -> kzg10::Powers<'a, E> { kzg10::Powers { - powers_of_g: self.powers.as_slice().into(), - powers_of_gamma_g: self.powers_of_gamma_g.as_slice().into(), + powers_of_g: ark_std::borrow::Cow::Owned(self.powers.clone()), + powers_of_gamma_g: ark_std::borrow::Cow::Owned(self.powers_of_gamma_g.clone()), } } From ebcf462b3839df3cb2d6a36bf838b652bd4a677c Mon Sep 17 00:00:00 2001 From: weikeng Date: Thu, 4 Feb 2021 22:23:16 -0800 Subject: [PATCH 38/56] bump digest abnd blake2 --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cf3add1e..e1fed511 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ hashbrown = { version = "0.9", optional = true } bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } rand_core = { version = "0.5", default-features = false } -digest = "0.8" +digest = "0.9" rayon = { version = "1", optional = true } derivative = { version = "2", features = [ "use_core" ] } tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } @@ -45,7 +45,7 @@ rand = { version = "0.7", default-features = false } ark-ed-on-bls12-381 = { git = "https://github.com/arkworks-rs/curves", default-features = false } ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves", default-features = false, features = [ "curve" ] } ark-bls12-377 = { git = "https://github.com/arkworks-rs/curves", default-features = false, features = [ "curve" ] } -blake2 = { version = "0.8", default-features = false } +blake2 = { version = "0.9", default-features = false } [profile.release] opt-level = 3 From 417154a1f83930ce279ba0da3cf3216d56e66a5a Mon Sep 17 00:00:00 2001 From: Weikeng Chen Date: Mon, 8 Feb 2021 01:38:15 -0800 Subject: [PATCH 39/56] Update src/marlin_pc/constraints.rs Co-authored-by: Pratyush Mishra --- src/marlin_pc/constraints.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/marlin_pc/constraints.rs b/src/marlin_pc/constraints.rs index 877003ff..bed4a13b 100644 --- a/src/marlin_pc/constraints.rs +++ b/src/marlin_pc/constraints.rs @@ -28,7 +28,7 @@ use ark_std::{ borrow::Borrow, convert::TryInto, marker::PhantomData, ops::Div, ops::MulAssign, vec, }; -/// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. +/// High level variable representing the verification key of the `MarlinKZG10` polynomial commitment scheme. #[allow(clippy::type_complexity)] pub struct VerifierKeyVar< CycleE: CycleEngine, From 9a633fb4710af34795c03fc752e764c4a41e3c04 Mon Sep 17 00:00:00 2001 From: weikeng Date: Mon, 8 Feb 2021 02:01:20 -0800 Subject: [PATCH 40/56] simplify and refactor --- Cargo.toml | 1 - src/data_structures.rs | 8 -------- src/kzg10/data_structures.rs | 9 --------- src/{ => marlin}/marlin_pc/constraints.rs | 0 src/marlin/marlin_pc/data_structures.rs | 16 ---------------- 5 files changed, 34 deletions(-) rename src/{ => marlin}/marlin_pc/constraints.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 2da5ea21..066ac5e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,6 @@ rand_core = { version = "0.5", default-features = false } digest = "0.9" rayon = { version = "1", optional = true } derivative = { version = "2", features = [ "use_core" ] } -tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } diff --git a/src/data_structures.rs b/src/data_structures.rs index 55473c67..f5098198 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -226,14 +226,6 @@ impl LabeledCommitment { } } -impl> ToConstraintField - for LabeledCommitment -{ - fn to_field_elements(&self) -> Option> { - self.commitment.to_field_elements() - } -} - impl ark_ff::ToBytes for LabeledCommitment { #[inline] fn write(&self, writer: W) -> ark_std::io::Result<()> { diff --git a/src/kzg10/data_structures.rs b/src/kzg10/data_structures.rs index 981b3309..4bb95430 100644 --- a/src/kzg10/data_structures.rs +++ b/src/kzg10/data_structures.rs @@ -403,15 +403,6 @@ impl<'a, E: PairingEngine> AddAssign<(E::Fr, &'a Commitment)> for Commitment< } } -impl ToConstraintField<::BasePrimeField> for Commitment -where - E::G1Affine: ToConstraintField<::BasePrimeField>, -{ - fn to_field_elements(&self) -> Option::BasePrimeField>> { - self.0.to_field_elements() - } -} - /// `PreparedCommitment` commits to a polynomial and prepares for mul_bits. #[derive(Derivative)] #[derivative( diff --git a/src/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs similarity index 100% rename from src/marlin_pc/constraints.rs rename to src/marlin/marlin_pc/constraints.rs diff --git a/src/marlin/marlin_pc/data_structures.rs b/src/marlin/marlin_pc/data_structures.rs index ca2f25a9..a87ab709 100644 --- a/src/marlin/marlin_pc/data_structures.rs +++ b/src/marlin/marlin_pc/data_structures.rs @@ -296,22 +296,6 @@ impl PCCommitment for Commitment { } } -impl ToConstraintField<::BasePrimeField> for Commitment -where - E::G1Affine: ToConstraintField<::BasePrimeField>, -{ - fn to_field_elements(&self) -> Option::BasePrimeField>> { - let mut res = Vec::new(); - res.extend_from_slice(&self.comm.to_field_elements().unwrap()); - - if let Some(shifted_comm) = &self.shifted_comm { - res.extend_from_slice(&shifted_comm.to_field_elements().unwrap()); - } - - Some(res) - } -} - /// Prepared commitment to a polynomial that optionally enforces a degree bound. #[derive(Derivative)] #[derivative( From 453841b529a7b1d5cf010e28cf9b86904524e383 Mon Sep 17 00:00:00 2001 From: weikeng Date: Mon, 8 Feb 2021 02:02:37 -0800 Subject: [PATCH 41/56] remove density-optimized feature --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 066ac5e0..75f8be20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,4 +66,3 @@ std = [ "ark-ff/std", "ark-ec/std", "ark-nonnative-field/std", "ark-poly/std", " r1cs = [ "ark-relations", "ark-r1cs-std", "ark-nonnative-field", "hashbrown" ] print-trace = [ "bench-utils/print-trace" ] parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ] -density-optimized = [ "r1cs", "ark-nonnative-field/density-optimized" ] From 9f328fba6786f0dd2f96d119101cc436a9c16cea Mon Sep 17 00:00:00 2001 From: weikeng Date: Mon, 8 Feb 2021 02:09:52 -0800 Subject: [PATCH 42/56] use PairingFriendlyCycle instead of CycleEngine --- src/marlin/marlin_pc/constraints.rs | 78 ++++++++++++++--------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index bed4a13b..813fb53f 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -9,7 +9,7 @@ use crate::{ BTreeMap, BTreeSet, BatchLCProof, LinearCombinationCoeffVar, LinearCombinationVar, PrepareGadget, String, ToString, Vec, }; -use ark_ec::{CycleEngine, PairingEngine}; +use ark_ec::{PairingEngine, PairingFriendlyCycle}; use ark_ff::{fields::Field, PrimeField, ToConstraintField}; use ark_nonnative_field::{NonNativeFieldMulResultVar, NonNativeFieldVar}; use ark_poly::UVPolynomial; @@ -31,7 +31,7 @@ use ark_std::{ /// High level variable representing the verification key of the `MarlinKZG10` polynomial commitment scheme. #[allow(clippy::type_complexity)] pub struct VerifierKeyVar< - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, > where ::G1Projective: MulAssign<::Fq>, @@ -54,7 +54,7 @@ pub struct VerifierKeyVar< impl VerifierKeyVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -140,7 +140,7 @@ where impl Clone for VerifierKeyVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -162,7 +162,7 @@ where impl AllocVar, ::Fr> for VerifierKeyVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -231,8 +231,7 @@ where impl ToBytesGadget<::Fr> for VerifierKeyVar where - CycleE: CycleEngine, - + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -265,8 +264,7 @@ where impl ToConstraintFieldGadget<::Fr> for VerifierKeyVar where - CycleE: CycleEngine, - + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -307,7 +305,7 @@ where /// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. #[allow(clippy::type_complexity)] pub struct PreparedVerifierKeyVar< - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, > where ::G1Projective: MulAssign<::Fq>, @@ -339,7 +337,7 @@ pub struct PreparedVerifierKeyVar< impl PreparedVerifierKeyVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -399,7 +397,7 @@ where impl PrepareGadget, ::Fr> for PreparedVerifierKeyVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -457,7 +455,7 @@ where impl Clone for PreparedVerifierKeyVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -483,7 +481,7 @@ where impl AllocVar, ::Fr> for PreparedVerifierKeyVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -582,7 +580,7 @@ where /// Var for an optionally hiding Marlin-KZG10 commitment. pub struct CommitmentVar< - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, > where ::G1Projective: MulAssign<::Fq>, @@ -598,8 +596,7 @@ pub struct CommitmentVar< impl Clone for CommitmentVar where - CycleE: CycleEngine, - + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -619,8 +616,7 @@ where impl AllocVar, ::Fr> for CommitmentVar where - CycleE: CycleEngine, - + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -664,7 +660,7 @@ where impl ToConstraintFieldGadget<::Fr> for CommitmentVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -694,7 +690,7 @@ where impl ToBytesGadget<::Fr> for CommitmentVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -719,7 +715,7 @@ where /// Prepared gadget for an optionally hiding Marlin-KZG10 commitment. /// shifted_comm is not prepared, due to the specific use case. pub struct PreparedCommitmentVar< - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, > where ::G1Projective: MulAssign<::Fq>, @@ -735,7 +731,7 @@ pub struct PreparedCommitmentVar< impl Clone for PreparedCommitmentVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -755,7 +751,7 @@ where impl PrepareGadget, ::Fr> for PreparedCommitmentVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -785,7 +781,7 @@ where impl AllocVar, ::Fr> for PreparedCommitmentVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -852,7 +848,7 @@ where /// Var for a Marlin-KZG10 commitment, with a string label and degree bound. pub struct LabeledCommitmentVar< - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, > where ::G1Projective: MulAssign<::Fq>, @@ -872,7 +868,7 @@ pub struct LabeledCommitmentVar< impl Clone for LabeledCommitmentVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -894,7 +890,7 @@ impl AllocVar>, ::Fr> for LabeledCommitmentVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -953,7 +949,7 @@ where /// Var for a Marlin-KZG10 commitment, with a string label and degree bound. pub struct PreparedLabeledCommitmentVar< - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, > where ::G1Projective: MulAssign<::Fq>, @@ -973,7 +969,7 @@ pub struct PreparedLabeledCommitmentVar< impl Clone for PreparedLabeledCommitmentVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -994,7 +990,7 @@ where impl PrepareGadget, ::Fr> for PreparedLabeledCommitmentVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -1018,7 +1014,7 @@ where /// Var for a Marlin-KZG10 proof. #[allow(clippy::type_complexity)] pub struct ProofVar< - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, > where ::G1Projective: MulAssign<::Fq>, @@ -1038,7 +1034,7 @@ pub struct ProofVar< impl Clone for ProofVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -1058,7 +1054,7 @@ where impl AllocVar, ::Fr> for ProofVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, ::G2Projective: MulAssign<::Fq>, @@ -1100,7 +1096,7 @@ where /// An allocated version of `BatchLCProof`. #[allow(clippy::type_complexity)] pub struct BatchLCProofVar< - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, P: UVPolynomial<::Fr, Point = ::Fr>, PG: PairingVar::Fr>, > where @@ -1125,7 +1121,7 @@ pub struct BatchLCProofVar< impl Clone for BatchLCProofVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, P: UVPolynomial<::Fr, Point = ::Fr>, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, @@ -1150,7 +1146,7 @@ impl ::Fr, > for BatchLCProofVar where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, P: UVPolynomial<::Fr, Point = ::Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, PG: PairingVar::Fr>, @@ -1221,7 +1217,7 @@ where /// Var for the Marlin-KZG10 polynomial commitment verifier. pub struct MarlinKZG10Gadget where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, P: UVPolynomial<::Fr, Point = ::Fr>, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, @@ -1238,7 +1234,7 @@ where impl Clone for MarlinKZG10Gadget where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, P: UVPolynomial<::Fr, Point = ::Fr>, PG: PairingVar::Fr>, ::G1Projective: MulAssign<::Fq>, @@ -1259,7 +1255,7 @@ where impl MarlinKZG10Gadget where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, P: UVPolynomial<::Fr, Point = ::Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, PG: PairingVar::Fr>, @@ -1621,7 +1617,7 @@ impl ::Fr, > for MarlinKZG10Gadget where - CycleE: CycleEngine, + CycleE: PairingFriendlyCycle, P: UVPolynomial<::Fr, Point = ::Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, PG: PairingVar::Fr>, From 9019c22d4f302640d8e04c80085d38e9209a0da5 Mon Sep 17 00:00:00 2001 From: weikeng Date: Mon, 8 Feb 2021 03:19:30 -0800 Subject: [PATCH 43/56] simplify CycleEngine --- src/marlin/marlin_pc/constraints.rs | 991 +++++++++++++--------------- 1 file changed, 469 insertions(+), 522 deletions(-) diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index 813fb53f..12b0c9ab 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -31,15 +31,15 @@ use ark_std::{ /// High level variable representing the verification key of the `MarlinKZG10` polynomial commitment scheme. #[allow(clippy::type_complexity)] pub struct VerifierKeyVar< - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { /// Generator of G1. pub g: PG::G1Var, @@ -49,26 +49,26 @@ pub struct VerifierKeyVar< pub beta_h: PG::G2Var, /// Used for the shift powers associated with different degree bounds. pub degree_bounds_and_shift_powers: - Option::Fr>, PG::G1Var)>>, + Option::Fr>, PG::G1Var)>>, } -impl VerifierKeyVar +impl VerifierKeyVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { /// Find the appropriate shift for the degree bound. #[tracing::instrument(target = "r1cs", skip(self, cs))] pub fn get_shift_power( &self, - cs: impl Into::Fr>>, - bound: &FpVar<::Fr>, + cs: impl Into::Fr>>, + bound: &FpVar<::Fr>, ) -> Option { // Search the bound using PIR if self.degree_bounds_and_shift_powers.is_none() { @@ -103,15 +103,15 @@ where } // Sum of the PIR values are equal to one - let mut sum = FpVar::<::Fr>::zero(); - let one = FpVar::<::Fr>::one(); + let mut sum = FpVar::<::Fr>::zero(); + let one = FpVar::<::Fr>::one(); for pir_gadget in pir_vector_gadgets.iter() { - sum += &FpVar::<::Fr>::from(pir_gadget.clone()); + sum += &FpVar::<::Fr>::from(pir_gadget.clone()); } sum.enforce_equal(&one).unwrap(); // PIR the value - let mut found_bound = FpVar::<::Fr>::zero(); + let mut found_bound = FpVar::<::Fr>::zero(); let mut found_shift_power = PG::G1Var::zero(); @@ -119,7 +119,7 @@ where .iter() .zip(degree_bounds_and_shift_powers.iter()) { - found_bound = FpVar::<::Fr>::conditionally_select( + found_bound = FpVar::<::Fr>::conditionally_select( pir_gadget, degree, &found_bound, @@ -138,16 +138,16 @@ where } } -impl Clone for VerifierKeyVar +impl Clone for VerifierKeyVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { fn clone(&self) -> Self { VerifierKeyVar { @@ -159,26 +159,25 @@ where } } -impl AllocVar, ::Fr> - for VerifierKeyVar +impl AllocVar, ::Fr> for VerifierKeyVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(cs, val))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::Fr>>, val: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { let vk_orig = val()?.borrow().clone(); @@ -196,10 +195,10 @@ where .map(|(s, g)| { ( *s, - FpVar::<::Fr>::new_variable( + FpVar::<::Fr>::new_variable( ark_relations::ns!(cs, "degree bound"), || { - Ok(<::Fr as From>::from( + Ok(<::Fr as From>::from( *s as u128, )) }, @@ -229,19 +228,19 @@ where } } -impl ToBytesGadget<::Fr> for VerifierKeyVar +impl ToBytesGadget<::Fr> for VerifierKeyVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_bytes(&self) -> R1CSResult::Fr>>> { + fn to_bytes(&self) -> R1CSResult::Fr>>> { let mut bytes = Vec::new(); bytes.extend_from_slice(&self.g.to_bytes()?); @@ -261,22 +260,21 @@ where } } -impl ToConstraintFieldGadget<::Fr> - for VerifierKeyVar +impl ToConstraintFieldGadget<::Fr> for VerifierKeyVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - PG::G1Var: ToConstraintFieldGadget<::Fr>, - PG::G2Var: ToConstraintFieldGadget<::Fr>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + PG::G1Var: ToConstraintFieldGadget<::Fr>, + PG::G2Var: ToConstraintFieldGadget<::Fr>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_constraint_field(&self) -> R1CSResult::Fr>>> { + fn to_constraint_field(&self) -> R1CSResult::Fr>>> { let mut res = Vec::new(); let mut g_gadget = self.g.to_constraint_field()?; @@ -305,15 +303,15 @@ where /// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. #[allow(clippy::type_complexity)] pub struct PreparedVerifierKeyVar< - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { /// Generator of G1. pub prepared_g: Vec, @@ -322,35 +320,30 @@ pub struct PreparedVerifierKeyVar< /// Generator of G1, times first monomial. pub prepared_beta_h: PG::G2PreparedVar, /// Used for the shift powers associated with different degree bounds. - pub prepared_degree_bounds_and_shift_powers: Option< - Vec<( - usize, - FpVar<::Fr>, - Vec, - )>, - >, + pub prepared_degree_bounds_and_shift_powers: + Option::Fr>, Vec)>>, /// Indicate whether or not it is a constant allocation (which decides whether or not shift powers are precomputed) pub constant_allocation: bool, /// If not a constant allocation, the original vk is attached (for computing the shift power series) - pub origin_vk: Option>, + pub origin_vk: Option>, } -impl PreparedVerifierKeyVar +impl PreparedVerifierKeyVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { /// Find the appropriate shift for the degree bound. pub fn get_shift_power( &self, - cs: impl Into::Fr>>, - bound: &FpVar<::Fr>, + cs: impl Into::Fr>>, + bound: &FpVar<::Fr>, ) -> Option> { if self.constant_allocation { if self.prepared_degree_bounds_and_shift_powers.is_none() { @@ -378,7 +371,7 @@ where if let Some(shift_power) = shift_power { let mut prepared_shift_gadgets = Vec::::new(); - let supported_bits = ::Fr::size_in_bits(); + let supported_bits = ::Fr::size_in_bits(); let mut cur: PG::G1Var = shift_power; for _ in 0..supported_bits { @@ -394,21 +387,21 @@ where } } -impl PrepareGadget, ::Fr> - for PreparedVerifierKeyVar +impl PrepareGadget, ::Fr> + for PreparedVerifierKeyVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(unprepared))] - fn prepare(unprepared: &VerifierKeyVar) -> R1CSResult { - let supported_bits = <::Fr as PrimeField>::size_in_bits(); + fn prepare(unprepared: &VerifierKeyVar) -> R1CSResult { + let supported_bits = <::Fr as PrimeField>::size_in_bits(); let mut prepared_g = Vec::::new(); let mut g: PG::G1Var = unprepared.g.clone(); @@ -422,11 +415,8 @@ where let prepared_degree_bounds_and_shift_powers = if unprepared.degree_bounds_and_shift_powers.is_some() { - let mut res = Vec::<( - usize, - FpVar<::Fr>, - Vec, - )>::new(); + let mut res = + Vec::<(usize, FpVar<::Fr>, Vec)>::new(); for (d, d_gadget, shift_power) in unprepared .degree_bounds_and_shift_powers @@ -453,16 +443,16 @@ where } } -impl Clone for PreparedVerifierKeyVar +impl Clone for PreparedVerifierKeyVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { fn clone(&self) -> Self { PreparedVerifierKeyVar { @@ -478,26 +468,26 @@ where } } -impl AllocVar, ::Fr> - for PreparedVerifierKeyVar +impl AllocVar, ::Fr> + for PreparedVerifierKeyVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(cs, f))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::Fr>>, f: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { let t = f()?; let obj = t.borrow(); @@ -508,8 +498,8 @@ where let mut prepared_g = Vec::::new(); for g in obj.prepared_vk.prepared_g.iter() { prepared_g.push(::G1Affine, - ::Fr, + ::G1Affine, + ::Fr, >>::new_variable( ark_relations::ns!(cs, "g"), || Ok(*g), mode )?); @@ -528,11 +518,8 @@ where let prepared_degree_bounds_and_shift_powers = if obj.prepared_degree_bounds_and_shift_powers.is_some() { - let mut res = Vec::<( - usize, - FpVar<::Fr>, - Vec, - )>::new(); + let mut res = + Vec::<(usize, FpVar<::Fr>, Vec)>::new(); for (d, shift_power_elems) in obj .prepared_degree_bounds_and_shift_powers @@ -543,17 +530,17 @@ where let mut gadgets = Vec::::new(); for shift_power_elem in shift_power_elems.iter() { gadgets.push(::G1Affine, - ::Fr, + ::G1Affine, + ::Fr, >>::new_variable( cs.clone(), || Ok(shift_power_elem), mode )?); } - let d_gadget = FpVar::<::Fr>::new_variable( + let d_gadget = FpVar::<::Fr>::new_variable( cs.clone(), || { - Ok(<::Fr as From>::from( + Ok(<::Fr as From>::from( *d as u128, )) }, @@ -580,30 +567,30 @@ where /// Var for an optionally hiding Marlin-KZG10 commitment. pub struct CommitmentVar< - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { comm: PG::G1Var, shifted_comm: Option, } -impl Clone for CommitmentVar +impl Clone for CommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { fn clone(&self) -> Self { CommitmentVar { @@ -613,26 +600,25 @@ where } } -impl AllocVar, ::Fr> - for CommitmentVar +impl AllocVar, ::Fr> for CommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { value_gen().and_then(|commitment| { let ns = cs.into(); @@ -657,21 +643,20 @@ where } } -impl ToConstraintFieldGadget<::Fr> - for CommitmentVar +impl ToConstraintFieldGadget<::Fr> for CommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - PG::G1Var: ToConstraintFieldGadget<::Fr>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + PG::G1Var: ToConstraintFieldGadget<::Fr>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_constraint_field(&self) -> R1CSResult::Fr>>> { + fn to_constraint_field(&self) -> R1CSResult::Fr>>> { let mut res = Vec::new(); let mut comm_gadget = self.comm.to_constraint_field()?; @@ -688,19 +673,19 @@ where } } -impl ToBytesGadget<::Fr> for CommitmentVar +impl ToBytesGadget<::Fr> for CommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_bytes(&self) -> R1CSResult::Fr>>> { + fn to_bytes(&self) -> R1CSResult::Fr>>> { let zero_shifted_comm = PG::G1Var::zero(); let mut bytes = Vec::new(); @@ -715,30 +700,30 @@ where /// Prepared gadget for an optionally hiding Marlin-KZG10 commitment. /// shifted_comm is not prepared, due to the specific use case. pub struct PreparedCommitmentVar< - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { prepared_comm: Vec, shifted_comm: Option, } -impl Clone for PreparedCommitmentVar +impl Clone for PreparedCommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { fn clone(&self) -> Self { PreparedCommitmentVar { @@ -748,22 +733,22 @@ where } } -impl PrepareGadget, ::Fr> - for PreparedCommitmentVar +impl PrepareGadget, ::Fr> + for PreparedCommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(unprepared))] - fn prepare(unprepared: &CommitmentVar) -> R1CSResult { + fn prepare(unprepared: &CommitmentVar) -> R1CSResult { let mut prepared_comm = Vec::::new(); - let supported_bits = <::Fr as PrimeField>::size_in_bits(); + let supported_bits = <::Fr as PrimeField>::size_in_bits(); let mut cur: PG::G1Var = unprepared.comm.clone(); for _ in 0..supported_bits { @@ -778,26 +763,26 @@ where } } -impl AllocVar, ::Fr> - for PreparedCommitmentVar +impl AllocVar, ::Fr> + for PreparedCommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(cs, f))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::Fr>>, f: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { let t = f()?; let obj = t.borrow(); @@ -809,13 +794,13 @@ where for comm_elem in obj.prepared_comm.0.iter() { prepared_comm.push(::G1Projective, - ::Fr, + ::G1Projective, + ::Fr, >>::new_variable( ark_relations::ns!(cs, "comm_elem"), || { - Ok(<::G1Projective as From< - ::G1Affine, + Ok(<::G1Projective as From< + ::G1Affine, >>::from(*comm_elem)) }, mode, @@ -824,13 +809,13 @@ where let shifted_comm = if obj.shifted_comm.is_some() { Some(::G1Projective, - ::Fr, + ::G1Projective, + ::Fr, >>::new_variable( ark_relations::ns!(cs, "shifted_comm"), || { - Ok(<::G1Projective as From< - ::G1Affine, + Ok(<::G1Projective as From< + ::G1Affine, >>::from(obj.shifted_comm.unwrap().0)) }, mode, @@ -848,34 +833,34 @@ where /// Var for a Marlin-KZG10 commitment, with a string label and degree bound. pub struct LabeledCommitmentVar< - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { /// A text label for the commitment. pub label: String, /// The plain commitment. - pub commitment: CommitmentVar, + pub commitment: CommitmentVar, /// Optionally, a bound on the polynomial degree. - pub degree_bound: Option::Fr>>, + pub degree_bound: Option::Fr>>, } -impl Clone for LabeledCommitmentVar +impl Clone for LabeledCommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { fn clone(&self) -> Self { LabeledCommitmentVar { @@ -886,27 +871,26 @@ where } } -impl - AllocVar>, ::Fr> - for LabeledCommitmentVar +impl AllocVar>, ::Fr> + for LabeledCommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>>, + T: Borrow>>, { value_gen().and_then(|labeled_commitment| { let ns = cs.into(); @@ -924,10 +908,10 @@ where )?; let degree_bound = if let Some(degree_bound) = degree_bound { - FpVar::<::Fr>::new_variable( + FpVar::<::Fr>::new_variable( ark_relations::ns!(cs, "degree_bound"), || { - Ok(<::Fr as From>::from( + Ok(<::Fr as From>::from( degree_bound as u128, )) }, @@ -949,34 +933,34 @@ where /// Var for a Marlin-KZG10 commitment, with a string label and degree bound. pub struct PreparedLabeledCommitmentVar< - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { /// A text label for the commitment. pub label: String, /// The plain commitment. - pub prepared_commitment: PreparedCommitmentVar, + pub prepared_commitment: PreparedCommitmentVar, /// Optionally, a bound on the polynomial degree. - pub degree_bound: Option::Fr>>, + pub degree_bound: Option::Fr>>, } -impl Clone for PreparedLabeledCommitmentVar +impl Clone for PreparedLabeledCommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { fn clone(&self) -> Self { PreparedLabeledCommitmentVar { @@ -987,20 +971,20 @@ where } } -impl PrepareGadget, ::Fr> - for PreparedLabeledCommitmentVar +impl PrepareGadget, ::Fr> + for PreparedLabeledCommitmentVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(unprepared))] - fn prepare(unprepared: &LabeledCommitmentVar) -> R1CSResult { + fn prepare(unprepared: &LabeledCommitmentVar) -> R1CSResult { let prepared_commitment = PreparedCommitmentVar::prepare(&unprepared.commitment)?; Ok(Self { @@ -1013,35 +997,32 @@ where /// Var for a Marlin-KZG10 proof. #[allow(clippy::type_complexity)] -pub struct ProofVar< - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, -> where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, +pub struct ProofVar::Fr>> +where + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { /// The commitment to the witness polynomial. pub w: PG::G1Var, /// The evaluation of the random hiding polynomial. - pub random_v: Option< - NonNativeFieldVar<::Fr, ::Fr>, - >, + pub random_v: + Option::Fr, ::Fr>>, } -impl Clone for ProofVar +impl Clone for ProofVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { fn clone(&self) -> Self { ProofVar { @@ -1051,26 +1032,25 @@ where } } -impl AllocVar, ::Fr> - for ProofVar +impl AllocVar, ::Fr> for ProofVar where - CycleE: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { value_gen().and_then(|proof| { let ns = cs.into(); @@ -1096,40 +1076,37 @@ where /// An allocated version of `BatchLCProof`. #[allow(clippy::type_complexity)] pub struct BatchLCProofVar< - CycleE: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::Fr>, + E: PairingFriendlyCycle, + P: UVPolynomial<::Fr, Point = ::Fr>, + PG: PairingVar::Fr>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { /// Evaluation proofs. - pub proofs: Vec>, + pub proofs: Vec>, /// Evaluations required to verify the proof. - pub evals: Option< - Vec< - NonNativeFieldVar<::Fr, ::Fr>, - >, - >, + pub evals: + Option::Fr, ::Fr>>>, #[doc(hidden)] pub polynomial: PhantomData

, } -impl Clone for BatchLCProofVar +impl Clone for BatchLCProofVar where - CycleE: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + P: UVPolynomial<::Fr, Point = ::Fr>, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { fn clone(&self) -> Self { BatchLCProofVar { @@ -1140,31 +1117,31 @@ where } } -impl +impl AllocVar< - BatchLCProof<::Fr, P, MarlinKZG10>, - ::Fr, - > for BatchLCProofVar + BatchLCProof<::Fr, P, MarlinKZG10>, + ::Fr, + > for BatchLCProofVar where - CycleE: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, + E: PairingFriendlyCycle, + P: UVPolynomial<::Fr, Point = ::Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::Fr>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow::Fr, P, MarlinKZG10>>, + T: Borrow::Fr, P, MarlinKZG10>>, { value_gen().map(|proof| { let ns = cs.into(); @@ -1173,7 +1150,7 @@ where let BatchLCProof { proof, evals } = proof.borrow().clone(); let proofs: Vec> = proof.to_vec(); - let proofs: Vec> = proofs + let proofs: Vec> = proofs .iter() .map(|p| { ProofVar::new_variable(ark_relations::ns!(cs, "proof"), || Ok(p), mode).unwrap() @@ -1182,12 +1159,7 @@ where #[allow(clippy::type_complexity)] let evals: Option< - Vec< - NonNativeFieldVar< - ::Fr, - ::Fr, - >, - >, + Vec::Fr, ::Fr>>, > = match evals { None => None, Some(evals_inner) => Some( @@ -1215,34 +1187,34 @@ where } /// Var for the Marlin-KZG10 polynomial commitment verifier. -pub struct MarlinKZG10Gadget +pub struct MarlinKZG10Gadget where - CycleE: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + P: UVPolynomial<::Fr, Point = ::Fr>, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { - _cycle_engine: PhantomData, + _cycle_engine: PhantomData, _pairing_gadget: PhantomData, _polynomial: PhantomData

, } -impl Clone for MarlinKZG10Gadget +impl Clone for MarlinKZG10Gadget where - CycleE: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + E: PairingFriendlyCycle, + P: UVPolynomial<::Fr, Point = ::Fr>, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { fn clone(&self) -> Self { MarlinKZG10Gadget { @@ -1253,18 +1225,18 @@ where } } -impl MarlinKZG10Gadget +impl MarlinKZG10Gadget where - CycleE: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, + E: PairingFriendlyCycle, + P: UVPolynomial<::Fr, Point = ::Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { #[allow(clippy::type_complexity, clippy::too_many_arguments)] #[tracing::instrument( @@ -1272,52 +1244,43 @@ where skip(prepared_verification_key, lc_info, query_set, evaluations, proofs) )] fn prepared_batch_check_evaluations( - cs: ConstraintSystemRef<::Fr>, + cs: ConstraintSystemRef<::Fr>, prepared_verification_key: &::Fr, + ::Fr, P, - MarlinKZG10, - ::Fr, + MarlinKZG10, + ::Fr, >>::PreparedVerifierKeyVar, lc_info: &[( String, Vec<( Option< - NonNativeFieldVar< - ::Fr, - ::Fr, - >, + NonNativeFieldVar<::Fr, ::Fr>, >, - Option::Fr>>, - PreparedCommitmentVar, + Option::Fr>>, + PreparedCommitmentVar, bool, )>, )], - query_set: &QuerySetVar< - ::Fr, - ::Fr, - >, - evaluations: &EvaluationsVar< - ::Fr, - ::Fr, - >, + query_set: &QuerySetVar<::Fr, ::Fr>, + evaluations: &EvaluationsVar<::Fr, ::Fr>, proofs: &[::Fr, + ::Fr, P, - MarlinKZG10, - ::Fr, + MarlinKZG10, + ::Fr, >>::ProofVar], opening_challenges: &[NonNativeFieldVar< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >], - opening_challenges_bits: &[Vec::Fr>>], + opening_challenges_bits: &[Vec::Fr>>], batching_rands: &[NonNativeFieldVar< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >], - batching_rands_bits: &[Vec::Fr>>], - ) -> R1CSResult::Fr>> { + batching_rands_bits: &[Vec::Fr>>], + ) -> R1CSResult::Fr>> { let mut batching_rands = batching_rands.to_vec(); let mut batching_rands_bits = batching_rands_bits.to_vec(); @@ -1328,12 +1291,12 @@ where Vec<( Option< NonNativeFieldVar< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >, >, - Option::Fr>>, - PreparedCommitmentVar, + Option::Fr>>, + PreparedCommitmentVar, bool, )>, ), @@ -1362,12 +1325,12 @@ where Vec<( Option< NonNativeFieldVar< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >, >, - Option::Fr>>, - PreparedCommitmentVar, + Option::Fr>>, + PreparedCommitmentVar, bool, )>, >::new(); @@ -1390,8 +1353,8 @@ where // Accumulate the commitments and evaluations corresponding to `query`. let mut combined_comm = PG::G1Var::zero(); let mut combined_eval = NonNativeFieldMulResultVar::< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >::zero(); let mut opening_challenges_counter = 0; @@ -1519,12 +1482,12 @@ where let mut total_w = PG::G1Var::zero(); let mut g_multiplier = NonNativeFieldMulResultVar::< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >::zero(); let mut g_multiplier_reduced = NonNativeFieldVar::< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >::zero(); for (i, (((c, z), v), proof)) in combined_comms .iter() @@ -1609,33 +1572,29 @@ where } } -impl - PCCheckVar< - ::Fr, - P, - MarlinKZG10, - ::Fr, - > for MarlinKZG10Gadget +impl + PCCheckVar<::Fr, P, MarlinKZG10, ::Fr> + for MarlinKZG10Gadget where - CycleE: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, + E: PairingFriendlyCycle, + P: UVPolynomial<::Fr, Point = ::Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + PG: PairingVar::Fr>, + ::G1Projective: MulAssign<::Fq>, + ::G2Projective: MulAssign<::Fq>, + ::G1Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::G2Affine: + ToConstraintField<<::Fr as Field>::BasePrimeField>, { - type VerifierKeyVar = VerifierKeyVar; - type PreparedVerifierKeyVar = PreparedVerifierKeyVar; - type CommitmentVar = CommitmentVar; - type PreparedCommitmentVar = PreparedCommitmentVar; - type LabeledCommitmentVar = LabeledCommitmentVar; - type PreparedLabeledCommitmentVar = PreparedLabeledCommitmentVar; - type ProofVar = ProofVar; - type BatchLCProofVar = BatchLCProofVar; + type VerifierKeyVar = VerifierKeyVar; + type PreparedVerifierKeyVar = PreparedVerifierKeyVar; + type CommitmentVar = CommitmentVar; + type PreparedCommitmentVar = PreparedCommitmentVar; + type LabeledCommitmentVar = LabeledCommitmentVar; + type PreparedLabeledCommitmentVar = PreparedLabeledCommitmentVar; + type ProofVar = ProofVar; + type BatchLCProofVar = BatchLCProofVar; #[allow(clippy::type_complexity)] #[tracing::instrument( @@ -1643,23 +1602,17 @@ where skip(verification_key, commitments, query_set, evaluations, proofs) )] fn batch_check_evaluations( - _cs: ConstraintSystemRef<::Fr>, + _cs: ConstraintSystemRef<::Fr>, verification_key: &Self::VerifierKeyVar, commitments: &[Self::LabeledCommitmentVar], - query_set: &QuerySetVar< - ::Fr, - ::Fr, - >, - evaluations: &EvaluationsVar< - ::Fr, - ::Fr, - >, + query_set: &QuerySetVar<::Fr, ::Fr>, + evaluations: &EvaluationsVar<::Fr, ::Fr>, proofs: &[Self::ProofVar], rand_data: &PCCheckRandomDataVar< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >, - ) -> R1CSResult::Fr>> { + ) -> R1CSResult::Fr>> { let mut batching_rands = rand_data.batching_rands.to_vec(); let mut batching_rands_bits = rand_data.batching_rands_bits.to_vec(); @@ -1704,8 +1657,8 @@ where // Accumulate the commitments and evaluations corresponding to `query`. let mut combined_comm = PG::G1Var::zero(); let mut combined_eval = NonNativeFieldMulResultVar::< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >::zero(); let mut opening_challenges_counter = 0; @@ -1769,8 +1722,8 @@ where let mut total_w = PG::G1Var::zero(); let mut g_multiplier = NonNativeFieldMulResultVar::< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >::zero(); for (((c, z), v), proof) in combined_comms .iter() @@ -1844,27 +1797,21 @@ where ) )] fn prepared_check_combinations( - cs: ConstraintSystemRef<::Fr>, + cs: ConstraintSystemRef<::Fr>, prepared_verification_key: &Self::PreparedVerifierKeyVar, linear_combinations: &[LinearCombinationVar< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >], prepared_commitments: &[Self::PreparedLabeledCommitmentVar], - query_set: &QuerySetVar< - ::Fr, - ::Fr, - >, - evaluations: &EvaluationsVar< - ::Fr, - ::Fr, - >, + query_set: &QuerySetVar<::Fr, ::Fr>, + evaluations: &EvaluationsVar<::Fr, ::Fr>, proof: &Self::BatchLCProofVar, rand_data: &PCCheckRandomDataVar< - ::Fr, - ::Fr, + ::Fr, + ::Fr, >, - ) -> R1CSResult::Fr>> { + ) -> R1CSResult::Fr>> { let BatchLCProofVar { proofs, .. } = proof; let label_comm_map = prepared_commitments @@ -1950,7 +1897,7 @@ where fn create_labeled_commitment( label: String, commitment: Self::CommitmentVar, - degree_bound: Option::Fr>>, + degree_bound: Option::Fr>>, ) -> Self::LabeledCommitmentVar { Self::LabeledCommitmentVar { label, @@ -1962,7 +1909,7 @@ where fn create_prepared_labeled_commitment( label: String, prepared_commitment: Self::PreparedCommitmentVar, - degree_bound: Option::Fr>>, + degree_bound: Option::Fr>>, ) -> Self::PreparedLabeledCommitmentVar { Self::PreparedLabeledCommitmentVar { label, From b0ff5313ffd4f9c33e03ded7c4bc40dffab5ba1d Mon Sep 17 00:00:00 2001 From: weikeng Date: Mon, 8 Feb 2021 03:43:11 -0800 Subject: [PATCH 44/56] simplify --- src/marlin/marlin_pc/constraints.rs | 660 +++++++++++----------------- 1 file changed, 261 insertions(+), 399 deletions(-) diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index 12b0c9ab..56669398 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -9,8 +9,8 @@ use crate::{ BTreeMap, BTreeSet, BatchLCProof, LinearCombinationCoeffVar, LinearCombinationVar, PrepareGadget, String, ToString, Vec, }; -use ark_ec::{PairingEngine, PairingFriendlyCycle}; -use ark_ff::{fields::Field, PrimeField, ToConstraintField}; +use ark_ec::{AffineCurve, PairingEngine, PairingFriendlyCycle}; +use ark_ff::{PrimeField, ToConstraintField}; use ark_nonnative_field::{NonNativeFieldMulResultVar, NonNativeFieldVar}; use ark_poly::UVPolynomial; use ark_r1cs_std::{ @@ -24,22 +24,15 @@ use ark_r1cs_std::{ R1CSVar, ToBytesGadget, ToConstraintFieldGadget, }; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError}; -use ark_std::{ - borrow::Borrow, convert::TryInto, marker::PhantomData, ops::Div, ops::MulAssign, vec, -}; +use ark_std::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::Div, vec}; /// High level variable representing the verification key of the `MarlinKZG10` polynomial commitment scheme. #[allow(clippy::type_complexity)] pub struct VerifierKeyVar< E: PairingFriendlyCycle, - PG: PairingVar::Fr>, + PG: PairingVar::BaseField>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, { /// Generator of G1. pub g: PG::G1Var, @@ -49,26 +42,21 @@ pub struct VerifierKeyVar< pub beta_h: PG::G2Var, /// Used for the shift powers associated with different degree bounds. pub degree_bounds_and_shift_powers: - Option::Fr>, PG::G1Var)>>, + Option::BaseField>, PG::G1Var)>>, } impl VerifierKeyVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { /// Find the appropriate shift for the degree bound. #[tracing::instrument(target = "r1cs", skip(self, cs))] pub fn get_shift_power( &self, - cs: impl Into::Fr>>, - bound: &FpVar<::Fr>, + cs: impl Into::BaseField>>, + bound: &FpVar<::BaseField>, ) -> Option { // Search the bound using PIR if self.degree_bounds_and_shift_powers.is_none() { @@ -103,15 +91,15 @@ where } // Sum of the PIR values are equal to one - let mut sum = FpVar::<::Fr>::zero(); - let one = FpVar::<::Fr>::one(); + let mut sum = FpVar::<::BaseField>::zero(); + let one = FpVar::<::BaseField>::one(); for pir_gadget in pir_vector_gadgets.iter() { - sum += &FpVar::<::Fr>::from(pir_gadget.clone()); + sum += &FpVar::<::BaseField>::from(pir_gadget.clone()); } sum.enforce_equal(&one).unwrap(); // PIR the value - let mut found_bound = FpVar::<::Fr>::zero(); + let mut found_bound = FpVar::<::BaseField>::zero(); let mut found_shift_power = PG::G1Var::zero(); @@ -119,7 +107,7 @@ where .iter() .zip(degree_bounds_and_shift_powers.iter()) { - found_bound = FpVar::<::Fr>::conditionally_select( + found_bound = FpVar::<::BaseField>::conditionally_select( pir_gadget, degree, &found_bound, @@ -141,13 +129,8 @@ where impl Clone for VerifierKeyVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { fn clone(&self) -> Self { VerifierKeyVar { @@ -159,25 +142,21 @@ where } } -impl AllocVar, ::Fr> for VerifierKeyVar +impl AllocVar, ::BaseField> + for VerifierKeyVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(cs, val))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::BaseField>>, val: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { let vk_orig = val()?.borrow().clone(); @@ -195,10 +174,10 @@ where .map(|(s, g)| { ( *s, - FpVar::<::Fr>::new_variable( + FpVar::<::BaseField>::new_variable( ark_relations::ns!(cs, "degree bound"), || { - Ok(<::Fr as From>::from( + Ok(<::BaseField as From>::from( *s as u128, )) }, @@ -228,19 +207,14 @@ where } } -impl ToBytesGadget<::Fr> for VerifierKeyVar +impl ToBytesGadget<::BaseField> for VerifierKeyVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_bytes(&self) -> R1CSResult::Fr>>> { + fn to_bytes(&self) -> R1CSResult::BaseField>>> { let mut bytes = Vec::new(); bytes.extend_from_slice(&self.g.to_bytes()?); @@ -260,21 +234,16 @@ where } } -impl ToConstraintFieldGadget<::Fr> for VerifierKeyVar +impl ToConstraintFieldGadget<::BaseField> for VerifierKeyVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - PG::G1Var: ToConstraintFieldGadget<::Fr>, - PG::G2Var: ToConstraintFieldGadget<::Fr>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, + PG::G1Var: ToConstraintFieldGadget<::BaseField>, + PG::G2Var: ToConstraintFieldGadget<::BaseField>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_constraint_field(&self) -> R1CSResult::Fr>>> { + fn to_constraint_field(&self) -> R1CSResult::BaseField>>> { let mut res = Vec::new(); let mut g_gadget = self.g.to_constraint_field()?; @@ -304,14 +273,9 @@ where #[allow(clippy::type_complexity)] pub struct PreparedVerifierKeyVar< E: PairingFriendlyCycle, - PG: PairingVar::Fr>, + PG: PairingVar::BaseField>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, { /// Generator of G1. pub prepared_g: Vec, @@ -320,8 +284,13 @@ pub struct PreparedVerifierKeyVar< /// Generator of G1, times first monomial. pub prepared_beta_h: PG::G2PreparedVar, /// Used for the shift powers associated with different degree bounds. - pub prepared_degree_bounds_and_shift_powers: - Option::Fr>, Vec)>>, + pub prepared_degree_bounds_and_shift_powers: Option< + Vec<( + usize, + FpVar<::BaseField>, + Vec, + )>, + >, /// Indicate whether or not it is a constant allocation (which decides whether or not shift powers are precomputed) pub constant_allocation: bool, /// If not a constant allocation, the original vk is attached (for computing the shift power series) @@ -331,19 +300,14 @@ pub struct PreparedVerifierKeyVar< impl PreparedVerifierKeyVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { /// Find the appropriate shift for the degree bound. pub fn get_shift_power( &self, - cs: impl Into::Fr>>, - bound: &FpVar<::Fr>, + cs: impl Into::BaseField>>, + bound: &FpVar<::BaseField>, ) -> Option> { if self.constant_allocation { if self.prepared_degree_bounds_and_shift_powers.is_none() { @@ -371,7 +335,7 @@ where if let Some(shift_power) = shift_power { let mut prepared_shift_gadgets = Vec::::new(); - let supported_bits = ::Fr::size_in_bits(); + let supported_bits = ::Fr::size_in_bits(); let mut cur: PG::G1Var = shift_power; for _ in 0..supported_bits { @@ -387,21 +351,16 @@ where } } -impl PrepareGadget, ::Fr> +impl PrepareGadget, ::BaseField> for PreparedVerifierKeyVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare(unprepared: &VerifierKeyVar) -> R1CSResult { - let supported_bits = <::Fr as PrimeField>::size_in_bits(); + let supported_bits = <::Fr as PrimeField>::size_in_bits(); let mut prepared_g = Vec::::new(); let mut g: PG::G1Var = unprepared.g.clone(); @@ -415,8 +374,11 @@ where let prepared_degree_bounds_and_shift_powers = if unprepared.degree_bounds_and_shift_powers.is_some() { - let mut res = - Vec::<(usize, FpVar<::Fr>, Vec)>::new(); + let mut res = Vec::<( + usize, + FpVar<::BaseField>, + Vec, + )>::new(); for (d, d_gadget, shift_power) in unprepared .degree_bounds_and_shift_powers @@ -446,13 +408,8 @@ where impl Clone for PreparedVerifierKeyVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { fn clone(&self) -> Self { PreparedVerifierKeyVar { @@ -468,26 +425,21 @@ where } } -impl AllocVar, ::Fr> +impl AllocVar, ::BaseField> for PreparedVerifierKeyVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(cs, f))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::BaseField>>, f: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { let t = f()?; let obj = t.borrow(); @@ -498,8 +450,8 @@ where let mut prepared_g = Vec::::new(); for g in obj.prepared_vk.prepared_g.iter() { prepared_g.push(::G1Affine, - ::Fr, + ::G1Affine, + ::BaseField, >>::new_variable( ark_relations::ns!(cs, "g"), || Ok(*g), mode )?); @@ -518,8 +470,11 @@ where let prepared_degree_bounds_and_shift_powers = if obj.prepared_degree_bounds_and_shift_powers.is_some() { - let mut res = - Vec::<(usize, FpVar<::Fr>, Vec)>::new(); + let mut res = Vec::<( + usize, + FpVar<::BaseField>, + Vec, + )>::new(); for (d, shift_power_elems) in obj .prepared_degree_bounds_and_shift_powers @@ -530,17 +485,17 @@ where let mut gadgets = Vec::::new(); for shift_power_elem in shift_power_elems.iter() { gadgets.push(::G1Affine, - ::Fr, + ::G1Affine, + ::BaseField, >>::new_variable( cs.clone(), || Ok(shift_power_elem), mode )?); } - let d_gadget = FpVar::<::Fr>::new_variable( + let d_gadget = FpVar::<::BaseField>::new_variable( cs.clone(), || { - Ok(<::Fr as From>::from( + Ok(<::BaseField as From>::from( *d as u128, )) }, @@ -568,14 +523,9 @@ where /// Var for an optionally hiding Marlin-KZG10 commitment. pub struct CommitmentVar< E: PairingFriendlyCycle, - PG: PairingVar::Fr>, + PG: PairingVar::BaseField>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, { comm: PG::G1Var, shifted_comm: Option, @@ -584,13 +534,8 @@ pub struct CommitmentVar< impl Clone for CommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { fn clone(&self) -> Self { CommitmentVar { @@ -600,25 +545,21 @@ where } } -impl AllocVar, ::Fr> for CommitmentVar +impl AllocVar, ::BaseField> + for CommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::BaseField>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { value_gen().and_then(|commitment| { let ns = cs.into(); @@ -643,20 +584,16 @@ where } } -impl ToConstraintFieldGadget<::Fr> for CommitmentVar +impl ToConstraintFieldGadget<::BaseField> for CommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - PG::G1Var: ToConstraintFieldGadget<::Fr>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + E::E2: ToConstraintField<::BaseField>, + PG: PairingVar::BaseField>, + PG::G1Var: ToConstraintFieldGadget<::BaseField>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_constraint_field(&self) -> R1CSResult::Fr>>> { + fn to_constraint_field(&self) -> R1CSResult::BaseField>>> { let mut res = Vec::new(); let mut comm_gadget = self.comm.to_constraint_field()?; @@ -673,19 +610,14 @@ where } } -impl ToBytesGadget<::Fr> for CommitmentVar +impl ToBytesGadget<::BaseField> for CommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_bytes(&self) -> R1CSResult::Fr>>> { + fn to_bytes(&self) -> R1CSResult::BaseField>>> { let zero_shifted_comm = PG::G1Var::zero(); let mut bytes = Vec::new(); @@ -701,15 +633,8 @@ where /// shifted_comm is not prepared, due to the specific use case. pub struct PreparedCommitmentVar< E: PairingFriendlyCycle, - PG: PairingVar::Fr>, -> where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, -{ + PG: PairingVar::BaseField>, +> { prepared_comm: Vec, shifted_comm: Option, } @@ -717,13 +642,7 @@ pub struct PreparedCommitmentVar< impl Clone for PreparedCommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + PG: PairingVar::BaseField>, { fn clone(&self) -> Self { PreparedCommitmentVar { @@ -733,22 +652,17 @@ where } } -impl PrepareGadget, ::Fr> +impl PrepareGadget, ::BaseField> for PreparedCommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare(unprepared: &CommitmentVar) -> R1CSResult { let mut prepared_comm = Vec::::new(); - let supported_bits = <::Fr as PrimeField>::size_in_bits(); + let supported_bits = <::Fr as PrimeField>::size_in_bits(); let mut cur: PG::G1Var = unprepared.comm.clone(); for _ in 0..supported_bits { @@ -763,26 +677,20 @@ where } } -impl AllocVar, ::Fr> +impl AllocVar, ::BaseField> for PreparedCommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(cs, f))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::BaseField>>, f: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { let t = f()?; let obj = t.borrow(); @@ -794,13 +702,13 @@ where for comm_elem in obj.prepared_comm.0.iter() { prepared_comm.push(::G1Projective, - ::Fr, + ::G1Projective, + ::BaseField, >>::new_variable( ark_relations::ns!(cs, "comm_elem"), || { - Ok(<::G1Projective as From< - ::G1Affine, + Ok(<::G1Projective as From< + ::G1Affine, >>::from(*comm_elem)) }, mode, @@ -809,13 +717,13 @@ where let shifted_comm = if obj.shifted_comm.is_some() { Some(::G1Projective, - ::Fr, + ::G1Projective, + ::BaseField, >>::new_variable( ark_relations::ns!(cs, "shifted_comm"), || { - Ok(<::G1Projective as From< - ::G1Affine, + Ok(<::G1Projective as From< + ::G1Affine, >>::from(obj.shifted_comm.unwrap().0)) }, mode, @@ -834,33 +742,23 @@ where /// Var for a Marlin-KZG10 commitment, with a string label and degree bound. pub struct LabeledCommitmentVar< E: PairingFriendlyCycle, - PG: PairingVar::Fr>, + PG: PairingVar::BaseField>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, { /// A text label for the commitment. pub label: String, /// The plain commitment. pub commitment: CommitmentVar, /// Optionally, a bound on the polynomial degree. - pub degree_bound: Option::Fr>>, + pub degree_bound: Option::BaseField>>, } impl Clone for LabeledCommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { fn clone(&self) -> Self { LabeledCommitmentVar { @@ -871,26 +769,21 @@ where } } -impl AllocVar>, ::Fr> +impl AllocVar>, ::BaseField> for LabeledCommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::BaseField>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>>, + T: Borrow>>, { value_gen().and_then(|labeled_commitment| { let ns = cs.into(); @@ -908,10 +801,10 @@ where )?; let degree_bound = if let Some(degree_bound) = degree_bound { - FpVar::<::Fr>::new_variable( + FpVar::<::BaseField>::new_variable( ark_relations::ns!(cs, "degree_bound"), || { - Ok(<::Fr as From>::from( + Ok(<::BaseField as From>::from( degree_bound as u128, )) }, @@ -934,33 +827,23 @@ where /// Var for a Marlin-KZG10 commitment, with a string label and degree bound. pub struct PreparedLabeledCommitmentVar< E: PairingFriendlyCycle, - PG: PairingVar::Fr>, + PG: PairingVar::BaseField>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, { /// A text label for the commitment. pub label: String, /// The plain commitment. pub prepared_commitment: PreparedCommitmentVar, /// Optionally, a bound on the polynomial degree. - pub degree_bound: Option::Fr>>, + pub degree_bound: Option::BaseField>>, } impl Clone for PreparedLabeledCommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { fn clone(&self) -> Self { PreparedLabeledCommitmentVar { @@ -971,17 +854,12 @@ where } } -impl PrepareGadget, ::Fr> +impl PrepareGadget, ::BaseField> for PreparedLabeledCommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare(unprepared: &LabeledCommitmentVar) -> R1CSResult { @@ -997,32 +875,25 @@ where /// Var for a Marlin-KZG10 proof. #[allow(clippy::type_complexity)] -pub struct ProofVar::Fr>> -where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, +pub struct ProofVar< + E: PairingFriendlyCycle, + PG: PairingVar::BaseField>, +> where + ::BaseField: PrimeField, { /// The commitment to the witness polynomial. pub w: PG::G1Var, /// The evaluation of the random hiding polynomial. - pub random_v: - Option::Fr, ::Fr>>, + pub random_v: Option< + NonNativeFieldVar<::Fr, ::BaseField>, + >, } impl Clone for ProofVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { fn clone(&self) -> Self { ProofVar { @@ -1032,25 +903,20 @@ where } } -impl AllocVar, ::Fr> for ProofVar +impl AllocVar, ::BaseField> for ProofVar where E: PairingFriendlyCycle, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::BaseField>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow>, + T: Borrow>, { value_gen().and_then(|proof| { let ns = cs.into(); @@ -1077,21 +943,19 @@ where #[allow(clippy::type_complexity)] pub struct BatchLCProofVar< E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::Fr>, + P: UVPolynomial<::Fr, Point = ::Fr>, + PG: PairingVar::BaseField>, > where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, { /// Evaluation proofs. pub proofs: Vec>, /// Evaluations required to verify the proof. - pub evals: - Option::Fr, ::Fr>>>, + pub evals: Option< + Vec< + NonNativeFieldVar<::Fr, ::BaseField>, + >, + >, #[doc(hidden)] pub polynomial: PhantomData

, } @@ -1099,14 +963,9 @@ pub struct BatchLCProofVar< impl Clone for BatchLCProofVar where E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + ::BaseField: PrimeField, + P: UVPolynomial<::Fr, Point = ::Fr>, + PG: PairingVar::BaseField>, { fn clone(&self) -> Self { BatchLCProofVar { @@ -1119,29 +978,24 @@ where impl AllocVar< - BatchLCProof<::Fr, P, MarlinKZG10>, - ::Fr, + BatchLCProof<::Fr, P, MarlinKZG10>, + ::BaseField, > for BatchLCProofVar where E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, + ::BaseField: PrimeField, + P: UVPolynomial<::Fr, Point = ::Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + PG: PairingVar::BaseField>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::Fr>>, + cs: impl Into::BaseField>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow::Fr, P, MarlinKZG10>>, + T: Borrow::Fr, P, MarlinKZG10>>, { value_gen().map(|proof| { let ns = cs.into(); @@ -1159,7 +1013,12 @@ where #[allow(clippy::type_complexity)] let evals: Option< - Vec::Fr, ::Fr>>, + Vec< + NonNativeFieldVar< + ::Fr, + ::BaseField, + >, + >, > = match evals { None => None, Some(evals_inner) => Some( @@ -1190,14 +1049,8 @@ where pub struct MarlinKZG10Gadget where E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + P: UVPolynomial<::Fr, Point = ::Fr>, + PG: PairingVar::BaseField>, { _cycle_engine: PhantomData, _pairing_gadget: PhantomData, @@ -1207,14 +1060,8 @@ where impl Clone for MarlinKZG10Gadget where E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + P: UVPolynomial<::Fr, Point = ::Fr>, + PG: PairingVar::BaseField>, { fn clone(&self) -> Self { MarlinKZG10Gadget { @@ -1228,15 +1075,10 @@ where impl MarlinKZG10Gadget where E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, + ::BaseField: PrimeField, + P: UVPolynomial<::Fr, Point = ::Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + PG: PairingVar::BaseField>, { #[allow(clippy::type_complexity, clippy::too_many_arguments)] #[tracing::instrument( @@ -1244,43 +1086,52 @@ where skip(prepared_verification_key, lc_info, query_set, evaluations, proofs) )] fn prepared_batch_check_evaluations( - cs: ConstraintSystemRef<::Fr>, + cs: ConstraintSystemRef<::BaseField>, prepared_verification_key: &::Fr, + ::Fr, P, - MarlinKZG10, - ::Fr, + MarlinKZG10, + ::BaseField, >>::PreparedVerifierKeyVar, lc_info: &[( String, Vec<( Option< - NonNativeFieldVar<::Fr, ::Fr>, + NonNativeFieldVar< + ::Fr, + ::BaseField, + >, >, - Option::Fr>>, + Option::BaseField>>, PreparedCommitmentVar, bool, )>, )], - query_set: &QuerySetVar<::Fr, ::Fr>, - evaluations: &EvaluationsVar<::Fr, ::Fr>, + query_set: &QuerySetVar< + ::Fr, + ::BaseField, + >, + evaluations: &EvaluationsVar< + ::Fr, + ::BaseField, + >, proofs: &[::Fr, + ::Fr, P, - MarlinKZG10, - ::Fr, + MarlinKZG10, + ::BaseField, >>::ProofVar], opening_challenges: &[NonNativeFieldVar< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >], - opening_challenges_bits: &[Vec::Fr>>], + opening_challenges_bits: &[Vec::BaseField>>], batching_rands: &[NonNativeFieldVar< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >], - batching_rands_bits: &[Vec::Fr>>], - ) -> R1CSResult::Fr>> { + batching_rands_bits: &[Vec::BaseField>>], + ) -> R1CSResult::BaseField>> { let mut batching_rands = batching_rands.to_vec(); let mut batching_rands_bits = batching_rands_bits.to_vec(); @@ -1291,11 +1142,11 @@ where Vec<( Option< NonNativeFieldVar< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >, >, - Option::Fr>>, + Option::BaseField>>, PreparedCommitmentVar, bool, )>, @@ -1325,11 +1176,11 @@ where Vec<( Option< NonNativeFieldVar< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >, >, - Option::Fr>>, + Option::BaseField>>, PreparedCommitmentVar, bool, )>, @@ -1353,8 +1204,8 @@ where // Accumulate the commitments and evaluations corresponding to `query`. let mut combined_comm = PG::G1Var::zero(); let mut combined_eval = NonNativeFieldMulResultVar::< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >::zero(); let mut opening_challenges_counter = 0; @@ -1482,12 +1333,12 @@ where let mut total_w = PG::G1Var::zero(); let mut g_multiplier = NonNativeFieldMulResultVar::< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >::zero(); let mut g_multiplier_reduced = NonNativeFieldVar::< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >::zero(); for (i, (((c, z), v), proof)) in combined_comms .iter() @@ -1573,19 +1424,18 @@ where } impl - PCCheckVar<::Fr, P, MarlinKZG10, ::Fr> - for MarlinKZG10Gadget + PCCheckVar< + ::Fr, + P, + MarlinKZG10, + ::BaseField, + > for MarlinKZG10Gadget where E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, + ::BaseField: PrimeField, + P: UVPolynomial<::Fr, Point = ::Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, - PG: PairingVar::Fr>, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, + PG: PairingVar::BaseField>, { type VerifierKeyVar = VerifierKeyVar; type PreparedVerifierKeyVar = PreparedVerifierKeyVar; @@ -1602,17 +1452,23 @@ where skip(verification_key, commitments, query_set, evaluations, proofs) )] fn batch_check_evaluations( - _cs: ConstraintSystemRef<::Fr>, + _cs: ConstraintSystemRef<::BaseField>, verification_key: &Self::VerifierKeyVar, commitments: &[Self::LabeledCommitmentVar], - query_set: &QuerySetVar<::Fr, ::Fr>, - evaluations: &EvaluationsVar<::Fr, ::Fr>, + query_set: &QuerySetVar< + ::Fr, + ::BaseField, + >, + evaluations: &EvaluationsVar< + ::Fr, + ::BaseField, + >, proofs: &[Self::ProofVar], rand_data: &PCCheckRandomDataVar< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >, - ) -> R1CSResult::Fr>> { + ) -> R1CSResult::BaseField>> { let mut batching_rands = rand_data.batching_rands.to_vec(); let mut batching_rands_bits = rand_data.batching_rands_bits.to_vec(); @@ -1657,8 +1513,8 @@ where // Accumulate the commitments and evaluations corresponding to `query`. let mut combined_comm = PG::G1Var::zero(); let mut combined_eval = NonNativeFieldMulResultVar::< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >::zero(); let mut opening_challenges_counter = 0; @@ -1722,8 +1578,8 @@ where let mut total_w = PG::G1Var::zero(); let mut g_multiplier = NonNativeFieldMulResultVar::< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >::zero(); for (((c, z), v), proof) in combined_comms .iter() @@ -1797,21 +1653,27 @@ where ) )] fn prepared_check_combinations( - cs: ConstraintSystemRef<::Fr>, + cs: ConstraintSystemRef<::BaseField>, prepared_verification_key: &Self::PreparedVerifierKeyVar, linear_combinations: &[LinearCombinationVar< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >], prepared_commitments: &[Self::PreparedLabeledCommitmentVar], - query_set: &QuerySetVar<::Fr, ::Fr>, - evaluations: &EvaluationsVar<::Fr, ::Fr>, + query_set: &QuerySetVar< + ::Fr, + ::BaseField, + >, + evaluations: &EvaluationsVar< + ::Fr, + ::BaseField, + >, proof: &Self::BatchLCProofVar, rand_data: &PCCheckRandomDataVar< - ::Fr, - ::Fr, + ::Fr, + ::BaseField, >, - ) -> R1CSResult::Fr>> { + ) -> R1CSResult::BaseField>> { let BatchLCProofVar { proofs, .. } = proof; let label_comm_map = prepared_commitments @@ -1897,7 +1759,7 @@ where fn create_labeled_commitment( label: String, commitment: Self::CommitmentVar, - degree_bound: Option::Fr>>, + degree_bound: Option::BaseField>>, ) -> Self::LabeledCommitmentVar { Self::LabeledCommitmentVar { label, @@ -1909,7 +1771,7 @@ where fn create_prepared_labeled_commitment( label: String, prepared_commitment: Self::PreparedCommitmentVar, - degree_bound: Option::Fr>>, + degree_bound: Option::BaseField>>, ) -> Self::PreparedLabeledCommitmentVar { Self::PreparedLabeledCommitmentVar { label, From 100bc57fe0fba4b64aeaa8d972073f2c08d8063e Mon Sep 17 00:00:00 2001 From: weikeng Date: Mon, 8 Feb 2021 03:56:51 -0800 Subject: [PATCH 45/56] derive Clone --- src/marlin/marlin_pc/constraints.rs | 633 ++++++++-------------------- 1 file changed, 187 insertions(+), 446 deletions(-) diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index 56669398..2ae2734e 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -9,30 +9,23 @@ use crate::{ BTreeMap, BTreeSet, BatchLCProof, LinearCombinationCoeffVar, LinearCombinationVar, PrepareGadget, String, ToString, Vec, }; -use ark_ec::{AffineCurve, PairingEngine, PairingFriendlyCycle}; +use ark_ec::{AffineCurve, CurveCycle, PairingEngine, PairingFriendlyCycle}; use ark_ff::{PrimeField, ToConstraintField}; use ark_nonnative_field::{NonNativeFieldMulResultVar, NonNativeFieldVar}; use ark_poly::UVPolynomial; -use ark_r1cs_std::{ - alloc::{AllocVar, AllocationMode}, - bits::{boolean::Boolean, uint8::UInt8, ToBitsGadget}, - eq::EqGadget, - fields::{fp::FpVar, FieldVar}, - groups::CurveVar, - pairing::PairingVar, - select::CondSelectGadget, - R1CSVar, ToBytesGadget, ToConstraintFieldGadget, -}; +use ark_r1cs_std::{fields::fp::FpVar, prelude::*, ToConstraintFieldGadget}; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError}; use ark_std::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::Div, vec}; +type E2Fr = <::E2 as AffineCurve>::ScalarField; +type E2Fq = <::E2 as AffineCurve>::BaseField; + /// High level variable representing the verification key of the `MarlinKZG10` polynomial commitment scheme. -#[allow(clippy::type_complexity)] -pub struct VerifierKeyVar< - E: PairingFriendlyCycle, - PG: PairingVar::BaseField>, -> where - ::BaseField: PrimeField, +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] +pub struct VerifierKeyVar>> +where + E2Fq: PrimeField, { /// Generator of G1. pub g: PG::G1Var, @@ -41,22 +34,21 @@ pub struct VerifierKeyVar< /// Generator of G1, times first monomial. pub beta_h: PG::G2Var, /// Used for the shift powers associated with different degree bounds. - pub degree_bounds_and_shift_powers: - Option::BaseField>, PG::G1Var)>>, + pub degree_bounds_and_shift_powers: Option>, PG::G1Var)>>, } impl VerifierKeyVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { /// Find the appropriate shift for the degree bound. #[tracing::instrument(target = "r1cs", skip(self, cs))] pub fn get_shift_power( &self, - cs: impl Into::BaseField>>, - bound: &FpVar<::BaseField>, + cs: impl Into>>, + bound: &FpVar>, ) -> Option { // Search the bound using PIR if self.degree_bounds_and_shift_powers.is_none() { @@ -91,15 +83,15 @@ where } // Sum of the PIR values are equal to one - let mut sum = FpVar::<::BaseField>::zero(); - let one = FpVar::<::BaseField>::one(); + let mut sum = FpVar::>::zero(); + let one = FpVar::>::one(); for pir_gadget in pir_vector_gadgets.iter() { - sum += &FpVar::<::BaseField>::from(pir_gadget.clone()); + sum += &FpVar::>::from(pir_gadget.clone()); } sum.enforce_equal(&one).unwrap(); // PIR the value - let mut found_bound = FpVar::<::BaseField>::zero(); + let mut found_bound = FpVar::>::zero(); let mut found_shift_power = PG::G1Var::zero(); @@ -107,12 +99,9 @@ where .iter() .zip(degree_bounds_and_shift_powers.iter()) { - found_bound = FpVar::<::BaseField>::conditionally_select( - pir_gadget, - degree, - &found_bound, - ) - .unwrap(); + found_bound = + FpVar::>::conditionally_select(pir_gadget, degree, &found_bound) + .unwrap(); found_shift_power = PG::G1Var::conditionally_select(pir_gadget, shift_power, &found_shift_power) @@ -126,32 +115,15 @@ where } } -impl Clone for VerifierKeyVar +impl AllocVar, E2Fq> for VerifierKeyVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, -{ - fn clone(&self) -> Self { - VerifierKeyVar { - g: self.g.clone(), - h: self.h.clone(), - beta_h: self.beta_h.clone(), - degree_bounds_and_shift_powers: self.degree_bounds_and_shift_powers.clone(), - } - } -} - -impl AllocVar, ::BaseField> - for VerifierKeyVar -where - E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(cs, val))] fn new_variable( - cs: impl Into::BaseField>>, + cs: impl Into>>, val: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult @@ -174,13 +146,9 @@ where .map(|(s, g)| { ( *s, - FpVar::<::BaseField>::new_variable( + FpVar::>::new_variable( ark_relations::ns!(cs, "degree bound"), - || { - Ok(<::BaseField as From>::from( - *s as u128, - )) - }, + || Ok( as From>::from(*s as u128)), mode, ) .unwrap(), @@ -207,14 +175,14 @@ where } } -impl ToBytesGadget<::BaseField> for VerifierKeyVar +impl ToBytesGadget> for VerifierKeyVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_bytes(&self) -> R1CSResult::BaseField>>> { + fn to_bytes(&self) -> R1CSResult>>> { let mut bytes = Vec::new(); bytes.extend_from_slice(&self.g.to_bytes()?); @@ -234,16 +202,16 @@ where } } -impl ToConstraintFieldGadget<::BaseField> for VerifierKeyVar +impl ToConstraintFieldGadget> for VerifierKeyVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, - PG::G1Var: ToConstraintFieldGadget<::BaseField>, - PG::G2Var: ToConstraintFieldGadget<::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, + PG::G1Var: ToConstraintFieldGadget>, + PG::G2Var: ToConstraintFieldGadget>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_constraint_field(&self) -> R1CSResult::BaseField>>> { + fn to_constraint_field(&self) -> R1CSResult>>> { let mut res = Vec::new(); let mut g_gadget = self.g.to_constraint_field()?; @@ -271,11 +239,11 @@ where /// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. #[allow(clippy::type_complexity)] -pub struct PreparedVerifierKeyVar< - E: PairingFriendlyCycle, - PG: PairingVar::BaseField>, -> where - ::BaseField: PrimeField, +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] +pub struct PreparedVerifierKeyVar>> +where + E2Fq: PrimeField, { /// Generator of G1. pub prepared_g: Vec, @@ -284,13 +252,8 @@ pub struct PreparedVerifierKeyVar< /// Generator of G1, times first monomial. pub prepared_beta_h: PG::G2PreparedVar, /// Used for the shift powers associated with different degree bounds. - pub prepared_degree_bounds_and_shift_powers: Option< - Vec<( - usize, - FpVar<::BaseField>, - Vec, - )>, - >, + pub prepared_degree_bounds_and_shift_powers: + Option>, Vec)>>, /// Indicate whether or not it is a constant allocation (which decides whether or not shift powers are precomputed) pub constant_allocation: bool, /// If not a constant allocation, the original vk is attached (for computing the shift power series) @@ -300,14 +263,14 @@ pub struct PreparedVerifierKeyVar< impl PreparedVerifierKeyVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { /// Find the appropriate shift for the degree bound. pub fn get_shift_power( &self, - cs: impl Into::BaseField>>, - bound: &FpVar<::BaseField>, + cs: impl Into>>, + bound: &FpVar>, ) -> Option> { if self.constant_allocation { if self.prepared_degree_bounds_and_shift_powers.is_none() { @@ -335,7 +298,7 @@ where if let Some(shift_power) = shift_power { let mut prepared_shift_gadgets = Vec::::new(); - let supported_bits = ::Fr::size_in_bits(); + let supported_bits = E2Fr::::size_in_bits(); let mut cur: PG::G1Var = shift_power; for _ in 0..supported_bits { @@ -351,16 +314,15 @@ where } } -impl PrepareGadget, ::BaseField> - for PreparedVerifierKeyVar +impl PrepareGadget, E2Fq> for PreparedVerifierKeyVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare(unprepared: &VerifierKeyVar) -> R1CSResult { - let supported_bits = <::Fr as PrimeField>::size_in_bits(); + let supported_bits = as PrimeField>::size_in_bits(); let mut prepared_g = Vec::::new(); let mut g: PG::G1Var = unprepared.g.clone(); @@ -374,11 +336,7 @@ where let prepared_degree_bounds_and_shift_powers = if unprepared.degree_bounds_and_shift_powers.is_some() { - let mut res = Vec::<( - usize, - FpVar<::BaseField>, - Vec, - )>::new(); + let mut res = Vec::<(usize, FpVar>, Vec)>::new(); for (d, d_gadget, shift_power) in unprepared .degree_bounds_and_shift_powers @@ -405,36 +363,15 @@ where } } -impl Clone for PreparedVerifierKeyVar -where - E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, -{ - fn clone(&self) -> Self { - PreparedVerifierKeyVar { - prepared_g: self.prepared_g.clone(), - prepared_h: self.prepared_h.clone(), - prepared_beta_h: self.prepared_beta_h.clone(), - prepared_degree_bounds_and_shift_powers: self - .prepared_degree_bounds_and_shift_powers - .clone(), - constant_allocation: self.constant_allocation, - origin_vk: self.origin_vk.clone(), - } - } -} - -impl AllocVar, ::BaseField> - for PreparedVerifierKeyVar +impl AllocVar, E2Fq> for PreparedVerifierKeyVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(cs, f))] fn new_variable( - cs: impl Into::BaseField>>, + cs: impl Into>>, f: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult @@ -451,7 +388,7 @@ where for g in obj.prepared_vk.prepared_g.iter() { prepared_g.push(::G1Affine, - ::BaseField, + E2Fq, >>::new_variable( ark_relations::ns!(cs, "g"), || Ok(*g), mode )?); @@ -470,11 +407,7 @@ where let prepared_degree_bounds_and_shift_powers = if obj.prepared_degree_bounds_and_shift_powers.is_some() { - let mut res = Vec::<( - usize, - FpVar<::BaseField>, - Vec, - )>::new(); + let mut res = Vec::<(usize, FpVar>, Vec)>::new(); for (d, shift_power_elems) in obj .prepared_degree_bounds_and_shift_powers @@ -486,19 +419,15 @@ where for shift_power_elem in shift_power_elems.iter() { gadgets.push(::G1Affine, - ::BaseField, + E2Fq, >>::new_variable( cs.clone(), || Ok(shift_power_elem), mode )?); } - let d_gadget = FpVar::<::BaseField>::new_variable( + let d_gadget = FpVar::>::new_variable( cs.clone(), - || { - Ok(<::BaseField as From>::from( - *d as u128, - )) - }, + || Ok( as From>::from(*d as u128)), mode, )?; @@ -521,40 +450,25 @@ where } /// Var for an optionally hiding Marlin-KZG10 commitment. -pub struct CommitmentVar< - E: PairingFriendlyCycle, - PG: PairingVar::BaseField>, -> where - ::BaseField: PrimeField, +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] +pub struct CommitmentVar>> +where + E2Fq: PrimeField, { comm: PG::G1Var, shifted_comm: Option, } -impl Clone for CommitmentVar +impl AllocVar, E2Fq> for CommitmentVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, -{ - fn clone(&self) -> Self { - CommitmentVar { - comm: self.comm.clone(), - shifted_comm: self.shifted_comm.clone(), - } - } -} - -impl AllocVar, ::BaseField> - for CommitmentVar -where - E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::BaseField>>, + cs: impl Into>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult @@ -584,16 +498,16 @@ where } } -impl ToConstraintFieldGadget<::BaseField> for CommitmentVar +impl ToConstraintFieldGadget> for CommitmentVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - E::E2: ToConstraintField<::BaseField>, - PG: PairingVar::BaseField>, - PG::G1Var: ToConstraintFieldGadget<::BaseField>, + E2Fq: PrimeField, + E::E2: ToConstraintField>, + PG: PairingVar>, + PG::G1Var: ToConstraintFieldGadget>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_constraint_field(&self) -> R1CSResult::BaseField>>> { + fn to_constraint_field(&self) -> R1CSResult>>> { let mut res = Vec::new(); let mut comm_gadget = self.comm.to_constraint_field()?; @@ -610,14 +524,14 @@ where } } -impl ToBytesGadget<::BaseField> for CommitmentVar +impl ToBytesGadget> for CommitmentVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(self))] - fn to_bytes(&self) -> R1CSResult::BaseField>>> { + fn to_bytes(&self) -> R1CSResult>>> { let zero_shifted_comm = PG::G1Var::zero(); let mut bytes = Vec::new(); @@ -631,38 +545,23 @@ where /// Prepared gadget for an optionally hiding Marlin-KZG10 commitment. /// shifted_comm is not prepared, due to the specific use case. -pub struct PreparedCommitmentVar< - E: PairingFriendlyCycle, - PG: PairingVar::BaseField>, -> { +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] +pub struct PreparedCommitmentVar>> { prepared_comm: Vec, shifted_comm: Option, } -impl Clone for PreparedCommitmentVar -where - E: PairingFriendlyCycle, - PG: PairingVar::BaseField>, -{ - fn clone(&self) -> Self { - PreparedCommitmentVar { - prepared_comm: self.prepared_comm.clone(), - shifted_comm: self.shifted_comm.clone(), - } - } -} - -impl PrepareGadget, ::BaseField> - for PreparedCommitmentVar +impl PrepareGadget, E2Fq> for PreparedCommitmentVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare(unprepared: &CommitmentVar) -> R1CSResult { let mut prepared_comm = Vec::::new(); - let supported_bits = <::Fr as PrimeField>::size_in_bits(); + let supported_bits = as PrimeField>::size_in_bits(); let mut cur: PG::G1Var = unprepared.comm.clone(); for _ in 0..supported_bits { @@ -677,15 +576,14 @@ where } } -impl AllocVar, ::BaseField> - for PreparedCommitmentVar +impl AllocVar, E2Fq> for PreparedCommitmentVar where E: PairingFriendlyCycle, - PG: PairingVar::BaseField>, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(cs, f))] fn new_variable( - cs: impl Into::BaseField>>, + cs: impl Into>>, f: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult @@ -703,7 +601,7 @@ where for comm_elem in obj.prepared_comm.0.iter() { prepared_comm.push(::G1Projective, - ::BaseField, + E2Fq, >>::new_variable( ark_relations::ns!(cs, "comm_elem"), || { @@ -718,7 +616,7 @@ where let shifted_comm = if obj.shifted_comm.is_some() { Some(::G1Projective, - ::BaseField, + E2Fq, >>::new_variable( ark_relations::ns!(cs, "shifted_comm"), || { @@ -740,45 +638,30 @@ where } /// Var for a Marlin-KZG10 commitment, with a string label and degree bound. -pub struct LabeledCommitmentVar< - E: PairingFriendlyCycle, - PG: PairingVar::BaseField>, -> where - ::BaseField: PrimeField, +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] +pub struct LabeledCommitmentVar>> +where + E2Fq: PrimeField, { /// A text label for the commitment. pub label: String, /// The plain commitment. pub commitment: CommitmentVar, /// Optionally, a bound on the polynomial degree. - pub degree_bound: Option::BaseField>>, -} - -impl Clone for LabeledCommitmentVar -where - E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, -{ - fn clone(&self) -> Self { - LabeledCommitmentVar { - label: self.label.clone(), - commitment: self.commitment.clone(), - degree_bound: self.degree_bound.clone(), - } - } + pub degree_bound: Option>>, } -impl AllocVar>, ::BaseField> +impl AllocVar>, E2Fq> for LabeledCommitmentVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::BaseField>>, + cs: impl Into>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult @@ -801,13 +684,9 @@ where )?; let degree_bound = if let Some(degree_bound) = degree_bound { - FpVar::<::BaseField>::new_variable( + FpVar::>::new_variable( ark_relations::ns!(cs, "degree_bound"), - || { - Ok(<::BaseField as From>::from( - degree_bound as u128, - )) - }, + || Ok( as From>::from(degree_bound as u128)), mode, ) .ok() @@ -825,41 +704,28 @@ where } /// Var for a Marlin-KZG10 commitment, with a string label and degree bound. +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct PreparedLabeledCommitmentVar< E: PairingFriendlyCycle, - PG: PairingVar::BaseField>, + PG: PairingVar>, > where - ::BaseField: PrimeField, + E2Fq: PrimeField, { /// A text label for the commitment. pub label: String, /// The plain commitment. pub prepared_commitment: PreparedCommitmentVar, /// Optionally, a bound on the polynomial degree. - pub degree_bound: Option::BaseField>>, + pub degree_bound: Option>>, } -impl Clone for PreparedLabeledCommitmentVar -where - E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, -{ - fn clone(&self) -> Self { - PreparedLabeledCommitmentVar { - label: self.label.clone(), - prepared_commitment: self.prepared_commitment.clone(), - degree_bound: self.degree_bound.clone(), - } - } -} - -impl PrepareGadget, ::BaseField> +impl PrepareGadget, E2Fq> for PreparedLabeledCommitmentVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(unprepared))] fn prepare(unprepared: &LabeledCommitmentVar) -> R1CSResult { @@ -875,43 +741,27 @@ where /// Var for a Marlin-KZG10 proof. #[allow(clippy::type_complexity)] -pub struct ProofVar< - E: PairingFriendlyCycle, - PG: PairingVar::BaseField>, -> where - ::BaseField: PrimeField, +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] +pub struct ProofVar>> +where + E2Fq: PrimeField, { /// The commitment to the witness polynomial. pub w: PG::G1Var, /// The evaluation of the random hiding polynomial. - pub random_v: Option< - NonNativeFieldVar<::Fr, ::BaseField>, - >, + pub random_v: Option, E2Fq>>, } -impl Clone for ProofVar +impl AllocVar, E2Fq> for ProofVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, -{ - fn clone(&self) -> Self { - ProofVar { - w: self.w.clone(), - random_v: self.random_v.clone(), - } - } -} - -impl AllocVar, ::BaseField> for ProofVar -where - E: PairingFriendlyCycle, - ::BaseField: PrimeField, - PG: PairingVar::BaseField>, + E2Fq: PrimeField, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::BaseField>>, + cs: impl Into>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult @@ -941,61 +791,40 @@ where /// An allocated version of `BatchLCProof`. #[allow(clippy::type_complexity)] +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct BatchLCProofVar< E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::BaseField>, + P: UVPolynomial, Point = E2Fr>, + PG: PairingVar>, > where - ::BaseField: PrimeField, + E2Fq: PrimeField, { /// Evaluation proofs. pub proofs: Vec>, /// Evaluations required to verify the proof. - pub evals: Option< - Vec< - NonNativeFieldVar<::Fr, ::BaseField>, - >, - >, + pub evals: Option, E2Fq>>>, #[doc(hidden)] pub polynomial: PhantomData

, } -impl Clone for BatchLCProofVar +impl AllocVar, P, MarlinKZG10>, E2Fq> + for BatchLCProofVar where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::BaseField>, -{ - fn clone(&self) -> Self { - BatchLCProofVar { - proofs: self.proofs.clone(), - evals: self.evals.clone(), - polynomial: PhantomData, - } - } -} - -impl - AllocVar< - BatchLCProof<::Fr, P, MarlinKZG10>, - ::BaseField, - > for BatchLCProofVar -where - E: PairingFriendlyCycle, - ::BaseField: PrimeField, - P: UVPolynomial<::Fr, Point = ::Fr>, + E2Fq: PrimeField, + P: UVPolynomial, Point = E2Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, - PG: PairingVar::BaseField>, + PG: PairingVar>, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( - cs: impl Into::BaseField>>, + cs: impl Into>>, value_gen: impl FnOnce() -> Result, mode: AllocationMode, ) -> R1CSResult where - T: Borrow::Fr, P, MarlinKZG10>>, + T: Borrow, P, MarlinKZG10>>, { value_gen().map(|proof| { let ns = cs.into(); @@ -1012,14 +841,7 @@ where .collect(); #[allow(clippy::type_complexity)] - let evals: Option< - Vec< - NonNativeFieldVar< - ::Fr, - ::BaseField, - >, - >, - > = match evals { + let evals: Option, E2Fq>>> = match evals { None => None, Some(evals_inner) => Some( evals_inner @@ -1046,39 +868,26 @@ where } /// Var for the Marlin-KZG10 polynomial commitment verifier. +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct MarlinKZG10Gadget where E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::BaseField>, + P: UVPolynomial, Point = E2Fr>, + PG: PairingVar>, { _cycle_engine: PhantomData, _pairing_gadget: PhantomData, _polynomial: PhantomData

, } -impl Clone for MarlinKZG10Gadget -where - E: PairingFriendlyCycle, - P: UVPolynomial<::Fr, Point = ::Fr>, - PG: PairingVar::BaseField>, -{ - fn clone(&self) -> Self { - MarlinKZG10Gadget { - _cycle_engine: PhantomData, - _pairing_gadget: PhantomData, - _polynomial: PhantomData, - } - } -} - impl MarlinKZG10Gadget where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - P: UVPolynomial<::Fr, Point = ::Fr>, + E2Fq: PrimeField, + P: UVPolynomial, Point = E2Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, - PG: PairingVar::BaseField>, + PG: PairingVar>, { #[allow(clippy::type_complexity, clippy::too_many_arguments)] #[tracing::instrument( @@ -1086,52 +895,35 @@ where skip(prepared_verification_key, lc_info, query_set, evaluations, proofs) )] fn prepared_batch_check_evaluations( - cs: ConstraintSystemRef<::BaseField>, + cs: ConstraintSystemRef>, prepared_verification_key: &::Fr, + E2Fr, P, MarlinKZG10, - ::BaseField, + E2Fq, >>::PreparedVerifierKeyVar, lc_info: &[( String, Vec<( - Option< - NonNativeFieldVar< - ::Fr, - ::BaseField, - >, - >, - Option::BaseField>>, + Option, E2Fq>>, + Option>>, PreparedCommitmentVar, bool, )>, )], - query_set: &QuerySetVar< - ::Fr, - ::BaseField, - >, - evaluations: &EvaluationsVar< - ::Fr, - ::BaseField, - >, + query_set: &QuerySetVar, E2Fq>, + evaluations: &EvaluationsVar, E2Fq>, proofs: &[::Fr, + E2Fr, P, MarlinKZG10, - ::BaseField, + E2Fq, >>::ProofVar], - opening_challenges: &[NonNativeFieldVar< - ::Fr, - ::BaseField, - >], - opening_challenges_bits: &[Vec::BaseField>>], - batching_rands: &[NonNativeFieldVar< - ::Fr, - ::BaseField, - >], - batching_rands_bits: &[Vec::BaseField>>], - ) -> R1CSResult::BaseField>> { + opening_challenges: &[NonNativeFieldVar, E2Fq>], + opening_challenges_bits: &[Vec>>], + batching_rands: &[NonNativeFieldVar, E2Fq>], + batching_rands_bits: &[Vec>>], + ) -> R1CSResult>> { let mut batching_rands = batching_rands.to_vec(); let mut batching_rands_bits = batching_rands_bits.to_vec(); @@ -1140,13 +932,8 @@ where ( String, Vec<( - Option< - NonNativeFieldVar< - ::Fr, - ::BaseField, - >, - >, - Option::BaseField>>, + Option, E2Fq>>, + Option>>, PreparedCommitmentVar, bool, )>, @@ -1174,13 +961,8 @@ where for (_, (point, labels)) in query_to_labels_map.into_iter() { let mut comms_to_combine = Vec::< Vec<( - Option< - NonNativeFieldVar< - ::Fr, - ::BaseField, - >, - >, - Option::BaseField>>, + Option, E2Fq>>, + Option>>, PreparedCommitmentVar, bool, )>, @@ -1203,10 +985,7 @@ where // Accumulate the commitments and evaluations corresponding to `query`. let mut combined_comm = PG::G1Var::zero(); - let mut combined_eval = NonNativeFieldMulResultVar::< - ::Fr, - ::BaseField, - >::zero(); + let mut combined_eval = NonNativeFieldMulResultVar::, E2Fq>::zero(); let mut opening_challenges_counter = 0; @@ -1332,14 +1111,8 @@ where let mut total_c = PG::G1Var::zero(); let mut total_w = PG::G1Var::zero(); - let mut g_multiplier = NonNativeFieldMulResultVar::< - ::Fr, - ::BaseField, - >::zero(); - let mut g_multiplier_reduced = NonNativeFieldVar::< - ::Fr, - ::BaseField, - >::zero(); + let mut g_multiplier = NonNativeFieldMulResultVar::, E2Fq>::zero(); + let mut g_multiplier_reduced = NonNativeFieldVar::, E2Fq>::zero(); for (i, (((c, z), v), proof)) in combined_comms .iter() .zip(combined_queries) @@ -1423,19 +1196,14 @@ where } } -impl - PCCheckVar< - ::Fr, - P, - MarlinKZG10, - ::BaseField, - > for MarlinKZG10Gadget +impl PCCheckVar, P, MarlinKZG10, E2Fq> + for MarlinKZG10Gadget where E: PairingFriendlyCycle, - ::BaseField: PrimeField, - P: UVPolynomial<::Fr, Point = ::Fr>, + E2Fq: PrimeField, + P: UVPolynomial, Point = E2Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, - PG: PairingVar::BaseField>, + PG: PairingVar>, { type VerifierKeyVar = VerifierKeyVar; type PreparedVerifierKeyVar = PreparedVerifierKeyVar; @@ -1452,23 +1220,14 @@ where skip(verification_key, commitments, query_set, evaluations, proofs) )] fn batch_check_evaluations( - _cs: ConstraintSystemRef<::BaseField>, + _cs: ConstraintSystemRef>, verification_key: &Self::VerifierKeyVar, commitments: &[Self::LabeledCommitmentVar], - query_set: &QuerySetVar< - ::Fr, - ::BaseField, - >, - evaluations: &EvaluationsVar< - ::Fr, - ::BaseField, - >, + query_set: &QuerySetVar, E2Fq>, + evaluations: &EvaluationsVar, E2Fq>, proofs: &[Self::ProofVar], - rand_data: &PCCheckRandomDataVar< - ::Fr, - ::BaseField, - >, - ) -> R1CSResult::BaseField>> { + rand_data: &PCCheckRandomDataVar, E2Fq>, + ) -> R1CSResult>> { let mut batching_rands = rand_data.batching_rands.to_vec(); let mut batching_rands_bits = rand_data.batching_rands_bits.to_vec(); @@ -1512,10 +1271,7 @@ where // Accumulate the commitments and evaluations corresponding to `query`. let mut combined_comm = PG::G1Var::zero(); - let mut combined_eval = NonNativeFieldMulResultVar::< - ::Fr, - ::BaseField, - >::zero(); + let mut combined_eval = NonNativeFieldMulResultVar::, E2Fq>::zero(); let mut opening_challenges_counter = 0; @@ -1577,10 +1333,7 @@ where let mut total_c = PG::G1Var::zero(); let mut total_w = PG::G1Var::zero(); - let mut g_multiplier = NonNativeFieldMulResultVar::< - ::Fr, - ::BaseField, - >::zero(); + let mut g_multiplier = NonNativeFieldMulResultVar::, E2Fq>::zero(); for (((c, z), v), proof) in combined_comms .iter() .zip(combined_queries) @@ -1653,27 +1406,15 @@ where ) )] fn prepared_check_combinations( - cs: ConstraintSystemRef<::BaseField>, + cs: ConstraintSystemRef>, prepared_verification_key: &Self::PreparedVerifierKeyVar, - linear_combinations: &[LinearCombinationVar< - ::Fr, - ::BaseField, - >], + linear_combinations: &[LinearCombinationVar, E2Fq>], prepared_commitments: &[Self::PreparedLabeledCommitmentVar], - query_set: &QuerySetVar< - ::Fr, - ::BaseField, - >, - evaluations: &EvaluationsVar< - ::Fr, - ::BaseField, - >, + query_set: &QuerySetVar, E2Fq>, + evaluations: &EvaluationsVar, E2Fq>, proof: &Self::BatchLCProofVar, - rand_data: &PCCheckRandomDataVar< - ::Fr, - ::BaseField, - >, - ) -> R1CSResult::BaseField>> { + rand_data: &PCCheckRandomDataVar, E2Fq>, + ) -> R1CSResult>> { let BatchLCProofVar { proofs, .. } = proof; let label_comm_map = prepared_commitments @@ -1759,7 +1500,7 @@ where fn create_labeled_commitment( label: String, commitment: Self::CommitmentVar, - degree_bound: Option::BaseField>>, + degree_bound: Option>>, ) -> Self::LabeledCommitmentVar { Self::LabeledCommitmentVar { label, @@ -1771,7 +1512,7 @@ where fn create_prepared_labeled_commitment( label: String, prepared_commitment: Self::PreparedCommitmentVar, - degree_bound: Option::BaseField>>, + degree_bound: Option>>, ) -> Self::PreparedLabeledCommitmentVar { Self::PreparedLabeledCommitmentVar { label, From a757cc22075b16314bde4b1c394c0a0cc638e0b0 Mon Sep 17 00:00:00 2001 From: weikeng Date: Mon, 8 Feb 2021 14:50:37 -0800 Subject: [PATCH 46/56] derive Clone for BatchLCProof --- src/data_structures.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/data_structures.rs b/src/data_structures.rs index f5098198..857d2374 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -103,7 +103,8 @@ pub trait PCProof: Clone + ark_ff::ToBytes + CanonicalSerialize + CanonicalDeser } /// A proof of satisfaction of linear combinations. -#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] +#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)] +#[derivative(Clone(bound = "F: Field, P: Polynomial, PC: PolynomialCommitment"))] pub struct BatchLCProof, PC: PolynomialCommitment> { /// Evaluation proof. pub proof: PC::BatchProof, From cffd1a496b942a474fccb91929419b5434485c70 Mon Sep 17 00:00:00 2001 From: weikeng Date: Mon, 8 Feb 2021 18:42:14 -0800 Subject: [PATCH 47/56] change the handling of one and minus one coeff --- src/marlin/marlin_pc/constraints.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index 2ae2734e..078bede3 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -1464,10 +1464,8 @@ where } let coeff = match coeff { - LinearCombinationCoeffVar::One => Some(NonNativeFieldVar::one()), - LinearCombinationCoeffVar::MinusOne => { - Some(NonNativeFieldVar::zero() - NonNativeFieldVar::one()) - } + LinearCombinationCoeffVar::One => None, + LinearCombinationCoeffVar::MinusOne => None, LinearCombinationCoeffVar::Var(variable) => Some(variable.clone()), }; From 93969dcfb9a90591a1a4d1952600a500a809c387 Mon Sep 17 00:00:00 2001 From: weikeng Date: Mon, 8 Feb 2021 22:38:59 -0800 Subject: [PATCH 48/56] no std --- src/marlin/marlin_pc/constraints.rs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index 078bede3..cc24b4b1 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -949,11 +949,6 @@ where labels.1.insert(label); } - println!( - "before PC combining commitments: constraints: {}", - cs.num_constraints() - ); - // Accumulate commitments and evaluations for each query. let mut combined_queries = Vec::new(); let mut combined_comms = Vec::new(); @@ -1101,11 +1096,6 @@ where combined_evals.push(combined_eval_reduced); } - println!( - "before PC batch check: constraints: {}", - cs.num_constraints() - ); - // Perform the batch check. { let mut total_c = PG::G1Var::zero(); @@ -1185,11 +1175,6 @@ where &[prepared_beta_h, prepared_h], )?; - println!( - "after PC batch check: constraints: {}", - cs.num_constraints() - ); - let rhs = &PG::GTVar::one(); lhs.is_eq(&rhs) } From 1751933e52280774fac0ec89a46006498d163bf3 Mon Sep 17 00:00:00 2001 From: weikeng Date: Tue, 23 Mar 2021 09:44:24 -0700 Subject: [PATCH 49/56] remove bench-utils --- Cargo.toml | 4 +--- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 75f8be20..228c4f55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,8 +32,6 @@ ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std", default-featur ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative", default-features = false, optional = true } hashbrown = { version = "0.9", optional = true } -bench-utils = { git = "https://github.com/arkworks-rs/utils", default-features = false } - rand_core = { version = "0.5", default-features = false } digest = "0.9" rayon = { version = "1", optional = true } @@ -64,5 +62,5 @@ debug = true default = [ "std", "parallel" ] std = [ "ark-ff/std", "ark-ec/std", "ark-nonnative-field/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std" ] r1cs = [ "ark-relations", "ark-r1cs-std", "ark-nonnative-field", "hashbrown" ] -print-trace = [ "bench-utils/print-trace" ] +print-trace = [ "ark-std/print-trace" ] parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ] diff --git a/src/lib.rs b/src/lib.rs index 0ac91ab9..a4546556 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ #[macro_use] extern crate derivative; #[macro_use] -extern crate bench_utils; +extern crate ark_std; use ark_ff::Field; pub use ark_poly::{Polynomial, UVPolynomial}; From 38add1bd5837579c5b49496f198d5236a6ca1950 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 14 Apr 2021 12:03:27 -0700 Subject: [PATCH 50/56] rewrote some comments --- src/marlin/marlin_pc/constraints.rs | 31 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index cc24b4b1..28beae12 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -20,7 +20,8 @@ use ark_std::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::Div, v type E2Fr = <::E2 as AffineCurve>::ScalarField; type E2Fq = <::E2 as AffineCurve>::BaseField; -/// High level variable representing the verification key of the `MarlinKZG10` polynomial commitment scheme. +/// High level variable representing the verification key of the `MarlinKZG10` polynomial commitment +/// scheme. #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct VerifierKeyVar>> @@ -237,7 +238,8 @@ where } } -/// Var for the verification key of the Marlin-KZG10 polynomial commitment scheme. +/// High level variable representing the verification key of the `MarlinKZG10` polynomial commitment +/// scheme, prepared for use in arithmetic. #[allow(clippy::type_complexity)] #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] @@ -254,9 +256,11 @@ where /// Used for the shift powers associated with different degree bounds. pub prepared_degree_bounds_and_shift_powers: Option>, Vec)>>, - /// Indicate whether or not it is a constant allocation (which decides whether or not shift powers are precomputed) + /// Indicate whether or not it is a constant allocation (which decides whether or not shift + /// powers are precomputed). pub constant_allocation: bool, - /// If not a constant allocation, the original vk is attached (for computing the shift power series) + /// If not a constant allocation, the original vk is attached (for computing the shift power + /// series). pub origin_vk: Option>, } @@ -449,7 +453,7 @@ where } } -/// Var for an optionally hiding Marlin-KZG10 commitment. +/// High level variable representing a commitment in the `MarlinKZG10` polynomial commitment scheme. #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct CommitmentVar>> @@ -543,8 +547,8 @@ where } } -/// Prepared gadget for an optionally hiding Marlin-KZG10 commitment. -/// shifted_comm is not prepared, due to the specific use case. +/// High level variable for a `MarlinKZG10` polynomial commitment, prepared for use in arirthmetic. +/// (`shifted_comm` is not prepared, due to the specific use case.) #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct PreparedCommitmentVar>> { @@ -637,7 +641,8 @@ where } } -/// Var for a Marlin-KZG10 commitment, with a string label and degree bound. +/// High level variable for a `MarlinKZG10` polynomial commitment, along with a string label and a +/// degree bound. #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct LabeledCommitmentVar>> @@ -703,7 +708,8 @@ where } } -/// Var for a Marlin-KZG10 commitment, with a string label and degree bound. +/// High level variable for a `MarlinKZG10` polynomial commitment, along with a string label and a +/// degree bound, prepared for use in arithmetic. #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct PreparedLabeledCommitmentVar< @@ -739,7 +745,7 @@ where } } -/// Var for a Marlin-KZG10 proof. +/// High level variable for a `MarlinKZG10` opening proof. #[allow(clippy::type_complexity)] #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] @@ -789,7 +795,8 @@ where } } -/// An allocated version of `BatchLCProof`. +/// High level variable for a batched `MarlinKZG10` proof, for the opening of a linear combination +/// of polynomials. #[allow(clippy::type_complexity)] #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] @@ -867,7 +874,7 @@ where } } -/// Var for the Marlin-KZG10 polynomial commitment verifier. +/// Gadget for the `MarlinKZG10` polynomial commitment verifier. #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct MarlinKZG10Gadget From 78af43d3b4a31a4e6a6caee3e2522d945a884e59 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 15 Apr 2021 10:03:40 -0700 Subject: [PATCH 51/56] LCInfo type for clarity --- src/marlin/marlin_pc/constraints.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index 28beae12..2efdbdcf 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -874,6 +874,18 @@ where } } +/// Helper struct for information about one member of a linear combination. +pub struct LCItem +where + E: PairingFriendlyCycle, + PG: PairingVar>, +{ + coeff: Option, E2Fq>>, + degree_bound: Option>>, + comm: PreparedCommitmentVar, + negate: bool, +} + /// Gadget for the `MarlinKZG10` polynomial commitment verifier. #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] @@ -911,12 +923,7 @@ where >>::PreparedVerifierKeyVar, lc_info: &[( String, - Vec<( - Option, E2Fq>>, - Option>>, - PreparedCommitmentVar, - bool, - )>, + Vec, )], query_set: &QuerySetVar, E2Fq>, evaluations: &EvaluationsVar, E2Fq>, @@ -997,7 +1004,8 @@ where let challenge_bits = opening_challenges_bits[opening_challenges_counter].clone(); opening_challenges_counter += 1; - for (coeff, degree_bound, comm, negate) in commitment_lcs.iter() { + for lc_info in commitment_lcs.iter() { + let LCInfo { coeff, degree_bound, comm, negate } = lc_info; let PreparedCommitmentVar { shifted_comm, .. } = comm; if coeff.is_none() { From caa3375763bee2765fca2de5eab015861341dd0e Mon Sep 17 00:00:00 2001 From: Will Lin Date: Thu, 29 Apr 2021 15:33:22 -0400 Subject: [PATCH 52/56] update dependencies to use release versions --- Cargo.toml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 228c4f55..4687c7ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,15 +21,15 @@ license = "MIT/Apache-2.0" edition = "2018" [dependencies] -ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false, features = [ "derive" ] } -ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false } -ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false } -ark-poly = { git = "https://github.com/arkworks-rs/algebra", default-features = false } +ark-serialize = { version = "^0.2.0", default-features = false, features = [ "derive" ] } +ark-ff = { version = "^0.2.0", default-features = false } +ark-ec = { version = "^0.2.0", default-features = false } +ark-poly = { version = "^0.2.0", default-features = false } -ark-std = { git = "https://github.com/arkworks-rs/utils", default-features = false } -ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features = false, optional = true } -ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std", default-features = false, optional = true } -ark-nonnative-field = { git = "https://github.com/arkworks-rs/nonnative", default-features = false, optional = true } +ark-std = { version = "^0.2.0", default-features = false } +ark-relations = { version = "^0.2.0", default-features = false, optional = true } +ark-r1cs-std = { version = "^0.2.0", default-features = false, optional = true } +ark-nonnative-field = { version = "^0.2.0", default-features = false, optional = true } hashbrown = { version = "0.9", optional = true } rand_core = { version = "0.5", default-features = false } @@ -41,9 +41,9 @@ tracing = { version = "0.1", default-features = false, features = [ "attributes" [dev-dependencies] rand = { version = "0.7", default-features = false } -ark-ed-on-bls12-381 = { git = "https://github.com/arkworks-rs/curves", default-features = false } -ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves", default-features = false, features = [ "curve" ] } -ark-bls12-377 = { git = "https://github.com/arkworks-rs/curves", default-features = false, features = [ "curve" ] } +ark-ed-on-bls12-381 = { version = "^0.2.0", default-features = false } +ark-bls12-381 = { version = "^0.2.0", default-features = false, features = [ "curve" ] } +ark-bls12-377 = { version = "^0.2.0", default-features = false, features = [ "curve" ] } blake2 = { version = "0.9", default-features = false } [profile.release] From 44ca5a644e08945d5451a53c397799c995fd964a Mon Sep 17 00:00:00 2001 From: Will Lin Date: Thu, 29 Apr 2021 16:05:38 -0400 Subject: [PATCH 53/56] fix lcitem type integration --- src/marlin/marlin_pc/constraints.rs | 33 ++++++++++++----------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index 2efdbdcf..5768524d 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -875,10 +875,13 @@ where } /// Helper struct for information about one member of a linear combination. +#[derive(Derivative)] +#[derivative(Clone(bound = "E: PairingFriendlyCycle"))] pub struct LCItem where E: PairingFriendlyCycle, PG: PairingVar>, + E2Fq: PrimeField, { coeff: Option, E2Fq>>, degree_bound: Option>>, @@ -923,7 +926,7 @@ where >>::PreparedVerifierKeyVar, lc_info: &[( String, - Vec, + Vec>, )], query_set: &QuerySetVar, E2Fq>, evaluations: &EvaluationsVar, E2Fq>, @@ -945,12 +948,7 @@ where String, ( String, - Vec<( - Option, E2Fq>>, - Option>>, - PreparedCommitmentVar, - bool, - )>, + Vec>, ), > = lc_info.iter().map(|c| (c.0.clone(), c.clone())).collect(); @@ -969,12 +967,7 @@ where let mut combined_evals = Vec::new(); for (_, (point, labels)) in query_to_labels_map.into_iter() { let mut comms_to_combine = Vec::< - Vec<( - Option, E2Fq>>, - Option>>, - PreparedCommitmentVar, - bool, - )>, + Vec>, >::new(); let mut values_to_combine = Vec::new(); for label in labels.into_iter() { @@ -1005,7 +998,7 @@ where opening_challenges_counter += 1; for lc_info in commitment_lcs.iter() { - let LCInfo { coeff, degree_bound, comm, negate } = lc_info; + let LCItem:: { coeff, degree_bound, comm, negate } = lc_info; let PreparedCommitmentVar { shifted_comm, .. } = comm; if coeff.is_none() { @@ -1469,12 +1462,12 @@ where LinearCombinationCoeffVar::Var(variable) => Some(variable.clone()), }; - coeffs_and_comms.push(( - coeff.clone(), - cur_comm.degree_bound.clone(), - cur_comm.prepared_commitment.clone(), - negate, - )); + coeffs_and_comms.push( LCItem { + coeff, + degree_bound: cur_comm.degree_bound.clone(), + comm: cur_comm.prepared_commitment.clone(), + negate + }); } } From 3cfa438ac78d0041eb7c1857f479db6c4586a011 Mon Sep 17 00:00:00 2001 From: Victor Lopes Date: Mon, 7 Mar 2022 20:55:12 +0100 Subject: [PATCH 54/56] Fix and update dependencies to 0.3 (#93) --- Cargo.toml | 27 ++++++------ src/data_structures.rs | 1 + src/marlin/marlin_pc/constraints.rs | 66 ++++++++++++++++------------- src/marlin/marlin_pc/mod.rs | 2 + 4 files changed, 54 insertions(+), 42 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b4805c12..e2a4471e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ark-poly-commit" -version = "0.3.0" +version = "0.3.1" authors = [ "Alessandro Chiesa ", "Mary Maller ", @@ -21,26 +21,27 @@ license = "MIT/Apache-2.0" edition = "2018" [dependencies] -ark-serialize = { version = "^0.3.0", default-features = false, features = [ "derive" ] } -ark-ff = { version = "^0.3.0", default-features = false } -ark-ec = { version = "^0.3.0", default-features = false } -ark-poly = {version = "^0.3.0", default-features = false } -ark-sponge = {version = "^0.3.0", default-features = false} +ark-serialize = { version = "0.3", default-features = false, features = [ "derive" ] } +ark-ff = { version = "0.3", default-features = false } +ark-ec = { version = "0.3", default-features = false } +ark-poly = {version = "0.3", default-features = false } +ark-sponge = {version = "0.3", default-features = false} -ark-std = { version = "^0.3.0", default-features = false } -ark-relations = { version = "^0.3.0", default-features = false, optional = true } -ark-r1cs-std = { version = "^0.3.0", default-features = false, optional = true } -ark-nonnative-field = { version = "^0.3.0", default-features = false, optional = true } +ark-std = { version = "0.3", default-features = false } +ark-relations = { version = "0.3", default-features = false, optional = true } +ark-r1cs-std = { version = "0.3", default-features = false, optional = true } +ark-nonnative-field = { version = "0.3", default-features = false, optional = true } hashbrown = { version = "0.9", optional = true } digest = "0.9" rayon = { version = "1", optional = true } derivative = { version = "2", features = [ "use_core" ] } +tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } [dev-dependencies] -ark-ed-on-bls12-381 = { version = "^0.3.0", default-features = false } -ark-bls12-381 = { version = "^0.3.0", default-features = false, features = [ "curve" ] } -ark-bls12-377 = { version = "^0.3.0", default-features = false, features = [ "curve" ] } +ark-ed-on-bls12-381 = { version = "0.3", default-features = false } +ark-bls12-381 = { version = "0.3", default-features = false, features = [ "curve" ] } +ark-bls12-377 = { version = "0.3", default-features = false, features = [ "curve" ] } blake2 = { version = "0.9", default-features = false } [profile.release] diff --git a/src/data_structures.rs b/src/data_structures.rs index ccf75874..6d155101 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -108,6 +108,7 @@ pub struct BatchLCProof>` should be `Vec<_>` pub evals: Option>, } diff --git a/src/marlin/marlin_pc/constraints.rs b/src/marlin/marlin_pc/constraints.rs index 5768524d..9d0dff50 100644 --- a/src/marlin/marlin_pc/constraints.rs +++ b/src/marlin/marlin_pc/constraints.rs @@ -15,6 +15,7 @@ use ark_nonnative_field::{NonNativeFieldMulResultVar, NonNativeFieldVar}; use ark_poly::UVPolynomial; use ark_r1cs_std::{fields::fp::FpVar, prelude::*, ToConstraintFieldGadget}; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError}; +use ark_sponge::CryptographicSponge; use ark_std::{borrow::Borrow, convert::TryInto, marker::PhantomData, ops::Div, vec}; type E2Fr = <::E2 as AffineCurve>::ScalarField; @@ -804,6 +805,7 @@ pub struct BatchLCProofVar< E: PairingFriendlyCycle, P: UVPolynomial, Point = E2Fr>, PG: PairingVar>, + S: CryptographicSponge, > where E2Fq: PrimeField, { @@ -813,16 +815,19 @@ pub struct BatchLCProofVar< pub evals: Option, E2Fq>>>, #[doc(hidden)] pub polynomial: PhantomData

, + _sponge: PhantomData, } -impl AllocVar, P, MarlinKZG10>, E2Fq> - for BatchLCProofVar +impl + AllocVar, Vec::Engine2>>>, E2Fq> + for BatchLCProofVar where E: PairingFriendlyCycle, E2Fq: PrimeField, P: UVPolynomial, Point = E2Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, PG: PairingVar>, + S: CryptographicSponge, { #[tracing::instrument(target = "r1cs", skip(cs, value_gen))] fn new_variable( @@ -831,7 +836,7 @@ where mode: AllocationMode, ) -> R1CSResult where - T: Borrow, P, MarlinKZG10>>, + T: Borrow, Vec::Engine2>>>>, { value_gen().map(|proof| { let ns = cs.into(); @@ -839,8 +844,7 @@ where let BatchLCProof { proof, evals } = proof.borrow().clone(); - let proofs: Vec> = proof.to_vec(); - let proofs: Vec> = proofs + let proofs: Vec> = proof .iter() .map(|p| { ProofVar::new_variable(ark_relations::ns!(cs, "proof"), || Ok(p), mode).unwrap() @@ -869,6 +873,7 @@ where proofs, evals, polynomial: PhantomData, + _sponge: PhantomData, } }) } @@ -892,49 +897,53 @@ where /// Gadget for the `MarlinKZG10` polynomial commitment verifier. #[derive(Derivative)] #[derivative(Clone(bound = "E: PairingFriendlyCycle"))] -pub struct MarlinKZG10Gadget +pub struct MarlinKZG10Gadget where E: PairingFriendlyCycle, P: UVPolynomial, Point = E2Fr>, PG: PairingVar>, + S: CryptographicSponge, { _cycle_engine: PhantomData, _pairing_gadget: PhantomData, _polynomial: PhantomData

, + _sponge: PhantomData, } -impl MarlinKZG10Gadget +impl MarlinKZG10Gadget where E: PairingFriendlyCycle, E2Fq: PrimeField, P: UVPolynomial, Point = E2Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, PG: PairingVar>, + S: CryptographicSponge, { #[allow(clippy::type_complexity, clippy::too_many_arguments)] #[tracing::instrument( target = "r1cs", skip(prepared_verification_key, lc_info, query_set, evaluations, proofs) )] + // rustfmt bug with generics struct + #[rustfmt::skip] fn prepared_batch_check_evaluations( cs: ConstraintSystemRef>, prepared_verification_key: &, P, - MarlinKZG10, + MarlinKZG10, E2Fq, + S, >>::PreparedVerifierKeyVar, - lc_info: &[( - String, - Vec>, - )], + lc_info: &[(String, Vec>)], query_set: &QuerySetVar, E2Fq>, evaluations: &EvaluationsVar, E2Fq>, proofs: &[, P, - MarlinKZG10, + MarlinKZG10, E2Fq, + S, >>::ProofVar], opening_challenges: &[NonNativeFieldVar, E2Fq>], opening_challenges_bits: &[Vec>>], @@ -944,13 +953,8 @@ where let mut batching_rands = batching_rands.to_vec(); let mut batching_rands_bits = batching_rands_bits.to_vec(); - let commitment_lcs: BTreeMap< - String, - ( - String, - Vec>, - ), - > = lc_info.iter().map(|c| (c.0.clone(), c.clone())).collect(); + let commitment_lcs: BTreeMap>)> = + lc_info.iter().map(|c| (c.0.clone(), c.clone())).collect(); let mut query_to_labels_map = BTreeMap::new(); @@ -966,9 +970,7 @@ where let mut combined_comms = Vec::new(); let mut combined_evals = Vec::new(); for (_, (point, labels)) in query_to_labels_map.into_iter() { - let mut comms_to_combine = Vec::< - Vec>, - >::new(); + let mut comms_to_combine = Vec::>>::new(); let mut values_to_combine = Vec::new(); for label in labels.into_iter() { let commitment_lc = commitment_lcs.get(label).unwrap().clone(); @@ -998,7 +1000,12 @@ where opening_challenges_counter += 1; for lc_info in commitment_lcs.iter() { - let LCItem:: { coeff, degree_bound, comm, negate } = lc_info; + let LCItem:: { + coeff, + degree_bound, + comm, + negate, + } = lc_info; let PreparedCommitmentVar { shifted_comm, .. } = comm; if coeff.is_none() { @@ -1189,14 +1196,15 @@ where } } -impl PCCheckVar, P, MarlinKZG10, E2Fq> - for MarlinKZG10Gadget +impl PCCheckVar, P, MarlinKZG10, E2Fq, S> + for MarlinKZG10Gadget where E: PairingFriendlyCycle, E2Fq: PrimeField, P: UVPolynomial, Point = E2Fr>, for<'a, 'b> &'a P: Div<&'b P, Output = P>, PG: PairingVar>, + S: CryptographicSponge, { type VerifierKeyVar = VerifierKeyVar; type PreparedVerifierKeyVar = PreparedVerifierKeyVar; @@ -1205,7 +1213,7 @@ where type LabeledCommitmentVar = LabeledCommitmentVar; type PreparedLabeledCommitmentVar = PreparedLabeledCommitmentVar; type ProofVar = ProofVar; - type BatchLCProofVar = BatchLCProofVar; + type BatchLCProofVar = BatchLCProofVar; #[allow(clippy::type_complexity)] #[tracing::instrument( @@ -1462,11 +1470,11 @@ where LinearCombinationCoeffVar::Var(variable) => Some(variable.clone()), }; - coeffs_and_comms.push( LCItem { + coeffs_and_comms.push(LCItem { coeff, degree_bound: cur_comm.degree_bound.clone(), comm: cur_comm.prepared_commitment.clone(), - negate + negate, }); } } diff --git a/src/marlin/marlin_pc/mod.rs b/src/marlin/marlin_pc/mod.rs index 138e7167..d5b94895 100644 --- a/src/marlin/marlin_pc/mod.rs +++ b/src/marlin/marlin_pc/mod.rs @@ -6,6 +6,7 @@ use crate::{PCRandomness, PCUniversalParams, PolynomialCommitment}; use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve}; use ark_ff::Zero; use ark_poly::UVPolynomial; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write}; use ark_std::rand::RngCore; use ark_std::{marker::PhantomData, ops::Div, vec}; @@ -32,6 +33,7 @@ pub use constraints::*; /// /// [kzg]: http://cacr.uwaterloo.ca/techreports/2010/cacr2010-10.pdf /// [marlin]: https://eprint.iacr.org/2019/104 +#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)] pub struct MarlinKZG10, S: CryptographicSponge> { _engine: PhantomData, _poly: PhantomData

, From 7f8e2c553e5d05b30f128310e762ef6e04c36a0c Mon Sep 17 00:00:00 2001 From: Victor Lopes Date: Tue, 8 Mar 2022 00:48:28 +0100 Subject: [PATCH 55/56] Merge `master` into `constraints` (#94) Co-authored-by: Pratyush Mishra Co-authored-by: Alex Xiong Co-authored-by: Weikeng Chen Co-authored-by: zhenfei Co-authored-by: Michael Rosenberg Co-authored-by: Yuncong Hu --- Cargo.toml | 1 + README.md | 6 +- src/README.md | 107 ++++++++++++++++++++++++++++++ src/ipa_pc/mod.rs | 16 +++-- src/kzg10/data_structures.rs | 75 +++++++++++++++++++-- src/lib.rs | 62 ++++++++--------- src/marlin/marlin_pc/mod.rs | 8 +-- src/marlin/marlin_pst13_pc/mod.rs | 6 +- src/sonic_pc/mod.rs | 6 +- 9 files changed, 232 insertions(+), 55 deletions(-) create mode 100644 src/README.md diff --git a/Cargo.toml b/Cargo.toml index e2a4471e..40adf368 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ ark-ed-on-bls12-381 = { version = "0.3", default-features = false } ark-bls12-381 = { version = "0.3", default-features = false, features = [ "curve" ] } ark-bls12-377 = { version = "0.3", default-features = false, features = [ "curve" ] } blake2 = { version = "0.9", default-features = false } +rand_chacha = { version = "0.3.0", default-features = false } [profile.release] opt-level = 3 diff --git a/README.md b/README.md index 6f5a3b9c..a468f981 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Unless you explicitly state otherwise, any contribution that you submit to this [sonic]: https://ia.cr/2019/099 [aurora-light]: https://ia.cr/2019/601 [pcd-acc]: https://ia.cr/2020/499 -[pst]: https://ia.cr.org/2011/587 +[pst]: https://ia.cr/2011/587 ## Reference papers @@ -78,8 +78,8 @@ EUROCRYPT 2020 Benedikt Bünz, Alessandro Chiesa, [Pratyush Mishra](https://www.github.com/pratyush), Nicholas Spooner TCC 2020 -[Signatures of Correct Computation][pst] -Charalampos Papamanthou, Elaine Shi, Roberto Tamassia +[Signatures of Correct Computation][pst] +Charalampos Papamanthou, Elaine Shi, Roberto Tamassia TCC 2013 ## Acknowledgements diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000..ec22e02a --- /dev/null +++ b/src/README.md @@ -0,0 +1,107 @@ +## Supported Polynomial Commitment Schemes + +The library supports four polynomial commitment schemes. + +### Inner-product-argument PC + +A polynomial commitment scheme based on the hardness of the discrete logarithm problem in prime-order groups. + +The construction is described in the following paper. + +[pcd-acc]: https://ia.cr/2020/499 + +[Proof-Carrying Data from Accumulation Schemes][pcd-acc] +Benedikt Bünz, Alessandro Chiesa, Pratyush Mishra, Nicholas Spooner +TCC 2020 + +### Marlin variant of the Kate-Zaverucha-Goldberg PC + +[kzg10]: http://cacr.uwaterloo.ca/techreports/2010/cacr2010-10.pdf +[marlin]: https://ia.cr/2019/1047 + +Polynomial commitment based on the Kate-Zaverucha-Goldberg construction, with degree enforcement, batching, and (optional) hiding property taken from Marlin. + +The construction is described in the following paper. + +[Marlin: Preprocessing zkSNARKs with Universal and Updatable SRS][marlin] +Alessandro Chiesa, Yuncong Hu, Mary Maller, Pratyush Mishra, Noah Vesely, Nicholas Ward +EUROCRYPT 2020 + +[Polynomial Commitments][kzg10] +Aniket Kate, Gregory M. Zaverucha, Ian Goldberg +ASIACRYPT 2010 + +### Sonic/AuroraLight variant of the Kate-Zaverucha-Goldberg PC + +Polynomial commitment based on the Kate-Zaverucha-Goldberg construction, with degree enforcement and batching taken from Sonic (more precisely, their counterparts in AuroraLight that avoid negative G1 powers). The (optional) hiding property of the commitment scheme follows the approach described in Marlin. + +The construction is described in the following papers. + +[sonic]: https://ia.cr/2019/099 +[aurora-light]: https://ia.cr/2019/601 + +[AuroraLight: Improved Prover Efficiency and SRS Size in a Sonic-Like System][aurora-light] +Ariel Gabizon +ePrint, 2019 + +[Sonic: Zero-Knowledge SNARKs from Linear-Size Universal and Updateable Structured Reference Strings][sonic] +Mary Maller, Sean Bowe, Markulf Kohlweiss, Sarah Meiklejohn +CCS 2019 + +[Marlin: Preprocessing zkSNARKs with Universal and Updatable SRS][marlin] +Alessandro Chiesa, Yuncong Hu, Mary Maller, Pratyush Mishra, Noah Vesely, Nicholas Ward +EUROCRYPT 2020 + +[Polynomial Commitments][kzg10] +Aniket Kate, Gregory M. Zaverucha, Ian Goldberg +ASIACRYPT 2010 + +### Marlin variant of the Papamanthou-Shi-Tamassia multivariate PC + +Multivariate polynomial commitment based on the construction in the Papamanthou-Shi-Tamassia construction with batching and (optional) hiding property inspired by the univariate scheme in Marlin. + +The construction is described in the following paper. + +[pst]: https://ia.cr/2011/587 + +[Signatures of Correct Computation][pst] +Charalampos Papamanthou, Elaine Shi, Roberto Tamassia +TCC 2013 + +[Marlin: Preprocessing zkSNARKs with Universal and Updatable SRS][marlin] +Alessandro Chiesa, Yuncong Hu, Mary Maller, Pratyush Mishra, Noah Vesely, Nicholas Ward +EUROCRYPT 2020 + +## Comparison + +### Comparison of `MarlinKZG10` and `SonicKZG10` + + +#### High-level: +They handle degree bounds differently. + +MarlinPC uses shift powers only in G1 and requires two commitments to enforce degree bounds. + +SonicPC uses shift powers in G1 and G2 and requires only one commitment to enforce degree bounds. + +#### Setup: + +SonicPC additionally computes some G2 elements for shift powers: `(1/\beta)^i H`. This results in a longer verifying key, as shift powers in SonicPC are in G2, while shift powers in Marlin are in G1, and are shared with the "non-shift" powers. + +#### Commit: + +When there is no degree bound, both are the same. + +When there is a degree bound, MarlinPC is more expensive: it needs an additional commitment to commit to the shifted poynomial. + +#### Open: + +When there is no degree bound, both are the same. + +When there is a degree bound, MarlinPC is slightly more expensive: it requires more scalar field computations. + +#### Check: + +MarlinPC simply adjusts the commitment of the shifted polynomial, so the overhead is small. It checks a pairing equation with two pairing operations. + +SonicPC is more expensive, as it checks a pairing equation of three pairing operations. It can be reduced into two if there is no degree bound. diff --git a/src/ipa_pc/mod.rs b/src/ipa_pc/mod.rs index fb9cc385..072dcf47 100644 --- a/src/ipa_pc/mod.rs +++ b/src/ipa_pc/mod.rs @@ -1044,23 +1044,31 @@ mod tests { use ark_ff::PrimeField; use ark_poly::{univariate::DensePolynomial as DensePoly, UVPolynomial}; use ark_sponge::poseidon::PoseidonSponge; - use ark_std::rand::rngs::StdRng; use blake2::Blake2s; + use rand_chacha::ChaCha20Rng; type UniPoly = DensePoly; type Sponge = PoseidonSponge<::ScalarField>; type PC = InnerProductArgPC; type PC_JJB2S = PC; - fn rand_poly(degree: usize, _: Option, rng: &mut StdRng) -> DensePoly { + fn rand_poly( + degree: usize, + _: Option, + rng: &mut ChaCha20Rng, + ) -> DensePoly { DensePoly::rand(degree, rng) } - fn constant_poly(_: usize, _: Option, rng: &mut StdRng) -> DensePoly { + fn constant_poly( + _: usize, + _: Option, + rng: &mut ChaCha20Rng, + ) -> DensePoly { DensePoly::from_coefficients_slice(&[F::rand(rng)]) } - fn rand_point(_: Option, rng: &mut StdRng) -> F { + fn rand_point(_: Option, rng: &mut ChaCha20Rng) -> F { F::rand(rng) } diff --git a/src/kzg10/data_structures.rs b/src/kzg10/data_structures.rs index 4bb95430..d14cbc23 100644 --- a/src/kzg10/data_structures.rs +++ b/src/kzg10/data_structures.rs @@ -11,7 +11,12 @@ use ark_std::{ /// `UniversalParams` are the universal parameters for the KZG10 scheme. #[derive(Derivative)] -#[derivative(Clone(bound = ""), Debug(bound = ""))] +#[derivative( + Clone(bound = ""), + Debug(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] pub struct UniversalParams { /// Group elements of the form `{ \beta^i G }`, where `i` ranges from 0 to `degree`. pub powers_of_g: Vec, @@ -24,10 +29,10 @@ pub struct UniversalParams { /// Group elements of the form `{ \beta^i G2 }`, where `i` ranges from `0` to `-degree`. pub neg_powers_of_h: BTreeMap, /// The generator of G2, prepared for use in pairings. - #[derivative(Debug = "ignore")] + #[derivative(Debug = "ignore", PartialEq = "ignore")] pub prepared_h: E::G2Prepared, /// \beta times the above generator of G2, prepared for use in pairings. - #[derivative(Debug = "ignore")] + #[derivative(Debug = "ignore", PartialEq = "ignore")] pub prepared_beta_h: E::G2Prepared, } @@ -153,7 +158,8 @@ impl CanonicalDeserialize for UniversalParams { Default(bound = ""), Hash(bound = ""), Clone(bound = ""), - Debug(bound = "") + Debug(bound = ""), + PartialEq )] pub struct Powers<'a, E: PairingEngine> { /// Group elements of the form `β^i G`, for different values of `i`. @@ -169,9 +175,64 @@ impl Powers<'_, E> { } } +impl<'a, E: PairingEngine> CanonicalSerialize for Powers<'a, E> { + fn serialize(&self, mut writer: W) -> Result<(), SerializationError> { + self.powers_of_g.serialize(&mut writer)?; + self.powers_of_gamma_g.serialize(&mut writer) + } + + fn serialized_size(&self) -> usize { + self.powers_of_g.serialized_size() + self.powers_of_gamma_g.serialized_size() + } + + fn serialize_unchecked(&self, mut writer: W) -> Result<(), SerializationError> { + self.powers_of_g.serialize_unchecked(&mut writer)?; + self.powers_of_gamma_g.serialize_unchecked(&mut writer) + } + + fn serialize_uncompressed(&self, mut writer: W) -> Result<(), SerializationError> { + self.powers_of_g.serialize_uncompressed(&mut writer)?; + self.powers_of_gamma_g.serialize_uncompressed(&mut writer) + } +} + +impl<'a, E: PairingEngine> CanonicalDeserialize for Powers<'a, E> { + fn deserialize(mut reader: R) -> Result { + let powers_of_g = Vec::::deserialize(&mut reader)?; + let powers_of_gamma_g = Vec::::deserialize(&mut reader)?; + Ok(Self { + powers_of_g: Cow::Owned(powers_of_g), + powers_of_gamma_g: Cow::Owned(powers_of_gamma_g), + }) + } + + fn deserialize_unchecked(mut reader: R) -> Result { + let powers_of_g = Vec::::deserialize_unchecked(&mut reader)?; + let powers_of_gamma_g = Vec::::deserialize_unchecked(&mut reader)?; + Ok(Self { + powers_of_g: Cow::Owned(powers_of_g), + powers_of_gamma_g: Cow::Owned(powers_of_gamma_g), + }) + } + + fn deserialize_uncompressed(mut reader: R) -> Result { + let powers_of_g = Vec::::deserialize_uncompressed(&mut reader)?; + let powers_of_gamma_g = Vec::::deserialize_uncompressed(&mut reader)?; + Ok(Self { + powers_of_g: Cow::Owned(powers_of_g), + powers_of_gamma_g: Cow::Owned(powers_of_gamma_g), + }) + } +} /// `VerifierKey` is used to check evaluation proofs for a given commitment. #[derive(Derivative)] -#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))] +#[derivative( + Default(bound = ""), + Clone(bound = ""), + Debug(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] pub struct VerifierKey { /// The generator of G1. pub g: E::G1Affine, @@ -182,10 +243,10 @@ pub struct VerifierKey { /// \beta times the above generator of G2. pub beta_h: E::G2Affine, /// The generator of G2, prepared for use in pairings. - #[derivative(Debug = "ignore")] + #[derivative(Debug = "ignore", PartialEq = "ignore")] pub prepared_h: E::G2Prepared, /// \beta times the above generator of G2, prepared for use in pairings. - #[derivative(Debug = "ignore")] + #[derivative(Debug = "ignore", PartialEq = "ignore")] pub prepared_beta_h: E::G2Prepared, } diff --git a/src/lib.rs b/src/lib.rs index 0107c1e9..a6dc40bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -530,10 +530,10 @@ pub mod tests { use ark_sponge::poseidon::{PoseidonParameters, PoseidonSponge}; use ark_std::rand::{ distributions::{Distribution, Uniform}, - rngs::StdRng, - Rng, + Rng, SeedableRng, }; use ark_std::test_rng; + use rand_chacha::ChaCha20Rng; struct TestInfo, S: CryptographicSponge> { num_iters: usize, @@ -544,14 +544,14 @@ pub mod tests { enforce_degree_bounds: bool, max_num_queries: usize, num_equations: Option, - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, } pub fn bad_degree_bound_test( - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -566,7 +566,7 @@ pub mod tests { ]; for challenge_gen in challenge_generators { - let rng = &mut test_rng(); + let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap(); let max_degree = 100; let pp = PC::setup(max_degree, None, rng)?; for _ in 0..10 { @@ -674,7 +674,7 @@ pub mod tests { ]; for challenge_gen in challenge_gens { - let rng = &mut test_rng(); + let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap(); // If testing multivariate polynomials, make the max degree lower let max_degree = match num_vars { Some(_) => max_degree.unwrap_or(Uniform::from(2..=10).sample(rng)), @@ -819,7 +819,7 @@ pub mod tests { ]; for challenge_gen in challenge_gens { - let rng = &mut test_rng(); + let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap(); // If testing multivariate polynomials, make the max degree lower let max_degree = match num_vars { Some(_) => max_degree.unwrap_or(Uniform::from(2..=10).sample(rng)), @@ -979,8 +979,8 @@ pub mod tests { pub fn single_poly_test( num_vars: Option, - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1006,8 +1006,8 @@ pub mod tests { } pub fn linear_poly_degree_bound_test( - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1033,8 +1033,8 @@ pub mod tests { } pub fn single_poly_degree_bound_test( - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1060,8 +1060,8 @@ pub mod tests { } pub fn quadratic_poly_degree_bound_multiple_queries_test( - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1087,8 +1087,8 @@ pub mod tests { } pub fn single_poly_degree_bound_multiple_queries_test( - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1114,8 +1114,8 @@ pub mod tests { } pub fn two_polys_degree_bound_single_query_test( - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1142,8 +1142,8 @@ pub mod tests { pub fn full_end_to_end_test( num_vars: Option, - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1170,8 +1170,8 @@ pub mod tests { pub fn full_end_to_end_equation_test( num_vars: Option, - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1198,8 +1198,8 @@ pub mod tests { pub fn single_equation_test( num_vars: Option, - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1226,8 +1226,8 @@ pub mod tests { pub fn two_equation_test( num_vars: Option, - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where @@ -1253,8 +1253,8 @@ pub mod tests { } pub fn two_equation_degree_bound_test( - rand_poly: fn(usize, Option, &mut StdRng) -> P, - rand_point: fn(Option, &mut StdRng) -> P::Point, + rand_poly: fn(usize, Option, &mut ChaCha20Rng) -> P, + rand_point: fn(Option, &mut ChaCha20Rng) -> P::Point, sponge: fn() -> S, ) -> Result<(), PC::Error> where diff --git a/src/marlin/marlin_pc/mod.rs b/src/marlin/marlin_pc/mod.rs index d5b94895..6acfe03c 100644 --- a/src/marlin/marlin_pc/mod.rs +++ b/src/marlin/marlin_pc/mod.rs @@ -550,7 +550,7 @@ mod tests { use ark_ff::UniformRand; use ark_poly::{univariate::DensePolynomial as DensePoly, UVPolynomial}; use ark_sponge::poseidon::PoseidonSponge; - use ark_std::rand::rngs::StdRng; + use rand_chacha::ChaCha20Rng; type UniPoly_381 = DensePoly<::Fr>; type UniPoly_377 = DensePoly<::Fr>; @@ -566,7 +566,7 @@ mod tests { fn rand_poly( degree: usize, _: Option, - rng: &mut StdRng, + rng: &mut ChaCha20Rng, ) -> DensePoly { DensePoly::::rand(degree, rng) } @@ -574,12 +574,12 @@ mod tests { fn constant_poly( _: usize, _: Option, - rng: &mut StdRng, + rng: &mut ChaCha20Rng, ) -> DensePoly { DensePoly::::from_coefficients_slice(&[E::Fr::rand(rng)]) } - fn rand_point(_: Option, rng: &mut StdRng) -> E::Fr { + fn rand_point(_: Option, rng: &mut ChaCha20Rng) -> E::Fr { E::Fr::rand(rng) } diff --git a/src/marlin/marlin_pst13_pc/mod.rs b/src/marlin/marlin_pst13_pc/mod.rs index d418eb86..34631a8c 100644 --- a/src/marlin/marlin_pst13_pc/mod.rs +++ b/src/marlin/marlin_pst13_pc/mod.rs @@ -727,7 +727,7 @@ mod tests { MVPolynomial, }; use ark_sponge::poseidon::PoseidonSponge; - use ark_std::rand::rngs::StdRng; + use rand_chacha::ChaCha20Rng; type MVPoly_381 = SparsePoly<::Fr, SparseTerm>; type MVPoly_377 = SparsePoly<::Fr, SparseTerm>; @@ -743,12 +743,12 @@ mod tests { fn rand_poly( degree: usize, num_vars: Option, - rng: &mut StdRng, + rng: &mut ChaCha20Rng, ) -> SparsePoly { SparsePoly::::rand(degree, num_vars.unwrap(), rng) } - fn rand_point(num_vars: Option, rng: &mut StdRng) -> Vec { + fn rand_point(num_vars: Option, rng: &mut ChaCha20Rng) -> Vec { let num_vars = num_vars.unwrap(); let mut point = Vec::with_capacity(num_vars); for _ in 0..num_vars { diff --git a/src/sonic_pc/mod.rs b/src/sonic_pc/mod.rs index e02d635f..1ddd1f67 100644 --- a/src/sonic_pc/mod.rs +++ b/src/sonic_pc/mod.rs @@ -685,7 +685,7 @@ mod tests { use ark_ff::UniformRand; use ark_poly::{univariate::DensePolynomial as DensePoly, UVPolynomial}; use ark_sponge::poseidon::PoseidonSponge; - use ark_std::rand::rngs::StdRng; + use rand_chacha::ChaCha20Rng; type UniPoly_381 = DensePoly<::Fr>; type UniPoly_377 = DensePoly<::Fr>; @@ -699,12 +699,12 @@ mod tests { fn rand_poly( degree: usize, _: Option, - rng: &mut StdRng, + rng: &mut ChaCha20Rng, ) -> DensePoly { DensePoly::::rand(degree, rng) } - fn rand_point(_: Option, rng: &mut StdRng) -> E::Fr { + fn rand_point(_: Option, rng: &mut ChaCha20Rng) -> E::Fr { E::Fr::rand(rng) } From a688fe93082abdf3f651a8af55ce1e4b8da38410 Mon Sep 17 00:00:00 2001 From: Victor Lopes Date: Mon, 25 Apr 2022 17:23:51 +0200 Subject: [PATCH 56/56] Update `PC::check_combinations` to optional rng (#97) Closes #96 --- src/ipa_pc/mod.rs | 9 +++++---- src/kzg10/mod.rs | 10 ++++++++-- src/lib.rs | 16 ++++++++-------- src/marlin/marlin_pc/mod.rs | 8 ++++---- src/marlin/marlin_pst13_pc/mod.rs | 9 +++++---- src/marlin/mod.rs | 2 +- src/sonic_pc/mod.rs | 9 +++++---- 7 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/ipa_pc/mod.rs b/src/ipa_pc/mod.rs index 072dcf47..2d27d83f 100644 --- a/src/ipa_pc/mod.rs +++ b/src/ipa_pc/mod.rs @@ -701,14 +701,14 @@ where }) } - fn check<'a>( + fn check<'a, R: RngCore>( vk: &Self::VerifierKey, commitments: impl IntoIterator>, point: &'a P::Point, values: impl IntoIterator, proof: &Self::Proof, opening_challenges: &mut ChallengeGenerator, - _rng: Option<&mut dyn RngCore>, + _rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, @@ -759,11 +759,12 @@ where values: &Evaluations, proof: &Self::BatchProof, opening_challenges: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, { + let rng = &mut crate::optional_rng::OptionalRng(rng); let commitments: BTreeMap<_, _> = commitments.into_iter().map(|c| (c.label(), c)).collect(); let mut query_to_labels_map = BTreeMap::new(); @@ -956,7 +957,7 @@ where eqn_evaluations: &Evaluations, proof: &BatchLCProof, opening_challenges: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, diff --git a/src/kzg10/mod.rs b/src/kzg10/mod.rs index e4f1c49c..608fcf69 100644 --- a/src/kzg10/mod.rs +++ b/src/kzg10/mod.rs @@ -321,11 +321,12 @@ where points: &[E::Fr], values: &[E::Fr], proofs: &[Proof], - rng: &mut R, + rng: Option<&mut R>, ) -> Result { let check_time = start_timer!(|| format!("Checking {} evaluation proofs", commitments.len())); + let rng = &mut crate::optional_rng::OptionalRng(rng); let mut total_c = ::zero(); let mut total_w = ::zero(); @@ -616,7 +617,12 @@ mod tests { proofs.push(proof); } assert!(KZG10::::batch_check( - &vk, &comms, &points, &values, &proofs, rng + &vk, + &comms, + &points, + &values, + &proofs, + Some(rng) )?); } Ok(()) diff --git a/src/lib.rs b/src/lib.rs index a6dc40bd..1e87404d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -222,14 +222,14 @@ pub trait PolynomialCommitment, S: Cryptographic Self::Commitment: 'a; /// check but with individual challenges - fn check<'a>( + fn check<'a, R: RngCore>( vk: &Self::VerifierKey, commitments: impl IntoIterator>, point: &'a P::Point, values: impl IntoIterator, proof: &Self::Proof, challenge_generator: &mut ChallengeGenerator, - rng: Option<&mut dyn RngCore>, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a; @@ -242,7 +242,7 @@ pub trait PolynomialCommitment, S: Cryptographic evaluations: &Evaluations, proof: &Self::BatchProof, challenge_generator: &mut ChallengeGenerator, - rng: &mut R, + mut rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, @@ -289,7 +289,7 @@ pub trait PolynomialCommitment, S: Cryptographic values, &proof, challenge_generator, - Some(rng), + rng.as_mut(), )?; end_timer!(proof_time); } @@ -341,7 +341,7 @@ pub trait PolynomialCommitment, S: Cryptographic eqn_evaluations: &Evaluations, proof: &BatchLCProof, challenge_generator: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, @@ -638,7 +638,7 @@ pub mod tests { &values, &proof, &mut (challenge_gen.clone()), - rng, + Some(rng), )?; assert!(result, "proof was incorrect, Query set: {:#?}", query_set); } @@ -774,7 +774,7 @@ pub mod tests { &values, &proof, &mut (challenge_gen.clone()), - rng, + Some(rng), )?; if !result { println!( @@ -955,7 +955,7 @@ pub mod tests { &values, &proof, &mut (challenge_gen.clone()), - rng, + Some(rng), )?; if !result { println!( diff --git a/src/marlin/marlin_pc/mod.rs b/src/marlin/marlin_pc/mod.rs index 6acfe03c..37f568e7 100644 --- a/src/marlin/marlin_pc/mod.rs +++ b/src/marlin/marlin_pc/mod.rs @@ -349,14 +349,14 @@ where /// Verifies that `value` is the evaluation at `x` of the polynomial /// committed inside `comm`. - fn check<'a>( + fn check<'a, R: RngCore>( vk: &Self::VerifierKey, commitments: impl IntoIterator>, point: &'a P::Point, values: impl IntoIterator, proof: &Self::Proof, opening_challenges: &mut ChallengeGenerator, - _rng: Option<&mut dyn RngCore>, + _rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, @@ -382,7 +382,7 @@ where values: &Evaluations, proof: &Self::BatchProof, opening_challenges: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, @@ -446,7 +446,7 @@ where evaluations: &Evaluations, proof: &BatchLCProof, opening_challenges: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, diff --git a/src/marlin/marlin_pst13_pc/mod.rs b/src/marlin/marlin_pst13_pc/mod.rs index 34631a8c..10773621 100644 --- a/src/marlin/marlin_pst13_pc/mod.rs +++ b/src/marlin/marlin_pst13_pc/mod.rs @@ -540,14 +540,14 @@ where /// Verifies that `value` is the evaluation at `x` of the polynomial /// committed inside `comm`. - fn check<'a>( + fn check<'a, R: RngCore>( vk: &Self::VerifierKey, commitments: impl IntoIterator>, point: &'a P::Point, values: impl IntoIterator, proof: &Self::Proof, opening_challenges: &mut ChallengeGenerator, - _rng: Option<&mut dyn RngCore>, + _rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, @@ -590,11 +590,12 @@ where values: &Evaluations, proof: &Self::BatchProof, opening_challenges: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, { + let rng = &mut crate::optional_rng::OptionalRng(rng); let (combined_comms, combined_queries, combined_evals) = Marlin::::combine_and_normalize( commitments, @@ -696,7 +697,7 @@ where eqn_evaluations: &Evaluations, proof: &BatchLCProof, opening_challenges: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, diff --git a/src/marlin/mod.rs b/src/marlin/mod.rs index 05ba0570..381f5757 100644 --- a/src/marlin/mod.rs +++ b/src/marlin/mod.rs @@ -328,7 +328,7 @@ where evaluations: &Evaluations, proof: &BatchLCProof, opening_challenges: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where R: RngCore, diff --git a/src/sonic_pc/mod.rs b/src/sonic_pc/mod.rs index 1ddd1f67..3dd4fdd8 100644 --- a/src/sonic_pc/mod.rs +++ b/src/sonic_pc/mod.rs @@ -385,14 +385,14 @@ where Ok(proof) } - fn check<'a>( + fn check<'a, R: RngCore>( vk: &Self::VerifierKey, commitments: impl IntoIterator>, point: &'a P::Point, values: impl IntoIterator, proof: &Self::Proof, opening_challenges: &mut ChallengeGenerator, - _rng: Option<&mut dyn RngCore>, + _rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, @@ -432,11 +432,12 @@ where values: &Evaluations, proof: &Self::BatchProof, opening_challenges: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a, { + let rng = &mut crate::optional_rng::OptionalRng(rng); let commitments: BTreeMap<_, _> = commitments.into_iter().map(|c| (c.label(), c)).collect(); let mut query_to_labels_map = BTreeMap::new(); @@ -600,7 +601,7 @@ where eqn_evaluations: &Evaluations, proof: &BatchLCProof, opening_challenges: &mut ChallengeGenerator, - rng: &mut R, + rng: Option<&mut R>, ) -> Result where Self::Commitment: 'a,