Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions w3f-plonk-common/src/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ pub struct EvaluatedDomain<F: FftField> {
pub l_first: F,
pub l_last: F,
pub vanishing_polynomial_inv: F,
pub z_n: F, // z^n
}

impl<F: FftField> EvaluatedDomain<F> {
Expand Down Expand Up @@ -224,6 +225,7 @@ impl<F: FftField> EvaluatedDomain<F> {
l_first,
l_last,
vanishing_polynomial_inv,
z_n,
}
}

Expand Down
12 changes: 10 additions & 2 deletions w3f-plonk-common/src/kzg_acc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,17 @@ impl<E: Pairing> KzgAccumulator<E> {
.map(|c| c.0)
.collect::<Vec<_>>(),
);
self.acc_points.push(proof.quotient_commitment.clone().0);
let mut r_nus = challenges.nus.iter().map(|nu| r * nu);
self.acc_scalars
.extend(challenges.nus.iter().map(|nu| *nu * r).collect::<Vec<_>>()); // numbers should match here
.extend(r_nus.by_ref().take(Piop::N_COLUMNS));
self.acc_points
.extend(proof.quotient_commitment.iter().map(|c| c.0));
let r_nu_last = r_nus.next().unwrap();
self.acc_scalars.extend(
piop.chunk_coeffs()
.map(|c| r_nu_last * c)
.take(proof.quotient_commitment.len()),
);

