Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

some code improvements: #14

Merged
merged 4 commits into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ test-evm-trace: ## test evm circuit with real trace
test-state-trace: ## test state circuit with real trace
@cargo test --features prove_verify --release test_state_prove_verify

## commented out for now, waiting for halo2 upstream upgrade
# test-circuit-connect: ## test connect evm circuit & state circuit
# @cargo test --features prove_verify --release test_state_evm_connect

.PHONY: help fmt clippy test test-ci test-evm-trace test-state-trace test-all
7 changes: 5 additions & 2 deletions setup/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use clap::Parser;
use zkevm::utils::{load_or_create_params, load_or_create_seed};
use zkevm::{
circuit::DEGREE,
utils::{load_or_create_params, load_or_create_seed},
};

#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
Expand All @@ -18,7 +21,7 @@ fn main() {

let args = Args::parse();
if let Some(path) = args.params_path {
load_or_create_params(&path).expect("failed to load or create params");
load_or_create_params(&path, *DEGREE).expect("failed to load or create params");
}
if let Some(path) = args.seed_path {
load_or_create_seed(&path).expect("failed to load or create seed");
Expand Down
1 change: 1 addition & 0 deletions zkevm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dotenv = "0.15.0"
env_logger = "0.9.0"
strum = "0.24"
strum_macros = "0.24"
once_cell = "1.8.0"

[features]
default = []
Expand Down
43 changes: 41 additions & 2 deletions zkevm/src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use halo2_proofs::arithmetic::BaseExt;
use halo2_proofs::pairing::bn256::Fr;
use halo2_proofs::plonk::Circuit;
use is_even::IsEven;
use once_cell::sync::Lazy;
use std::collections::HashMap;
use strum::IntoEnumIterator;
use types::eth::{AccountProofWrapper, BlockResult};
Expand All @@ -15,7 +16,26 @@ use zkevm_circuits::evm_circuit::test::TestCircuit;
use zkevm_circuits::evm_circuit::witness::{block_convert, Block, RwMap};
use zkevm_circuits::state_circuit::StateCircuit;

pub static DEGREE: usize = 18;
use crate::utils::read_env_var;

pub static DEGREE: Lazy<usize> = Lazy::new(|| read_env_var("DEGREE", 18));

/// For keygen_vk.
pub fn create_evm_circuit() -> TestCircuit<Fr> {
let default_block = Block::<Fr> {
pad_to: (1 << *DEGREE) - 64,
..Default::default()
};

// hack but useful
let tags = if *DEGREE <= 16 {
get_fixed_table_tags_for_block(&default_block)
} else {
FixedTableTag::iter().collect()
};

TestCircuit::new(default_block, tags)
}

/// For keygen_vk.
pub fn create_state_circuit() -> StateCircuit<Fr> {
Expand Down Expand Up @@ -53,7 +73,7 @@ pub fn block_result_to_circuits<F: Field>(
builder.handle_block(&eth_block, geth_trace.as_slice())?;

let mut witness_block = block_convert(&builder.block, &builder.code_db);
witness_block.pad_to = (1 << DEGREE) - 64;
witness_block.pad_to = (1 << *DEGREE) - 64;

Ok((
witness_block.clone(),
Expand Down Expand Up @@ -180,3 +200,22 @@ fn trace_proof(sdb: &mut StateDB, proof: Option<AccountProofWrapper>) {
},
)
}

fn get_fixed_table_tags_for_block(block: &Block<Fr>) -> Vec<FixedTableTag> {
let need_bitwise_lookup = block.txs.iter().any(|tx| {
tx.steps.iter().any(|step| {
matches!(
step.opcode,
Some(OpcodeId::AND) | Some(OpcodeId::OR) | Some(OpcodeId::XOR)
)
})
});
FixedTableTag::iter()
.filter(|t| {
!matches!(
t,
FixedTableTag::BitwiseAnd | FixedTableTag::BitwiseOr | FixedTableTag::BitwiseXor
) || need_bitwise_lookup
})
.collect()
}
25 changes: 7 additions & 18 deletions zkevm/src/keygen.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
use crate::circuit::{create_state_circuit, DEGREE};
use halo2_proofs::pairing::bn256::{Fr, G1Affine};
use halo2_proofs::plonk::{keygen_pk, keygen_vk, Circuit, Error, ProvingKey, VerifyingKey};
use crate::circuit::{create_evm_circuit, create_state_circuit};
use halo2_proofs::pairing::bn256::G1Affine;
use halo2_proofs::plonk::{keygen_pk, keygen_vk, Error, ProvingKey, VerifyingKey};
use halo2_proofs::poly::commitment::Params;
use strum::IntoEnumIterator;
use zkevm_circuits::evm_circuit::table::FixedTableTag;
use zkevm_circuits::evm_circuit::test::TestCircuit;
use zkevm_circuits::evm_circuit::witness::Block;

/// generate evm_circuit verifying key
pub fn gen_evm_vk(params: &Params<G1Affine>) -> Result<VerifyingKey<G1Affine>, Error> {
keygen_vk(params, &test_circuit())
let evm_circuit = create_evm_circuit();
keygen_vk(params, &evm_circuit)
}

/// generate evm_circuit proving key
pub fn gen_evm_pk(params: &Params<G1Affine>) -> Result<ProvingKey<G1Affine>, Error> {
let evm_circuit = create_evm_circuit();
let evm_vk = gen_evm_vk(params)?;
keygen_pk(params, evm_vk, &test_circuit())
keygen_pk(params, evm_vk, &evm_circuit)
}

/// generate state_circuit verifying key
Expand All @@ -30,12 +28,3 @@ pub fn gen_state_pk(params: &Params<G1Affine>) -> Result<ProvingKey<G1Affine>, E
let state_circuit = create_state_circuit();
keygen_pk(params, state_vk, &state_circuit)
}

fn test_circuit() -> impl Circuit<Fr> {
let default_block = Block::<Fr> {
pad_to: (1 << DEGREE) - 64,
..Default::default()
};

TestCircuit::new(default_block, FixedTableTag::iter().collect())
}
19 changes: 7 additions & 12 deletions zkevm/src/prover.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::circuit::block_result_to_circuits;
use crate::circuit::{block_result_to_circuits, DEGREE};
use crate::keygen::{gen_evm_pk, gen_state_pk};
use crate::utils::{load_params, load_randomness, load_seed};
use anyhow::Error;
Expand Down Expand Up @@ -43,22 +43,16 @@ impl Prover {
}

pub fn from_fpath(params_fpath: &str, seed_fpath: &str) -> Self {
let params = load_params(params_fpath).expect("failed to init params");
let params = load_params(params_fpath, *DEGREE).expect("failed to init params");
let seed = load_seed(seed_fpath).expect("failed to init rng");
let rng = XorShiftRng::from_seed(seed);
let evm_pk = gen_evm_pk(&params).expect("Failed to generate evm_circuit proving key");
let state_pk = gen_state_pk(&params).expect("Failed to generate state_circuit proving key");
Self {
params,
rng,
evm_pk,
state_pk,
}
Self::from_params_and_rng(params, rng)
}

pub fn create_evm_proof(&self, block_result: &BlockResult) -> Result<Vec<u8>, Error> {
let (_, circuit, _) = block_result_to_circuits::<Fr>(block_result)?;
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
let public_inputs: &[&[&[Fr]]] = &[&[]];

info!(
"Create evm proof of block {}",
Expand All @@ -68,7 +62,7 @@ impl Prover {
&self.params,
&self.evm_pk,
&[circuit],
&[&[]],
public_inputs,
self.rng.clone(),
&mut transcript,
)?;
Expand All @@ -83,6 +77,7 @@ impl Prover {
let (block, _, circuit) = block_result_to_circuits::<Fr>(block_result).unwrap();
let power_of_randomness = load_randomness(block);
let randomness: Vec<_> = power_of_randomness.iter().map(AsRef::as_ref).collect();
let public_inputs: &[&[&[Fr]]] = &[&randomness];

let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);

Expand All @@ -94,7 +89,7 @@ impl Prover {
&self.params,
&self.state_pk,
&[circuit],
&[&randomness],
public_inputs,
self.rng.clone(),
&mut transcript,
)?;
Expand Down
45 changes: 34 additions & 11 deletions zkevm/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::circuit::DEGREE;
use anyhow::Result;
use halo2_proofs::pairing::bn256::{Bn256, Fr, G1Affine};
use halo2_proofs::poly::commitment::Params;
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io::{BufReader, Read, Result, Write};
use std::io::{BufReader, Read, Write};
use std::path::Path;
use std::str::FromStr;
use types::eth::BlockResult;
use zkevm_circuits::evm_circuit::witness::Block;
use zkevm_circuits::state_circuit::StateCircuit;
Expand All @@ -20,27 +21,43 @@ pub fn load_randomness(block: Block<Fr>) -> Vec<Box<[Fr]>> {
}

/// return setup params by reading from file or generate new one
pub fn load_or_create_params(params_path: &str) -> Result<Params<G1Affine>> {
pub fn load_or_create_params(params_path: &str, degree: usize) -> Result<Params<G1Affine>> {
if Path::new(params_path).exists() {
load_params(params_path)
} else {
create_params(params_path)
match load_params(params_path, degree) {
Ok(r) => return Ok(r),
Err(e) => {
log::error!("load params err: {}. Recreating...", e)
}
}
}
create_params(params_path, degree)
}

/// load params from file
pub fn load_params(params_path: &str) -> Result<Params<G1Affine>> {
log::info!("start load params");
pub fn load_params(params_path: &str, degree: usize) -> Result<Params<G1Affine>> {
log::info!("start loading params with degree {}", degree);
let f = File::open(params_path)?;

// check params file length:
// len: 4 bytes
// g: 2**DEGREE g1 points, each 32 bytes(256bits)
// g_lagrange: 2**DEGREE g1 points, each 32 bytes(256bits)
// len of additional data: 4 bytes
// additional data: 1 g2 point, 64 bytes
let file_size = f.metadata()?.len();
if file_size != (1 << degree) * 64 + 72 {
return Err(anyhow::format_err!("invalid params file len {} for degree {}. check DEGREE or remove the invalid params file", file_size, degree));
}

let p = Params::read::<_>(&mut BufReader::new(f))?;
log::info!("load params successfully!");
Ok(p)
}

/// create params and write it into file
pub fn create_params(params_path: &str) -> Result<Params<G1Affine>> {
log::info!("start create params");
let params: Params<G1Affine> = Params::<G1Affine>::unsafe_setup::<Bn256>(DEGREE as u32);
pub fn create_params(params_path: &str, degree: usize) -> Result<Params<G1Affine>> {
log::info!("start creating params with degree {}", degree);
let params: Params<G1Affine> = Params::<G1Affine>::unsafe_setup::<Bn256>(degree as u32);
let mut params_buf = Vec::new();
params.write(&mut params_buf)?;

Expand Down Expand Up @@ -95,3 +112,9 @@ pub fn get_block_result_from_file<P: AsRef<Path>>(path: P) -> BlockResult {

j.result
}

pub fn read_env_var<T: Clone + FromStr>(var_name: &'static str, default: T) -> T {
std::env::var(var_name)
.map(|s| s.parse::<T>().unwrap_or_else(|_| default.clone()))
.unwrap_or(default)
}
28 changes: 12 additions & 16 deletions zkevm/src/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::circuit::block_result_to_circuits;
use crate::circuit::{block_result_to_circuits, DEGREE};
use crate::keygen::{gen_evm_vk, gen_state_vk};
use crate::utils::{load_params, load_randomness};
use halo2_proofs::pairing::bn256::{Bn256, Fr, G1Affine};
Expand Down Expand Up @@ -37,24 +37,19 @@ impl Verifier {
}

pub fn from_fpath(params_path: &str) -> Self {
let params = load_params(params_path).expect("failed to init params");
let evm_vk = gen_evm_vk(&params).expect("Failed to generate evm_circuit verifier key");
let state_vk =
gen_state_vk(&params).expect("Failed to generate state_circuit verifier key");
Self {
params,
evm_vk,
state_vk,
}
let params = load_params(params_path, *DEGREE).expect("failed to init params");
Self::from_params(params)
}

pub fn verify_evm_proof(&self, proof: Vec<u8>, block_result: &BlockResult) -> bool {
let (block, _, _) = block_result_to_circuits::<Fr>(block_result).unwrap();
let power_of_randomness = load_randomness(block);
let power_of_randomness: Vec<_> = power_of_randomness.iter().map(AsRef::as_ref).collect();
let _power_of_randomness: Vec<_> = power_of_randomness.iter().map(AsRef::as_ref).collect();
let public_input: &[&[&[Fr]]] = &[&[]];
let public_input_len = 0;

let verifier_params: ParamsVerifier<Bn256> =
self.params.verifier(power_of_randomness[0].len()).unwrap();
self.params.verifier(public_input_len).unwrap();

let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
let strategy = SingleVerifier::new(&verifier_params);
Expand All @@ -63,7 +58,7 @@ impl Verifier {
&verifier_params,
&self.evm_vk,
strategy,
&[&[]],
public_input,
&mut transcript,
)
.is_ok()
Expand All @@ -73,9 +68,10 @@ impl Verifier {
let (block, _, _) = block_result_to_circuits::<Fr>(block_result).unwrap();
let power_of_randomness = load_randomness(block);
let power_of_randomness: Vec<_> = power_of_randomness.iter().map(AsRef::as_ref).collect();

let public_input: &[&[&[Fr]]] = &[&power_of_randomness];
let public_input_len = power_of_randomness[0].len();
let verifier_params: ParamsVerifier<Bn256> =
self.params.verifier(power_of_randomness[0].len()).unwrap();
self.params.verifier(public_input_len).unwrap();

let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
let strategy = SingleVerifier::new(&verifier_params);
Expand All @@ -84,7 +80,7 @@ impl Verifier {
&verifier_params,
&self.state_vk,
strategy,
&[&power_of_randomness],
public_input,
&mut transcript,
)
.is_ok()
Expand Down
Loading