From 2e7754604527144fc411f3d89f53ddc2c67fefea Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 07:49:56 +0300 Subject: [PATCH 01/17] quotient is a vec now --- w3f-plonk-common/src/lib.rs | 7 ++++--- w3f-plonk-common/src/piop.rs | 4 ++++ w3f-plonk-common/src/prover.rs | 26 ++++++++++++++---------- w3f-plonk-common/src/q_chunking.rs | 32 ++++++++++++++++++++++++++++++ w3f-plonk-common/src/verifier.rs | 6 ++++-- 5 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 w3f-plonk-common/src/q_chunking.rs diff --git a/w3f-plonk-common/src/lib.rs b/w3f-plonk-common/src/lib.rs index 7f0f89d..78a232d 100644 --- a/w3f-plonk-common/src/lib.rs +++ b/w3f-plonk-common/src/lib.rs @@ -17,6 +17,7 @@ pub mod prover; pub mod test_helpers; pub mod transcript; pub mod verifier; +mod q_chunking; pub trait Column { fn domain(&self) -> GeneralEvaluationDomain; @@ -103,7 +104,7 @@ where { pub column_commitments: Commitments, pub columns_at_zeta: Evaluations, - pub quotient_commitment: CS::C, + pub quotient_chunks: Vec, pub lin_at_zeta_omega: F, pub agg_at_zeta_proof: CS::Proof, pub lin_at_zeta_omega_proof: CS::Proof, @@ -120,7 +121,7 @@ where { pub column_commitments: Commitments, pub columns_at_zeta: Evaluations, - pub quotient_commitment: C, + pub quotient_chunks: Vec, pub lin_at_zeta_omega: F, } @@ -135,7 +136,7 @@ where PiopProof { column_commitments: self.column_commitments.clone(), columns_at_zeta: self.columns_at_zeta.clone(), - quotient_commitment: self.quotient_commitment.clone(), + quotient_chunks: self.quotient_chunks.clone(), lin_at_zeta_omega: self.lin_at_zeta_omega, } } diff --git a/w3f-plonk-common/src/piop.rs b/w3f-plonk-common/src/piop.rs index fd9ec12..ecb3019 100644 --- a/w3f-plonk-common/src/piop.rs +++ b/w3f-plonk-common/src/piop.rs @@ -32,6 +32,10 @@ pub trait ProverPiop> { // Constraint polynomials in evaluation form. fn constraints(&self) -> Vec>; + fn quotient_chunks(&self, alphas: &[F]) -> Option>> { + self.compute_quotient(alphas).map(|q|vec![q]) + } + fn compute_quotient(&self, alphas: &[F]) -> Option> { let constraints = self.constraints(); // Aggregate constraint polynomials in evaluation form... diff --git a/w3f-plonk-common/src/prover.rs b/w3f-plonk-common/src/prover.rs index 0779926..dcbc6ce 100644 --- a/w3f-plonk-common/src/prover.rs +++ b/w3f-plonk-common/src/prover.rs @@ -69,15 +69,21 @@ impl, T: PlonkTranscript> PlonkProver end_timer!(t_commit_cols); // ROUND 2 + // The prover commits to the quotient polynomial... let alphas = transcript.get_constraints_aggregation_coeffs(P::N_CONSTRAINTS); - let quotient_poly = piop.compute_quotient(&alphas).unwrap(); + let quotient_chunks = piop.quotient_chunks(&alphas).unwrap(); let t_commit_q = start_timer!(|| format!( - "Committing to the degree-{} quotient", - quotient_poly.degree() + "Committing to {} degree-{} quotient chunks", quotient_chunks.len(), + quotient_chunks[0].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); + let quotient_chunks_committed: Vec<_> = quotient_chunks.iter() + .map(|qi| CS::commit(&self.pcs_ck, qi).unwrap()) + .collect(); + for qi_committed in quotient_chunks_committed.iter() { + transcript.add_quotient_commitment(&qi_committed); + } + // 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 @@ -94,11 +100,11 @@ impl, T: PlonkTranscript> PlonkProver transcript.add_evaluations(&columns_at_zeta, &lin_at_zeta_omega); let piop_proof = PiopProof { column_commitments, - quotient_commitment, + quotient_chunks: quotient_chunks_committed, columns_at_zeta, lin_at_zeta_omega, }; - let polys_at_zeta = [columns_to_open, vec![quotient_poly]].concat(); + let polys_at_zeta = [columns_to_open, quotient_chunks].concat(); let pcs_openings = PcsOpeningAt2Points { polys_at_zeta, polys_at_zeta_omega: vec![lin], @@ -122,7 +128,7 @@ impl, T: PlonkTranscript> PlonkProver let lin = &polys_at_zeta_omega[0]; let PiopProof { column_commitments, - quotient_commitment, + quotient_chunks: quotient_commitment, columns_at_zeta, lin_at_zeta_omega, } = piop_proof; @@ -137,7 +143,7 @@ impl, T: PlonkTranscript> PlonkProver end_timer!(_t_open_zeta_omega); Proof { column_commitments, - quotient_commitment, + quotient_chunks: quotient_commitment, columns_at_zeta, lin_at_zeta_omega, agg_at_zeta_proof, diff --git a/w3f-plonk-common/src/q_chunking.rs b/w3f-plonk-common/src/q_chunking.rs new file mode 100644 index 0000000..33623a2 --- /dev/null +++ b/w3f-plonk-common/src/q_chunking.rs @@ -0,0 +1,32 @@ +use ark_ff::{Field, PrimeField}; +use ark_poly::DenseUVPolynomial; +use ark_poly::univariate::DensePolynomial; +use w3f_pcs::pcs::Commitment; +use w3f_pcs::utils; + +fn chunk_quotient(q: DensePolynomial, n: usize) -> Vec> { + q.coeffs + .chunks(n) + .map(|coeffs| DensePolynomial::from_coefficients_slice(coeffs)) + .collect() +} + +fn fold_quotient_chunks(chunks: &[DensePolynomial], z_to_n: F) -> DensePolynomial { + chunks.iter() + .zip(utils::powers(z_to_n)) + .map(|(chunk, coeff)| chunk * coeff) + .reduce(|acc, new| acc + new) + .unwrap() +} + +fn quotient_commitment>(chunks: &[C], z_to_n: F) -> C { + chunks.iter() + .zip(utils::powers(z_to_n)) + .map(|(chunk, coeff)| chunk.mul(coeff)) + .sum() +} + +#[cfg(test)] +mod tests { + +} \ No newline at end of file diff --git a/w3f-plonk-common/src/verifier.rs b/w3f-plonk-common/src/verifier.rs index 4561559..14e9edf 100644 --- a/w3f-plonk-common/src/verifier.rs +++ b/w3f-plonk-common/src/verifier.rs @@ -53,7 +53,7 @@ impl, T: PlonkTranscript> PlonkVerifier, T: PlonkTranscript> PlonkVerifier Date: Sun, 31 May 2026 16:44:07 +0300 Subject: [PATCH 02/17] fmt --- w3f-plonk-common/src/lib.rs | 2 +- w3f-plonk-common/src/piop.rs | 2 +- w3f-plonk-common/src/prover.rs | 6 ++++-- w3f-plonk-common/src/q_chunking.rs | 12 ++++++------ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/w3f-plonk-common/src/lib.rs b/w3f-plonk-common/src/lib.rs index 78a232d..9167cd9 100644 --- a/w3f-plonk-common/src/lib.rs +++ b/w3f-plonk-common/src/lib.rs @@ -14,10 +14,10 @@ pub mod gadgets; pub mod kzg_acc; pub mod piop; pub mod prover; +mod q_chunking; pub mod test_helpers; pub mod transcript; pub mod verifier; -mod q_chunking; pub trait Column { fn domain(&self) -> GeneralEvaluationDomain; diff --git a/w3f-plonk-common/src/piop.rs b/w3f-plonk-common/src/piop.rs index ecb3019..d0f693f 100644 --- a/w3f-plonk-common/src/piop.rs +++ b/w3f-plonk-common/src/piop.rs @@ -33,7 +33,7 @@ pub trait ProverPiop> { fn constraints(&self) -> Vec>; fn quotient_chunks(&self, alphas: &[F]) -> Option>> { - self.compute_quotient(alphas).map(|q|vec![q]) + self.compute_quotient(alphas).map(|q| vec![q]) } fn compute_quotient(&self, alphas: &[F]) -> Option> { diff --git a/w3f-plonk-common/src/prover.rs b/w3f-plonk-common/src/prover.rs index dcbc6ce..af73118 100644 --- a/w3f-plonk-common/src/prover.rs +++ b/w3f-plonk-common/src/prover.rs @@ -73,10 +73,12 @@ impl, T: PlonkTranscript> PlonkProver let alphas = transcript.get_constraints_aggregation_coeffs(P::N_CONSTRAINTS); let quotient_chunks = piop.quotient_chunks(&alphas).unwrap(); let t_commit_q = start_timer!(|| format!( - "Committing to {} degree-{} quotient chunks", quotient_chunks.len(), + "Committing to {} degree-{} quotient chunks", + quotient_chunks.len(), quotient_chunks[0].degree() )); - let quotient_chunks_committed: Vec<_> = quotient_chunks.iter() + let quotient_chunks_committed: Vec<_> = quotient_chunks + .iter() .map(|qi| CS::commit(&self.pcs_ck, qi).unwrap()) .collect(); for qi_committed in quotient_chunks_committed.iter() { diff --git a/w3f-plonk-common/src/q_chunking.rs b/w3f-plonk-common/src/q_chunking.rs index 33623a2..32e099c 100644 --- a/w3f-plonk-common/src/q_chunking.rs +++ b/w3f-plonk-common/src/q_chunking.rs @@ -1,6 +1,6 @@ use ark_ff::{Field, PrimeField}; -use ark_poly::DenseUVPolynomial; use ark_poly::univariate::DensePolynomial; +use ark_poly::DenseUVPolynomial; use w3f_pcs::pcs::Commitment; use w3f_pcs::utils; @@ -12,7 +12,8 @@ fn chunk_quotient(q: DensePolynomial, n: usize) -> Vec(chunks: &[DensePolynomial], z_to_n: F) -> DensePolynomial { - chunks.iter() + chunks + .iter() .zip(utils::powers(z_to_n)) .map(|(chunk, coeff)| chunk * coeff) .reduce(|acc, new| acc + new) @@ -20,13 +21,12 @@ fn fold_quotient_chunks(chunks: &[DensePolynomial], z_to_n: F) -> D } fn quotient_commitment>(chunks: &[C], z_to_n: F) -> C { - chunks.iter() + chunks + .iter() .zip(utils::powers(z_to_n)) .map(|(chunk, coeff)| chunk.mul(coeff)) .sum() } #[cfg(test)] -mod tests { - -} \ No newline at end of file +mod tests {} From 376fd917f604a7174c2a88b8636ac3edb5fb0cdb Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 23:43:24 +0300 Subject: [PATCH 03/17] pub q_chunking --- w3f-plonk-common/src/lib.rs | 2 +- w3f-plonk-common/src/q_chunking.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/w3f-plonk-common/src/lib.rs b/w3f-plonk-common/src/lib.rs index 9167cd9..8e22961 100644 --- a/w3f-plonk-common/src/lib.rs +++ b/w3f-plonk-common/src/lib.rs @@ -14,7 +14,7 @@ pub mod gadgets; pub mod kzg_acc; pub mod piop; pub mod prover; -mod q_chunking; +pub mod q_chunking; pub mod test_helpers; pub mod transcript; pub mod verifier; diff --git a/w3f-plonk-common/src/q_chunking.rs b/w3f-plonk-common/src/q_chunking.rs index 32e099c..1b5243f 100644 --- a/w3f-plonk-common/src/q_chunking.rs +++ b/w3f-plonk-common/src/q_chunking.rs @@ -4,14 +4,14 @@ use ark_poly::DenseUVPolynomial; use w3f_pcs::pcs::Commitment; use w3f_pcs::utils; -fn chunk_quotient(q: DensePolynomial, n: usize) -> Vec> { +pub fn chunk_quotient(q: DensePolynomial, n: usize) -> Vec> { q.coeffs .chunks(n) .map(|coeffs| DensePolynomial::from_coefficients_slice(coeffs)) .collect() } -fn fold_quotient_chunks(chunks: &[DensePolynomial], z_to_n: F) -> DensePolynomial { +pub fn fold_quotient_chunks(chunks: &[DensePolynomial], z_to_n: F) -> DensePolynomial { chunks .iter() .zip(utils::powers(z_to_n)) @@ -20,7 +20,7 @@ fn fold_quotient_chunks(chunks: &[DensePolynomial], z_to_n: F) -> D .unwrap() } -fn quotient_commitment>(chunks: &[C], z_to_n: F) -> C { +pub fn compose_quotient>(chunks: &[C], z_to_n: F) -> C { chunks .iter() .zip(utils::powers(z_to_n)) From ba9a06f159f995e5c5d612949df321523c7be05e Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 23:44:42 +0300 Subject: [PATCH 04/17] chunking integrated --- w3f-plonk-common/src/domain.rs | 2 ++ w3f-plonk-common/src/prover.rs | 6 ++++-- w3f-plonk-common/src/verifier.rs | 8 ++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/w3f-plonk-common/src/domain.rs b/w3f-plonk-common/src/domain.rs index b7858f6..0114e3b 100644 --- a/w3f-plonk-common/src/domain.rs +++ b/w3f-plonk-common/src/domain.rs @@ -205,6 +205,7 @@ pub struct EvaluatedDomain { pub l_first: F, pub l_last: F, pub vanishing_polynomial_inv: F, + pub z_n: F, // z^N } impl EvaluatedDomain { @@ -243,6 +244,7 @@ impl EvaluatedDomain { l_first, l_last, vanishing_polynomial_inv, + z_n, } } diff --git a/w3f-plonk-common/src/prover.rs b/w3f-plonk-common/src/prover.rs index af73118..33e4430 100644 --- a/w3f-plonk-common/src/prover.rs +++ b/w3f-plonk-common/src/prover.rs @@ -11,7 +11,7 @@ use w3f_pcs::pcs::PCS; use crate::piop::ProverPiop; use crate::transcript::PlonkTranscript; -use crate::{PiopProof, Proof}; +use crate::{q_chunking, PiopProof, Proof}; pub struct PlonkProver, T: PlonkTranscript> { // Polynomial commitment scheme committer's key. @@ -92,6 +92,8 @@ impl, T: PlonkTranscript> PlonkProver // ROUND 3 let zeta = transcript.get_evaluation_point(); + let z_n = zeta.pow([piop.domain().domain_size() as u64]); + let q_folded = q_chunking::fold_quotient_chunks("ient_chunks, z_n); let columns_to_open = piop.columns(); let columns_at_zeta = piop.columns_evaluated(&zeta); let constraint_polys_linearized = piop.constraints_lin(&zeta); @@ -106,7 +108,7 @@ impl, T: PlonkTranscript> PlonkProver columns_at_zeta, lin_at_zeta_omega, }; - let polys_at_zeta = [columns_to_open, quotient_chunks].concat(); + let polys_at_zeta = [columns_to_open, vec![q_folded]].concat(); let pcs_openings = PcsOpeningAt2Points { polys_at_zeta, polys_at_zeta_omega: vec![lin], diff --git a/w3f-plonk-common/src/verifier.rs b/w3f-plonk-common/src/verifier.rs index 14e9edf..b91da46 100644 --- a/w3f-plonk-common/src/verifier.rs +++ b/w3f-plonk-common/src/verifier.rs @@ -6,7 +6,7 @@ use w3f_pcs::pcs::{Commitment, PcsParams, PCS}; use crate::piop::VerifierPiop; use crate::transcript::PlonkTranscript; -use crate::{ColumnsCommited, ColumnsEvaluated, PiopProof, Proof}; +use crate::{q_chunking, ColumnsCommited, ColumnsEvaluated, PiopProof, Proof}; pub struct PlonkVerifier, T: PlonkTranscript> { // Polynomial commitment scheme verifier's key. @@ -53,7 +53,11 @@ impl, T: PlonkTranscript> PlonkVerifier Date: Sun, 31 May 2026 23:54:17 +0300 Subject: [PATCH 05/17] chunking supported by piop --- w3f-plonk-common/src/piop.rs | 26 ++++++++++++++++++++------ w3f-plonk-common/src/prover.rs | 2 +- w3f-plonk-common/src/q_chunking.rs | 5 ++++- w3f-plonk-common/src/verifier.rs | 3 ++- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/w3f-plonk-common/src/piop.rs b/w3f-plonk-common/src/piop.rs index d0f693f..727f67c 100644 --- a/w3f-plonk-common/src/piop.rs +++ b/w3f-plonk-common/src/piop.rs @@ -1,13 +1,13 @@ +use crate::domain::{Domain, EvaluatedDomain}; +use crate::{q_chunking, ColumnsCommited, ColumnsEvaluated}; use ark_ff::{FftField, PrimeField}; use ark_poly::univariate::DensePolynomial; use ark_poly::Evaluations; +use ark_poly::Polynomial; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::vec::Vec; use w3f_pcs::pcs::Commitment; -use crate::domain::{Domain, EvaluatedDomain}; -use crate::{ColumnsCommited, ColumnsEvaluated}; - pub trait ProverPiop> { const N_COLUMNS: usize; const N_CONSTRAINTS: usize; @@ -32,11 +32,25 @@ pub trait ProverPiop> { // Constraint polynomials in evaluation form. fn constraints(&self) -> Vec>; - fn quotient_chunks(&self, alphas: &[F]) -> Option>> { - self.compute_quotient(alphas).map(|q| vec![q]) + fn _quotient_chunks(&self, alphas: &[F]) -> Option>> { + let q = Self::_compute_quotient(self, alphas); + q.map(|q| { + let q_deg = q.degree(); + let q_chunks = q_chunking::chunk_quotient(q, self.domain().domain_size()); + println!( + "Chunking deg {} polynomial into {} chunks", + q_deg, + q_chunks.len() + ); + q_chunks + }) + } + + fn quotient(&self, alphas: &[F]) -> Option>> { + self._compute_quotient(alphas).map(|q| vec![q]) } - fn compute_quotient(&self, alphas: &[F]) -> Option> { + fn _compute_quotient(&self, alphas: &[F]) -> Option> { let constraints = self.constraints(); // Aggregate constraint polynomials in evaluation form... let agg_constraint = aggregate_evaluations(&constraints, &alphas); diff --git a/w3f-plonk-common/src/prover.rs b/w3f-plonk-common/src/prover.rs index 33e4430..ba923e4 100644 --- a/w3f-plonk-common/src/prover.rs +++ b/w3f-plonk-common/src/prover.rs @@ -71,7 +71,7 @@ impl, T: PlonkTranscript> PlonkProver // ROUND 2 // The prover commits to the quotient polynomial... let alphas = transcript.get_constraints_aggregation_coeffs(P::N_CONSTRAINTS); - let quotient_chunks = piop.quotient_chunks(&alphas).unwrap(); + let quotient_chunks = piop.quotient(&alphas).unwrap(); let t_commit_q = start_timer!(|| format!( "Committing to {} degree-{} quotient chunks", quotient_chunks.len(), diff --git a/w3f-plonk-common/src/q_chunking.rs b/w3f-plonk-common/src/q_chunking.rs index 1b5243f..23ac8ef 100644 --- a/w3f-plonk-common/src/q_chunking.rs +++ b/w3f-plonk-common/src/q_chunking.rs @@ -11,7 +11,10 @@ pub fn chunk_quotient(q: DensePolynomial, n: usize) -> Vec(chunks: &[DensePolynomial], z_to_n: F) -> DensePolynomial { +pub fn fold_quotient_chunks( + chunks: &[DensePolynomial], + z_to_n: F, +) -> DensePolynomial { chunks .iter() .zip(utils::powers(z_to_n)) diff --git a/w3f-plonk-common/src/verifier.rs b/w3f-plonk-common/src/verifier.rs index b91da46..187f47e 100644 --- a/w3f-plonk-common/src/verifier.rs +++ b/w3f-plonk-common/src/verifier.rs @@ -56,7 +56,8 @@ impl, T: PlonkTranscript> PlonkVerifier Date: Sun, 31 May 2026 23:54:36 +0300 Subject: [PATCH 06/17] chunking implemented for pasta-tree --- pasta-tree/src/circuit_fat/prover.rs | 4 ++++ pasta-tree/src/circuit_tall/prover.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index a5aa88a..97b2d21 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -166,6 +166,10 @@ impl> type Evaluations = ProofEvals; type Instance = G; + fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { + >>::_quotient_chunks(self, alphas) + } + fn committed_columns) -> WrappedAffine>( &self, commit: Fun, diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index 4ac3b60..c045dc9 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -107,6 +107,10 @@ impl> type Evaluations = ProofEvals; type Instance = G; + fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { + >>::_quotient_chunks(self, alphas) + } + fn committed_columns) -> WrappedAffine>( &self, commit: Fun, From 68e850595e15c417940000e2bdab4e450c251b6a Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sun, 31 May 2026 23:54:48 +0300 Subject: [PATCH 07/17] tests --- pasta-tree/src/lib.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index b9353a4..b579f29 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -243,6 +243,26 @@ mod tests { } } + #[test] + fn test_circuit_tall() { + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsTall, + CircuitParamsTall, + >(9, 2); + } + + #[test] + fn test_circuit_fat() { + _test_proof::< + ark_pallas::Projective, + ark_vesta::Projective, + CircuitParamsFat, + CircuitParamsFat, + >(8, 4); + } + // 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] From f5ca67106f88d9807aaab87a4cea79c63579a401 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Mon, 1 Jun 2026 00:12:28 +0300 Subject: [PATCH 08/17] kzg_acc supports chunking --- w3f-plonk-common/src/kzg_acc.rs | 20 +++++++++++++++----- w3f-plonk-common/src/q_chunking.rs | 8 ++++++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/w3f-plonk-common/src/kzg_acc.rs b/w3f-plonk-common/src/kzg_acc.rs index 0b7bbeb..306cb4c 100644 --- a/w3f-plonk-common/src/kzg_acc.rs +++ b/w3f-plonk-common/src/kzg_acc.rs @@ -1,6 +1,6 @@ use crate::piop::VerifierPiop; use crate::verifier::Challenges; -use crate::{ColumnsCommited, ColumnsEvaluated, Proof}; +use crate::{q_chunking, ColumnsCommited, ColumnsEvaluated, Proof}; use ark_ec::pairing::Pairing; use ark_ec::{CurveGroup, VariableBaseMSM}; use ark_ff::{PrimeField, Zero}; @@ -93,8 +93,8 @@ impl KzgAccumulator { let zeta_omega = zeta * piop.domain_evaluated().omega(); let lin_comm = piop.lin_poly_commitment(&challenges.alphas); - // Openning at `z` - // TODO: try to get rid of the commitment wrapper in flonk + // Openning at `z`. Columns and the quotient are aggregated using `nu`s. + let mut r_nus = challenges.nus.iter().map(|nu| r * nu); self.acc_points.extend( piop.precommitted_columns() .iter() @@ -109,9 +109,19 @@ impl KzgAccumulator { .map(|c| c.0) .collect::>(), ); - self.acc_points.push(proof.quotient_commitment.clone().0); self.acc_scalars - .extend(challenges.nus.iter().map(|nu| *nu * r).collect::>()); // numbers should match here + .extend(r_nus.by_ref().take(Piop::N_COLUMNS)); + + // quotient (chunks) at `z` + let r_nu_last = r_nus.next().unwrap(); + let z_n = piop.domain_evaluated().z_n; + self.acc_points + .extend(proof.quotient_chunks.iter().map(|c| c.0)); + self.acc_scalars.extend( + q_chunking::chunk_coeffs(z_n) + .map(|c| r_nu_last * c) + .take(proof.quotient_chunks.len()), + ); self.acc_points.push(proof.agg_at_zeta_proof); self.acc_scalars.push(zeta * r); diff --git a/w3f-plonk-common/src/q_chunking.rs b/w3f-plonk-common/src/q_chunking.rs index 23ac8ef..ee71d6f 100644 --- a/w3f-plonk-common/src/q_chunking.rs +++ b/w3f-plonk-common/src/q_chunking.rs @@ -11,13 +11,17 @@ pub fn chunk_quotient(q: DensePolynomial, n: usize) -> Vec(z_to_n: F) -> impl Iterator { + utils::powers(z_to_n) +} + pub fn fold_quotient_chunks( chunks: &[DensePolynomial], z_to_n: F, ) -> DensePolynomial { chunks .iter() - .zip(utils::powers(z_to_n)) + .zip(chunk_coeffs(z_to_n)) .map(|(chunk, coeff)| chunk * coeff) .reduce(|acc, new| acc + new) .unwrap() @@ -26,7 +30,7 @@ pub fn fold_quotient_chunks( pub fn compose_quotient>(chunks: &[C], z_to_n: F) -> C { chunks .iter() - .zip(utils::powers(z_to_n)) + .zip(chunk_coeffs(z_to_n)) .map(|(chunk, coeff)| chunk.mul(coeff)) .sum() } From f941cdc5b6ca813217138653cca7f717347b3ad7 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Mon, 1 Jun 2026 01:05:19 +0300 Subject: [PATCH 09/17] chunk sizes asserted --- pasta-tree/src/circuit_fat/prover.rs | 7 ++++++- pasta-tree/src/circuit_tall/prover.rs | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index 97b2d21..3e5ad95 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -7,6 +7,7 @@ use ark_ec::CurveGroup; use ark_ff::One; use ark_ff::{FftField, PrimeField, Zero}; use ark_poly::Evaluations; +use ark_poly::Polynomial; use ark_poly::univariate::DensePolynomial; use ark_std::{vec, vec::Vec}; use w3f_pcs::pcs::commitment::WrappedAffine; @@ -167,7 +168,11 @@ impl> type Instance = G; fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { - >>::_quotient_chunks(self, alphas) + let chunks = + >>::_quotient_chunks(self, alphas); + debug_assert_eq!(chunks.as_ref().unwrap().len(), 4); + debug_assert_eq!(chunks.as_ref().unwrap()[3].degree(), 0); + chunks } fn committed_columns) -> WrappedAffine>( diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index c045dc9..c5faca8 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -108,7 +108,11 @@ impl> type Instance = G; fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { - >>::_quotient_chunks(self, alphas) + let chunks = + >>::_quotient_chunks(self, alphas); + debug_assert_eq!(chunks.as_ref().unwrap().len(), 4); + debug_assert_eq!(chunks.as_ref().unwrap()[3].degree(), 0); + chunks } fn committed_columns) -> WrappedAffine>( From e6ba1ef2ccabb6a710a44eb0447701727b2ce704 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Mon, 1 Jun 2026 01:12:12 +0300 Subject: [PATCH 10/17] pretty-print --- pasta-tree/src/lib.rs | 46 ++++++++++++++++----------------- pasta-tree/src/prover.rs | 52 ++++++++++++++++++++------------------ pasta-tree/src/verifier.rs | 41 +++++++++++++++++------------- 3 files changed, 74 insertions(+), 65 deletions(-) diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index b579f29..1c11f44 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -260,11 +260,11 @@ mod tests { ark_vesta::Projective, CircuitParamsFat, CircuitParamsFat, - >(8, 4); + >(8, 2); } - // 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 + // cargo test test_bench_curve_tree --release --features="print-trace" -- --show-output --ignored + // cargo test test_bench_curve_tree --release --features="print-trace parallel" -- --show-output --ignored #[test] #[ignore] fn test_bench_curve_tree() { @@ -278,25 +278,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); @@ -308,7 +308,7 @@ mod tests { >(log_n, h); println!(); - let (log_n, h) = (9, 4); + let (log_n, h) = (10, 4); println!("n = {}, height = {h}, TALL", 1 << log_n); _test_proof::< ark_pallas::Projective, diff --git a/pasta-tree/src/prover.rs b/pasta-tree/src/prover.rs index 1095d77..69fdae9 100644 --- a/pasta-tree/src/prover.rs +++ b/pasta-tree/src/prover.rs @@ -56,15 +56,22 @@ impl, P: CircuitParams< witness: Vec>, rng: &mut R, ) -> CycleSideProof { - let curve_name = &std::any::type_name::()[70..]; + 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); - debug_assert_eq!(blinded_path.len(), witness.len()); - 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); - let mut bfs = Vec::with_capacity(witness.len() * n_polys); + // per tree level + let n_columns = P::VerifierCircuit::N_COLUMNS; + let n_to_commit = n_columns + 4; // plus the quotient chunks + let n_to_open = 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 with_bfs = Vec::with_capacity(n_openings); let plonk_prover = PlonkProver::, _>::init( self.pcs_params.ck(), @@ -73,11 +80,10 @@ impl, P: CircuitParams< ); let t_commit_side = start_timer!(|| format!( - "Committing to {} polynomials at {curve_name}", - witness.len() * (n_polys - 1) + "Committing {n_levels} x {n_to_commit} polynomials to {curve_name}" )); 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 t_commit_level = start_timer!(|| format!("Committing {n_to_commit} polynomials")); let piop: P::ProverCircuit =

>::prover_circuit(&self.piop_params, level.clone()); let result = @@ -98,31 +104,29 @@ impl, P: CircuitParams< // polys_at_zeta[polys_at_zeta.len() - 1].evaluate(&zeta) // ); - coords.extend(vec![BTreeSet::from([zeta]); polys_at_zeta.len()]); - polys.extend(polys_at_zeta); - coords.extend(vec![ + at_coords.extend(vec![BTreeSet::from([zeta]); polys_at_zeta.len()]); + polys_to_open.extend(polys_at_zeta); + at_coords.extend(vec![ BTreeSet::from([zeta_omega]); polys_at_zeta_omega.len() ]); - polys.extend(polys_at_zeta_omega); - bfs.push(level.parent_bf); - bfs.resize(polys.len(), C::ScalarField::zero()); - end_timer!(t_commit_level); + polys_to_open.extend(polys_at_zeta_omega); + with_bfs.push(level.parent_bf); + with_bfs.resize(polys_to_open.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!( - "Opening {} polynomials with maximal degree-{}", - polys.len(), - max_degree + "Opening {n_openings} 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, - &bfs, - &coords, + &polys_to_open, + &with_bfs, + &at_coords, &mut todo.clone(), rng, ); diff --git a/pasta-tree/src/verifier.rs b/pasta-tree/src/verifier.rs index 33419bd..7072530 100644 --- a/pasta-tree/src/verifier.rs +++ b/pasta-tree/src/verifier.rs @@ -48,21 +48,26 @@ impl, P: CircuitParams< 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 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"), ); - 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: precompute let fixed_cols = self.commit_fixed_columns(); @@ -99,21 +104,21 @@ impl, P: CircuitParams< // vals_at_zeta[vals_at_zeta.len() - 1] // ); - coords.extend(vec![vec![zeta]; open_at_zeta.len()]); - polys.extend(open_at_zeta); - coords.extend(vec![vec![zeta_omega]; open_at_zeta_omega.len()]); - polys.extend(open_at_zeta_omega); - vals.extend(vals_at_zeta.into_iter().map(|v| vec![v])); - vals.extend(vals_at_zeta_omega.into_iter().map(|v| vec![v])); + at_coords.extend(vec![vec![zeta]; open_at_zeta.len()]); + polys_to_open.extend(open_at_zeta); + at_coords.extend(vec![vec![zeta_omega]; open_at_zeta_omega.len()]); + polys_to_open.extend(open_at_zeta_omega); + to_values.extend(vals_at_zeta.into_iter().map(|v| vec![v])); + to_values.extend(vals_at_zeta_omega.into_iter().map(|v| vec![v])); } let mut todo = side_proof.todo; let valid = Shplonk::>::verify_many( &self.pcs_params.vk(), - &polys, + &polys_to_open, side_proof.pcs_proof, - &coords, - &vals, + &at_coords, + &to_values, &mut todo, ); valid From 9b5df48e612f2e1ad13639c9aa25203daf6d6026 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Mon, 1 Jun 2026 23:06:06 +0300 Subject: [PATCH 11/17] no-std fixes --- Cargo.toml | 4 ++-- w3f-plonk-common/src/piop.rs | 6 ++++-- w3f-plonk-common/src/q_chunking.rs | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bf87c71..eb2d201 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,8 +15,8 @@ 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.6", default-features = false } -#w3f-pcs = { path = "../fflonk", default-features = false } -w3f-pcs = { version = "0.0.6", git = "https://github.com/paritytech/fflonk/", branch = "ipa-pcs", default-features = false } +w3f-pcs = { path = "../fflonk", 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.7", default-features = false } w3f-plonk-common = { path = "w3f-plonk-common", default-features = false } rayon = { version = "1", default-features = false } diff --git a/w3f-plonk-common/src/piop.rs b/w3f-plonk-common/src/piop.rs index 727f67c..c3bc3e0 100644 --- a/w3f-plonk-common/src/piop.rs +++ b/w3f-plonk-common/src/piop.rs @@ -5,6 +5,7 @@ use ark_poly::univariate::DensePolynomial; use ark_poly::Evaluations; use ark_poly::Polynomial; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::vec; use ark_std::vec::Vec; use w3f_pcs::pcs::Commitment; @@ -35,11 +36,12 @@ pub trait ProverPiop> { fn _quotient_chunks(&self, alphas: &[F]) -> Option>> { let q = Self::_compute_quotient(self, alphas); q.map(|q| { - let q_deg = q.degree(); + let _q_deg = q.degree(); let q_chunks = q_chunking::chunk_quotient(q, self.domain().domain_size()); + #[cfg(feature = "std")] println!( "Chunking deg {} polynomial into {} chunks", - q_deg, + _q_deg, q_chunks.len() ); q_chunks diff --git a/w3f-plonk-common/src/q_chunking.rs b/w3f-plonk-common/src/q_chunking.rs index ee71d6f..31c9e3f 100644 --- a/w3f-plonk-common/src/q_chunking.rs +++ b/w3f-plonk-common/src/q_chunking.rs @@ -1,6 +1,7 @@ use ark_ff::{Field, PrimeField}; use ark_poly::univariate::DensePolynomial; use ark_poly::DenseUVPolynomial; +use ark_std::vec::Vec; use w3f_pcs::pcs::Commitment; use w3f_pcs::utils; From 0f73d2822ede2bdeb7a4c02139cb8239627ee359 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Mon, 1 Jun 2026 23:11:49 +0300 Subject: [PATCH 12/17] Cargo.toml restored --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eb2d201..bf87c71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,8 +15,8 @@ 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.6", default-features = false } -w3f-pcs = { path = "../fflonk", default-features = false } -#w3f-pcs = { version = "0.0.6", git = "https://github.com/paritytech/fflonk/", branch = "ipa-pcs", default-features = false } +#w3f-pcs = { path = "../fflonk", 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.7", default-features = false } w3f-plonk-common = { path = "w3f-plonk-common", default-features = false } rayon = { version = "1", default-features = false } From 3a8c5dff7ba74b21ede760aca1c65bafc24e1cbd Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Sat, 6 Jun 2026 00:39:22 +0300 Subject: [PATCH 13/17] local ZK_ROWS --- pasta-tree/src/circuit_fat/params.rs | 6 +++++- pasta-tree/src/circuit_tall/params.rs | 6 +++++- pasta-tree/src/lib.rs | 10 +++------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/pasta-tree/src/circuit_fat/params.rs b/pasta-tree/src/circuit_fat/params.rs index 5d8679d..a8a046f 100644 --- a/pasta-tree/src/circuit_fat/params.rs +++ b/pasta-tree/src/circuit_fat/params.rs @@ -13,6 +13,9 @@ use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; +// Hiding Pedersen commitment opened in `2` points. +pub const ZK_ROWS: usize = 3; + /// Plonk Interactive Oracle Proofs (PIOP) parameters. #[derive(Clone)] pub struct PiopParams> { @@ -74,7 +77,8 @@ impl> CircuitParams, h: G, _seed: G) -> Self { + fn setup(domain_size: usize, h: G, _seed: G) -> Self { + let domain = Domain::::with_zk_rows(domain_size, ZK_ROWS); Self::setup(domain, h) } } diff --git a/pasta-tree/src/circuit_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index faa0c0c..776f4ce 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -13,6 +13,9 @@ use w3f_plonk_common::domain::Domain; use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; +// Hiding Pedersen commitment opened in `2` points. +pub const ZK_ROWS: usize = 3; + // `max_nodes + blinding_bits = domain.capacity - 1` // where `1` acounts for the `seed` point. /// Circuit parameters @@ -94,7 +97,8 @@ impl> CircuitParams, h: G, seed: G) -> Self { + fn setup(domain_size: usize, h: G, seed: G) -> Self { + let domain = Domain::::with_zk_rows(domain_size, ZK_ROWS); Self::setup(domain, h, seed) } } diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index 8c0d8c8..d766eae 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -10,8 +10,6 @@ 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}; @@ -58,7 +56,7 @@ pub trait CircuitParams #[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; + fn setup(domain_size: usize, h: G, seed: G) -> Self; } pub struct CycleSideParams< @@ -224,10 +222,8 @@ mod tests { 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::::with_zk_rows(domain_size, 3); - let c0_piop_params = P0::setup(c0_domain, c1_pcs_params.h, C1::Affine::rand(rng)); - let c1_domain = Domain::::with_zk_rows(domain_size, 3); - let c1_piop_params = P1::setup(c1_domain, c0_pcs_params.h, C0::Affine::rand(rng)); + let c0_piop_params = P0::setup(domain_size, c1_pcs_params.h, C1::Affine::rand(rng)); + let c1_piop_params = P1::setup(domain_size, c0_pcs_params.h, C0::Affine::rand(rng)); Self { c0_params: CycleSideParams { pcs_params: c0_pcs_params, From e6a2765eb437deb7b5021ed7a5d6a0982c7bda0b Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 9 Jun 2026 11:28:25 +0300 Subject: [PATCH 14/17] postmerge --- pasta-tree/src/lib.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pasta-tree/src/lib.rs b/pasta-tree/src/lib.rs index ffa7b9b..c86a00f 100644 --- a/pasta-tree/src/lib.rs +++ b/pasta-tree/src/lib.rs @@ -232,8 +232,10 @@ mod tests { 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 = P0::setup(domain_size, c1_pcs_params.h, AffinePoint::::rand(rng)); - let c1_piop_params = P1::setup(domain_size, c0_pcs_params.h, AffinePoint::::rand(rng)); + let c0_piop_params = + P0::setup(domain_size, c1_pcs_params.h, AffinePoint::::rand(rng)); + let c1_piop_params = + P1::setup(domain_size, c0_pcs_params.h, AffinePoint::::rand(rng)); Self { c0_params: CycleSideParams { pcs_params: c0_pcs_params, @@ -252,8 +254,8 @@ mod tests { #[test] fn test_circuit_tall() { _test_proof::< - ark_pallas::Projective, - ark_vesta::Projective, + PallasConfig, + VestaConfig, CircuitParamsTall, CircuitParamsTall, >(9, 2); @@ -262,8 +264,8 @@ mod tests { #[test] fn test_circuit_fat() { _test_proof::< - ark_pallas::Projective, - ark_vesta::Projective, + PallasConfig, + VestaConfig, CircuitParamsFat, CircuitParamsFat, >(8, 2); From f9fbe1c2ff1cd52be85b2966368380b5e356bdc9 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 9 Jun 2026 11:43:36 +0300 Subject: [PATCH 15/17] method order --- pasta-tree/src/circuit_fat/prover.rs | 16 ++++++++-------- pasta-tree/src/circuit_tall/prover.rs | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index 1cdef22..60e1d7c 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -171,14 +171,6 @@ impl> type Evaluations = ProofEvals; type Instance = AffinePoint; - fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { - let chunks = - >>::_quotient_chunks(self, alphas); - debug_assert_eq!(chunks.as_ref().unwrap().len(), 4); - debug_assert_eq!(chunks.as_ref().unwrap()[3].degree(), 0); - chunks - } - fn committed_columns) -> WrappedAffine>( &self, commit: Fun, @@ -238,6 +230,14 @@ impl> .concat() } + fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { + let chunks = + >>::_quotient_chunks(self, alphas); + debug_assert_eq!(chunks.as_ref().unwrap().len(), 4); + debug_assert_eq!(chunks.as_ref().unwrap()[3].degree(), 0); + chunks + } + fn constraints_lin(&self, zeta: &C::ScalarField) -> Vec> { vec![ self.selected_node.constraints_linearized(zeta), diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index 9c2cb4b..2694dad 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -110,14 +110,6 @@ impl> type Evaluations = ProofEvals; type Instance = AffinePoint; - fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { - let chunks = - >>::_quotient_chunks(self, alphas); - debug_assert_eq!(chunks.as_ref().unwrap().len(), 4); - debug_assert_eq!(chunks.as_ref().unwrap()[3].degree(), 0); - chunks - } - fn committed_columns) -> WrappedAffine>( &self, commit: Fun, @@ -170,6 +162,14 @@ impl> self.gadgets.iter().flat_map(|g| g.constraints()).collect() } + fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { + let chunks = + >>::_quotient_chunks(self, alphas); + debug_assert_eq!(chunks.as_ref().unwrap().len(), 4); + debug_assert_eq!(chunks.as_ref().unwrap()[3].degree(), 0); + chunks + } + fn constraints_lin(&self, zeta: &C::ScalarField) -> Vec> { self.gadgets .iter() From 57450d0e94a87079ca0083fcd2af91cb0a395eb2 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 9 Jun 2026 11:48:42 +0300 Subject: [PATCH 16/17] zk_rows = 2 --- pasta-tree/src/circuit_fat/params.rs | 2 +- pasta-tree/src/circuit_fat/prover.rs | 28 ++++++++++++--------------- pasta-tree/src/circuit_tall/params.rs | 2 +- pasta-tree/src/circuit_tall/prover.rs | 25 +++++------------------- w3f-plonk-common/src/piop.rs | 2 ++ 5 files changed, 21 insertions(+), 38 deletions(-) diff --git a/pasta-tree/src/circuit_fat/params.rs b/pasta-tree/src/circuit_fat/params.rs index 04e0564..879c559 100644 --- a/pasta-tree/src/circuit_fat/params.rs +++ b/pasta-tree/src/circuit_fat/params.rs @@ -14,7 +14,7 @@ use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; // Hiding Pedersen commitment opened in `2` points. -pub const ZK_ROWS: usize = 3; +pub const ZK_ROWS: usize = 2; /// Plonk Interactive Oracle Proofs (PIOP) parameters. #[derive(Clone)] diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index 60e1d7c..4031eaa 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -1,20 +1,16 @@ use crate::auth_path::node::LevelWitnessWithBlinding; use crate::circuit_fat::params::PiopParams; use crate::circuit_fat::{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; use ark_ff::{FftField, PrimeField, Zero}; -use ark_poly::Evaluations; -use ark_poly::Polynomial; 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; @@ -22,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, @@ -162,11 +160,13 @@ impl> PiopProver> { } } -impl> - ProverPiop> for PiopProver> +impl> +ProverPiop> for PiopProver> { const N_COLUMNS: usize = 9; const N_CONSTRAINTS: usize = 12; + const N_QUOTIENT_CHUNKS: usize = 3; + type Commitments = ProofComms; type Evaluations = ProofEvals; type Instance = AffinePoint; @@ -227,15 +227,11 @@ impl> C::ScalarField::one(), )], ] - .concat() + .concat() } fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { - let chunks = - >>::_quotient_chunks(self, alphas); - debug_assert_eq!(chunks.as_ref().unwrap().len(), 4); - debug_assert_eq!(chunks.as_ref().unwrap()[3].degree(), 0); - chunks + >>::_quotient_chunks(self, alphas) } fn constraints_lin(&self, zeta: &C::ScalarField) -> Vec> { @@ -253,7 +249,7 @@ impl> // vec![DensePolynomial::zero()], vec![DensePolynomial::zero()], ] - .concat() + .concat() } fn domain(&self) -> &Domain { @@ -271,7 +267,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_tall/params.rs b/pasta-tree/src/circuit_tall/params.rs index 613f75f..ac28082 100644 --- a/pasta-tree/src/circuit_tall/params.rs +++ b/pasta-tree/src/circuit_tall/params.rs @@ -14,7 +14,7 @@ use w3f_plonk_common::gadgets::booleanity::BitColumn; use w3f_plonk_common::gadgets::ec::AffineColumn; // Hiding Pedersen commitment opened in `2` points. -pub const ZK_ROWS: usize = 3; +pub const ZK_ROWS: usize = 2; // `max_nodes + blinding_bits = domain.capacity - 1` // where `1` acounts for the `seed` point. diff --git a/pasta-tree/src/circuit_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index 2694dad..a531b40 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -1,7 +1,6 @@ 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 crate::{AffinePoint, CurveModel}; use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::{FftField, One, Zero}; @@ -19,18 +18,6 @@ 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, @@ -101,11 +88,13 @@ impl> PiopProver> { } } -impl> - ProverPiop> for PiopProver> +impl> +ProverPiop> for PiopProver> { const N_COLUMNS: usize = 7; const N_CONSTRAINTS: usize = 7; + const N_QUOTIENT_CHUNKS: usize = 3; + type Commitments = ProofComms; type Evaluations = ProofEvals; type Instance = AffinePoint; @@ -163,11 +152,7 @@ impl> } fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { - let chunks = - >>::_quotient_chunks(self, alphas); - debug_assert_eq!(chunks.as_ref().unwrap().len(), 4); - debug_assert_eq!(chunks.as_ref().unwrap()[3].degree(), 0); - chunks + >>::_quotient_chunks(self, alphas) } fn constraints_lin(&self, zeta: &C::ScalarField) -> Vec> { diff --git a/w3f-plonk-common/src/piop.rs b/w3f-plonk-common/src/piop.rs index c3bc3e0..bc1b866 100644 --- a/w3f-plonk-common/src/piop.rs +++ b/w3f-plonk-common/src/piop.rs @@ -12,6 +12,7 @@ use w3f_pcs::pcs::Commitment; pub trait ProverPiop> { const N_COLUMNS: usize; const N_CONSTRAINTS: usize; + const N_QUOTIENT_CHUNKS: usize = 1; type Commitments: ColumnsCommited; type Evaluations: ColumnsEvaluated; @@ -38,6 +39,7 @@ pub trait ProverPiop> { q.map(|q| { let _q_deg = q.degree(); let q_chunks = q_chunking::chunk_quotient(q, self.domain().domain_size()); + debug_assert_eq!(q_chunks.len(), Self::N_QUOTIENT_CHUNKS); #[cfg(feature = "std")] println!( "Chunking deg {} polynomial into {} chunks", From 6e5b67c3e02226e9eb3659133f40fe68c9d59123 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 9 Jun 2026 11:49:05 +0300 Subject: [PATCH 17/17] fmt --- pasta-tree/src/circuit_fat/prover.rs | 16 ++++++++-------- pasta-tree/src/circuit_tall/prover.rs | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pasta-tree/src/circuit_fat/prover.rs b/pasta-tree/src/circuit_fat/prover.rs index 4031eaa..3ff3915 100644 --- a/pasta-tree/src/circuit_fat/prover.rs +++ b/pasta-tree/src/circuit_fat/prover.rs @@ -6,11 +6,13 @@ use ark_ec::AffineRepr; use ark_ec::CurveGroup; 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, @@ -160,8 +160,8 @@ impl> PiopProver> { } } -impl> -ProverPiop> for PiopProver> +impl> + ProverPiop> for PiopProver> { const N_COLUMNS: usize = 9; const N_CONSTRAINTS: usize = 12; @@ -227,7 +227,7 @@ ProverPiop> for PiopProver> C::ScalarField::one(), )], ] - .concat() + .concat() } fn quotient(&self, alphas: &[C::ScalarField]) -> Option>> { @@ -249,7 +249,7 @@ ProverPiop> for PiopProver> // vec![DensePolynomial::zero()], vec![DensePolynomial::zero()], ] - .concat() + .concat() } fn domain(&self) -> &Domain { @@ -267,7 +267,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_tall/prover.rs b/pasta-tree/src/circuit_tall/prover.rs index a531b40..c850288 100644 --- a/pasta-tree/src/circuit_tall/prover.rs +++ b/pasta-tree/src/circuit_tall/prover.rs @@ -88,8 +88,8 @@ impl> PiopProver> { } } -impl> -ProverPiop> for PiopProver> +impl> + ProverPiop> for PiopProver> { const N_COLUMNS: usize = 7; const N_CONSTRAINTS: usize = 7;