self.acc_points.push(proof.agg_at_zeta_proof);
self.acc_scalars.push(zeta * r);
Expand Down
4 changes: 2 additions & 2 deletions w3f-plonk-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ where
{
pub column_commitments: Commitments,
pub columns_at_zeta: Evaluations,
pub quotient_commitment: CS::C,
pub quotient_commitment: Vec<CS::C>,
pub lin_at_zeta_omega: F,
pub agg_at_zeta_proof: CS::Proof,
pub lin_at_zeta_omega_proof: CS::Proof,
Expand All @@ -120,7 +120,7 @@ where
{
pub column_commitments: Commitments,
pub columns_at_zeta: Evaluations,
pub quotient_commitment: C,
pub quotient_commitment: Vec<C>,
pub lin_at_zeta_omega: F,
}

Expand Down
73 changes: 68 additions & 5 deletions w3f-plonk-common/src/piop.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use ark_ff::PrimeField;
use crate::domain::{Domain, EvaluatedDomain};
use crate::{ColumnsCommited, ColumnsEvaluated};
use ark_ff::{FftField, PrimeField};
use ark_poly::univariate::DensePolynomial;
use ark_poly::Evaluations;
use ark_poly::{DenseUVPolynomial, EvaluationDomain, Evaluations};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::vec::Vec;
use w3f_pcs::pcs::Commitment;

use crate::domain::{Domain, EvaluatedDomain};
use crate::{ColumnsCommited, ColumnsEvaluated};
use w3f_pcs::utils;

pub trait ProverPiop<F: PrimeField, C: Commitment<F>> {
const N_CONSTRAINTS: usize;

type Commitments: ColumnsCommited<F, C>;
type Evaluations: ColumnsEvaluated<F>;
type Instance: CanonicalSerialize + CanonicalDeserialize;
Expand All @@ -29,6 +31,43 @@ pub trait ProverPiop<F: PrimeField, C: Commitment<F>> {
// Constraint polynomials in evaluation form.
fn constraints(&self) -> Vec<Evaluations<F>>;

fn quotient(&self, alphas: &[F]) -> DensePolynomial<F> {
let constraint_polys = self.constraints();
// Aggregate constraint polynomials in evaluation form...
let agg_constraint_poly = aggregate_evaluations(&constraint_polys, &alphas);
// ...and then interpolate (to save some FFTs).
let agg_constraint_poly = agg_constraint_poly.interpolate();
let quotient_poly = self.domain().divide_by_vanishing_poly(&agg_constraint_poly);
quotient_poly
}

fn split_quotient(&self, q: DensePolynomial<F>) -> Vec<DensePolynomial<F>> {
let n = self.domain().domains.x1.size();
let chunks: Vec<DensePolynomial<F>> = q
.coeffs
.chunks(n)
.map(|coeffs| DensePolynomial::from_coefficients_slice(coeffs))
.collect();
chunks
}

fn quotient_chunks(&self, alphas: &[F]) -> Vec<DensePolynomial<F>> {
let q = self.quotient(alphas);
self.split_quotient(q)
}

fn folded_quotient(&self, chunks: &[DensePolynomial<F>], zeta: F) -> DensePolynomial<F> {
let n = self.domain().domains.x1.size() as u64;
let zn = zeta.pow([n]);
let folded = chunks
.iter()
.zip(utils::powers(zn))
.map(|(chunk, coeff)| chunk * coeff)
.reduce(|acc, new| acc + new)
.unwrap();
folded
}

// 'Linearized' parts of constraint polynomials.
// For a constraint of the form C = C(c1(X),...,ck(X),c1(wX),...,ck(wX)), where ci's are of degree n,
// and an evaluation point z, it is a degree n polynomial r = C(c1(z),...,ck(z),c1(X),...,ck(X)).
Expand All @@ -41,6 +80,16 @@ pub trait ProverPiop<F: PrimeField, C: Commitment<F>> {
fn result(&self) -> Self::Instance;
}

fn aggregate_evaluations<F: FftField>(polys: &[Evaluations<F>], coeffs: &[F]) -> Evaluations<F> {
assert_eq!(coeffs.len(), polys.len());
polys
.iter()
.zip(coeffs.iter())
.map(|(p, &c)| p * c)
.reduce(|acc, p| &acc + &p)
.unwrap()
}

pub trait VerifierPiop<F: PrimeField, C: Commitment<F>> {
const N_CONSTRAINTS: usize;
const N_COLUMNS: usize;
Expand Down Expand Up @@ -71,5 +120,19 @@ pub trait VerifierPiop<F: PrimeField, C: Commitment<F>> {
// Commitment to the aggregated linearization polynomial without the constant term.
fn lin_poly_commitment(&self, agg_coeffs: &[F]) -> (Vec<F>, Vec<C>);

fn chunk_coeffs(&self) -> impl Iterator<Item = F> {
let zn = self.domain_evaluated().z_n;
utils::powers(zn)
}

fn quotient_commitment(&self, chunks: &[C]) -> C {
let quotient = chunks
.iter()
.zip(self.chunk_coeffs())
.map(|(chunk, coeff)| chunk.mul(coeff))
.sum();
quotient
}

fn domain_evaluated(&self) -> &EvaluatedDomain<F>;
}
38 changes: 14 additions & 24 deletions w3f-plonk-common/src/prover.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use ark_ff::PrimeField;
use ark_poly::univariate::DensePolynomial;
use ark_poly::{Evaluations, Polynomial};
use ark_poly::Polynomial;
use ark_serialize::CanonicalSerialize;
use ark_std::format;
use ark_std::vec::Vec;
use ark_std::{end_timer, start_timer, vec};

use w3f_pcs::aggregation::single::aggregate_polys;
use w3f_pcs::pcs::PCS;

Expand Down Expand Up @@ -62,21 +61,22 @@ impl<F: PrimeField, CS: PCS<F>, T: PlonkTranscript<F, CS>> PlonkProver<F, CS, T>
transcript.add_committed_cols(&column_commitments);

// ROUND 2
let constraint_polys = piop.constraints();
let alphas = transcript.get_constraints_aggregation_coeffs(constraint_polys.len());
// Aggregate constraint polynomials in evaluation form...
let agg_constraint_poly = Self::aggregate_evaluations(&constraint_polys, &alphas);
// ...and then interpolate (to save some FFTs).
let agg_constraint_poly = agg_constraint_poly.interpolate();
let quotient_poly = piop.domain().divide_by_vanishing_poly(&agg_constraint_poly);
let alphas = transcript.get_constraints_aggregation_coeffs(P::N_CONSTRAINTS);
// let quotient_poly = piop.quotient(&alphas);
// The prover commits to the quotient polynomial...
let quotient_commitment = CS::commit(&self.pcs_ck, &quotient_poly).unwrap();
transcript.add_quotient_commitment(&quotient_commitment);

let quotient_chunks = piop.quotient_chunks(&alphas);
let chunks_committed: Vec<_> = quotient_chunks
.iter()
.map(|qi| CS::commit(&self.pcs_ck, qi).unwrap())
.collect();
for qi_committed in chunks_committed.iter() {
transcript.add_quotient_commitment(&qi_committed);
}
// and receives the evaluation point in response

// ROUND 3
let zeta = transcript.get_evaluation_point();
let q_folded = piop.folded_quotient(&quotient_chunks, zeta);
let columns_to_open = piop.columns();
let columns_at_zeta = piop.columns_evaluated(&zeta);
let constraint_polys_linearized = piop.constraints_lin(&zeta);
Expand All @@ -87,11 +87,11 @@ impl<F: PrimeField, CS: PCS<F>, T: PlonkTranscript<F, CS>> PlonkProver<F, CS, T>
transcript.add_evaluations(&columns_at_zeta, &lin_at_zeta_omega);
let piop_proof = PiopProof {
column_commitments,
quotient_commitment,
quotient_commitment: 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, vec![q_folded]].concat();
let pcs_openings = PcsOpeningAt2Points {
polys_at_zeta,
polys_at_zeta_omega: vec![lin],
Expand Down Expand Up @@ -137,14 +137,4 @@ impl<F: PrimeField, CS: PCS<F>, T: PlonkTranscript<F, CS>> PlonkProver<F, CS, T>
lin_at_zeta_omega_proof,
}
}

pub fn aggregate_evaluations(polys: &[Evaluations<F>], coeffs: &[F]) -> Evaluations<F> {
assert_eq!(coeffs.len(), polys.len());
polys
.iter()
.zip(coeffs.iter())
.map(|(p, &c)| p * c)
.reduce(|acc, p| &acc + &p)
.unwrap()
}
}
6 changes: 4 additions & 2 deletions w3f-plonk-common/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl<F: PrimeField, CS: PCS<F>, T: PlonkTranscript<F, CS>> PlonkVerifier<F, CS,
{
let mut open_at_zeta = piop.precommitted_columns();
open_at_zeta.extend(proof.column_commitments.to_vec());
open_at_zeta.push(proof.quotient_commitment.clone());
open_at_zeta.push(piop.quotient_commitment(&proof.quotient_commitment));

let mut vals_at_zeta = proof.columns_at_zeta.to_vec();
let q_zeta = piop.evaluate_q_at_zeta(&challenges.alphas, proof.lin_at_zeta_omega);
Expand Down Expand Up @@ -134,7 +134,9 @@ impl<F: PrimeField, CS: PCS<F>, T: PlonkTranscript<F, CS>> PlonkVerifier<F, CS,
// let r = transcript.get_bitmask_aggregation_challenge();
// transcript.append_2nd_round_register_commitments(&proof.additional_commitments);
let alphas = transcript.get_constraints_aggregation_coeffs(n_constraints);
transcript.add_quotient_commitment(&proof.quotient_commitment);
for qi_committed in proof.quotient_commitment.iter() {
transcript.add_quotient_commitment(&qi_committed);
}
let zeta = transcript.get_evaluation_point();
transcript.add_evaluations(&proof.columns_at_zeta, &proof.lin_at_zeta_omega);
let nus = transcript.get_kzg_aggregation_challenges(n_polys);
Expand Down
2 changes: 1 addition & 1 deletion w3f-ring-proof/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ mod tests {
#[test]
// cargo test test_ring_proof_kzg --release --features="print-trace" -- --show-output
fn test_ring_proof_kzg() {
_test_ring_proof::<KZG<Bls12_381>>(2usize.pow(9), 1);
_test_ring_proof::<KZG<Bls12_381>>(2usize.pow(12), 1);
}

#[test]
Expand Down
4 changes: 4 additions & 0 deletions w3f-ring-proof/src/piop/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ where
C: Commitment<F>,
Curve: TECurveConfig<BaseField = F>,
{
const N_CONSTRAINTS: usize = 7;

type Commitments = RingCommitments<F, C>;
type Evaluations = RingEvaluations<F>;
type Instance = TeAffine<Curve>;
Expand Down Expand Up @@ -204,6 +206,8 @@ where
C: Commitment<F>,
Curve: SWCurveConfig<BaseField = F>,
{
const N_CONSTRAINTS: usize = 7;

type Commitments = RingCommitments<F, C>;
type Evaluations = RingEvaluations<F>;
type Instance = SwAffine<Curve>;
Expand Down
Loading