Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 40 additions & 31 deletions aggregator/src/aggregation/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ use zkevm_circuits::{
util::Challenges,
};

use crate::aggregation::decoder::tables::FixedLookupTag;

use self::{
tables::{
BitstringTable, FseTable, FseTableKind, LiteralsHeaderTable, RomFseOrderTable,
RomSequenceCodes, RomSequencesDataInterleavedOrder, RomTagTable,
tables::{BitstringTable, FixedTable, FseTable, LiteralsHeaderTable},
witgen::{
FseTableKind, ZstdTag, N_BITS_PER_BYTE, N_BITS_REPEAT_FLAG, N_BITS_ZSTD_TAG,
N_BLOCK_HEADER_BYTES,
},
witgen::{ZstdTag, N_BITS_PER_BYTE, N_BITS_REPEAT_FLAG, N_BITS_ZSTD_TAG, N_BLOCK_HEADER_BYTES},
};

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -82,14 +84,8 @@ pub struct DecoderConfig {
fse_table: FseTable,
/// Helper table for sequences as instructions.
/// TODO(enable): sequence_instruction_table: SequenceInstructionTable,
/// ROM table for validating tag transition.
rom_tag_table: RomTagTable,
/// ROM table for the correct order in which FSE tables are described in the sequences section.
rom_fse_order_table: RomFseOrderTable,
/// ROM table for the correct interleaved order while processing tag=ZstdBlockSequencesData.
rom_interleaved_order_table: RomSequencesDataInterleavedOrder,
/// ROM table for sequence codes to value. LLC, MOC and MLC.
rom_sequence_codes_table: RomSequenceCodes,
/// Fixed lookups table.
fixed_table: FixedTable,
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -970,11 +966,8 @@ impl DecoderConfig {
bitwise_op_table,
}: DecoderConfigArgs,
) -> Self {
// Fixed tables
let rom_tag_table = RomTagTable::construct(meta);
let rom_fse_order_table = RomFseOrderTable::construct(meta);
let rom_interleaved_order_table = RomSequencesDataInterleavedOrder::construct(meta);
let rom_sequence_codes_table = RomSequenceCodes::construct(meta);
// Fixed table
let fixed_table = FixedTable::construct(meta);

// Helper tables
let literals_header_table = LiteralsHeaderTable::configure(meta, range8, range16);
Expand Down Expand Up @@ -1021,10 +1014,7 @@ impl DecoderConfig {
bitstring_table,
fse_table,
// TODO(enable): sequence_instruction_table,
rom_tag_table,
rom_fse_order_table,
rom_interleaved_order_table,
rom_sequence_codes_table,
fixed_table,
};

macro_rules! is_tag {
Expand Down Expand Up @@ -1279,11 +1269,12 @@ impl DecoderConfig {
cb.gate(condition)
});

meta.lookup_any("DecoderConfig: lookup RomTagTable", |meta| {
meta.lookup_any("DecoderConfig: fixed lookup (tag transition)", |meta| {
let condition = meta.query_fixed(config.q_first, Rotation::cur())
+ meta.query_advice(config.tag_config.is_change, Rotation::cur());

[
FixedLookupTag::TagTransition.expr(),
meta.query_advice(config.tag_config.tag, Rotation::cur()),
meta.query_advice(config.tag_config.tag_next, Rotation::cur()),
meta.query_advice(config.tag_config.max_len, Rotation::cur()),
Expand All @@ -1292,7 +1283,7 @@ impl DecoderConfig {
meta.query_advice(config.block_config.is_block, Rotation::cur()),
]
.into_iter()
.zip_eq(config.rom_tag_table.table_exprs(meta))
.zip_eq(config.fixed_table.table_exprs(meta))
.map(|(value, table)| (condition.expr() * value, table))
.collect()
});
Expand Down Expand Up @@ -2047,17 +2038,24 @@ impl DecoderConfig {
meta.query_advice(config.tag_config.is_change, Rotation::cur()),
]);

[
let (cmode_llt, cmode_mot, cmode_mlt) = (
meta.query_advice(config.block_config.compression_modes[0], Rotation::cur()),
meta.query_advice(config.block_config.compression_modes[1], Rotation::cur()),
meta.query_advice(config.block_config.compression_modes[2], Rotation::cur()),
);

let cmodes_lc = (4.expr() * cmode_llt) + (2.expr() * cmode_mot) + cmode_mlt;
[
FixedLookupTag::SeqTagOrder.expr(),
cmodes_lc,
meta.query_advice(config.tag_config.tag, Rotation::prev()), // tag_prev
meta.query_advice(config.tag_config.tag, Rotation::cur()), // tag_cur
meta.query_advice(config.tag_config.tag_next, Rotation::cur()), // tag_next
meta.query_advice(config.fse_decoder.table_kind, Rotation::cur()), // table_kind
0.expr(), // unused
]
.into_iter()
.zip_eq(config.rom_fse_order_table.table_exprs(meta))
.zip_eq(config.fixed_table.table_exprs(meta))
.map(|(arg, table)| (condition.expr() * arg, table))
.collect()
},
Expand Down Expand Up @@ -2407,13 +2405,16 @@ impl DecoderConfig {
);

[
FixedLookupTag::SeqDataInterleavedOrder.expr(),
table_kind_prev,
table_kind_curr,
is_init_state,
is_update_state,
0.expr(), // unused
0.expr(), // unused
]
.into_iter()
.zip_eq(config.rom_interleaved_order_table.table_exprs(meta))
.zip_eq(config.fixed_table.table_exprs(meta))
.map(|(arg, table)| (condition.expr() * arg, table))
.collect()
},
Expand Down Expand Up @@ -2756,11 +2757,19 @@ impl DecoderConfig {
.bitstring_len(meta, Rotation::cur()),
);

[table_kind, code, baseline, nb]
.into_iter()
.zip_eq(config.rom_sequence_codes_table.table_exprs(meta))
.map(|(arg, table)| (condition.expr() * arg, table))
.collect()
[
FixedLookupTag::SeqCodeToValue.expr(),
table_kind,
code,
baseline,
nb,
0.expr(), // unused
0.expr(), // unused
]
.into_iter()
.zip_eq(config.fixed_table.table_exprs(meta))
.map(|(arg, table)| (condition.expr() * arg, table))
.collect()
},
);

Expand Down
17 changes: 3 additions & 14 deletions aggregator/src/aggregation/decoder/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,6 @@ pub use fse::FseTable;
mod literals_header;
pub use literals_header::LiteralsHeaderTable;

/// Validate the assignment of FSE table kind while decoding FSE tables in the sequences section.
mod rom_fse_order;
pub use rom_fse_order::{
predefined_table, predefined_table_values, FsePredefinedTable, FseTableKind, RomFseOrderTable,
RomSequencesDataInterleavedOrder,
};

/// The fixed code to Baseline/NumBits for Literal Length.
mod rom_sequence_codes;
pub use rom_sequence_codes::RomSequenceCodes;

/// Validate the following tag given the tag currently being processed.
mod rom_tag;
pub use rom_tag::RomTagTable;
/// Fixed lookup table and its variants.
mod fixed;
pub use fixed::{predefined_fse, FixedLookupTag, FixedTable, PredefinedFse};
149 changes: 149 additions & 0 deletions aggregator/src/aggregation/decoder/tables/fixed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use eth_types::Field;
use gadgets::impl_expr;
use halo2_proofs::{
circuit::{Layouter, Value},
halo2curves::bn256::Fr,
plonk::{Column, ConstraintSystem, Error, Expression, Fixed},
};
use itertools::Itertools;
use strum::IntoEnumIterator;
use strum_macros::EnumIter;
use zkevm_circuits::table::LookupTable;

mod fse_table_transition;
use fse_table_transition::RomFseTableTransition;

mod predefined_fse;
use predefined_fse::RomPredefinedFse;
pub use predefined_fse::{predefined_fse, PredefinedFse};

mod seq_code_to_value;
use seq_code_to_value::RomSeqCodeToValue;

mod seq_data_interleaved_order;
use seq_data_interleaved_order::RomSeqDataInterleavedOrder;

mod seq_tag_order;
use seq_tag_order::RomSeqTagOrder;

mod tag_transition;
use tag_transition::RomTagTransition;

pub trait FixedLookupValues {
fn values() -> Vec<[Value<Fr>; 7]>;
}

#[derive(Clone, Copy, Debug, EnumIter)]
pub enum FixedLookupTag {
/// Properties used to describe the ZstdTag of the chunk of bytes.
TagTransition = 1,
/// Depending on the compression modes used in the sequences header, we experience different
/// tag transitions and an FSE table for each tag=ZstdTagSequencesFseCode.
SeqTagOrder,
/// The bitstream which sequences are decoded from is interleaved with multiple variants. All
/// those variants are handled here.
SeqDataInterleavedOrder,
/// The predefined code-to-value table that allows us to compute "value" from the "code"
/// decoded.
SeqCodeToValue,
/// The FSE table's layout is assigned such that tables from different blocks appear in a
/// specific order, which is handled here.
FseTableTransition,
/// Represents the FSE table reconstructed from the default distributions, i.e. Predefined FSE
/// table.
PredefinedFse,
}

impl_expr!(FixedLookupTag);

impl FixedLookupTag {
fn values(&self) -> Vec<[Value<Fr>; 7]> {
match self {
Self::TagTransition => RomTagTransition::values(),
Self::SeqTagOrder => RomSeqTagOrder::values(),
Self::SeqDataInterleavedOrder => RomSeqDataInterleavedOrder::values(),
Self::SeqCodeToValue => RomSeqCodeToValue::values(),
Self::FseTableTransition => RomFseTableTransition::values(),
Self::PredefinedFse => RomPredefinedFse::values(),
}
}
}

#[derive(Clone, Debug)]
pub struct FixedTable {
lookup_tag: Column<Fixed>,
fixed1: Column<Fixed>,
fixed2: Column<Fixed>,
fixed3: Column<Fixed>,
fixed4: Column<Fixed>,
fixed5: Column<Fixed>,
fixed6: Column<Fixed>,
}

impl FixedTable {
pub fn construct(meta: &mut ConstraintSystem<Fr>) -> Self {
Self {
lookup_tag: meta.fixed_column(),
fixed1: meta.fixed_column(),
fixed2: meta.fixed_column(),
fixed3: meta.fixed_column(),
fixed4: meta.fixed_column(),
fixed5: meta.fixed_column(),
fixed6: meta.fixed_column(),
}
}

pub fn load(&self, layouter: &mut impl Layouter<Fr>) -> Result<(), Error> {
layouter.assign_region(
|| "Fixed lookup table",
|mut region| {
for (i, row) in FixedLookupTag::iter()
.flat_map(|lookup_tag| lookup_tag.values())
.enumerate()
{
for ((&column, annotation), &value) in self
.fixed_columns()
.iter()
.zip_eq(self.annotations())
.zip_eq(row.iter())
{
region.assign_fixed(
|| format!("{} at offset={i}", annotation),
column,
i,
|| value,
)?;
}
}

Ok(())
},
)
}
}

impl LookupTable<Fr> for FixedTable {
fn columns(&self) -> Vec<Column<halo2_proofs::plonk::Any>> {
vec![
self.lookup_tag.into(),
self.fixed1.into(),
self.fixed2.into(),
self.fixed3.into(),
self.fixed4.into(),
self.fixed5.into(),
self.fixed6.into(),
]
}

fn annotations(&self) -> Vec<String> {
vec![
String::from("lookup_tag"),
String::from("fixed1"),
String::from("fixed2"),
String::from("fixed3"),
String::from("fixed4"),
String::from("fixed5"),
String::from("fixed6"),
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use halo2_proofs::{circuit::Value, halo2curves::bn256::Fr};

use crate::aggregation::decoder::witgen::FseTableKind;

use super::{FixedLookupTag, FixedLookupValues};

pub struct RomFseTableTransition {
/// The block index on the previous FSE table.
block_idx_prev: u64,
/// The block index on the current FSE table.
block_idx_curr: u64,
/// The FSE table previously decoded.
table_kind_prev: u64,
/// The FSE table currently decoded.
table_kind_curr: u64,
}

impl FixedLookupValues for RomFseTableTransition {
fn values() -> Vec<[Value<Fr>; 7]> {
[
vec![[
Value::known(Fr::from(FixedLookupTag::FseTableTransition as u64)),
Value::known(Fr::zero()), // block_idx_prev
Value::known(Fr::one()), // block_idx_curr
Value::known(Fr::zero()), // table_kind_prev
Value::known(Fr::from(FseTableKind::LLT as u64)),
Value::known(Fr::zero()),
Value::known(Fr::zero()),
]],
[
(1, 1, FseTableKind::LLT, FseTableKind::MOT),
(1, 1, FseTableKind::MOT, FseTableKind::MLT),
// TODO: add more for multi-block scenario
]
.map(
|(block_idx_prev, block_idx_curr, table_kind_prev, table_kind_curr)| {
[
Value::known(Fr::from(FixedLookupTag::FseTableTransition as u64)),
Value::known(Fr::from(block_idx_prev)),
Value::known(Fr::from(block_idx_curr)),
Value::known(Fr::from(table_kind_prev as u64)),
Value::known(Fr::from(table_kind_curr as u64)),
Value::known(Fr::zero()),
Value::known(Fr::zero()),
]
},
)
.to_vec(),
]
.concat()
}
}
Loading