Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
lispc committed Apr 27, 2023
2 parents a31d7eb + ab6a91a commit cb26abb
Show file tree
Hide file tree
Showing 23 changed files with 212 additions and 30 deletions.
13 changes: 8 additions & 5 deletions circuit-benchmarks/src/bytecode_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ mod tests {
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::env::var;
use zkevm_circuits::bytecode_circuit::bytecode_unroller::{unroll, UnrolledBytecode};

use zkevm_circuits::bytecode_circuit::TestBytecodeCircuit;
use zkevm_circuits::{
bytecode_circuit::{
bytecode_unroller::{unroll, UnrolledBytecode},
TestBytecodeCircuit,
},
util::SubCircuit,
};

#[cfg_attr(not(feature = "benches"), ignore)]
#[test]
Expand All @@ -45,8 +49,7 @@ mod tests {
const MAX_BYTECODE_LEN: usize = 24576;

let num_rows = 1 << degree;
const NUM_BLINDING_ROWS: usize = 7 - 1;
let max_bytecode_row_num = num_rows - NUM_BLINDING_ROWS;
let max_bytecode_row_num = num_rows - TestBytecodeCircuit::<Fr>::unusable_rows();
let bytecode_len = std::cmp::min(MAX_BYTECODE_LEN, max_bytecode_row_num);
let bytecodes_num: usize = max_bytecode_row_num / bytecode_len;

Expand Down
7 changes: 5 additions & 2 deletions circuit-benchmarks/src/packed_multi_keccak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod tests {
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::env::var;
use zkevm_circuits::keccak_circuit::TestKeccakCircuit;
use zkevm_circuits::{keccak_circuit::TestKeccakCircuit, util::SubCircuit};

#[cfg_attr(not(feature = "benches"), ignore)]
#[test]
Expand All @@ -41,7 +41,10 @@ mod tests {
let inputs = vec![(0u8..135).collect::<Vec<_>>(); 3];

// Create the circuit. Leave last dozens of rows for blinding.
let circuit = TestKeccakCircuit::new(2usize.pow(degree) - 64, inputs);
let circuit = TestKeccakCircuit::new(
2usize.pow(degree) - TestKeccakCircuit::<Fr>::unusable_rows(),
inputs,
);

// Initialize the polynomial commitment parameters
let mut rng = XorShiftRng::from_seed([
Expand Down
15 changes: 7 additions & 8 deletions zkevm-circuits/src/bytecode_circuit/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,15 +936,14 @@ impl<F: Field> SubCircuit<F> for BytecodeCircuit<F> {
#[cfg(not(feature = "poseidon-codehash"))]
type Config = BytecodeCircuitConfig<F>;

fn unusable_rows() -> usize {
// No column queried at more than 3 distinct rotations, so returns 6 as
// minimum unusable rows.
6
}

fn new_from_block(block: &witness::Block<F>) -> Self {
// TODO: Find a nicer way to add the extra `128`. Is this to account for
// unusable rows? Then it could be calculated like this:
// fn unusable_rows<F: Field, C: Circuit<F>>() -> usize {
// let mut cs = ConstraintSystem::default();
// C::configure(&mut cs);
// cs.blinding_factors()
// }
let bytecode_size = block.circuits_params.max_bytecode + 128;
let bytecode_size = block.circuits_params.max_bytecode;
Self::new_from_block_sized(block, bytecode_size)
}

Expand Down
10 changes: 9 additions & 1 deletion zkevm-circuits/src/bytecode_circuit/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
use crate::{
bytecode_circuit::{bytecode_unroller::*, circuit::BytecodeCircuit},
table::BytecodeFieldTag,
util::{is_push, keccak, Challenges, SubCircuit},
util::{is_push, keccak, unusable_rows, Challenges, SubCircuit},
};
use bus_mapping::{evm::OpcodeId, state_db::CodeDB};
use eth_types::{Bytecode, Field, ToWord, Word};
use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr};
use log::error;

#[test]
fn bytecode_circuit_unusable_rows() {
assert_eq!(
BytecodeCircuit::<Fr>::unusable_rows(),
unusable_rows::<Fr, BytecodeCircuit::<Fr>>(),
)
}

impl<F: Field> BytecodeCircuit<F> {
/// Verify that the selected bytecode fulfills the circuit
pub fn verify_raw(k: u32, bytecodes: Vec<Vec<u8>>) {
Expand Down
6 changes: 6 additions & 0 deletions zkevm-circuits/src/copy_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,12 @@ impl<F: Field> CopyCircuit<F> {
impl<F: Field> SubCircuit<F> for CopyCircuit<F> {
type Config = CopyCircuitConfig<F>;

fn unusable_rows() -> usize {
// No column queried at more than 3 distinct rotations, so returns 6 as
// minimum unusable rows.
6
}

fn new_from_block(block: &witness::Block<F>) -> Self {
Self::new_with_external_data(
block.copy_events.clone(),
Expand Down
9 changes: 9 additions & 0 deletions zkevm-circuits/src/copy_circuit/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use crate::{
copy_circuit::*,
evm_circuit::{test::rand_bytes, witness::block_convert},
util::unusable_rows,
witness::Block,
};
use bus_mapping::{
Expand All @@ -17,6 +18,14 @@ use halo2_proofs::{
};
use mock::{test_ctx::helpers::account_0_code_account_1_no_code, TestContext, MOCK_ACCOUNTS};

#[test]
fn copy_circuit_unusable_rows() {
assert_eq!(
CopyCircuit::<Fr>::unusable_rows(),
unusable_rows::<Fr, CopyCircuit::<Fr>>(),
)
}

/// Test copy circuit from copy events and test data
pub fn test_copy_circuit<F: Field>(
k: u32,
Expand Down
16 changes: 16 additions & 0 deletions zkevm-circuits/src/evm_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub use self::EvmCircuit as TestEvmCircuit;

pub use crate::witness;
use crate::{
evm_circuit::param::{MAX_STEP_HEIGHT, STEP_STATE_HEIGHT},
table::{
BlockTable, BytecodeTable, CopyTable, ExpTable, KeccakTable, LookupTable, RwTable, TxTable,
},
Expand Down Expand Up @@ -245,6 +246,12 @@ impl<F: Field> EvmCircuit<F> {
impl<F: Field> SubCircuit<F> for EvmCircuit<F> {
type Config = EvmCircuitConfig<F>;

fn unusable_rows() -> usize {
// Most columns are queried at MAX_STEP_HEIGHT + STEP_STATE_HEIGHT distinct rotations, so
// returns (MAX_STEP_HEIGHT + STEP_STATE_HEIGHT + 3) unusable rows.
MAX_STEP_HEIGHT + STEP_STATE_HEIGHT + 3
}

fn new_from_block(block: &witness::Block<F>) -> Self {
Self::new(block.clone())
}
Expand Down Expand Up @@ -464,6 +471,7 @@ mod evm_circuit_stats {
},
stats::print_circuit_stats_by_states,
test_util::CircuitTestBuilder,
util::{unusable_rows, SubCircuit},
witness::block_convert,
};
use bus_mapping::{circuit_input_builder::CircuitsParams, mock::BlockData};
Expand All @@ -483,6 +491,14 @@ mod evm_circuit_stats {
MOCK_ACCOUNTS,
};

#[test]
fn evm_circuit_unusable_rows() {
assert_eq!(
EvmCircuit::<Fr>::unusable_rows(),
unusable_rows::<Fr, EvmCircuit::<Fr>>(),
)
}

#[test]
pub fn empty_evm_circuit_no_padding() {
CircuitTestBuilder::new_from_test_ctx(
Expand Down
23 changes: 23 additions & 0 deletions zkevm-circuits/src/exp_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,29 @@ impl<F: Field> ExpCircuit<F> {
impl<F: Field> SubCircuit<F> for ExpCircuit<F> {
type Config = ExpCircuitConfig<F>;

fn unusable_rows() -> usize {
// Column base_limb of ExpTable is queried at 8 distinct rotations at
// - Rotation(0)
// - Rotation(1)
// - Rotation(2)
// - Rotation(3)
// - Rotation(7)
// - Rotation(8)
// - Rotation(9)
// - Rotation(10)
// Also column col2 and col3 of are queried at 8 distinct rotations at
// - Rotation(0)
// - Rotation(1)
// - Rotation(2)
// - Rotation(3)
// - Rotation(4)
// - Rotation(5)
// - Rotation(6)
// - Rotation(9)
// so returns 11 unusable rows.
11
}

fn new_from_block(block: &witness::Block<F>) -> Self {
// Hardcoded to pass unit tests for now. In the future, insert:
// "block.circuits_params.max_exp_rows"
Expand Down
9 changes: 9 additions & 0 deletions zkevm-circuits/src/exp_circuit/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use crate::{
evm_circuit::witness::{block_convert, Block},
exp_circuit::ExpCircuit,
util::{unusable_rows, SubCircuit},
};
use bus_mapping::{
circuit_input_builder::{CircuitInputBuilder, CircuitsParams},
Expand All @@ -14,6 +15,14 @@ use halo2_proofs::{
};
use mock::TestContext;

#[test]
fn exp_circuit_unusable_rows() {
assert_eq!(
ExpCircuit::<Fr>::unusable_rows(),
unusable_rows::<Fr, ExpCircuit::<Fr>>(),
)
}

/// Test exponentiation circuit with the provided block witness
pub fn test_exp_circuit<F: Field>(k: u32, block: Block<F>) {
let circuit = ExpCircuit::<F>::new(
Expand Down
6 changes: 5 additions & 1 deletion zkevm-circuits/src/keccak_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use KeccakCircuitConfig as KeccakConfig;

use self::{
cell_manager::*,
keccak_packed_multi::{multi_keccak, KeccakRow},
keccak_packed_multi::{keccak_unusable_rows, multi_keccak, KeccakRow},
param::*,
table::*,
util::*,
Expand Down Expand Up @@ -990,6 +990,10 @@ pub struct KeccakCircuit<F: Field> {
impl<F: Field> SubCircuit<F> for KeccakCircuit<F> {
type Config = KeccakCircuitConfig<F>;

fn unusable_rows() -> usize {
keccak_unusable_rows()
}

/// The `block.circuits_params.keccak_padding` parmeter, when enabled, sets
/// up the circuit to support a fixed number of permutations/keccak_f's,
/// independently of the permutations required by `inputs`.
Expand Down
10 changes: 9 additions & 1 deletion zkevm-circuits/src/keccak_circuit/keccak_packed_multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,19 @@ const MAX_DEGREE: usize = 9;

pub(crate) fn get_num_rows_per_round() -> usize {
var("KECCAK_ROWS")
.unwrap_or_else(|_| "20".to_string())
.unwrap_or_else(|_| format!("{DEFAULT_KECCAK_ROWS}"))
.parse()
.expect("Cannot parse KECCAK_ROWS env var as usize")
}

pub(crate) fn keccak_unusable_rows() -> usize {
const UNUSABLE_ROWS_BY_KECCAK_ROWS: [usize; 24] = [
53, 67, 63, 59, 45, 79, 77, 75, 73, 71, 69, 67, 65, 63, 61, 59, 57, 71, 89, 107, 107, 107,
107, 107,
];
UNUSABLE_ROWS_BY_KECCAK_ROWS[get_num_rows_per_round() - NUM_BYTES_PER_WORD - 1]
}

pub(crate) fn get_num_bits_per_absorb_lookup() -> usize {
get_num_bits_per_lookup(ABSORB_LOOKUP_RANGE)
}
Expand Down
1 change: 1 addition & 0 deletions zkevm-circuits/src/keccak_circuit/param.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub(crate) const MAX_DEGREE: usize = 9;
pub(crate) const DEFAULT_KECCAK_ROWS: usize = 12;
pub(crate) const ABSORB_LOOKUP_RANGE: usize = 3;
pub(crate) const THETA_C_LOOKUP_RANGE: usize = 6;
pub(crate) const RHO_PI_LOOKUP_RANGE: usize = 4;
Expand Down
16 changes: 16 additions & 0 deletions zkevm-circuits/src/keccak_circuit/test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(unused_imports)]
use super::*;
use crate::util::unusable_rows;
use eth_types::Field;
use halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner},
Expand All @@ -12,6 +13,21 @@ use std::iter::zip;

use super::util::{target_part_sizes, target_part_sizes_rot, WordParts};

// This needs to be tested independent since it sets the environment variable
// which might affect other tests.
#[ignore]
#[test]
fn serial_keccak_circuit_unusable_rows() {
for keccak_rows in NUM_BYTES_PER_WORD + 1..=32 {
std::env::set_var("KECCAK_ROWS", format!("{keccak_rows}"));
assert_eq!(
KeccakCircuit::<Fr>::unusable_rows(),
unusable_rows::<Fr, KeccakCircuit::<Fr>>(),
)
}
std::env::set_var("KECCAK_ROWS", format!("{DEFAULT_KECCAK_ROWS}"));
}

fn verify<F: Field>(k: u32, inputs: Vec<Vec<u8>>, success: bool) {
let circuit = KeccakCircuit::new(2usize.pow(k), inputs);

Expand Down
4 changes: 2 additions & 2 deletions zkevm-circuits/src/keccak_circuit/util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Utility traits, functions used in the crate.
use super::param::*;
use super::{keccak_packed_multi::keccak_unusable_rows, param::*};
use eth_types::{Field, ToScalar, Word};
use halo2_proofs::{circuit::Value, halo2curves::FieldExt};
use std::env::var;
Expand Down Expand Up @@ -224,7 +224,7 @@ pub fn get_num_bits_per_lookup(range: usize) -> usize {

// Implementation of the above without environment dependency.
pub(crate) fn get_num_bits_per_lookup_impl(range: usize, log_height: usize) -> usize {
let num_unusable_rows = 31;
let num_unusable_rows = keccak_unusable_rows();
let height = 2usize.pow(log_height as u32);
let mut num_bits = 1;
while range.pow(num_bits + 1) + num_unusable_rows <= height {
Expand Down
4 changes: 4 additions & 0 deletions zkevm-circuits/src/pi_circuit/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ impl<F: Field, const MAX_TXS: usize, const MAX_CALLDATA: usize> SubCircuit<F>
{
type Config = PiCircuitConfig<F>;

fn unusable_rows() -> usize {
PiCircuit::<F>::unusable_rows()
}

fn new_from_block(block: &witness::Block<F>) -> Self {
assert_eq!(block.circuits_params.max_txs, MAX_TXS);
assert_eq!(block.circuits_params.max_calldata, MAX_CALLDATA);
Expand Down
11 changes: 11 additions & 0 deletions zkevm-circuits/src/pi_circuit/test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(unused_imports)]
use super::{dev::*, *};
use crate::util::unusable_rows;
use halo2_proofs::{
dev::{MockProver, VerifyFailure},
halo2curves::bn256::Fr,
Expand All @@ -8,6 +9,16 @@ use mock::{CORRECT_MOCK_TXS, MOCK_CHAIN_ID};
use rand::SeedableRng;
use rand_chacha::ChaCha20Rng;

#[test]
fn pi_circuit_unusable_rows() {
const MAX_TXS: usize = 2;
const MAX_CALLDATA: usize = 8;
assert_eq!(
PiCircuit::<Fr>::unusable_rows(),
unusable_rows::<Fr, PiTestCircuit::<Fr, MAX_TXS, MAX_CALLDATA>>(),
)
}

fn run<F: Field, const MAX_TXS: usize, const MAX_CALLDATA: usize>(
k: u32,
public_data: PublicData,
Expand Down
6 changes: 6 additions & 0 deletions zkevm-circuits/src/state_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,12 @@ impl<F: Field> SubCircuit<F> for StateCircuit<F> {
}
}

fn unusable_rows() -> usize {
// No column queried at more than 3 distinct rotations, so returns 6 as
// minimum unusable rows.
6
}

/// Return the minimum number of rows required to prove the block
fn min_num_rows_block(block: &witness::Block<F>) -> (usize, usize) {
(
Expand Down
10 changes: 9 additions & 1 deletion zkevm-circuits/src/state_circuit/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pub use super::{dev::*, *};
use crate::{
table::{AccountFieldTag, CallContextFieldTag, RwTableTag, TxLogFieldTag, TxReceiptFieldTag},
util::SubCircuit,
util::{unusable_rows, SubCircuit},
witness::{MptUpdates, Rw, RwMap},
};
use bus_mapping::operation::{
Expand All @@ -28,6 +28,14 @@ use strum::IntoEnumIterator;

const N_ROWS: usize = 1 << 16;

#[test]
fn state_circuit_unusable_rows() {
assert_eq!(
StateCircuit::<Fr>::unusable_rows(),
unusable_rows::<Fr, StateCircuit::<Fr>>(),
)
}

fn test_state_circuit_ok(
memory_ops: Vec<Operation<MemoryOp>>,
stack_ops: Vec<Operation<StackOp>>,
Expand Down
Loading

0 comments on commit cb26abb

Please sign in to comment.