From e573c19246a8bc62ced5741c45728a5e2eeed90b Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 21 May 2026 17:31:54 +0300 Subject: [PATCH 01/42] circuit --- pasta-tree/src/auth_path/node.rs | 3 +- pasta-tree/src/auth_path/path.rs | 7 +- pasta-tree/src/circuit/mod.rs | 56 +++++++++ pasta-tree/src/circuit/params.rs | 82 +++++++++++++ pasta-tree/src/circuit/prover.rs | 187 +++++++++++++++++++++++++++++ pasta-tree/src/circuit/verifier.rs | 124 +++++++++++++++++++ pasta-tree/src/level/mod.rs | 1 - pasta-tree/src/level/prover.rs | 6 +- pasta-tree/src/level/verifier.rs | 2 - pasta-tree/src/lib.rs | 114 +++++------------- pasta-tree/src/prover.rs | 38 +++--- pasta-tree/src/verifier.rs | 91 ++++++-------- 12 files changed, 542 insertions(+), 169 deletions(-) create mode 100644 pasta-tree/src/circuit/mod.rs create mode 100644 pasta-tree/src/circuit/params.rs create mode 100644 pasta-tree/src/circuit/prover.rs create mode 100644 pasta-tree/src/circuit/verifier.rs diff --git a/pasta-tree/src/auth_path/node.rs b/pasta-tree/src/auth_path/node.rs index 27c13fb..96ef397 100644 --- a/pasta-tree/src/auth_path/node.rs +++ b/pasta-tree/src/auth_path/node.rs @@ -71,11 +71,12 @@ impl LevelWitness { where G::BaseField: PrimeField, { - params.commit_nodes(&self.siblings, bf) + params.commit_x_coords(self.x_coords(), bf).map(|c| c.0) } } /// NB! It is not "blinded", meaning that the blinding factor hasn't been applied. +#[derive(Clone)] pub struct LevelWitnessWithBlinding { pub(crate) level_witness: LevelWitness, /// the verifier gets `Ci' = siblings[i] + bf.H` diff --git a/pasta-tree/src/auth_path/path.rs b/pasta-tree/src/auth_path/path.rs index d23d388..dee4e57 100644 --- a/pasta-tree/src/auth_path/path.rs +++ b/pasta-tree/src/auth_path/path.rs @@ -3,6 +3,7 @@ use crate::auth_path::node::LevelWitness; use crate::{CycleParams, CycleSide}; use ark_ec::CurveGroup; use ark_ff::PrimeField; +use ark_ff::UniformRand; use ark_std::rand::Rng; /// A non-hiding authentication path from a leaf to the root, split between the curves of the cycle. @@ -32,14 +33,14 @@ where let mut c0_path_iter = self.c0_path.iter(); let mut c0_nodes = c0_path_iter.next().unwrap(); // shouldn't be empty - let mut c0_bf = C0::ScalarField::rand(rng); + let mut c0_bf = C0::ScalarField::from(u128::rand(rng)); for c1_nodes in self.c1_path.iter() { - let c1_bf = C1::ScalarField::rand(rng); + let c1_bf = C1::ScalarField::from(u128::rand(rng)); path_0.push(c0_nodes.with_blinding(c0_bf, c1_bf)); match c0_path_iter.next() { Some(c0_nodes_) => { c0_nodes = c0_nodes_; - c0_bf = C0::ScalarField::rand(rng); + c0_bf = C0::ScalarField::from(u128::rand(rng)); path_1.push(c1_nodes.with_blinding(c1_bf, c0_bf)); } None => { diff --git a/pasta-tree/src/circuit/mod.rs b/pasta-tree/src/circuit/mod.rs new file mode 100644 index 0000000..7e58165 --- /dev/null +++ b/pasta-tree/src/circuit/mod.rs @@ -0,0 +1,56 @@ +use ark_ff::PrimeField; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::marker::PhantomData; +use ark_std::{vec, vec::Vec}; +use w3f_pcs::pcs::Commitment; +use w3f_plonk_common::{ColumnsCommited, ColumnsEvaluated}; + +pub mod params; +pub mod prover; +pub mod verifier; + +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] +pub struct ProofComms> { + pub(crate) node_selector: C, + pub(crate) bf_bits: C, + pub(crate) node_x_coord_acc: C, + pub(crate) blinded_node_acc: [C; 2], + pub(crate) phantom: PhantomData, +} + +impl> ColumnsCommited for ProofComms { + fn to_vec(self) -> Vec { + vec![ + self.node_selector, + self.bf_bits, + self.node_x_coord_acc, + self.blinded_node_acc[0].clone(), + self.blinded_node_acc[1].clone(), + ] + } +} + +#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] +pub struct ProofEvals { + pub(crate) x_coords: F, + pub(crate) h_powers: [F; 2], + pub(crate) node_selector: F, + pub(crate) bf_bits: F, + pub(crate) node_x_coord_acc: F, + pub(crate) blinded_node_acc: [F; 2], +} + +impl ColumnsEvaluated for ProofEvals { + fn to_vec(self) -> Vec { + vec![ + self.x_coords, + self.h_powers[0], + self.h_powers[1], + self.node_selector, + self.bf_bits, + self.node_x_coord_acc, + self.blinded_node_acc[0], + self.blinded_node_acc[1], + ] + } +} diff --git a/pasta-tree/src/circuit/params.rs b/pasta-tree/src/circuit/params.rs new file mode 100644 index 0000000..2dd03c5 --- /dev/null +++ b/pasta-tree/src/circuit/params.rs @@ -0,0 +1,82 @@ +use ark_ec::{AffineRepr, CurveGroup}; +use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; +use ark_std::{vec, vec::Vec}; + +use w3f_plonk_common::FieldColumn; +use w3f_plonk_common::domain::Domain; +use w3f_plonk_common::gadgets::booleanity::BitColumn; +use w3f_plonk_common::gadgets::ec::AffineColumn; + +/// Plonk Interactive Oracle Proofs (PIOP) parameters. +#[derive(Clone)] +pub struct PiopParams> { + /// Domain over which the piop is represented. + pub domain: Domain, + /// Number of bits used to represent a scalar. + pub scalar_bitlen: usize, + /// Blinding base point. + pub h: G, +} + +impl> PiopParams { + pub fn setup(domain: Domain, h: G) -> Self { + let scalar_bitlen = G::ScalarField::MODULUS_BIT_SIZE as usize; + Self { + domain, + scalar_bitlen, + h, + } + } + + pub fn children_capacity(&self) -> usize { + self.domain.capacity - 1 + } + + pub fn x_coords_column(&self, x_coords: Vec) -> FieldColumn { + let c = self.children_capacity(); + assert!(x_coords.len() <= c); + let mut x_coords = x_coords; + x_coords.resize(c, G::BaseField::zero()); // the last `(zk_rows + 1)` cells will be padded by the iFFT + self.domain.public_column(x_coords) + } + + pub fn h_powers_column(&self) -> AffineColumn { + let mut h_powers = self.power_of_2_multiples_of_h(); + h_powers.truncate(self.children_capacity()); + AffineColumn::public_column(h_powers, &self.domain) + } + + pub fn node_selector(&self, node_index: usize) -> BitColumn { + let c = self.children_capacity(); + let mut node_selector = vec![false; c]; + assert!(node_index < c); // allows to select a padding node + node_selector[node_index] = true; + BitColumn::init(node_selector, &self.domain) + } + + pub fn bf_bits_column(&self, bf: G::ScalarField) -> BitColumn { + let mut bf_bits = self.scalar_part(bf); + bf_bits.truncate(self.children_capacity()); + BitColumn::init(bf_bits, &self.domain) + } + + pub fn power_of_2_multiples_of_h(&self) -> Vec { + let mut h = self.h.into_group(); + let mut multiples = Vec::with_capacity(self.scalar_bitlen); + multiples.push(h); + for _ in 1..self.scalar_bitlen { + h.double_in_place(); + multiples.push(h); + } + CurveGroup::normalize_batch(&multiples) + } + + pub fn scalar_part(&self, e: G::ScalarField) -> Vec { + let bits_with_trailing_zeroes = e.into_bigint().to_bits_le(); + let significant_bits = &bits_with_trailing_zeroes[..self.scalar_bitlen]; + significant_bits.to_vec() + } +} + +#[cfg(test)] +mod tests {} diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit/prover.rs new file mode 100644 index 0000000..3404e05 --- /dev/null +++ b/pasta-tree/src/circuit/prover.rs @@ -0,0 +1,187 @@ +use crate::PiopParams; +use crate::auth_path::node::LevelWitnessWithBlinding; +use crate::circuit::{ProofComms, ProofEvals}; +use ark_ec::AffineRepr; +use ark_ec::CurveGroup; +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +use ark_ff::PrimeField; +use ark_poly::Evaluations; +use ark_poly::univariate::DensePolynomial; +use ark_std::marker::PhantomData; +use ark_std::{vec, vec::Vec}; +use w3f_pcs::pcs::Commitment; +use w3f_plonk_common::Column; +use w3f_plonk_common::FieldColumn; +use w3f_plonk_common::domain::Domain; +use w3f_plonk_common::gadgets::ProverGadget; +use w3f_plonk_common::gadgets::booleanity::{BitColumn, Booleanity}; +use w3f_plonk_common::gadgets::ec::AffineColumn; +use w3f_plonk_common::gadgets::ec::CondAdd; +use w3f_plonk_common::gadgets::inner_prod::InnerProd; +use w3f_plonk_common::piop::ProverPiop; + +pub struct PiopProver> { + domain: Domain, + // `x` coordinates of all the children of a node. Public input. + x_coords: FieldColumn, + // `H, 2H, 4H,...,2^sH` Fixed column. + h_powers: AffineColumn, + // `node_x = self.x_coords[self.node_idx]` Private input. + node_selector: BitColumn, + // Bits of the chosen blinding factor. Private input. + bf_bits: BitColumn, + node_x_coord: InnerProd, + blinded_node: CondAdd, // blinded_node.acc[0] = (x_i, y_i) = Ci, blinded_node.acc[capacity] = Ci + bf.H = Ci' + node_selector_bool: Booleanity, + bf_bits_bool: Booleanity, +} + +impl> PiopProver { + pub fn build(params: &PiopParams, level: LevelWitnessWithBlinding) -> Self { + let domain = params.domain.clone(); + let x_coords = params.x_coords_column(level.level_witness.x_coords()); + let h_powers = params.h_powers_column(); + let node_selector = params.node_selector(level.level_witness.path_node_idx); + let bf_bits = params.bf_bits_column(level.bf); + + let node = level.level_witness.path_node(); + + let node_x_coord = InnerProd::init(x_coords.clone(), node_selector.col.clone(), &domain); + let witnessed_x = node.x().unwrap(); + let computed_x = node_x_coord.acc.payload()[domain.capacity - 1]; + assert_eq!(computed_x, witnessed_x); + // here we witness yi + let blinded_node = CondAdd::init(bf_bits.clone(), h_powers.clone(), node, &domain); + assert_eq!( + blinded_node.seed_plus_sum(), + (node + params.h * level.bf).into_affine() + ); + let node_selector_bool = Booleanity::init(node_selector.clone()); + let bf_bits_bool = Booleanity::init(bf_bits.clone()); + // let cond_add_acc_x = FixedCells::init(blinded_node.acc.xs.clone(), &domain); + // let cond_add_acc_y = FixedCells::init(blinded_node.acc.ys.clone(), &domain); + // let inner_prod_acc = FixedCells::init(node_x_coord.acc.clone(), &domain); + Self { + domain, + x_coords, + h_powers, + node_selector, + bf_bits, + node_x_coord, + blinded_node, + node_selector_bool, + bf_bits_bool, + } + } + + fn _committed_columns, Fun: Fn(&DensePolynomial) -> C>( + &self, + commit: Fun, + ) -> ProofComms { + let node_selector = commit(self.node_selector.as_poly()); + let bf_bits = commit(self.bf_bits.as_poly()); + let node_x_coord_acc = commit(self.node_x_coord.acc.as_poly()); + let blinded_node_acc = [ + commit(self.blinded_node.acc.xs.as_poly()), + commit(self.blinded_node.acc.ys.as_poly()), + ]; + ProofComms { + node_selector, + bf_bits, + node_x_coord_acc, + blinded_node_acc, + phantom: PhantomData, + } + } + + // Should return polynomials in the consistent with + // Self::Evaluations::to_vec() and Self::Commitments::to_vec(). + fn _columns(&self) -> Vec> { + vec![ + self.x_coords.as_poly().clone(), + self.h_powers.xs.as_poly().clone(), + self.h_powers.ys.as_poly().clone(), + self.node_selector.as_poly().clone(), + self.bf_bits.as_poly().clone(), + self.node_x_coord.acc.as_poly().clone(), + self.blinded_node.acc.xs.as_poly().clone(), + self.blinded_node.acc.ys.as_poly().clone(), + ] + } + + fn _columns_evaluated(&self, zeta: &F) -> ProofEvals { + let x_coords = self.x_coords.evaluate(zeta); + let h_powers = [ + self.h_powers.xs.evaluate(zeta), + self.h_powers.ys.evaluate(zeta), + ]; + let node_selector = self.node_selector.evaluate(zeta); + let bf_bits = self.bf_bits.evaluate(zeta); + let blinded_node_acc = [ + self.blinded_node.acc.xs.evaluate(zeta), + self.blinded_node.acc.ys.evaluate(zeta), + ]; + let node_x_coord_acc = self.node_x_coord.acc.evaluate(zeta); + ProofEvals { + x_coords, + h_powers, + node_selector, + bf_bits, + node_x_coord_acc, + blinded_node_acc, + } + } +} + +impl, G: SWCurveConfig> ProverPiop + for PiopProver> +{ + type Commitments = ProofComms; + type Evaluations = ProofEvals; + 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![ + self.node_x_coord.constraints(), + self.blinded_node.constraints(), + self.node_selector_bool.constraints(), + self.bf_bits_bool.constraints(), + ] + .concat() + } + + fn constraints_lin(&self, zeta: &F) -> Vec> { + vec![ + self.node_x_coord.constraints_linearized(zeta), + self.blinded_node.constraints_linearized(zeta), + self.node_selector_bool.constraints_linearized(zeta), + self.bf_bits_bool.constraints_linearized(zeta), + ] + .concat() + } + + fn domain(&self) -> &Domain { + &self.domain + } + + fn result(&self) -> Self::Instance { + self.blinded_node.seed_plus_sum() + } +} diff --git a/pasta-tree/src/circuit/verifier.rs b/pasta-tree/src/circuit/verifier.rs new file mode 100644 index 0000000..8dc595f --- /dev/null +++ b/pasta-tree/src/circuit/verifier.rs @@ -0,0 +1,124 @@ +use ark_ec::AffineRepr; +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +use ark_ff::PrimeField; +use ark_std::marker::PhantomData; +use ark_std::{vec, vec::Vec}; +use w3f_pcs::pcs::Commitment; + +use crate::circuit::{ProofComms, ProofEvals}; +use w3f_plonk_common::domain::EvaluatedDomain; +use w3f_plonk_common::gadgets::VerifierGadget; +use w3f_plonk_common::gadgets::booleanity::BooleanityValues; +use w3f_plonk_common::gadgets::ec::CondAddValues; +use w3f_plonk_common::gadgets::inner_prod::InnerProdValues; +use w3f_plonk_common::piop::VerifierPiop; + +pub struct PiopVerifier, G: AffineRepr> { + domain_evals: EvaluatedDomain, + x_coords_comm: C, + h_powers_comm: [C; 2], + witness_columns: ProofComms, + // Gadget verifiers: + node_x_coord: InnerProdValues, + blinded_node: CondAddValues, + node_selector_bool: BooleanityValues, + bf_bits_bool: BooleanityValues, +} + +impl, G: AffineRepr> PiopVerifier { + pub fn init( + _blinded_node: G, + blinded_parent: C, + domain_evals: EvaluatedDomain, + h_powers_comm: [C; 2], + witness_columns: ProofComms, + all_evals: ProofEvals, + ) -> Self { + let node_x_coord = InnerProdValues { + a: all_evals.x_coords, + b: all_evals.node_selector, + not_last: domain_evals.not_last_row, + acc: all_evals.node_x_coord_acc, + }; + + let blinded_node = CondAddValues { + bitmask: all_evals.bf_bits, + points: (all_evals.h_powers[0], all_evals.h_powers[1]), + not_last: domain_evals.not_last_row, + acc: (all_evals.blinded_node_acc[0], all_evals.blinded_node_acc[1]), + _phantom: PhantomData, + }; + + let node_selector_bool = BooleanityValues { + bits: all_evals.node_selector, + }; + + let bf_bits_bool = BooleanityValues { + bits: all_evals.bf_bits, + }; + + Self { + domain_evals, + x_coords_comm: blinded_parent, + h_powers_comm, + witness_columns, + node_x_coord, + blinded_node, + node_selector_bool, + bf_bits_bool, + } + } +} + +impl, G: SWCurveConfig> VerifierPiop + for PiopVerifier> +{ + const N_CONSTRAINTS: usize = 5; + const N_COLUMNS: usize = 8; + + fn precommitted_columns(&self) -> Vec { + vec![ + self.x_coords_comm.clone(), + self.h_powers_comm[0].clone(), + self.h_powers_comm[1].clone(), + ] + } + + fn evaluate_constraints_main(&self) -> Vec { + vec![ + self.node_x_coord.evaluate_constraints_main(), + self.blinded_node.evaluate_constraints_main(), + self.node_selector_bool.evaluate_constraints_main(), + self.bf_bits_bool.evaluate_constraints_main(), + ] + .concat() + } + + fn lin_poly_commitment(&self, agg_coeffs: &[F]) -> (Vec, Vec) { + assert_eq!(agg_coeffs.len(), Self::N_CONSTRAINTS); + + let node_x_coord_acc = self.witness_columns.node_x_coord_acc.clone(); + let node_x_coord_coeff = agg_coeffs[0] * self.node_x_coord.not_last; + + let blinded_node_acc_x = self.witness_columns.blinded_node_acc[0].clone(); + let blinded_node_acc_y = self.witness_columns.blinded_node_acc[1].clone(); + let (c_acc_x, c_acc_y) = self.blinded_node.acc_coeffs_1(); + let mut blinded_node_x_coeff = agg_coeffs[1] * c_acc_x; + let mut blinded_node_y_coeff = agg_coeffs[1] * c_acc_y; + let (c_acc_x, c_acc_y) = self.blinded_node.acc_coeffs_2(); + blinded_node_x_coeff += agg_coeffs[2] * c_acc_x; + blinded_node_y_coeff += agg_coeffs[2] * c_acc_y; + ( + vec![ + node_x_coord_coeff, + blinded_node_x_coeff, + blinded_node_y_coeff, + ], + vec![node_x_coord_acc, blinded_node_acc_x, blinded_node_acc_y], + ) + } + + fn domain_evaluated(&self) -> &EvaluatedDomain { + &self.domain_evals + } +} diff --git a/pasta-tree/src/level/mod.rs b/pasta-tree/src/level/mod.rs index 0f0f8b1..13b82e5 100644 --- a/pasta-tree/src/level/mod.rs +++ b/pasta-tree/src/level/mod.rs @@ -7,7 +7,6 @@ use w3f_pcs::pcs::PCS; use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::AggregateProof; use w3f_plonk_common::PiopProof; -use w3f_ring_proof::piop::{RingCommitments, RingEvaluations}; pub struct LevelProof { piop_proof: PiopProof< diff --git a/pasta-tree/src/level/prover.rs b/pasta-tree/src/level/prover.rs index 651e3fc..995b8fc 100644 --- a/pasta-tree/src/level/prover.rs +++ b/pasta-tree/src/level/prover.rs @@ -13,8 +13,6 @@ use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::ProverPiop; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; -use w3f_ring_proof::ArkTranscript; -use w3f_ring_proof::piop::prover::PiopProver; impl> CycleSideParams> @@ -24,7 +22,7 @@ impl>, rng: &mut R, ) -> (Affine, LevelProof) { - let (fixed_columns, verifier_key) = + let (fixed_columns, verifxier_key) = self.commit_children(&witness.level_witness.siblings, witness.parent_bf); let piop = PiopProver::build( &self.piop_params, @@ -39,7 +37,7 @@ impl, _>::init( self.pcs_params.ck(), - verifier_key, + blinded_node, ArkTranscript::new(b"pasta-tree-level-proof"), ); let (pcs_openings, piop_proof, _transcript) = plonk_prover.reduce_to_pcs_opening(piop); diff --git a/pasta-tree/src/level/verifier.rs b/pasta-tree/src/level/verifier.rs index 4c47ecd..53566c5 100644 --- a/pasta-tree/src/level/verifier.rs +++ b/pasta-tree/src/level/verifier.rs @@ -8,8 +8,6 @@ use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::VerifierPiop; use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; -use w3f_ring_proof::piop::verifier::PiopVerifier; -use w3f_ring_proof::{ArkTranscript, FixedColumnsCommitted, VerifierKey}; impl> CycleSideParams> diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 36f9104..e4cd2f3 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -1,21 +1,19 @@ +use crate::circuit::params::PiopParams; +use crate::circuit::{ProofComms, ProofEvals}; use ark_ec::{AffineRepr, CurveGroup, PrimeGroup}; use ark_ff::{PrimeField, Zero}; use ark_std::rand::Rng; -use std::marker::PhantomData; use w3f_pcs::aggregation::multiple::ShplonkTranscript; use w3f_pcs::pcs::PCS; -use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::AggregateProof; use w3f_plonk_common::PiopProof; use w3f_plonk_common::domain::Domain; -use w3f_ring_proof::piop::{FixedColumns, RingCommitments, RingEvaluations}; -use w3f_ring_proof::{FixedColumnsCommitted, PiopParams, VerifierKey}; pub mod auth_path; -// pub mod circuit; -pub mod level; +pub mod circuit; +// pub mod level; pub mod prover; pub mod verifier; @@ -36,12 +34,10 @@ pub struct CycleParams< #[derive(Clone)] pub struct CycleSideProof> { - piop_proofs: Vec< - PiopProof, RingCommitments>, RingEvaluations>, - >, + piop_proofs: + Vec, ProofComms>, ProofEvals>>, pcs_proof: AggregateProof>, todo: Coeffs, - fixed_columns_committed: Vec>>, } #[derive(Clone)] @@ -66,8 +62,10 @@ where let setup_degree = 3 * domain_size; let c0_pcs_params = HidingIpa::::setup(setup_degree, rng); let c1_pcs_params = HidingIpa::::setup(setup_degree, rng); - let c0_piop_params = piop_params(domain_size, c1_pcs_params.h, rng); - let c1_piop_params = piop_params(domain_size, c0_pcs_params.h, rng); + let c0_domain = Domain::::new(domain_size, true); + let c0_piop_params = PiopParams::setup(c0_domain, c1_pcs_params.h); + let c1_domain = Domain::::new(domain_size, true); + let c1_piop_params = PiopParams::setup(c1_domain, c0_pcs_params.h); Self { c0_params: CycleSideParams { pcs_params: c0_pcs_params, @@ -81,60 +79,27 @@ where } } -fn piop_params, R: Rng>( - domain_size: usize, - h: G, - rng: &mut R, -) -> PiopParams { - let domain = Domain::::new(domain_size, true); - let seed = G::rand(rng); - let padding = G::rand(rng); - PiopParams::setup(domain, h, seed, padding) -} - impl> CycleSideParams { - pub fn commit_children( + pub fn commit_x_coords( &self, - children: &[G], + children_x_coords: Vec, bf: C::ScalarField, - ) -> ( - FixedColumns, - VerifierKey>, - ) { - let fixed_columns = self.piop_params.fixed_columns(&children); - let xs = fixed_columns.points.xs.as_poly(); - let ys = fixed_columns.points.ys.as_poly(); - let fixed_columns_committed = FixedColumnsCommitted { - points: [ - self.pcs_params.commit_hiding(xs, bf).unwrap(), - self.pcs_params - .commit_hiding(ys, C::ScalarField::zero()) - .unwrap(), - ], - ring_selector: self - .pcs_params - .commit_hiding( - fixed_columns.ring_selector.as_poly(), - C::ScalarField::zero(), - ) - .unwrap(), - phantom: PhantomData, - }; - let verifier_key = VerifierKey { - pcs_raw_vk: self.pcs_params.raw_vk(), - fixed_columns_committed, - }; - (fixed_columns, verifier_key) + ) -> Result, ()> { + let x_coords = self.piop_params.x_coords_column(children_x_coords); + Ok(self.pcs_params.commit_hiding(x_coords.as_poly(), bf)?) } - pub fn commit_nodes( - &self, - nodes: &[G], - // children_x_coords: Vec, - blinding: C::ScalarField, - ) -> Result { - let xs = self.piop_params.points_column(nodes).xs; - Ok(self.pcs_params.commit_hiding(xs.as_poly(), blinding)?.0) + pub fn commit_h_powers(&self) -> [IPACommitment; 2] { + let h_powers = self.piop_params.h_powers_column(); + let h_powers = [ + self.pcs_params + .commit_hiding(h_powers.xs.as_poly(), C::ScalarField::zero()) + .unwrap(), + self.pcs_params + .commit_hiding(h_powers.ys.as_poly(), C::ScalarField::zero()) + .unwrap(), + ]; + h_powers } } @@ -170,34 +135,28 @@ mod tests { use ark_ff::{BigInteger, Field, Zero}; use ark_pallas::PallasConfig; use ark_poly::DenseUVPolynomial; - use ark_std::iterable::Iterable; use ark_std::rand::Rng; use ark_std::{UniformRand, cfg_iter_mut, end_timer, start_timer, test_rng}; use ark_vesta::VestaConfig; use w3f_pcs::Poly; use w3f_pcs::pcs::PCS; use w3f_pcs::pcs::PcsParams; - use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::IPA; - use w3f_plonk_common::piop::ProverPiop; use w3f_plonk_common::test_helpers::random_vec; - use w3f_ring_proof::PiopParams; use crate::auth_path::node::LevelWitness; use crate::auth_path::path::AuthenticationPath; #[cfg(feature = "parallel")] use rayon::prelude::*; - use w3f_plonk_common::domain::Domain; type PallasIPA = IPA; - type PallasC = WrappedAffine; fn random_witness, R: Rng>( params: &CycleSideParams, path_node: G, rng: &mut R, ) -> LevelWitness { - let capacity = params.piop_params.keyset_part_size; + let capacity = params.piop_params.children_capacity(); let mut nodes = random_vec::(capacity, rng); let i = rng.gen_range(0..capacity); nodes[i] = path_node; @@ -258,17 +217,6 @@ mod tests { (leaf, path, root) } - fn setup, G: AffineRepr>( - rng: &mut R, - domain_size: usize, - ) -> (CS::Params, PiopParams) { - let setup_degree = 3 * domain_size; - let pcs_params = CS::setup(setup_degree, rng); - let domain = Domain::new(domain_size, true); - let piop_params = PiopParams::setup(domain, G::rand(rng), G::rand(rng), G::rand(rng)); - (pcs_params, piop_params) - } - fn _test_proof(log_n: usize, height: usize) where F0: PrimeField, @@ -281,12 +229,12 @@ mod tests { let domain_size = 1 << log_n; let params = CycleParams::, Projective>::setup(domain_size, rng); let (_leaf, path, wrapped_root) = random_path(¶ms, height, rng); - let _root = match wrapped_root { + let root = match wrapped_root { CycleSide::C0(root) => root, //TODO: panics on odd height _ => panic!(), }; - let capacity = params.c0_params.piop_params.keyset_part_size; + let capacity = params.c0_params.piop_params.children_capacity(); let t_prove = start_timer!(|| format!( "Proving CurveTree membership, H={height}, M={}, C={}, C^{height}={}", domain_size, @@ -297,7 +245,7 @@ mod tests { end_timer!(t_prove); let t_verify = start_timer!(|| "Verifying CurveTree opening"); - let valid = params.verify(auth_path, proof, wrapped_root); + let valid = params.verify(auth_path, proof, root); end_timer!(t_verify); assert!(valid); } @@ -306,7 +254,7 @@ mod tests { // cargo test test_proof --release --features="print-trace parallel" -- --show-output #[test] fn test_proof() { - _test_proof::<_, _, PallasConfig, VestaConfig>(9, 4); + _test_proof::<_, _, PallasConfig, VestaConfig>(8, 4); } fn _bench_msm(log_n: u32) { diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 0a070f9..0dcb3d0 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -1,6 +1,8 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; +use crate::circuit::prover::PiopProver; +use crate::verifier::V; use crate::{Coeffs, CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof, IPACommitment}; use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; @@ -11,10 +13,9 @@ use std::collections::BTreeSet; use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::Shplonk; -use w3f_plonk_common::piop::ProverPiop; +use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; use w3f_ring_proof::ArkTranscript; -use w3f_ring_proof::piop::prover::PiopProver; impl CycleParams, Projective> where @@ -36,10 +37,10 @@ where let auth_path = blinded_auth_path.clone(); let c0_proof = self.c0_params - .prove_side(blinded_auth_path.c1_path, &auth_path_with_bf.c1_path, rng); + .prove_side(blinded_auth_path.c1_path, auth_path_with_bf.c1_path, rng); let c1_proof = self.c1_params - .prove_side(blinded_auth_path.c0_path, &auth_path_with_bf.c0_path, rng); + .prove_side(blinded_auth_path.c0_path, auth_path_with_bf.c0_path, rng); (auth_path, CurveTreeProof { c0_proof, c1_proof }) } } @@ -50,33 +51,27 @@ impl( &self, blinded_path: Vec>, - witness: &[LevelWitnessWithBlinding>], + witness: Vec>>, rng: &mut R, ) -> CycleSideProof { + // let mut s = std::any::type_name::(); + // s = &s[70..s.len()]; + // println!("\n\nprover {s}\nchildren={blinded_path:?}\n"); debug_assert_eq!(blinded_path.len(), witness.len()); + let n_polys = V::::N_COLUMNS + 2; let mut piop_proofs = Vec::with_capacity(witness.len()); - let mut fixed_columns_committed = Vec::with_capacity(witness.len()); - let mut polys = Vec::with_capacity(witness.len() * 9); - let mut coords = Vec::with_capacity(witness.len() * 9); - let mut bfs = Vec::with_capacity(witness.len() * 9); + let mut polys = Vec::with_capacity(witness.len() * n_polys); + let mut coords = Vec::with_capacity(witness.len() * n_polys); + let mut bfs = Vec::with_capacity(witness.len() * n_polys); let plonk_prover = PlonkProver::, _>::init( self.pcs_params.ck(), - blinded_path.clone(), + (), ArkTranscript::new(b"pasta-tree-level-proof"), ); - for (level, blinded_node) in witness.iter().zip(blinded_path.into_iter()) { - let (fixed_columns, verifier_key) = - self.commit_children(&level.level_witness.siblings, level.parent_bf); - // debug_assert_eq!(verifier_key.fixed_columns_committed.points[0].0, *blinded_node); - fixed_columns_committed.push(verifier_key.fixed_columns_committed); - let piop = PiopProver::build( - &self.piop_params, - fixed_columns, - level.level_witness.path_node_idx, - level.bf, - ); + for (level, blinded_node) in witness.into_iter().zip(blinded_path.into_iter()) { + let piop = PiopProver::build(&self.piop_params, level.clone()); let blinded_node_ = > as ProverPiop< C::ScalarField, IPACommitment, @@ -116,7 +111,6 @@ impl CycleParams, Projective> where @@ -21,88 +23,71 @@ where &self, auth_path: BlindedAuthenticationPath, Projective>, proof: CurveTreeProof, Projective>, - _root: CycleSide, Affine>, + root: Affine, ) -> bool { - // println!("leaf = {}", auth_path.c0_path[0]); - // println!("root = {:?}", root); - let _c0_x_coords: Vec> = proof - .c0_proof - .fixed_columns_committed - .iter() - .map(|c| c.points[0].0) - .collect(); - let _c1_x_coords: Vec> = proof - .c1_proof - .fixed_columns_committed - .iter() - .map(|c| c.points[0].0) - .collect(); - // match root { - // CycleSide::C0(c0_root) => { - // assert_eq!(c0_root, c0_x_coords[c0_x_coords.len() - 1]); - // assert_eq!(auth_path.c1_path, c1_x_coords); - // assert_eq!(auth_path.c0_path[1..], c0_x_coords[..c0_x_coords.len() - 1]); - // } - // CycleSide::C1(c1_root) => { - // assert_eq!(c1_root, c1_x_coords[c1_x_coords.len() - 1]); - // assert_eq!(auth_path.c1_path, c1_x_coords[..c1_x_coords.len() - 1]); - // assert_eq!(auth_path.c0_path[1..], c0_x_coords); - // } - // } + let BlindedAuthenticationPath { c0_path, c1_path } = auth_path; + let mut c0_parents = c0_path[1..].to_vec(); + c0_parents.push(root); let c0_proof = self .c0_params - .verify_side(auth_path.c1_path, proof.c0_proof); + .verify_side(c1_path.clone(), c0_parents, proof.c0_proof); assert!(c0_proof); - let c1_proof = self - .c1_params - .verify_side(auth_path.c0_path, proof.c1_proof); + let c1_proof = self.c1_params.verify_side(c0_path, c1_path, proof.c1_proof); assert!(c1_proof); c0_proof && c1_proof } } +pub type V = PiopVerifier<::ScalarField, IPACommitment, Affine>; + impl> CycleSideParams> { pub fn verify_side( &self, - blinded_path: Vec>, + // selected re-randomized children + children: Vec>, + // parents, re-randomized at the previous step + parents: Vec, side_proof: CycleSideProof, ) -> bool { + // let mut s = std::any::type_name::(); + // s = &s[65..s.len()]; + // println!("\n\nverifier {s}\nchildren={children:?}\nparents={parents:?}\n"); let plonk_verifier: PlonkVerifier, _> = PlonkVerifier::init( self.pcs_params.vk(), - &blinded_path, + &(), ArkTranscript::new(b"pasta-tree-level-proof"), ); - let mut polys = Vec::with_capacity(side_proof.piop_proofs.len() * 9); - let mut coords = Vec::with_capacity(side_proof.piop_proofs.len() * 9); - let mut vals = Vec::with_capacity(side_proof.piop_proofs.len() * 9); + let n_polys = V::::N_COLUMNS + 2; + let mut polys = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); + let mut coords = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); + let mut vals = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); + + let h_powers = self.commit_h_powers(); - for ((blinded_node, piop_proof), parent) in blinded_path - .iter() + for ((selected_node, parent), piop_proof) in children + .into_iter() + .zip(parents.into_iter()) .zip(side_proof.piop_proofs.into_iter()) - .zip(side_proof.fixed_columns_committed.into_iter()) { let (challenges, _rng) = plonk_verifier.restore_challenges( - blinded_node, + &selected_node, &piop_proof, // '1' accounts for the quotient polynomial that is aggregated together with the columns - 8, - 7, + V::::N_COLUMNS + 1, + V::::N_CONSTRAINTS, ); - let seed = self.piop_params.seed; - let seed_plus_result = (seed + blinded_node).into_affine(); let domain_at_zeta = self.piop_params.domain.evaluate(challenges.zeta); - let piop = PiopVerifier::<_, _, Affine>::init( + let piop = V::::init( + selected_node, + WrappedAffine(parent), domain_at_zeta, - parent, + h_powers.clone(), piop_proof.column_commitments.clone(), piop_proof.columns_at_zeta.clone(), - (seed.x, seed.y), - (seed_plus_result.x, seed_plus_result.y), ); - let PcsOpeningAt2Points { open_at_zeta, open_at_zeta_omega, @@ -111,7 +96,7 @@ impl Date: Mon, 25 May 2026 07:22:17 +0300 Subject: [PATCH 02/42] ProverPiop::N_CONSTRAINTS --- pasta-tree/src/circuit/prover.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit/prover.rs index 3404e05..01b0380 100644 --- a/pasta-tree/src/circuit/prover.rs +++ b/pasta-tree/src/circuit/prover.rs @@ -136,6 +136,7 @@ impl> PiopProver { impl, G: SWCurveConfig> ProverPiop for PiopProver> { + const N_CONSTRAINTS: usize = 5; type Commitments = ProofComms; type Evaluations = ProofEvals; type Instance = SwAffine; From 081fd1093899a52a0cb33ebbe88e0c1321199a22 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Mon, 25 May 2026 10:17:17 +0300 Subject: [PATCH 03/42] random_witness doesn't need pcs --- pasta-tree/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index e4cd2f3..31a1332 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -151,12 +151,12 @@ mod tests { type PallasIPA = IPA; - fn random_witness, R: Rng>( - params: &CycleSideParams, + pub fn random_witness, R: Rng>( + piop_params: &PiopParams, path_node: G, rng: &mut R, ) -> LevelWitness { - let capacity = params.piop_params.children_capacity(); + let capacity = piop_params.children_capacity(); let mut nodes = random_vec::(capacity, rng); let i = rng.gen_range(0..capacity); nodes[i] = path_node; @@ -171,7 +171,7 @@ mod tests { path_node: G, rng: &mut R, ) -> (C::Affine, LevelWitness) { - let level_witness = random_witness(params, path_node, rng); + let level_witness = random_witness(¶ms.piop_params, path_node, rng); let parent = level_witness.compute_parent(params).unwrap(); (parent, level_witness) } From 9d20f57abf9697c5c07a792b4de09712aaa2b8e0 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Mon, 25 May 2026 10:26:58 +0300 Subject: [PATCH 04/42] more constraints added --- pasta-tree/Cargo.toml | 1 + pasta-tree/src/circuit/mod.rs | 20 ++-- pasta-tree/src/circuit/prover.rs | 149 ++++++++++++++++++++++------- pasta-tree/src/circuit/verifier.rs | 98 ++++++++++++++----- 4 files changed, 202 insertions(+), 66 deletions(-) diff --git a/pasta-tree/Cargo.toml b/pasta-tree/Cargo.toml index 8a4348b..495d9cf 100644 --- a/pasta-tree/Cargo.toml +++ b/pasta-tree/Cargo.toml @@ -24,6 +24,7 @@ rayon = { workspace = true, optional = true } [dev-dependencies] ark-bls12-381.workspace = true +ark-ed-on-bls12-381-bandersnatch.workspace = true criterion.workspace = true [features] diff --git a/pasta-tree/src/circuit/mod.rs b/pasta-tree/src/circuit/mod.rs index 7e58165..3bb3410 100644 --- a/pasta-tree/src/circuit/mod.rs +++ b/pasta-tree/src/circuit/mod.rs @@ -11,21 +11,23 @@ pub mod verifier; #[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct ProofComms> { - pub(crate) node_selector: C, + pub(crate) node_idx: C, pub(crate) bf_bits: C, - pub(crate) node_x_coord_acc: C, + pub(crate) selected_node_acc: C, pub(crate) blinded_node_acc: [C; 2], + pub(crate) node_idx_sum_acc: C, pub(crate) phantom: PhantomData, } impl> ColumnsCommited for ProofComms { fn to_vec(self) -> Vec { vec![ - self.node_selector, + self.node_idx, self.bf_bits, - self.node_x_coord_acc, + self.selected_node_acc, self.blinded_node_acc[0].clone(), self.blinded_node_acc[1].clone(), + self.node_idx_sum_acc, ] } } @@ -34,10 +36,11 @@ impl> ColumnsCommited for ProofComms pub struct ProofEvals { pub(crate) x_coords: F, pub(crate) h_powers: [F; 2], - pub(crate) node_selector: F, + pub(crate) node_idx: F, pub(crate) bf_bits: F, - pub(crate) node_x_coord_acc: F, + pub(crate) selected_node_acc: F, pub(crate) blinded_node_acc: [F; 2], + pub(crate) node_idx_sum_acc: F, } impl ColumnsEvaluated for ProofEvals { @@ -46,11 +49,12 @@ impl ColumnsEvaluated for ProofEvals { self.x_coords, self.h_powers[0], self.h_powers[1], - self.node_selector, + self.node_idx, self.bf_bits, - self.node_x_coord_acc, + self.selected_node_acc, self.blinded_node_acc[0], self.blinded_node_acc[1], + self.node_idx_sum_acc, ] } } diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit/prover.rs index 01b0380..fbd0b03 100644 --- a/pasta-tree/src/circuit/prover.rs +++ b/pasta-tree/src/circuit/prover.rs @@ -4,7 +4,7 @@ use crate::circuit::{ProofComms, ProofEvals}; use ark_ec::AffineRepr; use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; -use ark_ff::PrimeField; +use ark_ff::{PrimeField, Zero}; use ark_poly::Evaluations; use ark_poly::univariate::DensePolynomial; use ark_std::marker::PhantomData; @@ -15,25 +15,31 @@ use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::ProverGadget; use w3f_plonk_common::gadgets::booleanity::{BitColumn, Booleanity}; +use w3f_plonk_common::gadgets::column_sum::ColumnSumPolys; use w3f_plonk_common::gadgets::ec::AffineColumn; use w3f_plonk_common::gadgets::ec::CondAdd; +use w3f_plonk_common::gadgets::fixed_cells::FixedCells; use w3f_plonk_common::gadgets::inner_prod::InnerProd; use w3f_plonk_common::piop::ProverPiop; +// use crate::circuit::cell_equality::CellEqualityPolys; pub struct PiopProver> { domain: Domain, // `x` coordinates of all the children of a node. Public input. - x_coords: FieldColumn, + nodes: FieldColumn, // `H, 2H, 4H,...,2^sH` Fixed column. h_powers: AffineColumn, // `node_x = self.x_coords[self.node_idx]` Private input. - node_selector: BitColumn, + node_idx: BitColumn, // Bits of the chosen blinding factor. Private input. bf_bits: BitColumn, - node_x_coord: InnerProd, + selected_node: InnerProd, blinded_node: CondAdd, // blinded_node.acc[0] = (x_i, y_i) = Ci, blinded_node.acc[capacity] = Ci + bf.H = Ci' - node_selector_bool: Booleanity, + node_idx_bool: Booleanity, bf_bits_bool: Booleanity, + node_idx_sum: ColumnSumPolys, + node_idx_sum_vals: FixedCells, + // node_to_seed: CellEqualityPolys, } impl> PiopProver { @@ -41,36 +47,41 @@ impl> PiopProver { let domain = params.domain.clone(); let x_coords = params.x_coords_column(level.level_witness.x_coords()); let h_powers = params.h_powers_column(); - let node_selector = params.node_selector(level.level_witness.path_node_idx); + let node_idx = params.node_selector(level.level_witness.path_node_idx); let bf_bits = params.bf_bits_column(level.bf); + let selected_node = InnerProd::init(x_coords.clone(), node_idx.col.clone(), &domain); let node = level.level_witness.path_node(); - - let node_x_coord = InnerProd::init(x_coords.clone(), node_selector.col.clone(), &domain); - let witnessed_x = node.x().unwrap(); - let computed_x = node_x_coord.acc.payload()[domain.capacity - 1]; - assert_eq!(computed_x, witnessed_x); + assert_eq!( + selected_node.acc.payload()[domain.capacity - 1], + node.x().unwrap() + ); // here we witness yi let blinded_node = CondAdd::init(bf_bits.clone(), h_powers.clone(), node, &domain); assert_eq!( blinded_node.seed_plus_sum(), (node + params.h * level.bf).into_affine() ); - let node_selector_bool = Booleanity::init(node_selector.clone()); + let node_idx_bool = Booleanity::init(node_idx.clone()); let bf_bits_bool = Booleanity::init(bf_bits.clone()); - // let cond_add_acc_x = FixedCells::init(blinded_node.acc.xs.clone(), &domain); - // let cond_add_acc_y = FixedCells::init(blinded_node.acc.ys.clone(), &domain); - // let inner_prod_acc = FixedCells::init(node_x_coord.acc.clone(), &domain); + let node_idx_sum = ColumnSumPolys::init(node_idx.col.clone(), &domain); + let node_idx_sum_vals = + FixedCells::init(node_idx_sum.acc.clone(), &domain, F::zero(), F::one()); + // let node_to_seed = CellEqualityPolys::a_first_b_last(blinded_node.acc.xs.clone(), selected_node.acc.clone(), &domain); + Self { domain, - x_coords, + nodes: x_coords, h_powers, - node_selector, + node_idx, bf_bits, - node_x_coord, + selected_node, blinded_node, - node_selector_bool, + node_idx_bool, bf_bits_bool, + node_idx_sum, + node_idx_sum_vals, + // node_to_seed, } } @@ -78,18 +89,20 @@ impl> PiopProver { &self, commit: Fun, ) -> ProofComms { - let node_selector = commit(self.node_selector.as_poly()); + let node_idx = commit(self.node_idx.as_poly()); let bf_bits = commit(self.bf_bits.as_poly()); - let node_x_coord_acc = commit(self.node_x_coord.acc.as_poly()); + let selected_node_acc = commit(self.selected_node.acc.as_poly()); let blinded_node_acc = [ commit(self.blinded_node.acc.xs.as_poly()), commit(self.blinded_node.acc.ys.as_poly()), ]; + let node_idx_sum_acc = commit(self.node_idx_sum.acc.as_poly()); ProofComms { - node_selector, + node_idx, bf_bits, - node_x_coord_acc, + selected_node_acc, blinded_node_acc, + node_idx_sum_acc, phantom: PhantomData, } } @@ -98,37 +111,40 @@ impl> PiopProver { // Self::Evaluations::to_vec() and Self::Commitments::to_vec(). fn _columns(&self) -> Vec> { vec![ - self.x_coords.as_poly().clone(), + self.nodes.as_poly().clone(), self.h_powers.xs.as_poly().clone(), self.h_powers.ys.as_poly().clone(), - self.node_selector.as_poly().clone(), + self.node_idx.as_poly().clone(), self.bf_bits.as_poly().clone(), - self.node_x_coord.acc.as_poly().clone(), + self.selected_node.acc.as_poly().clone(), self.blinded_node.acc.xs.as_poly().clone(), self.blinded_node.acc.ys.as_poly().clone(), + self.node_idx_sum.acc.as_poly().clone(), ] } fn _columns_evaluated(&self, zeta: &F) -> ProofEvals { - let x_coords = self.x_coords.evaluate(zeta); + let x_coords = self.nodes.evaluate(zeta); let h_powers = [ self.h_powers.xs.evaluate(zeta), self.h_powers.ys.evaluate(zeta), ]; - let node_selector = self.node_selector.evaluate(zeta); + let node_idx = self.node_idx.evaluate(zeta); let bf_bits = self.bf_bits.evaluate(zeta); let blinded_node_acc = [ self.blinded_node.acc.xs.evaluate(zeta), self.blinded_node.acc.ys.evaluate(zeta), ]; - let node_x_coord_acc = self.node_x_coord.acc.evaluate(zeta); + let selected_node_acc = self.selected_node.acc.evaluate(zeta); + let node_idx_sum_acc = self.node_idx_sum.acc.evaluate(zeta); ProofEvals { x_coords, h_powers, - node_selector, + node_idx, bf_bits, - node_x_coord_acc, + selected_node_acc, blinded_node_acc, + node_idx_sum_acc, } } } @@ -136,7 +152,7 @@ impl> PiopProver { impl, G: SWCurveConfig> ProverPiop for PiopProver> { - const N_CONSTRAINTS: usize = 5; + const N_CONSTRAINTS: usize = 10; type Commitments = ProofComms; type Evaluations = ProofEvals; type Instance = SwAffine; @@ -159,21 +175,49 @@ impl, G: SWCurveConfig> ProverPio } fn constraints(&self) -> Vec> { + let (node_blinded_x, node_blinded_y) = self.blinded_node.seed_plus_sum().xy().unwrap(); vec![ - self.node_x_coord.constraints(), + self.selected_node.constraints(), self.blinded_node.constraints(), - self.node_selector_bool.constraints(), + self.node_idx_sum.constraints(), + self.node_idx_bool.constraints(), self.bf_bits_bool.constraints(), + self.node_idx_sum_vals.constraints(), + // // self.node_to_seed.constraints(), + vec![FixedCells::constraint_cell( + &self.blinded_node.acc.xs, + &self.domain.l_last, + self.domain.capacity - 1, + node_blinded_x, + )], + vec![FixedCells::constraint_cell( + &self.blinded_node.acc.ys, + &self.domain.l_last, + self.domain.capacity - 1, + node_blinded_y, + )], + vec![FixedCells::constraint_cell( + &self.selected_node.acc, + &self.domain.l_first, + 0, + F::zero(), + )], ] .concat() } fn constraints_lin(&self, zeta: &F) -> Vec> { vec![ - self.node_x_coord.constraints_linearized(zeta), + self.selected_node.constraints_linearized(zeta), self.blinded_node.constraints_linearized(zeta), - self.node_selector_bool.constraints_linearized(zeta), + self.node_idx_sum.constraints_linearized(zeta), + self.node_idx_bool.constraints_linearized(zeta), self.bf_bits_bool.constraints_linearized(zeta), + self.node_idx_sum_vals.constraints_linearized(zeta), + // self.node_to_seed.constraints_linearized(zeta), + vec![DensePolynomial::zero()], + vec![DensePolynomial::zero()], + vec![DensePolynomial::zero()], ] .concat() } @@ -186,3 +230,36 @@ impl, G: SWCurveConfig> ProverPio self.blinded_node.seed_plus_sum() } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::IPACommitment; + use crate::tests::random_witness; + use ark_bls12_381::G1Projective; + use ark_ed_on_bls12_381_bandersnatch::{Fq, Fr, SWAffine}; + use ark_std::{UniformRand, test_rng}; + + #[test] + fn test_constraints() { + let rng = &mut test_rng(); + + let domain_size = 256; + let domain = Domain::::new(domain_size, true); + + let node = SWAffine::rand(rng); + let h = SWAffine::rand(rng); + let bf = Fr::from(u128::rand(rng)); + let blinded_node = (node + h * bf).into_affine(); + + let piop_params = PiopParams::setup(domain, h); + let witness = random_witness(&piop_params, node, rng).with_blinding(bf, Fq::zero()); + let piop = PiopProver::build(&piop_params, witness); + + assert!(ProverPiop::<_, IPACommitment>::constraints_satisfied(&piop)); + assert_eq!( + ProverPiop::<_, IPACommitment>::result(&piop), + blinded_node + ); + } +} diff --git a/pasta-tree/src/circuit/verifier.rs b/pasta-tree/src/circuit/verifier.rs index 8dc595f..fa0a150 100644 --- a/pasta-tree/src/circuit/verifier.rs +++ b/pasta-tree/src/circuit/verifier.rs @@ -5,42 +5,48 @@ use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::Commitment; +// use crate::circuit::cell_equality::CellEqualityEvals; use crate::circuit::{ProofComms, ProofEvals}; use w3f_plonk_common::domain::EvaluatedDomain; use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::gadgets::booleanity::BooleanityValues; +use w3f_plonk_common::gadgets::column_sum::ColumnSumEvals; use w3f_plonk_common::gadgets::ec::CondAddValues; +use w3f_plonk_common::gadgets::fixed_cells::FixedCellsValues; use w3f_plonk_common::gadgets::inner_prod::InnerProdValues; use w3f_plonk_common::piop::VerifierPiop; pub struct PiopVerifier, G: AffineRepr> { domain_evals: EvaluatedDomain, + instance: G, x_coords_comm: C, h_powers_comm: [C; 2], witness_columns: ProofComms, // Gadget verifiers: - node_x_coord: InnerProdValues, + selected_node: InnerProdValues, blinded_node: CondAddValues, - node_selector_bool: BooleanityValues, + node_idx_sum: ColumnSumEvals, + node_idx_bool: BooleanityValues, bf_bits_bool: BooleanityValues, + node_idx_sum_vals: FixedCellsValues, + // node_to_seed: CellEqualityEvals, } impl, G: AffineRepr> PiopVerifier { pub fn init( - _blinded_node: G, + instance: G, blinded_parent: C, domain_evals: EvaluatedDomain, h_powers_comm: [C; 2], witness_columns: ProofComms, all_evals: ProofEvals, ) -> Self { - let node_x_coord = InnerProdValues { + let selected_node = InnerProdValues { a: all_evals.x_coords, - b: all_evals.node_selector, + b: all_evals.node_idx, not_last: domain_evals.not_last_row, - acc: all_evals.node_x_coord_acc, + acc: all_evals.selected_node_acc, }; - let blinded_node = CondAddValues { bitmask: all_evals.bf_bits, points: (all_evals.h_powers[0], all_evals.h_powers[1]), @@ -48,24 +54,44 @@ impl, G: AffineRepr> PiopVerifier acc: (all_evals.blinded_node_acc[0], all_evals.blinded_node_acc[1]), _phantom: PhantomData, }; - - let node_selector_bool = BooleanityValues { - bits: all_evals.node_selector, + let node_idx_sum = ColumnSumEvals { + col: all_evals.node_idx, + acc: all_evals.node_idx_sum_acc, + not_last: domain_evals.not_last_row, + }; + let node_idx_bool = BooleanityValues { + bits: all_evals.node_idx, }; - let bf_bits_bool = BooleanityValues { bits: all_evals.bf_bits, }; - + let node_idx_sum_vals = FixedCellsValues { + col: all_evals.node_idx_sum_acc, + col_first: F::zero(), + col_last: F::one(), + l_first: domain_evals.l_first, + l_last: domain_evals.l_last, + }; + // let node_to_seed = CellEqualityEvals { + // a: selected_node.acc, + // l_a: domain_evals.l_last, + // b: blinded_node.acc.0, + // l_b: domain_evals.l_first, + // }; Self { + instance, domain_evals, x_coords_comm: blinded_parent, h_powers_comm, witness_columns, - node_x_coord, + // gadgets + selected_node, blinded_node, - node_selector_bool, + node_idx_sum, + node_idx_bool, bf_bits_bool, + node_idx_sum_vals, + // node_to_seed, } } } @@ -73,8 +99,8 @@ impl, G: AffineRepr> PiopVerifier impl, G: SWCurveConfig> VerifierPiop for PiopVerifier> { - const N_CONSTRAINTS: usize = 5; - const N_COLUMNS: usize = 8; + const N_CONSTRAINTS: usize = 10; + const N_COLUMNS: usize = 9; fn precommitted_columns(&self) -> Vec { vec![ @@ -85,11 +111,30 @@ impl, G: SWCurveConfig> VerifierP } fn evaluate_constraints_main(&self) -> Vec { + let (x, y) = self.instance.xy().unwrap(); vec![ - self.node_x_coord.evaluate_constraints_main(), + self.selected_node.evaluate_constraints_main(), self.blinded_node.evaluate_constraints_main(), - self.node_selector_bool.evaluate_constraints_main(), + self.node_idx_sum.evaluate_constraints_main(), + self.node_idx_bool.evaluate_constraints_main(), self.bf_bits_bool.evaluate_constraints_main(), + self.node_idx_sum_vals.evaluate_constraints_main(), + // self.node_to_seed.evaluate_constraints_main(), + vec![FixedCellsValues::evaluate_for_cell( + self.blinded_node.acc.0, + self.domain_evals.l_last, + x, + )], + vec![FixedCellsValues::evaluate_for_cell( + self.blinded_node.acc.1, + self.domain_evals.l_last, + y, + )], + vec![FixedCellsValues::evaluate_for_cell( + self.selected_node.acc, + self.domain_evals.l_first, + F::zero(), + )], ] .concat() } @@ -97,8 +142,8 @@ impl, G: SWCurveConfig> VerifierP fn lin_poly_commitment(&self, agg_coeffs: &[F]) -> (Vec, Vec) { assert_eq!(agg_coeffs.len(), Self::N_CONSTRAINTS); - let node_x_coord_acc = self.witness_columns.node_x_coord_acc.clone(); - let node_x_coord_coeff = agg_coeffs[0] * self.node_x_coord.not_last; + let selected_node_acc = self.witness_columns.selected_node_acc.clone(); + let selected_node_coeff = agg_coeffs[0] * self.selected_node.not_last; let blinded_node_acc_x = self.witness_columns.blinded_node_acc[0].clone(); let blinded_node_acc_y = self.witness_columns.blinded_node_acc[1].clone(); @@ -108,13 +153,22 @@ impl, G: SWCurveConfig> VerifierP let (c_acc_x, c_acc_y) = self.blinded_node.acc_coeffs_2(); blinded_node_x_coeff += agg_coeffs[2] * c_acc_x; blinded_node_y_coeff += agg_coeffs[2] * c_acc_y; + + let node_idx_sum_acc = self.witness_columns.node_idx_sum_acc.clone(); + let node_idx_sum_coeff = agg_coeffs[3] * self.node_idx_sum.not_last; ( vec![ - node_x_coord_coeff, + selected_node_coeff, blinded_node_x_coeff, blinded_node_y_coeff, + node_idx_sum_coeff, + ], + vec![ + selected_node_acc, + blinded_node_acc_x, + blinded_node_acc_y, + node_idx_sum_acc, ], - vec![node_x_coord_acc, blinded_node_acc_x, blinded_node_acc_y], ) } From 51c511f0f10176731ce5f165a477ccce095c99f3 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Mon, 25 May 2026 11:23:49 +0300 Subject: [PATCH 05/42] more constraints added --- pasta-tree/src/circuit/prover.rs | 35 ++--- pasta-tree/src/circuit/verifier.rs | 35 +++-- w3f-plonk-common/src/gadgets/equal_cells.rs | 117 +++++++++++++++ .../src/gadgets/inner_prod_inv.rs | 139 ++++++++++++++++++ w3f-plonk-common/src/gadgets/mod.rs | 3 + 5 files changed, 290 insertions(+), 39 deletions(-) create mode 100644 w3f-plonk-common/src/gadgets/equal_cells.rs create mode 100644 w3f-plonk-common/src/gadgets/inner_prod_inv.rs diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit/prover.rs index fbd0b03..1a60206 100644 --- a/pasta-tree/src/circuit/prover.rs +++ b/pasta-tree/src/circuit/prover.rs @@ -10,7 +10,6 @@ use ark_poly::univariate::DensePolynomial; use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::Commitment; -use w3f_plonk_common::Column; use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::ProverGadget; @@ -18,10 +17,10 @@ use w3f_plonk_common::gadgets::booleanity::{BitColumn, Booleanity}; use w3f_plonk_common::gadgets::column_sum::ColumnSumPolys; use w3f_plonk_common::gadgets::ec::AffineColumn; use w3f_plonk_common::gadgets::ec::CondAdd; +use w3f_plonk_common::gadgets::equal_cells::CellsEqPolys; use w3f_plonk_common::gadgets::fixed_cells::FixedCells; -use w3f_plonk_common::gadgets::inner_prod::InnerProd; +use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInv; use w3f_plonk_common::piop::ProverPiop; -// use crate::circuit::cell_equality::CellEqualityPolys; pub struct PiopProver> { domain: Domain, @@ -33,13 +32,13 @@ pub struct PiopProver> { node_idx: BitColumn, // Bits of the chosen blinding factor. Private input. bf_bits: BitColumn, - selected_node: InnerProd, + selected_node: InnerProdInv, blinded_node: CondAdd, // blinded_node.acc[0] = (x_i, y_i) = Ci, blinded_node.acc[capacity] = Ci + bf.H = Ci' node_idx_bool: Booleanity, bf_bits_bool: Booleanity, node_idx_sum: ColumnSumPolys, node_idx_sum_vals: FixedCells, - // node_to_seed: CellEqualityPolys, + seed_eq_node: CellsEqPolys, } impl> PiopProver { @@ -49,25 +48,19 @@ impl> PiopProver { let h_powers = params.h_powers_column(); let node_idx = params.node_selector(level.level_witness.path_node_idx); let bf_bits = params.bf_bits_column(level.bf); - let selected_node = InnerProd::init(x_coords.clone(), node_idx.col.clone(), &domain); + let selected_node = InnerProdInv::init(x_coords.clone(), node_idx.col.clone(), &domain); let node = level.level_witness.path_node(); - assert_eq!( - selected_node.acc.payload()[domain.capacity - 1], - node.x().unwrap() - ); + debug_assert_eq!(selected_node.acc.evals[0], node.x().unwrap()); // here we witness yi let blinded_node = CondAdd::init(bf_bits.clone(), h_powers.clone(), node, &domain); - assert_eq!( - blinded_node.seed_plus_sum(), - (node + params.h * level.bf).into_affine() - ); + debug_assert_eq!(blinded_node.seed_plus_sum(), (node + params.h * level.bf).into_affine()); let node_idx_bool = Booleanity::init(node_idx.clone()); let bf_bits_bool = Booleanity::init(bf_bits.clone()); let node_idx_sum = ColumnSumPolys::init(node_idx.col.clone(), &domain); let node_idx_sum_vals = FixedCells::init(node_idx_sum.acc.clone(), &domain, F::zero(), F::one()); - // let node_to_seed = CellEqualityPolys::a_first_b_last(blinded_node.acc.xs.clone(), selected_node.acc.clone(), &domain); + let seed_eq_node = CellsEqPolys::first_cells(selected_node.acc.clone(), blinded_node.acc.xs.clone(), &domain); Self { domain, @@ -81,7 +74,7 @@ impl> PiopProver { bf_bits_bool, node_idx_sum, node_idx_sum_vals, - // node_to_seed, + seed_eq_node, } } @@ -152,7 +145,7 @@ impl> PiopProver { impl, G: SWCurveConfig> ProverPiop for PiopProver> { - const N_CONSTRAINTS: usize = 10; + const N_CONSTRAINTS: usize = 11; type Commitments = ProofComms; type Evaluations = ProofEvals; type Instance = SwAffine; @@ -183,7 +176,6 @@ impl, G: SWCurveConfig> ProverPio self.node_idx_bool.constraints(), self.bf_bits_bool.constraints(), self.node_idx_sum_vals.constraints(), - // // self.node_to_seed.constraints(), vec![FixedCells::constraint_cell( &self.blinded_node.acc.xs, &self.domain.l_last, @@ -198,10 +190,11 @@ impl, G: SWCurveConfig> ProverPio )], vec![FixedCells::constraint_cell( &self.selected_node.acc, - &self.domain.l_first, - 0, + &self.domain.l_last, + self.domain.capacity - 1, F::zero(), )], + self.seed_eq_node.constraints(), ] .concat() } @@ -214,10 +207,10 @@ impl, G: SWCurveConfig> ProverPio self.node_idx_bool.constraints_linearized(zeta), self.bf_bits_bool.constraints_linearized(zeta), self.node_idx_sum_vals.constraints_linearized(zeta), - // self.node_to_seed.constraints_linearized(zeta), vec![DensePolynomial::zero()], vec![DensePolynomial::zero()], vec![DensePolynomial::zero()], + self.seed_eq_node.constraints_linearized(zeta), ] .concat() } diff --git a/pasta-tree/src/circuit/verifier.rs b/pasta-tree/src/circuit/verifier.rs index fa0a150..be1f7ac 100644 --- a/pasta-tree/src/circuit/verifier.rs +++ b/pasta-tree/src/circuit/verifier.rs @@ -1,19 +1,19 @@ -use ark_ec::AffineRepr; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +use ark_ec::AffineRepr; use ark_ff::PrimeField; use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::Commitment; -// use crate::circuit::cell_equality::CellEqualityEvals; use crate::circuit::{ProofComms, ProofEvals}; use w3f_plonk_common::domain::EvaluatedDomain; -use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::gadgets::booleanity::BooleanityValues; use w3f_plonk_common::gadgets::column_sum::ColumnSumEvals; use w3f_plonk_common::gadgets::ec::CondAddValues; +use w3f_plonk_common::gadgets::equal_cells::EqualCells; use w3f_plonk_common::gadgets::fixed_cells::FixedCellsValues; -use w3f_plonk_common::gadgets::inner_prod::InnerProdValues; +use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInvValues; +use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::piop::VerifierPiop; pub struct PiopVerifier, G: AffineRepr> { @@ -23,13 +23,13 @@ pub struct PiopVerifier, G: AffineRepr, // Gadget verifiers: - selected_node: InnerProdValues, + selected_node: InnerProdInvValues, blinded_node: CondAddValues, node_idx_sum: ColumnSumEvals, node_idx_bool: BooleanityValues, bf_bits_bool: BooleanityValues, node_idx_sum_vals: FixedCellsValues, - // node_to_seed: CellEqualityEvals, + seed_eq_node: EqualCells, } impl, G: AffineRepr> PiopVerifier { @@ -41,7 +41,7 @@ impl, G: AffineRepr> PiopVerifier witness_columns: ProofComms, all_evals: ProofEvals, ) -> Self { - let selected_node = InnerProdValues { + let selected_node = InnerProdInvValues { a: all_evals.x_coords, b: all_evals.node_idx, not_last: domain_evals.not_last_row, @@ -72,12 +72,11 @@ impl, G: AffineRepr> PiopVerifier l_first: domain_evals.l_first, l_last: domain_evals.l_last, }; - // let node_to_seed = CellEqualityEvals { - // a: selected_node.acc, - // l_a: domain_evals.l_last, - // b: blinded_node.acc.0, - // l_b: domain_evals.l_first, - // }; + let seed_eq_node = EqualCells { + a: selected_node.acc, + b: blinded_node.acc.0, + li: domain_evals.l_first, + }; Self { instance, domain_evals, @@ -91,7 +90,7 @@ impl, G: AffineRepr> PiopVerifier node_idx_bool, bf_bits_bool, node_idx_sum_vals, - // node_to_seed, + seed_eq_node, } } } @@ -99,7 +98,7 @@ impl, G: AffineRepr> PiopVerifier impl, G: SWCurveConfig> VerifierPiop for PiopVerifier> { - const N_CONSTRAINTS: usize = 10; + const N_CONSTRAINTS: usize = 11; const N_COLUMNS: usize = 9; fn precommitted_columns(&self) -> Vec { @@ -119,7 +118,6 @@ impl, G: SWCurveConfig> VerifierP self.node_idx_bool.evaluate_constraints_main(), self.bf_bits_bool.evaluate_constraints_main(), self.node_idx_sum_vals.evaluate_constraints_main(), - // self.node_to_seed.evaluate_constraints_main(), vec![FixedCellsValues::evaluate_for_cell( self.blinded_node.acc.0, self.domain_evals.l_last, @@ -132,9 +130,10 @@ impl, G: SWCurveConfig> VerifierP )], vec![FixedCellsValues::evaluate_for_cell( self.selected_node.acc, - self.domain_evals.l_first, + self.domain_evals.l_last, F::zero(), )], + self.seed_eq_node.evaluate_constraints_main(), ] .concat() } @@ -143,7 +142,7 @@ impl, G: SWCurveConfig> VerifierP assert_eq!(agg_coeffs.len(), Self::N_CONSTRAINTS); let selected_node_acc = self.witness_columns.selected_node_acc.clone(); - let selected_node_coeff = agg_coeffs[0] * self.selected_node.not_last; + let selected_node_coeff = -agg_coeffs[0] * self.selected_node.not_last; let blinded_node_acc_x = self.witness_columns.blinded_node_acc[0].clone(); let blinded_node_acc_y = self.witness_columns.blinded_node_acc[1].clone(); diff --git a/w3f-plonk-common/src/gadgets/equal_cells.rs b/w3f-plonk-common/src/gadgets/equal_cells.rs new file mode 100644 index 0000000..691ee2a --- /dev/null +++ b/w3f-plonk-common/src/gadgets/equal_cells.rs @@ -0,0 +1,117 @@ +use ark_ff::{FftField, Field, Zero}; +use ark_poly::univariate::DensePolynomial; +use ark_poly::Evaluations; + +use ark_std::{vec, vec::Vec}; + +use crate::domain::Domain; +use crate::gadgets::VerifierGadget; +use crate::{Column, FieldColumn}; + +pub struct CellsEqPolys { + a: FieldColumn, + b: FieldColumn, + li: FieldColumn, +} + +pub struct EqualCells { + pub a: F, + pub b: F, + pub li: F, +} + +impl CellsEqPolys { + pub fn first_cells(a: FieldColumn, b: FieldColumn, domain: &Domain) -> Self { + Self::cells(a, b, 0, domain.l_first.clone(), domain) + } + + pub fn last_cells(a: FieldColumn, b: FieldColumn, domain: &Domain) -> Self { + Self::cells(a, b, domain.capacity - 1, domain.l_last.clone(), domain) + } + + pub fn cells(a: FieldColumn, b: FieldColumn, i: usize, li: FieldColumn, domain: &Domain) -> Self { + assert_eq!(a.payload_len(), domain.capacity); + assert_eq!(b.payload_len(), domain.capacity); + assert_eq!(a.evals.evals[i], b.evals.evals[i]); + Self { a, b, li } + } + + pub fn constraints(&self) -> Vec> { + let a = &self.a.evals_4x; + let b = &self.b.evals_4x; + let li = &self.li.evals_4x; + let c = li * &(a - b); + vec![c] + } + + pub fn constraints_linearized(&self, _z: &F) -> Vec> { + Self::constraints_lin() + } + + pub fn first_constraints(a: FieldColumn, b: FieldColumn, domain: &Domain) -> Vec> { + let gadget = Self::first_cells(a, b, domain); + gadget.constraints() + } + + pub fn last_constraints(a: FieldColumn, b: FieldColumn, domain: &Domain) -> Vec> { + let gadget = Self::last_cells(a, b, domain); + gadget.constraints() + } + + pub fn constraints_lin() -> Vec> { + vec![DensePolynomial::zero()] + } +} + +impl VerifierGadget for EqualCells { + fn evaluate_constraints_main(&self) -> Vec { + let c = self.li * (self.a - self.b); + vec![c] + } +} + +#[cfg(test)] +mod tests { + use super::*; + use ark_ed_on_bls12_381_bandersnatch::Fq; + use ark_std::test_rng; + use crate::test_helpers::random_vec; + use ark_poly::Polynomial; + + + fn _test_equal_cells_gadget(hiding: bool) { + let rng = &mut test_rng(); + + let log_n = 8; + let n = 1 << log_n; + let domain = Domain::new(n, hiding); + + let a = random_vec(domain.capacity, rng); + let mut b = random_vec(domain.capacity, rng); + b[0] = a[0]; + let a = domain.column(a); + let b = domain.column(b); + + let constraints_first = CellsEqPolys::::first_constraints(a, b, &domain); + let constraint_poly = constraints_first[0].interpolate_by_ref(); + assert_eq!(constraint_poly.degree(), 2 * n - 2); + assert!(domain.compute_quotient(&constraint_poly).is_some()); + + let a = random_vec(domain.capacity, rng); + let mut b = random_vec(domain.capacity, rng); + b[domain.capacity-1] = a[domain.capacity-1]; + let a = domain.column(a); + let b = domain.column(b); + + let constraints_last = CellsEqPolys::::last_constraints(a, b, &domain); + let constraint_poly = constraints_last[0].interpolate_by_ref(); + assert_eq!(constraint_poly.degree(), 2 * n - 2); + assert!(domain.compute_quotient(&constraint_poly).is_some()); + } + + #[test] + fn test_equal_cells_gadget() { + _test_equal_cells_gadget(false); + _test_equal_cells_gadget(true); + } +} \ No newline at end of file diff --git a/w3f-plonk-common/src/gadgets/inner_prod_inv.rs b/w3f-plonk-common/src/gadgets/inner_prod_inv.rs new file mode 100644 index 0000000..698a234 --- /dev/null +++ b/w3f-plonk-common/src/gadgets/inner_prod_inv.rs @@ -0,0 +1,139 @@ +use ark_ff::{FftField, Field}; +use ark_poly::univariate::DensePolynomial; +use ark_poly::{Evaluations, GeneralEvaluationDomain}; + +use ark_std::{vec, vec::Vec}; + +use crate::domain::Domain; +use crate::gadgets::{ProverGadget, VerifierGadget}; +use crate::{Column, FieldColumn}; + +/// Does the same as `inner_prod.rs`, but with the witness column reversed. +/// The input vectors keep the normal ordering. The witness column contains +/// the seed at `acc[domain.capacity - 1] = seed` +/// and the inner product result at `acc[0] = seed + `. +pub struct InnerProdInv { + a: FieldColumn, + b: FieldColumn, + not_last: FieldColumn, + pub acc: FieldColumn, +} + +pub struct InnerProdInvValues { + pub a: F, + pub b: F, + pub not_last: F, + pub acc: F, +} + +impl InnerProdInv { + pub fn init(a: FieldColumn, b: FieldColumn, domain: &Domain) -> Self { + // we need an extra slot to seed the partial inner products acc with `0`. + assert_eq!(a.payload_len(), domain.capacity - 1); + assert_eq!(b.payload_len(), domain.capacity - 1); + let inner_prods = Self::partial_inner_prods(a.payload(), b.payload()); + let mut acc = vec![F::zero()]; + acc.extend(inner_prods); + acc.reverse(); + let acc = domain.column(acc); + Self { + a, + b, + not_last: domain.not_last_row.clone(), + acc, + } + } + + /// Returns a[n-1]b[n-1], a[n-1]b[n-1] + a[n-2]b[n-2], ..., a[0]b[0] + a[1]b[1] + ... + a[n-1]b[n-1] + fn partial_inner_prods(a: &[F], b: &[F]) -> Vec { + assert_eq!(a.len(), b.len()); + a.iter().rev() + .zip(b.iter().rev()) + .scan(F::zero(), |state, (&a, b)| { + *state += a * b; + Some(*state) + }) + .collect() + } +} + +impl ProverGadget for InnerProdInv { + fn witness_columns(&self) -> Vec> { + vec![self.acc.poly.clone()] + } + + fn constraints(&self) -> Vec> { + let a = &self.a.evals_4x; + let b = &self.b.evals_4x; + let acc = &self.acc.evals_4x; + let acc_shifted = &self.acc.shifted_4x(); + let not_last = &self.not_last.evals_4x; + let c = &(&(acc - acc_shifted) - &(a * b)) * not_last; + vec![c] + } + + fn constraints_linearized(&self, _z: &F) -> Vec> { + let c = -(&self.acc.poly * self.not_last.evaluate(_z)); + vec![c] + } + + fn domain(&self) -> GeneralEvaluationDomain { + self.a.evals.domain() + } +} + +impl VerifierGadget for InnerProdInvValues { + fn evaluate_constraints_main(&self) -> Vec { + let c = (self.acc - self.a * self.b) * self.not_last; + vec![c] + } +} + +#[cfg(test)] +mod tests { + use ark_ed_on_bls12_381_bandersnatch::Fq; + use ark_ff::{Field, Zero}; + use ark_poly::Polynomial; + use ark_std::test_rng; + + use crate::domain::Domain; + use crate::test_helpers::random_vec; + + use super::*; + + fn inner_prod(a: &[F], b: &[F]) -> F { + assert_eq!(a.len(), b.len()); + a.iter().zip(b).map(|(a, b)| *a * b).sum() + } + + fn _test_inner_prod_inv_gadget(hiding: bool) { + let rng = &mut test_rng(); + + let log_n = 10; + let n = 2usize.pow(log_n); + let domain = Domain::new(n, hiding); + + let a = random_vec(domain.capacity - 1, rng); + let b = random_vec(domain.capacity - 1, rng); + let ab = inner_prod(&a, &b); + let a = domain.column(a); + let b = domain.column(b); + + let gadget = InnerProdInv::::init(a, b, &domain); + + let acc = &gadget.acc.evals.evals; + assert!(acc[domain.capacity - 1].is_zero()); + assert_eq!(acc[0], ab); + + let constraint_poly = gadget.constraints()[0].interpolate_by_ref(); + + assert_eq!(constraint_poly.degree(), 2 * n - 1); + assert!(domain.compute_quotient(&constraint_poly).is_some()); + } + + #[test] + fn test_inner_prod_inv_gadget() { + _test_inner_prod_inv_gadget(false); + _test_inner_prod_inv_gadget(true); + } +} diff --git a/w3f-plonk-common/src/gadgets/mod.rs b/w3f-plonk-common/src/gadgets/mod.rs index 9d8bdf2..5739fce 100644 --- a/w3f-plonk-common/src/gadgets/mod.rs +++ b/w3f-plonk-common/src/gadgets/mod.rs @@ -8,7 +8,10 @@ pub mod booleanity; pub mod column_sum; pub mod ec; pub mod fixed_cells; +pub mod equal_cells; pub mod inner_prod; +pub mod inner_prod_inv; + pub trait ProverGadget { // Columns populated by the gadget. From 795b0f9e83dd50086ecbb0d54057cdb1eb6c076e Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Mon, 25 May 2026 13:07:32 +0300 Subject: [PATCH 06/42] fmt --- pasta-tree/src/circuit/prover.rs | 11 +++++-- pasta-tree/src/circuit/verifier.rs | 4 +-- pasta-tree/src/lib.rs | 6 ++-- w3f-plonk-common/src/gadgets/equal_cells.rs | 29 ++++++++++++++----- .../src/gadgets/inner_prod_inv.rs | 3 +- w3f-plonk-common/src/gadgets/mod.rs | 3 +- 6 files changed, 38 insertions(+), 18 deletions(-) diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit/prover.rs index 1a60206..5011f57 100644 --- a/pasta-tree/src/circuit/prover.rs +++ b/pasta-tree/src/circuit/prover.rs @@ -54,13 +54,20 @@ impl> PiopProver { debug_assert_eq!(selected_node.acc.evals[0], node.x().unwrap()); // here we witness yi let blinded_node = CondAdd::init(bf_bits.clone(), h_powers.clone(), node, &domain); - debug_assert_eq!(blinded_node.seed_plus_sum(), (node + params.h * level.bf).into_affine()); + debug_assert_eq!( + blinded_node.seed_plus_sum(), + (node + params.h * level.bf).into_affine() + ); let node_idx_bool = Booleanity::init(node_idx.clone()); let bf_bits_bool = Booleanity::init(bf_bits.clone()); let node_idx_sum = ColumnSumPolys::init(node_idx.col.clone(), &domain); let node_idx_sum_vals = FixedCells::init(node_idx_sum.acc.clone(), &domain, F::zero(), F::one()); - let seed_eq_node = CellsEqPolys::first_cells(selected_node.acc.clone(), blinded_node.acc.xs.clone(), &domain); + let seed_eq_node = CellsEqPolys::first_cells( + selected_node.acc.clone(), + blinded_node.acc.xs.clone(), + &domain, + ); Self { domain, diff --git a/pasta-tree/src/circuit/verifier.rs b/pasta-tree/src/circuit/verifier.rs index be1f7ac..eefd7a4 100644 --- a/pasta-tree/src/circuit/verifier.rs +++ b/pasta-tree/src/circuit/verifier.rs @@ -1,5 +1,5 @@ -use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::AffineRepr; +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ff::PrimeField; use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; @@ -7,13 +7,13 @@ use w3f_pcs::pcs::Commitment; use crate::circuit::{ProofComms, ProofEvals}; use w3f_plonk_common::domain::EvaluatedDomain; +use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::gadgets::booleanity::BooleanityValues; use w3f_plonk_common::gadgets::column_sum::ColumnSumEvals; use w3f_plonk_common::gadgets::ec::CondAddValues; use w3f_plonk_common::gadgets::equal_cells::EqualCells; use w3f_plonk_common::gadgets::fixed_cells::FixedCellsValues; use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInvValues; -use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::piop::VerifierPiop; pub struct PiopVerifier, G: AffineRepr> { diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 31a1332..322058b 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -250,10 +250,10 @@ mod tests { assert!(valid); } - // cargo test test_proof --release --features="print-trace" -- --show-output - // cargo test test_proof --release --features="print-trace parallel" -- --show-output + // cargo test test_curve_tree_proof --release --features="print-trace" -- --show-output + // cargo test test_curve_tree_proof --release --features="print-trace parallel" -- --show-output #[test] - fn test_proof() { + fn test_curve_tree_proof() { _test_proof::<_, _, PallasConfig, VestaConfig>(8, 4); } diff --git a/w3f-plonk-common/src/gadgets/equal_cells.rs b/w3f-plonk-common/src/gadgets/equal_cells.rs index 691ee2a..0cf5d38 100644 --- a/w3f-plonk-common/src/gadgets/equal_cells.rs +++ b/w3f-plonk-common/src/gadgets/equal_cells.rs @@ -29,7 +29,13 @@ impl CellsEqPolys { Self::cells(a, b, domain.capacity - 1, domain.l_last.clone(), domain) } - pub fn cells(a: FieldColumn, b: FieldColumn, i: usize, li: FieldColumn, domain: &Domain) -> Self { + pub fn cells( + a: FieldColumn, + b: FieldColumn, + i: usize, + li: FieldColumn, + domain: &Domain, + ) -> Self { assert_eq!(a.payload_len(), domain.capacity); assert_eq!(b.payload_len(), domain.capacity); assert_eq!(a.evals.evals[i], b.evals.evals[i]); @@ -48,12 +54,20 @@ impl CellsEqPolys { Self::constraints_lin() } - pub fn first_constraints(a: FieldColumn, b: FieldColumn, domain: &Domain) -> Vec> { + pub fn first_constraints( + a: FieldColumn, + b: FieldColumn, + domain: &Domain, + ) -> Vec> { let gadget = Self::first_cells(a, b, domain); gadget.constraints() } - pub fn last_constraints(a: FieldColumn, b: FieldColumn, domain: &Domain) -> Vec> { + pub fn last_constraints( + a: FieldColumn, + b: FieldColumn, + domain: &Domain, + ) -> Vec> { let gadget = Self::last_cells(a, b, domain); gadget.constraints() } @@ -73,11 +87,10 @@ impl VerifierGadget for EqualCells { #[cfg(test)] mod tests { use super::*; - use ark_ed_on_bls12_381_bandersnatch::Fq; - use ark_std::test_rng; use crate::test_helpers::random_vec; + use ark_ed_on_bls12_381_bandersnatch::Fq; use ark_poly::Polynomial; - + use ark_std::test_rng; fn _test_equal_cells_gadget(hiding: bool) { let rng = &mut test_rng(); @@ -99,7 +112,7 @@ mod tests { let a = random_vec(domain.capacity, rng); let mut b = random_vec(domain.capacity, rng); - b[domain.capacity-1] = a[domain.capacity-1]; + b[domain.capacity - 1] = a[domain.capacity - 1]; let a = domain.column(a); let b = domain.column(b); @@ -114,4 +127,4 @@ mod tests { _test_equal_cells_gadget(false); _test_equal_cells_gadget(true); } -} \ No newline at end of file +} diff --git a/w3f-plonk-common/src/gadgets/inner_prod_inv.rs b/w3f-plonk-common/src/gadgets/inner_prod_inv.rs index 698a234..bbde15f 100644 --- a/w3f-plonk-common/src/gadgets/inner_prod_inv.rs +++ b/w3f-plonk-common/src/gadgets/inner_prod_inv.rs @@ -47,7 +47,8 @@ impl InnerProdInv { /// Returns a[n-1]b[n-1], a[n-1]b[n-1] + a[n-2]b[n-2], ..., a[0]b[0] + a[1]b[1] + ... + a[n-1]b[n-1] fn partial_inner_prods(a: &[F], b: &[F]) -> Vec { assert_eq!(a.len(), b.len()); - a.iter().rev() + a.iter() + .rev() .zip(b.iter().rev()) .scan(F::zero(), |state, (&a, b)| { *state += a * b; diff --git a/w3f-plonk-common/src/gadgets/mod.rs b/w3f-plonk-common/src/gadgets/mod.rs index 5739fce..9fd7d5d 100644 --- a/w3f-plonk-common/src/gadgets/mod.rs +++ b/w3f-plonk-common/src/gadgets/mod.rs @@ -7,12 +7,11 @@ pub mod booleanity; // pub mod inner_prod_pub; pub mod column_sum; pub mod ec; -pub mod fixed_cells; pub mod equal_cells; +pub mod fixed_cells; pub mod inner_prod; pub mod inner_prod_inv; - pub trait ProverGadget { // Columns populated by the gadget. fn witness_columns(&self) -> Vec>; From 92012130f20597d1f64434d8a1e587cdb4b72489 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 26 May 2026 05:57:20 +0300 Subject: [PATCH 07/42] on-curve check --- pasta-tree/src/circuit/prover.rs | 6 ++++- pasta-tree/src/circuit/verifier.rs | 5 ++-- .../src/gadgets/ec/sw_cond_add.rs | 25 ++++++++++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit/prover.rs index 5011f57..66158fb 100644 --- a/pasta-tree/src/circuit/prover.rs +++ b/pasta-tree/src/circuit/prover.rs @@ -58,6 +58,8 @@ impl> PiopProver { blinded_node.seed_plus_sum(), (node + params.h * level.bf).into_affine() ); + debug_assert_eq!(blinded_node.acc.xs.evals[0], node.x().unwrap()); + debug_assert_eq!(blinded_node.acc.ys.evals[0], node.y().unwrap()); let node_idx_bool = Booleanity::init(node_idx.clone()); let bf_bits_bool = Booleanity::init(bf_bits.clone()); let node_idx_sum = ColumnSumPolys::init(node_idx.col.clone(), &domain); @@ -152,7 +154,7 @@ impl> PiopProver { impl, G: SWCurveConfig> ProverPiop for PiopProver> { - const N_CONSTRAINTS: usize = 11; + const N_CONSTRAINTS: usize = 12; type Commitments = ProofComms; type Evaluations = ProofEvals; type Instance = SwAffine; @@ -202,6 +204,7 @@ impl, G: SWCurveConfig> ProverPio F::zero(), )], self.seed_eq_node.constraints(), + vec![self.blinded_node.acc.on_curve_constraint()], ] .concat() } @@ -218,6 +221,7 @@ impl, G: SWCurveConfig> ProverPio vec![DensePolynomial::zero()], vec![DensePolynomial::zero()], self.seed_eq_node.constraints_linearized(zeta), + vec![DensePolynomial::zero()], ] .concat() } diff --git a/pasta-tree/src/circuit/verifier.rs b/pasta-tree/src/circuit/verifier.rs index eefd7a4..e718dee 100644 --- a/pasta-tree/src/circuit/verifier.rs +++ b/pasta-tree/src/circuit/verifier.rs @@ -10,7 +10,7 @@ use w3f_plonk_common::domain::EvaluatedDomain; use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::gadgets::booleanity::BooleanityValues; use w3f_plonk_common::gadgets::column_sum::ColumnSumEvals; -use w3f_plonk_common::gadgets::ec::CondAddValues; +use w3f_plonk_common::gadgets::ec::{AffineColumn, CondAddValues}; use w3f_plonk_common::gadgets::equal_cells::EqualCells; use w3f_plonk_common::gadgets::fixed_cells::FixedCellsValues; use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInvValues; @@ -98,7 +98,7 @@ impl, G: AffineRepr> PiopVerifier impl, G: SWCurveConfig> VerifierPiop for PiopVerifier> { - const N_CONSTRAINTS: usize = 11; + const N_CONSTRAINTS: usize = 12; const N_COLUMNS: usize = 9; fn precommitted_columns(&self) -> Vec { @@ -134,6 +134,7 @@ impl, G: SWCurveConfig> VerifierP F::zero(), )], self.seed_eq_node.evaluate_constraints_main(), + vec![AffineColumn::>::on_curve_eval(self.blinded_node.acc)], ] .concat() } diff --git a/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs b/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs index 0e9470f..af7a0f8 100644 --- a/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs +++ b/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs @@ -4,14 +4,31 @@ use ark_poly::univariate::DensePolynomial; use ark_poly::{Evaluations, GeneralEvaluationDomain}; use ark_std::{vec, vec::Vec}; -use crate::gadgets::ec::{CondAdd, CondAddValues}; +use crate::gadgets::ec::{AffineColumn, CondAdd, CondAddValues}; use crate::gadgets::{ProverGadget, VerifierGadget}; use crate::{const_evals, Column}; +impl> AffineColumn> { + // y^2 = x^3 + ax + b + pub fn on_curve_constraint(&self) -> Evaluations { + let domain = self.xs.domain_4x(); + let sw_coeff_a = &const_evals(Curve::COEFF_A, domain); + let sw_coeff_b = &const_evals(Curve::COEFF_B, domain); + let x = &self.xs.evals_4x; + let y = &self.ys.evals_4x; + + &(&(y * y) - &(&(x * x) * x)) - &(&(sw_coeff_a * x) + &sw_coeff_b) + } + + pub fn on_curve_eval((x, y): (F, F)) -> F { + y * y - x * x * x - Curve::COEFF_A * x - Curve::COEFF_B + } +} + impl ProverGadget for CondAdd> where F: FftField, - Curve: SWCurveConfig, + Curve: SWCurveConfig, { fn witness_columns(&self) -> Vec> { vec![self.acc.xs.poly.clone(), self.acc.ys.poly.clone()] @@ -90,7 +107,7 @@ where } } -impl> CondAddValues> { +impl> CondAddValues> { pub fn acc_coeffs_1(&self) -> (F, F) { let b = self.bitmask; let (x1, _y1) = self.acc; @@ -120,7 +137,7 @@ impl> CondAddValues> { } } -impl> VerifierGadget for CondAddValues> { +impl> VerifierGadget for CondAddValues> { fn evaluate_constraints_main(&self) -> Vec { let b = self.bitmask; let (x1, y1) = self.acc; From b5f05fe9c252a2113c10d0337592c9787e05747f Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 26 May 2026 06:20:47 +0300 Subject: [PATCH 08/42] fmt --- pasta-tree/src/circuit/verifier.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pasta-tree/src/circuit/verifier.rs b/pasta-tree/src/circuit/verifier.rs index e718dee..6414958 100644 --- a/pasta-tree/src/circuit/verifier.rs +++ b/pasta-tree/src/circuit/verifier.rs @@ -134,7 +134,9 @@ impl, G: SWCurveConfig> VerifierP F::zero(), )], self.seed_eq_node.evaluate_constraints_main(), - vec![AffineColumn::>::on_curve_eval(self.blinded_node.acc)], + vec![AffineColumn::>::on_curve_eval( + self.blinded_node.acc, + )], ] .concat() } From 683d19f7e9a304c77bd4ad7c350c55f985d3957f Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 26 May 2026 06:24:19 +0300 Subject: [PATCH 09/42] fmt --- w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs b/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs index af7a0f8..c13981b 100644 --- a/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs +++ b/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs @@ -8,7 +8,7 @@ use crate::gadgets::ec::{AffineColumn, CondAdd, CondAddValues}; use crate::gadgets::{ProverGadget, VerifierGadget}; use crate::{const_evals, Column}; -impl> AffineColumn> { +impl> AffineColumn> { // y^2 = x^3 + ax + b pub fn on_curve_constraint(&self) -> Evaluations { let domain = self.xs.domain_4x(); @@ -28,7 +28,7 @@ impl> AffineColumn ProverGadget for CondAdd> where F: FftField, - Curve: SWCurveConfig, + Curve: SWCurveConfig, { fn witness_columns(&self) -> Vec> { vec![self.acc.xs.poly.clone(), self.acc.ys.poly.clone()] @@ -107,7 +107,7 @@ where } } -impl> CondAddValues> { +impl> CondAddValues> { pub fn acc_coeffs_1(&self) -> (F, F) { let b = self.bitmask; let (x1, _y1) = self.acc; @@ -137,7 +137,7 @@ impl> CondAddValues> { } } -impl> VerifierGadget for CondAddValues> { +impl> VerifierGadget for CondAddValues> { fn evaluate_constraints_main(&self) -> Vec { let b = self.bitmask; let (x1, y1) = self.acc; From 6bcd9ec904845f3ac6b94b31da791a8e189aeb06 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 26 May 2026 08:53:44 +0300 Subject: [PATCH 10/42] al's constraint --- pasta-tree/src/circuit/params.rs | 10 ++++++---- pasta-tree/src/circuit/prover.rs | 12 +++++++++++- pasta-tree/src/circuit/verifier.rs | 7 ++++++- w3f-plonk-common/src/domain.rs | 2 +- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/pasta-tree/src/circuit/params.rs b/pasta-tree/src/circuit/params.rs index 2dd03c5..d0dd115 100644 --- a/pasta-tree/src/circuit/params.rs +++ b/pasta-tree/src/circuit/params.rs @@ -1,4 +1,5 @@ use ark_ec::{AffineRepr, CurveGroup}; +use ark_ff::One; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; use ark_std::{vec, vec::Vec}; @@ -36,8 +37,9 @@ impl> PiopParams { let c = self.children_capacity(); assert!(x_coords.len() <= c); let mut x_coords = x_coords; - x_coords.resize(c, G::BaseField::zero()); // the last `(zk_rows + 1)` cells will be padded by the iFFT - self.domain.public_column(x_coords) + x_coords.resize(self.domain.domain_size(), G::BaseField::zero()); + x_coords[c] = G::BaseField::one(); + self.domain.domains.column_from_evals(x_coords, c) } pub fn h_powers_column(&self) -> AffineColumn { @@ -60,7 +62,7 @@ impl> PiopParams { BitColumn::init(bf_bits, &self.domain) } - pub fn power_of_2_multiples_of_h(&self) -> Vec { + fn power_of_2_multiples_of_h(&self) -> Vec { let mut h = self.h.into_group(); let mut multiples = Vec::with_capacity(self.scalar_bitlen); multiples.push(h); @@ -71,7 +73,7 @@ impl> PiopParams { CurveGroup::normalize_batch(&multiples) } - pub fn scalar_part(&self, e: G::ScalarField) -> Vec { + fn scalar_part(&self, e: G::ScalarField) -> Vec { let bits_with_trailing_zeroes = e.into_bigint().to_bits_le(); let significant_bits = &bits_with_trailing_zeroes[..self.scalar_bitlen]; significant_bits.to_vec() diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit/prover.rs index 66158fb..96c169e 100644 --- a/pasta-tree/src/circuit/prover.rs +++ b/pasta-tree/src/circuit/prover.rs @@ -154,7 +154,7 @@ impl> PiopProver { impl, G: SWCurveConfig> ProverPiop for PiopProver> { - const N_CONSTRAINTS: usize = 12; + const N_CONSTRAINTS: usize = 13; type Commitments = ProofComms; type Evaluations = ProofEvals; type Instance = SwAffine; @@ -205,6 +205,15 @@ impl, G: SWCurveConfig> ProverPio )], self.seed_eq_node.constraints(), vec![self.blinded_node.acc.on_curve_constraint()], + // this prevents opening to -parent=(x,-y) + // parent = commit([x1, ..., xl, 1, 0, 0, 0]; 0) = x1.G1 + ... + xl.Gl + 1.G_{l+1} + // then -parent = commit([-x1, ..., -xl, -1, 0, 0, 0]; 0) + vec![FixedCells::constraint_cell( + &self.nodes, + &self.domain.l_last, + self.domain.capacity - 1, + F::one(), + )], ] .concat() } @@ -222,6 +231,7 @@ impl, G: SWCurveConfig> ProverPio vec![DensePolynomial::zero()], self.seed_eq_node.constraints_linearized(zeta), vec![DensePolynomial::zero()], + vec![DensePolynomial::zero()], ] .concat() } diff --git a/pasta-tree/src/circuit/verifier.rs b/pasta-tree/src/circuit/verifier.rs index 6414958..0a53eea 100644 --- a/pasta-tree/src/circuit/verifier.rs +++ b/pasta-tree/src/circuit/verifier.rs @@ -98,7 +98,7 @@ impl, G: AffineRepr> PiopVerifier impl, G: SWCurveConfig> VerifierPiop for PiopVerifier> { - const N_CONSTRAINTS: usize = 12; + const N_CONSTRAINTS: usize = 13; const N_COLUMNS: usize = 9; fn precommitted_columns(&self) -> Vec { @@ -137,6 +137,11 @@ impl, G: SWCurveConfig> VerifierP vec![AffineColumn::>::on_curve_eval( self.blinded_node.acc, )], + vec![FixedCellsValues::evaluate_for_cell( + self.selected_node.a, + self.domain_evals.l_last, + F::one(), + )], ] .concat() } diff --git a/w3f-plonk-common/src/domain.rs b/w3f-plonk-common/src/domain.rs index ab6af0b..b7858f6 100644 --- a/w3f-plonk-common/src/domain.rs +++ b/w3f-plonk-common/src/domain.rs @@ -25,7 +25,7 @@ impl Domains { Self { x1, x4 } } - fn column_from_evals(&self, padded_evals: Vec, payload_len: usize) -> FieldColumn { + pub fn column_from_evals(&self, padded_evals: Vec, payload_len: usize) -> FieldColumn { debug_assert_eq!(padded_evals.len(), self.x1.size()); let evals = Evaluations::from_vec_and_domain(padded_evals, self.x1); let poly = evals.interpolate_by_ref(); From d6d90d1e1a77f8214b445052c11d791277b94181 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 26 May 2026 22:20:17 +0300 Subject: [PATCH 11/42] another long circuit --- pasta-tree/src/circuit/mod.rs | 2 +- pasta-tree/src/circuit/params.rs | 10 +- pasta-tree/src/circuit/prover.rs | 3 +- pasta-tree/src/circuit2/mod.rs | 52 +++++ pasta-tree/src/circuit2/params.rs | 97 +++++++++ pasta-tree/src/circuit2/prover.rs | 212 ++++++++++++++++++++ pasta-tree/src/circuit2/verifier.rs | 154 ++++++++++++++ pasta-tree/src/lib.rs | 8 +- w3f-plonk-common/src/gadgets/booleanity.rs | 18 +- w3f-plonk-common/src/gadgets/fixed_cells.rs | 36 ++-- 10 files changed, 564 insertions(+), 28 deletions(-) create mode 100644 pasta-tree/src/circuit2/mod.rs create mode 100644 pasta-tree/src/circuit2/params.rs create mode 100644 pasta-tree/src/circuit2/prover.rs create mode 100644 pasta-tree/src/circuit2/verifier.rs diff --git a/pasta-tree/src/circuit/mod.rs b/pasta-tree/src/circuit/mod.rs index 3bb3410..c7fab85 100644 --- a/pasta-tree/src/circuit/mod.rs +++ b/pasta-tree/src/circuit/mod.rs @@ -32,7 +32,7 @@ impl> ColumnsCommited for ProofComms } } -#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct ProofEvals { pub(crate) x_coords: F, pub(crate) h_powers: [F; 2], diff --git a/pasta-tree/src/circuit/params.rs b/pasta-tree/src/circuit/params.rs index d0dd115..67fa024 100644 --- a/pasta-tree/src/circuit/params.rs +++ b/pasta-tree/src/circuit/params.rs @@ -29,12 +29,12 @@ impl> PiopParams { } } - pub fn children_capacity(&self) -> usize { + pub fn max_nodes(&self) -> usize { self.domain.capacity - 1 } pub fn x_coords_column(&self, x_coords: Vec) -> FieldColumn { - let c = self.children_capacity(); + let c = self.max_nodes(); assert!(x_coords.len() <= c); let mut x_coords = x_coords; x_coords.resize(self.domain.domain_size(), G::BaseField::zero()); @@ -44,12 +44,12 @@ impl> PiopParams { pub fn h_powers_column(&self) -> AffineColumn { let mut h_powers = self.power_of_2_multiples_of_h(); - h_powers.truncate(self.children_capacity()); + h_powers.truncate(self.max_nodes()); AffineColumn::public_column(h_powers, &self.domain) } pub fn node_selector(&self, node_index: usize) -> BitColumn { - let c = self.children_capacity(); + let c = self.max_nodes(); let mut node_selector = vec![false; c]; assert!(node_index < c); // allows to select a padding node node_selector[node_index] = true; @@ -58,7 +58,7 @@ impl> PiopParams { pub fn bf_bits_column(&self, bf: G::ScalarField) -> BitColumn { let mut bf_bits = self.scalar_part(bf); - bf_bits.truncate(self.children_capacity()); + bf_bits.truncate(self.max_nodes()); BitColumn::init(bf_bits, &self.domain) } diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit/prover.rs index 96c169e..9d32130 100644 --- a/pasta-tree/src/circuit/prover.rs +++ b/pasta-tree/src/circuit/prover.rs @@ -267,7 +267,8 @@ mod tests { let blinded_node = (node + h * bf).into_affine(); let piop_params = PiopParams::setup(domain, h); - let witness = random_witness(&piop_params, node, rng).with_blinding(bf, Fq::zero()); + let witness = + random_witness(piop_params.max_nodes(), node, rng).with_blinding(bf, Fq::zero()); let piop = PiopProver::build(&piop_params, witness); assert!(ProverPiop::<_, IPACommitment>::constraints_satisfied(&piop)); diff --git a/pasta-tree/src/circuit2/mod.rs b/pasta-tree/src/circuit2/mod.rs new file mode 100644 index 0000000..4b1afc5 --- /dev/null +++ b/pasta-tree/src/circuit2/mod.rs @@ -0,0 +1,52 @@ +use ark_ff::PrimeField; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::marker::PhantomData; +use ark_std::{vec, vec::Vec}; +use w3f_pcs::pcs::Commitment; +use w3f_plonk_common::{ColumnsCommited, ColumnsEvaluated}; + +pub mod params; +pub mod prover; +pub mod verifier; + +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] +pub struct ProofComms> { + pub(crate) bits: C, + pub(crate) inn_prod_acc: C, + pub(crate) cond_add_acc: [C; 2], + pub(crate) phantom: PhantomData, +} + +impl> ColumnsCommited for ProofComms { + fn to_vec(self) -> Vec { + vec![ + self.bits, + self.inn_prod_acc, + self.cond_add_acc[0].clone(), + self.cond_add_acc[1].clone(), + ] + } +} + +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] +pub struct ProofEvals { + pub(crate) points: [F; 2], + pub(crate) ring_selector: F, + pub(crate) bits: F, + pub(crate) inn_prod_acc: F, + pub(crate) cond_add_acc: [F; 2], +} + +impl ColumnsEvaluated for ProofEvals { + fn to_vec(self) -> Vec { + vec![ + self.points[0], + self.points[1], + self.ring_selector, + self.bits, + self.inn_prod_acc, + self.cond_add_acc[0], + self.cond_add_acc[1], + ] + } +} diff --git a/pasta-tree/src/circuit2/params.rs b/pasta-tree/src/circuit2/params.rs new file mode 100644 index 0000000..d3b1c39 --- /dev/null +++ b/pasta-tree/src/circuit2/params.rs @@ -0,0 +1,97 @@ +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +use ark_ec::{AffineRepr, CurveGroup}; +use ark_ff::One; +use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; +use ark_std::{vec, vec::Vec}; + +use w3f_plonk_common::FieldColumn; +use w3f_plonk_common::domain::Domain; +use w3f_plonk_common::gadgets::booleanity::BitColumn; +use w3f_plonk_common::gadgets::ec::AffineColumn; + +/// Plonk Interactive Oracle Proofs (PIOP) parameters. +#[derive(Clone)] +pub struct PiopParams> { + /// Domain over which the piop is represented. + pub domain: Domain, + pub select_size: usize, + /// Number of bits used to represent a scalar. + pub rerand_size: usize, + pub seed: G, + /// Blinding base point. + pub h: G, +} + +impl> PiopParams> { + pub fn setup(domain: Domain, h: SwAffine, seed: SwAffine) -> Self { + assert!(domain.domain_size() > 256); + let actual_capacity = domain.capacity - 1; + let scalar_size = Domain::::new(256, domain.is_hiding()).capacity - 1; + let rerand_size = ark_std::cmp::min(G::ScalarField::MODULUS_BIT_SIZE as usize, scalar_size); + let select_size = actual_capacity - rerand_size; + Self { + domain, + select_size, + rerand_size, + seed, + h, + } + } + + pub fn max_nodes(&self) -> usize { + self.select_size + } + + pub fn points_column( + &self, + nodes: Vec>, + ) -> AffineColumn> { + assert!(nodes.len() <= self.select_size); + let mut points = nodes; + let zero = SwAffine::::new_unchecked(G::BaseField::ZERO, G::BaseField::ZERO); + points.resize(self.select_size, zero); + let powers_of_h = self.power_of_h(); + assert_eq!(powers_of_h.len(), self.rerand_size); + points.extend(powers_of_h); + // let flag = SwAffine::::new_unchecked(G::BaseField::ONE, G::BaseField::ZERO); + // points.push(flag); + AffineColumn::public_column(points, &self.domain) + } + + pub fn bits_column(&self, node_index: usize, bf: G::ScalarField) -> BitColumn { + let mut bits = vec![false; self.select_size]; + assert!(node_index < self.select_size); // allows to select a padding node + bits[node_index] = true; + bits.extend(self.scalar_part(bf)); + BitColumn::init(bits, &self.domain) + } + + pub fn select_part(&self) -> FieldColumn { + let selector = [ + vec![G::BaseField::one(); self.select_size], + vec![G::BaseField::zero(); self.rerand_size], + ] + .concat(); + self.domain.public_column(selector) + } + + fn power_of_h(&self) -> Vec> { + let mut h = self.h.into_group(); + let mut res = Vec::with_capacity(self.rerand_size); + res.push(h); + for _ in 1..self.rerand_size { + h.double_in_place(); + res.push(h); + } + CurveGroup::normalize_batch(&res) + } + + fn scalar_part(&self, e: G::ScalarField) -> Vec { + let bits_with_trailing_zeroes = e.into_bigint().to_bits_le(); + let significant_bits = &bits_with_trailing_zeroes[..self.rerand_size]; + significant_bits.to_vec() + } +} + +#[cfg(test)] +mod tests {} diff --git a/pasta-tree/src/circuit2/prover.rs b/pasta-tree/src/circuit2/prover.rs new file mode 100644 index 0000000..b906e90 --- /dev/null +++ b/pasta-tree/src/circuit2/prover.rs @@ -0,0 +1,212 @@ +use crate::auth_path::node::LevelWitnessWithBlinding; +use crate::circuit2::params::PiopParams; +use crate::circuit2::{ProofComms, ProofEvals}; +use ark_ec::AffineRepr; +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +use ark_ff::PrimeField; +use ark_poly::Evaluations; +use ark_poly::Polynomial; +use ark_poly::univariate::DensePolynomial; +use ark_std::marker::PhantomData; +use ark_std::{vec, vec::Vec}; +use w3f_pcs::pcs::Commitment; +use w3f_plonk_common::FieldColumn; +use w3f_plonk_common::domain::Domain; +use w3f_plonk_common::gadgets::ProverGadget; +use w3f_plonk_common::gadgets::booleanity::{BitColumn, Booleanity}; +use w3f_plonk_common::gadgets::ec::AffineColumn; +use w3f_plonk_common::gadgets::ec::CondAdd; +use w3f_plonk_common::gadgets::fixed_cells::FixedCells; +use w3f_plonk_common::gadgets::inner_prod::InnerProd; +use w3f_plonk_common::piop::ProverPiop; + +// struct Witness> { +// // `x` coordinates of all the children of a node. Public input. +// // `H, 2H, 4H,...,2^sH` Fixed column. +// points: AffineColumn, +// // `node_x = self.x_coords[self.node_idx]` Private input. +// // Bits of the chosen blinding factor. Private input. +// bits: BitColumn, +// select_part: FieldColumn, +// inner_prod_acc: DensePolynomial, +// cond_add_acc_x: DensePolynomial, +// cond_add_acc_y: DensePolynomial, +// } + +pub struct PiopProver> { + domain: Domain, + // `x` coordinates of all the children of a node. Public input. + // `H, 2H, 4H,...,2^sH` Fixed column. + points: AffineColumn, + // `node_x = self.x_coords[self.node_idx]` Private input. + // Bits of the chosen blinding factor. Private input. + bits: BitColumn, + select_part: FieldColumn, + inner_prod_acc: DensePolynomial, + cond_add_acc_x: DensePolynomial, + cond_add_acc_y: DensePolynomial, + // columns: Witness, + gadgets: Vec>>, + result: G, +} + +impl> PiopProver> { + pub fn build( + params: &PiopParams>, + level: LevelWitnessWithBlinding>, + ) -> Self { + let domain = params.domain.clone(); + let points = params.points_column(level.level_witness.siblings); + let bits = params.bits_column(level.level_witness.path_node_idx, level.bf); + let bits_bool = Booleanity::init(bits.clone()); + let select_part = params.select_part(); + let inner_prod = InnerProd::init(select_part.clone(), bits.col.clone(), &domain); + let inner_prod_vals = + FixedCells::init(inner_prod.acc.clone(), &domain, F::zero(), F::one()); + let cond_add = CondAdd::init(bits.clone(), points.clone(), params.seed, &domain); + let (seed_x, seed_y) = params.seed.xy().unwrap(); + let (result_x, result_y) = cond_add.seed_plus_sum().xy().unwrap(); + let cond_add_vals_x = FixedCells::init(cond_add.acc.xs.clone(), &domain, seed_x, result_x); + let cond_add_vals_y = FixedCells::init(cond_add.acc.ys.clone(), &domain, seed_y, result_y); + + let inner_prod_acc = inner_prod.acc.as_poly().clone(); + let cond_add_acc_x = cond_add.acc.xs.as_poly().clone(); + let cond_add_acc_y = cond_add.acc.ys.as_poly().clone(); + let result = cond_add.result(); + + let mut gadgets: Vec>> = Vec::new(); + gadgets.push(Box::new(bits_bool)); + gadgets.push(Box::new(inner_prod)); + gadgets.push(Box::new(inner_prod_vals)); + gadgets.push(Box::new(cond_add)); + gadgets.push(Box::new(cond_add_vals_x)); + gadgets.push(Box::new(cond_add_vals_y)); + + Self { + domain, + + points, + bits, + select_part, + + gadgets, + inner_prod_acc, + cond_add_acc_x, + cond_add_acc_y, + result, + } + } +} + +impl, G: SWCurveConfig> ProverPiop + for PiopProver> +{ + const N_CONSTRAINTS: usize = 7; + type Commitments = ProofComms; + type Evaluations = ProofEvals; + type Instance = SwAffine; + + fn committed_columns) -> C>( + &self, + commit: Fun, + ) -> Self::Commitments { + let bits = commit(self.bits.as_poly()); + let cond_add_acc = [commit(&self.cond_add_acc_x), commit(&self.cond_add_acc_y)]; + let inn_prod_acc = commit(&self.inner_prod_acc); + ProofComms { + bits, + cond_add_acc, + inn_prod_acc, + phantom: PhantomData, + } + } + + // Should return polynomials in the consistent with + // Self::Evaluations::to_vec() and Self::Commitments::to_vec(). + fn columns(&self) -> Vec> { + vec![ + self.points.xs.as_poly().clone(), + self.points.ys.as_poly().clone(), + self.select_part.as_poly().clone(), + self.bits.as_poly().clone(), + self.inner_prod_acc.clone(), + self.cond_add_acc_x.clone(), + self.cond_add_acc_y.clone(), + ] + } + + fn columns_evaluated(&self, zeta: &F) -> ProofEvals { + let points = [self.points.xs.evaluate(zeta), self.points.ys.evaluate(zeta)]; + let ring_selector = self.select_part.evaluate(zeta); + let bits = self.bits.evaluate(zeta); + let inn_prod_acc = self.inner_prod_acc.evaluate(zeta); + let cond_add_acc = [ + self.cond_add_acc_x.evaluate(zeta), + self.cond_add_acc_y.evaluate(zeta), + ]; + ProofEvals { + points, + ring_selector, + bits, + inn_prod_acc, + cond_add_acc, + } + } + + fn constraints(&self) -> Vec> { + self.gadgets.iter().flat_map(|g| g.constraints()).collect() + } + + fn constraints_lin(&self, zeta: &F) -> Vec> { + self.gadgets + .iter() + .flat_map(|g| g.constraints_linearized(zeta)) + .collect() + } + + fn domain(&self) -> &Domain { + &self.domain + } + + fn result(&self) -> Self::Instance { + self.result + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::IPACommitment; + use crate::tests::random_witness; + use ark_bls12_381::G1Projective; + use ark_ec::CurveGroup; + use ark_ff::Zero; + + use ark_ed_on_bls12_381_bandersnatch::{Fq, Fr, SWAffine}; + use ark_std::{UniformRand, test_rng}; + + #[test] + fn test_constraints() { + let rng = &mut test_rng(); + + let domain_size = 512; + let domain = Domain::::new(domain_size, true); + + let node = SWAffine::rand(rng); + let h = SWAffine::rand(rng); + let seed = SWAffine::rand(rng); + let bf = Fr::from(u128::rand(rng)); + let blinded_node = (node + h * bf).into_affine(); + + let piop_params = PiopParams::setup(domain, h, seed); + let witness = + random_witness(piop_params.max_nodes(), node, rng).with_blinding(bf, Fq::zero()); + let piop = PiopProver::build(&piop_params, witness); + + assert!(ProverPiop::<_, IPACommitment>::constraints_satisfied(&piop)); + assert_eq!( + ProverPiop::<_, IPACommitment>::result(&piop), + blinded_node + ); + } +} diff --git a/pasta-tree/src/circuit2/verifier.rs b/pasta-tree/src/circuit2/verifier.rs new file mode 100644 index 0000000..d82ef25 --- /dev/null +++ b/pasta-tree/src/circuit2/verifier.rs @@ -0,0 +1,154 @@ +use ark_ec::AffineRepr; +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +use ark_ff::PrimeField; +use ark_std::marker::PhantomData; +use ark_std::{vec, vec::Vec}; +use w3f_pcs::pcs::Commitment; + +use crate::circuit2::{ProofComms, ProofEvals}; +use w3f_plonk_common::domain::EvaluatedDomain; +use w3f_plonk_common::gadgets::VerifierGadget; +use w3f_plonk_common::gadgets::booleanity::BooleanityValues; +use w3f_plonk_common::gadgets::ec::CondAddValues; +use w3f_plonk_common::gadgets::fixed_cells::FixedCellsValues; +use w3f_plonk_common::gadgets::inner_prod::InnerProdValues; +use w3f_plonk_common::piop::VerifierPiop; + +pub struct PiopVerifier, G: AffineRepr> { + domain_evals: EvaluatedDomain, + + points_x: C, + points_y: C, + select_part: C, + witness_cols: ProofComms, + + // Gadget verifiers: + booleanity: BooleanityValues, + inner_prod: InnerProdValues, + inner_prod_acc: FixedCellsValues, + cond_add: CondAddValues, + cond_add_acc_x: FixedCellsValues, + cond_add_acc_y: FixedCellsValues, +} + +impl, G: AffineRepr> PiopVerifier { + pub fn init( + domain_evals: EvaluatedDomain, + points_x: C, + points_y: C, + select_part: C, + witness_cols: ProofComms, + evals: ProofEvals, + seed: G, + result: G, + ) -> Self { + let cond_add = CondAddValues { + bitmask: evals.bits, + points: (evals.points[0], evals.points[1]), + not_last: domain_evals.not_last_row, + acc: (evals.cond_add_acc[0], evals.cond_add_acc[1]), + _phantom: PhantomData, + }; + + let inner_prod = InnerProdValues { + a: evals.ring_selector, + b: evals.bits, + not_last: domain_evals.not_last_row, + acc: evals.inn_prod_acc, + }; + + let booleanity = BooleanityValues { bits: evals.bits }; + + let (seed_x, seed_y) = seed.xy().unwrap(); + let (result_x, result_y) = result.xy().unwrap(); + + let cond_add_acc_x = FixedCellsValues { + col: evals.cond_add_acc[0], + col_first: seed_x, + col_last: result_x, + l_first: domain_evals.l_first, + l_last: domain_evals.l_last, + }; + + let cond_add_acc_y = FixedCellsValues { + col: evals.cond_add_acc[1], + col_first: seed_y, + col_last: result_y, + l_first: domain_evals.l_first, + l_last: domain_evals.l_last, + }; + + let inner_prod_acc = FixedCellsValues { + col: evals.inn_prod_acc, + col_first: F::zero(), + col_last: F::one(), + l_first: domain_evals.l_first, + l_last: domain_evals.l_last, + }; + + Self { + domain_evals, + points_x, + points_y, + select_part, + witness_cols, + booleanity, + inner_prod, + inner_prod_acc, + cond_add, + cond_add_acc_x, + cond_add_acc_y, + } + } +} + +impl, G: SWCurveConfig> VerifierPiop + for PiopVerifier> +{ + const N_CONSTRAINTS: usize = 7; + const N_COLUMNS: usize = 7; + + fn precommitted_columns(&self) -> Vec { + vec![ + self.points_x.clone(), + self.points_y.clone(), + self.select_part.clone(), + ] + } + + 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, alphas: &[F]) -> (Vec, Vec) { + assert_eq!(alphas.len(), Self::N_CONSTRAINTS); + + let inner_prod_acc = self.witness_cols.inn_prod_acc.clone(); + let inner_prod_coeff = alphas[0] * self.inner_prod.not_last; + + let cond_add_acc_x = self.witness_cols.cond_add_acc[0].clone(); + let cond_add_acc_y = self.witness_cols.cond_add_acc[1].clone(); + let (c_acc_x, c_acc_y) = self.cond_add.acc_coeffs_1(); + let mut cond_add_x_coeff = alphas[1] * c_acc_x; + let mut cond_add_y_coeff = alphas[1] * c_acc_y; + let (c_acc_x, c_acc_y) = self.cond_add.acc_coeffs_2(); + cond_add_x_coeff += alphas[2] * c_acc_x; + cond_add_y_coeff += alphas[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 + } +} diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 322058b..a303af6 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -13,6 +13,7 @@ use w3f_plonk_common::domain::Domain; pub mod auth_path; pub mod circuit; +pub mod circuit2; // pub mod level; pub mod prover; pub mod verifier; @@ -152,11 +153,10 @@ mod tests { type PallasIPA = IPA; pub fn random_witness, R: Rng>( - piop_params: &PiopParams, + capacity: usize, path_node: G, rng: &mut R, ) -> LevelWitness { - let capacity = piop_params.children_capacity(); let mut nodes = random_vec::(capacity, rng); let i = rng.gen_range(0..capacity); nodes[i] = path_node; @@ -171,7 +171,7 @@ mod tests { path_node: G, rng: &mut R, ) -> (C::Affine, LevelWitness) { - let level_witness = random_witness(¶ms.piop_params, path_node, rng); + let level_witness = random_witness(params.piop_params.max_nodes(), path_node, rng); let parent = level_witness.compute_parent(params).unwrap(); (parent, level_witness) } @@ -234,7 +234,7 @@ mod tests { _ => panic!(), }; - let capacity = params.c0_params.piop_params.children_capacity(); + let capacity = params.c0_params.piop_params.max_nodes(); let t_prove = start_timer!(|| format!( "Proving CurveTree membership, H={height}, M={}, C={}, C^{height}={}", domain_size, diff --git a/w3f-plonk-common/src/gadgets/booleanity.rs b/w3f-plonk-common/src/gadgets/booleanity.rs index e8fa94e..001041b 100644 --- a/w3f-plonk-common/src/gadgets/booleanity.rs +++ b/w3f-plonk-common/src/gadgets/booleanity.rs @@ -5,7 +5,7 @@ use ark_poly::{Evaluations, GeneralEvaluationDomain, Polynomial}; use ark_std::{vec, vec::Vec}; use crate::domain::Domain; -use crate::gadgets::VerifierGadget; +use crate::gadgets::{ProverGadget, VerifierGadget}; use crate::{const_evals, Column, FieldColumn}; #[derive(Clone)] @@ -51,12 +51,18 @@ pub struct Booleanity { bits: BitColumn, } -impl<'a, F: FftField> Booleanity { +impl Booleanity { pub fn init(bits: BitColumn) -> Self { Self { bits } } +} + +impl ProverGadget for Booleanity { + fn witness_columns(&self) -> Vec> { + todo!() + } - pub fn constraints(&self) -> Vec> { + fn constraints(&self) -> Vec> { let mut c = const_evals(F::one(), self.bits.domain_4x()); // c = 1 let b = &self.bits.col.evals_4x; c -= b; // c = 1 - b @@ -64,9 +70,13 @@ impl<'a, F: FftField> Booleanity { vec![c] } - pub fn constraints_linearized(&self, _z: &F) -> Vec> { + fn constraints_linearized(&self, _z: &F) -> Vec> { vec![DensePolynomial::zero()] } + + fn domain(&self) -> GeneralEvaluationDomain { + todo!() + } } pub struct BooleanityValues { diff --git a/w3f-plonk-common/src/gadgets/fixed_cells.rs b/w3f-plonk-common/src/gadgets/fixed_cells.rs index 35eec37..d4d5ca0 100644 --- a/w3f-plonk-common/src/gadgets/fixed_cells.rs +++ b/w3f-plonk-common/src/gadgets/fixed_cells.rs @@ -1,11 +1,11 @@ use ark_ff::{FftField, Field, Zero}; use ark_poly::univariate::DensePolynomial; -use ark_poly::Evaluations; +use ark_poly::{Evaluations, GeneralEvaluationDomain}; use ark_std::{vec, vec::Vec}; use crate::domain::Domain; -use crate::gadgets::VerifierGadget; +use crate::gadgets::{ProverGadget, VerifierGadget}; use crate::{const_evals, Column, FieldColumn}; pub struct FixedCells { @@ -45,17 +45,6 @@ impl FixedCells { } } - pub fn constraints(&self) -> Vec> { - let domain_capacity = self.col.payload_len(); // that's an ugly way to learn the capacity, but we've asserted it above. - let c = &Self::constraint_cell(&self.col, &self.l_first, 0, self.col_first) - + &Self::constraint_cell(&self.col, &self.l_last, domain_capacity - 1, self.col_last); - vec![c] - } - - pub fn constraints_linearized(&self, _z: &F) -> Vec> { - vec![DensePolynomial::zero()] - } - /// Constraints the column `col` to have the value `col[i]` at index `i`. /// `li` should be the `i-th` Lagrange basis polynomial `li = L_i(X)`. /// The constraint polynomial is `c(X) = L_i(X).col(X) - col[i].L_i(X)`. @@ -74,6 +63,27 @@ impl FixedCells { } } +impl ProverGadget for FixedCells { + fn witness_columns(&self) -> Vec> { + todo!() + } + + fn constraints(&self) -> Vec> { + let domain_capacity = self.col.payload_len(); // that's an ugly way to learn the capacity, but we've asserted it above. + let c = &Self::constraint_cell(&self.col, &self.l_first, 0, self.col_first) + + &Self::constraint_cell(&self.col, &self.l_last, domain_capacity - 1, self.col_last); + vec![c] + } + + fn constraints_linearized(&self, _z: &F) -> Vec> { + vec![DensePolynomial::zero()] + } + + fn domain(&self) -> GeneralEvaluationDomain { + todo!() + } +} + impl FixedCellsValues { pub fn evaluate_for_cell(col_eval: F, li_eval: F, cell_val: F) -> F { li_eval * (col_eval - cell_val) From f6b674eb5e03683a1cad2342e4b8cc7d4259e240 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Wed, 27 May 2026 02:07:04 +0300 Subject: [PATCH 12/42] circuit2 works --- pasta-tree/src/auth_path/node.rs | 3 +- pasta-tree/src/circuit2/mod.rs | 4 +- pasta-tree/src/circuit2/params.rs | 35 +++++++++++----- pasta-tree/src/circuit2/prover.rs | 8 ++-- pasta-tree/src/circuit2/verifier.rs | 16 +++----- pasta-tree/src/lib.rs | 62 ++++++++++++++++++----------- pasta-tree/src/prover.rs | 13 ++++-- pasta-tree/src/verifier.rs | 25 +++++++----- 8 files changed, 104 insertions(+), 62 deletions(-) diff --git a/pasta-tree/src/auth_path/node.rs b/pasta-tree/src/auth_path/node.rs index 96ef397..1911ddf 100644 --- a/pasta-tree/src/auth_path/node.rs +++ b/pasta-tree/src/auth_path/node.rs @@ -71,7 +71,8 @@ impl LevelWitness { where G::BaseField: PrimeField, { - params.commit_x_coords(self.x_coords(), bf).map(|c| c.0) + // params.commit_x_coords(self.x_coords(), bf).map(|c| c.0) + params.commit_nodes(self.siblings.clone(), bf).map(|c| c.0) } } diff --git a/pasta-tree/src/circuit2/mod.rs b/pasta-tree/src/circuit2/mod.rs index 4b1afc5..9189c11 100644 --- a/pasta-tree/src/circuit2/mod.rs +++ b/pasta-tree/src/circuit2/mod.rs @@ -11,6 +11,7 @@ pub mod verifier; #[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct ProofComms> { + pub(crate) points_y: C, pub(crate) bits: C, pub(crate) inn_prod_acc: C, pub(crate) cond_add_acc: [C; 2], @@ -20,6 +21,7 @@ pub struct ProofComms> { impl> ColumnsCommited for ProofComms { fn to_vec(self) -> Vec { vec![ + self.points_y, self.bits, self.inn_prod_acc, self.cond_add_acc[0].clone(), @@ -41,8 +43,8 @@ impl ColumnsEvaluated for ProofEvals { fn to_vec(self) -> Vec { vec![ self.points[0], - self.points[1], self.ring_selector, + self.points[1], self.bits, self.inn_prod_acc, self.cond_add_acc[0], diff --git a/pasta-tree/src/circuit2/params.rs b/pasta-tree/src/circuit2/params.rs index d3b1c39..5f1a04e 100644 --- a/pasta-tree/src/circuit2/params.rs +++ b/pasta-tree/src/circuit2/params.rs @@ -1,9 +1,7 @@ -use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::One; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; use ark_std::{vec, vec::Vec}; - use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; @@ -22,8 +20,8 @@ pub struct PiopParams> { pub h: G, } -impl> PiopParams> { - pub fn setup(domain: Domain, h: SwAffine, seed: SwAffine) -> Self { +impl> PiopParams { + pub fn setup(domain: Domain, h: G, seed: G) -> Self { assert!(domain.domain_size() > 256); let actual_capacity = domain.capacity - 1; let scalar_size = Domain::::new(256, domain.is_hiding()).capacity - 1; @@ -42,13 +40,11 @@ impl> PiopParams> { self.select_size } - pub fn points_column( - &self, - nodes: Vec>, - ) -> AffineColumn> { + pub fn points_column(&self, nodes: Vec) -> AffineColumn { assert!(nodes.len() <= self.select_size); let mut points = nodes; - let zero = SwAffine::::new_unchecked(G::BaseField::ZERO, G::BaseField::ZERO); + // let zero = SwAffine::::new_unchecked(G::BaseField::ZERO, G::BaseField::ZERO); + let zero = G::ZERO; points.resize(self.select_size, zero); let powers_of_h = self.power_of_h(); assert_eq!(powers_of_h.len(), self.rerand_size); @@ -75,7 +71,7 @@ impl> PiopParams> { self.domain.public_column(selector) } - fn power_of_h(&self) -> Vec> { + fn power_of_h(&self) -> Vec { let mut h = self.h.into_group(); let mut res = Vec::with_capacity(self.rerand_size); res.push(h); @@ -91,6 +87,25 @@ impl> PiopParams> { let significant_bits = &bits_with_trailing_zeroes[..self.rerand_size]; significant_bits.to_vec() } + + // pub fn commit_nodes>( + // &self, + // pcs_params: HidingIpa, + // nodes: Vec>, + // bf: C::ScalarField, + // ) -> WrappedAffine { + // let points = self.points_column(nodes); + // let points_x = pcs_params.commit_hiding(points.xs.as_poly(), bf).unwrap(); + // points_x + // } + // + // pub fn commit_selector>( + // &self, + // pcs_params: HidingIpa, + // ) -> HidingIpa::C { + // let selector = self.select_part(); + // pcs_params.commit_hiding(selector.as_poly(), C::ScalarField::zero())? + // } } #[cfg(test)] diff --git a/pasta-tree/src/circuit2/prover.rs b/pasta-tree/src/circuit2/prover.rs index b906e90..ac4ea48 100644 --- a/pasta-tree/src/circuit2/prover.rs +++ b/pasta-tree/src/circuit2/prover.rs @@ -75,12 +75,12 @@ impl> PiopProver> let result = cond_add.result(); let mut gadgets: Vec>> = Vec::new(); - gadgets.push(Box::new(bits_bool)); gadgets.push(Box::new(inner_prod)); - gadgets.push(Box::new(inner_prod_vals)); gadgets.push(Box::new(cond_add)); + gadgets.push(Box::new(bits_bool)); gadgets.push(Box::new(cond_add_vals_x)); gadgets.push(Box::new(cond_add_vals_y)); + gadgets.push(Box::new(inner_prod_vals)); Self { domain, @@ -110,10 +110,12 @@ impl, G: SWCurveConfig> ProverPio &self, commit: Fun, ) -> Self::Commitments { + let points_y = commit(self.points.ys.as_poly()); let bits = commit(self.bits.as_poly()); let cond_add_acc = [commit(&self.cond_add_acc_x), commit(&self.cond_add_acc_y)]; let inn_prod_acc = commit(&self.inner_prod_acc); ProofComms { + points_y, bits, cond_add_acc, inn_prod_acc, @@ -126,8 +128,8 @@ impl, G: SWCurveConfig> ProverPio fn columns(&self) -> Vec> { vec![ self.points.xs.as_poly().clone(), - self.points.ys.as_poly().clone(), self.select_part.as_poly().clone(), + self.points.ys.as_poly().clone(), self.bits.as_poly().clone(), self.inner_prod_acc.clone(), self.cond_add_acc_x.clone(), diff --git a/pasta-tree/src/circuit2/verifier.rs b/pasta-tree/src/circuit2/verifier.rs index d82ef25..757cd5e 100644 --- a/pasta-tree/src/circuit2/verifier.rs +++ b/pasta-tree/src/circuit2/verifier.rs @@ -1,4 +1,5 @@ use ark_ec::AffineRepr; +use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ff::PrimeField; use ark_std::marker::PhantomData; @@ -18,7 +19,6 @@ pub struct PiopVerifier, G: AffineRepr, points_x: C, - points_y: C, select_part: C, witness_cols: ProofComms, @@ -35,7 +35,6 @@ impl, G: AffineRepr> PiopVerifier pub fn init( domain_evals: EvaluatedDomain, points_x: C, - points_y: C, select_part: C, witness_cols: ProofComms, evals: ProofEvals, @@ -60,12 +59,12 @@ impl, G: AffineRepr> PiopVerifier let booleanity = BooleanityValues { bits: evals.bits }; let (seed_x, seed_y) = seed.xy().unwrap(); - let (result_x, result_y) = result.xy().unwrap(); + let (res_x, res_y) = (seed + result).into_affine().xy().unwrap(); let cond_add_acc_x = FixedCellsValues { col: evals.cond_add_acc[0], col_first: seed_x, - col_last: result_x, + col_last: res_x, l_first: domain_evals.l_first, l_last: domain_evals.l_last, }; @@ -73,7 +72,7 @@ impl, G: AffineRepr> PiopVerifier let cond_add_acc_y = FixedCellsValues { col: evals.cond_add_acc[1], col_first: seed_y, - col_last: result_y, + col_last: res_y, l_first: domain_evals.l_first, l_last: domain_evals.l_last, }; @@ -89,7 +88,6 @@ impl, G: AffineRepr> PiopVerifier Self { domain_evals, points_x, - points_y, select_part, witness_cols, booleanity, @@ -109,11 +107,7 @@ impl, G: SWCurveConfig> VerifierP const N_COLUMNS: usize = 7; fn precommitted_columns(&self) -> Vec { - vec![ - self.points_x.clone(), - self.points_y.clone(), - self.select_part.clone(), - ] + vec![self.points_x.clone(), self.select_part.clone()] } fn evaluate_constraints_main(&self) -> Vec { diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index a303af6..59d01bc 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -1,7 +1,8 @@ -use crate::circuit::params::PiopParams; -use crate::circuit::{ProofComms, ProofEvals}; +use crate::circuit2::params::PiopParams; +use crate::circuit2::{ProofComms, ProofEvals}; use ark_ec::{AffineRepr, CurveGroup, PrimeGroup}; use ark_ff::{PrimeField, Zero}; +use ark_std::UniformRand; use ark_std::rand::Rng; use w3f_pcs::aggregation::multiple::ShplonkTranscript; use w3f_pcs::pcs::PCS; @@ -12,7 +13,7 @@ use w3f_plonk_common::PiopProof; use w3f_plonk_common::domain::Domain; pub mod auth_path; -pub mod circuit; +// pub mod circuit; pub mod circuit2; // pub mod level; pub mod prover; @@ -64,9 +65,9 @@ where let c0_pcs_params = HidingIpa::::setup(setup_degree, rng); let c1_pcs_params = HidingIpa::::setup(setup_degree, rng); let c0_domain = Domain::::new(domain_size, true); - let c0_piop_params = PiopParams::setup(c0_domain, c1_pcs_params.h); + let c0_piop_params = PiopParams::setup(c0_domain, c1_pcs_params.h, C1::Affine::rand(rng)); let c1_domain = Domain::::new(domain_size, true); - let c1_piop_params = PiopParams::setup(c1_domain, c0_pcs_params.h); + let c1_piop_params = PiopParams::setup(c1_domain, c0_pcs_params.h, C0::Affine::rand(rng)); Self { c0_params: CycleSideParams { pcs_params: c0_pcs_params, @@ -81,27 +82,40 @@ where } impl> CycleSideParams { - pub fn commit_x_coords( - &self, - children_x_coords: Vec, - bf: C::ScalarField, - ) -> Result, ()> { - let x_coords = self.piop_params.x_coords_column(children_x_coords); - Ok(self.pcs_params.commit_hiding(x_coords.as_poly(), bf)?) + pub fn commit_nodes(&self, nodes: Vec, bf: C::ScalarField) -> Result, ()> { + let points = self.piop_params.points_column(nodes); + let points_x = self.pcs_params.commit_hiding(points.xs.as_poly(), bf); + points_x } - pub fn commit_h_powers(&self) -> [IPACommitment; 2] { - let h_powers = self.piop_params.h_powers_column(); - let h_powers = [ - self.pcs_params - .commit_hiding(h_powers.xs.as_poly(), C::ScalarField::zero()) - .unwrap(), - self.pcs_params - .commit_hiding(h_powers.ys.as_poly(), C::ScalarField::zero()) - .unwrap(), - ]; - h_powers + pub fn commit_selector(&self) -> WrappedAffine { + let selector = self.piop_params.select_part(); + self.pcs_params + .commit_hiding(selector.as_poly(), C::ScalarField::zero()) + .unwrap() } + + // pub fn commit_x_coords( + // &self, + // children_x_coords: Vec, + // bf: C::ScalarField, + // ) -> Result, ()> { + // let x_coords = self.piop_params.x_coords_column(children_x_coords); + // Ok(self.pcs_params.commit_hiding(x_coords.as_poly(), bf)?) + // } + + // pub fn commit_h_powers(&self) -> [IPACommitment; 2] { + // let h_powers = self.piop_params.h_powers_column(); + // let h_powers = [ + // self.pcs_params + // .commit_hiding(h_powers.xs.as_poly(), C::ScalarField::zero()) + // .unwrap(), + // self.pcs_params + // .commit_hiding(h_powers.ys.as_poly(), C::ScalarField::zero()) + // .unwrap(), + // ]; + // h_powers + // } } #[derive(Debug, PartialEq)] @@ -254,7 +268,7 @@ mod tests { // cargo test test_curve_tree_proof --release --features="print-trace parallel" -- --show-output #[test] fn test_curve_tree_proof() { - _test_proof::<_, _, PallasConfig, VestaConfig>(8, 4); + _test_proof::<_, _, PallasConfig, VestaConfig>(9, 4); } fn _bench_msm(log_n: u32) { diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 0dcb3d0..a4e2b0a 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -1,7 +1,7 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; -use crate::circuit::prover::PiopProver; +use crate::circuit2::prover::PiopProver; use crate::verifier::V; use crate::{Coeffs, CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof, IPACommitment}; use ark_ec::CurveGroup; @@ -57,8 +57,9 @@ impl(); // s = &s[70..s.len()]; // println!("\n\nprover {s}\nchildren={blinded_path:?}\n"); + debug_assert_eq!(blinded_path.len(), witness.len()); - let n_polys = V::::N_COLUMNS + 2; + let n_polys = V::::N_COLUMNS + 2; // plus the quotient and the linearization polys let mut piop_proofs = Vec::with_capacity(witness.len()); let mut polys = Vec::with_capacity(witness.len() * n_polys); let mut coords = Vec::with_capacity(witness.len() * n_polys); @@ -85,7 +86,13 @@ impl(); // s = &s[65..s.len()]; // println!("\n\nverifier {s}\nchildren={children:?}\nparents={parents:?}\n"); + let plonk_verifier: PlonkVerifier, _> = PlonkVerifier::init( self.pcs_params.vk(), &(), ArkTranscript::new(b"pasta-tree-level-proof"), ); - let n_polys = V::::N_COLUMNS + 2; + let n_polys = V::::N_COLUMNS + 2; // plus the quotient and the linearization polys let mut polys = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); let mut coords = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); let mut vals = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); - let h_powers = self.commit_h_powers(); + let selector = self.commit_selector(); - for ((selected_node, parent), piop_proof) in children + for ((result, x_parent), piop_proof) in children .into_iter() .zip(parents.into_iter()) .zip(side_proof.piop_proofs.into_iter()) { let (challenges, _rng) = plonk_verifier.restore_challenges( - &selected_node, + &result, &piop_proof, // '1' accounts for the quotient polynomial that is aggregated together with the columns V::::N_COLUMNS + 1, @@ -81,12 +82,13 @@ impl::init( - selected_node, - WrappedAffine(parent), domain_at_zeta, - h_powers.clone(), + WrappedAffine(x_parent), + selector.clone(), piop_proof.column_commitments.clone(), piop_proof.columns_at_zeta.clone(), + self.piop_params.seed, + result, ); let PcsOpeningAt2Points { open_at_zeta, @@ -96,7 +98,12 @@ impl Date: Wed, 27 May 2026 04:22:42 +0300 Subject: [PATCH 13/42] y_coords are treated as witness --- pasta-tree/src/auth_path/node.rs | 3 +- pasta-tree/src/circuit2/params.rs | 91 ++++++++++++++++++++++--------- pasta-tree/src/circuit2/prover.rs | 2 +- pasta-tree/src/lib.rs | 20 ++++--- 4 files changed, 78 insertions(+), 38 deletions(-) diff --git a/pasta-tree/src/auth_path/node.rs b/pasta-tree/src/auth_path/node.rs index 1911ddf..96ef397 100644 --- a/pasta-tree/src/auth_path/node.rs +++ b/pasta-tree/src/auth_path/node.rs @@ -71,8 +71,7 @@ impl LevelWitness { where G::BaseField: PrimeField, { - // params.commit_x_coords(self.x_coords(), bf).map(|c| c.0) - params.commit_nodes(self.siblings.clone(), bf).map(|c| c.0) + params.commit_x_coords(self.x_coords(), bf).map(|c| c.0) } } diff --git a/pasta-tree/src/circuit2/params.rs b/pasta-tree/src/circuit2/params.rs index 5f1a04e..5aa3584 100644 --- a/pasta-tree/src/circuit2/params.rs +++ b/pasta-tree/src/circuit2/params.rs @@ -8,13 +8,14 @@ use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; /// Plonk Interactive Oracle Proofs (PIOP) parameters. +/// `max_nodes + blinding_bits = domain.capacity - 1` #[derive(Clone)] pub struct PiopParams> { /// Domain over which the piop is represented. pub domain: Domain, - pub select_size: usize, - /// Number of bits used to represent a scalar. - pub rerand_size: usize, + pub max_nodes: usize, + /// Number of bits used to represent a blinding factor. + pub blinding_bits: usize, pub seed: G, /// Blinding base point. pub h: G, @@ -25,38 +26,74 @@ impl> PiopParams { assert!(domain.domain_size() > 256); let actual_capacity = domain.capacity - 1; let scalar_size = Domain::::new(256, domain.is_hiding()).capacity - 1; - let rerand_size = ark_std::cmp::min(G::ScalarField::MODULUS_BIT_SIZE as usize, scalar_size); - let select_size = actual_capacity - rerand_size; + let blinding_bits = + ark_std::cmp::min(G::ScalarField::MODULUS_BIT_SIZE as usize, scalar_size); + let max_nodes = actual_capacity - blinding_bits; Self { domain, - select_size, - rerand_size, + max_nodes, + blinding_bits, seed, h, } } - pub fn max_nodes(&self) -> usize { - self.select_size + pub fn commit_x_coords(&self, siblings_x_coords: Vec) -> FieldColumn { + assert!(siblings_x_coords.len() <= self.max_nodes); + let mut x_coords = siblings_x_coords; + // padding + x_coords.resize(self.max_nodes, G::BaseField::zero()); + // `powers_of_h` x-coords + let powers_of_h = self.power_of_h(); + assert_eq!(powers_of_h.len(), self.blinding_bits); + let powers_of_h_xs = powers_of_h.into_iter().filter_map(|p| p.x()); + x_coords.extend(powers_of_h_xs); + let payload_len = self.domain.capacity - 1; + assert_eq!(x_coords.len(), payload_len); + // x_coords.push(G::BaseField::one()); + // assert_eq!(x_coords.len(), self.domain.capacity); + + // zk_rows + x_coords.resize(self.domain.domain_size(), G::BaseField::zero()); + self.domain + .domains + .column_from_evals(x_coords, payload_len) } - pub fn points_column(&self, nodes: Vec) -> AffineColumn { - assert!(nodes.len() <= self.select_size); - let mut points = nodes; - // let zero = SwAffine::::new_unchecked(G::BaseField::ZERO, G::BaseField::ZERO); - let zero = G::ZERO; - points.resize(self.select_size, zero); - let powers_of_h = self.power_of_h(); - assert_eq!(powers_of_h.len(), self.rerand_size); - points.extend(powers_of_h); - // let flag = SwAffine::::new_unchecked(G::BaseField::ONE, G::BaseField::ZERO); - // points.push(flag); + pub fn x_coords_from_points(&self, child_nodes: Vec) -> FieldColumn { + let points = self.siblings_with_blinding(child_nodes); + let (mut x_coords, mut y_coords): (Vec, Vec) = + points.iter().map(|p| p.xy().unwrap()).unzip(); + let payload_len = self.domain.capacity - 1; + assert_eq!(x_coords.len(), payload_len); + // x_coords.push(G::BaseField::one()); + // assert_eq!(x_coords.len(), self.domain.capacity); + + // zk_rows + x_coords.resize(self.domain.domain_size(), G::BaseField::zero()); + y_coords.resize(self.domain.domain_size(), G::BaseField::zero()); + self.domain + .domains + .column_from_evals(x_coords, payload_len) + } + + pub fn points_column(&self, child_nodes: Vec) -> AffineColumn { + let points = self.siblings_with_blinding(child_nodes); + assert_eq!(points.len(), self.domain.capacity - 1); AffineColumn::public_column(points, &self.domain) } + fn siblings_with_blinding(&self, siblings: Vec) -> Vec { + assert!(siblings.len() <= self.max_nodes); + let mut points = siblings; + points.resize(self.max_nodes, G::ZERO); // padding + points.extend(self.power_of_h()); // powers of `H` + points + } + pub fn bits_column(&self, node_index: usize, bf: G::ScalarField) -> BitColumn { - let mut bits = vec![false; self.select_size]; - assert!(node_index < self.select_size); // allows to select a padding node + let mut bits = vec![false; self.max_nodes]; + assert!(node_index < self.max_nodes); // allows to select a padding node bits[node_index] = true; bits.extend(self.scalar_part(bf)); BitColumn::init(bits, &self.domain) @@ -64,8 +101,8 @@ impl> PiopParams { pub fn select_part(&self) -> FieldColumn { let selector = [ - vec![G::BaseField::one(); self.select_size], - vec![G::BaseField::zero(); self.rerand_size], + vec![G::BaseField::one(); self.max_nodes], + vec![G::BaseField::zero(); self.blinding_bits], ] .concat(); self.domain.public_column(selector) @@ -73,9 +110,9 @@ impl> PiopParams { fn power_of_h(&self) -> Vec { let mut h = self.h.into_group(); - let mut res = Vec::with_capacity(self.rerand_size); + let mut res = Vec::with_capacity(self.blinding_bits); res.push(h); - for _ in 1..self.rerand_size { + for _ in 1..self.blinding_bits { h.double_in_place(); res.push(h); } @@ -84,7 +121,7 @@ impl> PiopParams { fn scalar_part(&self, e: G::ScalarField) -> Vec { let bits_with_trailing_zeroes = e.into_bigint().to_bits_le(); - let significant_bits = &bits_with_trailing_zeroes[..self.rerand_size]; + let significant_bits = &bits_with_trailing_zeroes[..self.blinding_bits]; significant_bits.to_vec() } diff --git a/pasta-tree/src/circuit2/prover.rs b/pasta-tree/src/circuit2/prover.rs index ac4ea48..241afdf 100644 --- a/pasta-tree/src/circuit2/prover.rs +++ b/pasta-tree/src/circuit2/prover.rs @@ -202,7 +202,7 @@ mod tests { let piop_params = PiopParams::setup(domain, h, seed); let witness = - random_witness(piop_params.max_nodes(), node, rng).with_blinding(bf, Fq::zero()); + random_witness(piop_params.max_nodes, node, rng).with_blinding(bf, Fq::zero()); let piop = PiopProver::build(&piop_params, witness); assert!(ProverPiop::<_, IPACommitment>::constraints_satisfied(&piop)); diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 59d01bc..c584301 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -82,10 +82,14 @@ where } impl> CycleSideParams { - pub fn commit_nodes(&self, nodes: Vec, bf: C::ScalarField) -> Result, ()> { - let points = self.piop_params.points_column(nodes); - let points_x = self.pcs_params.commit_hiding(points.xs.as_poly(), bf); - points_x + pub fn commit_x_coords( + &self, + child_x_coords: Vec, + bf: C::ScalarField, + ) -> Result, ()> { + let x_coords = self.piop_params.commit_x_coords(child_x_coords); + let x_parent = self.pcs_params.commit_hiding(x_coords.as_poly(), bf); + x_parent } pub fn commit_selector(&self) -> WrappedAffine { @@ -185,7 +189,7 @@ mod tests { path_node: G, rng: &mut R, ) -> (C::Affine, LevelWitness) { - let level_witness = random_witness(params.piop_params.max_nodes(), path_node, rng); + let level_witness = random_witness(params.piop_params.max_nodes, path_node, rng); let parent = level_witness.compute_parent(params).unwrap(); (parent, level_witness) } @@ -248,12 +252,12 @@ mod tests { _ => panic!(), }; - let capacity = params.c0_params.piop_params.max_nodes(); + let max_nodes = params.c0_params.piop_params.max_nodes; let t_prove = start_timer!(|| format!( "Proving CurveTree membership, H={height}, M={}, C={}, C^{height}={}", domain_size, - capacity, - capacity.pow(height as u32) + max_nodes, + max_nodes.pow(height as u32) )); let (auth_path, proof) = params.prove(path, rng); end_timer!(t_prove); From 0922eeaa19576cb881678d91e63e9c7d7d02fd14 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Wed, 27 May 2026 16:43:14 +0300 Subject: [PATCH 14/42] piop_params create prover/verifier --- pasta-tree/src/circuit2/params.rs | 75 ++++++++++++++++++++----------- pasta-tree/src/circuit2/prover.rs | 14 +++--- pasta-tree/src/lib.rs | 25 +++++------ pasta-tree/src/prover.rs | 2 +- pasta-tree/src/verifier.rs | 24 +++++----- 5 files changed, 79 insertions(+), 61 deletions(-) diff --git a/pasta-tree/src/circuit2/params.rs b/pasta-tree/src/circuit2/params.rs index 5aa3584..46341e0 100644 --- a/pasta-tree/src/circuit2/params.rs +++ b/pasta-tree/src/circuit2/params.rs @@ -1,7 +1,13 @@ +use crate::LevelProof; +use crate::auth_path::node::LevelWitnessWithBlinding; +use crate::circuit2::prover::PiopProver; +use crate::circuit2::verifier::PiopVerifier; +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::One; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; use ark_std::{vec, vec::Vec}; +use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; @@ -21,6 +27,43 @@ pub struct PiopParams> { pub h: G, } +impl> PiopParams> { + pub fn prover_piop( + &self, + level: LevelWitnessWithBlinding>, + ) -> PiopProver> { + PiopProver::build(&self, level) + } + + pub fn verifier_piop>( + &self, + // re-randomized child + child: SwAffine, + // re-randomized parent + parent: C::Affine, + selector: C::Affine, + proof: LevelProof, + zeta: C::ScalarField, + ) -> PiopVerifier, SwAffine> { + let domain_at_zeta = self.domain.evaluate(zeta); + PiopVerifier::init( + domain_at_zeta, + WrappedAffine(parent), + WrappedAffine(selector), + proof.column_commitments.clone(), + proof.columns_at_zeta.clone(), + self.seed, + child, + ) + } + + // use crate::circuit::prover::PiopProver as PiopProver2; + // pub fn prover2(&self, level: LevelWitnessWithBlinding>) -> PiopProver2> { + // let piop = PiopProver2::build(&self, level); + // piop + // } +} + impl> PiopParams { pub fn setup(domain: Domain, h: G, seed: G) -> Self { assert!(domain.domain_size() > 256); @@ -38,7 +81,10 @@ impl> PiopParams { } } - pub fn commit_x_coords(&self, siblings_x_coords: Vec) -> FieldColumn { + pub fn commit_x_coords( + &self, + siblings_x_coords: Vec, + ) -> FieldColumn { assert!(siblings_x_coords.len() <= self.max_nodes); let mut x_coords = siblings_x_coords; // padding @@ -55,9 +101,7 @@ impl> PiopParams { // zk_rows x_coords.resize(self.domain.domain_size(), G::BaseField::zero()); - self.domain - .domains - .column_from_evals(x_coords, payload_len) + self.domain.domains.column_from_evals(x_coords, payload_len) } pub fn x_coords_from_points(&self, child_nodes: Vec) -> FieldColumn { @@ -72,9 +116,7 @@ impl> PiopParams { // zk_rows x_coords.resize(self.domain.domain_size(), G::BaseField::zero()); y_coords.resize(self.domain.domain_size(), G::BaseField::zero()); - self.domain - .domains - .column_from_evals(x_coords, payload_len) + self.domain.domains.column_from_evals(x_coords, payload_len) } pub fn points_column(&self, child_nodes: Vec) -> AffineColumn { @@ -124,25 +166,6 @@ impl> PiopParams { let significant_bits = &bits_with_trailing_zeroes[..self.blinding_bits]; significant_bits.to_vec() } - - // pub fn commit_nodes>( - // &self, - // pcs_params: HidingIpa, - // nodes: Vec>, - // bf: C::ScalarField, - // ) -> WrappedAffine { - // let points = self.points_column(nodes); - // let points_x = pcs_params.commit_hiding(points.xs.as_poly(), bf).unwrap(); - // points_x - // } - // - // pub fn commit_selector>( - // &self, - // pcs_params: HidingIpa, - // ) -> HidingIpa::C { - // let selector = self.select_part(); - // pcs_params.commit_hiding(selector.as_poly(), C::ScalarField::zero())? - // } } #[cfg(test)] diff --git a/pasta-tree/src/circuit2/prover.rs b/pasta-tree/src/circuit2/prover.rs index 241afdf..8ae3190 100644 --- a/pasta-tree/src/circuit2/prover.rs +++ b/pasta-tree/src/circuit2/prover.rs @@ -3,7 +3,7 @@ use crate::circuit2::params::PiopParams; use crate::circuit2::{ProofComms, ProofEvals}; use ark_ec::AffineRepr; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; -use ark_ff::PrimeField; +use ark_ff::{One, PrimeField, Zero}; use ark_poly::Evaluations; use ark_poly::Polynomial; use ark_poly::univariate::DensePolynomial; @@ -50,7 +50,7 @@ pub struct PiopProver> { result: G, } -impl> PiopProver> { +impl> PiopProver> { pub fn build( params: &PiopParams>, level: LevelWitnessWithBlinding>, @@ -61,8 +61,12 @@ impl> PiopProver> let bits_bool = Booleanity::init(bits.clone()); let select_part = params.select_part(); let inner_prod = InnerProd::init(select_part.clone(), bits.col.clone(), &domain); - let inner_prod_vals = - FixedCells::init(inner_prod.acc.clone(), &domain, F::zero(), F::one()); + let inner_prod_vals = FixedCells::init( + inner_prod.acc.clone(), + &domain, + G::BaseField::zero(), + G::BaseField::one(), + ); let cond_add = CondAdd::init(bits.clone(), points.clone(), params.seed, &domain); let (seed_x, seed_y) = params.seed.xy().unwrap(); let (result_x, result_y) = cond_add.seed_plus_sum().xy().unwrap(); @@ -74,7 +78,7 @@ impl> PiopProver> let cond_add_acc_y = cond_add.acc.ys.as_poly().clone(); let result = cond_add.result(); - let mut gadgets: Vec>> = Vec::new(); + let mut gadgets: Vec>> = Vec::new(); gadgets.push(Box::new(inner_prod)); gadgets.push(Box::new(cond_add)); gadgets.push(Box::new(bits_bool)); diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index c584301..5631ee9 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -34,10 +34,16 @@ pub struct CycleParams< c1_params: CycleSideParams, } +pub type LevelProof = PiopProof< + ::ScalarField, + WrappedAffine, + ProofComms<::ScalarField, WrappedAffine>, + ProofEvals<::ScalarField>, +>; + #[derive(Clone)] pub struct CycleSideProof> { - piop_proofs: - Vec, ProofComms>, ProofEvals>>, + piop_proofs: Vec>, pcs_proof: AggregateProof>, todo: Coeffs, } @@ -99,15 +105,6 @@ impl> CycleSideParams, - // bf: C::ScalarField, - // ) -> Result, ()> { - // let x_coords = self.piop_params.x_coords_column(children_x_coords); - // Ok(self.pcs_params.commit_hiding(x_coords.as_poly(), bf)?) - // } - // pub fn commit_h_powers(&self) -> [IPACommitment; 2] { // let h_powers = self.piop_params.h_powers_column(); // let h_powers = [ @@ -254,15 +251,13 @@ mod tests { let max_nodes = params.c0_params.piop_params.max_nodes; let t_prove = start_timer!(|| format!( - "Proving CurveTree membership, H={height}, M={}, C={}, C^{height}={}", - domain_size, - max_nodes, + "Proving CurveTree membership, height={height}, domain={domain_size}, arity={max_nodes}, capacity={}", max_nodes.pow(height as u32) )); let (auth_path, proof) = params.prove(path, rng); end_timer!(t_prove); - let t_verify = start_timer!(|| "Verifying CurveTree opening"); + let t_verify = start_timer!(|| "Verifying CurveTree membership"); let valid = params.verify(auth_path, proof, root); end_timer!(t_verify); assert!(valid); diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index a4e2b0a..c1f58fa 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -72,7 +72,7 @@ impl> as ProverPiop< C::ScalarField, IPACommitment, diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 652c137..5de3126 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -5,7 +5,6 @@ use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; use ark_ec::{CurveGroup, PrimeGroup}; use ark_ff::PrimeField; use w3f_pcs::pcs::PcsParams; -use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::VerifierPiop; @@ -68,27 +67,24 @@ impl::N_COLUMNS + 1, V::::N_CONSTRAINTS, ); - let domain_at_zeta = self.piop_params.domain.evaluate(challenges.zeta); - let piop = V::::init( - domain_at_zeta, - WrappedAffine(x_parent), - selector.clone(), - piop_proof.column_commitments.clone(), - piop_proof.columns_at_zeta.clone(), - self.piop_params.seed, - result, + let piop = self.piop_params.verifier_piop( + child, + parent, + selector.0, + level_proof.clone(), + challenges.zeta, ); let PcsOpeningAt2Points { open_at_zeta, @@ -97,7 +93,7 @@ impl Date: Wed, 27 May 2026 16:52:10 +0300 Subject: [PATCH 15/42] generic arg removed --- pasta-tree/src/lib.rs | 10 +++++----- pasta-tree/src/prover.rs | 2 +- pasta-tree/src/verifier.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 5631ee9..fef036b 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -42,10 +42,10 @@ pub type LevelProof = PiopProof< >; #[derive(Clone)] -pub struct CycleSideProof> { +pub struct CycleSideProof { piop_proofs: Vec>, - pcs_proof: AggregateProof>, - todo: Coeffs, + pcs_proof: AggregateProof>, + todo: Coeffs, } #[derive(Clone)] @@ -55,8 +55,8 @@ pub struct CurveTreeProof< C0: CurveGroup, C1: CurveGroup, > { - c0_proof: CycleSideProof, - c1_proof: CycleSideProof, + c0_proof: CycleSideProof, + c1_proof: CycleSideProof, } impl CycleParams diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index c1f58fa..4e10b4a 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -53,7 +53,7 @@ impl>, witness: Vec>>, rng: &mut R, - ) -> CycleSideProof { + ) -> CycleSideProof { // let mut s = std::any::type_name::(); // s = &s[70..s.len()]; // println!("\n\nprover {s}\nchildren={blinded_path:?}\n"); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 5de3126..aaad039 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -48,7 +48,7 @@ impl>, // parents, re-randomized at the previous step parents: Vec, - side_proof: CycleSideProof, + side_proof: CycleSideProof, ) -> bool { // let mut s = std::any::type_name::(); // s = &s[65..s.len()]; From 7021d78115241ec8953ad405be474642fb8ed70a Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 28 May 2026 19:00:39 +0300 Subject: [PATCH 16/42] trait bounds simplified --- pasta-tree/src/circuit2/mod.rs | 62 ++++++++++++++++++++++------- pasta-tree/src/circuit2/params.rs | 4 +- pasta-tree/src/circuit2/prover.rs | 54 ++++++++++++------------- pasta-tree/src/circuit2/verifier.rs | 60 ++++++++++++++-------------- pasta-tree/src/lib.rs | 4 +- pasta-tree/src/prover.rs | 7 ++-- pasta-tree/src/verifier.rs | 6 +-- 7 files changed, 114 insertions(+), 83 deletions(-) diff --git a/pasta-tree/src/circuit2/mod.rs b/pasta-tree/src/circuit2/mod.rs index 9189c11..e75d7a9 100644 --- a/pasta-tree/src/circuit2/mod.rs +++ b/pasta-tree/src/circuit2/mod.rs @@ -1,31 +1,57 @@ +use ark_ec::CurveGroup; use ark_ff::PrimeField; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; -use w3f_pcs::pcs::Commitment; +use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::{ColumnsCommited, ColumnsEvaluated}; pub mod params; pub mod prover; pub mod verifier; +// struct SideProofParams { +// _phantom: PhantomData +// } +// +// impl GenericProofParams for SideProofParams { +// type Cols = ProofComms; +// type Evals = ProofEvals; +// } +// +// pub type LevelProof = PiopProof< +// ::ScalarField, +// WrappedAffine, +// ProofComms, +// ProofEvals<::ScalarField>, +// >; + #[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] -pub struct ProofComms> { - pub(crate) points_y: C, - pub(crate) bits: C, - pub(crate) inn_prod_acc: C, - pub(crate) cond_add_acc: [C; 2], - pub(crate) phantom: PhantomData, +pub struct ProofComms { + /// Witnessed Y-coordinates of the point vector `nodes || h_powers` TODO: last 4 elements + pub(crate) points_y: WrappedAffine, // aka y_parent + /// 0/1 vector `node_idx || bl` + pub(crate) bits: WrappedAffine, + /// Inner product gadget accumulator + pub(crate) inn_prod_acc: WrappedAffine, + /// EC addition (= fixed point multiplication) gadget accumulator + pub(crate) cond_add_acc: [WrappedAffine; 2], } -impl> ColumnsCommited for ProofComms { - fn to_vec(self) -> Vec { +impl ColumnsCommited> for ProofComms { + fn to_vec(self) -> Vec> { + self.into() + } +} + +impl From> for Vec> { + fn from(value: ProofComms) -> Self { + let [cond_add_acc_x, cond_add_acc_y] = value.cond_add_acc; vec![ - self.points_y, - self.bits, - self.inn_prod_acc, - self.cond_add_acc[0].clone(), - self.cond_add_acc[1].clone(), + value.points_y, + value.bits, + value.inn_prod_acc, + cond_add_acc_x, + cond_add_acc_y, ] } } @@ -52,3 +78,9 @@ impl ColumnsEvaluated for ProofEvals { ] } } + +impl From> for Vec { + fn from(value: ProofEvals) -> Self { + value.to_vec() + } +} diff --git a/pasta-tree/src/circuit2/params.rs b/pasta-tree/src/circuit2/params.rs index 46341e0..8e2daa0 100644 --- a/pasta-tree/src/circuit2/params.rs +++ b/pasta-tree/src/circuit2/params.rs @@ -31,7 +31,7 @@ impl> PiopParams> { pub fn prover_piop( &self, level: LevelWitnessWithBlinding>, - ) -> PiopProver> { + ) -> PiopProver> { PiopProver::build(&self, level) } @@ -44,7 +44,7 @@ impl> PiopParams> { selector: C::Affine, proof: LevelProof, zeta: C::ScalarField, - ) -> PiopVerifier, SwAffine> { + ) -> PiopVerifier> { let domain_at_zeta = self.domain.evaluate(zeta); PiopVerifier::init( domain_at_zeta, diff --git a/pasta-tree/src/circuit2/prover.rs b/pasta-tree/src/circuit2/prover.rs index 8ae3190..35ed54a 100644 --- a/pasta-tree/src/circuit2/prover.rs +++ b/pasta-tree/src/circuit2/prover.rs @@ -1,15 +1,14 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit2::params::PiopParams; use crate::circuit2::{ProofComms, ProofEvals}; -use ark_ec::AffineRepr; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; -use ark_ff::{One, PrimeField, Zero}; +use ark_ec::{AffineRepr, CurveGroup}; +use ark_ff::{FftField, One, PrimeField, Zero}; use ark_poly::Evaluations; use ark_poly::Polynomial; use ark_poly::univariate::DensePolynomial; -use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; -use w3f_pcs::pcs::Commitment; +use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::ProverGadget; @@ -33,24 +32,24 @@ use w3f_plonk_common::piop::ProverPiop; // cond_add_acc_y: DensePolynomial, // } -pub struct PiopProver> { - domain: Domain, +pub struct PiopProver> { + domain: Domain, // `x` coordinates of all the children of a node. Public input. // `H, 2H, 4H,...,2^sH` Fixed column. - points: AffineColumn, + points: AffineColumn, // `node_x = self.x_coords[self.node_idx]` Private input. // Bits of the chosen blinding factor. Private input. - bits: BitColumn, - select_part: FieldColumn, - inner_prod_acc: DensePolynomial, - cond_add_acc_x: DensePolynomial, - cond_add_acc_y: DensePolynomial, + bits: BitColumn, + select_part: FieldColumn, + inner_prod_acc: DensePolynomial, + cond_add_acc_x: DensePolynomial, + cond_add_acc_y: DensePolynomial, // columns: Witness, - gadgets: Vec>>, + gadgets: Vec>>, result: G, } -impl> PiopProver> { +impl> PiopProver> { pub fn build( params: &PiopParams>, level: LevelWitnessWithBlinding>, @@ -102,15 +101,15 @@ impl> PiopProver, G: SWCurveConfig> ProverPiop - for PiopProver> +impl> + ProverPiop> for PiopProver> { const N_CONSTRAINTS: usize = 7; - type Commitments = ProofComms; - type Evaluations = ProofEvals; + type Commitments = ProofComms; + type Evaluations = ProofEvals; type Instance = SwAffine; - fn committed_columns) -> C>( + fn committed_columns) -> WrappedAffine>( &self, commit: Fun, ) -> Self::Commitments { @@ -123,13 +122,12 @@ impl, G: SWCurveConfig> ProverPio bits, cond_add_acc, inn_prod_acc, - phantom: PhantomData, } } // 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.select_part.as_poly().clone(), @@ -141,7 +139,7 @@ impl, G: SWCurveConfig> ProverPio ] } - fn columns_evaluated(&self, zeta: &F) -> ProofEvals { + fn columns_evaluated(&self, zeta: &C::ScalarField) -> Self::Evaluations { let points = [self.points.xs.evaluate(zeta), self.points.ys.evaluate(zeta)]; let ring_selector = self.select_part.evaluate(zeta); let bits = self.bits.evaluate(zeta); @@ -159,18 +157,18 @@ impl, G: SWCurveConfig> ProverPio } } - fn constraints(&self) -> Vec> { + fn constraints(&self) -> Vec> { self.gadgets.iter().flat_map(|g| g.constraints()).collect() } - fn constraints_lin(&self, zeta: &F) -> Vec> { + fn constraints_lin(&self, zeta: &C::ScalarField) -> Vec> { self.gadgets .iter() .flat_map(|g| g.constraints_linearized(zeta)) .collect() } - fn domain(&self) -> &Domain { + fn domain(&self) -> &Domain { &self.domain } @@ -182,7 +180,6 @@ impl, G: SWCurveConfig> ProverPio #[cfg(test)] mod tests { use super::*; - use crate::IPACommitment; use crate::tests::random_witness; use ark_bls12_381::G1Projective; use ark_ec::CurveGroup; @@ -209,10 +206,11 @@ mod tests { random_witness(piop_params.max_nodes, node, rng).with_blinding(bf, Fq::zero()); let piop = PiopProver::build(&piop_params, witness); - assert!(ProverPiop::<_, IPACommitment>::constraints_satisfied(&piop)); + assert!(ProverPiop::<_, WrappedAffine>::constraints_satisfied(&piop)); assert_eq!( - ProverPiop::<_, IPACommitment>::result(&piop), + ProverPiop::<_, WrappedAffine>::result(&piop), blinded_node ); + carg } } diff --git a/pasta-tree/src/circuit2/verifier.rs b/pasta-tree/src/circuit2/verifier.rs index 757cd5e..2f5b40c 100644 --- a/pasta-tree/src/circuit2/verifier.rs +++ b/pasta-tree/src/circuit2/verifier.rs @@ -1,12 +1,11 @@ +use crate::circuit2::{ProofComms, ProofEvals}; use ark_ec::AffineRepr; use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; -use ark_ff::PrimeField; +use ark_ff::{One, Zero}; use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; -use w3f_pcs::pcs::Commitment; - -use crate::circuit2::{ProofComms, ProofEvals}; +use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::domain::EvaluatedDomain; use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::gadgets::booleanity::BooleanityValues; @@ -15,29 +14,29 @@ use w3f_plonk_common::gadgets::fixed_cells::FixedCellsValues; use w3f_plonk_common::gadgets::inner_prod::InnerProdValues; use w3f_plonk_common::piop::VerifierPiop; -pub struct PiopVerifier, G: AffineRepr> { - domain_evals: EvaluatedDomain, +pub struct PiopVerifier> { + domain_evals: EvaluatedDomain, - points_x: C, - select_part: C, - witness_cols: ProofComms, + points_x: WrappedAffine, + select_part: WrappedAffine, + witness_cols: ProofComms, // Gadget verifiers: - booleanity: BooleanityValues, - inner_prod: InnerProdValues, - inner_prod_acc: FixedCellsValues, - cond_add: CondAddValues, - cond_add_acc_x: FixedCellsValues, - cond_add_acc_y: FixedCellsValues, + booleanity: BooleanityValues, + inner_prod: InnerProdValues, + inner_prod_acc: FixedCellsValues, + cond_add: CondAddValues, + cond_add_acc_x: FixedCellsValues, + cond_add_acc_y: FixedCellsValues, } -impl, G: AffineRepr> PiopVerifier { +impl> PiopVerifier { pub fn init( - domain_evals: EvaluatedDomain, - points_x: C, - select_part: C, - witness_cols: ProofComms, - evals: ProofEvals, + domain_evals: EvaluatedDomain, + points_x: WrappedAffine, + select_part: WrappedAffine, + witness_cols: ProofComms, + evals: ProofEvals, seed: G, result: G, ) -> Self { @@ -79,8 +78,8 @@ impl, G: AffineRepr> PiopVerifier let inner_prod_acc = FixedCellsValues { col: evals.inn_prod_acc, - col_first: F::zero(), - col_last: F::one(), + col_first: C::ScalarField::zero(), + col_last: C::ScalarField::one(), l_first: domain_evals.l_first, l_last: domain_evals.l_last, }; @@ -100,17 +99,17 @@ impl, G: AffineRepr> PiopVerifier } } -impl, G: SWCurveConfig> VerifierPiop - for PiopVerifier> +impl> + VerifierPiop> for PiopVerifier> { const N_CONSTRAINTS: usize = 7; const N_COLUMNS: usize = 7; - fn precommitted_columns(&self) -> Vec { + fn precommitted_columns(&self) -> Vec> { vec![self.points_x.clone(), self.select_part.clone()] } - fn evaluate_constraints_main(&self) -> Vec { + fn evaluate_constraints_main(&self) -> Vec { vec![ self.inner_prod.evaluate_constraints_main(), self.cond_add.evaluate_constraints_main(), @@ -122,7 +121,10 @@ impl, G: SWCurveConfig> VerifierP .concat() } - fn lin_poly_commitment(&self, alphas: &[F]) -> (Vec, Vec) { + fn lin_poly_commitment( + &self, + alphas: &[C::ScalarField], + ) -> (Vec, Vec>) { assert_eq!(alphas.len(), Self::N_CONSTRAINTS); let inner_prod_acc = self.witness_cols.inn_prod_acc.clone(); @@ -142,7 +144,7 @@ impl, G: SWCurveConfig> VerifierP ) } - fn domain_evaluated(&self) -> &EvaluatedDomain { + fn domain_evaluated(&self) -> &EvaluatedDomain { &self.domain_evals } } diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index fef036b..703b6e9 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -19,8 +19,6 @@ pub mod circuit2; pub mod prover; pub mod verifier; -type IPACommitment = as PCS<::ScalarField>>::C; - pub struct CycleSideParams> { pcs_params: HidingIpa, piop_params: PiopParams, @@ -37,7 +35,7 @@ pub struct CycleParams< pub type LevelProof = PiopProof< ::ScalarField, WrappedAffine, - ProofComms<::ScalarField, WrappedAffine>, + ProofComms, ProofEvals<::ScalarField>, >; diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 4e10b4a..8bd93e5 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -3,7 +3,7 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; use crate::circuit2::prover::PiopProver; use crate::verifier::V; -use crate::{Coeffs, CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof, IPACommitment}; +use crate::{Coeffs, CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; use ark_ff::{PrimeField, Zero}; @@ -11,6 +11,7 @@ use ark_std::UniformRand; use ark_std::rand::Rng; use std::collections::BTreeSet; use w3f_pcs::pcs::PcsParams; +use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; @@ -73,9 +74,9 @@ impl> as ProverPiop< + let blinded_node_ = > as ProverPiop< C::ScalarField, - IPACommitment, + WrappedAffine, >>::result(&piop); debug_assert_eq!(blinded_node_, blinded_node); let (pcs_openings, piop_proof, _transcript) = plonk_prover.reduce_to_pcs_opening(piop); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index aaad039..7ed57a7 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,8 +1,8 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::circuit2::verifier::PiopVerifier; -use crate::{CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof, IPACommitment}; +use crate::{CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; +use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; -use ark_ec::{CurveGroup, PrimeGroup}; use ark_ff::PrimeField; use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::ipa::hiding::HidingIpa; @@ -37,7 +37,7 @@ where } } -pub type V = PiopVerifier<::ScalarField, IPACommitment, Affine>; +pub type V = PiopVerifier>; impl> CycleSideParams> From b0d4725d32da5c35229e8b341fb37bbc4991452e Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 28 May 2026 19:01:06 +0300 Subject: [PATCH 17/42] oopsy --- pasta-tree/src/circuit2/prover.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pasta-tree/src/circuit2/prover.rs b/pasta-tree/src/circuit2/prover.rs index 35ed54a..9275f35 100644 --- a/pasta-tree/src/circuit2/prover.rs +++ b/pasta-tree/src/circuit2/prover.rs @@ -211,6 +211,5 @@ mod tests { ProverPiop::<_, WrappedAffine>::result(&piop), blinded_node ); - carg } } From ad601689f6fcab105fa4b42b6473d369d9738871 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 28 May 2026 19:08:45 +0300 Subject: [PATCH 18/42] mod renamed --- pasta-tree/src/{circuit2 => circuit_tall}/mod.rs | 0 pasta-tree/src/{circuit2 => circuit_tall}/params.rs | 4 ++-- pasta-tree/src/{circuit2 => circuit_tall}/prover.rs | 4 ++-- pasta-tree/src/{circuit2 => circuit_tall}/verifier.rs | 2 +- pasta-tree/src/lib.rs | 6 +++--- pasta-tree/src/prover.rs | 2 +- pasta-tree/src/verifier.rs | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) rename pasta-tree/src/{circuit2 => circuit_tall}/mod.rs (100%) rename pasta-tree/src/{circuit2 => circuit_tall}/params.rs (98%) rename pasta-tree/src/{circuit2 => circuit_tall}/prover.rs (98%) rename pasta-tree/src/{circuit2 => circuit_tall}/verifier.rs (99%) diff --git a/pasta-tree/src/circuit2/mod.rs b/pasta-tree/src/circuit_tall/mod.rs similarity index 100% rename from pasta-tree/src/circuit2/mod.rs rename to pasta-tree/src/circuit_tall/mod.rs diff --git a/pasta-tree/src/circuit2/params.rs b/pasta-tree/src/circuit_tall/params.rs similarity index 98% rename from pasta-tree/src/circuit2/params.rs rename to pasta-tree/src/circuit_tall/params.rs index 8e2daa0..9e8b2ec 100644 --- a/pasta-tree/src/circuit2/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -1,7 +1,7 @@ use crate::LevelProof; use crate::auth_path::node::LevelWitnessWithBlinding; -use crate::circuit2::prover::PiopProver; -use crate::circuit2::verifier::PiopVerifier; +use crate::circuit_tall::prover::PiopProver; +use crate::circuit_tall::verifier::PiopVerifier; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::One; diff --git a/pasta-tree/src/circuit2/prover.rs b/pasta-tree/src/circuit_tall/prover.rs similarity index 98% rename from pasta-tree/src/circuit2/prover.rs rename to pasta-tree/src/circuit_tall/prover.rs index 9275f35..6e3be10 100644 --- a/pasta-tree/src/circuit2/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -1,6 +1,6 @@ use crate::auth_path::node::LevelWitnessWithBlinding; -use crate::circuit2::params::PiopParams; -use crate::circuit2::{ProofComms, ProofEvals}; +use crate::circuit_tall::params::PiopParams; +use crate::circuit_tall::{ProofComms, ProofEvals}; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::{FftField, One, PrimeField, Zero}; diff --git a/pasta-tree/src/circuit2/verifier.rs b/pasta-tree/src/circuit_tall/verifier.rs similarity index 99% rename from pasta-tree/src/circuit2/verifier.rs rename to pasta-tree/src/circuit_tall/verifier.rs index 2f5b40c..d883913 100644 --- a/pasta-tree/src/circuit2/verifier.rs +++ b/pasta-tree/src/circuit_tall/verifier.rs @@ -1,4 +1,4 @@ -use crate::circuit2::{ProofComms, ProofEvals}; +use crate::circuit_tall::{ProofComms, ProofEvals}; use ark_ec::AffineRepr; use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 703b6e9..c4fbb05 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -1,5 +1,5 @@ -use crate::circuit2::params::PiopParams; -use crate::circuit2::{ProofComms, ProofEvals}; +use crate::circuit_tall::params::PiopParams; +use crate::circuit_tall::{ProofComms, ProofEvals}; use ark_ec::{AffineRepr, CurveGroup, PrimeGroup}; use ark_ff::{PrimeField, Zero}; use ark_std::UniformRand; @@ -14,7 +14,7 @@ use w3f_plonk_common::domain::Domain; pub mod auth_path; // pub mod circuit; -pub mod circuit2; +pub mod circuit_tall; // pub mod level; pub mod prover; pub mod verifier; diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 8bd93e5..e35b97b 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -1,7 +1,7 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; -use crate::circuit2::prover::PiopProver; +use crate::circuit_tall::prover::PiopProver; use crate::verifier::V; use crate::{Coeffs, CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; use ark_ec::CurveGroup; diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 7ed57a7..79e7f35 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,5 +1,5 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; -use crate::circuit2::verifier::PiopVerifier; +use crate::circuit_tall::verifier::PiopVerifier; use crate::{CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; From d438c7a1fe67942cbe38295b3c10d35ec4f94ca9 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 28 May 2026 19:11:20 +0300 Subject: [PATCH 19/42] mod circuit --- pasta-tree/src/circuit/prover.rs | 8 ++++---- pasta-tree/src/lib.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit/prover.rs index 9d32130..758576f 100644 --- a/pasta-tree/src/circuit/prover.rs +++ b/pasta-tree/src/circuit/prover.rs @@ -1,5 +1,5 @@ -use crate::PiopParams; use crate::auth_path::node::LevelWitnessWithBlinding; +use crate::circuit::params::PiopParams; use crate::circuit::{ProofComms, ProofEvals}; use ark_ec::AffineRepr; use ark_ec::CurveGroup; @@ -248,11 +248,11 @@ impl, G: SWCurveConfig> ProverPio #[cfg(test)] mod tests { use super::*; - use crate::IPACommitment; use crate::tests::random_witness; use ark_bls12_381::G1Projective; use ark_ed_on_bls12_381_bandersnatch::{Fq, Fr, SWAffine}; use ark_std::{UniformRand, test_rng}; + use w3f_pcs::pcs::commitment::WrappedAffine; #[test] fn test_constraints() { @@ -271,9 +271,9 @@ mod tests { random_witness(piop_params.max_nodes(), node, rng).with_blinding(bf, Fq::zero()); let piop = PiopProver::build(&piop_params, witness); - assert!(ProverPiop::<_, IPACommitment>::constraints_satisfied(&piop)); + assert!(ProverPiop::<_, WrappedAffine>::constraints_satisfied(&piop)); assert_eq!( - ProverPiop::<_, IPACommitment>::result(&piop), + ProverPiop::<_, WrappedAffine>::result(&piop), blinded_node ); } diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index c4fbb05..7e4fafe 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -13,7 +13,7 @@ use w3f_plonk_common::PiopProof; use w3f_plonk_common::domain::Domain; pub mod auth_path; -// pub mod circuit; +pub mod circuit; pub mod circuit_tall; // pub mod level; pub mod prover; From ca3ca64109d57199725f71de59acc6bc6da38877 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 28 May 2026 19:12:25 +0300 Subject: [PATCH 20/42] renamed --- pasta-tree/src/{circuit => circuit_fat}/mod.rs | 0 pasta-tree/src/{circuit => circuit_fat}/params.rs | 0 pasta-tree/src/{circuit => circuit_fat}/prover.rs | 4 ++-- pasta-tree/src/{circuit => circuit_fat}/verifier.rs | 2 +- pasta-tree/src/lib.rs | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename pasta-tree/src/{circuit => circuit_fat}/mod.rs (100%) rename pasta-tree/src/{circuit => circuit_fat}/params.rs (100%) rename pasta-tree/src/{circuit => circuit_fat}/prover.rs (99%) rename pasta-tree/src/{circuit => circuit_fat}/verifier.rs (99%) diff --git a/pasta-tree/src/circuit/mod.rs b/pasta-tree/src/circuit_fat/mod.rs similarity index 100% rename from pasta-tree/src/circuit/mod.rs rename to pasta-tree/src/circuit_fat/mod.rs diff --git a/pasta-tree/src/circuit/params.rs b/pasta-tree/src/circuit_fat/params.rs similarity index 100% rename from pasta-tree/src/circuit/params.rs rename to pasta-tree/src/circuit_fat/params.rs diff --git a/pasta-tree/src/circuit/prover.rs b/pasta-tree/src/circuit_fat/prover.rs similarity index 99% rename from pasta-tree/src/circuit/prover.rs rename to pasta-tree/src/circuit_fat/prover.rs index 758576f..bd88ce7 100644 --- a/pasta-tree/src/circuit/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -1,6 +1,6 @@ use crate::auth_path::node::LevelWitnessWithBlinding; -use crate::circuit::params::PiopParams; -use crate::circuit::{ProofComms, ProofEvals}; +use crate::circuit_fat::params::PiopParams; +use crate::circuit_fat::{ProofComms, ProofEvals}; use ark_ec::AffineRepr; use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; diff --git a/pasta-tree/src/circuit/verifier.rs b/pasta-tree/src/circuit_fat/verifier.rs similarity index 99% rename from pasta-tree/src/circuit/verifier.rs rename to pasta-tree/src/circuit_fat/verifier.rs index 0a53eea..9cd737b 100644 --- a/pasta-tree/src/circuit/verifier.rs +++ b/pasta-tree/src/circuit_fat/verifier.rs @@ -5,7 +5,7 @@ use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::Commitment; -use crate::circuit::{ProofComms, ProofEvals}; +use crate::circuit_fat::{ProofComms, ProofEvals}; use w3f_plonk_common::domain::EvaluatedDomain; use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::gadgets::booleanity::BooleanityValues; diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 7e4fafe..3ce5923 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -13,7 +13,7 @@ use w3f_plonk_common::PiopProof; use w3f_plonk_common::domain::Domain; pub mod auth_path; -pub mod circuit; +pub mod circuit_fat; pub mod circuit_tall; // pub mod level; pub mod prover; From 9a0ec305eea48f1e2af8fecbdc9ea050aa9c3d77 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 28 May 2026 20:53:56 +0300 Subject: [PATCH 21/42] CircuitParams implemented --- pasta-tree/src/circuit_tall/mod.rs | 27 +++++++++++++++- pasta-tree/src/circuit_tall/params.rs | 44 +++++++++++---------------- pasta-tree/src/prover.rs | 14 +++++---- pasta-tree/src/verifier.rs | 8 ++--- 4 files changed, 56 insertions(+), 37 deletions(-) diff --git a/pasta-tree/src/circuit_tall/mod.rs b/pasta-tree/src/circuit_tall/mod.rs index e75d7a9..083292e 100644 --- a/pasta-tree/src/circuit_tall/mod.rs +++ b/pasta-tree/src/circuit_tall/mod.rs @@ -1,8 +1,9 @@ -use ark_ec::CurveGroup; +use ark_ec::{CurveGroup, PrimeGroup}; use ark_ff::PrimeField; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; +use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::{ColumnsCommited, ColumnsEvaluated}; pub mod params; @@ -25,6 +26,30 @@ pub mod verifier; // ProofEvals<::ScalarField>, // >; +/// The circuit is over `C::ScalarField`. +pub trait CircuitParams { + type Witness; + type Instance; + type Proof; + type ProverCircuit: ProverPiop>; + type VerifierCircuit: VerifierPiop>; + + fn prover_circuit(&self, w: Self::Witness) -> Self::ProverCircuit; + + fn verifier_circuit(&self, + instance: Self::Instance, + fixed_cols: &[WrappedAffine], + proof: Self::Proof, + zeta: C::ScalarField) -> Self::VerifierCircuit; +} + +type PiopProof = w3f_plonk_common::PiopProof< + ::ScalarField, + WrappedAffine, + ProofComms, + ProofEvals<::ScalarField> +>; + #[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct ProofComms { /// Witnessed Y-coordinates of the point vector `nodes || h_powers` TODO: last 4 elements diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 9e8b2ec..9267eec 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -1,4 +1,3 @@ -use crate::LevelProof; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::prover::PiopProver; use crate::circuit_tall::verifier::PiopVerifier; @@ -8,10 +7,11 @@ use ark_ff::One; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; -use w3f_plonk_common::FieldColumn; +use w3f_plonk_common::{FieldColumn}; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; +use crate::circuit_tall::{CircuitParams, PiopProof}; /// Plonk Interactive Oracle Proofs (PIOP) parameters. /// `max_nodes + blinding_bits = domain.capacity - 1` @@ -27,41 +27,33 @@ pub struct PiopParams> { pub h: G, } -impl> PiopParams> { - pub fn prover_piop( - &self, - level: LevelWitnessWithBlinding>, - ) -> PiopProver> { +impl> CircuitParams for PiopParams> { + type Witness = LevelWitnessWithBlinding>; + + /// (re-randomized child, re-randomized parent) + type Instance = (SwAffine, C::Affine); + type Proof = PiopProof; + type ProverCircuit = PiopProver>; + type VerifierCircuit = PiopVerifier>; + + fn prover_circuit(&self, level: Self::Witness) -> Self::ProverCircuit { PiopProver::build(&self, level) } - pub fn verifier_piop>( - &self, - // re-randomized child - child: SwAffine, - // re-randomized parent - parent: C::Affine, - selector: C::Affine, - proof: LevelProof, - zeta: C::ScalarField, - ) -> PiopVerifier> { + fn verifier_circuit(&self, instance: Self::Instance, fixed_cols: &[WrappedAffine], proof: Self::Proof, zeta: C::ScalarField) -> Self::VerifierCircuit { let domain_at_zeta = self.domain.evaluate(zeta); + let selector = fixed_cols[0].clone(); + let (child, x_parent) = instance; PiopVerifier::init( domain_at_zeta, - WrappedAffine(parent), - WrappedAffine(selector), + WrappedAffine(x_parent), + selector, proof.column_commitments.clone(), proof.columns_at_zeta.clone(), self.seed, child, ) } - - // use crate::circuit::prover::PiopProver as PiopProver2; - // pub fn prover2(&self, level: LevelWitnessWithBlinding>) -> PiopProver2> { - // let piop = PiopProver2::build(&self, level); - // piop - // } } impl> PiopParams { @@ -146,7 +138,7 @@ impl> PiopParams { vec![G::BaseField::one(); self.max_nodes], vec![G::BaseField::zero(); self.blinding_bits], ] - .concat(); + .concat(); self.domain.public_column(selector) } diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index e35b97b..4adc61b 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -4,8 +4,9 @@ use crate::auth_path::path::AuthenticationPath; use crate::circuit_tall::prover::PiopProver; use crate::verifier::V; use crate::{Coeffs, CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; +use crate::circuit_tall::CircuitParams; use ark_ec::CurveGroup; -use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; +use ark_ec::short_weierstrass::{Affine as SwAffine, Projective, SWCurveConfig}; use ark_ff::{PrimeField, Zero}; use ark_std::UniformRand; use ark_std::rand::Rng; @@ -17,6 +18,7 @@ use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; use w3f_ring_proof::ArkTranscript; +use crate::circuit_tall::params::PiopParams; impl CycleParams, Projective> where @@ -47,12 +49,12 @@ where } impl> - CycleSideParams> + CycleSideParams> { pub fn prove_side( &self, - blinded_path: Vec>, - witness: Vec>>, + blinded_path: Vec>, + witness: Vec>>, rng: &mut R, ) -> CycleSideProof { // let mut s = std::any::type_name::(); @@ -73,8 +75,8 @@ impl> as ProverPiop< + let piop = > as CircuitParams>::prover_circuit(&self.piop_params, level.clone()); + let blinded_node_ = > as ProverPiop< C::ScalarField, WrappedAffine, >>::result(&piop); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 79e7f35..b66a89d 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -10,6 +10,7 @@ use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::VerifierPiop; use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; use w3f_ring_proof::ArkTranscript; +use crate::circuit_tall::CircuitParams; impl CycleParams, Projective> where @@ -79,10 +80,9 @@ impl::N_COLUMNS + 1, V::::N_CONSTRAINTS, ); - let piop = self.piop_params.verifier_piop( - child, - parent, - selector.0, + let piop = self.piop_params.verifier_circuit( + (child, parent), + &[selector.clone()], level_proof.clone(), challenges.zeta, ); From f09de9d5957289317667cc1666e0d111a47a9804 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 28 May 2026 21:31:52 +0300 Subject: [PATCH 22/42] fat circuit updated --- pasta-tree/src/circuit_fat/mod.rs | 75 ++++++++++++++++--------- pasta-tree/src/circuit_fat/prover.rs | 78 ++++++++++++++------------ pasta-tree/src/circuit_fat/verifier.rs | 71 ++++++++++++----------- pasta-tree/src/circuit_tall/mod.rs | 34 +++++------ pasta-tree/src/circuit_tall/params.rs | 18 ++++-- pasta-tree/src/prover.rs | 9 ++- pasta-tree/src/verifier.rs | 2 +- 7 files changed, 164 insertions(+), 123 deletions(-) diff --git a/pasta-tree/src/circuit_fat/mod.rs b/pasta-tree/src/circuit_fat/mod.rs index c7fab85..30be6ae 100644 --- a/pasta-tree/src/circuit_fat/mod.rs +++ b/pasta-tree/src/circuit_fat/mod.rs @@ -1,33 +1,46 @@ +use ark_ec::CurveGroup; use ark_ff::PrimeField; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; -use w3f_pcs::pcs::Commitment; +use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::{ColumnsCommited, ColumnsEvaluated}; pub mod params; pub mod prover; pub mod verifier; +// type PiopProof = w3f_plonk_common::PiopProof< +// ::ScalarField, +// WrappedAffine, +// ProofComms, +// ProofEvals<::ScalarField>, +// >; + #[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] -pub struct ProofComms> { - pub(crate) node_idx: C, - pub(crate) bf_bits: C, - pub(crate) selected_node_acc: C, - pub(crate) blinded_node_acc: [C; 2], - pub(crate) node_idx_sum_acc: C, - pub(crate) phantom: PhantomData, +pub struct ProofComms { + pub(crate) node_idx: WrappedAffine, + pub(crate) bf_bits: WrappedAffine, + pub(crate) selected_node_acc: WrappedAffine, + pub(crate) blinded_node_acc: [WrappedAffine; 2], + pub(crate) node_idx_sum_acc: WrappedAffine, +} + +impl ColumnsCommited> for ProofComms { + fn to_vec(self) -> Vec> { + self.into() + } } -impl> ColumnsCommited for ProofComms { - fn to_vec(self) -> Vec { +impl From> for Vec> { + fn from(value: ProofComms) -> Self { + let [blinded_node_acc_x, blinded_node_acc_y] = value.blinded_node_acc; vec![ - self.node_idx, - self.bf_bits, - self.selected_node_acc, - self.blinded_node_acc[0].clone(), - self.blinded_node_acc[1].clone(), - self.node_idx_sum_acc, + value.node_idx, + value.bf_bits, + value.selected_node_acc, + blinded_node_acc_x, + blinded_node_acc_y, + value.node_idx_sum_acc, ] } } @@ -43,18 +56,24 @@ pub struct ProofEvals { pub(crate) node_idx_sum_acc: F, } -impl ColumnsEvaluated for ProofEvals { - fn to_vec(self) -> Vec { +impl From> for Vec { + fn from(value: ProofEvals) -> Self { vec![ - self.x_coords, - self.h_powers[0], - self.h_powers[1], - self.node_idx, - self.bf_bits, - self.selected_node_acc, - self.blinded_node_acc[0], - self.blinded_node_acc[1], - self.node_idx_sum_acc, + value.x_coords, + value.h_powers[0], + value.h_powers[1], + value.node_idx, + value.bf_bits, + value.selected_node_acc, + value.blinded_node_acc[0], + value.blinded_node_acc[1], + value.node_idx_sum_acc, ] } } + +impl ColumnsEvaluated for ProofEvals { + fn to_vec(self) -> Vec { + self.into() + } +} diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index bd88ce7..29d2720 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -4,12 +4,12 @@ use crate::circuit_fat::{ProofComms, ProofEvals}; use ark_ec::AffineRepr; use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; -use ark_ff::{PrimeField, Zero}; +use ark_ff::One; +use ark_ff::{FftField, PrimeField, Zero}; use ark_poly::Evaluations; use ark_poly::univariate::DensePolynomial; -use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; -use w3f_pcs::pcs::Commitment; +use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::ProverGadget; @@ -22,26 +22,26 @@ use w3f_plonk_common::gadgets::fixed_cells::FixedCells; use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInv; use w3f_plonk_common::piop::ProverPiop; -pub struct PiopProver> { - domain: Domain, +pub struct PiopProver> { + domain: Domain, // `x` coordinates of all the children of a node. Public input. - nodes: FieldColumn, + nodes: FieldColumn, // `H, 2H, 4H,...,2^sH` Fixed column. - h_powers: AffineColumn, + h_powers: AffineColumn, // `node_x = self.x_coords[self.node_idx]` Private input. - node_idx: BitColumn, + node_idx: BitColumn, // Bits of the chosen blinding factor. Private input. - bf_bits: BitColumn, - selected_node: InnerProdInv, - blinded_node: CondAdd, // blinded_node.acc[0] = (x_i, y_i) = Ci, blinded_node.acc[capacity] = Ci + bf.H = Ci' - node_idx_bool: Booleanity, - bf_bits_bool: Booleanity, - node_idx_sum: ColumnSumPolys, - node_idx_sum_vals: FixedCells, - seed_eq_node: CellsEqPolys, + bf_bits: BitColumn, + selected_node: InnerProdInv, + blinded_node: CondAdd, // blinded_node.acc[0] = (x_i, y_i) = Ci, blinded_node.acc[capacity] = Ci + bf.H = Ci' + node_idx_bool: Booleanity, + bf_bits_bool: Booleanity, + node_idx_sum: ColumnSumPolys, + node_idx_sum_vals: FixedCells, + seed_eq_node: CellsEqPolys, } -impl> PiopProver { +impl> PiopProver { pub fn build(params: &PiopParams, level: LevelWitnessWithBlinding) -> Self { let domain = params.domain.clone(); let x_coords = params.x_coords_column(level.level_witness.x_coords()); @@ -63,8 +63,12 @@ impl> PiopProver { let node_idx_bool = Booleanity::init(node_idx.clone()); let bf_bits_bool = Booleanity::init(bf_bits.clone()); let node_idx_sum = ColumnSumPolys::init(node_idx.col.clone(), &domain); - let node_idx_sum_vals = - FixedCells::init(node_idx_sum.acc.clone(), &domain, F::zero(), F::one()); + let node_idx_sum_vals = FixedCells::init( + node_idx_sum.acc.clone(), + &domain, + G::BaseField::zero(), + G::BaseField::one(), + ); let seed_eq_node = CellsEqPolys::first_cells( selected_node.acc.clone(), blinded_node.acc.xs.clone(), @@ -87,10 +91,13 @@ impl> PiopProver { } } - fn _committed_columns, Fun: Fn(&DensePolynomial) -> C>( + fn _committed_columns< + C: CurveGroup, + Fun: Fn(&DensePolynomial) -> WrappedAffine, + >( &self, commit: Fun, - ) -> ProofComms { + ) -> ProofComms { let node_idx = commit(self.node_idx.as_poly()); let bf_bits = commit(self.bf_bits.as_poly()); let selected_node_acc = commit(self.selected_node.acc.as_poly()); @@ -105,13 +112,12 @@ impl> PiopProver { selected_node_acc, blinded_node_acc, node_idx_sum_acc, - phantom: PhantomData, } } // 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.nodes.as_poly().clone(), self.h_powers.xs.as_poly().clone(), @@ -125,7 +131,7 @@ impl> PiopProver { ] } - fn _columns_evaluated(&self, zeta: &F) -> ProofEvals { + fn _columns_evaluated(&self, zeta: &G::BaseField) -> ProofEvals { let x_coords = self.nodes.evaluate(zeta); let h_powers = [ self.h_powers.xs.evaluate(zeta), @@ -151,15 +157,15 @@ impl> PiopProver { } } -impl, G: SWCurveConfig> ProverPiop - for PiopProver> +impl> + ProverPiop> for PiopProver> { const N_CONSTRAINTS: usize = 13; - type Commitments = ProofComms; - type Evaluations = ProofEvals; + type Commitments = ProofComms; + type Evaluations = ProofEvals; type Instance = SwAffine; - fn committed_columns) -> C>( + fn committed_columns) -> WrappedAffine>( &self, commit: Fun, ) -> Self::Commitments { @@ -168,15 +174,15 @@ impl, G: SWCurveConfig> ProverPio // Should return polynomials in the consistent with // Self::Evaluations::to_vec() and Self::Commitments::to_vec(). - fn columns(&self) -> Vec> { + fn columns(&self) -> Vec> { self._columns() } - fn columns_evaluated(&self, zeta: &F) -> Self::Evaluations { + fn columns_evaluated(&self, zeta: &C::ScalarField) -> Self::Evaluations { self._columns_evaluated(zeta) } - fn constraints(&self) -> Vec> { + fn constraints(&self) -> Vec> { let (node_blinded_x, node_blinded_y) = self.blinded_node.seed_plus_sum().xy().unwrap(); vec![ self.selected_node.constraints(), @@ -201,7 +207,7 @@ impl, G: SWCurveConfig> ProverPio &self.selected_node.acc, &self.domain.l_last, self.domain.capacity - 1, - F::zero(), + C::ScalarField::zero(), )], self.seed_eq_node.constraints(), vec![self.blinded_node.acc.on_curve_constraint()], @@ -212,13 +218,13 @@ impl, G: SWCurveConfig> ProverPio &self.nodes, &self.domain.l_last, self.domain.capacity - 1, - F::one(), + C::ScalarField::one(), )], ] .concat() } - fn constraints_lin(&self, zeta: &F) -> Vec> { + fn constraints_lin(&self, zeta: &C::ScalarField) -> Vec> { vec![ self.selected_node.constraints_linearized(zeta), self.blinded_node.constraints_linearized(zeta), @@ -236,7 +242,7 @@ impl, G: SWCurveConfig> ProverPio .concat() } - fn domain(&self) -> &Domain { + fn domain(&self) -> &Domain { &self.domain } diff --git a/pasta-tree/src/circuit_fat/verifier.rs b/pasta-tree/src/circuit_fat/verifier.rs index 9cd737b..5f86391 100644 --- a/pasta-tree/src/circuit_fat/verifier.rs +++ b/pasta-tree/src/circuit_fat/verifier.rs @@ -1,11 +1,11 @@ -use ark_ec::AffineRepr; +use crate::circuit_fat::{ProofComms, ProofEvals}; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; -use ark_ff::PrimeField; +use ark_ec::{AffineRepr, CurveGroup}; +use ark_ff::One; +use ark_ff::Zero; use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; -use w3f_pcs::pcs::Commitment; - -use crate::circuit_fat::{ProofComms, ProofEvals}; +use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::domain::EvaluatedDomain; use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::gadgets::booleanity::BooleanityValues; @@ -16,30 +16,30 @@ use w3f_plonk_common::gadgets::fixed_cells::FixedCellsValues; use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInvValues; use w3f_plonk_common::piop::VerifierPiop; -pub struct PiopVerifier, G: AffineRepr> { - domain_evals: EvaluatedDomain, +pub struct PiopVerifier> { + domain_evals: EvaluatedDomain, instance: G, - x_coords_comm: C, - h_powers_comm: [C; 2], - witness_columns: ProofComms, + x_coords_comm: WrappedAffine, + h_powers_comm: [WrappedAffine; 2], + witness_columns: ProofComms, // Gadget verifiers: - selected_node: InnerProdInvValues, - blinded_node: CondAddValues, - node_idx_sum: ColumnSumEvals, - node_idx_bool: BooleanityValues, - bf_bits_bool: BooleanityValues, - node_idx_sum_vals: FixedCellsValues, - seed_eq_node: EqualCells, + selected_node: InnerProdInvValues, + blinded_node: CondAddValues, + node_idx_sum: ColumnSumEvals, + node_idx_bool: BooleanityValues, + bf_bits_bool: BooleanityValues, + node_idx_sum_vals: FixedCellsValues, + seed_eq_node: EqualCells, } -impl, G: AffineRepr> PiopVerifier { +impl> PiopVerifier { pub fn init( instance: G, - blinded_parent: C, - domain_evals: EvaluatedDomain, - h_powers_comm: [C; 2], - witness_columns: ProofComms, - all_evals: ProofEvals, + blinded_parent: WrappedAffine, + domain_evals: EvaluatedDomain, + h_powers_comm: [WrappedAffine; 2], + witness_columns: ProofComms, + all_evals: ProofEvals, ) -> Self { let selected_node = InnerProdInvValues { a: all_evals.x_coords, @@ -67,8 +67,8 @@ impl, G: AffineRepr> PiopVerifier }; let node_idx_sum_vals = FixedCellsValues { col: all_evals.node_idx_sum_acc, - col_first: F::zero(), - col_last: F::one(), + col_first: C::ScalarField::zero(), + col_last: C::ScalarField::one(), l_first: domain_evals.l_first, l_last: domain_evals.l_last, }; @@ -95,13 +95,13 @@ impl, G: AffineRepr> PiopVerifier } } -impl, G: SWCurveConfig> VerifierPiop - for PiopVerifier> +impl> + VerifierPiop> for PiopVerifier> { const N_CONSTRAINTS: usize = 13; const N_COLUMNS: usize = 9; - fn precommitted_columns(&self) -> Vec { + fn precommitted_columns(&self) -> Vec> { vec![ self.x_coords_comm.clone(), self.h_powers_comm[0].clone(), @@ -109,7 +109,7 @@ impl, G: SWCurveConfig> VerifierP ] } - fn evaluate_constraints_main(&self) -> Vec { + fn evaluate_constraints_main(&self) -> Vec { let (x, y) = self.instance.xy().unwrap(); vec![ self.selected_node.evaluate_constraints_main(), @@ -131,22 +131,25 @@ impl, G: SWCurveConfig> VerifierP vec![FixedCellsValues::evaluate_for_cell( self.selected_node.acc, self.domain_evals.l_last, - F::zero(), + C::ScalarField::zero(), )], self.seed_eq_node.evaluate_constraints_main(), - vec![AffineColumn::>::on_curve_eval( + vec![AffineColumn::>::on_curve_eval( self.blinded_node.acc, )], vec![FixedCellsValues::evaluate_for_cell( self.selected_node.a, self.domain_evals.l_last, - F::one(), + C::ScalarField::one(), )], ] .concat() } - fn lin_poly_commitment(&self, agg_coeffs: &[F]) -> (Vec, Vec) { + fn lin_poly_commitment( + &self, + agg_coeffs: &[C::ScalarField], + ) -> (Vec, Vec>) { assert_eq!(agg_coeffs.len(), Self::N_CONSTRAINTS); let selected_node_acc = self.witness_columns.selected_node_acc.clone(); @@ -179,7 +182,7 @@ impl, G: SWCurveConfig> VerifierP ) } - fn domain_evaluated(&self) -> &EvaluatedDomain { + fn domain_evaluated(&self) -> &EvaluatedDomain { &self.domain_evals } } diff --git a/pasta-tree/src/circuit_tall/mod.rs b/pasta-tree/src/circuit_tall/mod.rs index 083292e..ab6d82f 100644 --- a/pasta-tree/src/circuit_tall/mod.rs +++ b/pasta-tree/src/circuit_tall/mod.rs @@ -36,18 +36,20 @@ pub trait CircuitParams { fn prover_circuit(&self, w: Self::Witness) -> Self::ProverCircuit; - fn verifier_circuit(&self, - instance: Self::Instance, - fixed_cols: &[WrappedAffine], - proof: Self::Proof, - zeta: C::ScalarField) -> Self::VerifierCircuit; + fn verifier_circuit( + &self, + instance: Self::Instance, + fixed_cols: &[WrappedAffine], + proof: Self::Proof, + zeta: C::ScalarField, + ) -> Self::VerifierCircuit; } type PiopProof = w3f_plonk_common::PiopProof< ::ScalarField, WrappedAffine, ProofComms, - ProofEvals<::ScalarField> + ProofEvals<::ScalarField>, >; #[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] @@ -92,20 +94,20 @@ pub struct ProofEvals { impl ColumnsEvaluated for ProofEvals { fn to_vec(self) -> Vec { - vec![ - self.points[0], - self.ring_selector, - self.points[1], - self.bits, - self.inn_prod_acc, - self.cond_add_acc[0], - self.cond_add_acc[1], - ] + self.into() } } impl From> for Vec { fn from(value: ProofEvals) -> Self { - value.to_vec() + vec![ + value.points[0], + value.ring_selector, + value.points[1], + value.bits, + value.inn_prod_acc, + value.cond_add_acc[0], + value.cond_add_acc[1], + ] } } diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 9267eec..3f8bef4 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -1,17 +1,17 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::prover::PiopProver; use crate::circuit_tall::verifier::PiopVerifier; +use crate::circuit_tall::{CircuitParams, PiopProof}; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::One; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; -use w3f_plonk_common::{FieldColumn}; +use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; -use crate::circuit_tall::{CircuitParams, PiopProof}; /// Plonk Interactive Oracle Proofs (PIOP) parameters. /// `max_nodes + blinding_bits = domain.capacity - 1` @@ -27,7 +27,9 @@ pub struct PiopParams> { pub h: G, } -impl> CircuitParams for PiopParams> { +impl> CircuitParams + for PiopParams> +{ type Witness = LevelWitnessWithBlinding>; /// (re-randomized child, re-randomized parent) @@ -40,7 +42,13 @@ impl> CircuitParams PiopProver::build(&self, level) } - fn verifier_circuit(&self, instance: Self::Instance, fixed_cols: &[WrappedAffine], proof: Self::Proof, zeta: C::ScalarField) -> Self::VerifierCircuit { + fn verifier_circuit( + &self, + instance: Self::Instance, + fixed_cols: &[WrappedAffine], + proof: Self::Proof, + zeta: C::ScalarField, + ) -> Self::VerifierCircuit { let domain_at_zeta = self.domain.evaluate(zeta); let selector = fixed_cols[0].clone(); let (child, x_parent) = instance; @@ -138,7 +146,7 @@ impl> PiopParams { vec![G::BaseField::one(); self.max_nodes], vec![G::BaseField::zero(); self.blinding_bits], ] - .concat(); + .concat(); self.domain.public_column(selector) } diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 4adc61b..11b3775 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -1,10 +1,11 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; +use crate::circuit_tall::CircuitParams; +use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::prover::PiopProver; use crate::verifier::V; use crate::{Coeffs, CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; -use crate::circuit_tall::CircuitParams; use ark_ec::CurveGroup; use ark_ec::short_weierstrass::{Affine as SwAffine, Projective, SWCurveConfig}; use ark_ff::{PrimeField, Zero}; @@ -18,7 +19,6 @@ use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; use w3f_ring_proof::ArkTranscript; -use crate::circuit_tall::params::PiopParams; impl CycleParams, Projective> where @@ -75,7 +75,10 @@ impl> as CircuitParams>::prover_circuit(&self.piop_params, level.clone()); + let piop = > as CircuitParams>::prover_circuit( + &self.piop_params, + level.clone(), + ); let blinded_node_ = > as ProverPiop< C::ScalarField, WrappedAffine, diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index b66a89d..72b8ccc 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,4 +1,5 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; +use crate::circuit_tall::CircuitParams; use crate::circuit_tall::verifier::PiopVerifier; use crate::{CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; use ark_ec::CurveGroup; @@ -10,7 +11,6 @@ use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::VerifierPiop; use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; use w3f_ring_proof::ArkTranscript; -use crate::circuit_tall::CircuitParams; impl CycleParams, Projective> where From a30878b1a0e9d77c65edbd3224460415001c1182 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 28 May 2026 22:24:24 +0300 Subject: [PATCH 23/42] trait moved --- pasta-tree/src/circuit_fat/mod.rs | 14 ++++----- pasta-tree/src/circuit_fat/params.rs | 44 ++++++++++++++++++++++++++- pasta-tree/src/circuit_tall/mod.rs | 36 ---------------------- pasta-tree/src/circuit_tall/params.rs | 6 ++-- pasta-tree/src/lib.rs | 20 ++++++++++++ pasta-tree/src/prover.rs | 2 +- pasta-tree/src/verifier.rs | 2 +- 7 files changed, 76 insertions(+), 48 deletions(-) diff --git a/pasta-tree/src/circuit_fat/mod.rs b/pasta-tree/src/circuit_fat/mod.rs index 30be6ae..6e9a709 100644 --- a/pasta-tree/src/circuit_fat/mod.rs +++ b/pasta-tree/src/circuit_fat/mod.rs @@ -1,4 +1,4 @@ -use ark_ec::CurveGroup; +use ark_ec::{CurveGroup, PrimeGroup}; use ark_ff::PrimeField; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::{vec, vec::Vec}; @@ -9,12 +9,12 @@ pub mod params; pub mod prover; pub mod verifier; -// type PiopProof = w3f_plonk_common::PiopProof< -// ::ScalarField, -// WrappedAffine, -// ProofComms, -// ProofEvals<::ScalarField>, -// >; +type PiopProof = w3f_plonk_common::PiopProof< + ::ScalarField, + WrappedAffine, + ProofComms, + ProofEvals<::ScalarField>, +>; #[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct ProofComms { diff --git a/pasta-tree/src/circuit_fat/params.rs b/pasta-tree/src/circuit_fat/params.rs index 67fa024..d76bed8 100644 --- a/pasta-tree/src/circuit_fat/params.rs +++ b/pasta-tree/src/circuit_fat/params.rs @@ -1,8 +1,14 @@ +use crate::CircuitParams; +use crate::auth_path::node::LevelWitnessWithBlinding; +use crate::circuit_fat::PiopProof; +use crate::circuit_fat::prover::PiopProver; +use crate::circuit_fat::verifier::PiopVerifier; +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::One; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; use ark_std::{vec, vec::Vec}; - +use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; @@ -19,6 +25,42 @@ pub struct PiopParams> { pub h: G, } +impl> CircuitParams + for PiopParams> +{ + type Witness = LevelWitnessWithBlinding>; + + /// (re-randomized child, re-randomized parent) + type Instance = (SwAffine, C::Affine); + type Proof = PiopProof; + type ProverCircuit = PiopProver>; + type VerifierCircuit = PiopVerifier>; + + fn prover_circuit(&self, level: Self::Witness) -> Self::ProverCircuit { + PiopProver::build(&self, level) + } + + fn verifier_circuit( + &self, + instance: Self::Instance, + fixed_cols: &[WrappedAffine], + proof: Self::Proof, + zeta: C::ScalarField, + ) -> Self::VerifierCircuit { + let h_powers_comm: &[_; 2] = fixed_cols.try_into().expect("Expected 2 fixed columns"); + let domain_at_zeta = self.domain.evaluate(zeta); + let (child, x_parent) = instance; + PiopVerifier::init( + child, + WrappedAffine(x_parent), + domain_at_zeta, + h_powers_comm.clone(), + proof.column_commitments.clone(), + proof.columns_at_zeta.clone(), + ) + } +} + impl> PiopParams { pub fn setup(domain: Domain, h: G) -> Self { let scalar_bitlen = G::ScalarField::MODULUS_BIT_SIZE as usize; diff --git a/pasta-tree/src/circuit_tall/mod.rs b/pasta-tree/src/circuit_tall/mod.rs index ab6d82f..48d3514 100644 --- a/pasta-tree/src/circuit_tall/mod.rs +++ b/pasta-tree/src/circuit_tall/mod.rs @@ -3,48 +3,12 @@ use ark_ff::PrimeField; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; -use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::{ColumnsCommited, ColumnsEvaluated}; pub mod params; pub mod prover; pub mod verifier; -// struct SideProofParams { -// _phantom: PhantomData -// } -// -// impl GenericProofParams for SideProofParams { -// type Cols = ProofComms; -// type Evals = ProofEvals; -// } -// -// pub type LevelProof = PiopProof< -// ::ScalarField, -// WrappedAffine, -// ProofComms, -// ProofEvals<::ScalarField>, -// >; - -/// The circuit is over `C::ScalarField`. -pub trait CircuitParams { - type Witness; - type Instance; - type Proof; - type ProverCircuit: ProverPiop>; - type VerifierCircuit: VerifierPiop>; - - fn prover_circuit(&self, w: Self::Witness) -> Self::ProverCircuit; - - fn verifier_circuit( - &self, - instance: Self::Instance, - fixed_cols: &[WrappedAffine], - proof: Self::Proof, - zeta: C::ScalarField, - ) -> Self::VerifierCircuit; -} - type PiopProof = w3f_plonk_common::PiopProof< ::ScalarField, WrappedAffine, diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 3f8bef4..00e15d0 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -1,7 +1,8 @@ +use crate::CircuitParams; use crate::auth_path::node::LevelWitnessWithBlinding; +use crate::circuit_tall::PiopProof; use crate::circuit_tall::prover::PiopProver; use crate::circuit_tall::verifier::PiopVerifier; -use crate::circuit_tall::{CircuitParams, PiopProof}; use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::One; @@ -49,8 +50,9 @@ impl> CircuitParams< proof: Self::Proof, zeta: C::ScalarField, ) -> Self::VerifierCircuit { - let domain_at_zeta = self.domain.evaluate(zeta); + assert_eq!(fixed_cols.len(), 1, "Expected 1 fixed columns"); let selector = fixed_cols[0].clone(); + let domain_at_zeta = self.domain.evaluate(zeta); let (child, x_parent) = instance; PiopVerifier::init( domain_at_zeta, diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 3ce5923..7eae4ef 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -11,6 +11,7 @@ use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::AggregateProof; use w3f_plonk_common::PiopProof; use w3f_plonk_common::domain::Domain; +use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; pub mod auth_path; pub mod circuit_fat; @@ -515,3 +516,22 @@ mod tests { assert_eq!(res_, res); } } + +/// The circuit is over `C::ScalarField`. +pub trait CircuitParams { + type Witness; + type Instance; + type Proof; + type ProverCircuit: ProverPiop>; + type VerifierCircuit: VerifierPiop>; + + fn prover_circuit(&self, w: Self::Witness) -> Self::ProverCircuit; + + fn verifier_circuit( + &self, + instance: Self::Instance, + fixed_cols: &[WrappedAffine], + proof: Self::Proof, + zeta: C::ScalarField, + ) -> Self::VerifierCircuit; +} diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 11b3775..7a706cc 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -1,7 +1,7 @@ +use crate::CircuitParams; use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; -use crate::circuit_tall::CircuitParams; use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::prover::PiopProver; use crate::verifier::V; diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 72b8ccc..7fbe87f 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,5 +1,5 @@ +use crate::CircuitParams; use crate::auth_path::blinded::BlindedAuthenticationPath; -use crate::circuit_tall::CircuitParams; use crate::circuit_tall::verifier::PiopVerifier; use crate::{CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; use ark_ec::CurveGroup; From ad6110c9af255a0c71a8ca8586da468f70a21074 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 08:45:15 +0300 Subject: [PATCH 24/42] traits simplified --- pasta-tree/src/lib.rs | 6 ++---- pasta-tree/src/prover.rs | 2 +- pasta-tree/src/verifier.rs | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 7eae4ef..174c92b 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -49,10 +49,8 @@ pub struct CycleSideProof { #[derive(Clone)] pub struct CurveTreeProof< - F0: PrimeField, - F1: PrimeField, - C0: CurveGroup, - C1: CurveGroup, + C0: CurveGroup, + C1: CurveGroup, > { c0_proof: CycleSideProof, c1_proof: CycleSideProof, diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 7a706cc..075bbad 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -33,7 +33,7 @@ where rng: &mut R, ) -> ( BlindedAuthenticationPath, Projective>, - CurveTreeProof, Projective>, + CurveTreeProof, Projective>, ) { let auth_path_with_bf = auth_path.with_blinding(rng); let blinded_auth_path = auth_path_with_bf.apply_bfs(&self); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 7fbe87f..9ebaa01 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -22,7 +22,7 @@ where pub fn verify( &self, auth_path: BlindedAuthenticationPath, Projective>, - proof: CurveTreeProof, Projective>, + proof: CurveTreeProof, Projective>, root: Affine, ) -> bool { let BlindedAuthenticationPath { c0_path, c1_path } = auth_path; From 588bea59566bbfa10ead1f86b1c5942c1a1589ee Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 09:14:52 +0300 Subject: [PATCH 25/42] te gadget disabled --- pasta-tree/src/circuit_fat/prover.rs | 6 +-- pasta-tree/src/circuit_fat/verifier.rs | 8 +-- w3f-plonk-common/src/gadgets/ec/mod.rs | 4 +- .../src/gadgets/ec/sw_cond_add.rs | 49 ++++++++++--------- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index 29d2720..3eb4694 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -160,7 +160,7 @@ impl> PiopProver { impl> ProverPiop> for PiopProver> { - const N_CONSTRAINTS: usize = 13; + const N_CONSTRAINTS: usize = 12; type Commitments = ProofComms; type Evaluations = ProofEvals; type Instance = SwAffine; @@ -210,7 +210,7 @@ impl> C::ScalarField::zero(), )], self.seed_eq_node.constraints(), - vec![self.blinded_node.acc.on_curve_constraint()], + // vec![self.blinded_node.acc.on_curve_constraint()], // this prevents opening to -parent=(x,-y) // parent = commit([x1, ..., xl, 1, 0, 0, 0]; 0) = x1.G1 + ... + xl.Gl + 1.G_{l+1} // then -parent = commit([-x1, ..., -xl, -1, 0, 0, 0]; 0) @@ -236,7 +236,7 @@ impl> vec![DensePolynomial::zero()], vec![DensePolynomial::zero()], self.seed_eq_node.constraints_linearized(zeta), - vec![DensePolynomial::zero()], + // vec![DensePolynomial::zero()], vec![DensePolynomial::zero()], ] .concat() diff --git a/pasta-tree/src/circuit_fat/verifier.rs b/pasta-tree/src/circuit_fat/verifier.rs index 5f86391..1870993 100644 --- a/pasta-tree/src/circuit_fat/verifier.rs +++ b/pasta-tree/src/circuit_fat/verifier.rs @@ -98,7 +98,7 @@ impl> PiopVerifier> VerifierPiop> for PiopVerifier> { - const N_CONSTRAINTS: usize = 13; + const N_CONSTRAINTS: usize = 12; const N_COLUMNS: usize = 9; fn precommitted_columns(&self) -> Vec> { @@ -134,9 +134,9 @@ impl> C::ScalarField::zero(), )], self.seed_eq_node.evaluate_constraints_main(), - vec![AffineColumn::>::on_curve_eval( - self.blinded_node.acc, - )], + // vec![AffineColumn::>::on_curve_eval( + // self.blinded_node.acc, + // )], vec![FixedCellsValues::evaluate_for_cell( self.selected_node.a, self.domain_evals.l_last, diff --git a/w3f-plonk-common/src/gadgets/ec/mod.rs b/w3f-plonk-common/src/gadgets/ec/mod.rs index 7c54d37..cdfa95f 100644 --- a/w3f-plonk-common/src/gadgets/ec/mod.rs +++ b/w3f-plonk-common/src/gadgets/ec/mod.rs @@ -9,8 +9,8 @@ use ark_std::marker::PhantomData; use ark_std::vec::Vec; pub mod sw_cond_add; -pub mod te_cond_add; -pub mod te_doubling; +// pub mod te_cond_add; +// pub mod te_doubling; // A vec of affine points from the prime-order subgroup of the curve whose base field enables FFTs, // and its convenience representation as columns of coordinates over the curve's base field. diff --git a/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs b/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs index c13981b..2726993 100644 --- a/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs +++ b/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs @@ -1,4 +1,5 @@ -use ark_ec::short_weierstrass::{Affine, SWCurveConfig}; +use ark_ec::AffineRepr; +// use ark_ec::short_weierstrass::{Affine, SWCurveConfig}; use ark_ff::{FftField, Field}; use ark_poly::univariate::DensePolynomial; use ark_poly::{Evaluations, GeneralEvaluationDomain}; @@ -8,27 +9,29 @@ use crate::gadgets::ec::{AffineColumn, CondAdd, CondAddValues}; use crate::gadgets::{ProverGadget, VerifierGadget}; use crate::{const_evals, Column}; -impl> AffineColumn> { - // y^2 = x^3 + ax + b - pub fn on_curve_constraint(&self) -> Evaluations { - let domain = self.xs.domain_4x(); - let sw_coeff_a = &const_evals(Curve::COEFF_A, domain); - let sw_coeff_b = &const_evals(Curve::COEFF_B, domain); - let x = &self.xs.evals_4x; - let y = &self.ys.evals_4x; - - &(&(y * y) - &(&(x * x) * x)) - &(&(sw_coeff_a * x) + &sw_coeff_b) - } - - pub fn on_curve_eval((x, y): (F, F)) -> F { - y * y - x * x * x - Curve::COEFF_A * x - Curve::COEFF_B - } -} - -impl ProverGadget for CondAdd> +// impl> AffineColumn> { +// // y^2 = x^3 + ax + b +// pub fn on_curve_constraint(&self) -> Evaluations { +// let domain = self.xs.domain_4x(); +// let sw_coeff_a = &const_evals(Curve::COEFF_A, domain); +// let sw_coeff_b = &const_evals(Curve::COEFF_B, domain); +// let x = &self.xs.evals_4x; +// let y = &self.ys.evals_4x; +// +// &(&(y * y) - &(&(x * x) * x)) - &(&(sw_coeff_a * x) + &sw_coeff_b) +// } +// +// pub fn on_curve_eval((x, y): (F, F)) -> F { +// y * y - x * x * x - Curve::COEFF_A * x - Curve::COEFF_B +// } +// } + +// impl ProverGadget for CondAdd> +impl ProverGadget for CondAdd where F: FftField, - Curve: SWCurveConfig, + // Curve: SWCurveConfig, + Curve: AffineRepr, { fn witness_columns(&self) -> Vec> { vec![self.acc.xs.poly.clone(), self.acc.ys.poly.clone()] @@ -107,7 +110,8 @@ where } } -impl> CondAddValues> { +// impl> CondAddValues> { +impl> CondAddValues { pub fn acc_coeffs_1(&self) -> (F, F) { let b = self.bitmask; let (x1, _y1) = self.acc; @@ -137,7 +141,8 @@ impl> CondAddValues> { } } -impl> VerifierGadget for CondAddValues> { +// impl> VerifierGadget for CondAddValues> { +impl> VerifierGadget for CondAddValues { fn evaluate_constraints_main(&self) -> Vec { let b = self.bitmask; let (x1, y1) = self.acc; From 65ae8bcdb190763368ba478d1f39ccacde83b6f3 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 09:20:33 +0300 Subject: [PATCH 26/42] tall circuit uses AffineRepr --- pasta-tree/src/circuit_tall/params.rs | 14 +++++++------- pasta-tree/src/circuit_tall/prover.rs | 14 +++++++------- pasta-tree/src/circuit_tall/verifier.rs | 6 +++--- pasta-tree/src/lib.rs | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 00e15d0..e15bf2f 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -3,7 +3,7 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::PiopProof; use crate::circuit_tall::prover::PiopProver; use crate::circuit_tall::verifier::PiopVerifier; -use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +// use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::One; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; @@ -28,16 +28,16 @@ pub struct PiopParams> { pub h: G, } -impl> CircuitParams - for PiopParams> +impl> CircuitParams + for PiopParams { - type Witness = LevelWitnessWithBlinding>; + type Witness = LevelWitnessWithBlinding; /// (re-randomized child, re-randomized parent) - type Instance = (SwAffine, C::Affine); + type Instance = (G, C::Affine); type Proof = PiopProof; - type ProverCircuit = PiopProver>; - type VerifierCircuit = PiopVerifier>; + type ProverCircuit = PiopProver; + type VerifierCircuit = PiopVerifier; fn prover_circuit(&self, level: Self::Witness) -> Self::ProverCircuit { PiopProver::build(&self, level) diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index 6e3be10..3a4ac43 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -1,7 +1,7 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::{ProofComms, ProofEvals}; -use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +// use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::{FftField, One, PrimeField, Zero}; use ark_poly::Evaluations; @@ -49,10 +49,10 @@ pub struct PiopProver> { result: G, } -impl> PiopProver> { +impl> PiopProver { pub fn build( - params: &PiopParams>, - level: LevelWitnessWithBlinding>, + params: &PiopParams, + level: LevelWitnessWithBlinding, ) -> Self { let domain = params.domain.clone(); let points = params.points_column(level.level_witness.siblings); @@ -101,13 +101,13 @@ impl> PiopProver> { } } -impl> - ProverPiop> for PiopProver> +impl> + ProverPiop> for PiopProver { const N_CONSTRAINTS: usize = 7; type Commitments = ProofComms; type Evaluations = ProofEvals; - type Instance = SwAffine; + type Instance = G; fn committed_columns) -> WrappedAffine>( &self, diff --git a/pasta-tree/src/circuit_tall/verifier.rs b/pasta-tree/src/circuit_tall/verifier.rs index d883913..74df3dd 100644 --- a/pasta-tree/src/circuit_tall/verifier.rs +++ b/pasta-tree/src/circuit_tall/verifier.rs @@ -1,7 +1,7 @@ use crate::circuit_tall::{ProofComms, ProofEvals}; use ark_ec::AffineRepr; use ark_ec::CurveGroup; -use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +// use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ff::{One, Zero}; use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; @@ -99,8 +99,8 @@ impl> PiopVerifier> - VerifierPiop> for PiopVerifier> +impl> + VerifierPiop> for PiopVerifier { const N_CONSTRAINTS: usize = 7; const N_COLUMNS: usize = 7; diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 174c92b..cf6d098 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -14,7 +14,7 @@ use w3f_plonk_common::domain::Domain; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; pub mod auth_path; -pub mod circuit_fat; +// pub mod circuit_fat; pub mod circuit_tall; // pub mod level; pub mod prover; From 1d5cd2c9e782fb59248774f1d97d213b6e639def Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 09:32:04 +0300 Subject: [PATCH 27/42] all switched to AffineRepr --- pasta-tree/src/circuit_tall/params.rs | 6 ++-- pasta-tree/src/lib.rs | 41 ++++++++++++++------------- pasta-tree/src/prover.rs | 32 ++++++++++----------- pasta-tree/src/verifier.rs | 30 +++++++++----------- 4 files changed, 53 insertions(+), 56 deletions(-) diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index e15bf2f..12a1242 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -28,18 +28,16 @@ pub struct PiopParams> { pub h: G, } -impl> CircuitParams +impl> CircuitParams for PiopParams { - type Witness = LevelWitnessWithBlinding; - /// (re-randomized child, re-randomized parent) type Instance = (G, C::Affine); type Proof = PiopProof; type ProverCircuit = PiopProver; type VerifierCircuit = PiopVerifier; - fn prover_circuit(&self, level: Self::Witness) -> Self::ProverCircuit { + fn prover_circuit(&self, level: LevelWitnessWithBlinding) -> Self::ProverCircuit { PiopProver::build(&self, level) } diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index cf6d098..50b1ca5 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -12,6 +12,7 @@ use w3f_pcs::shplonk::AggregateProof; use w3f_plonk_common::PiopProof; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; +use crate::auth_path::node::LevelWitnessWithBlinding; pub mod auth_path; // pub mod circuit_fat; @@ -20,6 +21,25 @@ pub mod circuit_tall; pub mod prover; pub mod verifier; +/// The circuit is over `C::ScalarField`. +pub trait CircuitParams { + type Instance; + type Proof; + type ProverCircuit: ProverPiop>; + type VerifierCircuit: VerifierPiop>; + + fn prover_circuit(&self, level: LevelWitnessWithBlinding) -> Self::ProverCircuit; + + fn verifier_circuit( + &self, + instance: Self::Instance, + fixed_cols: &[WrappedAffine], + proof: Self::Proof, + zeta: C::ScalarField, + ) -> Self::VerifierCircuit; +} + + pub struct CycleSideParams> { pcs_params: HidingIpa, piop_params: PiopParams, @@ -513,23 +533,4 @@ mod tests { assert_eq!(res_, res); } -} - -/// The circuit is over `C::ScalarField`. -pub trait CircuitParams { - type Witness; - type Instance; - type Proof; - type ProverCircuit: ProverPiop>; - type VerifierCircuit: VerifierPiop>; - - fn prover_circuit(&self, w: Self::Witness) -> Self::ProverCircuit; - - fn verifier_circuit( - &self, - instance: Self::Instance, - fixed_cols: &[WrappedAffine], - proof: Self::Proof, - zeta: C::ScalarField, - ) -> Self::VerifierCircuit; -} +} \ No newline at end of file diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 075bbad..d254648 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -4,10 +4,9 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::prover::PiopProver; -use crate::verifier::V; use crate::{Coeffs, CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; -use ark_ec::CurveGroup; -use ark_ec::short_weierstrass::{Affine as SwAffine, Projective, SWCurveConfig}; +use ark_ec::{AffineRepr, CurveGroup}; +// use ark_ec::short_weierstrass::{Affine as SwAffine, Projective, SWCurveConfig}; use ark_ff::{PrimeField, Zero}; use ark_std::UniformRand; use ark_std::rand::Rng; @@ -19,21 +18,22 @@ use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; use w3f_ring_proof::ArkTranscript; +use crate::circuit_tall::verifier::PiopVerifier; -impl CycleParams, Projective> +impl CycleParams where F0: PrimeField, F1: PrimeField, - C0: SWCurveConfig, - C1: SWCurveConfig, + C0: CurveGroup, + C1: CurveGroup, { pub fn prove( &self, - auth_path: AuthenticationPath, Projective>, + auth_path: AuthenticationPath, rng: &mut R, ) -> ( - BlindedAuthenticationPath, Projective>, - CurveTreeProof, Projective>, + BlindedAuthenticationPath, + CurveTreeProof, ) { let auth_path_with_bf = auth_path.with_blinding(rng); let blinded_auth_path = auth_path_with_bf.apply_bfs(&self); @@ -48,13 +48,13 @@ where } } -impl> - CycleSideParams> +impl> + CycleSideParams { pub fn prove_side( &self, - blinded_path: Vec>, - witness: Vec>>, + blinded_path: Vec, + witness: Vec>, rng: &mut R, ) -> CycleSideProof { // let mut s = std::any::type_name::(); @@ -62,7 +62,7 @@ impl::N_COLUMNS + 2; // plus the quotient and the linearization polys + let n_polys = PiopVerifier::::N_COLUMNS + 2; // plus the quotient and the linearization polys let mut piop_proofs = Vec::with_capacity(witness.len()); let mut polys = Vec::with_capacity(witness.len() * n_polys); let mut coords = Vec::with_capacity(witness.len() * n_polys); @@ -75,11 +75,11 @@ impl> as CircuitParams>::prover_circuit( + let piop = as CircuitParams>::prover_circuit( &self.piop_params, level.clone(), ); - let blinded_node_ = > as ProverPiop< + let blinded_node_ = as ProverPiop< C::ScalarField, WrappedAffine, >>::result(&piop); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 9ebaa01..d681059 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -2,8 +2,8 @@ use crate::CircuitParams; use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::circuit_tall::verifier::PiopVerifier; use crate::{CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; -use ark_ec::CurveGroup; -use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; +use ark_ec::{AffineRepr, CurveGroup}; +// use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; use ark_ff::PrimeField; use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::ipa::hiding::HidingIpa; @@ -12,18 +12,18 @@ use w3f_plonk_common::piop::VerifierPiop; use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; use w3f_ring_proof::ArkTranscript; -impl CycleParams, Projective> +impl CycleParams where F0: PrimeField, F1: PrimeField, - C0: SWCurveConfig, - C1: SWCurveConfig, + C0: CurveGroup, + C1: CurveGroup, { pub fn verify( &self, - auth_path: BlindedAuthenticationPath, Projective>, - proof: CurveTreeProof, Projective>, - root: Affine, + auth_path: BlindedAuthenticationPath, + proof: CurveTreeProof, + root: C0::Affine, ) -> bool { let BlindedAuthenticationPath { c0_path, c1_path } = auth_path; let mut c0_parents = c0_path[1..].to_vec(); @@ -38,15 +38,13 @@ where } } -pub type V = PiopVerifier>; - -impl> - CycleSideParams> +impl> + CycleSideParams { pub fn verify_side( &self, // selected re-randomized children - children: Vec>, + children: Vec, // parents, re-randomized at the previous step parents: Vec, side_proof: CycleSideProof, @@ -61,7 +59,7 @@ impl::N_COLUMNS + 2; // plus the quotient and the linearization polys + let n_polys = PiopVerifier::::N_COLUMNS + 2; // plus the quotient and the linearization polys let mut polys = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); let mut coords = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); let mut vals = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); @@ -77,8 +75,8 @@ impl::N_COLUMNS + 1, - V::::N_CONSTRAINTS, + PiopVerifier::::N_COLUMNS + 1, + PiopVerifier::::N_CONSTRAINTS, ); let piop = self.piop_params.verifier_circuit( (child, parent), From 5ef7fe7c4bd3c2f886647b7c590b492888bd5c68 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 09:53:05 +0300 Subject: [PATCH 28/42] Prover and Params have phantom C --- pasta-tree/src/auth_path/node.rs | 2 +- pasta-tree/src/circuit_tall/params.rs | 83 +++++++++++++++------------ pasta-tree/src/circuit_tall/prover.rs | 13 +++-- pasta-tree/src/lib.rs | 36 ++++++------ pasta-tree/src/prover.rs | 4 +- pasta-tree/src/verifier.rs | 2 +- 6 files changed, 76 insertions(+), 64 deletions(-) diff --git a/pasta-tree/src/auth_path/node.rs b/pasta-tree/src/auth_path/node.rs index 96ef397..55907ab 100644 --- a/pasta-tree/src/auth_path/node.rs +++ b/pasta-tree/src/auth_path/node.rs @@ -71,7 +71,7 @@ impl LevelWitness { where G::BaseField: PrimeField, { - params.commit_x_coords(self.x_coords(), bf).map(|c| c.0) + params.commit_tree_nodes(&self.x_coords(), bf).map(|c| c.0) } } diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 12a1242..63148fa 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -1,3 +1,4 @@ +use std::marker::PhantomData; use crate::CircuitParams; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::PiopProof; @@ -17,7 +18,7 @@ use w3f_plonk_common::gadgets::ec::AffineColumn; /// Plonk Interactive Oracle Proofs (PIOP) parameters. /// `max_nodes + blinding_bits = domain.capacity - 1` #[derive(Clone)] -pub struct PiopParams> { +pub struct PiopParams> { /// Domain over which the piop is represented. pub domain: Domain, pub max_nodes: usize, @@ -26,15 +27,16 @@ pub struct PiopParams> { pub seed: G, /// Blinding base point. pub h: G, + phantom: PhantomData } impl> CircuitParams - for PiopParams + for PiopParams { /// (re-randomized child, re-randomized parent) type Instance = (G, C::Affine); type Proof = PiopProof; - type ProverCircuit = PiopProver; + type ProverCircuit = PiopProver; type VerifierCircuit = PiopVerifier; fn prover_circuit(&self, level: LevelWitnessWithBlinding) -> Self::ProverCircuit { @@ -62,31 +64,13 @@ impl> CircuitParams> PiopParams { - pub fn setup(domain: Domain, h: G, seed: G) -> Self { - assert!(domain.domain_size() > 256); - let actual_capacity = domain.capacity - 1; - let scalar_size = Domain::::new(256, domain.is_hiding()).capacity - 1; - let blinding_bits = - ark_std::cmp::min(G::ScalarField::MODULUS_BIT_SIZE as usize, scalar_size); - let max_nodes = actual_capacity - blinding_bits; - Self { - domain, - max_nodes, - blinding_bits, - seed, - h, - } - } - - pub fn commit_x_coords( + fn tree_nodes_column( &self, - siblings_x_coords: Vec, + children_x_coords: &[G::BaseField], ) -> FieldColumn { - assert!(siblings_x_coords.len() <= self.max_nodes); - let mut x_coords = siblings_x_coords; + assert!(children_x_coords.len() <= self.max_nodes); + let mut x_coords = children_x_coords.to_vec(); // padding x_coords.resize(self.max_nodes, G::BaseField::zero()); // `powers_of_h` x-coords @@ -104,21 +88,44 @@ impl> PiopParams { self.domain.domains.column_from_evals(x_coords, payload_len) } - pub fn x_coords_from_points(&self, child_nodes: Vec) -> FieldColumn { - let points = self.siblings_with_blinding(child_nodes); - let (mut x_coords, mut y_coords): (Vec, Vec) = - points.iter().map(|p| p.xy().unwrap()).unzip(); - let payload_len = self.domain.capacity - 1; - assert_eq!(x_coords.len(), payload_len); - // x_coords.push(G::BaseField::one()); - // assert_eq!(x_coords.len(), self.domain.capacity); + fn fixed_columns(&self) -> Vec> { + vec![self.select_part()] + } +} - // zk_rows - x_coords.resize(self.domain.domain_size(), G::BaseField::zero()); - y_coords.resize(self.domain.domain_size(), G::BaseField::zero()); - self.domain.domains.column_from_evals(x_coords, payload_len) +impl> PiopParams { + pub fn setup(domain: Domain, h: G, seed: G) -> Self { + assert!(domain.domain_size() > 256); + let actual_capacity = domain.capacity - 1; + let scalar_size = Domain::::new(256, domain.is_hiding()).capacity - 1; + let blinding_bits = + ark_std::cmp::min(G::ScalarField::MODULUS_BIT_SIZE as usize, scalar_size); + let max_nodes = actual_capacity - blinding_bits; + Self { + domain, + max_nodes, + blinding_bits, + seed, + h, + phantom: PhantomData, + } } + // fn x_coords_from_points(&self, child_nodes: Vec) -> FieldColumn { + // let points = self.siblings_with_blinding(child_nodes); + // let (mut x_coords, mut y_coords): (Vec, Vec) = + // points.iter().map(|p| p.xy().unwrap()).unzip(); + // let payload_len = self.domain.capacity - 1; + // assert_eq!(x_coords.len(), payload_len); + // // x_coords.push(G::BaseField::one()); + // // assert_eq!(x_coords.len(), self.domain.capacity); + // + // // zk_rows + // x_coords.resize(self.domain.domain_size(), G::BaseField::zero()); + // y_coords.resize(self.domain.domain_size(), G::BaseField::zero()); + // self.domain.domains.column_from_evals(x_coords, payload_len) + // } + pub fn points_column(&self, child_nodes: Vec) -> AffineColumn { let points = self.siblings_with_blinding(child_nodes); assert_eq!(points.len(), self.domain.capacity - 1); @@ -141,7 +148,7 @@ impl> PiopParams { BitColumn::init(bits, &self.domain) } - pub fn select_part(&self) -> FieldColumn { + pub(super) fn select_part(&self) -> FieldColumn { let selector = [ vec![G::BaseField::one(); self.max_nodes], vec![G::BaseField::zero(); self.blinding_bits], diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index 3a4ac43..dc59527 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -1,3 +1,4 @@ +use std::marker::PhantomData; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::{ProofComms, ProofEvals}; @@ -32,7 +33,7 @@ use w3f_plonk_common::piop::ProverPiop; // cond_add_acc_y: DensePolynomial, // } -pub struct PiopProver> { +pub struct PiopProver> { domain: Domain, // `x` coordinates of all the children of a node. Public input. // `H, 2H, 4H,...,2^sH` Fixed column. @@ -47,11 +48,12 @@ pub struct PiopProver> { // columns: Witness, gadgets: Vec>>, result: G, + phantom: PhantomData, } -impl> PiopProver { +impl> PiopProver { pub fn build( - params: &PiopParams, + params: &PiopParams, level: LevelWitnessWithBlinding, ) -> Self { let domain = params.domain.clone(); @@ -97,12 +99,13 @@ impl> PiopProver { cond_add_acc_x, cond_add_acc_y, result, + phantom: PhantomData, } } } -impl> - ProverPiop> for PiopProver +impl> +ProverPiop> for PiopProver { const N_CONSTRAINTS: usize = 7; type Commitments = ProofComms; diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 50b1ca5..d72c069 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -9,7 +9,7 @@ use w3f_pcs::pcs::PCS; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::AggregateProof; -use w3f_plonk_common::PiopProof; +use w3f_plonk_common::{FieldColumn, PiopProof}; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use crate::auth_path::node::LevelWitnessWithBlinding; @@ -37,12 +37,16 @@ pub trait CircuitParams { proof: Self::Proof, zeta: C::ScalarField, ) -> Self::VerifierCircuit; + + fn tree_nodes_column(&self, children_x_coords: &[C::ScalarField]) -> FieldColumn; + + fn fixed_columns(&self) -> Vec>; } pub struct CycleSideParams> { pcs_params: HidingIpa, - piop_params: PiopParams, + piop_params: PiopParams, } pub struct CycleParams< @@ -76,12 +80,10 @@ pub struct CurveTreeProof< c1_proof: CycleSideProof, } -impl CycleParams +impl CycleParams where - F0: PrimeField, - F1: PrimeField, - C0: CurveGroup, - C1: CurveGroup, + C0: CurveGroup, + C1: CurveGroup, { pub fn setup(domain_size: usize, rng: &mut R) -> Self { let setup_degree = 3 * domain_size; @@ -105,21 +107,21 @@ where } impl> CycleSideParams { - pub fn commit_x_coords( + + pub fn commit_tree_nodes( &self, - child_x_coords: Vec, + nodes_x_coords: &[C::ScalarField], bf: C::ScalarField, ) -> Result, ()> { - let x_coords = self.piop_params.commit_x_coords(child_x_coords); - let x_parent = self.pcs_params.commit_hiding(x_coords.as_poly(), bf); - x_parent + let nodes_column = self.piop_params.tree_nodes_column(nodes_x_coords); + let parent_node = self.pcs_params.commit_hiding(nodes_column.as_poly(), bf); + parent_node } - pub fn commit_selector(&self) -> WrappedAffine { - let selector = self.piop_params.select_part(); - self.pcs_params - .commit_hiding(selector.as_poly(), C::ScalarField::zero()) - .unwrap() + pub fn commit_fixed_columns(&self) -> Vec> { + self.piop_params.fixed_columns().iter() + .map(|c| self.pcs_params.commit_hiding(c.as_poly(), C::ScalarField::zero()).unwrap()) + .collect() } // pub fn commit_h_powers(&self) -> [IPACommitment; 2] { diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index d254648..c49d065 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -75,11 +75,11 @@ impl as CircuitParams>::prover_circuit( + let piop = as CircuitParams>::prover_circuit( &self.piop_params, level.clone(), ); - let blinded_node_ = as ProverPiop< + let blinded_node_ = as ProverPiop< C::ScalarField, WrappedAffine, >>::result(&piop); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index d681059..9e51a02 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -64,7 +64,7 @@ impl Date: Fri, 29 May 2026 09:56:16 +0300 Subject: [PATCH 29/42] trait calls simplified --- pasta-tree/src/prover.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index c49d065..a89645b 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -24,8 +24,8 @@ impl CycleParams where F0: PrimeField, F1: PrimeField, - C0: CurveGroup, - C1: CurveGroup, + C0: CurveGroup, + C1: CurveGroup, { pub fn prove( &self, @@ -48,8 +48,8 @@ where } } -impl> - CycleSideParams +impl> +CycleSideParams { pub fn prove_side( &self, @@ -75,15 +75,8 @@ impl as CircuitParams>::prover_circuit( - &self.piop_params, - level.clone(), - ); - let blinded_node_ = as ProverPiop< - C::ScalarField, - WrappedAffine, - >>::result(&piop); - debug_assert_eq!(blinded_node_, blinded_node); + let piop = self.piop_params.prover_circuit(level.clone()); + debug_assert_eq!(piop.result(), blinded_node); let (pcs_openings, piop_proof, _transcript) = plonk_prover.reduce_to_pcs_opening(piop); piop_proofs.push(piop_proof); let PcsOpeningAt2Points { From b2005b60c1acae425324b9d6d9df90efdc9fdc15 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 16:49:03 +0300 Subject: [PATCH 30/42] phantoms removed --- pasta-tree/src/circuit_tall/params.rs | 13 +++--- pasta-tree/src/circuit_tall/prover.rs | 13 +++--- pasta-tree/src/lib.rs | 44 ++++++++++--------- pasta-tree/src/prover.rs | 5 ++- .../src/gadgets/ec/sw_cond_add.rs | 2 +- 5 files changed, 37 insertions(+), 40 deletions(-) diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 63148fa..367d772 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -1,4 +1,3 @@ -use std::marker::PhantomData; use crate::CircuitParams; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::PiopProof; @@ -6,7 +5,7 @@ use crate::circuit_tall::prover::PiopProver; use crate::circuit_tall::verifier::PiopVerifier; // use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; -use ark_ff::One; +use ark_ff::{FftField, One}; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; @@ -18,7 +17,7 @@ use w3f_plonk_common::gadgets::ec::AffineColumn; /// Plonk Interactive Oracle Proofs (PIOP) parameters. /// `max_nodes + blinding_bits = domain.capacity - 1` #[derive(Clone)] -pub struct PiopParams> { +pub struct PiopParams> { /// Domain over which the piop is represented. pub domain: Domain, pub max_nodes: usize, @@ -27,16 +26,15 @@ pub struct PiopParams> pub seed: G, /// Blinding base point. pub h: G, - phantom: PhantomData } impl> CircuitParams - for PiopParams + for PiopParams { /// (re-randomized child, re-randomized parent) type Instance = (G, C::Affine); type Proof = PiopProof; - type ProverCircuit = PiopProver; + type ProverCircuit = PiopProver; type VerifierCircuit = PiopVerifier; fn prover_circuit(&self, level: LevelWitnessWithBlinding) -> Self::ProverCircuit { @@ -93,7 +91,7 @@ impl> CircuitParams> PiopParams { +impl> PiopParams { pub fn setup(domain: Domain, h: G, seed: G) -> Self { assert!(domain.domain_size() > 256); let actual_capacity = domain.capacity - 1; @@ -107,7 +105,6 @@ impl> PiopParams blinding_bits, seed, h, - phantom: PhantomData, } } diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index dc59527..e511671 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -1,10 +1,9 @@ -use std::marker::PhantomData; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::{ProofComms, ProofEvals}; // use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; -use ark_ff::{FftField, One, PrimeField, Zero}; +use ark_ff::{FftField, One, Zero}; use ark_poly::Evaluations; use ark_poly::Polynomial; use ark_poly::univariate::DensePolynomial; @@ -33,7 +32,7 @@ use w3f_plonk_common::piop::ProverPiop; // cond_add_acc_y: DensePolynomial, // } -pub struct PiopProver> { +pub struct PiopProver> { domain: Domain, // `x` coordinates of all the children of a node. Public input. // `H, 2H, 4H,...,2^sH` Fixed column. @@ -48,12 +47,11 @@ pub struct PiopProver> { // columns: Witness, gadgets: Vec>>, result: G, - phantom: PhantomData, } -impl> PiopProver { +impl> PiopProver { pub fn build( - params: &PiopParams, + params: &PiopParams, level: LevelWitnessWithBlinding, ) -> Self { let domain = params.domain.clone(); @@ -99,13 +97,12 @@ impl> PiopProver { cond_add_acc_x, cond_add_acc_y, result, - phantom: PhantomData, } } } impl> -ProverPiop> for PiopProver +ProverPiop> for PiopProver { const N_CONSTRAINTS: usize = 7; type Commitments = ProofComms; diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index d72c069..1b5f06d 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -1,18 +1,19 @@ +use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::{ProofComms, ProofEvals}; use ark_ec::{AffineRepr, CurveGroup, PrimeGroup}; -use ark_ff::{PrimeField, Zero}; -use ark_std::UniformRand; +use ark_ff::PrimeField; use ark_std::rand::Rng; +use ark_ff::Zero; +use ark_std::UniformRand; use w3f_pcs::aggregation::multiple::ShplonkTranscript; -use w3f_pcs::pcs::PCS; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; +use w3f_pcs::pcs::PCS; use w3f_pcs::shplonk::AggregateProof; -use w3f_plonk_common::{FieldColumn, PiopProof}; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; -use crate::auth_path::node::LevelWitnessWithBlinding; +use w3f_plonk_common::{FieldColumn, PiopProof}; pub mod auth_path; // pub mod circuit_fat; @@ -22,7 +23,7 @@ pub mod prover; pub mod verifier; /// The circuit is over `C::ScalarField`. -pub trait CircuitParams { +pub trait CircuitParams> { type Instance; type Proof; type ProverCircuit: ProverPiop>; @@ -44,14 +45,14 @@ pub trait CircuitParams { } -pub struct CycleSideParams> { +pub struct CycleSideParams> { pcs_params: HidingIpa, - piop_params: PiopParams, + piop_params: PiopParams, } pub struct CycleParams< C0: CurveGroup, - C1: CurveGroup, + C1: CurveGroup, > { c0_params: CycleSideParams, c1_params: CycleSideParams, @@ -83,7 +84,7 @@ pub struct CurveTreeProof< impl CycleParams where C0: CurveGroup, - C1: CurveGroup, + C1: CurveGroup, { pub fn setup(domain_size: usize, rng: &mut R) -> Self { let setup_degree = 3 * domain_size; @@ -113,13 +114,14 @@ impl> CycleSideParams Result, ()> { - let nodes_column = self.piop_params.tree_nodes_column(nodes_x_coords); + let nodes_column = as CircuitParams>::tree_nodes_column(&self.piop_params, nodes_x_coords); let parent_node = self.pcs_params.commit_hiding(nodes_column.as_poly(), bf); parent_node } pub fn commit_fixed_columns(&self) -> Vec> { - self.piop_params.fixed_columns().iter() + let fixed_columns = as CircuitParams>::fixed_columns(&self.piop_params); + fixed_columns.iter() .map(|c| self.pcs_params.commit_hiding(c.as_poly(), C::ScalarField::zero()).unwrap()) .collect() } @@ -161,22 +163,22 @@ impl> ShplonkTranscript for Coeffs { #[cfg(test)] mod tests { use super::*; - use ark_ec::AdditiveGroup; use ark_ec::scalar_mul::glv::GLVConfig; use ark_ec::scalar_mul::wnaf::WnafContext; use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; + use ark_ec::AdditiveGroup; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::PrimeField; use ark_ff::{BigInteger, Field, Zero}; use ark_pallas::PallasConfig; use ark_poly::DenseUVPolynomial; use ark_std::rand::Rng; - use ark_std::{UniformRand, cfg_iter_mut, end_timer, start_timer, test_rng}; + use ark_std::{cfg_iter_mut, end_timer, start_timer, test_rng, UniformRand}; use ark_vesta::VestaConfig; - use w3f_pcs::Poly; - use w3f_pcs::pcs::PCS; - use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::ipa::IPA; + use w3f_pcs::pcs::PcsParams; + use w3f_pcs::pcs::PCS; + use w3f_pcs::Poly; use w3f_plonk_common::test_helpers::random_vec; use crate::auth_path::node::LevelWitness; @@ -200,7 +202,7 @@ mod tests { } } - pub fn random_nodes, R: Rng>( + pub fn random_nodes, R: Rng>( params: &CycleSideParams, path_node: G, rng: &mut R, @@ -212,7 +214,7 @@ mod tests { pub fn random_path< C0: CurveGroup, - C1: CurveGroup, + C1: CurveGroup, R: Rng, >( params: &CycleParams, @@ -255,8 +257,8 @@ mod tests { where F0: PrimeField, F1: PrimeField, - C0: SWCurveConfig, - C1: SWCurveConfig, + C0: SWCurveConfig, + C1: SWCurveConfig, { let rng = &mut test_rng(); diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index a89645b..fa9af50 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -75,8 +75,9 @@ CycleSideParams ); for (level, blinded_node) in witness.into_iter().zip(blinded_path.into_iter()) { - let piop = self.piop_params.prover_circuit(level.clone()); - debug_assert_eq!(piop.result(), blinded_node); + let piop: PiopProver = as CircuitParams>::prover_circuit(&self.piop_params, level.clone()); + let result = as ProverPiop>>::result(&piop); + debug_assert_eq!(result, blinded_node); let (pcs_openings, piop_proof, _transcript) = plonk_prover.reduce_to_pcs_opening(piop); piop_proofs.push(piop_proof); let PcsOpeningAt2Points { diff --git a/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs b/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs index 2726993..e3cdd44 100644 --- a/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs +++ b/w3f-plonk-common/src/gadgets/ec/sw_cond_add.rs @@ -5,7 +5,7 @@ use ark_poly::univariate::DensePolynomial; use ark_poly::{Evaluations, GeneralEvaluationDomain}; use ark_std::{vec, vec::Vec}; -use crate::gadgets::ec::{AffineColumn, CondAdd, CondAddValues}; +use crate::gadgets::ec::{CondAdd, CondAddValues}; use crate::gadgets::{ProverGadget, VerifierGadget}; use crate::{const_evals, Column}; From 8111b6c5f891f202b05b7547f0efdbd34cbdfa7c Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 17:56:29 +0300 Subject: [PATCH 31/42] CircuitParams implemented for PiopParams --- pasta-tree/src/auth_path/blinded.rs | 27 ++++++++------- pasta-tree/src/auth_path/node.rs | 20 ++++++++---- pasta-tree/src/auth_path/path.rs | 23 ++++++------- pasta-tree/src/circuit_tall/mod.rs | 2 +- pasta-tree/src/circuit_tall/params.rs | 5 ++- pasta-tree/src/lib.rs | 47 +++++++++++++++------------ pasta-tree/src/prover.rs | 29 ++++++++--------- pasta-tree/src/verifier.rs | 22 +++++++------ 8 files changed, 96 insertions(+), 79 deletions(-) diff --git a/pasta-tree/src/auth_path/blinded.rs b/pasta-tree/src/auth_path/blinded.rs index 041b4e3..b9db745 100644 --- a/pasta-tree/src/auth_path/blinded.rs +++ b/pasta-tree/src/auth_path/blinded.rs @@ -1,7 +1,8 @@ use crate::auth_path::node::LevelWitnessWithBlinding; -use crate::{CycleParams, CycleSide}; +use crate::{CircuitParams, CycleParams2, CycleSide}; use ark_ec::CurveGroup; use ark_ff::PrimeField; +use w3f_pcs::pcs::ipa::hiding::HidingIpa; pub struct AuthenticationPathWithBlinding { pub(crate) c0_path: Vec>, @@ -14,23 +15,22 @@ pub struct BlindedAuthenticationPath { pub(crate) c1_path: Vec, } -impl AuthenticationPathWithBlinding +impl AuthenticationPathWithBlinding where - F0: PrimeField, - F1: PrimeField, - C0: CurveGroup, - C1: CurveGroup, + C0: CurveGroup, + C1: CurveGroup, { pub(crate) fn apply_bfs( &self, - params: &CycleParams, + c0_pcs_params: &HidingIpa, + c1_pcs_params: &HidingIpa, ) -> BlindedAuthenticationPath { let c0_path = self .c0_path .iter() .map(|c0_level| { c0_level - .blinded_path_node(¶ms.c0_params.pcs_params) + .blinded_path_node(c0_pcs_params) .unwrap() }) .collect(); @@ -39,16 +39,19 @@ where .iter() .map(|c1_level| { c1_level - .blinded_path_node(¶ms.c1_params.pcs_params) + .blinded_path_node(c1_pcs_params) .unwrap() }) .collect(); BlindedAuthenticationPath { c0_path, c1_path } } - pub fn compute_root( + pub fn compute_root( &self, - params: &CycleParams, - ) -> Result, ()> { + params: &CycleParams2, + ) -> Result, ()> where + P0: CircuitParams, + P1: CircuitParams, + { let mut c0_path_iter = self.c0_path.iter(); let c0_nodes = c0_path_iter.next().unwrap(); let mut parent_on_c1 = c0_nodes.compute_parent(¶ms.c1_params)?; diff --git a/pasta-tree/src/auth_path/node.rs b/pasta-tree/src/auth_path/node.rs index 55907ab..c7b13a1 100644 --- a/pasta-tree/src/auth_path/node.rs +++ b/pasta-tree/src/auth_path/node.rs @@ -1,4 +1,4 @@ -use crate::CycleSideParams; +use crate::{CircuitParams, CycleSideParams2}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::{PrimeField, Zero}; use ark_std::UniformRand; @@ -53,23 +53,27 @@ impl LevelWitness { self.with_blinding(G::ScalarField::rand(rng), parent_bf) } - pub fn compute_parent>( + pub fn compute_parent( &self, - params: &CycleSideParams, + params: &CycleSideParams2, ) -> Result where G::BaseField: PrimeField, + C: CurveGroup, + P: CircuitParams, { self.compute_parent_with_bf(params, C::ScalarField::zero()) } - fn compute_parent_with_bf>( + fn compute_parent_with_bf( &self, - params: &CycleSideParams, + params: &CycleSideParams2, bf: C::ScalarField, ) -> Result where G::BaseField: PrimeField, + C: CurveGroup, + P: CircuitParams, { params.commit_tree_nodes(&self.x_coords(), bf).map(|c| c.0) } @@ -99,12 +103,14 @@ impl LevelWitnessWithBlinding { Ok(blinded_path_node.0) } - pub(crate) fn compute_parent>( + pub(crate) fn compute_parent( &self, - params: &CycleSideParams, + params: &CycleSideParams2, ) -> Result where G::BaseField: PrimeField, + C: CurveGroup, + P: CircuitParams, { self.level_witness .compute_parent_with_bf(params, self.parent_bf) diff --git a/pasta-tree/src/auth_path/path.rs b/pasta-tree/src/auth_path/path.rs index dee4e57..0383adf 100644 --- a/pasta-tree/src/auth_path/path.rs +++ b/pasta-tree/src/auth_path/path.rs @@ -1,8 +1,8 @@ use crate::auth_path::blinded::AuthenticationPathWithBlinding; use crate::auth_path::node::LevelWitness; -use crate::{CycleParams, CycleSide}; +use crate::{CircuitParams, CycleParams2, CycleSide}; use ark_ec::CurveGroup; -use ark_ff::PrimeField; +use ark_ff::{PrimeField, Zero}; use ark_ff::UniformRand; use ark_std::rand::Rng; @@ -20,12 +20,10 @@ pub struct AuthenticationPath { pub c1_path: Vec>, } -impl AuthenticationPath +impl AuthenticationPath where - F0: PrimeField, - F1: PrimeField, - C0: CurveGroup, - C1: CurveGroup, + C0: CurveGroup, + C1: CurveGroup, { pub fn with_blinding(&self, rng: &mut R) -> AuthenticationPathWithBlinding { let mut path_0 = Vec::with_capacity(self.c0_path.len()); @@ -70,10 +68,13 @@ where self.c0_path[0].path_node() } - pub fn compute_root( + pub fn compute_root( &self, - params: &CycleParams, - ) -> Result, ()> { + params: &CycleParams2, + ) -> Result, ()> where + P0: CircuitParams, + P1: CircuitParams, + { let mut c0_path_iter = self.c0_path.iter(); let c0_nodes = c0_path_iter.next().unwrap(); // shouldn't be empty let mut parent_on_c1 = c0_nodes.compute_parent(¶ms.c1_params)?; @@ -110,7 +111,7 @@ mod tests { let domain_size = 2usize.pow(9); let params = - CycleParams::::setup(domain_size, rng); + CycleParams2::::setup(domain_size, rng); let (leaf, path, root) = random_path(¶ms, 2, rng); diff --git a/pasta-tree/src/circuit_tall/mod.rs b/pasta-tree/src/circuit_tall/mod.rs index 48d3514..f4f1b6f 100644 --- a/pasta-tree/src/circuit_tall/mod.rs +++ b/pasta-tree/src/circuit_tall/mod.rs @@ -9,7 +9,7 @@ pub mod params; pub mod prover; pub mod verifier; -type PiopProof = w3f_plonk_common::PiopProof< +pub type PiopProof = w3f_plonk_common::PiopProof< ::ScalarField, WrappedAffine, ProofComms, diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 367d772..30eacae 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -31,8 +31,7 @@ pub struct PiopParams> { impl> CircuitParams for PiopParams { - /// (re-randomized child, re-randomized parent) - type Instance = (G, C::Affine); + type Proof = PiopProof; type ProverCircuit = PiopProver; type VerifierCircuit = PiopVerifier; @@ -43,7 +42,7 @@ impl> CircuitParams], proof: Self::Proof, zeta: C::ScalarField, diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 1b5f06d..5f8f70d 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -1,3 +1,4 @@ +use std::marker::PhantomData; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::{ProofComms, ProofEvals}; @@ -24,7 +25,6 @@ pub mod verifier; /// The circuit is over `C::ScalarField`. pub trait CircuitParams> { - type Instance; type Proof; type ProverCircuit: ProverPiop>; type VerifierCircuit: VerifierPiop>; @@ -33,7 +33,7 @@ pub trait CircuitParams> fn verifier_circuit( &self, - instance: Self::Instance, + instance: (G, C::Affine), fixed_cols: &[WrappedAffine], proof: Self::Proof, zeta: C::ScalarField, @@ -44,18 +44,20 @@ pub trait CircuitParams> fn fixed_columns(&self) -> Vec>; } - -pub struct CycleSideParams> { +pub struct CycleSideParams2, P: CircuitParams> { pcs_params: HidingIpa, - piop_params: PiopParams, + piop_params: P, + phantomm: PhantomData, } -pub struct CycleParams< +pub struct CycleParams2< C0: CurveGroup, C1: CurveGroup, + P0: CircuitParams, + P1: CircuitParams, > { - c0_params: CycleSideParams, - c1_params: CycleSideParams, + c0_params: CycleSideParams2, + c1_params: CycleSideParams2, } pub type LevelProof = PiopProof< @@ -81,7 +83,7 @@ pub struct CurveTreeProof< c1_proof: CycleSideProof, } -impl CycleParams +impl CycleParams2, PiopParams> where C0: CurveGroup, C1: CurveGroup, @@ -95,32 +97,36 @@ where let c1_domain = Domain::::new(domain_size, true); let c1_piop_params = PiopParams::setup(c1_domain, c0_pcs_params.h, C0::Affine::rand(rng)); Self { - c0_params: CycleSideParams { + c0_params: CycleSideParams2 { pcs_params: c0_pcs_params, piop_params: c0_piop_params, + phantomm: PhantomData, }, - c1_params: CycleSideParams { + c1_params: CycleSideParams2 { pcs_params: c1_pcs_params, piop_params: c1_piop_params, + phantomm: PhantomData, }, } } } -impl> CycleSideParams { - pub fn commit_tree_nodes( +impl, P: CircuitParams> CycleSideParams2 +where +{ + pub fn commit_tree_nodes<>( &self, nodes_x_coords: &[C::ScalarField], bf: C::ScalarField, ) -> Result, ()> { - let nodes_column = as CircuitParams>::tree_nodes_column(&self.piop_params, nodes_x_coords); + let nodes_column =

>::tree_nodes_column(&self.piop_params, nodes_x_coords); let parent_node = self.pcs_params.commit_hiding(nodes_column.as_poly(), bf); parent_node } pub fn commit_fixed_columns(&self) -> Vec> { - let fixed_columns = as CircuitParams>::fixed_columns(&self.piop_params); + let fixed_columns =

>::fixed_columns(&self.piop_params); fixed_columns.iter() .map(|c| self.pcs_params.commit_hiding(c.as_poly(), C::ScalarField::zero()).unwrap()) .collect() @@ -140,6 +146,7 @@ impl> CycleSideParams { C0(C0), @@ -168,7 +175,7 @@ mod tests { use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; use ark_ec::AdditiveGroup; use ark_ec::{AffineRepr, CurveGroup}; - use ark_ff::PrimeField; + use ark_ff::{FftField, PrimeField}; use ark_ff::{BigInteger, Field, Zero}; use ark_pallas::PallasConfig; use ark_poly::DenseUVPolynomial; @@ -203,7 +210,7 @@ mod tests { } pub fn random_nodes, R: Rng>( - params: &CycleSideParams, + params: &CycleSideParams2>, path_node: G, rng: &mut R, ) -> (C::Affine, LevelWitness) { @@ -213,11 +220,11 @@ mod tests { } pub fn random_path< - C0: CurveGroup, + C0: CurveGroup, C1: CurveGroup, R: Rng, >( - params: &CycleParams, + params: &CycleParams2, PiopParams>, length: usize, rng: &mut R, ) -> ( @@ -263,7 +270,7 @@ mod tests { let rng = &mut test_rng(); let domain_size = 1 << log_n; - let params = CycleParams::, Projective>::setup(domain_size, rng); + let params = CycleParams2::, Projective, _, _>::setup(domain_size, rng); let (_leaf, path, wrapped_root) = random_path(¶ms, height, rng); let root = match wrapped_root { CycleSide::C0(root) => root, //TODO: panics on odd height diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index fa9af50..8769817 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -1,31 +1,30 @@ -use crate::CircuitParams; use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; -use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::prover::PiopProver; -use crate::{Coeffs, CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; +use crate::circuit_tall::verifier::PiopVerifier; +use crate::{CircuitParams, CycleParams2, CycleSideParams2}; +use crate::{Coeffs, CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; // use ark_ec::short_weierstrass::{Affine as SwAffine, Projective, SWCurveConfig}; use ark_ff::{PrimeField, Zero}; -use ark_std::UniformRand; use ark_std::rand::Rng; +use ark_std::UniformRand; use std::collections::BTreeSet; -use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; +use w3f_pcs::pcs::PcsParams; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; use w3f_ring_proof::ArkTranscript; -use crate::circuit_tall::verifier::PiopVerifier; -impl CycleParams +impl CycleParams2 where - F0: PrimeField, - F1: PrimeField, - C0: CurveGroup, - C1: CurveGroup, + C0: CurveGroup, + C1: CurveGroup, + P0: CircuitParams>, + P1: CircuitParams>, { pub fn prove( &self, @@ -36,7 +35,7 @@ where CurveTreeProof, ) { let auth_path_with_bf = auth_path.with_blinding(rng); - let blinded_auth_path = auth_path_with_bf.apply_bfs(&self); + let blinded_auth_path = auth_path_with_bf.apply_bfs(&self.c0_params.pcs_params, &self.c1_params.pcs_params); let auth_path = blinded_auth_path.clone(); let c0_proof = self.c0_params @@ -48,8 +47,8 @@ where } } -impl> -CycleSideParams +impl, P: CircuitParams>> +CycleSideParams2 { pub fn prove_side( &self, @@ -75,7 +74,7 @@ CycleSideParams ); for (level, blinded_node) in witness.into_iter().zip(blinded_path.into_iter()) { - let piop: PiopProver = as CircuitParams>::prover_circuit(&self.piop_params, level.clone()); + let piop: PiopProver =

>::prover_circuit(&self.piop_params, level.clone()); let result = as ProverPiop>>::result(&piop); debug_assert_eq!(result, blinded_node); let (pcs_openings, piop_proof, _transcript) = plonk_prover.reduce_to_pcs_opening(piop); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 9e51a02..fa789c3 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,23 +1,25 @@ -use crate::CircuitParams; use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::circuit_tall::verifier::PiopVerifier; -use crate::{CurveTreeProof, CycleParams, CycleSideParams, CycleSideProof}; +use crate::circuit_tall::PiopProof; +use crate::{CircuitParams, CycleParams2, CycleSideParams2}; +use crate::{CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; // use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; use ark_ff::PrimeField; -use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::ipa::hiding::HidingIpa; +use w3f_pcs::pcs::PcsParams; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::VerifierPiop; use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; use w3f_ring_proof::ArkTranscript; -impl CycleParams + +impl CycleParams2 where - F0: PrimeField, - F1: PrimeField, - C0: CurveGroup, - C1: CurveGroup, + C0: CurveGroup, + C1: CurveGroup, + P0: CircuitParams>, + P1: CircuitParams>, { pub fn verify( &self, @@ -38,8 +40,8 @@ where } } -impl> - CycleSideParams +impl, P: CircuitParams>> +CycleSideParams2 { pub fn verify_side( &self, From 53fb2e17ed5c718c075ae19007bb7a71ea82b35e Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 17:57:09 +0300 Subject: [PATCH 32/42] fmt --- pasta-tree/src/auth_path/blinded.rs | 17 ++----- pasta-tree/src/auth_path/node.rs | 11 ++--- pasta-tree/src/auth_path/path.rs | 13 +++-- pasta-tree/src/circuit_tall/params.rs | 8 +-- pasta-tree/src/circuit_tall/prover.rs | 9 ++-- pasta-tree/src/lib.rs | 70 +++++++++++++++------------ pasta-tree/src/prover.rs | 31 ++++++------ pasta-tree/src/verifier.rs | 18 ++++--- 8 files changed, 88 insertions(+), 89 deletions(-) diff --git a/pasta-tree/src/auth_path/blinded.rs b/pasta-tree/src/auth_path/blinded.rs index b9db745..fd85909 100644 --- a/pasta-tree/src/auth_path/blinded.rs +++ b/pasta-tree/src/auth_path/blinded.rs @@ -18,7 +18,7 @@ pub struct BlindedAuthenticationPath { impl AuthenticationPathWithBlinding where C0: CurveGroup, - C1: CurveGroup, + C1: CurveGroup, { pub(crate) fn apply_bfs( &self, @@ -28,27 +28,20 @@ where let c0_path = self .c0_path .iter() - .map(|c0_level| { - c0_level - .blinded_path_node(c0_pcs_params) - .unwrap() - }) + .map(|c0_level| c0_level.blinded_path_node(c0_pcs_params).unwrap()) .collect(); let c1_path = self .c1_path .iter() - .map(|c1_level| { - c1_level - .blinded_path_node(c1_pcs_params) - .unwrap() - }) + .map(|c1_level| c1_level.blinded_path_node(c1_pcs_params).unwrap()) .collect(); BlindedAuthenticationPath { c0_path, c1_path } } pub fn compute_root( &self, params: &CycleParams2, - ) -> Result, ()> where + ) -> Result, ()> + where P0: CircuitParams, P1: CircuitParams, { diff --git a/pasta-tree/src/auth_path/node.rs b/pasta-tree/src/auth_path/node.rs index c7b13a1..a6d0c04 100644 --- a/pasta-tree/src/auth_path/node.rs +++ b/pasta-tree/src/auth_path/node.rs @@ -53,13 +53,10 @@ impl LevelWitness { self.with_blinding(G::ScalarField::rand(rng), parent_bf) } - pub fn compute_parent( - &self, - params: &CycleSideParams2, - ) -> Result + pub fn compute_parent(&self, params: &CycleSideParams2) -> Result where G::BaseField: PrimeField, - C: CurveGroup, + C: CurveGroup, P: CircuitParams, { self.compute_parent_with_bf(params, C::ScalarField::zero()) @@ -72,7 +69,7 @@ impl LevelWitness { ) -> Result where G::BaseField: PrimeField, - C: CurveGroup, + C: CurveGroup, P: CircuitParams, { params.commit_tree_nodes(&self.x_coords(), bf).map(|c| c.0) @@ -109,7 +106,7 @@ impl LevelWitnessWithBlinding { ) -> Result where G::BaseField: PrimeField, - C: CurveGroup, + C: CurveGroup, P: CircuitParams, { self.level_witness diff --git a/pasta-tree/src/auth_path/path.rs b/pasta-tree/src/auth_path/path.rs index 0383adf..8dff40f 100644 --- a/pasta-tree/src/auth_path/path.rs +++ b/pasta-tree/src/auth_path/path.rs @@ -2,8 +2,8 @@ use crate::auth_path::blinded::AuthenticationPathWithBlinding; use crate::auth_path::node::LevelWitness; use crate::{CircuitParams, CycleParams2, CycleSide}; use ark_ec::CurveGroup; -use ark_ff::{PrimeField, Zero}; use ark_ff::UniformRand; +use ark_ff::{PrimeField, Zero}; use ark_std::rand::Rng; /// A non-hiding authentication path from a leaf to the root, split between the curves of the cycle. @@ -23,7 +23,7 @@ pub struct AuthenticationPath { impl AuthenticationPath where C0: CurveGroup, - C1: CurveGroup, + C1: CurveGroup, { pub fn with_blinding(&self, rng: &mut R) -> AuthenticationPathWithBlinding { let mut path_0 = Vec::with_capacity(self.c0_path.len()); @@ -71,7 +71,8 @@ where pub fn compute_root( &self, params: &CycleParams2, - ) -> Result, ()> where + ) -> Result, ()> + where P0: CircuitParams, P1: CircuitParams, { @@ -110,8 +111,10 @@ mod tests { let rng = &mut test_rng(); let domain_size = 2usize.pow(9); - let params = - CycleParams2::::setup(domain_size, rng); + let params = CycleParams2::::setup( + domain_size, + rng, + ); let (leaf, path, root) = random_path(¶ms, 2, rng); diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 30eacae..6b0f1c9 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -5,8 +5,8 @@ use crate::circuit_tall::prover::PiopProver; use crate::circuit_tall::verifier::PiopVerifier; // use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; -use ark_ff::{FftField, One}; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; +use ark_ff::{FftField, One}; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::FieldColumn; @@ -31,7 +31,6 @@ pub struct PiopParams> { impl> CircuitParams for PiopParams { - type Proof = PiopProof; type ProverCircuit = PiopProver; type VerifierCircuit = PiopVerifier; @@ -62,10 +61,7 @@ impl> CircuitParams FieldColumn { + fn tree_nodes_column(&self, children_x_coords: &[G::BaseField]) -> FieldColumn { assert!(children_x_coords.len() <= self.max_nodes); let mut x_coords = children_x_coords.to_vec(); // padding diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index e511671..1e54392 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -50,10 +50,7 @@ pub struct PiopProver> { } impl> PiopProver { - pub fn build( - params: &PiopParams, - level: LevelWitnessWithBlinding, - ) -> Self { + pub fn build(params: &PiopParams, level: LevelWitnessWithBlinding) -> Self { let domain = params.domain.clone(); let points = params.points_column(level.level_witness.siblings); let bits = params.bits_column(level.level_witness.path_node_idx, level.bf); @@ -101,8 +98,8 @@ impl> PiopProver { } } -impl> -ProverPiop> for PiopProver +impl> + ProverPiop> for PiopProver { const N_CONSTRAINTS: usize = 7; type Commitments = ProofComms; diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 5f8f70d..4206545 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -1,16 +1,16 @@ -use std::marker::PhantomData; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_tall::params::PiopParams; use crate::circuit_tall::{ProofComms, ProofEvals}; use ark_ec::{AffineRepr, CurveGroup, PrimeGroup}; use ark_ff::PrimeField; -use ark_std::rand::Rng; use ark_ff::Zero; use ark_std::UniformRand; +use ark_std::rand::Rng; +use std::marker::PhantomData; use w3f_pcs::aggregation::multiple::ShplonkTranscript; +use w3f_pcs::pcs::PCS; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; -use w3f_pcs::pcs::PCS; use w3f_pcs::shplonk::AggregateProof; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; @@ -24,7 +24,7 @@ pub mod prover; pub mod verifier; /// The circuit is over `C::ScalarField`. -pub trait CircuitParams> { +pub trait CircuitParams> { type Proof; type ProverCircuit: ProverPiop>; type VerifierCircuit: VerifierPiop>; @@ -39,12 +39,19 @@ pub trait CircuitParams> zeta: C::ScalarField, ) -> Self::VerifierCircuit; - fn tree_nodes_column(&self, children_x_coords: &[C::ScalarField]) -> FieldColumn; + fn tree_nodes_column( + &self, + children_x_coords: &[C::ScalarField], + ) -> FieldColumn; fn fixed_columns(&self) -> Vec>; } -pub struct CycleSideParams2, P: CircuitParams> { +pub struct CycleSideParams2< + C: CurveGroup, + G: AffineRepr, + P: CircuitParams, +> { pcs_params: HidingIpa, piop_params: P, phantomm: PhantomData, @@ -52,7 +59,7 @@ pub struct CycleSideParams2, + C1: CurveGroup, P0: CircuitParams, P1: CircuitParams, > { @@ -75,10 +82,7 @@ pub struct CycleSideProof { } #[derive(Clone)] -pub struct CurveTreeProof< - C0: CurveGroup, - C1: CurveGroup, -> { +pub struct CurveTreeProof { c0_proof: CycleSideProof, c1_proof: CycleSideProof, } @@ -86,7 +90,7 @@ pub struct CurveTreeProof< impl CycleParams2, PiopParams> where C0: CurveGroup, - C1: CurveGroup, + C1: CurveGroup, { pub fn setup(domain_size: usize, rng: &mut R) -> Self { let setup_degree = 3 * domain_size; @@ -111,24 +115,29 @@ where } } - -impl, P: CircuitParams> CycleSideParams2 -where +impl, P: CircuitParams> + CycleSideParams2 { - pub fn commit_tree_nodes<>( + pub fn commit_tree_nodes( &self, nodes_x_coords: &[C::ScalarField], bf: C::ScalarField, ) -> Result, ()> { - let nodes_column =

>::tree_nodes_column(&self.piop_params, nodes_x_coords); + let nodes_column = +

>::tree_nodes_column(&self.piop_params, nodes_x_coords); let parent_node = self.pcs_params.commit_hiding(nodes_column.as_poly(), bf); parent_node } pub fn commit_fixed_columns(&self) -> Vec> { let fixed_columns =

>::fixed_columns(&self.piop_params); - fixed_columns.iter() - .map(|c| self.pcs_params.commit_hiding(c.as_poly(), C::ScalarField::zero()).unwrap()) + fixed_columns + .iter() + .map(|c| { + self.pcs_params + .commit_hiding(c.as_poly(), C::ScalarField::zero()) + .unwrap() + }) .collect() } @@ -146,7 +155,6 @@ where // } } - #[derive(Debug, PartialEq)] pub enum CycleSide { C0(C0), @@ -170,22 +178,22 @@ impl> ShplonkTranscript for Coeffs { #[cfg(test)] mod tests { use super::*; + use ark_ec::AdditiveGroup; use ark_ec::scalar_mul::glv::GLVConfig; use ark_ec::scalar_mul::wnaf::WnafContext; use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; - use ark_ec::AdditiveGroup; use ark_ec::{AffineRepr, CurveGroup}; - use ark_ff::{FftField, PrimeField}; use ark_ff::{BigInteger, Field, Zero}; + use ark_ff::{FftField, PrimeField}; use ark_pallas::PallasConfig; use ark_poly::DenseUVPolynomial; use ark_std::rand::Rng; - use ark_std::{cfg_iter_mut, end_timer, start_timer, test_rng, UniformRand}; + use ark_std::{UniformRand, cfg_iter_mut, end_timer, start_timer, test_rng}; use ark_vesta::VestaConfig; - use w3f_pcs::pcs::ipa::IPA; - use w3f_pcs::pcs::PcsParams; - use w3f_pcs::pcs::PCS; use w3f_pcs::Poly; + use w3f_pcs::pcs::PCS; + use w3f_pcs::pcs::PcsParams; + use w3f_pcs::pcs::ipa::IPA; use w3f_plonk_common::test_helpers::random_vec; use crate::auth_path::node::LevelWitness; @@ -209,7 +217,7 @@ mod tests { } } - pub fn random_nodes, R: Rng>( + pub fn random_nodes, R: Rng>( params: &CycleSideParams2>, path_node: G, rng: &mut R, @@ -221,7 +229,7 @@ mod tests { pub fn random_path< C0: CurveGroup, - C1: CurveGroup, + C1: CurveGroup, R: Rng, >( params: &CycleParams2, PiopParams>, @@ -264,8 +272,8 @@ mod tests { where F0: PrimeField, F1: PrimeField, - C0: SWCurveConfig, - C1: SWCurveConfig, + C0: SWCurveConfig, + C1: SWCurveConfig, { let rng = &mut test_rng(); @@ -544,4 +552,4 @@ mod tests { assert_eq!(res_, res); } -} \ No newline at end of file +} diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 8769817..12c7995 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -8,12 +8,12 @@ use crate::{Coeffs, CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; // use ark_ec::short_weierstrass::{Affine as SwAffine, Projective, SWCurveConfig}; use ark_ff::{PrimeField, Zero}; -use ark_std::rand::Rng; use ark_std::UniformRand; +use ark_std::rand::Rng; use std::collections::BTreeSet; +use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; -use w3f_pcs::pcs::PcsParams; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; @@ -22,20 +22,18 @@ use w3f_ring_proof::ArkTranscript; impl CycleParams2 where C0: CurveGroup, - C1: CurveGroup, - P0: CircuitParams>, - P1: CircuitParams>, + C1: CurveGroup, + P0: CircuitParams>, + P1: CircuitParams>, { pub fn prove( &self, auth_path: AuthenticationPath, rng: &mut R, - ) -> ( - BlindedAuthenticationPath, - CurveTreeProof, - ) { + ) -> (BlindedAuthenticationPath, CurveTreeProof) { let auth_path_with_bf = auth_path.with_blinding(rng); - let blinded_auth_path = auth_path_with_bf.apply_bfs(&self.c0_params.pcs_params, &self.c1_params.pcs_params); + let blinded_auth_path = + auth_path_with_bf.apply_bfs(&self.c0_params.pcs_params, &self.c1_params.pcs_params); let auth_path = blinded_auth_path.clone(); let c0_proof = self.c0_params @@ -47,8 +45,11 @@ where } } -impl, P: CircuitParams>> -CycleSideParams2 +impl< + C: CurveGroup, + G: AffineRepr, + P: CircuitParams>, +> CycleSideParams2 { pub fn prove_side( &self, @@ -74,8 +75,10 @@ CycleSideParams2 ); for (level, blinded_node) in witness.into_iter().zip(blinded_path.into_iter()) { - let piop: PiopProver =

>::prover_circuit(&self.piop_params, level.clone()); - let result = as ProverPiop>>::result(&piop); + let piop: PiopProver = +

>::prover_circuit(&self.piop_params, level.clone()); + let result = + as ProverPiop>>::result(&piop); debug_assert_eq!(result, blinded_node); let (pcs_openings, piop_proof, _transcript) = plonk_prover.reduce_to_pcs_opening(piop); piop_proofs.push(piop_proof); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index fa789c3..e454fba 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,25 +1,24 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; -use crate::circuit_tall::verifier::PiopVerifier; use crate::circuit_tall::PiopProof; +use crate::circuit_tall::verifier::PiopVerifier; use crate::{CircuitParams, CycleParams2, CycleSideParams2}; use crate::{CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; // use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; use ark_ff::PrimeField; -use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::pcs::PcsParams; +use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::VerifierPiop; use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; use w3f_ring_proof::ArkTranscript; - impl CycleParams2 where C0: CurveGroup, - C1: CurveGroup, - P0: CircuitParams>, - P1: CircuitParams>, + C1: CurveGroup, + P0: CircuitParams>, + P1: CircuitParams>, { pub fn verify( &self, @@ -40,8 +39,11 @@ where } } -impl, P: CircuitParams>> -CycleSideParams2 +impl< + C: CurveGroup, + G: AffineRepr, + P: CircuitParams>, +> CycleSideParams2 { pub fn verify_side( &self, From bddb90cf443a9649970b946a646ec709fec2e594 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 18:09:54 +0300 Subject: [PATCH 33/42] renamed back --- pasta-tree/src/auth_path/blinded.rs | 4 ++-- pasta-tree/src/auth_path/node.rs | 8 ++++---- pasta-tree/src/auth_path/path.rs | 6 +++--- pasta-tree/src/lib.rs | 22 +++++++++++----------- pasta-tree/src/prover.rs | 6 +++--- pasta-tree/src/verifier.rs | 6 +++--- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/pasta-tree/src/auth_path/blinded.rs b/pasta-tree/src/auth_path/blinded.rs index fd85909..d7955bb 100644 --- a/pasta-tree/src/auth_path/blinded.rs +++ b/pasta-tree/src/auth_path/blinded.rs @@ -1,5 +1,5 @@ use crate::auth_path::node::LevelWitnessWithBlinding; -use crate::{CircuitParams, CycleParams2, CycleSide}; +use crate::{CircuitParams, CycleParams, CycleSide}; use ark_ec::CurveGroup; use ark_ff::PrimeField; use w3f_pcs::pcs::ipa::hiding::HidingIpa; @@ -39,7 +39,7 @@ where } pub fn compute_root( &self, - params: &CycleParams2, + params: &CycleParams, ) -> Result, ()> where P0: CircuitParams, diff --git a/pasta-tree/src/auth_path/node.rs b/pasta-tree/src/auth_path/node.rs index a6d0c04..ed16793 100644 --- a/pasta-tree/src/auth_path/node.rs +++ b/pasta-tree/src/auth_path/node.rs @@ -1,4 +1,4 @@ -use crate::{CircuitParams, CycleSideParams2}; +use crate::{CircuitParams, CycleSideParams}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::{PrimeField, Zero}; use ark_std::UniformRand; @@ -53,7 +53,7 @@ impl LevelWitness { self.with_blinding(G::ScalarField::rand(rng), parent_bf) } - pub fn compute_parent(&self, params: &CycleSideParams2) -> Result + pub fn compute_parent(&self, params: &CycleSideParams) -> Result where G::BaseField: PrimeField, C: CurveGroup, @@ -64,7 +64,7 @@ impl LevelWitness { fn compute_parent_with_bf( &self, - params: &CycleSideParams2, + params: &CycleSideParams, bf: C::ScalarField, ) -> Result where @@ -102,7 +102,7 @@ impl LevelWitnessWithBlinding { pub(crate) fn compute_parent( &self, - params: &CycleSideParams2, + params: &CycleSideParams, ) -> Result where G::BaseField: PrimeField, diff --git a/pasta-tree/src/auth_path/path.rs b/pasta-tree/src/auth_path/path.rs index 8dff40f..3eb5653 100644 --- a/pasta-tree/src/auth_path/path.rs +++ b/pasta-tree/src/auth_path/path.rs @@ -1,6 +1,6 @@ use crate::auth_path::blinded::AuthenticationPathWithBlinding; use crate::auth_path::node::LevelWitness; -use crate::{CircuitParams, CycleParams2, CycleSide}; +use crate::{CircuitParams, CycleParams, CycleSide}; use ark_ec::CurveGroup; use ark_ff::UniformRand; use ark_ff::{PrimeField, Zero}; @@ -70,7 +70,7 @@ where pub fn compute_root( &self, - params: &CycleParams2, + params: &CycleParams, ) -> Result, ()> where P0: CircuitParams, @@ -111,7 +111,7 @@ mod tests { let rng = &mut test_rng(); let domain_size = 2usize.pow(9); - let params = CycleParams2::::setup( + let params = CycleParams::::setup( domain_size, rng, ); diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 4206545..23dcc6d 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -47,7 +47,7 @@ pub trait CircuitParams fn fixed_columns(&self) -> Vec>; } -pub struct CycleSideParams2< +pub struct CycleSideParams< C: CurveGroup, G: AffineRepr, P: CircuitParams, @@ -57,14 +57,14 @@ pub struct CycleSideParams2< phantomm: PhantomData, } -pub struct CycleParams2< +pub struct CycleParams< C0: CurveGroup, C1: CurveGroup, P0: CircuitParams, P1: CircuitParams, > { - c0_params: CycleSideParams2, - c1_params: CycleSideParams2, + c0_params: CycleSideParams, + c1_params: CycleSideParams, } pub type LevelProof = PiopProof< @@ -87,7 +87,7 @@ pub struct CurveTreeProof { c1_proof: CycleSideProof, } -impl CycleParams2, PiopParams> +impl CycleParams, PiopParams> where C0: CurveGroup, C1: CurveGroup, @@ -101,12 +101,12 @@ where let c1_domain = Domain::::new(domain_size, true); let c1_piop_params = PiopParams::setup(c1_domain, c0_pcs_params.h, C0::Affine::rand(rng)); Self { - c0_params: CycleSideParams2 { + c0_params: CycleSideParams { pcs_params: c0_pcs_params, piop_params: c0_piop_params, phantomm: PhantomData, }, - c1_params: CycleSideParams2 { + c1_params: CycleSideParams { pcs_params: c1_pcs_params, piop_params: c1_piop_params, phantomm: PhantomData, @@ -116,7 +116,7 @@ where } impl, P: CircuitParams> - CycleSideParams2 + CycleSideParams { pub fn commit_tree_nodes( &self, @@ -218,7 +218,7 @@ mod tests { } pub fn random_nodes, R: Rng>( - params: &CycleSideParams2>, + params: &CycleSideParams>, path_node: G, rng: &mut R, ) -> (C::Affine, LevelWitness) { @@ -232,7 +232,7 @@ mod tests { C1: CurveGroup, R: Rng, >( - params: &CycleParams2, PiopParams>, + params: &CycleParams, PiopParams>, length: usize, rng: &mut R, ) -> ( @@ -278,7 +278,7 @@ mod tests { let rng = &mut test_rng(); let domain_size = 1 << log_n; - let params = CycleParams2::, Projective, _, _>::setup(domain_size, rng); + let params = CycleParams::, Projective, _, _>::setup(domain_size, rng); let (_leaf, path, wrapped_root) = random_path(¶ms, height, rng); let root = match wrapped_root { CycleSide::C0(root) => root, //TODO: panics on odd height diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 12c7995..b0c3de2 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -3,7 +3,7 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; use crate::circuit_tall::prover::PiopProver; use crate::circuit_tall::verifier::PiopVerifier; -use crate::{CircuitParams, CycleParams2, CycleSideParams2}; +use crate::{CircuitParams, CycleParams, CycleSideParams}; use crate::{Coeffs, CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; // use ark_ec::short_weierstrass::{Affine as SwAffine, Projective, SWCurveConfig}; @@ -19,7 +19,7 @@ use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; use w3f_ring_proof::ArkTranscript; -impl CycleParams2 +impl CycleParams where C0: CurveGroup, C1: CurveGroup, @@ -49,7 +49,7 @@ impl< C: CurveGroup, G: AffineRepr, P: CircuitParams>, -> CycleSideParams2 +> CycleSideParams { pub fn prove_side( &self, diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index e454fba..544bc1e 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,7 +1,7 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::circuit_tall::PiopProof; use crate::circuit_tall::verifier::PiopVerifier; -use crate::{CircuitParams, CycleParams2, CycleSideParams2}; +use crate::{CircuitParams, CycleParams, CycleSideParams}; use crate::{CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; // use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; @@ -13,7 +13,7 @@ use w3f_plonk_common::piop::VerifierPiop; use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; use w3f_ring_proof::ArkTranscript; -impl CycleParams2 +impl CycleParams where C0: CurveGroup, C1: CurveGroup, @@ -43,7 +43,7 @@ impl< C: CurveGroup, G: AffineRepr, P: CircuitParams>, -> CycleSideParams2 +> CycleSideParams { pub fn verify_side( &self, From 8da08b031a511fa9c8b3ab410de3726c6e11bc97 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 29 May 2026 18:36:40 +0300 Subject: [PATCH 34/42] circuit_fat restored --- pasta-tree/src/circuit_fat/params.rs | 41 +++++++++++++------------- pasta-tree/src/circuit_fat/prover.rs | 18 +++++------ pasta-tree/src/circuit_fat/verifier.rs | 10 +++---- pasta-tree/src/lib.rs | 15 +--------- 4 files changed, 35 insertions(+), 49 deletions(-) diff --git a/pasta-tree/src/circuit_fat/params.rs b/pasta-tree/src/circuit_fat/params.rs index d76bed8..67d4273 100644 --- a/pasta-tree/src/circuit_fat/params.rs +++ b/pasta-tree/src/circuit_fat/params.rs @@ -3,7 +3,7 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_fat::PiopProof; use crate::circuit_fat::prover::PiopProver; use crate::circuit_fat::verifier::PiopVerifier; -use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +// use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::One; use ark_ff::{AdditiveGroup, BigInteger, PrimeField, Zero}; @@ -25,28 +25,18 @@ pub struct PiopParams> { pub h: G, } -impl> CircuitParams - for PiopParams> +impl> CircuitParams +for PiopParams { - type Witness = LevelWitnessWithBlinding>; - - /// (re-randomized child, re-randomized parent) - type Instance = (SwAffine, C::Affine); type Proof = PiopProof; - type ProverCircuit = PiopProver>; - type VerifierCircuit = PiopVerifier>; + type ProverCircuit = PiopProver; + type VerifierCircuit = PiopVerifier; - fn prover_circuit(&self, level: Self::Witness) -> Self::ProverCircuit { + fn prover_circuit(&self, level: LevelWitnessWithBlinding) -> Self::ProverCircuit { PiopProver::build(&self, level) } - fn verifier_circuit( - &self, - instance: Self::Instance, - fixed_cols: &[WrappedAffine], - proof: Self::Proof, - zeta: C::ScalarField, - ) -> Self::VerifierCircuit { + fn verifier_circuit(&self, instance: (G, C::Affine), fixed_cols: &[WrappedAffine], proof: Self::Proof, zeta: C::ScalarField) -> Self::VerifierCircuit { let h_powers_comm: &[_; 2] = fixed_cols.try_into().expect("Expected 2 fixed columns"); let domain_at_zeta = self.domain.evaluate(zeta); let (child, x_parent) = instance; @@ -59,6 +49,15 @@ impl> CircuitParams< proof.columns_at_zeta.clone(), ) } + + fn tree_nodes_column(&self, children_x_coords: &[C::ScalarField]) -> FieldColumn { + self.x_coords_column(children_x_coords) + } + + fn fixed_columns(&self) -> Vec> { + let h_powers_col = self.h_powers_column(); + vec![h_powers_col.xs, h_powers_col.ys] + } } impl> PiopParams { @@ -75,17 +74,17 @@ impl> PiopParams { self.domain.capacity - 1 } - pub fn x_coords_column(&self, x_coords: Vec) -> FieldColumn { + pub fn x_coords_column(&self, x_coords: &[G::BaseField]) -> FieldColumn { let c = self.max_nodes(); assert!(x_coords.len() <= c); - let mut x_coords = x_coords; + let mut x_coords = x_coords.to_vec(); x_coords.resize(self.domain.domain_size(), G::BaseField::zero()); x_coords[c] = G::BaseField::one(); self.domain.domains.column_from_evals(x_coords, c) } pub fn h_powers_column(&self) -> AffineColumn { - let mut h_powers = self.power_of_2_multiples_of_h(); + let mut h_powers = self.powers_of_h(); h_powers.truncate(self.max_nodes()); AffineColumn::public_column(h_powers, &self.domain) } @@ -104,7 +103,7 @@ impl> PiopParams { BitColumn::init(bf_bits, &self.domain) } - fn power_of_2_multiples_of_h(&self) -> Vec { + fn powers_of_h(&self) -> Vec { let mut h = self.h.into_group(); let mut multiples = Vec::with_capacity(self.scalar_bitlen); multiples.push(h); diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index 3eb4694..f36872f 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -3,16 +3,14 @@ use crate::circuit_fat::params::PiopParams; use crate::circuit_fat::{ProofComms, ProofEvals}; use ark_ec::AffineRepr; use ark_ec::CurveGroup; -use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +// use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ff::One; use ark_ff::{FftField, PrimeField, Zero}; -use ark_poly::Evaluations; use ark_poly::univariate::DensePolynomial; +use ark_poly::Evaluations; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; -use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; -use w3f_plonk_common::gadgets::ProverGadget; use w3f_plonk_common::gadgets::booleanity::{BitColumn, Booleanity}; use w3f_plonk_common::gadgets::column_sum::ColumnSumPolys; use w3f_plonk_common::gadgets::ec::AffineColumn; @@ -20,7 +18,9 @@ use w3f_plonk_common::gadgets::ec::CondAdd; use w3f_plonk_common::gadgets::equal_cells::CellsEqPolys; use w3f_plonk_common::gadgets::fixed_cells::FixedCells; use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInv; +use w3f_plonk_common::gadgets::ProverGadget; use w3f_plonk_common::piop::ProverPiop; +use w3f_plonk_common::FieldColumn; pub struct PiopProver> { domain: Domain, @@ -44,7 +44,7 @@ pub struct PiopProver> { impl> PiopProver { pub fn build(params: &PiopParams, level: LevelWitnessWithBlinding) -> Self { let domain = params.domain.clone(); - let x_coords = params.x_coords_column(level.level_witness.x_coords()); + let x_coords = params.x_coords_column(&level.level_witness.x_coords()); let h_powers = params.h_powers_column(); let node_idx = params.node_selector(level.level_witness.path_node_idx); let bf_bits = params.bf_bits_column(level.bf); @@ -157,13 +157,13 @@ impl> PiopProver { } } -impl> - ProverPiop> for PiopProver> +impl> + ProverPiop> for PiopProver { const N_CONSTRAINTS: usize = 12; type Commitments = ProofComms; type Evaluations = ProofEvals; - type Instance = SwAffine; + type Instance = G; fn committed_columns) -> WrappedAffine>( &self, @@ -257,7 +257,7 @@ mod tests { use crate::tests::random_witness; use ark_bls12_381::G1Projective; use ark_ed_on_bls12_381_bandersnatch::{Fq, Fr, SWAffine}; - use ark_std::{UniformRand, test_rng}; + use ark_std::{test_rng, UniformRand}; use w3f_pcs::pcs::commitment::WrappedAffine; #[test] diff --git a/pasta-tree/src/circuit_fat/verifier.rs b/pasta-tree/src/circuit_fat/verifier.rs index 1870993..d69d036 100644 --- a/pasta-tree/src/circuit_fat/verifier.rs +++ b/pasta-tree/src/circuit_fat/verifier.rs @@ -1,5 +1,5 @@ use crate::circuit_fat::{ProofComms, ProofEvals}; -use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +// use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::One; use ark_ff::Zero; @@ -7,13 +7,13 @@ use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::domain::EvaluatedDomain; -use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::gadgets::booleanity::BooleanityValues; use w3f_plonk_common::gadgets::column_sum::ColumnSumEvals; -use w3f_plonk_common::gadgets::ec::{AffineColumn, CondAddValues}; +use w3f_plonk_common::gadgets::ec::CondAddValues; use w3f_plonk_common::gadgets::equal_cells::EqualCells; use w3f_plonk_common::gadgets::fixed_cells::FixedCellsValues; use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInvValues; +use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::piop::VerifierPiop; pub struct PiopVerifier> { @@ -95,8 +95,8 @@ impl> PiopVerifier> - VerifierPiop> for PiopVerifier> +impl> + VerifierPiop> for PiopVerifier { const N_CONSTRAINTS: usize = 12; const N_COLUMNS: usize = 9; diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 23dcc6d..1897216 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -17,7 +17,7 @@ use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::{FieldColumn, PiopProof}; pub mod auth_path; -// pub mod circuit_fat; +pub mod circuit_fat; pub mod circuit_tall; // pub mod level; pub mod prover; @@ -140,19 +140,6 @@ impl, P: CircuitParams< }) .collect() } - - // pub fn commit_h_powers(&self) -> [IPACommitment; 2] { - // let h_powers = self.piop_params.h_powers_column(); - // let h_powers = [ - // self.pcs_params - // .commit_hiding(h_powers.xs.as_poly(), C::ScalarField::zero()) - // .unwrap(), - // self.pcs_params - // .commit_hiding(h_powers.ys.as_poly(), C::ScalarField::zero()) - // .unwrap(), - // ]; - // h_powers - // } } #[derive(Debug, PartialEq)] From 16121bdec19414ba40f35936ee2034a3bde1cd95 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sat, 30 May 2026 19:25:57 +0300 Subject: [PATCH 35/42] the CircuitParams trait fixed --- pasta-tree/src/circuit_fat/mod.rs | 9 +-- pasta-tree/src/circuit_fat/params.rs | 24 ++++-- pasta-tree/src/circuit_fat/prover.rs | 8 +- pasta-tree/src/circuit_fat/verifier.rs | 2 +- pasta-tree/src/circuit_tall/params.rs | 22 +++--- pasta-tree/src/lib.rs | 100 ++++++++++++++----------- pasta-tree/src/prover.rs | 26 +++---- pasta-tree/src/verifier.rs | 27 +++---- 8 files changed, 116 insertions(+), 102 deletions(-) diff --git a/pasta-tree/src/circuit_fat/mod.rs b/pasta-tree/src/circuit_fat/mod.rs index 6e9a709..e7e53b4 100644 --- a/pasta-tree/src/circuit_fat/mod.rs +++ b/pasta-tree/src/circuit_fat/mod.rs @@ -1,4 +1,4 @@ -use ark_ec::{CurveGroup, PrimeGroup}; +use ark_ec::CurveGroup; use ark_ff::PrimeField; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::{vec, vec::Vec}; @@ -9,13 +9,6 @@ pub mod params; pub mod prover; pub mod verifier; -type PiopProof = w3f_plonk_common::PiopProof< - ::ScalarField, - WrappedAffine, - ProofComms, - ProofEvals<::ScalarField>, ->; - #[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct ProofComms { pub(crate) node_idx: WrappedAffine, diff --git a/pasta-tree/src/circuit_fat/params.rs b/pasta-tree/src/circuit_fat/params.rs index 67d4273..e92bd03 100644 --- a/pasta-tree/src/circuit_fat/params.rs +++ b/pasta-tree/src/circuit_fat/params.rs @@ -1,6 +1,5 @@ use crate::CircuitParams; use crate::auth_path::node::LevelWitnessWithBlinding; -use crate::circuit_fat::PiopProof; use crate::circuit_fat::prover::PiopProver; use crate::circuit_fat::verifier::PiopVerifier; // use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; @@ -26,9 +25,10 @@ pub struct PiopParams> { } impl> CircuitParams -for PiopParams + for PiopParams { - type Proof = PiopProof; + type Commitments = crate::circuit_fat::ProofComms; + type Evaluations = crate::circuit_fat::ProofEvals; type ProverCircuit = PiopProver; type VerifierCircuit = PiopVerifier; @@ -36,7 +36,14 @@ for PiopParams PiopProver::build(&self, level) } - fn verifier_circuit(&self, instance: (G, C::Affine), fixed_cols: &[WrappedAffine], proof: Self::Proof, zeta: C::ScalarField) -> Self::VerifierCircuit { + fn verifier_circuit( + &self, + instance: (G, C::Affine), + fixed_cols: &[WrappedAffine], + cols: Self::Commitments, + evals: Self::Evaluations, + zeta: C::ScalarField, + ) -> Self::VerifierCircuit { let h_powers_comm: &[_; 2] = fixed_cols.try_into().expect("Expected 2 fixed columns"); let domain_at_zeta = self.domain.evaluate(zeta); let (child, x_parent) = instance; @@ -45,12 +52,15 @@ for PiopParams WrappedAffine(x_parent), domain_at_zeta, h_powers_comm.clone(), - proof.column_commitments.clone(), - proof.columns_at_zeta.clone(), + cols, + evals, ) } - fn tree_nodes_column(&self, children_x_coords: &[C::ScalarField]) -> FieldColumn { + fn tree_nodes_column( + &self, + children_x_coords: &[C::ScalarField], + ) -> FieldColumn { self.x_coords_column(children_x_coords) } diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index f36872f..91d9e9e 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -6,11 +6,13 @@ use ark_ec::CurveGroup; // use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; use ark_ff::One; use ark_ff::{FftField, PrimeField, Zero}; -use ark_poly::univariate::DensePolynomial; use ark_poly::Evaluations; +use ark_poly::univariate::DensePolynomial; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; +use w3f_plonk_common::FieldColumn; use w3f_plonk_common::domain::Domain; +use w3f_plonk_common::gadgets::ProverGadget; use w3f_plonk_common::gadgets::booleanity::{BitColumn, Booleanity}; use w3f_plonk_common::gadgets::column_sum::ColumnSumPolys; use w3f_plonk_common::gadgets::ec::AffineColumn; @@ -18,9 +20,7 @@ use w3f_plonk_common::gadgets::ec::CondAdd; use w3f_plonk_common::gadgets::equal_cells::CellsEqPolys; use w3f_plonk_common::gadgets::fixed_cells::FixedCells; use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInv; -use w3f_plonk_common::gadgets::ProverGadget; use w3f_plonk_common::piop::ProverPiop; -use w3f_plonk_common::FieldColumn; pub struct PiopProver> { domain: Domain, @@ -257,7 +257,7 @@ mod tests { use crate::tests::random_witness; use ark_bls12_381::G1Projective; use ark_ed_on_bls12_381_bandersnatch::{Fq, Fr, SWAffine}; - use ark_std::{test_rng, UniformRand}; + use ark_std::{UniformRand, test_rng}; use w3f_pcs::pcs::commitment::WrappedAffine; #[test] diff --git a/pasta-tree/src/circuit_fat/verifier.rs b/pasta-tree/src/circuit_fat/verifier.rs index d69d036..a98b4ae 100644 --- a/pasta-tree/src/circuit_fat/verifier.rs +++ b/pasta-tree/src/circuit_fat/verifier.rs @@ -7,13 +7,13 @@ use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::domain::EvaluatedDomain; +use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::gadgets::booleanity::BooleanityValues; use w3f_plonk_common::gadgets::column_sum::ColumnSumEvals; use w3f_plonk_common::gadgets::ec::CondAddValues; use w3f_plonk_common::gadgets::equal_cells::EqualCells; use w3f_plonk_common::gadgets::fixed_cells::FixedCellsValues; use w3f_plonk_common::gadgets::inner_prod_inv::InnerProdInvValues; -use w3f_plonk_common::gadgets::VerifierGadget; use w3f_plonk_common::piop::VerifierPiop; pub struct PiopVerifier> { diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 6b0f1c9..0b48604 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -1,6 +1,5 @@ use crate::CircuitParams; use crate::auth_path::node::LevelWitnessWithBlinding; -use crate::circuit_tall::PiopProof; use crate::circuit_tall::prover::PiopProver; use crate::circuit_tall::verifier::PiopVerifier; // use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; @@ -14,24 +13,28 @@ use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; -/// Plonk Interactive Oracle Proofs (PIOP) parameters. -/// `max_nodes + blinding_bits = domain.capacity - 1` +// `max_nodes + blinding_bits = domain.capacity - 1` +// where `1` acounts for the `seed` point. +/// Circuit parameters #[derive(Clone)] pub struct PiopParams> { - /// Domain over which the piop is represented. + /// Domain over which the circuit is represented. pub domain: Domain, + /// Maximal number of children per tree node. pub max_nodes: usize, /// Number of bits used to represent a blinding factor. pub blinding_bits: usize, + /// Point that initializes the EC addition gadget accumulator. pub seed: G, - /// Blinding base point. + /// Pedersen blinding base point. pub h: G, } impl> CircuitParams for PiopParams { - type Proof = PiopProof; + type Commitments = crate::circuit_tall::ProofComms; + type Evaluations = crate::circuit_tall::ProofEvals; type ProverCircuit = PiopProver; type VerifierCircuit = PiopVerifier; @@ -43,7 +46,8 @@ impl> CircuitParams], - proof: Self::Proof, + cols: Self::Commitments, + evals: Self::Evaluations, zeta: C::ScalarField, ) -> Self::VerifierCircuit { assert_eq!(fixed_cols.len(), 1, "Expected 1 fixed columns"); @@ -54,8 +58,8 @@ impl> CircuitParams> { - type Proof; - type ProverCircuit: ProverPiop>; + type Commitments: ColumnsCommited>; + type Evaluations: ColumnsEvaluated; + type ProverCircuit: ProverPiop< + C::ScalarField, + WrappedAffine, + Instance = G, + Commitments = Self::Commitments, + Evaluations = Self::Evaluations, + >; type VerifierCircuit: VerifierPiop>; fn prover_circuit(&self, level: LevelWitnessWithBlinding) -> Self::ProverCircuit; @@ -35,7 +37,8 @@ pub trait CircuitParams &self, instance: (G, C::Affine), fixed_cols: &[WrappedAffine], - proof: Self::Proof, + cols: Self::Commitments, + evals: Self::Evaluations, zeta: C::ScalarField, ) -> Self::VerifierCircuit; @@ -67,54 +70,63 @@ pub struct CycleParams< c1_params: CycleSideParams, } -pub type LevelProof = PiopProof< +type LevelProof = w3f_plonk_common::PiopProof< ::ScalarField, WrappedAffine, - ProofComms, - ProofEvals<::ScalarField>, +

>::Commitments, +

>::Evaluations, >; #[derive(Clone)] -pub struct CycleSideProof { - piop_proofs: Vec>, +pub struct CycleSideProof< + C: CurveGroup, + G: AffineRepr, + P: CircuitParams, +> { + piop_proofs: Vec>, pcs_proof: AggregateProof>, todo: Coeffs, } #[derive(Clone)] -pub struct CurveTreeProof { - c0_proof: CycleSideProof, - c1_proof: CycleSideProof, -} - -impl CycleParams, PiopParams> -where - C0: CurveGroup, +pub struct CurveTreeProof< + C0: CurveGroup, C1: CurveGroup, -{ - pub fn setup(domain_size: usize, rng: &mut R) -> Self { - let setup_degree = 3 * domain_size; - let c0_pcs_params = HidingIpa::::setup(setup_degree, rng); - let c1_pcs_params = HidingIpa::::setup(setup_degree, rng); - let c0_domain = Domain::::new(domain_size, true); - let c0_piop_params = PiopParams::setup(c0_domain, c1_pcs_params.h, C1::Affine::rand(rng)); - let c1_domain = Domain::::new(domain_size, true); - let c1_piop_params = PiopParams::setup(c1_domain, c0_pcs_params.h, C0::Affine::rand(rng)); - Self { - c0_params: CycleSideParams { - pcs_params: c0_pcs_params, - piop_params: c0_piop_params, - phantomm: PhantomData, - }, - c1_params: CycleSideParams { - pcs_params: c1_pcs_params, - piop_params: c1_piop_params, - phantomm: PhantomData, - }, - } - } + P0: CircuitParams, + P1: CircuitParams, +> { + c0_proof: CycleSideProof, + c1_proof: CycleSideProof, } +// impl CycleParams +// where +// C0: CurveGroup, +// C1: CurveGroup, +// { +// pub fn setup(domain_size: usize, rng: &mut R) -> Self { +// let setup_degree = 3 * domain_size; +// let c0_pcs_params = HidingIpa::::setup(setup_degree, rng); +// let c1_pcs_params = HidingIpa::::setup(setup_degree, rng); +// let c0_domain = Domain::::new(domain_size, true); +// let c0_piop_params = PiopParams::setup(c0_domain, c1_pcs_params.h, C1::Affine::rand(rng)); +// let c1_domain = Domain::::new(domain_size, true); +// let c1_piop_params = PiopParams::setup(c1_domain, c0_pcs_params.h, C0::Affine::rand(rng)); +// Self { +// c0_params: CycleSideParams { +// pcs_params: c0_pcs_params, +// piop_params: c0_piop_params, +// phantomm: PhantomData, +// }, +// c1_params: CycleSideParams { +// pcs_params: c1_pcs_params, +// piop_params: c1_piop_params, +// phantomm: PhantomData, +// }, +// } +// } +// } + impl, P: CircuitParams> CycleSideParams { diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index b0c3de2..e1f91a2 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -1,8 +1,6 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; -use crate::circuit_tall::prover::PiopProver; -use crate::circuit_tall::verifier::PiopVerifier; use crate::{CircuitParams, CycleParams, CycleSideParams}; use crate::{Coeffs, CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; @@ -23,14 +21,17 @@ impl CycleParams where C0: CurveGroup, C1: CurveGroup, - P0: CircuitParams>, - P1: CircuitParams>, + P0: CircuitParams, + P1: CircuitParams, { pub fn prove( &self, auth_path: AuthenticationPath, rng: &mut R, - ) -> (BlindedAuthenticationPath, CurveTreeProof) { + ) -> ( + BlindedAuthenticationPath, + CurveTreeProof, + ) { let auth_path_with_bf = auth_path.with_blinding(rng); let blinded_auth_path = auth_path_with_bf.apply_bfs(&self.c0_params.pcs_params, &self.c1_params.pcs_params); @@ -45,24 +46,21 @@ where } } -impl< - C: CurveGroup, - G: AffineRepr, - P: CircuitParams>, -> CycleSideParams +impl, P: CircuitParams> + CycleSideParams { pub fn prove_side( &self, blinded_path: Vec, witness: Vec>, rng: &mut R, - ) -> CycleSideProof { + ) -> CycleSideProof { // let mut s = std::any::type_name::(); // s = &s[70..s.len()]; // println!("\n\nprover {s}\nchildren={blinded_path:?}\n"); debug_assert_eq!(blinded_path.len(), witness.len()); - let n_polys = PiopVerifier::::N_COLUMNS + 2; // plus the quotient and the linearization polys + let n_polys = P::VerifierCircuit::N_COLUMNS + 2; // plus the quotient and the linearization polys let mut piop_proofs = Vec::with_capacity(witness.len()); let mut polys = Vec::with_capacity(witness.len() * n_polys); let mut coords = Vec::with_capacity(witness.len() * n_polys); @@ -75,10 +73,10 @@ impl< ); for (level, blinded_node) in witness.into_iter().zip(blinded_path.into_iter()) { - let piop: PiopProver = + let piop: P::ProverCircuit =

>::prover_circuit(&self.piop_params, level.clone()); let result = - as ProverPiop>>::result(&piop); + >>::result(&piop); debug_assert_eq!(result, blinded_node); let (pcs_openings, piop_proof, _transcript) = plonk_prover.reduce_to_pcs_opening(piop); piop_proofs.push(piop_proof); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 544bc1e..50f0ea1 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,6 +1,4 @@ use crate::auth_path::blinded::BlindedAuthenticationPath; -use crate::circuit_tall::PiopProof; -use crate::circuit_tall::verifier::PiopVerifier; use crate::{CircuitParams, CycleParams, CycleSideParams}; use crate::{CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; @@ -17,13 +15,13 @@ impl CycleParams where C0: CurveGroup, C1: CurveGroup, - P0: CircuitParams>, - P1: CircuitParams>, + P0: CircuitParams, + P1: CircuitParams, { pub fn verify( &self, auth_path: BlindedAuthenticationPath, - proof: CurveTreeProof, + proof: CurveTreeProof, root: C0::Affine, ) -> bool { let BlindedAuthenticationPath { c0_path, c1_path } = auth_path; @@ -39,11 +37,8 @@ where } } -impl< - C: CurveGroup, - G: AffineRepr, - P: CircuitParams>, -> CycleSideParams +impl, P: CircuitParams> + CycleSideParams { pub fn verify_side( &self, @@ -51,7 +46,7 @@ impl< children: Vec, // parents, re-randomized at the previous step parents: Vec, - side_proof: CycleSideProof, + side_proof: CycleSideProof, ) -> bool { // let mut s = std::any::type_name::(); // s = &s[65..s.len()]; @@ -63,11 +58,12 @@ impl< ArkTranscript::new(b"pasta-tree-level-proof"), ); - let n_polys = PiopVerifier::::N_COLUMNS + 2; // plus the quotient and the linearization polys + let n_polys = P::VerifierCircuit::N_COLUMNS + 2; // plus the quotient and the linearization polys let mut polys = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); let mut coords = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); let mut vals = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); + //TODO: let selector = self.commit_fixed_columns()[0].clone(); for ((child, parent), level_proof) in children @@ -79,13 +75,14 @@ impl< &child, &level_proof, // '1' accounts for the quotient polynomial that is aggregated together with the columns - PiopVerifier::::N_COLUMNS + 1, - PiopVerifier::::N_CONSTRAINTS, + P::VerifierCircuit::N_COLUMNS + 1, + P::VerifierCircuit::N_CONSTRAINTS, ); let piop = self.piop_params.verifier_circuit( (child, parent), &[selector.clone()], - level_proof.clone(), + level_proof.column_commitments.clone(), + level_proof.columns_at_zeta.clone(), challenges.zeta, ); let PcsOpeningAt2Points { From bc7405a3929c37a7d2a026137eb9f850784daf31 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 01:19:00 +0300 Subject: [PATCH 36/42] test fixed --- pasta-tree/src/auth_path/path.rs | 11 ++- pasta-tree/src/circuit_fat/params.rs | 9 +++ pasta-tree/src/circuit_tall/params.rs | 13 ++- pasta-tree/src/lib.rs | 111 ++++++++++++++++---------- 4 files changed, 94 insertions(+), 50 deletions(-) diff --git a/pasta-tree/src/auth_path/path.rs b/pasta-tree/src/auth_path/path.rs index 3eb5653..5ad436b 100644 --- a/pasta-tree/src/auth_path/path.rs +++ b/pasta-tree/src/auth_path/path.rs @@ -103,6 +103,7 @@ where #[cfg(test)] mod tests { use super::*; + use crate::circuit_tall::params::PiopParams; use crate::tests::random_path; use ark_std::test_rng; @@ -111,10 +112,12 @@ mod tests { let rng = &mut test_rng(); let domain_size = 2usize.pow(9); - let params = CycleParams::::setup( - domain_size, - rng, - ); + let params = CycleParams::< + ark_pallas::Projective, + ark_vesta::Projective, + PiopParams, + PiopParams, + >::setup(domain_size, rng); let (leaf, path, root) = random_path(¶ms, 2, rng); diff --git a/pasta-tree/src/circuit_fat/params.rs b/pasta-tree/src/circuit_fat/params.rs index e92bd03..787746c 100644 --- a/pasta-tree/src/circuit_fat/params.rs +++ b/pasta-tree/src/circuit_fat/params.rs @@ -68,6 +68,15 @@ impl> CircuitParams usize { + self.max_nodes() + } + + #[cfg(test)] + fn setup(domain: Domain, h: G, _seed: G) -> Self { + Self::setup(domain, h) + } } impl> PiopParams { diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 0b48604..4971f27 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -65,6 +65,10 @@ impl> CircuitParams Vec> { + vec![self.select_part()] + } + fn tree_nodes_column(&self, children_x_coords: &[G::BaseField]) -> FieldColumn { assert!(children_x_coords.len() <= self.max_nodes); let mut x_coords = children_x_coords.to_vec(); @@ -85,8 +89,13 @@ impl> CircuitParams Vec> { - vec![self.select_part()] + fn max_children(&self) -> usize { + self.max_nodes + } + + #[cfg(test)] + fn setup(domain: Domain, h: G, seed: G) -> Self { + Self::setup(domain, h, seed) } } diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 696e96a..e746fe3 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -8,6 +8,8 @@ use w3f_pcs::pcs::PCS; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::AggregateProof; +#[cfg(test)] +use w3f_plonk_common::domain::Domain; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::{ColumnsCommited, ColumnsEvaluated, FieldColumn}; @@ -18,7 +20,8 @@ pub mod circuit_tall; pub mod prover; pub mod verifier; -/// The circuit is over `C::ScalarField`. +// TODO: goes vto plonk-common in some form +/// A circuit over `C::ScalarField`. pub trait CircuitParams> { type Commitments: ColumnsCommited>; type Evaluations: ColumnsEvaluated; @@ -42,12 +45,18 @@ pub trait CircuitParams zeta: C::ScalarField, ) -> Self::VerifierCircuit; + fn fixed_columns(&self) -> Vec>; + fn tree_nodes_column( &self, children_x_coords: &[C::ScalarField], ) -> FieldColumn; - fn fixed_columns(&self) -> Vec>; + fn max_children(&self) -> usize; + + #[cfg(test)] // an "application" runs usually a single circuit + /// `h` is the pedersen blinding base (from the opposite side) to prove `C' = Ci + rH` + fn setup(domain: Domain, h: G, seed: G) -> Self; } pub struct CycleSideParams< @@ -99,34 +108,6 @@ pub struct CurveTreeProof< c1_proof: CycleSideProof, } -// impl CycleParams -// where -// C0: CurveGroup, -// C1: CurveGroup, -// { -// pub fn setup(domain_size: usize, rng: &mut R) -> Self { -// let setup_degree = 3 * domain_size; -// let c0_pcs_params = HidingIpa::::setup(setup_degree, rng); -// let c1_pcs_params = HidingIpa::::setup(setup_degree, rng); -// let c0_domain = Domain::::new(domain_size, true); -// let c0_piop_params = PiopParams::setup(c0_domain, c1_pcs_params.h, C1::Affine::rand(rng)); -// let c1_domain = Domain::::new(domain_size, true); -// let c1_piop_params = PiopParams::setup(c1_domain, c0_pcs_params.h, C0::Affine::rand(rng)); -// Self { -// c0_params: CycleSideParams { -// pcs_params: c0_pcs_params, -// piop_params: c0_piop_params, -// phantomm: PhantomData, -// }, -// c1_params: CycleSideParams { -// pcs_params: c1_pcs_params, -// piop_params: c1_piop_params, -// phantomm: PhantomData, -// }, -// } -// } -// } - impl, P: CircuitParams> CycleSideParams { @@ -180,7 +161,7 @@ mod tests { use ark_ec::AdditiveGroup; use ark_ec::scalar_mul::glv::GLVConfig; use ark_ec::scalar_mul::wnaf::WnafContext; - use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; + use ark_ec::short_weierstrass::{Affine, SWCurveConfig}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::{BigInteger, Field, Zero}; use ark_ff::{FftField, PrimeField}; @@ -188,7 +169,6 @@ mod tests { use ark_poly::DenseUVPolynomial; use ark_std::rand::Rng; use ark_std::{UniformRand, cfg_iter_mut, end_timer, start_timer, test_rng}; - use ark_vesta::VestaConfig; use w3f_pcs::Poly; use w3f_pcs::pcs::PCS; use w3f_pcs::pcs::PcsParams; @@ -197,11 +177,42 @@ mod tests { use crate::auth_path::node::LevelWitness; use crate::auth_path::path::AuthenticationPath; + use crate::circuit_tall::params::PiopParams; #[cfg(feature = "parallel")] use rayon::prelude::*; type PallasIPA = IPA; + impl CycleParams + where + C0: CurveGroup, + C1: CurveGroup, + P0: CircuitParams, + P1: CircuitParams, + { + pub fn setup(domain_size: usize, rng: &mut R) -> Self { + let setup_degree = 3 * domain_size; + let c0_pcs_params = HidingIpa::::setup(setup_degree, rng); + let c1_pcs_params = HidingIpa::::setup(setup_degree, rng); + let c0_domain = Domain::::new(domain_size, true); + let c0_piop_params = P0::setup(c0_domain, c1_pcs_params.h, C1::Affine::rand(rng)); + let c1_domain = Domain::::new(domain_size, true); + let c1_piop_params = P1::setup(c1_domain, c0_pcs_params.h, C0::Affine::rand(rng)); + Self { + c0_params: CycleSideParams { + pcs_params: c0_pcs_params, + piop_params: c0_piop_params, + phantomm: PhantomData, + }, + c1_params: CycleSideParams { + pcs_params: c1_pcs_params, + piop_params: c1_piop_params, + phantomm: PhantomData, + }, + } + } + } + pub fn random_witness, R: Rng>( capacity: usize, path_node: G, @@ -216,12 +227,17 @@ mod tests { } } - pub fn random_nodes, R: Rng>( - params: &CycleSideParams>, + pub fn random_nodes< + C: CurveGroup, + G: AffineRepr, + P: CircuitParams, + R: Rng, + >( + params: &CycleSideParams, path_node: G, rng: &mut R, ) -> (C::Affine, LevelWitness) { - let level_witness = random_witness(params.piop_params.max_nodes, path_node, rng); + let level_witness = random_witness(params.piop_params.max_children(), path_node, rng); let parent = level_witness.compute_parent(params).unwrap(); (parent, level_witness) } @@ -229,9 +245,11 @@ mod tests { pub fn random_path< C0: CurveGroup, C1: CurveGroup, + P0: CircuitParams, + P1: CircuitParams, R: Rng, >( - params: &CycleParams, PiopParams>, + params: &CycleParams, length: usize, rng: &mut R, ) -> ( @@ -267,24 +285,24 @@ mod tests { (leaf, path, root) } - fn _test_proof(log_n: usize, height: usize) + fn _test_proof(log_n: usize, height: usize) where - F0: PrimeField, - F1: PrimeField, - C0: SWCurveConfig, - C1: SWCurveConfig, + C0: CurveGroup, + C1: CurveGroup, + P0: CircuitParams, + P1: CircuitParams, { let rng = &mut test_rng(); let domain_size = 1 << log_n; - let params = CycleParams::, Projective, _, _>::setup(domain_size, rng); + let params = CycleParams::::setup(domain_size, rng); let (_leaf, path, wrapped_root) = random_path(¶ms, height, rng); let root = match wrapped_root { CycleSide::C0(root) => root, //TODO: panics on odd height _ => panic!(), }; - let max_nodes = params.c0_params.piop_params.max_nodes; + let max_nodes = params.c0_params.piop_params.max_children(); let t_prove = start_timer!(|| format!( "Proving CurveTree membership, height={height}, domain={domain_size}, arity={max_nodes}, capacity={}", max_nodes.pow(height as u32) @@ -302,7 +320,12 @@ mod tests { // cargo test test_curve_tree_proof --release --features="print-trace parallel" -- --show-output #[test] fn test_curve_tree_proof() { - _test_proof::<_, _, PallasConfig, VestaConfig>(9, 4); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + PiopParams, + PiopParams, + >(9, 4); } fn _bench_msm(log_n: u32) { From 419a4e295d2a2b7c5fe21216ff1e2c9da3e65266 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 01:30:35 +0300 Subject: [PATCH 37/42] test fixed - 2 --- pasta-tree/src/circuit_fat/params.rs | 10 +++++----- pasta-tree/src/lib.rs | 30 +++++++++++++++++++--------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/pasta-tree/src/circuit_fat/params.rs b/pasta-tree/src/circuit_fat/params.rs index 787746c..5d8679d 100644 --- a/pasta-tree/src/circuit_fat/params.rs +++ b/pasta-tree/src/circuit_fat/params.rs @@ -57,6 +57,11 @@ impl> CircuitParams Vec> { + let h_powers_col = self.h_powers_column(); + vec![h_powers_col.xs, h_powers_col.ys] + } + fn tree_nodes_column( &self, children_x_coords: &[C::ScalarField], @@ -64,11 +69,6 @@ impl> CircuitParams Vec> { - let h_powers_col = self.h_powers_column(); - vec![h_powers_col.xs, h_powers_col.ys] - } - fn max_children(&self) -> usize { self.max_nodes() } diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index e746fe3..4e83a67 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -158,6 +158,10 @@ impl> ShplonkTranscript for Coeffs { #[cfg(test)] mod tests { use super::*; + use crate::auth_path::node::LevelWitness; + use crate::auth_path::path::AuthenticationPath; + use crate::circuit_fat::params::PiopParams as CircuitParamsFat; + use crate::circuit_tall::params::PiopParams as CircuitParamsTall; use ark_ec::AdditiveGroup; use ark_ec::scalar_mul::glv::GLVConfig; use ark_ec::scalar_mul::wnaf::WnafContext; @@ -175,9 +179,6 @@ mod tests { use w3f_pcs::pcs::ipa::IPA; use w3f_plonk_common::test_helpers::random_vec; - use crate::auth_path::node::LevelWitness; - use crate::auth_path::path::AuthenticationPath; - use crate::circuit_tall::params::PiopParams; #[cfg(feature = "parallel")] use rayon::prelude::*; @@ -316,16 +317,27 @@ mod tests { assert!(valid); } - // cargo test test_curve_tree_proof --release --features="print-trace" -- --show-output - // cargo test test_curve_tree_proof --release --features="print-trace parallel" -- --show-output + // cargo test test_bench_curve_tree --release --features="print-trace" -- --show-output + // cargo test test_bench_curve_tree --release --features="print-trace parallel" -- --show-output #[test] - fn test_curve_tree_proof() { + fn test_bench_curve_tree() { + // let log_n = 8; + // println!("n = {}, height = 4", 1 << log_n); + // _test_proof::< + // ark_pallas::Projective, + // ark_vesta::Projective, + // CircuitParamsFat, + // CircuitParamsFat, + // >(log_n, 4); + + let log_n = 9; + println!("n = {}, height = 4", 1 << log_n); _test_proof::< ark_pallas::Projective, ark_vesta::Projective, - PiopParams, - PiopParams, - >(9, 4); + CircuitParamsTall, + CircuitParamsTall, + >(log_n, 4); } fn _bench_msm(log_n: u32) { From a9ce26b2068bbf85707bd08f60a78140d1489800 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 01:33:20 +0300 Subject: [PATCH 38/42] tests pass --- pasta-tree/src/lib.rs | 16 ++++++++-------- pasta-tree/src/verifier.rs | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 4e83a67..678ee1a 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -321,14 +321,14 @@ mod tests { // cargo test test_bench_curve_tree --release --features="print-trace parallel" -- --show-output #[test] fn test_bench_curve_tree() { - // let log_n = 8; - // println!("n = {}, height = 4", 1 << log_n); - // _test_proof::< - // ark_pallas::Projective, - // ark_vesta::Projective, - // CircuitParamsFat, - // CircuitParamsFat, - // >(log_n, 4); + let log_n = 8; + println!("n = {}, height = 4", 1 << log_n); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsFat, + CircuitParamsFat, + >(log_n, 4); let log_n = 9; println!("n = {}, height = 4", 1 << log_n); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 50f0ea1..158f456 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -63,8 +63,8 @@ impl, P: CircuitParams< let mut coords = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); let mut vals = Vec::with_capacity(side_proof.piop_proofs.len() * n_polys); - //TODO: - let selector = self.commit_fixed_columns()[0].clone(); + //TODO: precompute + let fixed_cols = self.commit_fixed_columns(); for ((child, parent), level_proof) in children .into_iter() @@ -80,7 +80,7 @@ impl, P: CircuitParams< ); let piop = self.piop_params.verifier_circuit( (child, parent), - &[selector.clone()], + &fixed_cols, level_proof.column_commitments.clone(), level_proof.columns_at_zeta.clone(), challenges.zeta, From 306a3c73662a9ec62049904535d072e022cbcf45 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 03:06:40 +0300 Subject: [PATCH 39/42] better benches --- pasta-tree/Cargo.toml | 1 + pasta-tree/src/circuit_fat/prover.rs | 1 + pasta-tree/src/circuit_fat/verifier.rs | 2 +- pasta-tree/src/circuit_tall/prover.rs | 1 + pasta-tree/src/circuit_tall/verifier.rs | 2 +- pasta-tree/src/lib.rs | 145 +++++++++++++++--------- pasta-tree/src/prover.rs | 10 +- w3f-plonk-common/src/piop.rs | 3 +- w3f-plonk-common/src/prover.rs | 5 + w3f-ring-proof/src/piop/prover.rs | 2 + w3f-ring-proof/src/piop/verifier.rs | 2 +- 11 files changed, 115 insertions(+), 59 deletions(-) diff --git a/pasta-tree/Cargo.toml b/pasta-tree/Cargo.toml index 495d9cf..0cac01c 100644 --- a/pasta-tree/Cargo.toml +++ b/pasta-tree/Cargo.toml @@ -23,6 +23,7 @@ ark-serialize.workspace = true rayon = { workspace = true, optional = true } [dev-dependencies] +num-format = "0.4" ark-bls12-381.workspace = true ark-ed-on-bls12-381-bandersnatch.workspace = true criterion.workspace = true diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index 91d9e9e..a5aa88a 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -160,6 +160,7 @@ impl> PiopProver { impl> ProverPiop> for PiopProver { + const N_COLUMNS: usize = 9; const N_CONSTRAINTS: usize = 12; type Commitments = ProofComms; type Evaluations = ProofEvals; diff --git a/pasta-tree/src/circuit_fat/verifier.rs b/pasta-tree/src/circuit_fat/verifier.rs index a98b4ae..05df06e 100644 --- a/pasta-tree/src/circuit_fat/verifier.rs +++ b/pasta-tree/src/circuit_fat/verifier.rs @@ -98,8 +98,8 @@ impl> PiopVerifier> VerifierPiop> for PiopVerifier { - const N_CONSTRAINTS: usize = 12; const N_COLUMNS: usize = 9; + const N_CONSTRAINTS: usize = 12; fn precommitted_columns(&self) -> Vec> { vec![ diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index 1e54392..4ac3b60 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -101,6 +101,7 @@ impl> PiopProver { impl> ProverPiop> for PiopProver { + const N_COLUMNS: usize = 7; const N_CONSTRAINTS: usize = 7; type Commitments = ProofComms; type Evaluations = ProofEvals; diff --git a/pasta-tree/src/circuit_tall/verifier.rs b/pasta-tree/src/circuit_tall/verifier.rs index 74df3dd..715d35e 100644 --- a/pasta-tree/src/circuit_tall/verifier.rs +++ b/pasta-tree/src/circuit_tall/verifier.rs @@ -102,8 +102,8 @@ impl> PiopVerifier> VerifierPiop> for PiopVerifier { - const N_CONSTRAINTS: usize = 7; const N_COLUMNS: usize = 7; + const N_CONSTRAINTS: usize = 7; fn precommitted_columns(&self) -> Vec> { vec![self.points_x.clone(), self.select_part.clone()] diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 678ee1a..56ce560 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -173,6 +173,7 @@ mod tests { use ark_poly::DenseUVPolynomial; use ark_std::rand::Rng; use ark_std::{UniformRand, cfg_iter_mut, end_timer, start_timer, test_rng}; + use num_format::{Locale, ToFormattedString}; use w3f_pcs::Poly; use w3f_pcs::pcs::PCS; use w3f_pcs::pcs::PcsParams; @@ -214,6 +215,96 @@ mod tests { } } + // cargo test test_bench_curve_tree --release --features="print-trace" -- --show-output + // cargo test test_bench_curve_tree --release --features="print-trace parallel" -- --show-output + #[test] + fn test_bench_curve_tree() { + let (log_n, h) = (8, 2); + println!("n = {}, height = {h}, FAT", 1 << log_n); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsFat, + CircuitParamsFat, + >(log_n, h); + println!(); + + let (log_n, h) = (9, 2); + println!("n = {}, height = {h}, TALL", 1 << log_n); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsTall, + CircuitParamsTall, + >(log_n, h); + println!(); + + let (log_n, h) = (10, 2); + println!("n = {}, height = {h}, TALL", 1 << log_n); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsTall, + CircuitParamsTall, + >(log_n, h); + println!(); + + let (log_n, h) = (8, 4); + println!("n = {}, height = {h}, FAT", 1 << log_n); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsFat, + CircuitParamsFat, + >(log_n, h); + println!(); + + let (log_n, h) = (9, 4); + println!("n = {}, height = {h}, TALL", 1 << log_n); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsTall, + CircuitParamsTall, + >(log_n, h); + println!(); + } + + fn _test_proof(log_n: usize, height: usize) + where + C0: CurveGroup, + C1: CurveGroup, + P0: CircuitParams, + P1: CircuitParams, + { + let rng = &mut test_rng(); + let domain_size = 1 << log_n; + let params = CycleParams::::setup(domain_size, rng); + let (_leaf, path, wrapped_root) = random_path(¶ms, height, rng); + let root = match wrapped_root { + CycleSide::C0(root) => root, //TODO: panics on odd height + _ => panic!(), + }; + let max_nodes = params.c0_params.piop_params.max_children(); + println!( + "capacity=**{}**, arity={max_nodes}", + max_nodes + .pow(height as u32) + .to_formatted_string(&Locale::en) + ); + let t_prove = start_timer!(|| format!( + "Proving CurveTree membership, height={height}, domain={domain_size}, arity={max_nodes}, capacity={}", + max_nodes.pow(height as u32) + )); + let (auth_path, proof) = params.prove(path, rng); + end_timer!(t_prove); + + let t_verify = start_timer!(|| "Verifying CurveTree membership"); + let valid = params.verify(auth_path, proof, root); + end_timer!(t_verify); + assert!(valid); + } + pub fn random_witness, R: Rng>( capacity: usize, path_node: G, @@ -286,60 +377,6 @@ mod tests { (leaf, path, root) } - fn _test_proof(log_n: usize, height: usize) - where - C0: CurveGroup, - C1: CurveGroup, - P0: CircuitParams, - P1: CircuitParams, - { - let rng = &mut test_rng(); - - let domain_size = 1 << log_n; - let params = CycleParams::::setup(domain_size, rng); - let (_leaf, path, wrapped_root) = random_path(¶ms, height, rng); - let root = match wrapped_root { - CycleSide::C0(root) => root, //TODO: panics on odd height - _ => panic!(), - }; - - let max_nodes = params.c0_params.piop_params.max_children(); - let t_prove = start_timer!(|| format!( - "Proving CurveTree membership, height={height}, domain={domain_size}, arity={max_nodes}, capacity={}", - max_nodes.pow(height as u32) - )); - let (auth_path, proof) = params.prove(path, rng); - end_timer!(t_prove); - - let t_verify = start_timer!(|| "Verifying CurveTree membership"); - let valid = params.verify(auth_path, proof, root); - end_timer!(t_verify); - assert!(valid); - } - - // cargo test test_bench_curve_tree --release --features="print-trace" -- --show-output - // cargo test test_bench_curve_tree --release --features="print-trace parallel" -- --show-output - #[test] - fn test_bench_curve_tree() { - let log_n = 8; - println!("n = {}, height = 4", 1 << log_n); - _test_proof::< - ark_pallas::Projective, - ark_vesta::Projective, - CircuitParamsFat, - CircuitParamsFat, - >(log_n, 4); - - let log_n = 9; - println!("n = {}, height = 4", 1 << log_n); - _test_proof::< - ark_pallas::Projective, - ark_vesta::Projective, - CircuitParamsTall, - CircuitParamsTall, - >(log_n, 4); - } - fn _bench_msm(log_n: u32) { let rng = &mut test_rng(); let n = 2usize.pow(log_n); diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index e1f91a2..e387569 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -6,8 +6,9 @@ use crate::{Coeffs, CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; // use ark_ec::short_weierstrass::{Affine as SwAffine, Projective, SWCurveConfig}; use ark_ff::{PrimeField, Zero}; -use ark_std::UniformRand; +use ark_poly::Polynomial; use ark_std::rand::Rng; +use ark_std::{UniformRand, end_timer, start_timer}; use std::collections::BTreeSet; use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::commitment::WrappedAffine; @@ -104,6 +105,12 @@ impl, P: CircuitParams< bfs.resize(polys.len(), C::ScalarField::zero()); } + let max_degree = polys.iter().map(|p| p.degree()).max().unwrap(); + let t_open = start_timer!(|| format!( + "Opening {} polynomials with maximal degree-{}", + polys.len(), + max_degree + )); let todo = Coeffs(C::ScalarField::rand(rng), C::ScalarField::rand(rng)); let pcs_proof = Shplonk::>::open_many_hiding( &self.pcs_params, @@ -113,6 +120,7 @@ impl, P: CircuitParams< &mut todo.clone(), rng, ); + end_timer!(t_open); let proof = CycleSideProof { piop_proofs, diff --git a/w3f-plonk-common/src/piop.rs b/w3f-plonk-common/src/piop.rs index 1facf2c..fd9ec12 100644 --- a/w3f-plonk-common/src/piop.rs +++ b/w3f-plonk-common/src/piop.rs @@ -9,6 +9,7 @@ use crate::domain::{Domain, EvaluatedDomain}; use crate::{ColumnsCommited, ColumnsEvaluated}; pub trait ProverPiop> { + const N_COLUMNS: usize; const N_CONSTRAINTS: usize; type Commitments: ColumnsCommited; @@ -78,8 +79,8 @@ pub fn aggregate_evaluations( } pub trait VerifierPiop> { - const N_CONSTRAINTS: usize; const N_COLUMNS: usize; + const N_CONSTRAINTS: usize; // Columns the commitments to which are publicly known. These commitments are omitted from the proof. fn precommitted_columns(&self) -> Vec; diff --git a/w3f-plonk-common/src/prover.rs b/w3f-plonk-common/src/prover.rs index b1049df..7d0cbbb 100644 --- a/w3f-plonk-common/src/prover.rs +++ b/w3f-plonk-common/src/prover.rs @@ -56,17 +56,22 @@ impl, T: PlonkTranscript> PlonkProver { let mut transcript = self.transcript_prelude.clone(); transcript.add_instance(&piop.result()); + // ROUND 1 // The prover commits to the columns. + let t_commit_cols = start_timer!(|| format!("Committing to {} degree-{} columns", P::N_COLUMNS, piop.domain().domain_size() - 1)); let column_commitments = piop.committed_columns(|p| CS::commit(&self.pcs_ck, p).unwrap()); transcript.add_committed_cols(&column_commitments); + end_timer!(t_commit_cols); // ROUND 2 let alphas = transcript.get_constraints_aggregation_coeffs(P::N_CONSTRAINTS); let quotient_poly = piop.compute_quotient(&alphas).unwrap(); + let t_commit_q = start_timer!(|| format!("Committing to the degree-{} quotient", quotient_poly.degree())); // The prover commits to the quotient polynomial... let quotient_commitment = CS::commit(&self.pcs_ck, "ient_poly).unwrap(); transcript.add_quotient_commitment("ient_commitment); + end_timer!(t_commit_q); // and receives the evaluation point in response diff --git a/w3f-ring-proof/src/piop/prover.rs b/w3f-ring-proof/src/piop/prover.rs index 285f7fb..464fd97 100644 --- a/w3f-ring-proof/src/piop/prover.rs +++ b/w3f-ring-proof/src/piop/prover.rs @@ -146,6 +146,7 @@ where C: Commitment, Curve: TECurveConfig, { + const N_COLUMNS: usize = 7; const N_CONSTRAINTS: usize = 7; type Commitments = RingCommitments; @@ -208,6 +209,7 @@ where C: Commitment, Curve: SWCurveConfig, { + const N_COLUMNS: usize = 7; const N_CONSTRAINTS: usize = 7; type Commitments = RingCommitments; diff --git a/w3f-ring-proof/src/piop/verifier.rs b/w3f-ring-proof/src/piop/verifier.rs index eeb53b0..0f4b4a5 100644 --- a/w3f-ring-proof/src/piop/verifier.rs +++ b/w3f-ring-proof/src/piop/verifier.rs @@ -153,8 +153,8 @@ impl, Jubjub: TECurveConfig> Veri impl, Jubjub: SWCurveConfig> VerifierPiop for PiopVerifier> { - const N_CONSTRAINTS: usize = 7; const N_COLUMNS: usize = 7; + const N_CONSTRAINTS: usize = 7; fn precommitted_columns(&self) -> Vec { self.fixed_columns_committed.as_vec() From 6d1a9d93009c95bad2fc88f207c078436969162b Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 03:31:36 +0300 Subject: [PATCH 40/42] bench output improved --- pasta-tree/src/lib.rs | 56 ++++++++++++++++++++-------------------- pasta-tree/src/prover.rs | 9 ++++--- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 56ce560..7ae9992 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -229,25 +229,25 @@ mod tests { >(log_n, h); println!(); - let (log_n, h) = (9, 2); - println!("n = {}, height = {h}, TALL", 1 << log_n); - _test_proof::< - ark_pallas::Projective, - ark_vesta::Projective, - CircuitParamsTall, - CircuitParamsTall, - >(log_n, h); - println!(); - - let (log_n, h) = (10, 2); - println!("n = {}, height = {h}, TALL", 1 << log_n); - _test_proof::< - ark_pallas::Projective, - ark_vesta::Projective, - CircuitParamsTall, - CircuitParamsTall, - >(log_n, h); - println!(); + // let (log_n, h) = (9, 2); + // println!("n = {}, height = {h}, TALL", 1 << log_n); + // _test_proof::< + // ark_pallas::Projective, + // ark_vesta::Projective, + // CircuitParamsTall, + // CircuitParamsTall, + // >(log_n, h); + // println!(); + // + // let (log_n, h) = (10, 2); + // println!("n = {}, height = {h}, TALL", 1 << log_n); + // _test_proof::< + // ark_pallas::Projective, + // ark_vesta::Projective, + // CircuitParamsTall, + // CircuitParamsTall, + // >(log_n, h); + // println!(); let (log_n, h) = (8, 4); println!("n = {}, height = {h}, FAT", 1 << log_n); @@ -259,15 +259,15 @@ mod tests { >(log_n, h); println!(); - let (log_n, h) = (9, 4); - println!("n = {}, height = {h}, TALL", 1 << log_n); - _test_proof::< - ark_pallas::Projective, - ark_vesta::Projective, - CircuitParamsTall, - CircuitParamsTall, - >(log_n, h); - println!(); + // let (log_n, h) = (9, 4); + // println!("n = {}, height = {h}, TALL", 1 << log_n); + // _test_proof::< + // ark_pallas::Projective, + // ark_vesta::Projective, + // CircuitParamsTall, + // CircuitParamsTall, + // >(log_n, h); + // println!(); } fn _test_proof(log_n: usize, height: usize) diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index e387569..01723b3 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -56,9 +56,8 @@ impl, P: CircuitParams< witness: Vec>, rng: &mut R, ) -> CycleSideProof { - // let mut s = std::any::type_name::(); - // s = &s[70..s.len()]; - // println!("\n\nprover {s}\nchildren={blinded_path:?}\n"); + let curve_name = &std::any::type_name::()[70..]; + // println!("\n\nprover {curve_name}\nchildren={blinded_path:?}\n"); debug_assert_eq!(blinded_path.len(), witness.len()); let n_polys = P::VerifierCircuit::N_COLUMNS + 2; // plus the quotient and the linearization polys @@ -73,7 +72,9 @@ impl, P: CircuitParams< ArkTranscript::new(b"pasta-tree-level-proof"), ); + let t_commit_side = start_timer!(|| format!("Committing to {} polynomials at {curve_name}", witness.len() * (n_polys- 1))); for (level, blinded_node) in witness.into_iter().zip(blinded_path.into_iter()) { + let t_commit_level = start_timer!(|| format!("Committing to {} polynomials", n_polys)); let piop: P::ProverCircuit =

>::prover_circuit(&self.piop_params, level.clone()); let result = @@ -103,7 +104,9 @@ impl, P: CircuitParams< polys.extend(polys_at_zeta_omega); bfs.push(level.parent_bf); bfs.resize(polys.len(), C::ScalarField::zero()); + end_timer!(t_commit_level); } + end_timer!(t_commit_side); let max_degree = polys.iter().map(|p| p.degree()).max().unwrap(); let t_open = start_timer!(|| format!( From 566d032bd9e13f1728e27489836cb914d1b1c0d4 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 04:31:32 +0300 Subject: [PATCH 41/42] fmt --- pasta-tree/src/prover.rs | 5 ++++- w3f-plonk-common/src/prover.rs | 11 +++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 01723b3..7e1a022 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -72,7 +72,10 @@ impl, P: CircuitParams< ArkTranscript::new(b"pasta-tree-level-proof"), ); - let t_commit_side = start_timer!(|| format!("Committing to {} polynomials at {curve_name}", witness.len() * (n_polys- 1))); + let t_commit_side = start_timer!(|| format!( + "Committing to {} polynomials at {curve_name}", + witness.len() * (n_polys - 1) + )); for (level, blinded_node) in witness.into_iter().zip(blinded_path.into_iter()) { let t_commit_level = start_timer!(|| format!("Committing to {} polynomials", n_polys)); let piop: P::ProverCircuit = diff --git a/w3f-plonk-common/src/prover.rs b/w3f-plonk-common/src/prover.rs index 7d0cbbb..0779926 100644 --- a/w3f-plonk-common/src/prover.rs +++ b/w3f-plonk-common/src/prover.rs @@ -59,7 +59,11 @@ impl, T: PlonkTranscript> PlonkProver // ROUND 1 // The prover commits to the columns. - let t_commit_cols = start_timer!(|| format!("Committing to {} degree-{} columns", P::N_COLUMNS, piop.domain().domain_size() - 1)); + let t_commit_cols = start_timer!(|| format!( + "Committing to {} degree-{} columns", + P::N_COLUMNS, + piop.domain().domain_size() - 1 + )); let column_commitments = piop.committed_columns(|p| CS::commit(&self.pcs_ck, p).unwrap()); transcript.add_committed_cols(&column_commitments); end_timer!(t_commit_cols); @@ -67,7 +71,10 @@ impl, T: PlonkTranscript> PlonkProver // ROUND 2 let alphas = transcript.get_constraints_aggregation_coeffs(P::N_CONSTRAINTS); let quotient_poly = piop.compute_quotient(&alphas).unwrap(); - let t_commit_q = start_timer!(|| format!("Committing to the degree-{} quotient", quotient_poly.degree())); + let t_commit_q = start_timer!(|| format!( + "Committing to the degree-{} quotient", + quotient_poly.degree() + )); // The prover commits to the quotient polynomial... let quotient_commitment = CS::commit(&self.pcs_ck, "ient_poly).unwrap(); transcript.add_quotient_commitment("ient_commitment); From 2e715dc7d1b107aa33523cd10d11b4ce99c0ecd0 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 06:58:03 +0300 Subject: [PATCH 42/42] ring-proof disabled --- Cargo.toml | 2 +- pasta-tree/Cargo.toml | 6 +- pasta-tree/src/lib.rs | 85 +++++++++++++++++--------- pasta-tree/src/prover.rs | 2 +- pasta-tree/src/verifier.rs | 2 +- w3f-plonk-common/Cargo.toml | 1 + w3f-plonk-common/src/gadgets/ec/mod.rs | 7 ++- w3f-ring-proof/Cargo.toml | 37 +++++------ w3f-ring-proof/src/piop/prover.rs | 8 ++- w3f-ring-proof/src/piop/verifier.rs | 8 ++- 10 files changed, 100 insertions(+), 58 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0baec55..bf87c71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = [ # "evm-vrfier", "pasta-tree", "w3f-plonk-common", - "w3f-ring-proof", +# "w3f-ring-proof", # "w3f-ring-vrf-snark", ] diff --git a/pasta-tree/Cargo.toml b/pasta-tree/Cargo.toml index 0cac01c..0697a1e 100644 --- a/pasta-tree/Cargo.toml +++ b/pasta-tree/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/w3f/ring-proof" [dependencies] w3f-pcs.workspace = true w3f-plonk-common.workspace = true -w3f-ring-proof = { path = "../w3f-ring-proof", default-features = false } +#w3f-ring-proof = { path = "../w3f-ring-proof", default-features = false } ark-pallas = { version = "0.6", default-features = false, features = ["curve"] } ark-vesta = { version = "0.6", default-features = false } ark-transcript.workspace = true @@ -38,7 +38,7 @@ std = [ "ark-serialize/std", "w3f-pcs/std", "w3f-plonk-common/std", - "w3f-ring-proof/std", +# "w3f-ring-proof/std", ] parallel = [ "std", @@ -49,7 +49,7 @@ parallel = [ "ark-poly/parallel", "w3f-pcs/parallel", "w3f-plonk-common/parallel", - "w3f-ring-proof/parallel", +# "w3f-ring-proof/parallel", ] print-trace = ["ark-std/print-trace", ] asm = ["w3f-pcs/asm"] \ No newline at end of file diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 7ae9992..b9353a4 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -2,6 +2,8 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use ark_ec::{AffineRepr, CurveGroup, PrimeGroup}; use ark_ff::PrimeField; use ark_ff::Zero; +use ark_serialize::CanonicalSerialize; +use ark_std::rand::RngCore; use std::marker::PhantomData; use w3f_pcs::aggregation::multiple::ShplonkTranscript; use w3f_pcs::pcs::PCS; @@ -141,6 +143,32 @@ pub enum CycleSide { C1(C1), } +#[derive(Clone)] +pub struct ArkTranscript(ark_transcript::Transcript); + +impl> w3f_plonk_common::transcript::PlonkTranscript + for ArkTranscript +{ + fn _128_bit_point(&mut self, label: &'static [u8]) -> F { + self.0.challenge(label).read_reduce() + } + + fn _add_serializable(&mut self, label: &'static [u8], message: &impl CanonicalSerialize) { + self.0.label(label); + self.0.append(message); + } + + fn to_rng(mut self) -> impl RngCore { + self.0.challenge(b"transcript_rng") + } +} + +impl ArkTranscript { + pub fn new(label: &'static [u8]) -> Self { + Self(ark_transcript::Transcript::new_labeled(label)) + } +} + #[derive(Clone)] pub struct Coeffs(F, F); impl> ShplonkTranscript for Coeffs { @@ -218,6 +246,7 @@ mod tests { // cargo test test_bench_curve_tree --release --features="print-trace" -- --show-output // cargo test test_bench_curve_tree --release --features="print-trace parallel" -- --show-output #[test] + #[ignore] fn test_bench_curve_tree() { let (log_n, h) = (8, 2); println!("n = {}, height = {h}, FAT", 1 << log_n); @@ -229,25 +258,25 @@ mod tests { >(log_n, h); println!(); - // let (log_n, h) = (9, 2); - // println!("n = {}, height = {h}, TALL", 1 << log_n); - // _test_proof::< - // ark_pallas::Projective, - // ark_vesta::Projective, - // CircuitParamsTall, - // CircuitParamsTall, - // >(log_n, h); - // println!(); - // - // let (log_n, h) = (10, 2); - // println!("n = {}, height = {h}, TALL", 1 << log_n); - // _test_proof::< - // ark_pallas::Projective, - // ark_vesta::Projective, - // CircuitParamsTall, - // CircuitParamsTall, - // >(log_n, h); - // println!(); + let (log_n, h) = (9, 2); + println!("n = {}, height = {h}, TALL", 1 << log_n); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsTall, + CircuitParamsTall, + >(log_n, h); + println!(); + + let (log_n, h) = (10, 2); + println!("n = {}, height = {h}, TALL", 1 << log_n); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsTall, + CircuitParamsTall, + >(log_n, h); + println!(); let (log_n, h) = (8, 4); println!("n = {}, height = {h}, FAT", 1 << log_n); @@ -259,15 +288,15 @@ mod tests { >(log_n, h); println!(); - // let (log_n, h) = (9, 4); - // println!("n = {}, height = {h}, TALL", 1 << log_n); - // _test_proof::< - // ark_pallas::Projective, - // ark_vesta::Projective, - // CircuitParamsTall, - // CircuitParamsTall, - // >(log_n, h); - // println!(); + let (log_n, h) = (9, 4); + println!("n = {}, height = {h}, TALL", 1 << log_n); + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsTall, + CircuitParamsTall, + >(log_n, h); + println!(); } fn _test_proof(log_n: usize, height: usize) diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 7e1a022..1095d77 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -5,6 +5,7 @@ use crate::{CircuitParams, CycleParams, CycleSideParams}; use crate::{Coeffs, CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; // use ark_ec::short_weierstrass::{Affine as SwAffine, Projective, SWCurveConfig}; +use crate::ArkTranscript; use ark_ff::{PrimeField, Zero}; use ark_poly::Polynomial; use ark_std::rand::Rng; @@ -16,7 +17,6 @@ use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; -use w3f_ring_proof::ArkTranscript; impl CycleParams where diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 158f456..33419bd 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -3,13 +3,13 @@ use crate::{CircuitParams, CycleParams, CycleSideParams}; use crate::{CurveTreeProof, CycleSideProof}; use ark_ec::{AffineRepr, CurveGroup}; // use ark_ec::short_weierstrass::{Affine, Projective, SWCurveConfig}; +use crate::ArkTranscript; use ark_ff::PrimeField; use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::Shplonk; use w3f_plonk_common::piop::VerifierPiop; use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; -use w3f_ring_proof::ArkTranscript; impl CycleParams where diff --git a/w3f-plonk-common/Cargo.toml b/w3f-plonk-common/Cargo.toml index f3393a7..8850113 100644 --- a/w3f-plonk-common/Cargo.toml +++ b/w3f-plonk-common/Cargo.toml @@ -51,3 +51,4 @@ parallel = [ print-trace = ["ark-std/print-trace"] asm = ["w3f-pcs/asm"] test-vectors = [] +twisted_edwards = [] \ No newline at end of file diff --git a/w3f-plonk-common/src/gadgets/ec/mod.rs b/w3f-plonk-common/src/gadgets/ec/mod.rs index cdfa95f..04b023e 100644 --- a/w3f-plonk-common/src/gadgets/ec/mod.rs +++ b/w3f-plonk-common/src/gadgets/ec/mod.rs @@ -8,9 +8,12 @@ use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::marker::PhantomData; use ark_std::vec::Vec; +#[cfg(not(feature = "twisted_edwards"))] pub mod sw_cond_add; -// pub mod te_cond_add; -// pub mod te_doubling; +#[cfg(feature = "twisted_edwards")] +pub mod te_cond_add; +#[cfg(feature = "twisted_edwards")] +pub mod te_doubling; // A vec of affine points from the prime-order subgroup of the curve whose base field enables FFTs, // and its convenience representation as columns of coordinates over the curve's base field. diff --git a/w3f-ring-proof/Cargo.toml b/w3f-ring-proof/Cargo.toml index 893c03f..230ba94 100644 --- a/w3f-ring-proof/Cargo.toml +++ b/w3f-ring-proof/Cargo.toml @@ -29,26 +29,27 @@ name = "ring_proof" harness = false [features] -default = [ "std" ] +default = ["std", "twisted_edwards"] std = [ - "ark-std/std", - "ark-ff/std", - "ark-ec/std", - "ark-poly/std", - "ark-serialize/std", - "w3f-pcs/std", - "w3f-plonk-common/std" + "ark-std/std", + "ark-ff/std", + "ark-ec/std", + "ark-poly/std", + "ark-serialize/std", + "w3f-pcs/std", + "w3f-plonk-common/std" ] parallel = [ - "std", - "rayon", - "ark-std/parallel", - "ark-ff/parallel", - "ark-ec/parallel", - "ark-poly/parallel", - "w3f-plonk-common/parallel", - "w3f-pcs/parallel" + "std", + "rayon", + "ark-std/parallel", + "ark-ff/parallel", + "ark-ec/parallel", + "ark-poly/parallel", + "w3f-plonk-common/parallel", + "w3f-pcs/parallel" ] print-trace = ["ark-std/print-trace"] -asm = [ "w3f-pcs/asm" ] -test-vectors = [ "w3f-plonk-common/test-vectors" ] +asm = ["w3f-pcs/asm"] +test-vectors = ["w3f-plonk-common/test-vectors"] +twisted_edwards = ["w3f-plonk-common/twisted_edwards"] diff --git a/w3f-ring-proof/src/piop/prover.rs b/w3f-ring-proof/src/piop/prover.rs index 464fd97..3aaa4bc 100644 --- a/w3f-ring-proof/src/piop/prover.rs +++ b/w3f-ring-proof/src/piop/prover.rs @@ -1,5 +1,3 @@ -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; @@ -140,6 +138,9 @@ impl> PiopProver { } } +#[cfg(feature = "twisted_edwards")] +use ark_ec::twisted_edwards::{Affine as TeAffine, TECurveConfig}; +#[cfg(feature = "twisted_edwards")] impl ProverPiop for PiopProver> where F: PrimeField, @@ -203,6 +204,9 @@ where } } +#[cfg(not(feature = "twisted_edwards"))] +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +#[cfg(not(feature = "twisted_edwards"))] impl ProverPiop for PiopProver> where F: PrimeField, diff --git a/w3f-ring-proof/src/piop/verifier.rs b/w3f-ring-proof/src/piop/verifier.rs index 0f4b4a5..15c90c7 100644 --- a/w3f-ring-proof/src/piop/verifier.rs +++ b/w3f-ring-proof/src/piop/verifier.rs @@ -1,5 +1,3 @@ -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,6 +100,9 @@ impl, P: AffineRepr> PiopVerifier } } +#[cfg(feature = "twisted_edwards")] +use ark_ec::twisted_edwards::{Affine as TeAffine, TECurveConfig}; +#[cfg(feature = "twisted_edwards")] impl, Jubjub: TECurveConfig> VerifierPiop for PiopVerifier> { @@ -150,6 +151,9 @@ impl, Jubjub: TECurveConfig> Veri } } +#[cfg(not(feature = "twisted_edwards"))] +use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; +#[cfg(not(feature = "twisted_edwards"))] impl, Jubjub: SWCurveConfig> VerifierPiop for PiopVerifier> {