From 2e8fd8ef1c390f355063b38d6b7f9f27af4c3ced Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Wed, 10 Jun 2026 20:50:44 +0300 Subject: [PATCH 1/7] dirty code --- pasta-tree/src/auth_path/node.rs | 2 +- pasta-tree/src/auth_path/path.rs | 7 ++ pasta-tree/src/lib.rs | 79 ++++++++++++++------ pasta-tree/src/prover.rs | 101 ++++++++++++++++++++++++-- pasta-tree/src/verifier.rs | 114 +++++++++++++++++++++++++++-- w3f-plonk-common/src/batch.rs | 119 +++++++++++++++++++++++++++++++ w3f-plonk-common/src/lib.rs | 7 +- w3f-plonk-common/src/piop.rs | 4 +- w3f-ring-proof/src/piop/mod.rs | 4 +- 9 files changed, 397 insertions(+), 40 deletions(-) create mode 100644 w3f-plonk-common/src/batch.rs diff --git a/pasta-tree/src/auth_path/node.rs b/pasta-tree/src/auth_path/node.rs index e0f1564..ea09136 100644 --- a/pasta-tree/src/auth_path/node.rs +++ b/pasta-tree/src/auth_path/node.rs @@ -77,7 +77,7 @@ impl LevelWitness> { } /// NB! It is not "blinded", meaning that the blinding factor hasn't been applied. -#[derive(Clone)] +#[derive(Clone, Debug)] 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 5793fa8..664b634 100644 --- a/pasta-tree/src/auth_path/path.rs +++ b/pasta-tree/src/auth_path/path.rs @@ -20,6 +20,13 @@ pub struct AuthenticationPath { pub c1_path: Vec>, } +pub struct AuthenticationPath2 { + /// Nodes on the `C0` curve. + pub c0_path: [LevelWitness; L0], + /// Nodes on the `C1` curve. + pub c1_path: [LevelWitness; L1], +} + impl AuthenticationPath, ProjectivePoint> where C0: CurveModel, diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index c86a00f..8513349 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -28,16 +28,16 @@ type ProjectivePoint = ark_ec::short_weierstrass::Projective; // TODO: goes vto plonk-common in some form /// A circuit over `C::ScalarField`. -pub trait CircuitParams> { +pub trait CircuitParams> { type Commitments: ColumnsCommited>; type Evaluations: ColumnsEvaluated; type ProverCircuit: ProverPiop< - C::ScalarField, - WrappedAffine, - Instance = AffinePoint, - Commitments = Self::Commitments, - Evaluations = Self::Evaluations, - >; + C::ScalarField, + WrappedAffine, + Instance=AffinePoint, + Commitments=Self::Commitments, + Evaluations=Self::Evaluations, + >; type VerifierCircuit: VerifierPiop>; fn prover_circuit( @@ -70,7 +70,7 @@ pub trait CircuitParams pub struct CycleSideParams< C: CurveGroup, - G: CurveModel, + G: CurveModel, P: CircuitParams, > { pcs_params: HidingIpa, @@ -80,7 +80,7 @@ pub struct CycleSideParams< pub struct CycleParams< C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, > { @@ -95,10 +95,29 @@ type LevelProof = w3f_plonk_common::PiopProof<

