Skip to content

Commit

Permalink
Poly-commitment/KZG: uniform definition of SRS::create
Browse files Browse the repository at this point in the history
And include additional documentation for the method.
KZG won't be used in production in the near future, and there is no plan for
now.
Therefore, it seems reasonable to have these changes, with the warning.

Note that we should get rid of create_trusted_setup in IPA::SRS, and stop
relying on IPA::SRS to define the KZG SRS. It was initially introduced to avoid
to reimplement all methods and have something quick for testing.
  • Loading branch information
dannywillems committed Oct 14, 2024
1 parent 1834bba commit fa8e6a3
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 53 deletions.
5 changes: 1 addition & 4 deletions ivc/tests/folding_ivc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use ark_ff::UniformRand;
use ark_poly::{EvaluationDomain, Radix2EvaluationDomain};
use folding::{
instance_witness::Foldable, Alphas, FoldingCompatibleExpr, FoldingConfig, FoldingEnv,
Expand Down Expand Up @@ -123,10 +122,8 @@ fn test_regression_additional_columns_reduction_to_degree_2() {
constrain_ivc::<Ff1, _>(&mut constraint_env);
let constraints = constraint_env.get_relation_constraints();

let mut rng = o1_utils::tests::make_test_rng(None);
let toxic_waste = Fp::rand(&mut rng);
let domain = Radix2EvaluationDomain::<Fp>::new(2).unwrap();
let mut srs = unsafe { PairingSRS::create(toxic_waste, 2) };
let mut srs = PairingSRS::create(2);
srs.add_lagrange_basis(domain);

let folding_compat_expresions: Vec<FoldingCompatibleExpr<TestConfig>> = constraints
Expand Down
9 changes: 2 additions & 7 deletions kimchi/src/tests/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,9 @@ fn test_generic_gate_kzg() {
type BaseSponge = DefaultFqSponge<ark_bn254::g1::Config, SpongeParams>;
type ScalarSponge = DefaultFrSponge<Fp, SpongeParams>;

use ark_ff::UniformRand;

let public = vec![Fp::from(3u8); 5];
let gates = create_circuit(0, public.len());

let rng = &mut rand::rngs::OsRng;
let x = Fp::rand(rng);

// create witness
let mut witness: [Vec<Fp>; COLUMNS] = array::from_fn(|_| vec![Fp::zero(); gates.len()]);
fill_in_witness(0, &mut witness, &public);
Expand All @@ -118,8 +113,8 @@ fn test_generic_gate_kzg() {
.gates(gates)
.witness(witness)
.public_inputs(public)
.setup_with_custom_srs(|d1, usize| {
let mut srs = unsafe { poly_commitment::kzg::PairingSRS::create(x, usize) };
.setup_with_custom_srs(|d1, srs_size| {
let mut srs = poly_commitment::kzg::PairingSRS::create(srs_size);
srs.full_srs.add_lagrange_basis(d1);
srs
})
Expand Down
8 changes: 2 additions & 6 deletions msm/src/precomputed_srs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
use crate::{Fp, BN254, DOMAIN_SIZE};
use ark_ec::pairing::Pairing;
use ark_ff::UniformRand;
use ark_serialize::Write;
use kimchi::{circuits::domains::EvaluationDomains, precomputed_srs::TestSRS};
use poly_commitment::{kzg::PairingSRS, SRS as _};
use rand::{prelude::StdRng, SeedableRng};
use serde::{Deserialize, Serialize};
use std::{fs::File, io::BufReader, path::PathBuf};

Expand Down Expand Up @@ -40,7 +38,7 @@ pub fn get_bn254_srs(domain: EvaluationDomains<Fp>) -> PairingSRS<BN254> {
let mut srs = if domain.d1.size as usize == DOMAIN_SIZE {
read_bn254_srs_from_disk(get_bn254_srs_path())
} else {
unsafe { PairingSRS::create(Fp::rand(&mut rand::rngs::OsRng), domain.d1.size as usize) }
PairingSRS::create(domain.d1.size as usize)
};
srs.full_srs.add_lagrange_basis(domain.d1); // not added if already present.
srs
Expand Down Expand Up @@ -73,9 +71,7 @@ fn create_and_store_srs_with_path(
srs_path: PathBuf,
) -> PairingSRS<BN254> {
// We generate with a fixed-seed RNG, only used for testing.
let mut rng = &mut StdRng::from_seed([42u8; 32]);
let trapdoor = Fp::rand(&mut rng);
let mut srs = unsafe { PairingSRS::create(trapdoor, domain_size) };
let mut srs = PairingSRS::create(domain_size);

for sub_domain_size in 1..=domain_size {
let domain = EvaluationDomains::<Fp>::create(sub_domain_size).unwrap();
Expand Down
5 changes: 1 addition & 4 deletions msm/src/test/logup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ mod tests {
let domain_size = 1 << 8;
let domain = EvaluationDomains::<Fp>::create(domain_size).unwrap();

let mut srs: PairingSRS<BN254> = {
let toxic_waste = Fp::rand(&mut rng);
unsafe { PairingSRS::create(toxic_waste, domain.d1.size as usize) }
};
let mut srs: PairingSRS<BN254> = { PairingSRS::create(domain.d1.size as usize) };
srs.full_srs.add_lagrange_basis(domain.d1);

let mut inputs = ProofInputs::random(domain);
Expand Down
5 changes: 2 additions & 3 deletions o1vm/src/legacy/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,8 @@ pub fn main() -> ExitCode {
let mut rng = o1_utils::tests::make_test_rng(None);

let srs = {
let toxic_waste = Fp::rand(&mut rand::rngs::OsRng);

let mut srs = unsafe { poly_commitment::kzg::PairingSRS::create(toxic_waste, DOMAIN_SIZE) };
// FIXME: toxic waste is generated in `create`. This is unsafe for prod.
let mut srs = poly_commitment::kzg::PairingSRS::create(DOMAIN_SIZE);
srs.full_srs.add_lagrange_basis(domain.d1);
srs
};
Expand Down
49 changes: 25 additions & 24 deletions poly-commitment/src/kzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use ark_poly::{
DenseUVPolynomial, EvaluationDomain, Evaluations, Polynomial, Radix2EvaluationDomain as D,
};
use mina_poseidon::FqSponge;
use rand::thread_rng;
use rand_core::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
Expand Down Expand Up @@ -128,6 +129,26 @@ pub struct PairingSRS<Pair: Pairing> {
pub verifier_srs: SRS<Pair::G2Affine>,
}

impl<
F: PrimeField,
G: CommitmentCurve<ScalarField = F>,
G2: CommitmentCurve<ScalarField = F>,
Pair: Pairing<G1Affine = G, G2Affine = G2>,
> PairingSRS<Pair>
{
/// Create a trusted setup for the KZG protocol.
/// The setup is created using a toxic waste `toxic_waste` and a depth
/// `depth`.
fn create_trusted_setup(toxic_waste: F, depth: usize) -> Self {
let full_srs = unsafe { SRS::create_trusted_setup(toxic_waste, depth) };
let verifier_srs = unsafe { SRS::create_trusted_setup(toxic_waste, depth) };
Self {
full_srs,
verifier_srs,
}
}
}

impl<Pair: Pairing> Default for PairingSRS<Pair> {
fn default() -> Self {
Self {
Expand All @@ -146,28 +167,6 @@ impl<Pair: Pairing> Clone for PairingSRS<Pair> {
}
}

impl<
F: PrimeField,
G: CommitmentCurve<ScalarField = F>,
G2: CommitmentCurve<ScalarField = F>,
Pair: Pairing<G1Affine = G, G2Affine = G2>,
> PairingSRS<Pair>
{
/// Create a new SRS for the KZG protocol.
///
/// # Safety
///
/// The method is annotated as unsafe because it does use a method
/// generating the toxic waste. A safe method would be to load an existing
/// SRS where it is broadly accepted that the trapdoor is not recoverable.
pub unsafe fn create(x: F, n: usize) -> Self {
PairingSRS {
full_srs: unsafe { SRS::create_trusted_setup(x, n) },
verifier_srs: unsafe { SRS::create_trusted_setup(x, 3) },
}
}
}

impl<
F: PrimeField,
G: CommitmentCurve<ScalarField = F>,
Expand Down Expand Up @@ -318,8 +317,10 @@ impl<
.commit_evaluations_custom(domain, plnm, blinders)
}

fn create(_depth: usize) -> Self {
todo!()
fn create(depth: usize) -> Self {
let mut rng = thread_rng();
let toxic_waste = G::ScalarField::rand(&mut rng);
Self::create_trusted_setup(toxic_waste, depth)
}

fn add_lagrange_basis(&mut self, domain: D<<G>::ScalarField>) {
Expand Down
9 changes: 9 additions & 0 deletions poly-commitment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ pub trait SRS<G: CommitmentCurve>: Clone + Sized {
blinders: &PolyComm<G::ScalarField>,
) -> Result<BlindedCommitment<G>, CommitmentError>;

/// Create an SRS of size `depth`.
///
/// Warning: in the case of a trusted setup, as it is required for a
/// polynomial commitment scheme like KZG, a toxic waste is generated using
/// `rand::thread_rng()`. This is not the behavior you would expect in a
/// production environment.
/// However, we do accept this behavior for the sake of simplicity in the
/// interface, and this method will only be supposed to be used in tests in
/// this case.
fn create(depth: usize) -> Self;

fn add_lagrange_basis(&mut self, domain: D<G::ScalarField>);
Expand Down
6 changes: 1 addition & 5 deletions poly-commitment/tests/kzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,8 @@ fn test_kzg_proof() {
fn check_srs_g2_valid_and_serializes() {
type BN254 = Bn<Config>;
type BN254G2BaseField = <G2 as AffineRepr>::BaseField;
type Fp = ark_bn254::Fr;

let mut rng = o1_utils::tests::make_test_rng(None);

let x = Fp::rand(&mut rng);
let srs: PairingSRS<BN254> = unsafe { PairingSRS::create(x, 1 << 5) };
let srs: PairingSRS<BN254> = PairingSRS::create(1 << 5);

let mut vec: Vec<u8> = vec![0u8; 1024];

Expand Down

0 comments on commit fa8e6a3

Please sign in to comment.