diff --git a/crates/playground/Cargo.lock b/crates/playground/Cargo.lock index 79b1fb62c..89209d395 100644 --- a/crates/playground/Cargo.lock +++ b/crates/playground/Cargo.lock @@ -667,14 +667,14 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "ec-gpu" version = "0.2.0" -source = "git+https://github.com/lanbones/ec-gpu#165d1dd6215f6fd1dd85c83cf430ff511a03a00a" +source = "git+https://github.com/lanbones/ec-gpu#36b9abf8611347e2fe44f21a2f3607eba3aed71d" [[package]] name = "ec-gpu-gen" version = "0.4.0" -source = "git+https://github.com/lanbones/ec-gpu?branch=halo2-opt-v2#5481be558da026bb9bddcd5807f973f6b1a8346e" +source = "git+https://github.com/lanbones/ec-gpu?branch=halo2-opt-v2#aedc591657644f047f25a2e089f0b489eba0bf38" dependencies = [ - "ark-std 0.3.0", + "ark-std 0.4.0", "bitvec", "crossbeam-channel", "ec-gpu", @@ -982,7 +982,7 @@ dependencies = [ [[package]] name = "halo2_proofs" version = "0.1.0-beta.1" -source = "git+https://github.com/DelphinusLab/halo2-gpu-specific.git#9a81f601607bdc3ff3360a9ad66885c9796f487b" +source = "git+https://github.com/DelphinusLab/halo2-gpu-specific.git#fe464bd14d7d1155964d39a029c9903b453aeac8" dependencies = [ "ark-std 0.4.0", "blake2b_simd", @@ -2300,10 +2300,12 @@ dependencies = [ "hex", "lazy_static", "num-bigint", + "num-traits", "parity-wasm", "rayon", "serde", "serde_json", + "static_assertions", "strum", "strum_macros", ] diff --git a/crates/zkwasm/src/circuits/etable/allocator.rs b/crates/zkwasm/src/circuits/etable/allocator.rs index 88048130a..c093c0e54 100644 --- a/crates/zkwasm/src/circuits/etable/allocator.rs +++ b/crates/zkwasm/src/circuits/etable/allocator.rs @@ -347,11 +347,19 @@ impl EventTableCellAllocator { pub(super) fn new( meta: &mut ConstraintSystem, sel: Column, + (l_0, l_active, l_active_last): (Column, Column, Column), rtable: &RangeTableConfig, mtable: &impl ConfigureLookupTable, cols: &mut impl Iterator>, ) -> Self { - let mut allocator = Self::_new(meta, sel, rtable, mtable, cols); + let mut allocator = Self::_new( + meta, + sel, + (l_0, l_active, l_active_last), + rtable, + mtable, + cols, + ); for _ in 0..U32_CELLS { let cell = allocator.prepare_alloc_u32_cell(); allocator.free_u32_cells.push(cell); @@ -371,6 +379,7 @@ impl EventTableCellAllocator { fn _new( meta: &mut ConstraintSystem, sel: Column, + (l_0, l_active, l_active_last): (Column, Column, Column), rtable: &RangeTableConfig, mtable: &impl ConfigureLookupTable, cols: &mut impl Iterator>, @@ -386,14 +395,14 @@ impl EventTableCellAllocator { all_cols.insert( EventTableCellType::U8, [0; U8_COLUMNS] - .map(|_| vec![U8Column::configure(meta, cols, rtable, |_| constant_from!(1)).col]) + .map(|_| vec![U8Column::configure(meta, (l_0, l_active, l_active_last)).col]) .into_iter() .collect(), ); all_cols.insert( EventTableCellType::U16, [0; U16_COLUMNS] - .map(|_| vec![U16Column::configure(meta, cols, rtable, |_| constant_from!(1)).col]) + .map(|_| vec![U16Column::configure(meta, (l_0, l_active, l_active_last)).col]) .into_iter() .collect(), ); diff --git a/crates/zkwasm/src/circuits/etable/mod.rs b/crates/zkwasm/src/circuits/etable/mod.rs index 0aa7f0931..1ce6ccccc 100644 --- a/crates/zkwasm/src/circuits/etable/mod.rs +++ b/crates/zkwasm/src/circuits/etable/mod.rs @@ -231,6 +231,7 @@ pub struct EventTableConfig { impl EventTableConfig { pub(crate) fn configure( meta: &mut ConstraintSystem, + (l_0, l_active, l_active_last): (Column, Column, Column), cols: &mut (impl Iterator> + Clone), rtable: &RangeTableConfig, image_table: &ImageTableConfig, @@ -242,7 +243,14 @@ impl EventTableConfig { ) -> EventTableConfig { let step_sel = meta.fixed_column(); - let mut allocator = EventTableCellAllocator::new(meta, step_sel, rtable, mtable, cols); + let mut allocator = EventTableCellAllocator::new( + meta, + step_sel, + (l_0, l_active, l_active_last), + rtable, + mtable, + cols, + ); let ops = [0; OP_CAPABILITY].map(|_| allocator.alloc_bit_cell()); let enabled_cell = allocator.alloc_bit_cell(); diff --git a/crates/zkwasm/src/circuits/mtable/allocator.rs b/crates/zkwasm/src/circuits/mtable/allocator.rs index e640ac26d..7236686eb 100644 --- a/crates/zkwasm/src/circuits/mtable/allocator.rs +++ b/crates/zkwasm/src/circuits/mtable/allocator.rs @@ -152,10 +152,17 @@ impl MemoryTableCellAllocator { pub(super) fn new( meta: &mut ConstraintSystem, sel: Column, + (l_0, l_active, l_active_last): (Column, Column, Column), rtable: &RangeTableConfig, cols: &mut impl Iterator>, ) -> Self { - let mut allocator = Self::_new(meta, sel.clone(), rtable, cols); + let mut allocator = Self::_new( + meta, + sel.clone(), + (l_0, l_active, l_active_last), + rtable, + cols, + ); for _ in 0..U32_CELLS { let cell = allocator.prepare_alloc_u32_cell(); allocator.free_u32_cells.push(cell); @@ -170,6 +177,7 @@ impl MemoryTableCellAllocator { fn _new( meta: &mut ConstraintSystem, sel: Column, + (l_0, l_active, l_active_last): (Column, Column, Column), rtable: &RangeTableConfig, cols: &mut impl Iterator>, ) -> Self { @@ -184,7 +192,7 @@ impl MemoryTableCellAllocator { all_cols.insert( MemoryTableCellType::U16, [0; U16_COLUMNS] - .map(|_| U16Column::configure(meta, cols, rtable, |_| constant_from!(1)).col) + .map(|_| U16Column::configure(meta, (l_0, l_active, l_active_last)).col) .into_iter() .collect(), ); diff --git a/crates/zkwasm/src/circuits/mtable/mod.rs b/crates/zkwasm/src/circuits/mtable/mod.rs index 5713276d9..579e1689b 100644 --- a/crates/zkwasm/src/circuits/mtable/mod.rs +++ b/crates/zkwasm/src/circuits/mtable/mod.rs @@ -69,13 +69,20 @@ pub struct MemoryTableConfig { impl MemoryTableConfig { pub(crate) fn configure( meta: &mut ConstraintSystem, + (l_0, l_active, l_active_last): (Column, Column, Column), cols: &mut (impl Iterator> + Clone), rtable: &RangeTableConfig, image_table: &ImageTableConfig, ) -> Self { let entry_sel = meta.fixed_column(); - let mut allocator = MemoryTableCellAllocator::new(meta, entry_sel, rtable, cols); + let mut allocator = MemoryTableCellAllocator::new( + meta, + entry_sel, + (l_0, l_active, l_active_last), + rtable, + cols, + ); allocator.enable_equality(meta, &MemoryTableCellType::CommonRange); let enabled_cell = allocator.alloc_bit_cell(); diff --git a/crates/zkwasm/src/circuits/rtable.rs b/crates/zkwasm/src/circuits/rtable.rs index 374cff64a..1cab0a03a 100644 --- a/crates/zkwasm/src/circuits/rtable.rs +++ b/crates/zkwasm/src/circuits/rtable.rs @@ -50,11 +50,6 @@ struct OpTable { pub struct RangeTableConfig { // [0 .. common_range()) common_range_col: TableColumn, - // [0 .. 65536) - u16_col: TableColumn, - // [0 .. 256) - u8_col: TableColumn, - op_table: OpTable, _mark: PhantomData, @@ -71,8 +66,6 @@ impl RangeTableConfig { RangeTableConfig { common_range_col: meta.lookup_table_column(), - u16_col: meta.lookup_table_column(), - u8_col: u8_col_multiset, op_table: OpTable { op: meta.lookup_table_column(), left: u8_col_multiset, @@ -92,24 +85,6 @@ impl RangeTableConfig { meta.lookup(key, |meta| vec![(expr(meta), self.common_range_col)]); } - pub fn configure_in_u16_range( - &self, - meta: &mut ConstraintSystem, - key: &'static str, - expr: impl FnOnce(&mut VirtualCells<'_, F>) -> Expression, - ) { - meta.lookup(key, |meta| vec![(expr(meta), self.u16_col)]); - } - - pub fn configure_in_u8_range( - &self, - meta: &mut ConstraintSystem, - key: &'static str, - expr: impl FnOnce(&mut VirtualCells<'_, F>) -> Expression, - ) { - meta.lookup(key, |meta| vec![(expr(meta), self.u8_col)]); - } - pub fn configure_in_op_table( &self, meta: &mut ConstraintSystem, @@ -175,21 +150,6 @@ impl RangeTableChip { }, )?; - layouter.assign_table( - || "u16 range table", - |table| { - for i in 0..(1 << 16) { - table.assign_cell( - || "range table", - self.config.u16_col, - i, - || Ok(F::from(i as u64)), - )?; - } - Ok(()) - }, - )?; - { layouter.assign_table( || "op lookup table", diff --git a/crates/zkwasm/src/circuits/utils/u16.rs b/crates/zkwasm/src/circuits/utils/u16.rs index b82e96860..570d63813 100644 --- a/crates/zkwasm/src/circuits/utils/u16.rs +++ b/crates/zkwasm/src/circuits/utils/u16.rs @@ -1,13 +1,10 @@ use super::Context; -use crate::circuits::rtable::RangeTableConfig; -use crate::curr; use halo2_proofs::arithmetic::FieldExt; use halo2_proofs::plonk::Advice; use halo2_proofs::plonk::Column; use halo2_proofs::plonk::ConstraintSystem; use halo2_proofs::plonk::Error; -use halo2_proofs::plonk::Expression; -use halo2_proofs::plonk::VirtualCells; +use halo2_proofs::plonk::Fixed; use std::marker::PhantomData; #[derive(Clone)] @@ -19,13 +16,16 @@ pub struct U16Column { impl U16Column { pub fn configure( meta: &mut ConstraintSystem, - cols: &mut impl Iterator>, - rtable: &RangeTableConfig, - enable: impl Fn(&mut VirtualCells<'_, F>) -> Expression, + (l_0, l_active, l_active_last): (Column, Column, Column), ) -> Self { - let col = cols.next().unwrap(); - - rtable.configure_in_u16_range(meta, "u16", |meta| curr!(meta, col) * enable(meta)); + let col = meta.advice_column_range( + l_0, + l_active, + l_active_last, + (0, F::zero()), + (u16::MAX as u32, F::from(u16::MAX as u64)), + (2, F::from(2)), + ); Self { col, diff --git a/crates/zkwasm/src/circuits/utils/u8.rs b/crates/zkwasm/src/circuits/utils/u8.rs index da601e517..0e8861d4f 100644 --- a/crates/zkwasm/src/circuits/utils/u8.rs +++ b/crates/zkwasm/src/circuits/utils/u8.rs @@ -1,13 +1,10 @@ use super::Context; -use crate::circuits::rtable::RangeTableConfig; -use crate::curr; use halo2_proofs::arithmetic::FieldExt; use halo2_proofs::plonk::Advice; use halo2_proofs::plonk::Column; use halo2_proofs::plonk::ConstraintSystem; use halo2_proofs::plonk::Error; -use halo2_proofs::plonk::Expression; -use halo2_proofs::plonk::VirtualCells; +use halo2_proofs::plonk::Fixed; use std::marker::PhantomData; #[derive(Clone)] @@ -19,13 +16,16 @@ pub struct U8Column { impl U8Column { pub fn configure( meta: &mut ConstraintSystem, - cols: &mut impl Iterator>, - rtable: &RangeTableConfig, - enable: impl Fn(&mut VirtualCells<'_, F>) -> Expression, + (l_0, l_active, l_active_last): (Column, Column, Column), ) -> Self { - let col = cols.next().unwrap(); - - rtable.configure_in_u8_range(meta, "u8", |meta| curr!(meta, col) * enable(meta)); + let col = meta.advice_column_range( + l_0, + l_active, + l_active_last, + (0, F::from(0)), + (u8::MAX as u32, F::from(u8::MAX as u64)), + (1, F::one()), + ); Self { col, diff --git a/crates/zkwasm/src/circuits/zkwasm_circuit/mod.rs b/crates/zkwasm/src/circuits/zkwasm_circuit/mod.rs index 1df19ea24..1ecc3eeae 100644 --- a/crates/zkwasm/src/circuits/zkwasm_circuit/mod.rs +++ b/crates/zkwasm/src/circuits/zkwasm_circuit/mod.rs @@ -63,14 +63,14 @@ use super::LastSliceCircuit; use super::OngoingCircuit; pub const VAR_COLUMNS: usize = if cfg!(feature = "continuation") { - 56 + 40 } else { - 49 + 40 }; // Reserve a few rows to keep usable rows away from blind rows. // The maximal step size of all tables is bit_table::STEP_SIZE. -pub(crate) const RESERVE_ROWS: usize = crate::circuits::bit_table::STEP_SIZE; +pub(crate) const RESERVE_ROWS: usize = crate::circuits::bit_table::STEP_SIZE + (1 << 16); #[derive(Default, Clone)] struct AssignedCells { @@ -87,6 +87,7 @@ struct AssignedCells { #[derive(Clone)] pub struct ZkWasmCircuitConfig { + shuffle_range_check_helper: (Column, Column, Column), rtable: RangeTableConfig, image_table: ImageTableConfig, post_image_table: PostImageTableConfig, @@ -101,6 +102,7 @@ pub struct ZkWasmCircuitConfig { max_available_rows: usize, circuit_maximal_pages: u32, + l_last: usize, k: u32, } @@ -154,6 +156,12 @@ macro_rules! impl_zkwasm_circuit { meta.enable_equality(constants); } + let (l_0, l_active, l_active_last) = ( + meta.fixed_column(), + meta.fixed_column(), + meta.fixed_column(), + ); + let memory_addr_sel = if cfg!(feature = "continuation") { Some(meta.fixed_column()) } else { @@ -166,7 +174,13 @@ macro_rules! impl_zkwasm_circuit { let rtable = RangeTableConfig::configure(meta); let image_table = ImageTableConfig::configure(meta, memory_addr_sel); - let mtable = MemoryTableConfig::configure(meta, &mut cols, &rtable, &image_table); + let mtable = MemoryTableConfig::configure( + meta, + (l_0, l_active, l_active_last), + &mut cols, + &rtable, + &image_table, + ); let frame_table = JumpTableConfig::configure(meta, $last_slice); let post_image_table = PostImageTableConfig::configure( meta, @@ -196,6 +210,7 @@ macro_rules! impl_zkwasm_circuit { let etable = EventTableConfig::configure( meta, + (l_0, l_active, l_active_last), &mut cols, &rtable, &image_table, @@ -218,6 +233,7 @@ macro_rules! impl_zkwasm_circuit { ); Self::Config { + shuffle_range_check_helper: (l_0, l_active, l_active_last), rtable, image_table, post_image_table, @@ -231,6 +247,7 @@ macro_rules! impl_zkwasm_circuit { max_available_rows, circuit_maximal_pages, + l_last: (1 << k) - (meta.blinding_factors() + 1), k, } @@ -298,10 +315,44 @@ macro_rules! impl_zkwasm_circuit { let _layouter = layouter.clone(); s.spawn(move |_| { - exec_with_profile!( - || "Init range chip", + exec_with_profile!(|| "Init range chip", { + let (l_0, l_active, l_active_last) = config.shuffle_range_check_helper; + + _layouter + .assign_region( + || "range check sel helper", + |region| { + region + .assign_fixed(|| "l_0", l_0, 0, || Ok(F::one())) + .unwrap(); + + region + .assign_fixed( + || "l_active_last", + l_active_last, + config.l_last - 1, + || Ok(F::one()), + ) + .unwrap(); + + for offset in 0..config.l_last { + region + .assign_fixed( + || "l_active_last", + l_active, + offset, + || Ok(F::one()), + ) + .unwrap(); + } + + Ok(()) + }, + ) + .unwrap(); + rchip.init(_layouter, config.k).unwrap() - ); + }); }); let _layouter = layouter.clone();