Add TableWithColumns struct

This commit is contained in:
wborgeaud 2022-06-06 20:51:14 +02:00
parent 47efff834f
commit 820456fc88
2 changed files with 68 additions and 62 deletions

View File

@ -61,7 +61,7 @@ mod tests {
use crate::config::StarkConfig; use crate::config::StarkConfig;
use crate::cpu; use crate::cpu;
use crate::cpu::cpu_stark::CpuStark; use crate::cpu::cpu_stark::CpuStark;
use crate::cross_table_lookup::CrossTableLookup; use crate::cross_table_lookup::{CrossTableLookup, TableWithColumns};
use crate::keccak::keccak_stark::KeccakStark; use crate::keccak::keccak_stark::KeccakStark;
use crate::proof::AllProof; use crate::proof::AllProof;
use crate::prover::prove; use crate::prover::prove;
@ -104,10 +104,12 @@ mod tests {
let default = vec![F::ZERO; 2]; let default = vec![F::ZERO; 2];
let cross_table_lookups = vec![CrossTableLookup { let cross_table_lookups = vec![CrossTableLookup {
looking_tables: vec![Table::Cpu], looking_tables: vec![TableWithColumns::new(
looking_columns: vec![vec![cpu::columns::OPCODE]], Table::Cpu,
looked_table: Table::Keccak, vec![cpu::columns::OPCODE],
looked_columns: vec![keccak_looked_col], None,
)],
looked_table: TableWithColumns::new(Table::Keccak, vec![keccak_looked_col], None),
default, default,
}]; }];

View File

@ -1,5 +1,4 @@
use anyhow::{ensure, Result}; use anyhow::{ensure, Result};
use itertools::izip;
use plonky2::field::extension_field::{Extendable, FieldExtension}; use plonky2::field::extension_field::{Extendable, FieldExtension};
use plonky2::field::field_types::Field; use plonky2::field::field_types::Field;
use plonky2::field::packed_field::PackedField; use plonky2::field::packed_field::PackedField;
@ -21,32 +20,42 @@ use crate::proof::{StarkProofWithPublicInputs, StarkProofWithPublicInputsTarget}
use crate::stark::Stark; use crate::stark::Stark;
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
#[derive(Clone)]
pub struct TableWithColumns {
pub table: Table,
pub columns: Vec<usize>,
pub filter_column: Option<usize>,
}
impl TableWithColumns {
pub fn new(table: Table, columns: Vec<usize>, filter_column: Option<usize>) -> Self {
Self {
table,
columns,
filter_column,
}
}
}
#[derive(Clone)] #[derive(Clone)]
pub struct CrossTableLookup<F: Field> { pub struct CrossTableLookup<F: Field> {
pub looking_tables: Vec<Table>, pub looking_tables: Vec<TableWithColumns>,
pub looking_columns: Vec<Vec<usize>>, pub looked_table: TableWithColumns,
pub looked_table: Table,
pub looked_columns: Vec<usize>,
pub default: Vec<F>, pub default: Vec<F>,
} }
impl<F: Field> CrossTableLookup<F> { impl<F: Field> CrossTableLookup<F> {
pub fn new( pub fn new(
looking_tables: Vec<Table>, looking_tables: Vec<TableWithColumns>,
looking_columns: Vec<Vec<usize>>, looked_table: TableWithColumns,
looked_table: Table,
looked_columns: Vec<usize>,
default: Vec<F>, default: Vec<F>,
) -> Self { ) -> Self {
assert_eq!(looking_tables.len(), looking_columns.len()); assert!(looking_tables
assert!(looking_columns
.iter() .iter()
.all(|cols| cols.len() == looked_columns.len())); .all(|twc| twc.columns.len() == looked_table.columns.len()));
Self { Self {
looking_tables, looking_tables,
looking_columns,
looked_table, looked_table,
looked_columns,
default, default,
} }
} }
@ -92,22 +101,21 @@ pub fn cross_table_lookup_data<F: RichField, C: GenericConfig<D, F = F>, const D
let mut ctl_data_per_table = vec![CtlData::new(challenges.clone()); trace_poly_values.len()]; let mut ctl_data_per_table = vec![CtlData::new(challenges.clone()); trace_poly_values.len()];
for CrossTableLookup { for CrossTableLookup {
looking_tables, looking_tables,
looking_columns,
looked_table, looked_table,
looked_columns,
default, default,
} in cross_table_lookups } in cross_table_lookups
{ {
for &challenge in &challenges.challenges { for &challenge in &challenges.challenges {
let zs_looking = looking_tables let zs_looking = looking_tables.iter().map(|table| {
.iter() partial_products(
.zip(looking_columns) &trace_poly_values[table.table as usize],
.map(|(table, columns)| { &table.columns,
partial_products(&trace_poly_values[*table as usize], columns, challenge) challenge,
}); )
});
let z_looked = partial_products( let z_looked = partial_products(
&trace_poly_values[*looked_table as usize], &trace_poly_values[looked_table.table as usize],
looked_columns, &looked_table.columns,
challenge, challenge,
); );
@ -120,20 +128,20 @@ pub fn cross_table_lookup_data<F: RichField, C: GenericConfig<D, F = F>, const D
* challenge.combine(default).exp_u64( * challenge.combine(default).exp_u64(
looking_tables looking_tables
.iter() .iter()
.map(|table| trace_poly_values[*table as usize][0].len() as u64) .map(|table| trace_poly_values[table.table as usize][0].len() as u64)
.sum::<u64>() .sum::<u64>()
- trace_poly_values[*looked_table as usize][0].len() as u64 - trace_poly_values[looked_table.table as usize][0].len() as u64
) )
); );
for (table, columns, z) in izip!(looking_tables, looking_columns, zs_looking) { for (table, z) in looking_tables.iter().zip(zs_looking) {
ctl_data_per_table[*table as usize] ctl_data_per_table[table.table as usize]
.zs_columns .zs_columns
.push((z, columns.clone())); .push((z, table.columns.clone()));
} }
ctl_data_per_table[*looked_table as usize] ctl_data_per_table[looked_table.table as usize]
.zs_columns .zs_columns
.push((z_looked, looked_columns.clone())); .push((z_looked, looked_table.columns.clone()));
} }
} }
ctl_data_per_table ctl_data_per_table
@ -191,29 +199,27 @@ impl<'a, F: RichField + Extendable<D>, const D: usize>
let mut ctl_vars_per_table = vec![vec![]; proofs.len()]; let mut ctl_vars_per_table = vec![vec![]; proofs.len()];
for CrossTableLookup { for CrossTableLookup {
looking_tables, looking_tables,
looking_columns,
looked_table, looked_table,
looked_columns,
.. ..
} in cross_table_lookups } in cross_table_lookups
{ {
for &challenges in &ctl_challenges.challenges { for &challenges in &ctl_challenges.challenges {
for (table, columns) in looking_tables.iter().zip(looking_columns) { for table in looking_tables {
let (looking_z, looking_z_next) = ctl_zs[*table as usize].next().unwrap(); let (looking_z, looking_z_next) = ctl_zs[table.table as usize].next().unwrap();
ctl_vars_per_table[*table as usize].push(Self { ctl_vars_per_table[table.table as usize].push(Self {
local_z: *looking_z, local_z: *looking_z,
next_z: *looking_z_next, next_z: *looking_z_next,
challenges, challenges,
columns, columns: &table.columns,
}); });
} }
let (looked_z, looked_z_next) = ctl_zs[*looked_table as usize].next().unwrap(); let (looked_z, looked_z_next) = ctl_zs[looked_table.table as usize].next().unwrap();
ctl_vars_per_table[*looked_table as usize].push(Self { ctl_vars_per_table[looked_table.table as usize].push(Self {
local_z: *looked_z, local_z: *looked_z,
next_z: *looked_z_next, next_z: *looked_z_next,
challenges, challenges,
columns: looked_columns, columns: &looked_table.columns,
}); });
} }
} }
@ -278,29 +284,27 @@ impl<'a, const D: usize> CtlCheckVarsTarget<'a, D> {
let mut ctl_vars_per_table = vec![vec![]; proofs.len()]; let mut ctl_vars_per_table = vec![vec![]; proofs.len()];
for CrossTableLookup { for CrossTableLookup {
looking_tables, looking_tables,
looking_columns,
looked_table, looked_table,
looked_columns,
.. ..
} in cross_table_lookups } in cross_table_lookups
{ {
for &challenges in &ctl_challenges.challenges { for &challenges in &ctl_challenges.challenges {
for (table, columns) in looking_tables.iter().zip(looking_columns) { for table in looking_tables {
let (looking_z, looking_z_next) = ctl_zs[*table as usize].next().unwrap(); let (looking_z, looking_z_next) = ctl_zs[table.table as usize].next().unwrap();
ctl_vars_per_table[*table as usize].push(Self { ctl_vars_per_table[table.table as usize].push(Self {
local_z: *looking_z, local_z: *looking_z,
next_z: *looking_z_next, next_z: *looking_z_next,
challenges, challenges,
columns, columns: &table.columns,
}); });
} }
let (looked_z, looked_z_next) = ctl_zs[*looked_table as usize].next().unwrap(); let (looked_z, looked_z_next) = ctl_zs[looked_table.table as usize].next().unwrap();
ctl_vars_per_table[*looked_table as usize].push(Self { ctl_vars_per_table[looked_table.table as usize].push(Self {
local_z: *looked_z, local_z: *looked_z,
next_z: *looked_z_next, next_z: *looked_z_next,
challenges, challenges,
columns: looked_columns, columns: &looked_table.columns,
}); });
} }
} }
@ -380,14 +384,14 @@ pub(crate) fn verify_cross_table_lookups<
{ {
let looking_degrees_sum = looking_tables let looking_degrees_sum = looking_tables
.iter() .iter()
.map(|&table| 1 << degrees_bits[table as usize]) .map(|table| 1 << degrees_bits[table.table as usize])
.sum::<u64>(); .sum::<u64>();
let looked_degree = 1 << degrees_bits[looked_table as usize]; let looked_degree = 1 << degrees_bits[looked_table.table as usize];
let looking_zs_prod = looking_tables let looking_zs_prod = looking_tables
.into_iter() .into_iter()
.map(|table| *ctl_zs_openings[table as usize].next().unwrap()) .map(|table| *ctl_zs_openings[table.table as usize].next().unwrap())
.product::<F>(); .product::<F>();
let looked_z = *ctl_zs_openings[looked_table as usize].next().unwrap(); let looked_z = *ctl_zs_openings[looked_table.table as usize].next().unwrap();
let challenge = challenges.challenges[i % config.num_challenges]; let challenge = challenges.challenges[i % config.num_challenges];
let combined_default = challenge.combine(default.iter()); let combined_default = challenge.combine(default.iter());
@ -432,15 +436,15 @@ pub(crate) fn verify_cross_table_lookups_circuit<
{ {
let looking_degrees_sum = looking_tables let looking_degrees_sum = looking_tables
.iter() .iter()
.map(|&table| 1 << degrees_bits[table as usize]) .map(|table| 1 << degrees_bits[table.table as usize])
.sum::<u64>(); .sum::<u64>();
let looked_degree = 1 << degrees_bits[looked_table as usize]; let looked_degree = 1 << degrees_bits[looked_table.table as usize];
let looking_zs_prod = builder.mul_many( let looking_zs_prod = builder.mul_many(
looking_tables looking_tables
.into_iter() .into_iter()
.map(|table| *ctl_zs_openings[table as usize].next().unwrap()), .map(|table| *ctl_zs_openings[table.table as usize].next().unwrap()),
); );
let looked_z = *ctl_zs_openings[looked_table as usize].next().unwrap(); let looked_z = *ctl_zs_openings[looked_table.table as usize].next().unwrap();
let challenge = challenges.challenges[i % inner_config.num_challenges]; let challenge = challenges.challenges[i % inner_config.num_challenges];
let default = default let default = default
.into_iter() .into_iter()