From e502a0dfb11e8dc3543e18b367e0ab53d06aada8 Mon Sep 17 00:00:00 2001 From: Robin Salen <30937548+Nashtare@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:41:42 -0500 Subject: [PATCH] Make CTLs more generic (#1493) * Make number of tables generic * Remove dependency on Table in the CTL module * Remove needless conversion * Remove more needless conversion * Clippy * Apply reviews --- evm/src/all_stark.rs | 57 ++++++---- evm/src/arithmetic/arithmetic_stark.rs | 2 +- evm/src/cpu/cpu_stark.rs | 2 +- evm/src/cross_table_lookup.rs | 139 ++++++++++++++----------- evm/src/fixed_recursive_verifier.rs | 18 ++-- evm/src/prover.rs | 2 +- evm/src/recursive_verifier.rs | 4 +- evm/src/verifier.rs | 2 +- 8 files changed, 125 insertions(+), 101 deletions(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index fadb9d1622..d69ff302cf 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -1,4 +1,5 @@ use core::iter; +use core::ops::Deref; use itertools::Itertools; use plonky2::field::extension::Extendable; @@ -12,7 +13,7 @@ use crate::config::StarkConfig; use crate::cpu::cpu_stark; use crate::cpu::cpu_stark::CpuStark; use crate::cpu::membus::NUM_GP_CHANNELS; -use crate::cross_table_lookup::{CrossTableLookup, TableWithColumns}; +use crate::cross_table_lookup::{CrossTableLookup, TableIdx, TableWithColumns}; use crate::keccak::keccak_stark; use crate::keccak::keccak_stark::KeccakStark; use crate::keccak_sponge::columns::KECCAK_RATE_BYTES; @@ -79,6 +80,16 @@ pub enum Table { Memory = 6, } +impl Deref for Table { + type Target = TableIdx; + + fn deref(&self) -> &Self::Target { + // Hacky way to implement `Deref` for `Table` so that we don't have to + // call `Table::Foo as usize`, but perhaps too ugly to be worth it. + [&0, &1, &2, &3, &4, &5, &6][*self as TableIdx] + } +} + /// Number of STARK tables. pub(crate) const NUM_TABLES: usize = Table::Memory as usize + 1; @@ -121,27 +132,27 @@ fn ctl_arithmetic() -> CrossTableLookup { /// `CrossTableLookup` for `BytePackingStark`, to connect it with the `Cpu` module. fn ctl_byte_packing() -> CrossTableLookup { let cpu_packing_looking = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_byte_packing(), Some(cpu_stark::ctl_filter_byte_packing()), ); let cpu_unpacking_looking = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_byte_unpacking(), Some(cpu_stark::ctl_filter_byte_unpacking()), ); let cpu_push_packing_looking = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_byte_packing_push(), Some(cpu_stark::ctl_filter_byte_packing_push()), ); let cpu_jumptable_read_looking = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_jumptable_read(), Some(cpu_stark::ctl_filter_syscall_exceptions()), ); let byte_packing_looked = TableWithColumns::new( - Table::BytePacking, + *Table::BytePacking, byte_packing_stark::ctl_looked_data(), Some(byte_packing_stark::ctl_looked_filter()), ); @@ -161,12 +172,12 @@ fn ctl_byte_packing() -> CrossTableLookup { /// Its consistency with the 'output' CTL is ensured through a timestamp column on the `KeccakStark` side. fn ctl_keccak_inputs() -> CrossTableLookup { let keccak_sponge_looking = TableWithColumns::new( - Table::KeccakSponge, + *Table::KeccakSponge, keccak_sponge_stark::ctl_looking_keccak_inputs(), Some(keccak_sponge_stark::ctl_looking_keccak_filter()), ); let keccak_looked = TableWithColumns::new( - Table::Keccak, + *Table::Keccak, keccak_stark::ctl_data_inputs(), Some(keccak_stark::ctl_filter_inputs()), ); @@ -177,12 +188,12 @@ fn ctl_keccak_inputs() -> CrossTableLookup { /// `KeccakStarkSponge` looks into `KeccakStark` to give the outputs of the sponge. fn ctl_keccak_outputs() -> CrossTableLookup { let keccak_sponge_looking = TableWithColumns::new( - Table::KeccakSponge, + *Table::KeccakSponge, keccak_sponge_stark::ctl_looking_keccak_outputs(), Some(keccak_sponge_stark::ctl_looking_keccak_filter()), ); let keccak_looked = TableWithColumns::new( - Table::Keccak, + *Table::Keccak, keccak_stark::ctl_data_outputs(), Some(keccak_stark::ctl_filter_outputs()), ); @@ -192,12 +203,12 @@ fn ctl_keccak_outputs() -> CrossTableLookup { /// `CrossTableLookup` for `KeccakSpongeStark` to connect it with the `Cpu` module. fn ctl_keccak_sponge() -> CrossTableLookup { let cpu_looking = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_keccak_sponge(), Some(cpu_stark::ctl_filter_keccak_sponge()), ); let keccak_sponge_looked = TableWithColumns::new( - Table::KeccakSponge, + *Table::KeccakSponge, keccak_sponge_stark::ctl_looked_data(), Some(keccak_sponge_stark::ctl_looked_filter()), ); @@ -207,63 +218,63 @@ fn ctl_keccak_sponge() -> CrossTableLookup { /// `CrossTableLookup` for `LogicStark` to connect it with the `Cpu` and `KeccakSponge` modules. fn ctl_logic() -> CrossTableLookup { let cpu_looking = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_logic(), Some(cpu_stark::ctl_filter_logic()), ); let mut all_lookers = vec![cpu_looking]; for i in 0..keccak_sponge_stark::num_logic_ctls() { let keccak_sponge_looking = TableWithColumns::new( - Table::KeccakSponge, + *Table::KeccakSponge, keccak_sponge_stark::ctl_looking_logic(i), Some(keccak_sponge_stark::ctl_looking_logic_filter()), ); all_lookers.push(keccak_sponge_looking); } let logic_looked = - TableWithColumns::new(Table::Logic, logic::ctl_data(), Some(logic::ctl_filter())); + TableWithColumns::new(*Table::Logic, logic::ctl_data(), Some(logic::ctl_filter())); CrossTableLookup::new(all_lookers, logic_looked) } /// `CrossTableLookup` for `MemoryStark` to connect it with all the modules which need memory accesses. fn ctl_memory() -> CrossTableLookup { let cpu_memory_code_read = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_code_memory(), Some(cpu_stark::ctl_filter_code_memory()), ); let cpu_memory_gp_ops = (0..NUM_GP_CHANNELS).map(|channel| { TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_gp_memory(channel), Some(cpu_stark::ctl_filter_gp_memory(channel)), ) }); let cpu_push_write_ops = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_partial_memory::(), Some(cpu_stark::ctl_filter_partial_memory()), ); let cpu_set_context_write = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_memory_old_sp_write_set_context::(), Some(cpu_stark::ctl_filter_set_context()), ); let cpu_set_context_read = TableWithColumns::new( - Table::Cpu, + *Table::Cpu, cpu_stark::ctl_data_memory_new_sp_read_set_context::(), Some(cpu_stark::ctl_filter_set_context()), ); let keccak_sponge_reads = (0..KECCAK_RATE_BYTES).map(|i| { TableWithColumns::new( - Table::KeccakSponge, + *Table::KeccakSponge, keccak_sponge_stark::ctl_looking_memory(i), Some(keccak_sponge_stark::ctl_looking_memory_filter(i)), ) }); let byte_packing_ops = (0..32).map(|i| { TableWithColumns::new( - Table::BytePacking, + *Table::BytePacking, byte_packing_stark::ctl_looking_memory(i), Some(byte_packing_stark::ctl_looking_memory_filter(i)), ) @@ -280,7 +291,7 @@ fn ctl_memory() -> CrossTableLookup { .chain(byte_packing_ops) .collect(); let memory_looked = TableWithColumns::new( - Table::Memory, + *Table::Memory, memory_stark::ctl_data(), Some(memory_stark::ctl_filter()), ); diff --git a/evm/src/arithmetic/arithmetic_stark.rs b/evm/src/arithmetic/arithmetic_stark.rs index 0165542e16..5cd0697392 100644 --- a/evm/src/arithmetic/arithmetic_stark.rs +++ b/evm/src/arithmetic/arithmetic_stark.rs @@ -110,7 +110,7 @@ pub(crate) fn ctl_arithmetic_rows() -> TableWithColumns { // corresponding to a 256-bit input or output register (also `ops` // is used as the operation filter). TableWithColumns::new( - Table::Arithmetic, + *Table::Arithmetic, cpu_arith_data_link(&all_combined_cols, ®ISTER_MAP), filter, ) diff --git a/evm/src/cpu/cpu_stark.rs b/evm/src/cpu/cpu_stark.rs index 91e1f3ef63..114525e99c 100644 --- a/evm/src/cpu/cpu_stark.rs +++ b/evm/src/cpu/cpu_stark.rs @@ -108,7 +108,7 @@ pub(crate) fn ctl_arithmetic_base_rows() -> TableWithColumns { F::ONE, ); TableWithColumns::new( - Table::Cpu, + *Table::Cpu, columns, Some(Filter::new( vec![(Column::single(COL_MAP.op.push_prover_input), col_bit)], diff --git a/evm/src/cross_table_lookup.rs b/evm/src/cross_table_lookup.rs index c3110ee89a..28d14ca0d5 100644 --- a/evm/src/cross_table_lookup.rs +++ b/evm/src/cross_table_lookup.rs @@ -52,7 +52,7 @@ use plonky2::plonk::plonk_common::{ use plonky2::util::ceil_div_usize; use plonky2::util::serialization::{Buffer, IoResult, Read, Write}; -use crate::all_stark::{Table, NUM_TABLES}; +use crate::all_stark::Table; use crate::config::StarkConfig; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::evaluation_frame::StarkEvaluationFrame; @@ -423,19 +423,22 @@ impl Filter { } } -/// A `Table` with a linear combination of columns and a filter. -/// `filter` is used to determine the rows to select in `Table`. -/// `columns` represents linear combinations of the columns of `Table`. +/// An alias for `usize`, to represent the index of a STARK table in a multi-STARK setting. +pub(crate) type TableIdx = usize; + +/// A `table` index with a linear combination of columns and a filter. +/// `filter` is used to determine the rows to select in `table`. +/// `columns` represents linear combinations of the columns of `table`. #[derive(Clone, Debug)] pub(crate) struct TableWithColumns { - table: Table, + table: TableIdx, columns: Vec>, pub(crate) filter: Option>, } impl TableWithColumns { - /// Generates a new `TableWithColumns` given a `Table`, a linear combination of columns `columns` and a `filter`. - pub(crate) fn new(table: Table, columns: Vec>, filter: Option>) -> Self { + /// Generates a new `TableWithColumns` given a `table` index, a linear combination of columns `columns` and a `filter`. + pub(crate) fn new(table: TableIdx, columns: Vec>, filter: Option>) -> Self { Self { table, columns, @@ -447,7 +450,7 @@ impl TableWithColumns { /// Cross-table lookup data consisting in the lookup table (`looked_table`) and all the tables that look into `looked_table` (`looking_tables`). /// Each `looking_table` corresponds to a STARK's table whose rows have been filtered out and whose columns have been through a linear combination (see `eval_table`). The concatenation of those smaller tables should result in the `looked_table`. #[derive(Clone)] -pub(crate) struct CrossTableLookup { +pub struct CrossTableLookup { /// Column linear combinations for all tables that are looking into the current table. pub(crate) looking_tables: Vec>, /// Column linear combination for the current table. @@ -476,7 +479,7 @@ impl CrossTableLookup { /// - the number of helper columns for this table, for each Cross-table lookup. pub(crate) fn num_ctl_helpers_zs_all( ctls: &[Self], - table: Table, + table: TableIdx, num_challenges: usize, constraint_degree: usize, ) -> (usize, usize, Vec) { @@ -698,17 +701,17 @@ pub(crate) fn get_grand_product_challenge_set_target< } /// Returns the number of helper columns for each `Table`. -pub(crate) fn num_ctl_helper_columns_by_table( +pub(crate) fn num_ctl_helper_columns_by_table( ctls: &[CrossTableLookup], constraint_degree: usize, -) -> Vec<[usize; NUM_TABLES]> { - let mut res = vec![[0; NUM_TABLES]; ctls.len()]; +) -> Vec<[usize; N]> { + let mut res = vec![[0; N]; ctls.len()]; for (i, ctl) in ctls.iter().enumerate() { let CrossTableLookup { looking_tables, looked_table, } = ctl; - let mut num_by_table = [0; NUM_TABLES]; + let mut num_by_table = [0; N]; let grouped_lookups = looking_tables.iter().group_by(|&a| a.table); @@ -716,7 +719,7 @@ pub(crate) fn num_ctl_helper_columns_by_table( let sum = group.count(); if sum > 2 { // We only need helper columns if there are more than 2 columns. - num_by_table[table as usize] = ceil_div_usize(sum, constraint_degree - 1); + num_by_table[table] = ceil_div_usize(sum, constraint_degree - 1); } } @@ -731,13 +734,13 @@ pub(crate) fn num_ctl_helper_columns_by_table( /// - `ctl_challenges` corresponds to the challenges used for CTLs. /// - `constraint_degree` is the maximal constraint degree for the table. /// For each `CrossTableLookup`, and each looking/looked table, the partial products for the CTL are computed, and added to the said table's `CtlZData`. -pub(crate) fn cross_table_lookup_data<'a, F: RichField, const D: usize>( - trace_poly_values: &[Vec>; NUM_TABLES], +pub(crate) fn cross_table_lookup_data<'a, F: RichField, const D: usize, const N: usize>( + trace_poly_values: &[Vec>; N], cross_table_lookups: &'a [CrossTableLookup], ctl_challenges: &GrandProductChallengeSet, constraint_degree: usize, -) -> [CtlData<'a, F>; NUM_TABLES] { - let mut ctl_data_per_table = [0; NUM_TABLES].map(|_| CtlData::default()); +) -> [CtlData<'a, F>; N] { + let mut ctl_data_per_table = [0; N].map(|_| CtlData::default()); for CrossTableLookup { looking_tables, looked_table, @@ -753,7 +756,7 @@ pub(crate) fn cross_table_lookup_data<'a, F: RichField, const D: usize>( ); let mut z_looked = partial_sums( - &trace_poly_values[looked_table.table as usize], + &trace_poly_values[looked_table.table], &[(&looked_table.columns, &looked_table.filter)], challenge, constraint_degree, @@ -763,10 +766,10 @@ pub(crate) fn cross_table_lookup_data<'a, F: RichField, const D: usize>( let num_helpers = helpers_zs.len() - 1; let count = looking_tables .iter() - .filter(|looking_table| looking_table.table as usize == table) + .filter(|looking_table| looking_table.table == table) .count(); let cols_filts = looking_tables.iter().filter_map(|looking_table| { - if looking_table.table as usize == table { + if looking_table.table == table { Some((&looking_table.columns, &looking_table.filter)) } else { None @@ -788,7 +791,7 @@ pub(crate) fn cross_table_lookup_data<'a, F: RichField, const D: usize>( } // There is no helper column for the looking table. let looked_poly = z_looked[0].clone(); - ctl_data_per_table[looked_table.table as usize] + ctl_data_per_table[looked_table.table] .zs_columns .push(CtlZData { helper_columns: vec![], @@ -899,8 +902,8 @@ pub(crate) fn get_helper_cols( /// Computes helper columns and Z polynomials for all looking tables /// of one cross-table lookup (i.e. for one looked table). -fn ctl_helper_zs_cols( - all_stark_traces: &[Vec>; NUM_TABLES], +fn ctl_helper_zs_cols( + all_stark_traces: &[Vec>; N], looking_tables: Vec>, challenge: GrandProductChallenge, constraint_degree: usize, @@ -910,14 +913,14 @@ fn ctl_helper_zs_cols( grouped_lookups .into_iter() .map(|(table, group)| { - let degree = all_stark_traces[table as usize][0].len(); + let degree = all_stark_traces[table][0].len(); let columns_filters = group .map(|table| (&table.columns[..], &table.filter)) .collect::], &Option>)>>(); ( - table as usize, + table, partial_sums( - &all_stark_traces[table as usize], + &all_stark_traces[table], &columns_filters, challenge, constraint_degree, @@ -1000,16 +1003,16 @@ impl<'a, F: RichField + Extendable, const D: usize> CtlCheckVars<'a, F, F::Extension, F::Extension, D> { /// Extracts the `CtlCheckVars` for each STARK. - pub(crate) fn from_proofs>( - proofs: &[StarkProofWithMetadata; NUM_TABLES], + pub(crate) fn from_proofs, const N: usize>( + proofs: &[StarkProofWithMetadata; N], cross_table_lookups: &'a [CrossTableLookup], ctl_challenges: &'a GrandProductChallengeSet, - num_lookup_columns: &[usize; NUM_TABLES], - num_helper_ctl_columns: &Vec<[usize; NUM_TABLES]>, - ) -> [Vec; NUM_TABLES] { - let mut total_num_helper_cols_by_table = [0; NUM_TABLES]; + num_lookup_columns: &[usize; N], + num_helper_ctl_columns: &Vec<[usize; N]>, + ) -> [Vec; N] { + let mut total_num_helper_cols_by_table = [0; N]; for p_ctls in num_helper_ctl_columns { - for j in 0..NUM_TABLES { + for j in 0..N { total_num_helper_cols_by_table[j] += p_ctls[j] * ctl_challenges.challenges.len(); } } @@ -1028,9 +1031,9 @@ impl<'a, F: RichField + Extendable, const D: usize> .collect::>(); // Put each cross-table lookup polynomial into the correct table data: if a CTL polynomial is extracted from looking/looked table t, then we add it to the `CtlCheckVars` of table t. - let mut start_indices = [0; NUM_TABLES]; - let mut z_indices = [0; NUM_TABLES]; - let mut ctl_vars_per_table = [0; NUM_TABLES].map(|_| vec![]); + let mut start_indices = [0; N]; + let mut z_indices = [0; N]; + let mut ctl_vars_per_table = [0; N].map(|_| vec![]); for ( CrossTableLookup { looking_tables, @@ -1042,11 +1045,10 @@ impl<'a, F: RichField + Extendable, const D: usize> for &challenges in &ctl_challenges.challenges { // Group looking tables by `Table`, since we bundle the looking tables taken from the same `Table` together thanks to helper columns. // We want to only iterate on each `Table` once. - let mut filtered_looking_tables = - Vec::with_capacity(min(looking_tables.len(), NUM_TABLES)); + let mut filtered_looking_tables = Vec::with_capacity(min(looking_tables.len(), N)); for table in looking_tables { - if !filtered_looking_tables.contains(&(table.table as usize)) { - filtered_looking_tables.push(table.table as usize); + if !filtered_looking_tables.contains(&(table.table)) { + filtered_looking_tables.push(table.table); } } @@ -1057,10 +1059,10 @@ impl<'a, F: RichField + Extendable, const D: usize> let count = looking_tables .iter() - .filter(|looking_table| looking_table.table as usize == table) + .filter(|looking_table| looking_table.table == table) .count(); let cols_filts = looking_tables.iter().filter_map(|looking_table| { - if looking_table.table as usize == table { + if looking_table.table == table { Some((&looking_table.columns, &looking_table.filter)) } else { None @@ -1091,15 +1093,15 @@ impl<'a, F: RichField + Extendable, const D: usize> }); } - let (looked_z, looked_z_next) = ctl_zs[looked_table.table as usize] - [total_num_helper_cols_by_table[looked_table.table as usize] - + z_indices[looked_table.table as usize]]; + let (looked_z, looked_z_next) = ctl_zs[looked_table.table] + [total_num_helper_cols_by_table[looked_table.table] + + z_indices[looked_table.table]]; - z_indices[looked_table.table as usize] += 1; + z_indices[looked_table.table] += 1; let columns = vec![&looked_table.columns[..]]; let filter = vec![looked_table.filter.clone()]; - ctl_vars_per_table[looked_table.table as usize].push(Self { + ctl_vars_per_table[looked_table.table].push(Self { helper_columns: vec![], local_z: *looked_z, next_z: *looked_z_next, @@ -1281,7 +1283,7 @@ pub(crate) struct CtlCheckVarsTarget { impl<'a, F: Field, const D: usize> CtlCheckVarsTarget { /// Circuit version of `from_proofs`. Extracts the `CtlCheckVarsTarget` for each STARK. pub(crate) fn from_proof( - table: Table, + table: TableIdx, proof: &StarkProofTarget, cross_table_lookups: &'a [CrossTableLookup], ctl_challenges: &'a GrandProductChallengeSet, @@ -1544,9 +1546,13 @@ pub(crate) fn eval_cross_table_lookup_checks_circuit< } /// Verifies all cross-table lookups. -pub(crate) fn verify_cross_table_lookups, const D: usize>( +pub(crate) fn verify_cross_table_lookups< + F: RichField + Extendable, + const D: usize, + const N: usize, +>( cross_table_lookups: &[CrossTableLookup], - ctl_zs_first: [Vec; NUM_TABLES], + ctl_zs_first: [Vec; N], ctl_extra_looking_sums: Vec>, config: &StarkConfig, ) -> Result<()> { @@ -1560,12 +1566,12 @@ pub(crate) fn verify_cross_table_lookups, const D: ) in cross_table_lookups.iter().enumerate() { // Get elements looking into `looked_table` that are not associated to any STARK. - let extra_sum_vec = &ctl_extra_looking_sums[looked_table.table as usize]; + let extra_sum_vec = &ctl_extra_looking_sums[looked_table.table]; // We want to iterate on each looking table only once. let mut filtered_looking_tables = vec![]; for table in looking_tables { - if !filtered_looking_tables.contains(&(table.table as usize)) { - filtered_looking_tables.push(table.table as usize); + if !filtered_looking_tables.contains(&(table.table)) { + filtered_looking_tables.push(table.table); } } for c in 0..config.num_challenges { @@ -1578,7 +1584,7 @@ pub(crate) fn verify_cross_table_lookups, const D: + extra_sum_vec[c]; // Get the looked table CTL polynomial opening. - let looked_z = *ctl_zs_openings[looked_table.table as usize].next().unwrap(); + let looked_z = *ctl_zs_openings[looked_table.table].next().unwrap(); // Ensure that the combination of looking table openings is equal to the looked table opening. ensure!( looking_zs_sum == looked_z, @@ -1593,10 +1599,14 @@ pub(crate) fn verify_cross_table_lookups, const D: } /// Circuit version of `verify_cross_table_lookups`. Verifies all cross-table lookups. -pub(crate) fn verify_cross_table_lookups_circuit, const D: usize>( +pub(crate) fn verify_cross_table_lookups_circuit< + F: RichField + Extendable, + const D: usize, + const N: usize, +>( builder: &mut CircuitBuilder, cross_table_lookups: Vec>, - ctl_zs_first: [Vec; NUM_TABLES], + ctl_zs_first: [Vec; N], ctl_extra_looking_sums: Vec>, inner_config: &StarkConfig, ) { @@ -1607,12 +1617,12 @@ pub(crate) fn verify_cross_table_lookups_circuit, c } in cross_table_lookups.into_iter() { // Get elements looking into `looked_table` that are not associated to any STARK. - let extra_sum_vec = &ctl_extra_looking_sums[looked_table.table as usize]; + let extra_sum_vec = &ctl_extra_looking_sums[looked_table.table]; // We want to iterate on each looking table only once. let mut filtered_looking_tables = vec![]; for table in looking_tables { - if !filtered_looking_tables.contains(&(table.table as usize)) { - filtered_looking_tables.push(table.table as usize); + if !filtered_looking_tables.contains(&(table.table)) { + filtered_looking_tables.push(table.table); } } for c in 0..inner_config.num_challenges { @@ -1626,7 +1636,7 @@ pub(crate) fn verify_cross_table_lookups_circuit, c looking_zs_sum = builder.add(looking_zs_sum, extra_sum_vec[c]); // Get the looked table CTL polynomial opening. - let looked_z = *ctl_zs_openings[looked_table.table as usize].next().unwrap(); + let looked_z = *ctl_zs_openings[looked_table.table].next().unwrap(); // Verify that the combination of looking table openings is equal to the looked table opening. builder.connect(looked_z, looking_zs_sum); } @@ -1708,7 +1718,7 @@ pub(crate) mod testutils { table: &TableWithColumns, multiset: &mut MultiSet, ) { - let trace = &trace_poly_values[table.table as usize]; + let trace = &trace_poly_values[table.table]; for i in 0..trace[0].len() { let filter = if let Some(combin) = &table.filter { combin.eval_table(trace, i) @@ -1721,7 +1731,10 @@ pub(crate) mod testutils { .iter() .map(|c| c.eval_table(trace, i)) .collect::>(); - multiset.entry(row).or_default().push((table.table, i)); + multiset + .entry(row) + .or_default() + .push((Table::all()[table.table], i)); } else { assert_eq!(filter, F::ZERO, "Non-binary filter?") } diff --git a/evm/src/fixed_recursive_verifier.rs b/evm/src/fixed_recursive_verifier.rs index c7a705c37a..2e57ea3026 100644 --- a/evm/src/fixed_recursive_verifier.rs +++ b/evm/src/fixed_recursive_verifier.rs @@ -419,49 +419,49 @@ where let arithmetic = RecursiveCircuitsForTable::new( Table::Arithmetic, &all_stark.arithmetic_stark, - degree_bits_ranges[Table::Arithmetic as usize].clone(), + degree_bits_ranges[*Table::Arithmetic].clone(), &all_stark.cross_table_lookups, stark_config, ); let byte_packing = RecursiveCircuitsForTable::new( Table::BytePacking, &all_stark.byte_packing_stark, - degree_bits_ranges[Table::BytePacking as usize].clone(), + degree_bits_ranges[*Table::BytePacking].clone(), &all_stark.cross_table_lookups, stark_config, ); let cpu = RecursiveCircuitsForTable::new( Table::Cpu, &all_stark.cpu_stark, - degree_bits_ranges[Table::Cpu as usize].clone(), + degree_bits_ranges[*Table::Cpu].clone(), &all_stark.cross_table_lookups, stark_config, ); let keccak = RecursiveCircuitsForTable::new( Table::Keccak, &all_stark.keccak_stark, - degree_bits_ranges[Table::Keccak as usize].clone(), + degree_bits_ranges[*Table::Keccak].clone(), &all_stark.cross_table_lookups, stark_config, ); let keccak_sponge = RecursiveCircuitsForTable::new( Table::KeccakSponge, &all_stark.keccak_sponge_stark, - degree_bits_ranges[Table::KeccakSponge as usize].clone(), + degree_bits_ranges[*Table::KeccakSponge].clone(), &all_stark.cross_table_lookups, stark_config, ); let logic = RecursiveCircuitsForTable::new( Table::Logic, &all_stark.logic_stark, - degree_bits_ranges[Table::Logic as usize].clone(), + degree_bits_ranges[*Table::Logic].clone(), &all_stark.cross_table_lookups, stark_config, ); let memory = RecursiveCircuitsForTable::new( Table::Memory, &all_stark.memory_stark, - degree_bits_ranges[Table::Memory as usize].clone(), + degree_bits_ranges[*Table::Memory].clone(), &all_stark.cross_table_lookups, stark_config, ); @@ -574,7 +574,7 @@ where vec![vec![builder.zero(); stark_config.num_challenges]; NUM_TABLES]; // Memory - extra_looking_sums[Table::Memory as usize] = (0..stark_config.num_challenges) + extra_looking_sums[*Table::Memory] = (0..stark_config.num_challenges) .map(|c| { get_memory_extra_looking_sum_circuit( &mut builder, @@ -585,7 +585,7 @@ where .collect_vec(); // Verify the CTL checks. - verify_cross_table_lookups_circuit::( + verify_cross_table_lookups_circuit::( &mut builder, all_cross_table_lookups(), pis.map(|p| p.ctl_zs_first), diff --git a/evm/src/prover.rs b/evm/src/prover.rs index e642602315..8ca00d7659 100644 --- a/evm/src/prover.rs +++ b/evm/src/prover.rs @@ -131,7 +131,7 @@ where let ctl_data_per_table = timed!( timing, "compute CTL data", - cross_table_lookup_data::( + cross_table_lookup_data::( &trace_poly_values, &all_stark.cross_table_lookups, &ctl_challenges, diff --git a/evm/src/recursive_verifier.rs b/evm/src/recursive_verifier.rs index f3065e10f1..0d8e7367ce 100644 --- a/evm/src/recursive_verifier.rs +++ b/evm/src/recursive_verifier.rs @@ -232,7 +232,7 @@ where let (total_num_helpers, num_ctl_zs, num_helpers_by_ctl) = CrossTableLookup::num_ctl_helpers_zs_all( cross_table_lookups, - table, + *table, inner_config.num_challenges, stark.constraint_degree(), ); @@ -266,7 +266,7 @@ where }; let ctl_vars = CtlCheckVarsTarget::from_proof( - table, + *table, &proof_target, cross_table_lookups, &ctl_challenges_target, diff --git a/evm/src/verifier.rs b/evm/src/verifier.rs index a173be5b69..106f6983ae 100644 --- a/evm/src/verifier.rs +++ b/evm/src/verifier.rs @@ -138,7 +138,7 @@ where .map(|i| get_memory_extra_looking_sum(&public_values, ctl_challenges.challenges[i])) .collect_vec(); - verify_cross_table_lookups::( + verify_cross_table_lookups::( cross_table_lookups, all_proof .stark_proofs