Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Introducing PCS codebase as a separate module #361

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions benches/common/supernova/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use halo2curves::bn256::Bn256;

pub type E1 = arecibo::provider::Bn256EngineKZG;
pub type E2 = arecibo::provider::GrumpkinEngine;
pub type EE1 = arecibo::provider::hyperkzg::EvaluationEngine<Bn256, E1>;
pub type EE2 = arecibo::provider::ipa_pc::EvaluationEngine<E2>;
pub type EE1 = arecibo::provider::pcs::hyperkzg::EvaluationEngine<Bn256, E1>;
pub type EE2 = arecibo::provider::pcs::ipa_pc::EvaluationEngine<E2>;
// SNARKs without computation commitments
pub type S1 = arecibo::spartan::batched::BatchedRelaxedR1CSSNARK<E1, EE1>;
pub type S2 = arecibo::spartan::snark::RelaxedR1CSSNARK<E2, EE2>;
Expand Down
4 changes: 2 additions & 2 deletions benches/compressed-snark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use common::{noise_threshold_env, BenchParams};

type E1 = Bn256EngineKZG;
type E2 = GrumpkinEngine;
type EE1 = arecibo::provider::hyperkzg::EvaluationEngine<Bn256, E1>;
type EE2 = arecibo::provider::ipa_pc::EvaluationEngine<E2>;
type EE1 = arecibo::provider::pcs::hyperkzg::EvaluationEngine<Bn256, E1>;
type EE2 = arecibo::provider::pcs::ipa_pc::EvaluationEngine<E2>;
// SNARKs without computation commitmnets
type S1 = arecibo::spartan::snark::RelaxedR1CSSNARK<E1, EE1>;
type S2 = arecibo::spartan::snark::RelaxedR1CSSNARK<E2, EE2>;
Expand Down
2 changes: 1 addition & 1 deletion benches/pcs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use arecibo::provider::{
use arecibo::provider::pcs::{
hyperkzg::EvaluationEngine as MLEvaluationEngine,
ipa_pc::EvaluationEngine as IPAEvaluationEngine, non_hiding_zeromorph::ZMPCS,
};
Expand Down
4 changes: 2 additions & 2 deletions examples/and.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ use std::time::Instant;

type E1 = Bn256EngineKZG;
type E2 = GrumpkinEngine;
type EE1 = arecibo::provider::hyperkzg::EvaluationEngine<Bn256, E1>;
type EE2 = arecibo::provider::ipa_pc::EvaluationEngine<E2>;
type EE1 = arecibo::provider::pcs::hyperkzg::EvaluationEngine<Bn256, E1>;
type EE2 = arecibo::provider::pcs::ipa_pc::EvaluationEngine<E2>;
type S1 = arecibo::spartan::snark::RelaxedR1CSSNARK<E1, EE1>; // non-preprocessing SNARK
type S2 = arecibo::spartan::snark::RelaxedR1CSSNARK<E2, EE2>; // non-preprocessing SNARK

Expand Down
4 changes: 2 additions & 2 deletions examples/hashchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use std::time::Instant;

type E1 = Bn256EngineKZG;
type E2 = GrumpkinEngine;
type EE1 = arecibo::provider::hyperkzg::EvaluationEngine<Bn256, E1>;
type EE2 = arecibo::provider::ipa_pc::EvaluationEngine<E2>;
type EE1 = arecibo::provider::pcs::hyperkzg::EvaluationEngine<Bn256, E1>;
type EE2 = arecibo::provider::pcs::ipa_pc::EvaluationEngine<E2>;
type S1 = arecibo::spartan::snark::RelaxedR1CSSNARK<E1, EE1>; // non-preprocessing SNARK
type S2 = arecibo::spartan::snark::RelaxedR1CSSNARK<E2, EE2>; // non-preprocessing SNARK

Expand Down
4 changes: 2 additions & 2 deletions examples/minroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ fn main() {
let start = Instant::now();
type E1 = Bn256EngineKZG;
type E2 = GrumpkinEngine;
type EE1 = arecibo::provider::hyperkzg::EvaluationEngine<Bn256, E1>;
type EE2 = arecibo::provider::ipa_pc::EvaluationEngine<E2>;
type EE1 = arecibo::provider::pcs::hyperkzg::EvaluationEngine<Bn256, E1>;
type EE2 = arecibo::provider::pcs::ipa_pc::EvaluationEngine<E2>;
type S1 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK<E1, EE1>; // preprocessing SNARK
type S2 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK<E2, EE2>; // preprocessing SNARK

Expand Down
16 changes: 8 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ where
///
/// ```rust
/// # use arecibo::spartan::ppsnark::RelaxedR1CSSNARK;
/// # use arecibo::provider::ipa_pc::EvaluationEngine;
/// # use arecibo::provider::pcs::ipa_pc::EvaluationEngine;
/// # use arecibo::provider::{PallasEngine, VestaEngine};
/// # use arecibo::traits::{circuit::TrivialCircuit, Engine, snark::RelaxedR1CSSNARKTrait};
/// use arecibo::PublicParams;
Expand Down Expand Up @@ -1022,8 +1022,8 @@ mod tests {
use super::*;
use crate::{
provider::{
non_hiding_zeromorph::ZMPCS, Bn256EngineIPA, Bn256EngineKZG, Bn256EngineZM, PallasEngine,
Secp256k1Engine,
pcs, pcs::non_hiding_zeromorph::ZMPCS, Bn256EngineIPA, Bn256EngineKZG, Bn256EngineZM,
PallasEngine, Secp256k1Engine,
},
traits::{evaluation::EvaluationEngineTrait, snark::default_ck_hint},
};
Expand All @@ -1034,7 +1034,7 @@ mod tests {
use halo2curves::bn256::Bn256;
use traits::circuit::TrivialCircuit;

type EE<E> = provider::ipa_pc::EvaluationEngine<E>;
type EE<E> = pcs::ipa_pc::EvaluationEngine<E>;
type S<E, EE> = spartan::snark::RelaxedR1CSSNARK<E, EE>;
type SPrime<E, EE> = spartan::ppsnark::RelaxedR1CSSNARK<E, EE>;

Expand Down Expand Up @@ -1375,7 +1375,7 @@ mod tests {
test_ivc_nontrivial_with_compression_with::<Bn256EngineZM, ZMPCS<Bn256, _>, EE<_>>();
test_ivc_nontrivial_with_compression_with::<
Bn256EngineKZG,
provider::hyperkzg::EvaluationEngine<Bn256, _>,
pcs::hyperkzg::EvaluationEngine<Bn256, _>,
EE<_>,
>();
}
Expand All @@ -1400,7 +1400,7 @@ mod tests {
test_ivc_nontrivial_with_spark_compression_with::<Bn256EngineZM, ZMPCS<Bn256, _>, EE<_>>();
test_ivc_nontrivial_with_spark_compression_with::<
Bn256EngineKZG,
provider::hyperkzg::EvaluationEngine<Bn256, _>,
pcs::hyperkzg::EvaluationEngine<Bn256, _>,
EE<_>,
>();
}
Expand Down Expand Up @@ -1429,7 +1429,7 @@ mod tests {
test_ivc_nontrivial_with_batched_compression_with::<Bn256EngineZM, ZMPCS<Bn256, _>, EE<_>>();
test_ivc_nontrivial_with_batched_compression_with::<
Bn256EngineKZG,
provider::hyperkzg::EvaluationEngine<Bn256, _>,
pcs::hyperkzg::EvaluationEngine<Bn256, _>,
EE<_>,
>();
}
Expand Down Expand Up @@ -1457,7 +1457,7 @@ mod tests {
);
test_ivc_nontrivial_with_batched_spark_compression_with::<
Bn256EngineKZG,
provider::hyperkzg::EvaluationEngine<Bn256, _>,
pcs::hyperkzg::EvaluationEngine<Bn256, _>,
EE<_>,
>();
}
Expand Down
13 changes: 4 additions & 9 deletions src/provider/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
//! This module implements Nova's traits using the following several different combinations

// public modules to be used as an evaluation engine with Spartan
pub mod hyperkzg;
pub mod ipa_pc;
pub mod non_hiding_zeromorph;
/// Schemes used as an evaluation engine (including non-hiding variants) with Spartan
pub mod pcs;

// crate-public modules, made crate-public mostly for tests
pub(crate) mod bn256_grumpkin;
mod pasta;
mod pedersen;
pub(crate) mod poseidon;
pub(crate) mod secp_secq;
pub(crate) mod traits;
// a non-hiding variant of {kzg, zeromorph}
mod kzg_commitment;
pub(crate) mod util;

// crate-private modules
Expand All @@ -24,7 +19,6 @@ use crate::{
provider::{
bn256_grumpkin::{bn256, grumpkin},
keccak::Keccak256Transcript,
pedersen::CommitmentEngine as PedersenCommitmentEngine,
poseidon::{PoseidonRO, PoseidonROCircuit},
secp_secq::{secp256k1, secq256k1},
},
Expand All @@ -33,7 +27,8 @@ use crate::{
use halo2curves::bn256::Bn256;
use pasta_curves::{pallas, vesta};

use self::kzg_commitment::KZGCommitmentEngine;
use pcs::kzg10_utilities::KZGCommitmentEngine;
use pcs::pedersen::CommitmentEngine as PedersenCommitmentEngine;

/// An implementation of the Nova `Engine` trait with Grumpkin curve and Pedersen commitment scheme
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
Expand Down
15 changes: 6 additions & 9 deletions src/provider/hyperkzg.rs → src/provider/pcs/hyperkzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
//! Compared to pure HyperKZG, this optimisation in theory improves prover (at cost of using 1 fixed KZG opening) and verifier (at cost of eliminating MSM)
//!
#![allow(non_snake_case)]
use crate::provider::pcs::kzg10_utilities::UVKZGPCS;
use crate::{
errors::NovaError,
provider::{
kzg_commitment::{KZGCommitmentEngine, KZGProverKey, KZGVerifierKey, UniversalKZGParam},
pedersen::Commitment,
pcs::kzg10_utilities::{KZGCommitmentEngine, KZGProverKey, KZGVerifierKey, UniversalKZGParam},
pcs::pedersen::Commitment,
traits::DlogGroup,
util::iterators::IndexedParallelIteratorExt as _,
},
Expand Down Expand Up @@ -196,7 +197,7 @@ where

fn prove(
ck: &UniversalKZGParam<E>,
_pk: &Self::ProverKey,
pk: &Self::ProverKey,
transcript: &mut <NE as NovaEngine>::TE,
_C: &Commitment<NE>,
hat_P: &[E::Fr],
Expand Down Expand Up @@ -237,18 +238,14 @@ where
// K(x) = P(x) - Q(x) * D(a) - R(a), note that R(a) should be subtracted from a free term of polynomial
let K_x = Self::compute_k_polynomial(&batched_Pi, &Q_x, &D, &R_x, a);

// TODO: since this is a usual KZG10 we should use it as utility instead
let h = K_x.divide_minus_u(a);
let C_H = <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &h.coeffs)
.comm
.to_affine();
let C_H = UVKZGPCS::<E>::open(pk, &K_x, &a).unwrap();

Ok(EvaluationArgument::<E> {
comms,
evals,
R_x: R_x.coeffs,
C_Q,
C_H,
C_H: C_H.opening,
})
}

Expand Down
5 changes: 3 additions & 2 deletions src/provider/ipa_pc.rs → src/provider/pcs/ipa_pc.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
//! This module implements `EvaluationEngine` using an IPA-based polynomial commitment scheme
use crate::provider::pcs::pedersen::CommitmentKeyExtTrait;
use crate::{
digest::SimpleDigestible,
errors::{NovaError, PCSError},
provider::{pedersen::CommitmentKeyExtTrait, traits::DlogGroup, util::field::batch_invert},
provider::{traits::DlogGroup, util::field::batch_invert},
spartan::polys::eq::EqPolynomial,
traits::{
commitment::{CommitmentEngineTrait, CommitmentTrait},
Expand Down Expand Up @@ -377,7 +378,7 @@ where

#[cfg(test)]
mod test {
use crate::provider::ipa_pc::EvaluationEngine;
use crate::provider::pcs::ipa_pc::EvaluationEngine;
use crate::provider::util::test_utils::prove_verify_from_num_vars;
use crate::provider::GrumpkinEngine;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
//! Commitment engine for KZG commitments
//!

use std::borrow::Borrow;
use std::marker::PhantomData;

use abomonation_derive::Abomonation;
use ff::{Field, PrimeField, PrimeFieldBits};
use group::{prime::PrimeCurveAffine, Curve, Group as _};
use pairing::Engine;
use pairing::{Engine, MultiMillerLoop};
use rand::rngs::StdRng;
use rand_core::{CryptoRng, RngCore, SeedableRng};
use serde::{Deserialize, Serialize};
use std::sync::Arc;

use crate::provider::pedersen::Commitment;
use crate::errors::PCSError;
use crate::provider::pcs::pedersen::Commitment;
use crate::provider::traits::DlogGroup;
use crate::provider::util::fb_msm;
use crate::spartan::polys::univariate::UniPoly;
use crate::{
digest::SimpleDigestible,
traits::{
commitment::{CommitmentEngineTrait, Len},
Engine as NovaEngine, Group, TranscriptReprTrait,
},
NovaError,
};

/// `UniversalParams` are the universal parameters for the KZG10 scheme.
Expand Down Expand Up @@ -88,7 +92,7 @@ impl<E: Engine> KZGProverKey<E> {
}
}

pub fn powers_of_g(&self) -> &[E::G1Affine] {
pub(in crate::provider) fn powers_of_g(&self) -> &[E::G1Affine] {
&self.uv_params.powers_of_g[self.offset..self.offset + self.supported_size]
}
}
Expand Down Expand Up @@ -271,3 +275,92 @@ where
}
}
}

/// Polynomial Evaluation
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub struct UVKZGEvaluation<E: Engine>(pub E::Fr);

#[derive(Debug, Clone, Eq, PartialEq, Default)]

/// KZG10 polynomial opening at some point
pub struct UVKZGOpening<E: Engine> {
/// KZG10 opening represented as an affine point
pub opening: E::G1Affine,
}

/// Polynomial and its associated types
pub type UVKZGPoly<F> = UniPoly<F>;

#[derive(Debug, Clone, Eq, PartialEq, Default)]
/// KZG Polynomial Commitment Scheme on univariate polynomial.
/// Note: this is non-hiding, which is why we will implement traits on this token struct,
/// as we expect to have several impls for the trait pegged on the same instance of a pairing::Engine.
#[allow(clippy::upper_case_acronyms)]
pub struct UVKZGPCS<E> {
#[doc(hidden)]
phantom: PhantomData<E>,
}

impl<E: MultiMillerLoop> UVKZGPCS<E>
where
E::G1: DlogGroup<AffineExt = E::G1Affine, ScalarExt = E::Fr>,
{
pub(crate) fn commit_offset(
prover_param: impl Borrow<KZGProverKey<E>>,
poly: &UVKZGPoly<E::Fr>,
offset: usize,
) -> Result<UVKZGCommitment<E>, NovaError> {
let prover_param = prover_param.borrow();

if poly.degree() > prover_param.powers_of_g().len() {
return Err(NovaError::PCSError(PCSError::LengthError));
}

let scalars = poly.coeffs.as_slice();
let bases = prover_param.powers_of_g();

// We can avoid some scalar multiplications if 'scalars' contains a lot of leading zeroes using
// offset, that points where non-zero scalars start.
let C = <E::G1 as DlogGroup>::vartime_multiscalar_mul(
&scalars[offset..],
&bases[offset..scalars.len()],
);

Ok(UVKZGCommitment(C.to_affine()))
}

/// Generate a commitment for a polynomial
/// Note that the scheme is not hiding
pub fn commit(
prover_param: impl Borrow<KZGProverKey<E>>,
poly: &UVKZGPoly<E::Fr>,
) -> Result<UVKZGCommitment<E>, NovaError> {
let prover_param = prover_param.borrow();

if poly.degree() > prover_param.powers_of_g().len() {
return Err(NovaError::PCSError(PCSError::LengthError));
}
let C = <E::G1 as DlogGroup>::vartime_multiscalar_mul(
poly.coeffs.as_slice(),
&prover_param.powers_of_g()[..poly.coeffs.len()],
);
Ok(UVKZGCommitment(C.to_affine()))
}

/// Vanilla KZG10 opening algorithm
pub fn open(
prover_param: impl Borrow<KZGProverKey<E>>,
polynomial: &UVKZGPoly<E::Fr>,
point: &E::Fr,
) -> Result<UVKZGOpening<E>, NovaError> {
let prover_param = prover_param.borrow();
let witness_polynomial = polynomial.divide_minus_u(*point);
let opening = <E::G1 as DlogGroup>::vartime_multiscalar_mul(
witness_polynomial.coeffs.as_slice(),
&prover_param.powers_of_g()[..witness_polynomial.coeffs.len()],
)
.to_affine();

Ok(UVKZGOpening { opening })
}
}
9 changes: 9 additions & 0 deletions src/provider/pcs/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/// TODO write docs for PCS module
///
// public modules to be used as an evaluation engine with Spartan
pub mod hyperkzg;
pub mod ipa_pc;
// a non-hiding variant of {kzg, zeromorph}
pub mod kzg10_utilities;
pub mod non_hiding_zeromorph;
pub mod pedersen;
Loading
Loading