>::Evaluations, >; +type BatchLevelProof = w3f_plonk_common::PiopProof< + ::ScalarField, + WrappedAffine, + [

>::Commitments; L], + [

>::Evaluations; L], +>; + +#[derive(Clone, Debug)] +pub struct BatchSideProof< + C: CurveGroup, + G: CurveModel, + P: CircuitParams, + const L: usize, +> { + piop_proof: BatchLevelProof, + pcs_proof: AggregateProof>, + todo: Coeffs, +} + #[derive(Clone)] pub struct CycleSideProof< C: CurveGroup, - G: CurveModel, + G: CurveModel, P: CircuitParams, > { piop_proofs: Vec>, @@ -109,7 +128,7 @@ pub struct CycleSideProof< #[derive(Clone)] pub struct CurveTreeProof< C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, > { @@ -117,8 +136,20 @@ pub struct CurveTreeProof< c1_proof: CycleSideProof, C0, P1>, } -impl, P: CircuitParams> - CycleSideParams +#[derive(Clone, Debug)] +pub struct CurveTreeProof2< + C0: CurveModel, + C1: CurveModel, + P0: CircuitParams, C1>, + P1: CircuitParams, C0>, + const L: usize, +> { + c0_proof: BatchSideProof, C1, P0, L>, + c1_proof: BatchSideProof, C0, P1, L>, +} + +impl, P: CircuitParams> +CycleSideParams { pub fn commit_tree_nodes( &self, @@ -154,7 +185,7 @@ pub enum CycleSide { pub struct ArkTranscript(ark_transcript::Transcript); impl> w3f_plonk_common::transcript::PlonkTranscript - for ArkTranscript +for ArkTranscript { fn _128_bit_point(&mut self, label: &'static [u8]) -> F { self.0.challenge(label).read_reduce() @@ -176,7 +207,7 @@ impl ArkTranscript { } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Coeffs(F, F); impl> ShplonkTranscript for Coeffs { fn get_gamma(&mut self) -> F { @@ -224,7 +255,7 @@ mod tests { impl CycleParams where C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, { @@ -268,7 +299,7 @@ mod tests { VestaConfig, CircuitParamsFat, CircuitParamsFat, - >(8, 2); + >(8, 4); } // cargo test test_bench_curve_tree --release --features="print-trace" -- --show-output --ignored @@ -330,7 +361,7 @@ mod tests { fn _test_proof(log_n: usize, height: usize) where C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, { @@ -353,11 +384,13 @@ mod tests { "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); + let (auth_path, proof) = params.batch_prove::<_, 2>(path, rng); + // 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); + // let valid = params.verify(auth_path, proof, root); + let valid = params.batch_verify(auth_path, proof, root); end_timer!(t_verify); assert!(valid); } @@ -378,7 +411,7 @@ mod tests { pub fn random_nodes< C: CurveGroup, - G: CurveModel, + G: CurveModel, P: CircuitParams, R: Rng, >( @@ -393,7 +426,7 @@ mod tests { pub fn random_path< C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, R: Rng, diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index c36174d..6f7dff2 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -1,4 +1,4 @@ -use crate::ArkTranscript; +use crate::{ArkTranscript, BatchLevelProof, BatchSideProof, CurveTreeProof2}; use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; @@ -12,17 +12,20 @@ use ark_poly::Polynomial; use ark_std::rand::Rng; use ark_std::{UniformRand, end_timer, start_timer}; use std::collections::BTreeSet; +use std::marker::PhantomData; 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::batch::BatchProver; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; +use w3f_plonk_common::Proof; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; impl CycleParams where C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, { @@ -46,10 +49,29 @@ where .prove_side(blinded_auth_path.c0_path, auth_path_with_bf.c0_path, rng); (auth_path, CurveTreeProof { c0_proof, c1_proof }) } + + pub fn batch_prove( + &self, + auth_path: AuthenticationPath, ProjectivePoint>, + rng: &mut R, + ) -> ( + BlindedAuthenticationPath, ProjectivePoint>, + CurveTreeProof2, + ) { + 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 auth_path = blinded_auth_path.clone(); + let c1_path: [_; L] = auth_path_with_bf.c1_path.try_into().unwrap(); + let c0_path: [_; L] = auth_path_with_bf.c0_path.try_into().unwrap(); + let c0_proof = self.c0_params.batch_prove_side(blinded_auth_path.c1_path, c1_path, rng); + let c1_proof = self.c1_params.batch_prove_side(blinded_auth_path.c0_path, c0_path, rng); + (auth_path, CurveTreeProof2 { c0_proof, c1_proof }) + } } -impl, P: CircuitParams> - CycleSideParams +impl, P: CircuitParams> +CycleSideParams { pub fn prove_side( &self, @@ -65,7 +87,7 @@ impl, P: CircuitParams< // per tree level let n_columns = P::VerifierCircuit::N_COLUMNS; - let n_to_commit = n_columns + 4; // plus the quotient chunks + let n_to_commit = n_columns + 3; // plus the quotient chunks let n_to_open = n_columns + 2; // plus the (folded) quotient (chunks) and the linearization polynomial // per side @@ -140,4 +162,73 @@ impl, P: CircuitParams< }; proof } + + pub fn batch_prove_side( + &self, + blinded_path: Vec>, + witness: [LevelWitnessWithBlinding>; L], + rng: &mut R, + ) -> BatchSideProof { + let curve_name = &std::any::type_name::()[53..]; + // println!("\n\nprover {curve_name}\nchildren={blinded_path:?}\n"); + // let n_levels = witness.len(); // number of tree levels on this side + // debug_assert_eq!(blinded_path.len(), n_levels); + // let mut piop_proofs = Vec::with_capacity(n_levels); + // + // // per tree level + let n_columns = P::VerifierCircuit::N_COLUMNS; + let n_to_commit = L * n_columns + 3; // plus the quotient chunks + let n_to_open = L * n_columns + 2; // plus the (folded) quotient (chunks) and the linearization polynomial + + let plonk_prover = PlonkProver::, _>::init( + self.pcs_params.ck(), + (), + ArkTranscript::new(b"pasta-tree-level-proof"), + ); + + let parent_bfs: Vec<_> = witness.iter().map(|level| level.parent_bf).collect(); + let batch_piop = witness.map(|level| self.piop_params.prover_circuit(level)); + let batch_piop = BatchProver(batch_piop, PhantomData, PhantomData); + + + let t_commit_side = start_timer!(|| format!( + "Committing {L}x{n_columns}+3 = {n_to_commit} polynomials to {curve_name}" + )); + let (pcs_openings, piop_proof, _transcript) = plonk_prover.reduce_to_pcs_opening(batch_piop); + end_timer!(t_commit_side); + + let PcsOpeningAt2Points { + polys_at_zeta, + polys_at_zeta_omega, + zeta, + zeta_omega, + } = pcs_openings; + let mut at_coords = vec![BTreeSet::from([zeta]); polys_at_zeta.len()]; + let mut polys_to_open = polys_at_zeta; + at_coords.extend(vec![BTreeSet::from([zeta_omega]); polys_at_zeta_omega.len()]); + polys_to_open.extend(polys_at_zeta_omega); + let with_bfs = vec![C::ScalarField::zero(); polys_to_open.len()]; + + let t_open = start_timer!(|| format!( + "Opening {L}x{n_columns}+2 = {n_to_open} polynomials, max_degree = {}", + polys_to_open.iter().map(|p| p.degree()).max().unwrap() + )); + let todo = Coeffs(C::ScalarField::rand(rng), C::ScalarField::rand(rng)); + let pcs_proof = Shplonk::>::open_many_hiding( + &self.pcs_params, + &polys_to_open, + &with_bfs, + &at_coords, + &mut todo.clone(), + rng, + ); + end_timer!(t_open); + + let proof = BatchSideProof { + piop_proof, + pcs_proof, + todo, + }; + proof + } } diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 6be1aa0..1d81dbe 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,4 +1,6 @@ -use crate::ArkTranscript; +use std::collections::BTreeSet; +use std::marker::PhantomData; +use crate::{ArkTranscript, BatchSideProof, CurveTreeProof2}; use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::{ AffinePoint, CircuitParams, CurveModel, CycleParams, CycleSideParams, ProjectivePoint, @@ -9,13 +11,14 @@ 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::batch::BatchVerifier; use w3f_plonk_common::piop::VerifierPiop; use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; impl CycleParams where C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, { @@ -36,10 +39,28 @@ where assert!(c1_proof); c0_proof && c1_proof } + + pub fn batch_verify( + &self, + auth_path: BlindedAuthenticationPath, ProjectivePoint>, + proof: CurveTreeProof2, + root: AffinePoint, + ) -> bool { + 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_batch(c1_path.clone(), c0_parents, proof.c0_proof); + assert!(c0_proof); + let c1_proof = self.c1_params.verify_batch(c0_path, c1_path, proof.c1_proof); + assert!(c1_proof); + c0_proof && c1_proof + } } -impl, P: CircuitParams> - CycleSideParams +impl, P: CircuitParams> +CycleSideParams { pub fn verify_side( &self, @@ -124,4 +145,89 @@ impl, P: CircuitParams< ); valid } + + pub fn verify_batch( + &self, + // selected re-randomized children + children: Vec>, + // parents, re-randomized at the previous step + parents: Vec, + side_proof: BatchSideProof, + ) -> bool { + // let curve_name = &std::any::type_name::()[53..]; + // println!("\n\nverifier {curve_name}\nchildren={children:?}\nparents={parents:?}\n"); + + // // number of tree levels on this side + // let n_levels = side_proof.piop_proofs.len(); + // // per tree level + // let n_to_open = P::VerifierCircuit::N_COLUMNS + 2; // plus the (folded) quotient (chunks) and the linearization polynomial + // // per side + // let n_openings = n_levels * n_to_open; + // + // let mut polys_to_open = Vec::with_capacity(n_openings); + // let mut at_coords = Vec::with_capacity(n_openings); + // let mut to_values = Vec::with_capacity(n_openings); + + let plonk_verifier: PlonkVerifier, _> = PlonkVerifier::init( + self.pcs_params.vk(), + &(), // TODO + ArkTranscript::new(b"pasta-tree-level-proof"), + ); + + //TODO: precompute + let fixed_cols = self.commit_fixed_columns(); + + let piop_proof = side_proof.piop_proof.clone(); + + let (challenges, _rng) = plonk_verifier.restore_challenges( + &children, + &piop_proof, + // '1' accounts for the quotient polynomial that is aggregated together with the columns + P::VerifierCircuit::N_COLUMNS + 1, + P::VerifierCircuit::N_CONSTRAINTS, + ); + + let batch_piop: [_; L] = children.into_iter() + .zip(parents.into_iter()) + .zip(piop_proof.column_commitments.into_iter()) + .zip(piop_proof.columns_at_zeta.into_iter()) + .map(|(((child, parent), cols), evals)| + self.piop_params.verifier_circuit( + (child, parent), + &fixed_cols, + cols, + evals, + challenges.zeta, + )).collect::>().try_into().unwrap_or_else(|_| panic!("wtf")); + let batch_piop = BatchVerifier(batch_piop, PhantomData, PhantomData); + + let PcsOpeningAt2Points { + open_at_zeta, + open_at_zeta_omega, + zeta, + zeta_omega, + vals_at_zeta, + vals_at_zeta_omega, + } = plonk_verifier.evaluate_piop(batch_piop, side_proof.piop_proof, challenges); + + let mut at_coords = vec![vec![zeta]; open_at_zeta.len()]; + let mut polys_to_open = open_at_zeta; + at_coords.extend(vec![vec![zeta_omega]; open_at_zeta_omega.len()]); + polys_to_open.extend(open_at_zeta_omega); + let to_values: Vec> = vals_at_zeta.into_iter() + .chain(vals_at_zeta_omega.into_iter()) + .map(|v| vec![v]) + .collect(); + + let mut todo = side_proof.todo; + let valid = Shplonk::>::verify_many( + &self.pcs_params.vk(), + &polys_to_open, + side_proof.pcs_proof, + &at_coords, + &to_values, + &mut todo, + ); + valid + } } diff --git a/w3f-plonk-common/src/batch.rs b/w3f-plonk-common/src/batch.rs new file mode 100644 index 0000000..2d8487c --- /dev/null +++ b/w3f-plonk-common/src/batch.rs @@ -0,0 +1,119 @@ +use std::marker::PhantomData; +use ark_ff::PrimeField; +use ark_poly::Evaluations; +use ark_poly::univariate::DensePolynomial; +use w3f_pcs::pcs::Commitment; +use w3f_pcs::pcs::commitment::WrappedAffine; +use crate::{ColumnsCommited, ColumnsEvaluated}; +use crate::domain::{Domain, EvaluatedDomain}; +use crate::piop::{ProverPiop, VerifierPiop}; + +impl, CC: ColumnsCommited, const K: usize> ColumnsCommited for [CC; K] { + fn to_vec(self) -> Vec { + self.into_iter() + .flat_map(|p| p.to_vec()) + .collect() + } +} + +impl, const K: usize> ColumnsEvaluated for [CE; K] { + fn to_vec(self) -> Vec { + self.into_iter() + .flat_map(|p| p.to_vec()) + .collect() + } +} + +pub struct BatchProver, P: ProverPiop, const K: usize>(pub [P; K], pub PhantomData, pub PhantomData); +pub struct BatchVerifier, V: VerifierPiop, const K: usize>(pub [V; K], pub PhantomData, pub PhantomData); + +impl, P: ProverPiop, const K: usize> ProverPiop for BatchProver { + const N_COLUMNS: usize = P::N_COLUMNS * K; + const N_CONSTRAINTS: usize = P::N_CONSTRAINTS * K; + const N_QUOTIENT_CHUNKS: usize = P::N_QUOTIENT_CHUNKS; + type Commitments = [P::Commitments; K]; + type Evaluations = [P::Evaluations; K]; + type Instance = [P::Instance; K]; + + fn committed_columns) -> C + Clone>(&self, commit: Fun) -> Self::Commitments { + self.0.iter() + .map(|p| p.committed_columns(commit.clone())) + .collect::>() + .try_into() + .unwrap() + } + + fn columns(&self) -> Vec> { + self.0.iter() + .flat_map(|p| p.columns()) + .collect() + } + + fn columns_evaluated(&self, zeta: &F) -> Self::Evaluations { + self.0.iter() + .map(|p| p.columns_evaluated(zeta)) + .collect::>() + .try_into() + .unwrap() + } + + fn constraints(&self) -> Vec> { + self.0.iter() + .flat_map(|p| p.constraints()) + .collect() + } + + fn constraints_lin(&self, zeta: &F) -> Vec> { + self.0.iter() + .flat_map(|p| p.constraints_lin(zeta)) + .collect() + } + + fn quotient(&self, alphas: &[F]) -> Option>> { + self._quotient_chunks(alphas) + } + + fn domain(&self) -> &Domain { + self.0[0].domain() + } + + fn result(&self) -> Self::Instance { + self.0.iter() + .map(|p| p.result()) + .collect::>() // Requires allocation if you use .collect() + .try_into() + .unwrap() + } +} + +impl, V: VerifierPiop, const K: usize> VerifierPiop for BatchVerifier { + const N_COLUMNS: usize = V::N_COLUMNS * K; + const N_CONSTRAINTS: usize = V::N_CONSTRAINTS * K; + + fn precommitted_columns(&self) -> Vec { + self.0.iter() + .flat_map(|p| p.precommitted_columns()) + .collect() + } + + fn evaluate_constraints_main(&self) -> Vec { + self.0.iter() + .flat_map(|p| p.evaluate_constraints_main()) + .collect() + } + + fn lin_poly_commitment(&self, agg_coeffs: &[F]) -> (Vec, Vec) { + self.0.iter() + .map(|p| p.lin_poly_commitment(agg_coeffs)) + .reduce(| (mut acc_f, mut acc_c), (f, c)| { + acc_f.extend(f); + acc_c.extend(c); + (acc_f, acc_c) + }) + .unwrap() + } + + fn domain_evaluated(&self) -> &EvaluatedDomain { + self.0[0].domain_evaluated() + } +} \ No newline at end of file diff --git a/w3f-plonk-common/src/lib.rs b/w3f-plonk-common/src/lib.rs index 2aaa412..46398da 100644 --- a/w3f-plonk-common/src/lib.rs +++ b/w3f-plonk-common/src/lib.rs @@ -18,6 +18,7 @@ pub mod q_chunking; pub mod test_helpers; pub mod transcript; pub mod verifier; +pub mod batch; pub trait Column { fn domain(&self) -> GeneralEvaluationDomain; @@ -74,13 +75,13 @@ pub fn const_evals(c: F, domain: GeneralEvaluationDomain) -> Eva } pub trait ColumnsEvaluated: - Clone + CanonicalSerialize + CanonicalDeserialize +Clone + ark_std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize { fn to_vec(self) -> Vec; } pub trait ColumnsCommited>: - Clone + CanonicalSerialize + CanonicalDeserialize +Clone + ark_std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize { fn to_vec(self) -> Vec; } @@ -111,7 +112,7 @@ where } /// Same as `Proof` but excluding the PCS opening. -#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct PiopProof where F: PrimeField, diff --git a/w3f-plonk-common/src/piop.rs b/w3f-plonk-common/src/piop.rs index bc1b866..04c6faf 100644 --- a/w3f-plonk-common/src/piop.rs +++ b/w3f-plonk-common/src/piop.rs @@ -16,10 +16,10 @@ pub trait ProverPiop> { type Commitments: ColumnsCommited; type Evaluations: ColumnsEvaluated; - type Instance: CanonicalSerialize + CanonicalDeserialize; + type Instance: Clone + ark_std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize; // Commitments to the column polynomials excluding the precommitted columns. - fn committed_columns) -> C>( + fn committed_columns) -> C + Clone>( &self, commit: Fun, ) -> Self::Commitments; diff --git a/w3f-ring-proof/src/piop/mod.rs b/w3f-ring-proof/src/piop/mod.rs index 6fd12e1..4f85a5b 100644 --- a/w3f-ring-proof/src/piop/mod.rs +++ b/w3f-ring-proof/src/piop/mod.rs @@ -21,7 +21,7 @@ pub mod params; pub mod prover; pub mod verifier; -#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct RingCommitments> { pub(crate) bits: C, pub(crate) inn_prod_acc: C, @@ -40,7 +40,7 @@ impl> ColumnsCommited for RingCommitments< } } -#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct RingEvaluations { pub(crate) points: [F; 2], pub(crate) ring_selector: F, From 2e4cfad10536ba34420cd872e0f4de7776f74c64 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Thu, 11 Jun 2026 00:27:53 +0300 Subject: [PATCH 2/7] doesn't work --- pasta-tree/src/auth_path/path.rs | 6 ++-- pasta-tree/src/lib.rs | 2 +- pasta-tree/src/prover.rs | 25 +++++++++++++++-- pasta-tree/src/verifier.rs | 47 ++++++++++++++++++++------------ w3f-plonk-common/src/batch.rs | 3 +- w3f-plonk-common/src/verifier.rs | 2 +- 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/pasta-tree/src/auth_path/path.rs b/pasta-tree/src/auth_path/path.rs index 664b634..1f8057e 100644 --- a/pasta-tree/src/auth_path/path.rs +++ b/pasta-tree/src/auth_path/path.rs @@ -41,14 +41,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::from(u128::rand(rng)); + let mut c0_bf = C0::ScalarField::zero();//::from(u128::rand(rng)); for c1_nodes in self.c1_path.iter() { - let c1_bf = C1::ScalarField::from(u128::rand(rng)); + let c1_bf = C1::ScalarField::zero();//::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::from(u128::rand(rng)); + c0_bf = C0::ScalarField::zero();//::from(u128::rand(rng)); path_1.push(c1_nodes.with_blinding(c1_bf, c0_bf)); } None => { diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 8513349..44c11cc 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -390,7 +390,7 @@ mod tests { // let t_verify = start_timer!(|| "Verifying CurveTree membership"); // let valid = params.verify(auth_path, proof, root); - let valid = params.batch_verify(auth_path, proof, root); + let valid = params.batch_verify::<2>(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 6f7dff2..34df1e3 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -13,6 +13,7 @@ use ark_std::rand::Rng; use ark_std::{UniformRand, end_timer, start_timer}; use std::collections::BTreeSet; use std::marker::PhantomData; +use ark_std::iterable::Iterable; use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_pcs::pcs::ipa::hiding::HidingIpa; @@ -190,7 +191,6 @@ CycleSideParams let batch_piop = witness.map(|level| self.piop_params.prover_circuit(level)); let batch_piop = BatchProver(batch_piop, PhantomData, PhantomData); - let t_commit_side = start_timer!(|| format!( "Committing {L}x{n_columns}+3 = {n_to_commit} polynomials to {curve_name}" )); @@ -203,11 +203,30 @@ CycleSideParams zeta, zeta_omega, } = pcs_openings; + println!("zeta = {zeta}\nq(zeta) = {}\n", polys_at_zeta[polys_at_zeta.len() - 1].evaluate(&zeta)); let mut at_coords = vec![BTreeSet::from([zeta]); polys_at_zeta.len()]; let mut polys_to_open = polys_at_zeta; at_coords.extend(vec![BTreeSet::from([zeta_omega]); polys_at_zeta_omega.len()]); - polys_to_open.extend(polys_at_zeta_omega); - let with_bfs = vec![C::ScalarField::zero(); polys_to_open.len()]; + polys_to_open.extend(polys_at_zeta_omega.clone()); + let with_bfs = parent_bfs.into_iter().flat_map(|bf| { + let mut res = vec![C::ScalarField::zero(); n_columns]; + res[0] = bf; + res + }).chain(vec![C::ScalarField::zero(); 2]) + .collect::>(); + debug_assert_eq!(with_bfs.len(), n_to_open); + + let lin = &polys_at_zeta_omega[0]; + use w3f_pcs::pcs::PCS; + let lin_c = HidingIpa::::commit(&self.pcs_params,&lin).unwrap().0; + println!("C_lin = {lin_c}"); + + for (i, ((p, z), bf)) in polys_to_open.iter() + .zip(at_coords.iter().map(|z| z.first().unwrap())) + .zip(with_bfs.iter()) + .enumerate() { + println!("{i}: z={z}, p(z)={}, bf={bf}", p.evaluate(z)); + } let t_open = start_timer!(|| format!( "Opening {L}x{n_columns}+2 = {n_to_open} polynomials, max_degree = {}", diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 1d81dbe..bdcf090 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -101,8 +101,7 @@ CycleSideParams let (challenges, _rng) = plonk_verifier.restore_challenges( &child, &level_proof, - // '1' accounts for the quotient polynomial that is aggregated together with the columns - P::VerifierCircuit::N_COLUMNS + 1, + 0, P::VerifierCircuit::N_CONSTRAINTS, ); let piop = self.piop_params.verifier_circuit( @@ -168,24 +167,25 @@ CycleSideParams // let mut at_coords = Vec::with_capacity(n_openings); // let mut to_values = Vec::with_capacity(n_openings); + //TODO: precompute + let fixed_cols = self.commit_fixed_columns(); + let piop_proof = side_proof.piop_proof.clone(); + let instance: [AffinePoint; L] = children.clone().try_into().unwrap(); + let plonk_verifier: PlonkVerifier, _> = PlonkVerifier::init( self.pcs_params.vk(), &(), // TODO ArkTranscript::new(b"pasta-tree-level-proof"), ); - //TODO: precompute - let fixed_cols = self.commit_fixed_columns(); - - let piop_proof = side_proof.piop_proof.clone(); - let (challenges, _rng) = plonk_verifier.restore_challenges( - &children, + &instance, &piop_proof, - // '1' accounts for the quotient polynomial that is aggregated together with the columns - P::VerifierCircuit::N_COLUMNS + 1, - P::VerifierCircuit::N_CONSTRAINTS, + 0, + L * P::VerifierCircuit::N_CONSTRAINTS, ); + let zeta_ = challenges.zeta; + println!("zeta = {zeta_}"); let batch_piop: [_; L] = children.into_iter() .zip(parents.into_iter()) @@ -193,12 +193,12 @@ CycleSideParams .zip(piop_proof.columns_at_zeta.into_iter()) .map(|(((child, parent), cols), evals)| self.piop_params.verifier_circuit( - (child, parent), - &fixed_cols, - cols, - evals, - challenges.zeta, - )).collect::>().try_into().unwrap_or_else(|_| panic!("wtf")); + (child, parent), + &fixed_cols, + cols, + evals, + challenges.zeta, + )).collect::>().try_into().unwrap_or_else(|_| panic!("wtf")); let batch_piop = BatchVerifier(batch_piop, PhantomData, PhantomData); let PcsOpeningAt2Points { @@ -209,16 +209,27 @@ CycleSideParams vals_at_zeta, vals_at_zeta_omega, } = plonk_verifier.evaluate_piop(batch_piop, side_proof.piop_proof, challenges); + debug_assert_eq!(zeta, zeta_); + println!("q(zeta) = {}", vals_at_zeta[vals_at_zeta.len() - 1]); let mut at_coords = vec![vec![zeta]; open_at_zeta.len()]; let mut polys_to_open = open_at_zeta; at_coords.extend(vec![vec![zeta_omega]; open_at_zeta_omega.len()]); - polys_to_open.extend(open_at_zeta_omega); + polys_to_open.extend(open_at_zeta_omega.clone()); let to_values: Vec> = vals_at_zeta.into_iter() .chain(vals_at_zeta_omega.into_iter()) .map(|v| vec![v]) .collect(); + let lin = open_at_zeta_omega[0].0; + println!("C_lin = {lin}"); + for (i, ((p, z), v)) in polys_to_open.iter() + .zip(at_coords.iter().map(|z| z.first().unwrap())) + .zip(to_values.iter().map(|v| v.first().unwrap())) + .enumerate() { + println!("{i}: z={z}, v={v}"); + } + let mut todo = side_proof.todo; let valid = Shplonk::>::verify_many( &self.pcs_params.vk(), diff --git a/w3f-plonk-common/src/batch.rs b/w3f-plonk-common/src/batch.rs index 2d8487c..4f977d3 100644 --- a/w3f-plonk-common/src/batch.rs +++ b/w3f-plonk-common/src/batch.rs @@ -104,7 +104,8 @@ impl, V: VerifierPiop, const K: usize> Ver fn lin_poly_commitment(&self, agg_coeffs: &[F]) -> (Vec, Vec) { self.0.iter() - .map(|p| p.lin_poly_commitment(agg_coeffs)) + .zip(agg_coeffs.chunks(V::N_CONSTRAINTS)) + .map(|(p, alphas)| p.lin_poly_commitment(alphas)) .reduce(| (mut acc_f, mut acc_c), (f, c)| { acc_f.extend(f); acc_c.extend(c); diff --git a/w3f-plonk-common/src/verifier.rs b/w3f-plonk-common/src/verifier.rs index 187f47e..8f3c9f2 100644 --- a/w3f-plonk-common/src/verifier.rs +++ b/w3f-plonk-common/src/verifier.rs @@ -119,7 +119,7 @@ impl, T: PlonkTranscript> PlonkVerifier( From 43ed5a84e4130d029f8b7567a2be98e41566171c Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 21 Jun 2026 14:16:30 +0300 Subject: [PATCH 3/7] clumsy but works --- pasta-tree/src/auth_path/path.rs | 7 +- pasta-tree/src/lib.rs | 72 +++++++++++-------- pasta-tree/src/prover.rs | 79 ++++++++++----------- pasta-tree/src/verifier.rs | 62 ++++++++--------- w3f-plonk-common/src/batch.rs | 110 +++++++++++++++++++++--------- w3f-plonk-common/src/lib.rs | 6 +- w3f-plonk-common/src/verifier.rs | 2 +- w3f-ring-proof/src/piop/mod.rs | 55 +++++++++++++++ w3f-ring-proof/src/piop/prover.rs | 29 -------- 9 files changed, 249 insertions(+), 173 deletions(-) diff --git a/pasta-tree/src/auth_path/path.rs b/pasta-tree/src/auth_path/path.rs index 1f8057e..aa8a2bd 100644 --- a/pasta-tree/src/auth_path/path.rs +++ b/pasta-tree/src/auth_path/path.rs @@ -13,6 +13,7 @@ use ark_std::rand::Rng; /// `path_0[0]` contains the leaf (with its siblings). /// `commit(path_0[k].siblings) = path_1[k].siblings[path_1[k].i]`, if `path_1[k]` exists, /// otherwise it's the root. +#[derive(Clone, Debug)] pub struct AuthenticationPath { /// Nodes on the `C0` curve. pub c0_path: Vec>, @@ -41,14 +42,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::zero();//::from(u128::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::zero();//::from(u128::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::zero();//::from(u128::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/lib.rs b/pasta-tree/src/lib.rs index 44c11cc..c7ec67d 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -28,16 +28,16 @@ type ProjectivePoint = ark_ec::short_weierstrass::Projective; // TODO: goes vto plonk-common in some form /// A circuit over `C::ScalarField`. -pub trait CircuitParams> { +pub trait CircuitParams> { type Commitments: ColumnsCommited>; type Evaluations: ColumnsEvaluated; type ProverCircuit: ProverPiop< - C::ScalarField, - WrappedAffine, - Instance=AffinePoint, - Commitments=Self::Commitments, - Evaluations=Self::Evaluations, - >; + C::ScalarField, + WrappedAffine, + Instance = AffinePoint, + Commitments = Self::Commitments, + Evaluations = Self::Evaluations, + >; type VerifierCircuit: VerifierPiop>; fn prover_circuit( @@ -70,7 +70,7 @@ pub trait CircuitParams> pub struct CycleSideParams< C: CurveGroup, - G: CurveModel, + G: CurveModel, P: CircuitParams, > { pcs_params: HidingIpa, @@ -80,7 +80,7 @@ pub struct CycleSideParams< pub struct CycleParams< C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, > { @@ -105,7 +105,7 @@ type BatchLevelProof = w3f_plonk_common::PiopProof< #[derive(Clone, Debug)] pub struct BatchSideProof< C: CurveGroup, - G: CurveModel, + G: CurveModel, P: CircuitParams, const L: usize, > { @@ -117,7 +117,7 @@ pub struct BatchSideProof< #[derive(Clone)] pub struct CycleSideProof< C: CurveGroup, - G: CurveModel, + G: CurveModel, P: CircuitParams, > { piop_proofs: Vec>, @@ -128,7 +128,7 @@ pub struct CycleSideProof< #[derive(Clone)] pub struct CurveTreeProof< C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, > { @@ -139,7 +139,7 @@ pub struct CurveTreeProof< #[derive(Clone, Debug)] pub struct CurveTreeProof2< C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, const L: usize, @@ -148,8 +148,8 @@ pub struct CurveTreeProof2< c1_proof: BatchSideProof, C0, P1, L>, } -impl, P: CircuitParams> -CycleSideParams +impl, P: CircuitParams> + CycleSideParams { pub fn commit_tree_nodes( &self, @@ -185,7 +185,7 @@ pub enum CycleSide { pub struct ArkTranscript(ark_transcript::Transcript); impl> w3f_plonk_common::transcript::PlonkTranscript -for ArkTranscript + for ArkTranscript { fn _128_bit_point(&mut self, label: &'static [u8]) -> F { self.0.challenge(label).read_reduce() @@ -255,7 +255,7 @@ mod tests { impl CycleParams where C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, { @@ -292,6 +292,8 @@ mod tests { >(9, 2); } + // cargo test test_circuit_fat --release --features="print-trace" -- --show-output + // cargo test test_circuit_fat --release --features="print-trace parallel" -- --show-output #[test] fn test_circuit_fat() { _test_proof::< @@ -361,7 +363,7 @@ mod tests { fn _test_proof(log_n: usize, height: usize) where C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, { @@ -380,19 +382,29 @@ mod tests { .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.batch_prove::<_, 2>(path, rng); - // let (auth_path, proof) = params.prove(path, rng); + let t_prove = + start_timer!(|| format!("Proving membership, height={height}, domain={domain_size}")); + let (auth_path, proof) = params.prove(path.clone(), rng); end_timer!(t_prove); - // - let t_verify = start_timer!(|| "Verifying CurveTree membership"); - // let valid = params.verify(auth_path, proof, root); - let valid = params.batch_verify::<2>(auth_path, proof, root); + + let t_verify = start_timer!(|| "Verifying membership"); + let valid = params.verify(auth_path, proof, root); end_timer!(t_verify); assert!(valid); + + if height == 4 { + println!("\n\n"); + let t_prove = start_timer!(|| format!( + "Batch-proving membership, height={height}, domain={domain_size}" + )); + let (auth_path, proof) = params.batch_prove::<_, 2>(path, rng); + end_timer!(t_prove); + + let t_verify = start_timer!(|| "Verifying membership batch-proof"); + let valid = params.batch_verify::<2>(auth_path, proof, root); + end_timer!(t_verify); + assert!(valid); + } } pub fn random_witness, R: Rng>( @@ -411,7 +423,7 @@ mod tests { pub fn random_nodes< C: CurveGroup, - G: CurveModel, + G: CurveModel, P: CircuitParams, R: Rng, >( @@ -426,7 +438,7 @@ mod tests { pub fn random_path< C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, R: Rng, diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 34df1e3..24630f2 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -1,10 +1,10 @@ -use crate::{ArkTranscript, BatchLevelProof, BatchSideProof, CurveTreeProof2}; use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::auth_path::node::LevelWitnessWithBlinding; use crate::auth_path::path::AuthenticationPath; use crate::{ AffinePoint, CircuitParams, CurveModel, CycleParams, CycleSideParams, ProjectivePoint, }; +use crate::{ArkTranscript, BatchSideProof, CurveTreeProof2}; use crate::{Coeffs, CurveTreeProof, CycleSideProof}; use ark_ec::CurveGroup; use ark_ff::{PrimeField, Zero}; @@ -13,20 +13,18 @@ use ark_std::rand::Rng; use ark_std::{UniformRand, end_timer, start_timer}; use std::collections::BTreeSet; use std::marker::PhantomData; -use ark_std::iterable::Iterable; 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::batch::BatchProver; use w3f_plonk_common::piop::{ProverPiop, VerifierPiop}; -use w3f_plonk_common::Proof; use w3f_plonk_common::prover::{PcsOpeningAt2Points, PlonkProver}; impl CycleParams where C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, { @@ -65,14 +63,18 @@ where let auth_path = blinded_auth_path.clone(); let c1_path: [_; L] = auth_path_with_bf.c1_path.try_into().unwrap(); let c0_path: [_; L] = auth_path_with_bf.c0_path.try_into().unwrap(); - let c0_proof = self.c0_params.batch_prove_side(blinded_auth_path.c1_path, c1_path, rng); - let c1_proof = self.c1_params.batch_prove_side(blinded_auth_path.c0_path, c0_path, rng); + let c0_proof = self + .c0_params + .batch_prove_side(blinded_auth_path.c1_path, c1_path, rng); + let c1_proof = self + .c1_params + .batch_prove_side(blinded_auth_path.c0_path, c0_path, rng); (auth_path, CurveTreeProof2 { c0_proof, c1_proof }) } } -impl, P: CircuitParams> -CycleSideParams +impl, P: CircuitParams> + CycleSideParams { pub fn prove_side( &self, @@ -166,24 +168,20 @@ CycleSideParams pub fn batch_prove_side( &self, - blinded_path: Vec>, + _blinded_path: Vec>, // TODO: probably not required witness: [LevelWitnessWithBlinding>; L], rng: &mut R, ) -> BatchSideProof { let curve_name = &std::any::type_name::()[53..]; // println!("\n\nprover {curve_name}\nchildren={blinded_path:?}\n"); - // let n_levels = witness.len(); // number of tree levels on this side - // debug_assert_eq!(blinded_path.len(), n_levels); - // let mut piop_proofs = Vec::with_capacity(n_levels); - // - // // per tree level + let n_columns = P::VerifierCircuit::N_COLUMNS; - let n_to_commit = L * n_columns + 3; // plus the quotient chunks - let n_to_open = L * n_columns + 2; // plus the (folded) quotient (chunks) and the linearization polynomial + let n_to_commit = L * n_columns + 3; // columns for multiple levels + the shared quotient chunks + let n_to_open = L * n_columns + 2; // --//-- + the (folded) quotient + the linearization polynomial let plonk_prover = PlonkProver::, _>::init( self.pcs_params.ck(), - (), + (), // TODO: ArkTranscript::new(b"pasta-tree-level-proof"), ); @@ -194,7 +192,8 @@ CycleSideParams let t_commit_side = start_timer!(|| format!( "Committing {L}x{n_columns}+3 = {n_to_commit} polynomials to {curve_name}" )); - let (pcs_openings, piop_proof, _transcript) = plonk_prover.reduce_to_pcs_opening(batch_piop); + let (pcs_openings, piop_proof, _transcript) = + plonk_prover.reduce_to_pcs_opening(batch_piop); end_timer!(t_commit_side); let PcsOpeningAt2Points { @@ -203,30 +202,32 @@ CycleSideParams zeta, zeta_omega, } = pcs_openings; - println!("zeta = {zeta}\nq(zeta) = {}\n", polys_at_zeta[polys_at_zeta.len() - 1].evaluate(&zeta)); + // println!("zeta = {zeta}\nq(zeta) = {}\n", polys_at_zeta[polys_at_zeta.len() - 1].evaluate(&zeta)); + let mut at_coords = vec![BTreeSet::from([zeta]); polys_at_zeta.len()]; let mut polys_to_open = polys_at_zeta; - at_coords.extend(vec![BTreeSet::from([zeta_omega]); polys_at_zeta_omega.len()]); + at_coords.extend(vec![ + BTreeSet::from([zeta_omega]); + polys_at_zeta_omega.len() + ]); polys_to_open.extend(polys_at_zeta_omega.clone()); - let with_bfs = parent_bfs.into_iter().flat_map(|bf| { - let mut res = vec![C::ScalarField::zero(); n_columns]; - res[0] = bf; - res - }).chain(vec![C::ScalarField::zero(); 2]) - .collect::>(); - debug_assert_eq!(with_bfs.len(), n_to_open); - - let lin = &polys_at_zeta_omega[0]; - use w3f_pcs::pcs::PCS; - let lin_c = HidingIpa::::commit(&self.pcs_params,&lin).unwrap().0; - println!("C_lin = {lin_c}"); - - for (i, ((p, z), bf)) in polys_to_open.iter() - .zip(at_coords.iter().map(|z| z.first().unwrap())) - .zip(with_bfs.iter()) - .enumerate() { - println!("{i}: z={z}, p(z)={}, bf={bf}", p.evaluate(z)); - } + assert_eq!(polys_to_open.len(), n_to_open); + + let mut with_bfs: Vec<_> = parent_bfs + .into_iter() + .flat_map(|bf| vec![bf, C::ScalarField::zero(), C::ScalarField::zero()]) + .collect(); + with_bfs.resize(n_to_open, C::ScalarField::zero()); + + // use ark_ec::AffineRepr; + // for (i, ((p, z), bf)) in polys_to_open.iter() + // .zip(at_coords.iter().map(|z| z.first().unwrap())) + // .zip(with_bfs.iter()) + // .enumerate() { + // let v = p.evaluate(z); + // let c = HidingIpa::::commit(&self.pcs_params, &p).unwrap().0; + // println!("{i}: z={:.5}, v={:.5}, c={:.5}, bf={:.5}", z.to_string(), v.to_string(), c.x().unwrap().to_string(), bf.to_string()); + // } let t_open = start_timer!(|| format!( "Opening {L}x{n_columns}+2 = {n_to_open} polynomials, max_degree = {}", diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index bdcf090..12acf79 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -1,13 +1,12 @@ -use std::collections::BTreeSet; -use std::marker::PhantomData; -use crate::{ArkTranscript, BatchSideProof, CurveTreeProof2}; use crate::auth_path::blinded::BlindedAuthenticationPath; use crate::{ AffinePoint, CircuitParams, CurveModel, CycleParams, CycleSideParams, ProjectivePoint, }; +use crate::{ArkTranscript, BatchSideProof, CurveTreeProof2}; use crate::{CurveTreeProof, CycleSideProof}; use ark_ec::CurveGroup; use ark_ff::PrimeField; +use std::marker::PhantomData; use w3f_pcs::pcs::PcsParams; use w3f_pcs::pcs::ipa::hiding::HidingIpa; use w3f_pcs::shplonk::Shplonk; @@ -18,7 +17,7 @@ use w3f_plonk_common::verifier::{PcsOpeningAt2Points, PlonkVerifier}; impl CycleParams where C0: CurveModel, - C1: CurveModel, + C1: CurveModel, P0: CircuitParams, C1>, P1: CircuitParams, C0>, { @@ -53,14 +52,16 @@ where .c0_params .verify_batch(c1_path.clone(), c0_parents, proof.c0_proof); assert!(c0_proof); - let c1_proof = self.c1_params.verify_batch(c0_path, c1_path, proof.c1_proof); + let c1_proof = self + .c1_params + .verify_batch(c0_path, c1_path, proof.c1_proof); assert!(c1_proof); c0_proof && c1_proof } } -impl, P: CircuitParams> -CycleSideParams +impl, P: CircuitParams> + CycleSideParams { pub fn verify_side( &self, @@ -156,19 +157,7 @@ CycleSideParams // let curve_name = &std::any::type_name::()[53..]; // println!("\n\nverifier {curve_name}\nchildren={children:?}\nparents={parents:?}\n"); - // // number of tree levels on this side - // let n_levels = side_proof.piop_proofs.len(); - // // per tree level - // let n_to_open = P::VerifierCircuit::N_COLUMNS + 2; // plus the (folded) quotient (chunks) and the linearization polynomial - // // per side - // let n_openings = n_levels * n_to_open; - // - // let mut polys_to_open = Vec::with_capacity(n_openings); - // let mut at_coords = Vec::with_capacity(n_openings); - // let mut to_values = Vec::with_capacity(n_openings); - - //TODO: precompute - let fixed_cols = self.commit_fixed_columns(); + let fixed_cols = self.commit_fixed_columns(); // TODO: precompute let piop_proof = side_proof.piop_proof.clone(); let instance: [AffinePoint; L] = children.clone().try_into().unwrap(); @@ -185,20 +174,25 @@ CycleSideParams L * P::VerifierCircuit::N_CONSTRAINTS, ); let zeta_ = challenges.zeta; - println!("zeta = {zeta_}"); + // println!("zeta = {zeta_}"); - let batch_piop: [_; L] = children.into_iter() + let batch_piop: [_; L] = children + .into_iter() .zip(parents.into_iter()) .zip(piop_proof.column_commitments.into_iter()) .zip(piop_proof.columns_at_zeta.into_iter()) - .map(|(((child, parent), cols), evals)| + .map(|(((child, parent), cols), evals)| { self.piop_params.verifier_circuit( (child, parent), &fixed_cols, cols, evals, challenges.zeta, - )).collect::>().try_into().unwrap_or_else(|_| panic!("wtf")); + ) + }) + .collect::>() + .try_into() + .unwrap_or_else(|_| panic!("wtf")); let batch_piop = BatchVerifier(batch_piop, PhantomData, PhantomData); let PcsOpeningAt2Points { @@ -210,25 +204,25 @@ CycleSideParams vals_at_zeta_omega, } = plonk_verifier.evaluate_piop(batch_piop, side_proof.piop_proof, challenges); debug_assert_eq!(zeta, zeta_); - println!("q(zeta) = {}", vals_at_zeta[vals_at_zeta.len() - 1]); + // println!("q(zeta) = {}", vals_at_zeta[vals_at_zeta.len() - 1]); let mut at_coords = vec![vec![zeta]; open_at_zeta.len()]; let mut polys_to_open = open_at_zeta; at_coords.extend(vec![vec![zeta_omega]; open_at_zeta_omega.len()]); polys_to_open.extend(open_at_zeta_omega.clone()); - let to_values: Vec> = vals_at_zeta.into_iter() + let to_values: Vec> = vals_at_zeta + .into_iter() .chain(vals_at_zeta_omega.into_iter()) .map(|v| vec![v]) .collect(); - let lin = open_at_zeta_omega[0].0; - println!("C_lin = {lin}"); - for (i, ((p, z), v)) in polys_to_open.iter() - .zip(at_coords.iter().map(|z| z.first().unwrap())) - .zip(to_values.iter().map(|v| v.first().unwrap())) - .enumerate() { - println!("{i}: z={z}, v={v}"); - } + // use ark_ec::AffineRepr; + // for (i, ((c, z), v)) in polys_to_open.iter() + // .zip(at_coords.iter().map(|z| z.first().unwrap())) + // .zip(to_values.iter().map(|v| v.first().unwrap())) + // .enumerate() { + // println!("{i}: z={:.5}, v={:.5}, c = {:.5}", z.to_string(), v.to_string(), c.0.x().unwrap().to_string()); + // } let mut todo = side_proof.todo; let valid = Shplonk::>::verify_many( diff --git a/w3f-plonk-common/src/batch.rs b/w3f-plonk-common/src/batch.rs index 4f977d3..f2dd3e8 100644 --- a/w3f-plonk-common/src/batch.rs +++ b/w3f-plonk-common/src/batch.rs @@ -1,33 +1,66 @@ -use std::marker::PhantomData; +use crate::domain::{Domain, EvaluatedDomain}; +use crate::piop::{ProverPiop, VerifierPiop}; +use crate::{ColumnsCommited, ColumnsEvaluated}; use ark_ff::PrimeField; -use ark_poly::Evaluations; use ark_poly::univariate::DensePolynomial; +use ark_poly::Evaluations; +use std::marker::PhantomData; use w3f_pcs::pcs::Commitment; -use w3f_pcs::pcs::commitment::WrappedAffine; -use crate::{ColumnsCommited, ColumnsEvaluated}; -use crate::domain::{Domain, EvaluatedDomain}; -use crate::piop::{ProverPiop, VerifierPiop}; -impl, CC: ColumnsCommited, const K: usize> ColumnsCommited for [CC; K] { +impl, CC: ColumnsCommited, const K: usize> + ColumnsCommited for [CC; K] +{ fn to_vec(self) -> Vec { - self.into_iter() - .flat_map(|p| p.to_vec()) - .collect() + self.into_iter().flat_map(|p| p.to_vec()).collect() } } +// TODO: remove +// TODO: fixed columns that are fixed (selectors) don't have to be re-evaluated in the same point. +// TODO: other columns (like root layer) can be just witnessed in the proof. +// Flattens the vec while moving the first 3 elements of each inner vec to the beginning of the vec. +fn excerpt_fixed_columns(column_vecs: Vec>) -> Vec { + let k = column_vecs.len(); + let total_cols = 9; + let fixed_cols = 3; + let advice_cols = total_cols - fixed_cols; + let mut fixed = Vec::with_capacity(fixed_cols * k); + let mut advice = Vec::with_capacity(advice_cols * k); + for mut vec in column_vecs { + assert_eq!(vec.len(), total_cols); + advice.extend(vec.split_off(3)); + fixed.extend(vec); + } + [fixed, advice].concat() +} + impl, const K: usize> ColumnsEvaluated for [CE; K] { fn to_vec(self) -> Vec { - self.into_iter() - .flat_map(|p| p.to_vec()) - .collect() + let column_vecs = self + .iter() + .map(|evals| evals.clone().to_vec()) + .collect::>(); + let res = excerpt_fixed_columns(column_vecs); + let total_cols = 9; + debug_assert_eq!(res.len(), total_cols * K); + res } } -pub struct BatchProver, P: ProverPiop, const K: usize>(pub [P; K], pub PhantomData, pub PhantomData); -pub struct BatchVerifier, V: VerifierPiop, const K: usize>(pub [V; K], pub PhantomData, pub PhantomData); - -impl, P: ProverPiop, const K: usize> ProverPiop for BatchProver { +pub struct BatchProver, P: ProverPiop, const K: usize>( + pub [P; K], + pub PhantomData, + pub PhantomData, +); +pub struct BatchVerifier, V: VerifierPiop, const K: usize>( + pub [V; K], + pub PhantomData, + pub PhantomData, +); + +impl, P: ProverPiop, const K: usize> ProverPiop + for BatchProver +{ const N_COLUMNS: usize = P::N_COLUMNS * K; const N_CONSTRAINTS: usize = P::N_CONSTRAINTS * K; const N_QUOTIENT_CHUNKS: usize = P::N_QUOTIENT_CHUNKS; @@ -35,8 +68,12 @@ impl, P: ProverPiop, const K: usize> Prove type Evaluations = [P::Evaluations; K]; type Instance = [P::Instance; K]; - fn committed_columns) -> C + Clone>(&self, commit: Fun) -> Self::Commitments { - self.0.iter() + fn committed_columns) -> C + Clone>( + &self, + commit: Fun, + ) -> Self::Commitments { + self.0 + .iter() .map(|p| p.committed_columns(commit.clone())) .collect::>() .try_into() @@ -44,13 +81,13 @@ impl, P: ProverPiop, const K: usize> Prove } fn columns(&self) -> Vec> { - self.0.iter() - .flat_map(|p| p.columns()) - .collect() + let column_vecs = self.0.iter().map(|p| p.columns()).collect::>(); + excerpt_fixed_columns(column_vecs) } fn columns_evaluated(&self, zeta: &F) -> Self::Evaluations { - self.0.iter() + self.0 + .iter() .map(|p| p.columns_evaluated(zeta)) .collect::>() .try_into() @@ -58,13 +95,12 @@ impl, P: ProverPiop, const K: usize> Prove } fn constraints(&self) -> Vec> { - self.0.iter() - .flat_map(|p| p.constraints()) - .collect() + self.0.iter().flat_map(|p| p.constraints()).collect() } fn constraints_lin(&self, zeta: &F) -> Vec> { - self.0.iter() + self.0 + .iter() .flat_map(|p| p.constraints_lin(zeta)) .collect() } @@ -78,7 +114,8 @@ impl, P: ProverPiop, const K: usize> Prove } fn result(&self) -> Self::Instance { - self.0.iter() + self.0 + .iter() .map(|p| p.result()) .collect::>() // Requires allocation if you use .collect() .try_into() @@ -86,27 +123,32 @@ impl, P: ProverPiop, const K: usize> Prove } } -impl, V: VerifierPiop, const K: usize> VerifierPiop for BatchVerifier { +impl, V: VerifierPiop, const K: usize> VerifierPiop + for BatchVerifier +{ const N_COLUMNS: usize = V::N_COLUMNS * K; const N_CONSTRAINTS: usize = V::N_CONSTRAINTS * K; fn precommitted_columns(&self) -> Vec { - self.0.iter() + self.0 + .iter() .flat_map(|p| p.precommitted_columns()) .collect() } fn evaluate_constraints_main(&self) -> Vec { - self.0.iter() + self.0 + .iter() .flat_map(|p| p.evaluate_constraints_main()) .collect() } fn lin_poly_commitment(&self, agg_coeffs: &[F]) -> (Vec, Vec) { - self.0.iter() + self.0 + .iter() .zip(agg_coeffs.chunks(V::N_CONSTRAINTS)) .map(|(p, alphas)| p.lin_poly_commitment(alphas)) - .reduce(| (mut acc_f, mut acc_c), (f, c)| { + .reduce(|(mut acc_f, mut acc_c), (f, c)| { acc_f.extend(f); acc_c.extend(c); (acc_f, acc_c) @@ -117,4 +159,4 @@ impl, V: VerifierPiop, const K: usize> Ver fn domain_evaluated(&self) -> &EvaluatedDomain { self.0[0].domain_evaluated() } -} \ No newline at end of file +} diff --git a/w3f-plonk-common/src/lib.rs b/w3f-plonk-common/src/lib.rs index 46398da..8d3d043 100644 --- a/w3f-plonk-common/src/lib.rs +++ b/w3f-plonk-common/src/lib.rs @@ -9,6 +9,7 @@ use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::{Commitment, PCS}; +pub mod batch; pub mod domain; pub mod gadgets; pub mod kzg_acc; @@ -18,7 +19,6 @@ pub mod q_chunking; pub mod test_helpers; pub mod transcript; pub mod verifier; -pub mod batch; pub trait Column { fn domain(&self) -> GeneralEvaluationDomain; @@ -75,13 +75,13 @@ pub fn const_evals(c: F, domain: GeneralEvaluationDomain) -> Eva } pub trait ColumnsEvaluated: -Clone + ark_std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize + Clone + ark_std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize { fn to_vec(self) -> Vec; } pub trait ColumnsCommited>: -Clone + ark_std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize + Clone + ark_std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize { fn to_vec(self) -> Vec; } diff --git a/w3f-plonk-common/src/verifier.rs b/w3f-plonk-common/src/verifier.rs index 8f3c9f2..187f47e 100644 --- a/w3f-plonk-common/src/verifier.rs +++ b/w3f-plonk-common/src/verifier.rs @@ -119,7 +119,7 @@ impl, T: PlonkTranscript> PlonkVerifier( diff --git a/w3f-ring-proof/src/piop/mod.rs b/w3f-ring-proof/src/piop/mod.rs index 4f85a5b..8bc5263 100644 --- a/w3f-ring-proof/src/piop/mod.rs +++ b/w3f-ring-proof/src/piop/mod.rs @@ -208,3 +208,58 @@ pub fn index, G: AffineRepr>( }; (prover_key, verifier_key) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::index; + use crate::tests::setup; + use ark_ed_on_bls12_381_bandersnatch::{EdwardsAffine, Fq, Fr}; + use ark_std::{test_rng, UniformRand}; + use w3f_pcs::pcs::id::WrappedPolynomial; + use w3f_pcs::pcs::IdentityCommitment; + use w3f_pcs::Polynomial; + use w3f_plonk_common::piop::ProverPiop; + use w3f_plonk_common::test_helpers::random_vec; + + #[test] + fn test_ring_piop() { + let rng = &mut test_rng(); + + let log_n = 9; + let n = 1 << log_n; + + let (pcs_params, piop_params) = setup::<_, IdentityCommitment>(rng, n); + let pks = random_vec::(piop_params.keyset_part_size, rng); + let (prover_key, verifier_key) = + index::<_, IdentityCommitment, _>(&pcs_params, &piop_params, &pks); + let fixed_columns = prover_key.fixed_columns.clone(); + let prover: PiopProver = + PiopProver::build(&piop_params, fixed_columns, 1, Fr::rand(rng)); + assert!(ProverPiop::>::constraints_satisfied(&prover)); + + let zeta = Fq::rand(rng); + let columns = ProverPiop::>::columns(&prover); + let evals = ProverPiop::>::columns_evaluated(&prover, &zeta); + let evals = evals.to_vec(); + assert_eq!(columns.len(), evals.len()); + for (p, v) in columns.iter().zip(evals) { + assert_eq!(p.evaluate(&zeta), v); + } + + let fixed_columns = verifier_key.fixed_columns_committed.as_vec(); + let advice_columns = + ProverPiop::>::committed_columns(&prover, |p| { + IdentityCommitment::commit(&prover_key.pcs_ck, p).unwrap() + }); + let advice_columns = advice_columns.to_vec(); + let commitments = [fixed_columns, advice_columns].concat(); + assert_eq!(columns.len(), commitments.len()); + for (p, c) in columns.iter().zip(commitments) { + assert_eq!( + IdentityCommitment::commit(&prover_key.pcs_ck, p).unwrap(), + c + ); + } + } +} diff --git a/w3f-ring-proof/src/piop/prover.rs b/w3f-ring-proof/src/piop/prover.rs index 464fd97..f0d22d0 100644 --- a/w3f-ring-proof/src/piop/prover.rs +++ b/w3f-ring-proof/src/piop/prover.rs @@ -265,32 +265,3 @@ where self.cond_add.result() } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::index; - use crate::tests::setup; - use ark_ed_on_bls12_381_bandersnatch::{EdwardsAffine, Fq, Fr}; - use ark_std::{test_rng, UniformRand}; - use w3f_pcs::pcs::id::WrappedPolynomial; - use w3f_pcs::pcs::IdentityCommitment; - use w3f_plonk_common::test_helpers::random_vec; - - #[test] - fn test_constraints() { - let rng = &mut test_rng(); - - let log_n = 9; - let n = 1 << log_n; - - let (pcs_params, piop_params) = setup::<_, IdentityCommitment>(rng, n); - let pks = random_vec::(piop_params.keyset_part_size, rng); - let (prover_key, _verifier_key) = - index::<_, IdentityCommitment, _>(&pcs_params, &piop_params, &pks); - let fixed_columns = prover_key.fixed_columns.clone(); - let piop: PiopProver = - PiopProver::build(&piop_params, fixed_columns, 1, Fr::rand(rng)); - assert!(ProverPiop::>::constraints_satisfied(&piop)); - } -} From e21827c7f7f78354174f006c29351749f048a539 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 11 Sep 2026 02:25:49 +0300 Subject: [PATCH 4/7] post-merge fix --- w3f-plonk-common/src/batch.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/w3f-plonk-common/src/batch.rs b/w3f-plonk-common/src/batch.rs index f2dd3e8..60f63b3 100644 --- a/w3f-plonk-common/src/batch.rs +++ b/w3f-plonk-common/src/batch.rs @@ -128,6 +128,7 @@ impl, V: VerifierPiop, const K: usize> Ver { const N_COLUMNS: usize = V::N_COLUMNS * K; const N_CONSTRAINTS: usize = V::N_CONSTRAINTS * K; + type Instance = [V::Instance; K]; fn precommitted_columns(&self) -> Vec { self.0 From ba3797af856d2df9fdff4348e492e42fa1e171e9 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 11 Sep 2026 02:30:42 +0300 Subject: [PATCH 5/7] no-std --- w3f-plonk-common/src/batch.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/w3f-plonk-common/src/batch.rs b/w3f-plonk-common/src/batch.rs index 60f63b3..cae0453 100644 --- a/w3f-plonk-common/src/batch.rs +++ b/w3f-plonk-common/src/batch.rs @@ -4,7 +4,8 @@ use crate::{ColumnsCommited, ColumnsEvaluated}; use ark_ff::PrimeField; use ark_poly::univariate::DensePolynomial; use ark_poly::Evaluations; -use std::marker::PhantomData; +use ark_std::marker::PhantomData; +use ark_std::vec::Vec; use w3f_pcs::pcs::Commitment; impl, CC: ColumnsCommited, const K: usize> From 0ee1be5a3f4cfe45da18cdddb10f351064bfbf12 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 11 Sep 2026 07:35:46 +0300 Subject: [PATCH 6/7] smth works --- Cargo.toml | 4 ++-- pasta-tree/src/auth_path/path.rs | 7 ------- pasta-tree/src/circuit_fat/params.rs | 8 +++++++- pasta-tree/src/circuit_fat/prover.rs | 8 +++++++- pasta-tree/src/circuit_fat/verifier.rs | 1 + pasta-tree/src/circuit_tall/params.rs | 8 +++++++- pasta-tree/src/circuit_tall/prover.rs | 6 +++++- pasta-tree/src/circuit_tall/verifier.rs | 4 +++- pasta-tree/src/lib.rs | 9 +++++++-- pasta-tree/src/verifier.rs | 21 +++++++++------------ 10 files changed, 48 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0207849..b631cd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ resolver = "2" members = [ # "evm-vrfier", -# "pasta-tree", + "pasta-tree", "w3f-plonk-common", "w3f-ring-proof", # "w3f-ring-vrf-snark", @@ -20,7 +20,7 @@ ark-ff = { version = "0.6", default-features = false } ark-ec = { version = "0.6", default-features = false } ark-poly = { version = "0.6", default-features = false } ark-serialize = { version = "0.6", default-features = false, features = ["derive"] } -w3f-pcs = { version = "0.0.7", default-features = false } +w3f-pcs = { version = "0.0.6", git = "https://github.com/paritytech/fflonk/", branch = "ipa-pcs", default-features = false } w3f-plonk-common = { version = "0.0.10", path = "w3f-plonk-common", default-features = false } rayon = { version = "1", default-features = false } ark-transcript = { version = "0.0.6", default-features = false } diff --git a/pasta-tree/src/auth_path/path.rs b/pasta-tree/src/auth_path/path.rs index aa8a2bd..b1d8619 100644 --- a/pasta-tree/src/auth_path/path.rs +++ b/pasta-tree/src/auth_path/path.rs @@ -21,13 +21,6 @@ pub struct AuthenticationPath { pub c1_path: Vec>, } -pub struct AuthenticationPath2 { - /// Nodes on the `C0` curve. - pub c0_path: [LevelWitness; L0], - /// Nodes on the `C1` curve. - pub c1_path: [LevelWitness; L1], -} - impl AuthenticationPath, ProjectivePoint> where C0: CurveModel, diff --git a/pasta-tree/src/circuit_fat/params.rs b/pasta-tree/src/circuit_fat/params.rs index 879c559..59d41ab 100644 --- a/pasta-tree/src/circuit_fat/params.rs +++ b/pasta-tree/src/circuit_fat/params.rs @@ -9,6 +9,7 @@ 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::cond_select::CondSelect; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; @@ -29,6 +30,8 @@ pub struct PiopParams> { impl> CircuitParams for PiopParams> +where + G::BaseField: CondSelect, { type Commitments = crate::circuit_fat::ProofComms; type Evaluations = crate::circuit_fat::ProofEvals; @@ -86,7 +89,10 @@ impl> CircuitParams> PiopParams { +impl> PiopParams +where + G::BaseField: CondSelect, +{ pub fn setup(domain: Domain, h: G) -> Self { let scalar_bitlen = G::ScalarField::MODULUS_BIT_SIZE as usize; Self { diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index f5d89f0..591172b 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -11,6 +11,7 @@ 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::cond_select::CondSelect; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::ProverGadget; use w3f_plonk_common::gadgets::booleanity::{BitColumn, Booleanity}; @@ -41,7 +42,10 @@ pub struct PiopProver> { result: G, } -impl> PiopProver> { +impl> PiopProver> +where + G::BaseField: CondSelect, +{ pub fn build( params: &PiopParams>, level: LevelWitnessWithBlinding>, @@ -195,6 +199,8 @@ impl> PiopProver> { impl> ProverPiop> for PiopProver> +where + G::BaseField: CondSelect, { const N_COLUMNS: usize = 9; const N_CONSTRAINTS: usize = 13; diff --git a/pasta-tree/src/circuit_fat/verifier.rs b/pasta-tree/src/circuit_fat/verifier.rs index 31a5c8b..d473ddf 100644 --- a/pasta-tree/src/circuit_fat/verifier.rs +++ b/pasta-tree/src/circuit_fat/verifier.rs @@ -99,6 +99,7 @@ impl> { const N_COLUMNS: usize = 9; const N_CONSTRAINTS: usize = 13; + type Instance = AffinePoint; fn precommitted_columns(&self) -> Vec> { vec![ diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index ac28082..7b888e3 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -9,6 +9,7 @@ use ark_ff::{FftField, One}; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; use w3f_plonk_common::FieldColumn; +use w3f_plonk_common::cond_select::CondSelect; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; @@ -35,6 +36,8 @@ pub struct PiopParams> { impl> CircuitParams for PiopParams> +where + G::BaseField: CondSelect, { type Commitments = crate::circuit_tall::ProofComms; type Evaluations = crate::circuit_tall::ProofEvals; @@ -106,7 +109,10 @@ impl> CircuitParams> PiopParams { +impl> PiopParams +where + G::BaseField: CondSelect, +{ pub fn setup(domain: Domain, h: G, seed: G) -> Self { assert!(domain.domain_size() > 256); let actual_capacity = domain.capacity - 1; diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index a9a33b3..24687c9 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -10,6 +10,7 @@ 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::cond_select::CondSelect; use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::ProverGadget; use w3f_plonk_common::gadgets::booleanity::{BitColumn, Booleanity}; @@ -35,7 +36,10 @@ pub struct PiopProver> { result: G, } -impl> PiopProver> { +impl> PiopProver> +where + G::BaseField: CondSelect, +{ pub fn build( params: &PiopParams>, level: LevelWitnessWithBlinding>, diff --git a/pasta-tree/src/circuit_tall/verifier.rs b/pasta-tree/src/circuit_tall/verifier.rs index cefcdf1..fdac640 100644 --- a/pasta-tree/src/circuit_tall/verifier.rs +++ b/pasta-tree/src/circuit_tall/verifier.rs @@ -1,8 +1,8 @@ use crate::circuit_tall::{ProofComms, ProofEvals}; +use crate::{AffinePoint, CurveModel}; use ark_ec::AffineRepr; use ark_ec::CurveGroup; // use ark_ec::short_weierstrass::{Affine as SwAffine, SWCurveConfig}; -use crate::{AffinePoint, CurveModel}; use ark_ff::{One, Zero}; use ark_std::marker::PhantomData; use ark_std::{vec, vec::Vec}; @@ -99,6 +99,8 @@ impl> { const N_COLUMNS: usize = 7; const N_CONSTRAINTS: usize = 7; + type Instance = AffinePoint; + // type Instance = > as ProverPiop>>::Instance; 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 c7ec67d..1d4381b 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -38,7 +38,11 @@ pub trait CircuitParams Commitments = Self::Commitments, Evaluations = Self::Evaluations, >; - type VerifierCircuit: VerifierPiop>; + type VerifierCircuit: VerifierPiop< + C::ScalarField, + WrappedAffine, + Instance = AffinePoint + >; fn prover_circuit( &self, @@ -392,7 +396,8 @@ mod tests { end_timer!(t_verify); assert!(valid); - if height == 4 { + // number of columns for the FAT scheme is hardcoded in batch.rs + if height == 4 && log_n == 8 { println!("\n\n"); let t_prove = start_timer!(|| format!( "Batch-proving membership, height={height}, domain={domain_size}" diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 12acf79..d073897 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -8,6 +8,7 @@ use ark_ec::CurveGroup; use ark_ff::PrimeField; use std::marker::PhantomData; 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::batch::BatchVerifier; @@ -99,12 +100,8 @@ impl, P: CircuitParams< .zip(parents.into_iter()) .zip(side_proof.piop_proofs.into_iter()) { - let (challenges, _rng) = plonk_verifier.restore_challenges( - &child, - &level_proof, - 0, - P::VerifierCircuit::N_CONSTRAINTS, - ); + let challenges = plonk_verifier + .restore_fs_challenges::(&child, &level_proof); let piop = self.piop_params.verifier_circuit( (child, parent), &fixed_cols, @@ -167,12 +164,12 @@ impl, P: CircuitParams< ArkTranscript::new(b"pasta-tree-level-proof"), ); - let (challenges, _rng) = plonk_verifier.restore_challenges( - &instance, - &piop_proof, - 0, - L * P::VerifierCircuit::N_CONSTRAINTS, - ); + let challenges = plonk_verifier.restore_fs_challenges::, + P::VerifierCircuit, + L, + >, _, _>(&instance, &piop_proof); let zeta_ = challenges.zeta; // println!("zeta = {zeta_}"); From 2fb7591e69d49810078e544b89a61b6707dce8a9 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Fri, 11 Sep 2026 07:36:48 +0300 Subject: [PATCH 7/7] fmt --- pasta-tree/src/lib.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 1d4381b..8543bb3 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -38,11 +38,7 @@ pub trait CircuitParams Commitments = Self::Commitments, Evaluations = Self::Evaluations, >; - type VerifierCircuit: VerifierPiop< - C::ScalarField, - WrappedAffine, - Instance = AffinePoint - >; + type VerifierCircuit: VerifierPiop, Instance = AffinePoint>; fn prover_circuit( &self,