diff --git a/zkevm-circuits/src/evm_circuit.rs b/zkevm-circuits/src/evm_circuit.rs index a7b9d740b1e..4b9b1a705ae 100644 --- a/zkevm-circuits/src/evm_circuit.rs +++ b/zkevm-circuits/src/evm_circuit.rs @@ -111,8 +111,8 @@ impl SubCircuitConfig for EvmCircuitConfig { &exp_table, )); - meta.annotate_lookup_any_column(u8_table[0], || "u8_range"); - meta.annotate_lookup_any_column(u16_table[0], || "u16_range"); + u8_table.annotate_columns(meta); + u16_table.annotate_columns(meta); fixed_table.iter().enumerate().for_each(|(idx, &col)| { meta.annotate_lookup_any_column(col, || format!("fix_table_{}", idx)) }); @@ -426,8 +426,8 @@ impl Circuit for EvmCircuit { .dev_load(&mut layouter, &block.sha3_inputs, &challenges)?; config.exp_table.load(&mut layouter, block)?; - config.u8_table.load(&mut layouter); - config.u16_table.load(&mut layouter); + config.u8_table.load(&mut layouter)?; + config.u16_table.load(&mut layouter)?; self.synthesize_sub(&config, &challenges, &mut layouter) } diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index 9b1e8e34fc2..5db7297523c 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -836,18 +836,22 @@ impl ExecutionConfig { for column in cell_manager.columns().iter() { if let CellType::LookupU8 = column.cell_type { meta.lookup_any("u8 lookup", |meta| { - debug_assert_eq!(u8_table.table_exprs(meta).len(), 1); - let u8_table_expression = u8_table.table_exprs(meta)[0].clone(); - vec![(column.expr(), u8_table_expression)] + vec![column.expr()] + .into_iter() + .zip(u8_table.table_exprs(meta).into_iter()) + .map(|(expr, table)| (expr, table)) + .collect() }); } } for column in cell_manager.columns().iter() { if let CellType::LookupU16 = column.cell_type { - debug_assert_eq!(u16_table.table_exprs(meta).len(), 1); meta.lookup_any("u16 lookup", |meta| { - let u16_table_expression = u16_table.table_exprs(meta)[0].clone(); - vec![(column.expr(), u16_table_expression)] + vec![column.expr()] + .into_iter() + .zip(u16_table.table_exprs(meta).into_iter()) + .map(|(expr, table)| (expr, table)) + .collect() }); } } diff --git a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs index 18dcb8cc022..2c94a41315a 100644 --- a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs +++ b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs @@ -464,7 +464,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> { // each limb is 16 bits, and any conversion to smaller limbs inherits the type check. pub(crate) fn query_word16(&mut self) -> Word16> { - Word16::new(self.query_u16_dyn(N)) + Word16::new(self.query_u16()) } // query_word32 each limb is 8 bits, and any conversion to smaller limbs inherits the type @@ -497,6 +497,10 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> { self.query_cells(CellType::LookupU8, count) } + pub(crate) fn query_u16(&mut self) -> [Cell; N] { + self.query_u16_dyn(N).try_into().unwrap() + } + pub(crate) fn query_u16_dyn(&mut self, count: usize) -> Vec> { self.query_cells(CellType::LookupU16, count) } diff --git a/zkevm-circuits/src/state_circuit.rs b/zkevm-circuits/src/state_circuit.rs index bb6cab8b411..0eb8b2cdeb5 100644 --- a/zkevm-circuits/src/state_circuit.rs +++ b/zkevm-circuits/src/state_circuit.rs @@ -82,11 +82,11 @@ pub struct StateCircuitConfigArgs { /// MptTable pub mpt_table: MptTable, /// U8Table - u8_table: MaxNBitTable<8>, + pub u8_table: MaxNBitTable<8>, /// U10Table - u10_table: MaxNBitTable<10>, + pub u10_table: MaxNBitTable<10>, /// U16Table - u16_table: MaxNBitTable<16>, + pub u16_table: MaxNBitTable<16>, /// Challenges pub challenges: Challenges>, } diff --git a/zkevm-circuits/src/state_circuit/lookups.rs b/zkevm-circuits/src/state_circuit/lookups.rs index 4eadd16f39b..0aea28180be 100644 --- a/zkevm-circuits/src/state_circuit/lookups.rs +++ b/zkevm-circuits/src/state_circuit/lookups.rs @@ -5,6 +5,7 @@ use halo2_proofs::{ plonk::{Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells}, poly::Rotation, }; +use itertools::Itertools; use std::marker::PhantomData; use strum::IntoEnumIterator; @@ -14,9 +15,9 @@ use super::test::{LookupTable, MaxNBitTable}; pub struct Config { // Can these be TableColumn's? // https://github.com/zcash/halo2/blob/642efc1536d3ea2566b04814bd60a00c4745ae22/halo2_proofs/src/plonk/circuit.rs#L266 - u8: Column, - u10: Column, - u16: Column, + u8_table: MaxNBitTable<8>, + u10_table: MaxNBitTable<10>, + u16_table: MaxNBitTable<16>, pub call_context_field_tag: Column, } @@ -29,7 +30,11 @@ impl Config { ) { meta.lookup_any(msg, |meta| { let exp = exp_fn(meta); - vec![(exp, meta.query_fixed(self.u8, Rotation::cur()))] + vec![exp] + .into_iter() + .zip_eq(self.u8_table.table_exprs(meta)) + .map(|(exp, table_expr)| (exp, table_expr)) + .collect() }); } pub fn range_check_u10( @@ -40,7 +45,11 @@ impl Config { ) { meta.lookup_any(msg, |meta| { let exp = exp_fn(meta); - vec![(exp, meta.query_fixed(self.u10, Rotation::cur()))] + vec![exp] + .into_iter() + .zip_eq(self.u10_table.table_exprs(meta)) + .map(|(exp, table_expr)| (exp, table_expr)) + .collect() }); } pub fn range_check_u16( @@ -51,7 +60,11 @@ impl Config { ) { meta.lookup_any(msg, |meta| { let exp = exp_fn(meta); - vec![(exp, meta.query_fixed(self.u16, Rotation::cur()))] + vec![exp] + .into_iter() + .zip_eq(self.u16_table.table_exprs(meta)) + .map(|(exp, table_expr)| (exp, table_expr)) + .collect() }); } } @@ -67,9 +80,9 @@ pub struct Queries { impl Queries { pub fn new(meta: &mut VirtualCells<'_, F>, c: Config) -> Self { Self { - u8: meta.query_fixed(c.u8, Rotation::cur()), - u10: meta.query_fixed(c.u10, Rotation::cur()), - u16: meta.query_fixed(c.u16, Rotation::cur()), + u8: c.u8_table.table_exprs(meta)[0].clone(), + u10: c.u10_table.table_exprs(meta)[0].clone(), + u16: c.u16_table.table_exprs(meta)[0].clone(), call_context_field_tag: meta.query_fixed(c.call_context_field_tag, Rotation::cur()), } } @@ -94,13 +107,10 @@ impl Chip { u10_table: MaxNBitTable<10>, u16_table: MaxNBitTable<16>, ) -> Config { - debug_assert_eq!(u8_table.columns().len(), 1); - debug_assert_eq!(u10_table.columns().len(), 1); - debug_assert_eq!(u16_table.columns().len(), 1); let config = Config { - u8: u8_table.columns()[0], - u10: u10_table.columns()[0], - u16: u16_table.columns()[0], + u8_table, + u10_table, + u16_table, call_context_field_tag: meta.fixed_column(), }; u8_table.annotate_columns(meta); diff --git a/zkevm-circuits/src/super_circuit.rs b/zkevm-circuits/src/super_circuit.rs index 0b4e372ebbb..ef5592ce887 100644 --- a/zkevm-circuits/src/super_circuit.rs +++ b/zkevm-circuits/src/super_circuit.rs @@ -429,9 +429,9 @@ impl LookupTable for ExpTable { } } -// fixed table to serve max unsigned N bits range lookup +/// Lookup table for max n bits range check +#[derive(Clone, Copy, Debug)] pub struct MaxNBitTable { col: Column, } @@ -1574,6 +1575,7 @@ impl MaxNBitTable { } } + /// Load the `MaxNBitTable` for range check pub fn load(&self, layouter: &mut impl Layouter) -> Result<(), Error> { layouter.assign_region( || format!("assign u{} fixed column", 8), @@ -1599,7 +1601,7 @@ impl LookupTable for MaxNBitTable { } fn annotations(&self) -> Vec { - vec![String::from(format!("u{}_col", N_BITS))] + vec![format!("u{}_col", N_BITS)] } fn table_exprs(&self, meta: &mut VirtualCells) -> Vec> {