Skip to content

Commit

Permalink
batching zeromorph working
Browse files Browse the repository at this point in the history
  • Loading branch information
PatStiles committed Jan 15, 2024
1 parent a522875 commit 11435ca
Show file tree
Hide file tree
Showing 8 changed files with 633 additions and 469 deletions.
1 change: 1 addition & 0 deletions src/lasso/densified.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ impl<F: PrimeField, const C: usize> DensifiedRepresentation<F, C> {
}
}

//TODO: make this a commitment generic over
#[tracing::instrument(skip_all, name = "DensifiedRepresentation.commit")]
pub fn commit<G: CurveGroup<ScalarField = F>>(
&self,
Expand Down
3 changes: 3 additions & 0 deletions src/lasso/surge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use ark_std::log2;
use merlin::Transcript;
use std::marker::Sync;

// Public Params
pub struct SparsePolyCommitmentGens<G> {
pub gens_combined_l_variate: PolyCommitmentGens<G>,
pub gens_combined_log_m_variate: PolyCommitmentGens<G>,
Expand Down Expand Up @@ -89,6 +90,8 @@ struct PrimarySumcheck<G: CurveGroup, const ALPHA: usize> {
proof_derefs: CombinedTableEvalProof<G, ALPHA>,
}

// TODO Implement trait interface for this:
// DensifiedRepresentation ->
#[derive(Debug, CanonicalSerialize, CanonicalDeserialize)]
pub struct SparsePolynomialEvaluationProof<
G: CurveGroup,
Expand Down
6 changes: 2 additions & 4 deletions src/poly/unipoly.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(dead_code)]

use std::cmp::Ordering;
use std::ops::{Index, IndexMut, MulAssign, AddAssign, Mul};
use std::ops::{AddAssign, Index, IndexMut, Mul, MulAssign};

use super::commitments::{Commitments, MultiCommitGens};
use crate::utils::gaussian_elimination::gaussian_elimination;
Expand Down Expand Up @@ -60,7 +60,7 @@ impl<F: PrimeField> UniPoly<F> {
gaussian_elimination(&mut vandermonde)
}

/// Divide self by another polynomial, and returns the
/// Divide self by another polynomial, and returns the
/// quotient and remainder.
pub fn divide_with_q_and_r(&self, divisor: &Self) -> Option<(Self, Self)> {
if self.is_zero() {
Expand Down Expand Up @@ -169,7 +169,6 @@ impl<F: PrimeField> Mul<F> for UniPoly<F> {
//TODO: feature gate parallel
Self::from_coeff(self.coeffs.into_iter().map(|c| c * rhs).collect::<Vec<_>>())
}

}

impl<F: PrimeField> Mul<&F> for UniPoly<F> {
Expand All @@ -179,7 +178,6 @@ impl<F: PrimeField> Mul<&F> for UniPoly<F> {
//TODO: feature gate parallel
Self::from_coeff(self.coeffs.into_iter().map(|c| c * rhs).collect::<Vec<_>>())
}

}

impl<F: PrimeField> AddAssign<&Self> for UniPoly<F> {
Expand Down
13 changes: 11 additions & 2 deletions src/subprotocols/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use std::borrow::Borrow;

use merlin::Transcript;

pub trait CommitmentScheme {
pub trait PCS {
type Commitment;
type Evaluation;
type Polynomial;
type CommitPolynomial;
type Challenge;
type Proof;
type Error;
Expand All @@ -15,7 +16,7 @@ pub trait CommitmentScheme {

//TODO: convert to impl IntoIterator<Item = Self::Polynomial>
fn commit(
polys: &[Self::Polynomial],
polys: &[Self::CommitPolynomial],
ck: &Self::ProverKey,
) -> Result<Vec<Self::Commitment>, Self::Error>;

Expand All @@ -27,6 +28,14 @@ pub trait CommitmentScheme {
transcript: &mut Transcript,
) -> Result<Self::Proof, Self::Error>;

fn open(
polys: &[Self::Polynomial],
evals: &[Self::Evaluation],
challenges: &[Self::Challenge],
pk: impl Borrow<Self::ProverKey>,
transcript: &mut Transcript,
) -> Result<Self::Proof, Self::Error>;

fn verify(
commitments: &[Self::Commitment],
evals: &[Self::Evaluation],
Expand Down
156 changes: 43 additions & 113 deletions src/subprotocols/zeromorph/data_structures.rs
Original file line number Diff line number Diff line change
@@ -1,88 +1,68 @@
use crate::subprotocols::zeromorph::kzg::UNIVERSAL_KZG_SRS;
use ark_bn254::Bn254;
use ark_ec::{pairing::Pairing, CurveGroup};
use ark_ff::UniformRand;
use ark_std::rand::rngs::StdRng;
use lazy_static::lazy_static;
use rand_chacha::rand_core::SeedableRng;
use rand_chacha::{
rand_core::{RngCore, SeedableRng},
ChaCha20Rng,
};
use std::sync::{Arc, Mutex};

use crate::utils::math::Math;
use super::kzg::KZGProverKey;

//TODO: The SRS is set with a default value of ____ if this is to be changed (extended) use the cli arg and change it manually.
//TODO: add input specifiying monomial or lagrange basis
const MAX_VARS: usize = 20;
lazy_static! {
pub static ref ZEROMORPH_SRS: Arc<Mutex<ZeromorphSRS<20, Bn254>>> =
Arc::new(Mutex::new(ZeromorphSRS::setup(None)));
pub static ref ZEROMORPH_SRS: Arc<Mutex<ZeromorphSRS<Bn254>>> =
Arc::new(Mutex::new(ZeromorphSRS::setup(
None,
1 << (MAX_VARS + 1),
&mut ChaCha20Rng::from_seed(*b"11111111111111111111111111111111")
)));
}

#[derive(Debug, Clone, Default)]
pub struct ZeromorphSRS<const N_MAX: usize, P: Pairing> {
g1_powers: Vec<P::G1Affine>,
g2_powers: Vec<P::G2Affine>,
}

impl<const N_MAX: usize, P: Pairing> ZeromorphSRS<N_MAX, P> {
fn compute_g_powers<G: CurveGroup>(tau: G::ScalarField) -> Vec<G::Affine> {
let g_srs = vec![G::zero(); N_MAX - 1];

let g_srs: Vec<G> = std::iter::once(G::generator())
.chain(g_srs.iter().scan(G::generator(), |state, _| {
*state *= &tau;
Some(*state)
}))
.collect();

G::normalize_batch(&g_srs)
}

pub fn setup(toxic_waste: Option<&[u8]>) -> ZeromorphSRS<N_MAX, P> {
let tau: &[u8] = if toxic_waste.is_none() {
b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
} else {
toxic_waste.unwrap()
};
/*
if ENV_VAR_NOT_PASSED_IN
*/
let mut bytes = [0u8; 32];
let len = tau.len();
bytes[..len].copy_from_slice(&tau[..len]);
let rng = &mut StdRng::from_seed(bytes);

let tau = P::ScalarField::rand(rng);
let g1_powers = Self::compute_g_powers::<P::G1>(tau);
let g2_powers = Self::compute_g_powers::<P::G2>(tau);
ZeromorphSRS {
g1_powers,
g2_powers,
}
}

pub fn get_prover_key(&self) -> ZeromorphProverKey<P> {
ZeromorphProverKey {
g1: self.g1_powers[0],
tau_1: self.g1_powers[1],
g1_powers: self.g1_powers.clone(),
}
pub struct ZeromorphSRS<P: Pairing>(UNIVERSAL_KZG_SRS<P>);

impl<P: Pairing> ZeromorphSRS<P> {
pub fn setup<R: RngCore>(
toxic_waste: Option<&[u8]>,
max_degree: usize,
mut rng: &mut R,
) -> ZeromorphSRS<P> {
ZeromorphSRS(UNIVERSAL_KZG_SRS::<P>::setup(None, max_degree, rng))
}

pub fn get_verifier_key(&self) -> ZeromorphVerifierKey<P> {
let idx = N_MAX - (2_usize.pow(N_MAX.log_2() as u32) - 1);
ZeromorphVerifierKey {
g1: self.g1_powers[0],
g2: self.g2_powers[0],
tau_2: self.g2_powers[1],
tau_N_max_sub_2_N: self.g2_powers[idx],
}
pub fn get_pk_vk(&self, max_degree: usize) -> (ZeromorphProverKey<P>, ZeromorphVerifierKey<P>) {
let offset = self.0.g1_powers.len() - max_degree;
let offset_g1_powers = self.0.g1_powers[offset..].to_vec();
(
ZeromorphProverKey {
g1_powers: KZGProverKey {
g1_powers: self.0.g1_powers.clone(),
},
offset_g1_powers: KZGProverKey {
g1_powers: offset_g1_powers,
},
},
ZeromorphVerifierKey {
g1: self.0.g1_powers[0],
g2: self.0.g2_powers[0],
tau_2: self.0.g2_powers[1],
tau_N_max_sub_2_N: self.0.g2_powers[offset],
},
)
}
}

#[derive(Clone, Debug)]
pub struct ZeromorphProverKey<P: Pairing> {
// generator
pub g1: P::G1Affine,
pub tau_1: P::G1Affine,
pub g1_powers: Vec<P::G1Affine>,
pub g1_powers: KZGProverKey<P>,
pub offset_g1_powers: KZGProverKey<P>,
}

#[derive(Copy, Clone, Debug)]
Expand All @@ -100,53 +80,3 @@ pub struct ZeromorphProof<P: Pairing> {
pub q_hat_com: P::G1Affine,
pub q_k_com: Vec<P::G1Affine>,
}

#[cfg(test)]
mod test {
use super::*;
use ark_bn254::Bn254;
use ark_ec::{pairing::Pairing, AffineRepr};
use ark_ff::One;
use std::ops::Mul;

fn expected_srs<E: Pairing>(n: usize, seed: &[u8]) -> (Vec<E::G1Affine>, Vec<E::G2Affine>) {
let mut bytes = [0u8; 32];
let len = seed.len();
bytes[..len].copy_from_slice(&seed[..len]);
let rng = &mut StdRng::from_seed(bytes);

let tau = E::ScalarField::rand(rng);

let powers_of_tau: Vec<E::ScalarField> =
std::iter::successors(Some(E::ScalarField::one()), |p| Some(*p * tau))
.take(n)
.collect();

let g1_gen = E::G1Affine::generator();
let g2_gen = E::G2Affine::generator();

let srs_g1: Vec<E::G1Affine> = powers_of_tau
.iter()
.map(|tp| g1_gen.mul(tp).into())
.collect();
let srs_g2: Vec<E::G2Affine> = powers_of_tau
.iter()
.map(|tp| g2_gen.mul(tp).into())
.collect();

(srs_g1, srs_g2)
}

#[test]
fn test_srs() {
const K: i32 = 1;
const N: usize = 1 << K;
let seed = b"111111111111111111111111111";

let (g1_srs_expected, g2_srs_expected) = expected_srs::<Bn254>(N, seed);

let srs = ZeromorphSRS::<N, Bn254>::setup(Some(seed));
assert_eq!(g1_srs_expected, srs.g1_powers);
assert_eq!(g2_srs_expected, srs.g2_powers);
}
}
Loading

0 comments on commit 11435ca

Please sign in to comment.