diff --git a/w3f-ring-proof/src/piop/mod.rs b/w3f-ring-proof/src/piop/mod.rs index 0cd73c3..c791d6a 100644 --- a/w3f-ring-proof/src/piop/mod.rs +++ b/w3f-ring-proof/src/piop/mod.rs @@ -1,5 +1,4 @@ use ark_ec::pairing::Pairing; -use ark_ec::twisted_edwards::{Affine, TECurveConfig}; use ark_ec::AffineRepr; use ark_ff::PrimeField; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; @@ -97,7 +96,7 @@ impl> FixedColumnsCommitted { } impl FixedColumnsCommitted> { - pub fn from_ring>( + pub fn from_ring>( ring: &Ring, ) -> Self { let cx = KzgCommitment(ring.cx); @@ -159,7 +158,7 @@ impl> Clone for VerifierKey { } impl VerifierKey> { - pub fn from_ring_and_kzg_vk>( + pub fn from_ring_and_kzg_vk>( ring: &Ring, kzg_vk: RawKzgVerifierKey, ) -> Self { @@ -181,11 +180,11 @@ impl VerifierKey> { } } -pub fn index, Curve: TECurveConfig>( +pub fn index, G: AffineRepr>( pcs_params: &CS::Params, - piop_params: &PiopParams>, - keys: &[Affine], -) -> (ProverKey>, VerifierKey) { + piop_params: &PiopParams, + keys: &[G], +) -> (ProverKey, VerifierKey) { let pcs_ck = pcs_params.ck(); let pcs_raw_vk = pcs_params.raw_vk(); let fixed_columns = piop_params.fixed_columns(&keys); diff --git a/w3f-ring-proof/src/piop/prover.rs b/w3f-ring-proof/src/piop/prover.rs index ddec2ba..ca06cea 100644 --- a/w3f-ring-proof/src/piop/prover.rs +++ b/w3f-ring-proof/src/piop/prover.rs @@ -1,4 +1,6 @@ -use ark_ec::twisted_edwards::{Affine, TECurveConfig}; +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +use ark_ec::twisted_edwards::{Affine as TeAffine, TECurveConfig}; +use ark_ec::AffineRepr; use ark_ff::PrimeField; use ark_poly::univariate::DensePolynomial; use ark_poly::Evaluations; @@ -22,10 +24,10 @@ use w3f_plonk_common::FieldColumn; // The 'table': columns representing the execution trace of the computation // and the constraints -- polynomials that vanish on every 2 consecutive rows. -pub struct PiopProver> { +pub struct PiopProver> { domain: Domain, /// Advice (public input) columns - points: AffineColumn>, + points: AffineColumn, ring_selector: FieldColumn, // Private input column. bits: BitColumn, @@ -33,17 +35,17 @@ pub struct PiopProver> { booleanity: Booleanity, inner_prod: InnerProd, inner_prod_acc: FixedCells, - cond_add: CondAdd>, + cond_add: CondAdd, cond_add_acc_x: FixedCells, cond_add_acc_y: FixedCells, } -impl> PiopProver { +impl> PiopProver { pub fn build( - params: &PiopParams>, - fixed_columns: FixedColumns>, + params: &PiopParams, + fixed_columns: FixedColumns, prover_index_in_keys: usize, - secret: Curve::ScalarField, + secret: G::ScalarField, ) -> Self { let domain = params.domain.clone(); let FixedColumns { @@ -73,9 +75,9 @@ impl> PiopProver { // TODO: move to params? fn bits_column( - params: &PiopParams>, + params: &PiopParams, index_in_keys: usize, - secret: Curve::ScalarField, + secret: G::ScalarField, ) -> BitColumn { let mut keyset_part = vec![false; params.keyset_part_size]; keyset_part[index_in_keys] = true; @@ -84,29 +86,18 @@ impl> PiopProver { assert_eq!(bits.len(), params.domain.capacity - 1); BitColumn::init(bits, ¶ms.domain) } -} - -impl ProverPiop for PiopProver -where - F: PrimeField, - C: Commitment, - Curve: TECurveConfig, -{ - type Commitments = RingCommitments; - type Evaluations = RingEvaluations; - type Instance = Affine; - fn committed_columns) -> C>( + fn _committed_columns, Fun: Fn(&DensePolynomial) -> C>( &self, commit: Fun, - ) -> Self::Commitments { + ) -> RingCommitments { let bits = commit(self.bits.as_poly()); let cond_add_acc = [ commit(self.cond_add.acc.xs.as_poly()), commit(self.cond_add.acc.ys.as_poly()), ]; let inn_prod_acc = commit(self.inner_prod.acc.as_poly()); - Self::Commitments { + RingCommitments { bits, cond_add_acc, inn_prod_acc, @@ -116,7 +107,7 @@ where // Should return polynomials in the consistent with // Self::Evaluations::to_vec() and Self::Commitments::to_vec(). - fn columns(&self) -> Vec> { + fn _columns(&self) -> Vec> { vec![ self.points.xs.as_poly().clone(), self.points.ys.as_poly().clone(), @@ -128,7 +119,7 @@ where ] } - fn columns_evaluated(&self, zeta: &F) -> Self::Evaluations { + fn _columns_evaluated(&self, zeta: &F) -> RingEvaluations { let points = [self.points.xs.evaluate(zeta), self.points.ys.evaluate(zeta)]; let ring_selector = self.ring_selector.evaluate(zeta); let bits = self.bits.evaluate(zeta); @@ -137,7 +128,7 @@ where self.cond_add.acc.xs.evaluate(zeta), self.cond_add.acc.ys.evaluate(zeta), ]; - Self::Evaluations { + RingEvaluations { points, ring_selector, bits, @@ -145,6 +136,94 @@ where cond_add_acc, } } +} + +impl ProverPiop for PiopProver> +where + F: PrimeField, + C: Commitment, + Curve: TECurveConfig, +{ + type Commitments = RingCommitments; + type Evaluations = RingEvaluations; + type Instance = TeAffine; + + fn committed_columns) -> C>( + &self, + commit: Fun, + ) -> Self::Commitments { + self._committed_columns(commit) + } + + // Should return polynomials in the consistent with + // Self::Evaluations::to_vec() and Self::Commitments::to_vec(). + fn columns(&self) -> Vec> { + self._columns() + } + + fn columns_evaluated(&self, zeta: &F) -> Self::Evaluations { + self._columns_evaluated(zeta) + } + + fn constraints(&self) -> Vec> { + vec![ + self.inner_prod.constraints(), + self.cond_add.constraints(), + self.booleanity.constraints(), + self.cond_add_acc_x.constraints(), + self.cond_add_acc_y.constraints(), + self.inner_prod_acc.constraints(), + ] + .concat() + } + + fn constraints_lin(&self, zeta: &F) -> Vec> { + vec![ + self.inner_prod.constraints_linearized(zeta), + self.cond_add.constraints_linearized(zeta), + self.booleanity.constraints_linearized(zeta), + self.cond_add_acc_x.constraints_linearized(zeta), + self.cond_add_acc_y.constraints_linearized(zeta), + self.inner_prod_acc.constraints_linearized(zeta), + ] + .concat() + } + + fn domain(&self) -> &Domain { + &self.domain + } + + fn result(&self) -> Self::Instance { + self.cond_add.result() + } +} + +impl ProverPiop for PiopProver> +where + F: PrimeField, + C: Commitment, + Curve: SWCurveConfig, +{ + type Commitments = RingCommitments; + type Evaluations = RingEvaluations; + type Instance = SwAffine; + + fn committed_columns) -> C>( + &self, + commit: Fun, + ) -> Self::Commitments { + self._committed_columns(commit) + } + + // Should return polynomials in the consistent with + // Self::Evaluations::to_vec() and Self::Commitments::to_vec(). + fn columns(&self) -> Vec> { + self._columns() + } + + fn columns_evaluated(&self, zeta: &F) -> Self::Evaluations { + self._columns_evaluated(zeta) + } fn constraints(&self) -> Vec> { vec![ diff --git a/w3f-ring-proof/src/piop/verifier.rs b/w3f-ring-proof/src/piop/verifier.rs index 8eb663f..eeb53b0 100644 --- a/w3f-ring-proof/src/piop/verifier.rs +++ b/w3f-ring-proof/src/piop/verifier.rs @@ -1,4 +1,5 @@ -use ark_ec::twisted_edwards::{Affine, TECurveConfig}; +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +use ark_ec::twisted_edwards::{Affine as TeAffine, TECurveConfig}; use ark_ec::AffineRepr; use ark_ff::PrimeField; use ark_std::marker::PhantomData; @@ -102,7 +103,55 @@ impl, P: AffineRepr> PiopVerifier } impl, Jubjub: TECurveConfig> VerifierPiop - for PiopVerifier> + for PiopVerifier> +{ + const N_CONSTRAINTS: usize = 7; + const N_COLUMNS: usize = 7; + + fn precommitted_columns(&self) -> Vec { + self.fixed_columns_committed.as_vec() + } + + fn evaluate_constraints_main(&self) -> Vec { + vec![ + self.inner_prod.evaluate_constraints_main(), + self.cond_add.evaluate_constraints_main(), + self.booleanity.evaluate_constraints_main(), + self.cond_add_acc_x.evaluate_constraints_main(), + self.cond_add_acc_y.evaluate_constraints_main(), + self.inner_prod_acc.evaluate_constraints_main(), + ] + .concat() + } + + fn lin_poly_commitment(&self, agg_coeffs: &[F]) -> (Vec, Vec) { + assert_eq!(agg_coeffs.len(), Self::N_CONSTRAINTS); + + let inner_prod_acc = self.witness_columns_committed.inn_prod_acc.clone(); + let inner_prod_coeff = agg_coeffs[0] * self.inner_prod.not_last; + + let cond_add_acc_x = self.witness_columns_committed.cond_add_acc[0].clone(); + let cond_add_acc_y = self.witness_columns_committed.cond_add_acc[1].clone(); + let (c_acc_x, c_acc_y) = self.cond_add.acc_coeffs_1(); + let mut cond_add_x_coeff = agg_coeffs[1] * c_acc_x; + let mut cond_add_y_coeff = agg_coeffs[1] * c_acc_y; + let (c_acc_x, c_acc_y) = self.cond_add.acc_coeffs_2(); + cond_add_x_coeff += agg_coeffs[2] * c_acc_x; + cond_add_y_coeff += agg_coeffs[2] * c_acc_y; + + ( + vec![inner_prod_coeff, cond_add_x_coeff, cond_add_y_coeff], + vec![inner_prod_acc.clone(), cond_add_acc_x, cond_add_acc_y], + ) + } + + fn domain_evaluated(&self) -> &EvaluatedDomain { + &self.domain_evals + } +} + +impl, Jubjub: SWCurveConfig> VerifierPiop + for PiopVerifier> { const N_CONSTRAINTS: usize = 7; const N_COLUMNS: usize = 7; diff --git a/w3f-ring-proof/src/ring.rs b/w3f-ring-proof/src/ring.rs index 527a6c0..a69843f 100644 --- a/w3f-ring-proof/src/ring.rs +++ b/w3f-ring-proof/src/ring.rs @@ -1,5 +1,4 @@ use ark_ec::pairing::Pairing; -use ark_ec::twisted_edwards::{Affine, TECurveConfig}; use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM}; use ark_ff::PrimeField; use ark_poly::EvaluationDomain; @@ -33,11 +32,7 @@ const IDLE_ROWS: usize = ZK_ROWS + 1; /// Thus, the vector of points we commit to coordinatewise is /// `pk1, ..., pkn, padding, ..., padding, H, 2H, ..., 2^(s-1)H, 0, 0, 0, 0` #[derive(Clone, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)] -pub struct Ring< - F: PrimeField, - KzgCurve: Pairing, - VrfCurveConfig: TECurveConfig, -> { +pub struct Ring, G: AffineRepr> { /// KZG commitment to the x coordinates of the described vector. pub cx: KzgCurve::G1Affine, /// KZG commitment to the y coordinates of the described vector. @@ -49,14 +44,11 @@ pub struct Ring< /// Number of keys "stored" in this commitment. pub curr_keys: usize, // Padding point. - pub padding: Affine, + pub padding: G, } -impl< - F: PrimeField, - KzgCurve: Pairing, - VrfCurveConfig: TECurveConfig, - > fmt::Debug for Ring +impl, G: AffineRepr> fmt::Debug + for Ring { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( @@ -67,11 +59,8 @@ impl< } } -impl< - F: PrimeField, - KzgCurve: Pairing, - VrfCurveConfig: TECurveConfig, - > Ring +impl, G: AffineRepr> + Ring { /// Builds the commitment to the vector /// `padding, ..., padding, H, 2H, ..., 2^(s-1)H, 0, 0, 0, 0`. @@ -85,7 +74,7 @@ impl< /// - `srs`: Should return `srs[range]` for `range = (piop_params.keyset_part_size..domain_size)` /// - `g`: Generator used in the SRS pub fn empty( - piop_params: &PiopParams>, + piop_params: &PiopParams, srs: impl Fn(Range) -> Result, ()>, g: KzgCurve::G1, ) -> Self { @@ -130,7 +119,7 @@ impl< /// - `srs`: Should return `srs[range]` for `range = (self.curr_keys..self.curr_keys + keys.len())` pub fn append( &mut self, - keys: &[Affine], + keys: &[G], srs: impl Fn(Range) -> Result, ()>, ) { let new_size = self.curr_keys + keys.len(); @@ -162,8 +151,8 @@ impl< /// - `piop_params`: SNARK parameters. /// - `srs`: full-size Lagrangian SRS. pub fn with_keys( - piop_params: &PiopParams>, - keys: &[Affine], + piop_params: &PiopParams, + keys: &[G], srs: &RingBuilderKey, ) -> Self { let (padding_x, padding_y) = piop_params.padding.xy().unwrap(); // panics on inf, never happens @@ -222,10 +211,9 @@ impl< cx: KzgCurve::G1Affine, cy: KzgCurve::G1Affine, selector: KzgCurve::G1Affine, - padding: Affine, + padding: G, ) -> Self { - let max_keys = - domain_size - (VrfCurveConfig::ScalarField::MODULUS_BIT_SIZE as usize + IDLE_ROWS); + let max_keys = domain_size - (G::ScalarField::MODULUS_BIT_SIZE as usize + IDLE_ROWS); Self { cx, cy, @@ -257,7 +245,7 @@ impl> RingBuilderKey; + type TestRing = Ring; #[test] fn test_ring_mgmt() { diff --git a/w3f-ring-proof/src/ring_prover.rs b/w3f-ring-proof/src/ring_prover.rs index 7aabea6..2a3647e 100644 --- a/w3f-ring-proof/src/ring_prover.rs +++ b/w3f-ring-proof/src/ring_prover.rs @@ -70,7 +70,7 @@ where r: Curve::ScalarField, ) -> (Affine, RingProof) { let piop = PiopProver::build(&self.piop_params, self.fixed_columns.clone(), k, r); - let blinded_pk = as ProverPiop>::result(&piop); + let blinded_pk = > as ProverPiop>::result(&piop); let proof = self.plonk_prover.prove(piop); (blinded_pk, proof) }