Skip to content

Commit

Permalink
[feat] expand circuit unit tests with aggregation and evm verificatio…
Browse files Browse the repository at this point in the history
…n; two layers recursion unit test
  • Loading branch information
zhenfeizhang committed Mar 31, 2023
1 parent 99493fd commit 377b355
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 9 deletions.
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":24,"num_advice":[5],"num_lookup_advice":[1],"num_fixed":1,"lookup_bits":20,"limb_bits":88,"num_limbs":3}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"strategy":"Simple","degree":25,"num_advice":[21],"num_lookup_advice":[2],"num_fixed":1,"lookup_bits":20,"limb_bits":88,"num_limbs":3}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"strategy":"Simple","degree":26,"num_advice":[1],"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/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ pub fn evm_verify(deployment_code: Vec<u8>, instances: Vec<Vec<Fr>>, proof: Vec<
let verifier = evm.deploy(caller, deployment_code.into(), 0.into()).address.unwrap();
let result = evm.call_raw(caller, verifier, calldata.into(), 0.into());

dbg!(result.gas_used);
log::info!("gas used: {}", result.gas_used);

!result.reverted
};
Expand Down
174 changes: 170 additions & 4 deletions snark-verifier-sdk/src/evm_circuits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ mod super_circuit;
#[cfg(all(test, feature = "zkevm"))]
mod test {
use crate::{
evm::{evm_verify, gen_evm_proof_shplonk, gen_evm_verifier_shplonk},
gen_pk,
halo2::{gen_snark_shplonk, verify_snark_shplonk},
halo2::{aggregation::AggregationCircuit, gen_snark_shplonk, verify_snark_shplonk},
CircuitExt,
};
use ark_std::test_rng;
use ark_std::{end_timer, start_timer, test_rng};
use bus_mapping::{circuit_input_builder::CircuitsParams, mock::BlockData};
use eth_types::{address, bytecode, geth_types::GethData, U256};
use ethers_signers::{LocalWallet, Signer};
Expand All @@ -38,6 +39,7 @@ mod test {
};

const TEST_CURRENT_K: u32 = 19;
const TEST_AGG_K: u32 = 24;
const TEST_MAX_CALLDATA: usize = 3200;
const TEST_MAX_INNER_BLOCKS: usize = 1;
const TEST_MAX_TXS: usize = 1;
Expand Down Expand Up @@ -161,15 +163,179 @@ mod test {
}

fn verify_circuit<C: CircuitExt<Fr>>(circuit: C) -> bool {
env::set_var("VERIFY_CONFIG", "./configs/verify_circuit.config");
std::env::set_var("VERIFY_CONFIG", "./configs/example_evm_accumulator.config");

let mut rng = test_rng();
let params = gen_srs(TEST_CURRENT_K);
let params_outer = gen_srs(TEST_AGG_K);
log::info!("finished parameter generation");

let pk = gen_pk(&params, &circuit, None);
let vk = pk.get_vk();
log::info!("finished key extraction");

let snark = gen_snark_shplonk(&params, &pk, circuit, &mut rng, None::<String>);
verify_snark_shplonk::<C>(&params, snark, vk)
log::info!("finished snark generation");

if !verify_snark_shplonk::<C>(&params, snark.clone(), vk) {
log::error!("snark verification failed");
return false;
}
log::info!("snark verification succeeded");

let agg_circuit = AggregationCircuit::new(&params_outer, [snark], &mut rng);
let pk_outer = gen_pk(&params_outer, &agg_circuit, None);

log::info!("finished aggregation circuit generation");

let instances = agg_circuit.instances();
let proof = gen_evm_proof_shplonk(
&params_outer,
&pk_outer,
agg_circuit.clone(),
instances.clone(),
&mut rng,
);

log::info!("finished aggregation proof generation");

let deployment_code = gen_evm_verifier_shplonk::<AggregationCircuit>(
&params_outer,
pk_outer.get_vk(),
agg_circuit.num_instance(),
None,
);
log::info!("finished byte code generation");
evm_verify(deployment_code, instances, proof);
log::info!("EVM verification succeeded");
true
}

#[test]
fn super_circuit_two_layer_recursion() {
let mut rng = test_rng();
let params = gen_srs(TEST_CURRENT_K);
let params_layer_1 = gen_srs(25);
let params_layer_2 = gen_srs(25);
log::info!("finished parameter generation");

//
// load circuit and generate first layer proof
//
let super_circuit_snark = {
let circuit = build_circuit::<
SuperCircuit<
Fr,
TEST_MAX_TXS,
TEST_MAX_CALLDATA,
TEST_MAX_INNER_BLOCKS,
TEST_MOCK_RANDOMNESS,
>,
>();
log::info!("finished super circuit generation");

let pk = gen_pk(&params, &circuit, None);
let vk = pk.get_vk();
log::info!("finished key extraction");
log::info!("domain size {}", vk.get_domain().k());
let super_circuit_timer = start_timer!(|| "super circuit snark gen");
let super_circuit_snark =
gen_snark_shplonk(&params, &pk, circuit, &mut rng, None::<String>);
end_timer!(super_circuit_timer);

let super_circuit_timer = start_timer!(|| "super circuit rust verify (optional)");
if !verify_snark_shplonk::<
SuperCircuit<
Fr,
TEST_MAX_TXS,
TEST_MAX_CALLDATA,
TEST_MAX_INNER_BLOCKS,
TEST_MOCK_RANDOMNESS,
>,
>(&params, super_circuit_snark.clone(), vk)
{
log::error!("super circuit snark verification failed");
return;
}
log::info!("super circuit snark verification succeeded");
end_timer!(super_circuit_timer);
super_circuit_snark
};
//
// build first layer recursion proof
//
std::env::set_var("VERIFY_CONFIG", "./configs/two_layer_recursion_first_layer.config");
let layer_1_snark = {
let agg_circuit =
AggregationCircuit::new(&params_layer_1, [super_circuit_snark], &mut rng);
let pk = gen_pk(&params_layer_1, &agg_circuit, None);
let vk = pk.get_vk();
log::info!("domain size {}", vk.get_domain().k());

log::info!("finished layer 1 aggregation circuit generation");
let layer_1_circuit_timer = start_timer!(|| "layer 1 circuit snark gen");
let layer_1_snark = gen_snark_shplonk(
&params_layer_1,
&pk,
agg_circuit.clone(),
&mut rng,
None::<String>,
);
end_timer!(layer_1_circuit_timer);

let layer_1_circuit_timer = start_timer!(|| "layer 1 circuit rust verify (optional)");
if !verify_snark_shplonk::<
SuperCircuit<
Fr,
TEST_MAX_TXS,
TEST_MAX_CALLDATA,
TEST_MAX_INNER_BLOCKS,
TEST_MOCK_RANDOMNESS,
>,
>(&params_layer_1, layer_1_snark.clone(), vk)
{
log::error!("layer 1 snark verification failed");
return;
}
log::info!("layer 1 snark verification succeeded");
end_timer!(layer_1_circuit_timer);
layer_1_snark
};
//
// verify layer 1 snark with evm
//
{
std::env::set_var("VERIFY_CONFIG", "./configs/two_layer_recursion_second_layer.config");

let agg_circuit = AggregationCircuit::new(&params_layer_2, [layer_1_snark], &mut rng);
let pk_outer = gen_pk(&params_layer_2, &agg_circuit, None);
log::info!("finished layer 2 aggregation circuit generation");
log::info!("domain size {}", pk_outer.get_vk().get_domain().k());

let instances = agg_circuit.instances();
let layer_2_circuit_timer = start_timer!(|| "layer 2 circuit snark gen");
let proof = gen_evm_proof_shplonk(
&params_layer_2,
&pk_outer,
agg_circuit.clone(),
instances.clone(),
&mut rng,
);
end_timer!(layer_2_circuit_timer);
log::info!("finished layer 2 aggregation proof generation");

let layer_2_circuit_timer = start_timer!(|| "layer 2 circuit evm verify");
let deployment_code = gen_evm_verifier_shplonk::<AggregationCircuit>(
&params_layer_2,
pk_outer.get_vk(),
agg_circuit.num_instance(),
None,
);
log::info!("finished byte code generation");

evm_verify(deployment_code, instances, proof);
end_timer!(layer_2_circuit_timer);
log::info!("EVM verification succeeded");
}
}
}
6 changes: 3 additions & 3 deletions snark-verifier-sdk/src/halo2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use halo2_base::halo2_proofs::{
};
use halo2_proofs::{
circuit::Layouter,
dev::MockProver,
halo2curves::{
bn256::{Bn256, Fr, G1Affine},
group::ff::Field,
Expand All @@ -16,7 +15,7 @@ use halo2_proofs::{
VerifyingKey,
},
poly::{
commitment::{Params, ParamsProver, Prover, Verifier},
commitment::{ParamsProver, Prover, Verifier},
kzg::{
commitment::{KZGCommitmentScheme, ParamsKZG},
msm::DualMSM,
Expand Down Expand Up @@ -91,7 +90,8 @@ where
{
#[cfg(debug_assertions)]
{
MockProver::run(params.k(), &circuit, instances.clone()).unwrap().assert_satisfied();
use halo2_proofs::poly::commitment::Params;
halo2_proofs::dev::MockProver::run(params.k(), &circuit, instances.clone()).unwrap().assert_satisfied();
}

if let Some((instance_path, proof_path)) = path {
Expand Down
2 changes: 2 additions & 0 deletions super.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ for c in evm state poseidon mpt super
do
RUST_BACKTRACE=1 RUST_LOG=debug cargo test -F zkevm --release -- --nocapture test_${c}_circuit_verification 2>&1 | tee ${c}.log
done

RUST_BACKTRACE=1 RUST_LOG=debug cargo test -F zkevm --release -- --nocapture super_circuit_two_layer_recursion 2>&1 | tee super_2_layers.log

0 comments on commit 377b355

Please sign in to comment.