Skip to content

Commit

Permalink
Enable batch verification
Browse files Browse the repository at this point in the history
In this commit k and n are removed from CS parameters
  • Loading branch information
iquerejeta committed Dec 19, 2024
1 parent ddcb294 commit 77d47b2
Show file tree
Hide file tree
Showing 20 changed files with 373 additions and 339 deletions.
28 changes: 15 additions & 13 deletions benches/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ use rand_core::OsRng;
use std::marker::PhantomData;

use criterion::{BenchmarkId, Criterion};
use halo2_proofs::poly::commitment::Guard;
use halo2_proofs::poly::kzg::params::ParamsVerifierKZG;
use halo2_proofs::poly::kzg::{params::ParamsKZG, KZGCommitmentScheme};
use halo2_proofs::transcript::{CircuitTranscript, Transcript};
use halo2_proofs::utils::rational::Rational;
use halo2curves::bn256::Bn256;

fn criterion_benchmark(c: &mut Criterion) {
/// This represents an advice column at a certain row in the ConstraintSystem
Expand Down Expand Up @@ -257,13 +260,13 @@ fn criterion_benchmark(c: &mut Criterion) {
ParamsKZG<bn256::Bn256>,
ProvingKey<bn256::Fr, KZGCommitmentScheme<bn256::Bn256>>,
) {
let params: ParamsKZG<bn256::Bn256> = ParamsKZG::new(k);
let params: ParamsKZG<Bn256> = ParamsKZG::unsafe_setup(k, OsRng);
let empty_circuit: MyCircuit<bn256::Fr> = MyCircuit {
a: Value::unknown(),
k,
};
let vk = keygen_vk(&params, &empty_circuit).expect("keygen_vk should not fail");
let pk = keygen_pk(&params, vk, &empty_circuit).expect("keygen_pk should not fail");
let pk = keygen_pk(vk, &empty_circuit).expect("keygen_pk should not fail");
(params, pk)
}

Expand Down Expand Up @@ -294,20 +297,19 @@ fn criterion_benchmark(c: &mut Criterion) {
}

fn verifier(
params: &ParamsKZG<bn256::Bn256>,
params: &ParamsVerifierKZG<bn256::Bn256>,
vk: &VerifyingKey<bn256::Fr, KZGCommitmentScheme<bn256::Bn256>>,
proof: &[u8],
) {
let mut transcript = CircuitTranscript::init_from_bytes(proof);
assert!(
verify_proof::<bn256::Fr, KZGCommitmentScheme<bn256::Bn256>, _>(
params,
vk,
&[&[]],
&mut transcript
)
.is_ok()
);
assert!(prepare::<bn256::Fr, KZGCommitmentScheme<bn256::Bn256>, _>(
vk,
&[&[]],
&mut transcript
)
.unwrap()
.verify(params)
.is_ok());
}

let k_range = 8..=16;
Expand Down Expand Up @@ -345,7 +347,7 @@ fn criterion_benchmark(c: &mut Criterion) {
BenchmarkId::from_parameter(k),
&(&params, pk.get_vk(), &proof[..]),
|b, &(params, vk, proof)| {
b.iter(|| verifier(params, vk, proof));
b.iter(|| verifier(&params.verifier_params(), vk, proof));
},
);
}
Expand Down
14 changes: 8 additions & 6 deletions examples/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ use std::{
};

