Skip to content

Commit

Permalink
Minor compatibility updates (privacy-scaling-explorations#5)
Browse files Browse the repository at this point in the history
* feat: add bench for zkEVM EVM + State circuit aggregation

* chore: minor update with new `print_stats`

* chore: update Cargo

* chore: change `AggregationConfigParams` to allow multi-phase advice
columns

* chore: update Cargo

* sdk: remove `ExtraCircuitParams` from `CircuitExt` and just allow
`num_instance` to depend on circuit itself

* feat: change `EvmSingleVerifierCircuit` to `PublicAggregationCircuit`

* aggregation circuit that passes through instances from multiple snarks
* assumes snarks are either all aggregation circuits or all
  non-aggregation circuits when determining passthrough logic

* chore: update pk serialization to new halo2_proofs API
  • Loading branch information
jonathanpwang authored Jan 16, 2023
1 parent 6bc8ac2 commit a1c07a5
Show file tree
Hide file tree
Showing 17 changed files with 356 additions and 110 deletions.
4 changes: 0 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ incremental = false
inherits = "release"
debug = true

# patch until PR https://github.com/privacy-scaling-explorations/halo2curves/pull/10 is merged
[patch."https://github.com/privacy-scaling-explorations/halo2curves.git"]
halo2curves = { git = "https://github.com/jonathanpwang/halo2curves.git", branch = "feat/serde-field" }

# patch until PR https://github.com/privacy-scaling-explorations/halo2/pull/111 is merged
[patch."https://github.com/privacy-scaling-explorations/halo2.git"]
halo2_proofs = { git = "https://github.com/axiom-crypto/halo2.git", branch = "feat/serde-raw" }
7 changes: 6 additions & 1 deletion snark-verifier-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ serde_json = "1.0"
bincode = "1.3.3"
ark-std = { version = "0.3.0", features = ["print-trace"], optional = true }

halo2-base = { git = "ssh://git@github.com/axiom-crypto/axiom-core-working.git", branch = "experiment/optimizations", default-features = false }
halo2-base = { git = "ssh://git@github.com/axiom-crypto/axiom-core-working.git", default-features = false }
snark-verifier = { path = "../snark-verifier", default-features = false }

# loader_evm
Expand Down Expand Up @@ -63,4 +63,9 @@ harness = false
[[bench]]
name = "zkevm"
required-features = ["loader_halo2", "zkevm", "halo2-pse", "halo2-base/jemallocator"]
harness = false

[[bench]]
name = "zkevm_plus_state"
required-features = ["loader_halo2", "zkevm", "halo2-pse", "halo2-base/jemallocator"]
harness = false
4 changes: 1 addition & 3 deletions snark-verifier-sdk/benches/standard_plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,7 @@ mod application {
}

impl CircuitExt<Fr> for StandardPlonk {
fn extra_params(&self) -> Self::ExtraCircuitParams {}

fn num_instance(_: &Self::ExtraCircuitParams) -> Vec<usize> {
fn num_instance(&self) -> Vec<usize> {
vec![1]
}

Expand Down
48 changes: 38 additions & 10 deletions snark-verifier-sdk/benches/zkevm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use snark_verifier_sdk::{
gen_pk,
halo2::{
aggregation::load_verify_circuit_degree, aggregation::AggregationCircuit, gen_proof_gwc,
gen_proof_shplonk, gen_snark_shplonk, PoseidonTranscript, POSEIDON_SPEC,
gen_proof_shplonk, gen_snark_gwc, gen_snark_shplonk, PoseidonTranscript, POSEIDON_SPEC,
},
CircuitExt,
};
Expand Down Expand Up @@ -66,13 +66,13 @@ fn bench(c: &mut Criterion) {
let circuit = zkevm::test_circuit();
let params_app = gen_srs(k);
let pk = gen_pk(&params_app, &circuit, Some(Path::new("data/zkevm_evm.pkey")));
let snark = gen_snark_shplonk(
let snark = gen_snark_gwc(
&params_app,
&pk,
circuit,
&mut transcript,
&mut rng,
None, // Some((Path::new("data/zkevm_evm.in"), Path::new("data/zkevm_evm.pf"))),
Some(Path::new("data/zkevm_evm.snark")),
);
let snarks = [snark];
// === finished zkevm evm circuit ===
Expand All @@ -88,7 +88,7 @@ fn bench(c: &mut Criterion) {

let pk = gen_pk(&params, &agg_circuit, None);

let mut group = c.benchmark_group("plonk-prover");
let mut group = c.benchmark_group("shplonk-proof");
group.sample_size(10);
group.bench_with_input(
BenchmarkId::new("zkevm-evm-agg", k),
Expand All @@ -110,12 +110,34 @@ fn bench(c: &mut Criterion) {
);
group.finish();

let mut group = c.benchmark_group("gwc-proof");
group.sample_size(10);
group.bench_with_input(
BenchmarkId::new("zkevm-evm-agg", k),
&(&params, &pk, &agg_circuit),
|b, &(params, pk, agg_circuit)| {
b.iter(|| {
let instances = agg_circuit.instances();
gen_proof_gwc(
params,
pk,
agg_circuit.clone(),
instances,
&mut transcript,
&mut rng,
None,
);
})
},
);
group.finish();

#[cfg(feature = "loader_evm")]
{
let deployment_code =
gen_evm_verifier_shplonk::<AggregationCircuit>(&params, pk.get_vk(), &(), None::<&str>);

let start2 = start_timer!(|| "Create EVM proof");
let start2 = start_timer!(|| "Create EVM SHPLONK proof");
let proof = gen_evm_proof_shplonk(
&params,
&pk,
Expand All @@ -126,12 +148,18 @@ fn bench(c: &mut Criterion) {
end_timer!(start2);

evm_verify(deployment_code, agg_circuit.instances(), proof);

let deployment_code =
gen_evm_verifier_shplonk::<AggregationCircuit>(&params, pk.get_vk(), &(), None::<&str>);

let start2 = start_timer!(|| "Create EVM GWC proof");
let proof =
gen_evm_proof_gwc(&params, &pk, agg_circuit.clone(), agg_circuit.instances(), &mut rng);
end_timer!(start2);

evm_verify(deployment_code, agg_circuit.instances(), proof);
}
}

criterion_group! {
name = benches;
config = Criterion::default().with_profiler(PProfProfiler::new(10, Output::Flamegraph(None)));
targets = bench
}
criterion_group!(benches, bench);
criterion_main!(benches);
187 changes: 187 additions & 0 deletions snark-verifier-sdk/benches/zkevm_plus_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
use ark_std::{end_timer, start_timer};
use halo2_base::halo2_proofs;
use halo2_base::utils::fs::gen_srs;
use halo2_proofs::halo2curves::bn256::Fr;
use rand::SeedableRng;
use rand_chacha::ChaCha20Rng;
use snark_verifier::loader::native::NativeLoader;
use snark_verifier_sdk::{
self,
evm::{
evm_verify, gen_evm_proof_gwc, gen_evm_proof_shplonk, gen_evm_verifier_gwc,
gen_evm_verifier_shplonk,
},
gen_pk,
halo2::{
aggregation::load_verify_circuit_degree, aggregation::AggregationCircuit, gen_proof_gwc,
gen_proof_shplonk, gen_snark_gwc, gen_snark_shplonk, PoseidonTranscript, POSEIDON_SPEC,
},
CircuitExt,
};
use std::env::{set_var, var};
use std::path::Path;

use criterion::{criterion_group, criterion_main};
use criterion::{BenchmarkId, Criterion};
use pprof::criterion::{Output, PProfProfiler};

pub mod zkevm {
use super::Fr;
use bus_mapping::{circuit_input_builder::CircuitsParams, mock::BlockData};
use eth_types::geth_types::GethData;
use mock::TestContext;
use zkevm_circuits::{
evm_circuit::{witness::block_convert, EvmCircuit},
state_circuit::StateCircuit,
witness::RwMap,
};

pub fn test_evm_circuit() -> EvmCircuit<Fr> {
let empty_data: GethData =
TestContext::<0, 0>::new(None, |_| {}, |_, _| {}, |b, _| b).unwrap().into();

let mut builder = BlockData::new_from_geth_data_with_params(
empty_data.clone(),
CircuitsParams::default(),
)
.new_circuit_input_builder();

builder.handle_block(&empty_data.eth_block, &empty_data.geth_traces).unwrap();

let block = block_convert(&builder.block, &builder.code_db).unwrap();

EvmCircuit::<Fr>::new(block)
}

pub fn test_state_circuit() -> StateCircuit<Fr> {
StateCircuit::new(RwMap::default(), 1 << 16)
}
}

fn bench(c: &mut Criterion) {
let mut rng = ChaCha20Rng::from_entropy();
let mut transcript =
PoseidonTranscript::<NativeLoader, _>::from_spec(vec![], POSEIDON_SPEC.clone());

// === create zkevm evm circuit snark ===
let k: u32 = var("DEGREE")
.unwrap_or_else(|_| {
set_var("DEGREE", "18");
"18".to_owned()
})
.parse()
.unwrap();
let evm_circuit = zkevm::test_evm_circuit();
let state_circuit = zkevm::test_state_circuit();
let params_app = gen_srs(k);
let evm_snark = {
let pk = gen_pk(&params_app, &evm_circuit, Some(Path::new("data/zkevm_evm.pkey")));
gen_snark_gwc(
&params_app,
&pk,
evm_circuit,
&mut transcript,
&mut rng,
Some(Path::new("data/zkevm_evm.snark")),
)
};
let state_snark = {
let pk = gen_pk(&params_app, &state_circuit, Some(Path::new("data/zkevm_state.pkey")));
gen_snark_shplonk(
&params_app,
&pk,
state_circuit,
&mut transcript,
&mut rng,
Some(Path::new("data/zkevm_state.snark")),
)
};
let snarks = [evm_snark, state_snark];
// === finished zkevm evm circuit ===

// === now to do aggregation ===
set_var("VERIFY_CONFIG", "./configs/bench_zkevm_plus_state.config");
let k = load_verify_circuit_degree();
let params = gen_srs(k);

let start1 = start_timer!(|| "Create aggregation circuit");
let agg_circuit = AggregationCircuit::new(&params, snarks, &mut transcript, &mut rng);
end_timer!(start1);

let pk = gen_pk(&params, &agg_circuit, None);

let mut group = c.benchmark_group("shplonk-proof");
group.sample_size(10);
group.bench_with_input(
BenchmarkId::new("zkevm-evm-state-agg", k),
&(&params, &pk, &agg_circuit),
|b, &(params, pk, agg_circuit)| {
b.iter(|| {
let instances = agg_circuit.instances();
gen_proof_shplonk(
params,
pk,
agg_circuit.clone(),
instances,
&mut transcript,
&mut rng,
None,
);
})
},
);
group.finish();

let mut group = c.benchmark_group("gwc-proof");
group.sample_size(10);
group.bench_with_input(
BenchmarkId::new("zkevm-evm-state-agg", k),
&(&params, &pk, &agg_circuit),
|b, &(params, pk, agg_circuit)| {
b.iter(|| {
let instances = agg_circuit.instances();
gen_proof_gwc(
params,
pk,
agg_circuit.clone(),
instances,
&mut transcript,
&mut rng,
None,
);
})
},
);
group.finish();

#[cfg(feature = "loader_evm")]
{
let deployment_code =
gen_evm_verifier_shplonk::<AggregationCircuit>(&params, pk.get_vk(), &(), None::<&str>);

let start2 = start_timer!(|| "Create EVM SHPLONK proof");
let proof = gen_evm_proof_shplonk(
&params,
&pk,
agg_circuit.clone(),
agg_circuit.instances(),
&mut rng,
);
end_timer!(start2);

evm_verify(deployment_code, agg_circuit.instances(), proof);

let deployment_code =
gen_evm_verifier_shplonk::<AggregationCircuit>(&params, pk.get_vk(), &(), None::<&str>);

let start2 = start_timer!(|| "Create EVM GWC proof");
let proof =
gen_evm_proof_gwc(&params, &pk, agg_circuit.clone(), agg_circuit.instances(), &mut rng);
end_timer!(start2);

evm_verify(deployment_code, agg_circuit.instances(), proof);
}
}

criterion_group!(benches, bench);
criterion_main!(benches);
2 changes: 1 addition & 1 deletion snark-verifier-sdk/configs/bench_zkevm.config
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"strategy":"Simple","degree":23,"num_advice":5,"num_lookup_advice":1,"num_fixed":1,"lookup_bits":22,"limb_bits":88,"num_limbs":3}
{"strategy":"Simple","degree":23,"num_advice":[5],"num_lookup_advice":[1],"num_fixed":1,"lookup_bits":22,"limb_bits":88,"num_limbs":3}
2 changes: 1 addition & 1 deletion snark-verifier-sdk/configs/example_evm_accumulator.config
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"strategy":"Simple","degree":21,"num_advice":5,"num_lookup_advice":1,"num_fixed":1,"lookup_bits":20,"limb_bits":88,"num_limbs":3}
{"strategy":"Simple","degree":21,"num_advice":[5],"num_lookup_advice":[1],"num_fixed":1,"lookup_bits":20,"limb_bits":88,"num_limbs":3}
2 changes: 1 addition & 1 deletion snark-verifier-sdk/configs/verify_circuit.config
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"strategy":"Simple","degree":21,"num_advice":4,"num_lookup_advice":1,"num_fixed":1,"lookup_bits":20,"limb_bits":88,"num_limbs":3}
{"strategy":"Simple","degree":21,"num_advice":[4],"num_lookup_advice":[1],"num_fixed":1,"lookup_bits":20,"limb_bits":88,"num_limbs":3}
14 changes: 7 additions & 7 deletions snark-verifier-sdk/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ pub fn gen_evm_proof_shplonk<'params, C: Circuit<Fr>>(
pub fn gen_evm_verifier<C, PCS>(
params: &ParamsKZG<Bn256>,
vk: &VerifyingKey<G1Affine>,
extra_circuit_params: &C::ExtraCircuitParams,
num_instance: Vec<usize>,
path: Option<&Path>,
) -> Vec<u8>
where
Expand All @@ -136,15 +136,15 @@ where
params,
vk,
Config::kzg()
.with_num_instance(C::num_instance(extra_circuit_params))
.with_num_instance(num_instance.clone())
.with_accumulator_indices(C::accumulator_indices()),
);

let loader = EvmLoader::new::<Fq, Fr>();
let protocol = protocol.loaded(&loader);
let mut transcript = EvmTranscript::<_, Rc<EvmLoader>, _, _>::new(&loader);

let instances = transcript.load_instances(C::num_instance(extra_circuit_params));
let instances = transcript.load_instances(num_instance);
let proof = Plonk::<PCS>::read_proof(&svk, &protocol, &instances, &mut transcript);
Plonk::<PCS>::verify(&svk, &dk, &protocol, &instances, &proof);

Expand All @@ -160,19 +160,19 @@ where
pub fn gen_evm_verifier_gwc<C: CircuitExt<Fr>>(
params: &ParamsKZG<Bn256>,
vk: &VerifyingKey<G1Affine>,
extra_circuit_params: &C::ExtraCircuitParams,
num_instance: Vec<usize>,
path: Option<&Path>,
) -> Vec<u8> {
gen_evm_verifier::<C, Kzg<Bn256, Gwc19>>(params, vk, extra_circuit_params, path)
gen_evm_verifier::<C, Kzg<Bn256, Gwc19>>(params, vk, num_instance, path)
}

pub fn gen_evm_verifier_shplonk<C: CircuitExt<Fr>>(
params: &ParamsKZG<Bn256>,
vk: &VerifyingKey<G1Affine>,
extra_circuit_params: &C::ExtraCircuitParams,
num_instance: Vec<usize>,
path: Option<&Path>,
) -> Vec<u8> {
gen_evm_verifier::<C, Kzg<Bn256, Bdfg21>>(params, vk, extra_circuit_params, path)
gen_evm_verifier::<C, Kzg<Bn256, Bdfg21>>(params, vk, num_instance, path)
}

pub fn evm_verify(deployment_code: Vec<u8>, instances: Vec<Vec<Fr>>, proof: Vec<u8>) {
Expand Down
Loading

0 comments on commit a1c07a5

Please sign in to comment.