Skip to content

Commit

Permalink
refactoring: Move (from ZM) and refactor vanilla KZG10 utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
storojs72 committed Mar 11, 2024
1 parent 76de47f commit 43112c1
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 113 deletions.
2 changes: 1 addition & 1 deletion src/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::{
use halo2curves::bn256::Bn256;
use pasta_curves::{pallas, vesta};

use pcs::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
Expand Down
13 changes: 5 additions & 8 deletions src/provider/pcs/hyperkzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
//! 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::{
pcs::kzg_commitment::{KZGCommitmentEngine, KZGProverKey, KZGVerifierKey, UniversalKZGParam},
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
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::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 @@ -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 })
}
}
2 changes: 1 addition & 1 deletion src/provider/pcs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
pub mod hyperkzg;
pub mod ipa_pc;
// a non-hiding variant of {kzg, zeromorph}
pub mod kzg_commitment;
pub mod kzg10_utilities;
pub mod non_hiding_zeromorph;
pub mod pedersen;
108 changes: 6 additions & 102 deletions src/provider/pcs/non_hiding_zeromorph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
//!
//!
use crate::provider::pcs::kzg_commitment::{
KZGCommitmentEngine, KZGProverKey, KZGVerifierKey, UVKZGCommitment, UniversalKZGParam,
use crate::provider::pcs::kzg10_utilities::{
KZGCommitmentEngine, KZGProverKey, KZGVerifierKey, UVKZGCommitment, UVKZGEvaluation,
UVKZGOpening, UniversalKZGParam, UVKZGPCS,
};
use crate::{
digest::SimpleDigestible,
Expand All @@ -29,101 +30,6 @@ use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::{borrow::Borrow, iter, marker::PhantomData};

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

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

/// Proofs
pub struct UVKZGProof<E: Engine> {
/// proof
pub proof: 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>,
{
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()))
}

/// On input a polynomial `p` and a point `point`, outputs a proof for the
/// same.
pub fn open(
prover_param: impl Borrow<KZGProverKey<E>>,
polynomial: &UVKZGPoly<E::Fr>,
point: &E::Fr,
) -> Result<(UVKZGProof<E>, UVKZGEvaluation<E>), NovaError> {
let prover_param = prover_param.borrow();
let witness_polynomial = polynomial.divide_minus_u(*point);
let proof = <E::G1 as DlogGroup>::vartime_multiscalar_mul(
witness_polynomial.coeffs.as_slice(),
&prover_param.powers_of_g()[..witness_polynomial.coeffs.len()],
);
let evaluation = UVKZGEvaluation(polynomial.evaluate(point));

Ok((
UVKZGProof {
proof: proof.to_affine(),
},
evaluation,
))
}
}

/// `ZMProverKey` is used to generate a proof
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ZMProverKey<E: Engine> {
Expand Down Expand Up @@ -318,11 +224,10 @@ where
// hence uveval == Fr::ZERO

// Compute and send proof commitment pi
let (uvproof, _uveval): (UVKZGProof<_>, UVKZGEvaluation<_>) =
UVKZGPCS::<E>::open(&pp.open_pp, &f, &x)?;
let pi: UVKZGOpening<_> = UVKZGPCS::<E>::open(&pp.open_pp, &f, &x)?;

let proof = ZMProof {
pi: uvproof.proof,
pi: pi.opening,
cqhat: q_hat_comm,
ck: q_comms,
};
Expand Down Expand Up @@ -552,7 +457,6 @@ where
{
type ProverKey = ZMProverKey<E>;
type VerifierKey = ZMVerifierKey<E>;

type EvaluationArgument = ZMProof<E>;

fn setup(ck: Arc<UniversalKZGParam<E>>) -> (Self::ProverKey, Self::VerifierKey) {
Expand Down Expand Up @@ -611,7 +515,7 @@ mod test {
use super::{quotients, UVKZGPCS};

use crate::provider::pcs::{
kzg_commitment::{KZGProverKey, UVKZGCommitment, UniversalKZGParam},
kzg10_utilities::{KZGProverKey, UVKZGCommitment, UniversalKZGParam},
non_hiding_zeromorph::{batched_lifted_degree_quotient, eval_and_quotient_scalars, ZMPCS},
};
use crate::spartan::polys::univariate::UniPoly;
Expand Down

0 comments on commit 43112c1

Please sign in to comment.