use ff::Field;
use halo2_proofs::poly::commitment::Guard;
use halo2_proofs::transcript::{CircuitTranscript, Transcript};
use halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner, Value},
plonk::{
create_proof, keygen_pk, keygen_vk, verify_proof, Advice, Circuit, Column,
ConstraintSystem, Error, Fixed, Instance, ProvingKey,
create_proof, keygen_pk, keygen_vk, prepare, Advice, Circuit, Column, ConstraintSystem,
Error, Fixed, Instance, ProvingKey,
},
poly::{
kzg::{params::ParamsKZG, KZGCommitmentScheme},
Expand Down Expand Up @@ -126,10 +127,10 @@ impl Circuit<Fr> for StandardPlonk {
fn main() {
let k = 4;
let circuit = StandardPlonk(Fr::random(OsRng));
let params = ParamsKZG::<Bn256>::setup(k, OsRng);
let params = ParamsKZG::<Bn256>::unsafe_setup(k, OsRng);
let vk = keygen_vk::<_, KZGCommitmentScheme<Bn256>, _>(&params, &circuit)
.expect("vk should not fail");
let pk = keygen_pk(&params, vk, &circuit).expect("pk should not fail");
let pk = keygen_pk(vk, &circuit).expect("pk should not fail");

let f = File::create("serialization-test.pk").unwrap();
let mut writer = BufWriter::new(f);
Expand Down Expand Up @@ -166,11 +167,12 @@ fn main() {

let mut transcript = CircuitTranscript::<State>::init_from_bytes(&proof[..]);

assert!(verify_proof::<Fr, KZGCommitmentScheme<Bn256>, _>(
&params,
assert!(prepare::<Fr, KZGCommitmentScheme<Bn256>, _>(
pk.get_vk(),
&[instances],
&mut transcript,
)
.unwrap()
.verify(&params.verifier_params())
.is_ok());
}
14 changes: 6 additions & 8 deletions examples/vector-ops-unblinded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use blake2b_simd::State;
use std::marker::PhantomData;

use ff::{FromUniformBytes, WithSmallOrderMulGroup};
use halo2_proofs::poly::commitment::Guard;
use halo2_proofs::poly::kzg::{params::ParamsKZG, KZGCommitmentScheme};
use halo2_proofs::transcript::{CircuitTranscript, Hashable, Sampleable, Transcript};
use halo2_proofs::{
Expand Down Expand Up @@ -477,9 +478,9 @@ where
+ Hashable<State>
+ Ord,
{
let params = ParamsKZG::<E>::new(k);
let params: ParamsKZG<E> = ParamsKZG::unsafe_setup(k, OsRng);
let vk = keygen_vk(&params, &circuit).unwrap();
let pk = keygen_pk(&params, vk, &circuit).unwrap();
let pk = keygen_pk(vk, &circuit).unwrap();

let proof = {
let mut transcript = CircuitTranscript::<State>::init();
Expand All @@ -500,12 +501,9 @@ where
let accepted = {
let mut transcript = CircuitTranscript::<State>::init_from_bytes(&proof[..]);

verify_proof::<E::Fr, KZGCommitmentScheme<E>, _>(
&params,
pk.get_vk(),
&[&[&instances]],
&mut transcript,
)
prepare::<E::Fr, KZGCommitmentScheme<E>, _>(pk.get_vk(), &[&[&instances]], &mut transcript)
.unwrap()
.verify(&params.verifier_params())
};

assert_eq!(accepted.is_ok(), expected);
Expand Down
89 changes: 64 additions & 25 deletions src/plonk/keygen.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(clippy::int_plus_one)]

use std::marker::PhantomData;
use std::ops::Range;

use ff::{Field, FromUniformBytes, WithSmallOrderMulGroup};
Expand All @@ -15,7 +16,7 @@ use super::{
};
use crate::circuit::Value;
use crate::poly::batch_invert_rational;
use crate::poly::commitment::{Params, PolynomialCommitmentScheme};
use crate::poly::commitment::PolynomialCommitmentScheme;
use crate::utils::rational::Rational;
use crate::{poly::EvaluationDomain, utils::arithmetic::parallelize};

Expand Down Expand Up @@ -198,33 +199,76 @@ impl<F: Field> Assignment<F> for Assembly<F> {
}
}

fn k_from_circuit<F: Ord + Field + FromUniformBytes<64>, C: Circuit<F>>(circuit: &C) -> u32 {
// TODO: We could optimize the order here.
(3..25)
.find(|k| {
let n = 2usize.pow(*k);

let mut cs = ConstraintSystem::default();
#[cfg(feature = "circuit-params")]
let config = C::configure_with_params(&mut cs, circuit.params());
#[cfg(not(feature = "circuit-params"))]
let config = C::configure(&mut cs);
let cs = cs;

if n < cs.minimum_rows() {
return false;
}

let zero_poly = Polynomial {
values: vec![F::ZERO.into(); n],
_marker: PhantomData,
};

let mut assembly = Assembly {
k: *k,
fixed: vec![zero_poly; cs.num_fixed_columns],
permutation: permutation::Assembly::new(n, &cs.permutation),
selectors: vec![vec![false; n]; cs.num_selectors],
usable_rows: 0..n - (cs.blinding_factors() + 1),
_marker: std::marker::PhantomData,
};

// Synthesize the circuit to obtain URS
C::FloorPlanner::synthesize(
&mut assembly,
circuit,
config.clone(),
cs.constants.clone(),
)
.is_ok()
})
.expect("A circuit which can be implemented with at most 2^24 rows.")
}

/// Generate a `VerifyingKey` from an instance of `Circuit`.
/// By default, selector compression is turned **off**.
pub fn keygen_vk<F, CS, ConcreteCircuit>(
params: &CS::VerifierParameters,
params: &CS::Parameters,
circuit: &ConcreteCircuit,
) -> Result<VerifyingKey<F, CS>, Error>
where
F: WithSmallOrderMulGroup<3> + FromUniformBytes<64>,
F: WithSmallOrderMulGroup<3> + FromUniformBytes<64> + Ord,
CS: PolynomialCommitmentScheme<F>,
ConcreteCircuit: Circuit<F>,
{
let (domain, cs, config) = create_domain::<F, ConcreteCircuit>(
params.k(),
k_from_circuit(circuit),
#[cfg(feature = "circuit-params")]
circuit.params(),
);

if (params.n() as usize) < cs.minimum_rows() {
return Err(Error::not_enough_rows_available(params.k()));
if (domain.n as usize) < cs.minimum_rows() {
return Err(Error::not_enough_rows_available(domain.k()));
}

let mut assembly: Assembly<F> = Assembly {
k: params.k(),
k: domain.k(),
fixed: vec![domain.empty_lagrange_rational(); cs.num_fixed_columns],
permutation: permutation::keygen::Assembly::new(params.n() as usize, &cs.permutation),
selectors: vec![vec![false; params.n() as usize]; cs.num_selectors],
usable_rows: 0..params.n() as usize - (cs.blinding_factors() + 1),
permutation: permutation::keygen::Assembly::new(domain.n as usize, &cs.permutation),
selectors: vec![vec![false; domain.n as usize]; cs.num_selectors],
usable_rows: 0..domain.n as usize - (cs.blinding_factors() + 1),
_marker: std::marker::PhantomData,
};

Expand Down Expand Up @@ -252,7 +296,7 @@ where

let fixed_commitments = fixed
.iter()
.map(|poly| params.commit_lagrange(poly))
.map(|poly| CS::commit_lagrange(params, poly))
.collect();

Ok(VerifyingKey::from_parts(
Expand All @@ -266,7 +310,6 @@ where

/// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `Circuit`.
pub fn keygen_pk<F, CS, ConcreteCircuit>(
params: &CS::Parameters,
vk: VerifyingKey<F, CS>,
circuit: &ConcreteCircuit,
) -> Result<ProvingKey<F, CS>, Error>
Expand All @@ -283,16 +326,13 @@ where

let cs = cs;

if (params.n() as usize) < cs.minimum_rows() {
return Err(Error::not_enough_rows_available(params.k()));
}

let n = vk.domain.n as usize;
let mut assembly: Assembly<F> = Assembly {
k: params.k(),
k: vk.domain.k(),
fixed: vec![vk.domain.empty_lagrange_rational(); cs.num_fixed_columns],
permutation: permutation::keygen::Assembly::new(params.n() as usize, &cs.permutation),
selectors: vec![vec![false; params.n() as usize]; cs.num_selectors],
usable_rows: 0..params.n() as usize - (cs.blinding_factors() + 1),
permutation: permutation::keygen::Assembly::new(n, &cs.permutation),
selectors: vec![vec![false; n]; cs.num_selectors],
usable_rows: 0..n - (cs.blinding_factors() + 1),
_marker: std::marker::PhantomData,
};

Expand Down Expand Up @@ -322,10 +362,9 @@ where
.map(|poly| vk.domain.coeff_to_extended(poly.clone()))
.collect();

let permutation_pk =
assembly
.permutation
.build_pk::<F, CS>(params, &vk.domain, &cs.permutation);
let permutation_pk = assembly
.permutation
.build_pk::<F>(&vk.domain, &cs.permutation);

// Compute l_0(X)
// TODO: this can be done more efficiently
Expand All @@ -346,7 +385,7 @@ where
// Compute l_last(X) which evaluates to 1 on the first inactive row (just
// before the blinding factors) and 0 otherwise over the domain
let mut l_last = vk.domain.empty_lagrange();
l_last[params.n() as usize - cs.blinding_factors() - 1] = F::ONE;
l_last[n - cs.blinding_factors() - 1] = F::ONE;
let l_last = vk.domain.lagrange_to_coeff(l_last);
let l_last = vk.domain.coeff_to_extended(l_last);

Expand Down
Loading

0 comments on commit 77d47b2

Please sign in to comment.