From c06991c1e0895ee391a77332536728bef6bc4704 Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Tue, 7 Feb 2023 18:48:45 +0100 Subject: [PATCH 01/11] Start layout refactor --- zkevm-circuits/src/circuit_tools.rs | 524 +++++++++++++++++- zkevm-circuits/src/mpt_circuit.rs | 198 +++++-- .../account_leaf/account_leaf_key.rs | 116 ++-- .../account_leaf_key_in_added_branch.rs | 85 +-- .../account_leaf_storage_codehash.rs | 79 +-- .../account_leaf/account_non_existing.rs | 37 +- zkevm-circuits/src/mpt_circuit/branch.rs | 134 ++++- .../src/mpt_circuit/branch/branch_key.rs | 142 +++-- .../src/mpt_circuit/branch/extension_node.rs | 7 +- zkevm-circuits/src/mpt_circuit/helpers.rs | 310 ++++++++--- .../src/mpt_circuit/storage_leaf.rs | 1 + .../mpt_circuit/storage_leaf/leaf_combined.rs | 331 +++++++++++ .../src/mpt_circuit/storage_leaf/leaf_key.rs | 118 ++-- .../storage_leaf/leaf_key_in_added_branch.rs | 22 +- .../storage_leaf/leaf_non_existing.rs | 64 ++- .../mpt_circuit/storage_leaf/leaf_value.rs | 101 ++-- zkevm-circuits/src/mpt_circuit/witness_row.rs | 24 +- 17 files changed, 1824 insertions(+), 469 deletions(-) create mode 100644 zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs diff --git a/zkevm-circuits/src/circuit_tools.rs b/zkevm-circuits/src/circuit_tools.rs index b137c6c436..0175f8ede9 100644 --- a/zkevm-circuits/src/circuit_tools.rs +++ b/zkevm-circuits/src/circuit_tools.rs @@ -1,9 +1,19 @@ //! Circuit utilities -use crate::{evm_circuit::util::rlc, util::Expr}; +use std::{ + collections::BTreeMap, + marker::PhantomData, + ops::{Index, IndexMut}, +}; + +use crate::{ + evm_circuit::util::rlc, + util::{query_expression, Expr}, +}; use gadgets::util::{and, select, sum}; use halo2_proofs::{ arithmetic::FieldExt, - plonk::{Advice, Column, ConstraintSystem, Expression, VirtualCells}, + circuit::{AssignedCell, Layouter, Region, Value}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, VirtualCells}, poly::Rotation, }; use itertools::Itertools; @@ -57,6 +67,415 @@ impl Expr for DataTransition { } } +#[derive(Clone, Debug)] +pub(crate) struct Cell { + // expression for constraint + expression: Expression, + column: Column, + // relative position to selector for synthesis + rotation: usize, +} + +impl Cell { + pub(crate) fn new(meta: &mut VirtualCells, column: Column, rotation: usize) -> Self { + Self { + expression: meta.query_advice(column, Rotation(rotation as i32)), + column, + rotation, + } + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + value: Value, + ) -> Result, Error> { + region.assign_advice( + || { + format!( + "Cell column: {:?} and rotation: {}", + self.column, self.rotation + ) + }, + self.column, + offset + self.rotation, + || value, + ) + } +} + +impl Expr for Cell { + fn expr(&self) -> Expression { + self.expression.clone() + } +} + +impl Expr for &Cell { + fn expr(&self) -> Expression { + self.expression.clone() + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub(crate) enum CellType { + Storage, +} + +#[derive(Clone, Debug)] +pub(crate) struct CellColumn { + pub(crate) index: usize, + pub(crate) cell_type: CellType, + pub(crate) height: usize, + pub(crate) expr: Expression, +} + +impl Expr for CellColumn { + fn expr(&self) -> Expression { + self.expr.clone() + } +} + +#[derive(Clone, Debug)] +pub(crate) struct CellManager { + width: usize, + height: usize, + cells: Vec>, + columns: Vec>, +} + +impl CellManager { + pub(crate) fn new( + meta: &mut VirtualCells, + height: usize, + advices: &[Column], + height_offset: usize, + ) -> Self { + // Setup the columns and query the cells + let width = advices.len(); + let mut cells = Vec::with_capacity(height * width); + let mut columns = Vec::with_capacity(width); + for c in 0..width { + for r in 0..height { + cells.push(Cell::new(meta, advices[c], height_offset + r)); + } + columns.push(CellColumn { + index: c, + cell_type: CellType::Storage, + height: 0, + expr: cells[c * height].expr(), + }); + } + + Self { + width, + height, + cells, + columns, + } + } + + pub(crate) fn query_cells(&mut self, cell_type: CellType, count: usize) -> Vec> { + let mut cells = Vec::with_capacity(count); + while cells.len() < count { + let column_idx = self.next_column(cell_type); + let column = &mut self.columns[column_idx]; + cells.push(self.cells[column_idx * self.height + column.height].clone()); + column.height += 1; + } + cells + } + + pub(crate) fn query_cell(&mut self, cell_type: CellType) -> Cell { + self.query_cells(cell_type, 1)[0].clone() + } + + fn next_column(&self, cell_type: CellType) -> usize { + let mut best_index: Option = None; + let mut best_height = self.height; + for column in self.columns.iter() { + if column.cell_type == cell_type && column.height < best_height { + best_index = Some(column.index); + best_height = column.height; + } + } + match best_index { + Some(index) => index, + None => unreachable!("not enough cells for query: {:?}", cell_type), + } + } + + pub(crate) fn get_height(&self) -> usize { + self.columns + .iter() + .map(|column| column.height) + .max() + .unwrap() + } + + /// Returns a map of CellType -> (width, height, num_cells) + pub(crate) fn get_stats(&self) -> BTreeMap { + let mut data = BTreeMap::new(); + for column in self.columns.iter() { + let (mut count, mut height, mut num_cells) = + data.get(&column.cell_type).unwrap_or(&(0, 0, 0)); + count += 1; + height = height.max(column.height); + num_cells += column.height; + data.insert(column.cell_type, (count, height, num_cells)); + } + data + } + + pub(crate) fn columns(&self) -> &[CellColumn] { + &self.columns + } +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct Memory { + columns: Vec>, + banks: Vec>, +} + +impl Memory { + pub(crate) fn new(columns: Vec>) -> Self { + Self { + columns, + banks: Vec::new(), + } + } + + pub(crate) fn allocate>( + &mut self, + meta: &mut ConstraintSystem, + tag: S, + ) -> &MemoryBank { + self.banks + .push(MemoryBank::new(meta, self.columns[self.banks.len()], tag)); + self.banks.last().unwrap() + } + + pub(crate) fn get>(&self, tag: S) -> &MemoryBank { + for bank in self.banks.iter() { + if bank.tag() == tag.as_ref() { + return bank; + } + } + unreachable!() + } + + pub(crate) fn get_mut>(&mut self, tag: S) -> &mut MemoryBank { + for bank in self.banks.iter_mut() { + if bank.tag() == tag.as_ref() { + return bank; + } + } + unreachable!() + } + + pub(crate) fn generate_constraints(&self, cb: &mut ConstraintBuilder) { + for bank in self.banks.iter() { + bank.generate_constraints(cb); + + cb.generate_lookup_table_checks(bank.tag()); + + /*let lookups = cb.consume_lookups(&[bank.tag()]); + if !lookups.is_empty() { + //println!("{}: {}", tag, lookups.len()); + let (_, values) = merge_lookups(cb, lookups); + crate::circuit!([meta, cb], { + require!(values => @bank.tag()); + }) + }*/ + } + } + + pub(crate) fn clear_witness_data(&mut self) { + for bank in self.banks.iter_mut() { + bank.clear_witness_data(); + } + } + + pub(crate) fn assign( + &self, + layouter: &mut impl Layouter, + height: usize, + ) -> Result<(), Error> { + for bank in self.banks.iter() { + bank.assign(layouter, height)?; + } + Ok(()) + } + + pub(crate) fn tags(&self) -> Vec { + self.banks.iter().map(|bank| bank.tag()).collect() + } +} + +impl> Index for Memory { + type Output = MemoryBank; + + fn index(&self, tag: S) -> &Self::Output { + for bank in self.banks.iter() { + if bank.tag() == tag.as_ref() { + return bank; + } + } + unreachable!() + } +} + +impl> IndexMut for Memory { + fn index_mut(&mut self, tag: S) -> &mut Self::Output { + for bank in self.banks.iter_mut() { + if bank.tag() == tag.as_ref() { + return bank; + } + } + unreachable!() + } +} + +#[derive(Clone, Debug)] +pub(crate) struct MemoryBank { + column: Column, + tag: String, + cur: Expression, + next: Expression, + store_offsets: Vec, + stored_values: Vec>, + _marker: PhantomData, +} + +impl MemoryBank { + pub(crate) fn new>( + meta: &mut ConstraintSystem, + column: Column, + tag: S, + ) -> Self { + let mut cur = 0.expr(); + let mut next = 0.expr(); + query_expression(meta, |meta| { + cur = meta.query_advice(column, Rotation::cur()); + next = meta.query_advice(column, Rotation::next()); + }); + Self { + column, + tag: tag.as_ref().to_owned(), + cur, + next, + store_offsets: Vec::new(), + stored_values: Vec::new(), + _marker: PhantomData, + } + } + + pub(crate) fn key(&self) -> Expression { + self.cur.expr() + } + + pub(crate) fn load( + &self, + description: &'static str, + cb: &mut ConstraintBuilder, + offset: Expression, + values: &[Expression], + ) { + self.load_with_key(description, cb, self.key() - offset, values); + } + + pub(crate) fn load_with_key( + &self, + description: &'static str, + cb: &mut ConstraintBuilder, + key: Expression, + values: &[Expression], + ) { + let mut key_values = values.to_vec(); + key_values.insert(0, key); + cb.lookup(description, self.tag(), values.to_vec()); + } + + pub(crate) fn store(&self, cb: &mut ConstraintBuilder, values: &[Expression]) { + self.store_with_key(cb, self.key() + 1.expr(), values); + } + + pub(crate) fn store_with_key( + &self, + cb: &mut ConstraintBuilder, + key: Expression, + values: &[Expression], + ) { + let mut key_values = values.to_vec(); + key_values.insert(0, key); + cb.lookup_table("memory store", self.tag(), values.to_vec()); + } + + pub(crate) fn witness_store(&mut self, offset: usize, values: &[F]) { + self.stored_values.push(values.to_vec()); + self.store_offsets.push(offset); + } + + pub(crate) fn witness_store_init(&mut self, values: &[F]) { + self.stored_values.push(values.to_vec()); + } + + pub(crate) fn witness_load(&self, offset: usize) -> Vec { + self.stored_values[self.stored_values.len() - 1 - offset].clone() + } + + pub(crate) fn clear_witness_data(&mut self) { + self.store_offsets.clear(); + } + + pub(crate) fn generate_constraints(&self, cb: &mut ConstraintBuilder) { + let lookup_table = cb.get_lookup_table(self.tag()); + crate::circuit!([meta, cb], { + require!(self.next => self.cur.expr() + lookup_table.0); + }); + } + + pub(crate) fn assign( + &self, + layouter: &mut impl Layouter, + height: usize, + ) -> Result<(), Error> { + layouter.assign_region( + || "memory bank", + |mut region| { + // Pad to the full circuit (necessary for reads) + let mut store_offsets = self.store_offsets.clone(); + store_offsets.push(height); + + //println!("offsets: {:?}", self.store_offsets); + + //println!("height: {}", height); + let mut store_index = 0; + let mut offset = 0; + for &stored_offset in store_offsets.iter() { + while offset <= stored_offset { + region.assign_advice( + || "assign memory index".to_string(), + self.column, + offset, + || Value::known(F::from(store_index as u64)), + )?; + //println!("[{}] {}: {}", self.tag(), offset, store_index); + offset += 1; + } + store_index += 1; + } + Ok(()) + }, + ) + } + + pub(crate) fn tag(&self) -> String { + self.tag.clone() + } +} + /// Lookup data #[derive(Clone)] pub struct LookupData { @@ -79,6 +498,8 @@ pub struct ConstraintBuilder { pub lookups: Vec>, /// The lookup tables pub lookup_tables: Vec>, + /// Query offset + pub query_offset: i32, } impl ConstraintBuilder { @@ -89,6 +510,7 @@ impl ConstraintBuilder { conditions: Vec::new(), lookups: Vec::new(), lookup_tables: Vec::new(), + query_offset: 0, } } @@ -186,7 +608,7 @@ impl ConstraintBuilder { .collect::>(); for lookup in lookups.iter() { meta.lookup_any(lookup.description, |_meta| { - let table = self.get_lookup_table(lookup_name); + let table = self.get_lookup_table_values(lookup_name); let mut values: Vec<_> = lookup .values .iter() @@ -218,31 +640,31 @@ impl ConstraintBuilder { self.get_condition().unwrap_or_else(|| 1.expr()) } - pub(crate) fn lookup_table( + pub(crate) fn lookup_table>( &mut self, description: &'static str, - tag: String, + tag: S, values: Vec>, ) { let condition = self.get_condition_expr(); self.lookup_tables.push(LookupData { description, - tag, + tag: tag.as_ref().to_owned(), condition, values, }); } - pub(crate) fn lookup( + pub(crate) fn lookup>( &mut self, description: &'static str, - tag: String, + tag: S, values: Vec>, ) { let condition = self.get_condition_expr(); self.lookups.push(LookupData { description, - tag, + tag: tag.as_ref().to_owned(), condition, values, }); @@ -256,23 +678,62 @@ impl ConstraintBuilder { .collect::>() } - pub(crate) fn get_lookup_table>(&self, tag: S) -> Vec> { + pub(crate) fn consume_lookups>(&mut self, tags: &[S]) -> Vec> { + let lookups = self.get_lookups(tags); + self.lookups + .retain(|lookup| tags.iter().any(|tag| lookup.tag != tag.as_ref())); + lookups + } + + pub(crate) fn get_lookup_table>( + &self, + tag: S, + ) -> (Expression, Vec>) { let lookups = self .lookup_tables .iter() .filter(|lookup| lookup.tag == tag.as_ref()) .collect::>(); - let selector = sum::expr(lookups.iter().map(|lookup| lookup.condition.expr())); - let mut table = vec![0.expr(); lookups[0].values.len()]; - for (idx, value) in table.iter_mut().enumerate() { - *value = sum::expr( - lookups - .iter() - .map(|lookup| selector.expr() * lookup.values[idx].expr()), + merge_values_unsafe( + lookups + .iter() + .map(|lookup| (lookup.condition.clone(), lookup.values.clone())) + .collect::>(), + ) + } + + pub(crate) fn get_lookup_table_values>(&self, tag: S) -> Vec> { + let lookup_table = self.get_lookup_table(tag); + // Combine with the merged selector as well + lookup_table + .1 + .iter() + .map(|v| v.expr() * lookup_table.0.expr()) + .collect::>() + } + + pub(crate) fn generate_lookup_table_checks>(&mut self, tag: S) { + let lookups = self + .lookup_tables + .iter() + .filter(|lookup| lookup.tag == tag.as_ref()) + .collect::>(); + let selectors = lookups + .iter() + .map(|lookup| lookup.condition.expr()) + .collect::>(); + for selector in selectors.iter() { + self.require_boolean( + "lookup table condition needs to be boolean", + selector.expr(), ); } - table + let selector = sum::expr(&selectors); + self.require_boolean( + "lookup table conditions sum needs to be boolean", + selector.expr(), + ); } pub(crate) fn print_stats(&self) { @@ -282,6 +743,14 @@ impl ConstraintBuilder { println!("'{}': {}", name, expr.degree()); } } + + pub(crate) fn get_query_offset(&self) -> i32 { + self.query_offset + } + + pub(crate) fn set_query_offset(&mut self, query_offset: i32) { + self.query_offset = query_offset; + } } pub(crate) fn merge_lookups( @@ -306,6 +775,16 @@ pub(crate) fn merge_values( crate::circuit!([meta, cb], { require!(selector => bool); }); + merge_values_unsafe(values) +} + +pub(crate) fn merge_values_unsafe( + values: Vec<(Expression, Vec>)>, +) -> (Expression, Vec>) { + if values.is_empty() { + return (0.expr(), Vec::new()); + } + let selector = sum::expr(values.iter().map(|(condition, _)| condition.expr())); // Merge let max_length = values.iter().map(|(_, values)| values.len()).max().unwrap(); let mut merged_values = vec![0.expr(); max_length]; @@ -419,6 +898,7 @@ impl_expressable!(usize); impl_expressable!(isize); impl_expressable!(Expression); impl_expressable!(DataTransition); +impl_expressable!(Cell); /// Trait around select pub trait Selectable { @@ -867,20 +1347,20 @@ macro_rules! circuit { #[allow(unused_macros)] macro_rules! f { ($column:expr, $rot:expr) => {{ - $meta.query_fixed($column.clone(), Rotation($rot as i32)) + $meta.query_fixed($column.clone(), Rotation($cb.get_query_offset() + ($rot as i32))) }}; ($column:expr) => {{ - $meta.query_fixed($column.clone(), Rotation::cur()) + $meta.query_fixed($column.clone(), Rotation($cb.get_query_offset())) }}; } #[allow(unused_macros)] macro_rules! a { ($column:expr, $rot:expr) => {{ - $meta.query_advice($column.clone(), Rotation($rot as i32)) + $meta.query_advice($column.clone(), Rotation($cb.get_query_offset() + ($rot as i32))) }}; ($column:expr) => {{ - $meta.query_advice($column.clone(), Rotation::cur()) + $meta.query_advice($column.clone(), Rotation($cb.get_query_offset())) }}; } diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index 51045235e0..7499d16cc9 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -44,9 +44,11 @@ use selectors::SelectorsConfig; use crate::{ circuit, - circuit_tools::merge_lookups, + circuit_tools::{merge_lookups, Memory, CellManager}, evm_circuit::util::rlc, - mpt_circuit::helpers::{extend_rand, BranchNodeInfo, MPTConstraintBuilder}, + mpt_circuit::{helpers::{ + extend_rand, parent_memory, BranchNodeInfo, KeyData, MPTConstraintBuilder, ParentData, + }, storage_leaf::leaf_combined::LeafCombinedConfig}, table::{DynamicTableColumns, KeccakTable}, util::{power_of_randomness_from_instance, Challenges}, }; @@ -84,7 +86,7 @@ use self::{ */ /// Merkle Patricia Trie config. -#[derive(Clone, Debug, Default)] +#[derive(Debug)] pub struct RowConfig { account_leaf_key_s: AccountLeafKeyConfig, account_leaf_key_c: AccountLeafKeyConfig, @@ -95,6 +97,7 @@ pub struct RowConfig { account_leaf_key_in_added_branch: AccountLeafKeyInAddedBranchConfig, account_non_existing: AccountNonExistingConfig, branch_config: BranchConfig, + branch_key_config: BranchKeyConfig, ext_node_config_s: ExtensionNodeConfig, ext_node_config_c: ExtensionNodeConfig, storage_leaf_key_s: LeafKeyConfig, @@ -122,7 +125,9 @@ pub struct MPTContext { pub(crate) storage_leaf: StorageLeafCols, pub(crate) denoter: DenoteCols, pub(crate) address_rlc: Column, + pub(crate) managed_columns: Vec>, pub(crate) r: Vec>, + pub(crate) memory: Memory, } impl MPTContext { @@ -184,6 +189,8 @@ pub struct MPTConfig { pub(crate) account_leaf: AccountLeafCols, pub(crate) storage_leaf: StorageLeafCols, pub(crate) denoter: DenoteCols, + pub(crate) managed_columns: Vec>, + pub(crate) memory: Memory, keccak_table: KeccakTable, fixed_table: [Column; 3], pub(crate) address_rlc: Column, /* The same in all rows of a modification. The same @@ -202,6 +209,7 @@ pub struct MPTConfig { account_leaf_key_in_added_branch: AccountLeafKeyInAddedBranchConfig, account_non_existing: AccountNonExistingConfig, branch_config: BranchConfig, + branch_key_config: BranchKeyConfig, ext_node_config_s: ExtensionNodeConfig, ext_node_config_c: ExtensionNodeConfig, storage_leaf_key_s: LeafKeyConfig, @@ -233,7 +241,6 @@ pub enum FixedTableTag { impl_expr!(FixedTableTag); -#[derive(Default)] /* Some values are accumulating through the rows (or block of rows) and we need to access the previous value to continue the calculation, for this reason the previous values are stored in `ProofValues` struct. @@ -241,6 +248,7 @@ Such accumulated value is for example `key_rlc` which stores the intermediate ke and extension node block a new intermediate key RLC is computed). Also, for example, `modified_node` is given in branch init but needed to be set in every branch children row. */ +#[derive(Default)] pub(crate) struct ProofValues { pub(crate) modified_node: u8, /* branch child that is being changed, it is the same in all * branch children rows */ @@ -270,6 +278,7 @@ pub(crate) struct ProofValues { * go one level back * to get previous key_rlc */ pub(crate) key_rlc_mult_prev: F, + pub(crate) nibbles_num_prev: usize, pub(crate) mult_diff: F, /* power of randomness r: multiplier_curr = multiplier_prev * * mult_diff */ pub(crate) key_rlc_sel: bool, /* If true, nibble is multiplied by 16, otherwise by 1. */ @@ -294,17 +303,36 @@ pub(crate) struct ProofValues { pub(crate) nonce_value_s: F, pub(crate) balance_value_s: F, pub(crate) storage_root_value_s: F, + pub(crate) storage_root_value_c: F, pub(crate) codehash_value_s: F, pub(crate) before_account_leaf: bool, pub(crate) nibbles_num: usize, pub(crate) account_key_rlc: F, pub(crate) storage_key_rlc: F, + + pub(crate) is_hashed_s: bool, + pub(crate) is_hashed_c: bool, + + pub(crate) ext_is_hashed_s: bool, + pub(crate) ext_is_hashed_c: bool, + + pub(crate) parent_rlc_s: F, + pub(crate) parent_is_hashed_s: bool, + + pub(crate) parent_rlc_c: F, + pub(crate) parent_is_hashed_c: bool, + + pub(crate) is_placeholder_leaf_s: bool, + pub(crate) is_placeholder_leaf_c: bool, + + pub(crate) memory: Memory, } impl ProofValues { - fn new() -> Self { + fn new(memory: &Memory) -> Self { Self { + memory: memory.clone(), key_rlc_mult: F::one(), key_rlc_mult_prev: F::one(), mult_diff: F::one(), @@ -353,6 +381,15 @@ impl MPTConfig { .try_into() .unwrap(); + let managed_columns = (0..32).map(|_| meta.advice_column()).collect::>(); + + let memory_columns = (0..4).map(|_| meta.advice_column()).collect::>(); + + let mut memory = Memory::new(memory_columns); + memory.allocate(meta, "key"); + memory.allocate(meta, parent_memory(false)); + memory.allocate(meta, parent_memory(true)); + /* Note: `key_rlc_mult` would not be needed if we would have big endian instead of little endian. However, then it would be much more @@ -400,10 +437,12 @@ impl MPTConfig { accumulators: accumulators.clone(), denoter: denoter.clone(), address_rlc: address_rlc.clone(), + managed_columns: managed_columns.clone(), r: extend_rand(&power_of_randomness), + memory: memory.clone(), }; - let mut row_config: RowConfig = RowConfig::default(); + let mut row_config: Option> = None; let mut cb = MPTConstraintBuilder::new(17); meta.create_gate("MPT", |meta| { @@ -412,6 +451,21 @@ impl MPTConfig { SelectorsConfig::configure(meta, &mut cb, ctx.clone()); ProofChainConfig::configure(meta, &mut cb, ctx.clone()); + /* Initial values */ + // Initial key values + ifx!{not!(f!(position_cols.q_enable)) => { + //KeyData::store(&mut cb.base, &ctx.key_memory, KeyData::default_values()); + KeyData::store_initial_values(&mut cb.base, &ctx.memory["key"]); + }} + // Initial parent values + ifx!{f!(position_cols.q_enable), not!(a!(ctx.position_cols.not_first_level)), + a!(branch.is_init) + a!(storage_leaf.is_s_key) + a!(account_leaf.is_key_s) => { + for is_s in [true, false] { + let root = a!(ctx.inter_root(is_s)); + ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [root, true.expr()]); + } + }} + // TODO(Brecht): Make an actual state machine (currently close, but not yet) /* Branch node */ let branch_config = BranchConfig::configure(meta, &mut cb, ctx.clone()); @@ -439,31 +493,30 @@ impl MPTConfig { ext_node_config_c = ExtensionNodeConfig::configure(meta, &mut cb, ctx.clone(), false); }} // BRANCH.IS_EXTENSION_NODE_S + BRANCH.IS_EXTENSION_NODE_C - BranchKeyConfig::configure(meta, &mut cb, ctx.clone()); + let branch_key_config = BranchKeyConfig::configure(meta, &mut cb, ctx.clone()); /* Storage Leaf */ + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); // LEAF_KEY_S // LEAF_KEY_C + // LEAF_VALUE_S + // LEAF_VALUE_C let storage_leaf_key_s; let storage_leaf_key_c; + let storage_leaf_value_s; + let storage_leaf_value_c; ifx!{f!(position_cols.q_not_first), a!(position_cols.not_first_level) => { ifx!{a!(storage_leaf.is_s_key) => { - storage_leaf_key_s = LeafKeyConfig::configure(meta, &mut cb, ctx.clone(), true); + storage_leaf_key_s = LeafKeyConfig::configure(meta, &mut cb, &mut cm, ctx.clone(), true); }} - ifx!{a!(storage_leaf.is_c_key) => { - storage_leaf_key_c = LeafKeyConfig::configure(meta, &mut cb, ctx.clone(), false); - }} - }} - // LEAF_VALUE_S - // LEAF_VALUE_C - let storage_leaf_value_s; - let storage_leaf_value_c; - ifx!{f!(position_cols.q_not_first) => { ifx!{a!(ctx.storage_leaf.is_s_value) => { - storage_leaf_value_s = LeafValueConfig::configure(meta, &mut cb, ctx.clone(), true); + storage_leaf_value_s = LeafValueConfig::configure(meta, &mut cb, &mut cm, ctx.clone(), true); + }} + ifx!{a!(storage_leaf.is_c_key) => { + storage_leaf_key_c = LeafKeyConfig::configure(meta, &mut cb, &mut cm, ctx.clone(), false); }} ifx!{a!(ctx.storage_leaf.is_c_value) => { - storage_leaf_value_c = LeafValueConfig::configure(meta, &mut cb, ctx.clone(), false); + storage_leaf_value_c = LeafValueConfig::configure(meta, &mut cb, &mut cm, ctx.clone(), false); }} }} // LEAF_DRIFTED @@ -474,7 +527,7 @@ impl MPTConfig { // LEAF_NON_EXISTING let storage_non_existing; ifx!{f!(position_cols.q_enable), a!(storage_leaf.is_non_existing) => { - storage_non_existing = StorageNonExistingConfig::::configure(meta, &mut cb, ctx.clone()); + storage_non_existing = StorageNonExistingConfig::::configure(meta, &mut cb, &mut cm, ctx.clone()); }} /* Account Leaf */ @@ -517,6 +570,16 @@ impl MPTConfig { account_leaf_key_in_added_branch = AccountLeafKeyInAddedBranchConfig::configure(meta, &mut cb, ctx.clone()); }} + ifx!{f!(position_cols.q_not_first), a!(position_cols.not_first_level) => { + matchx! { + a!(storage_leaf.is_s_key) => { + LeafCombinedConfig::configure(meta, &mut cb, ctx.clone()); + () + }, + _ => (), + } + }} + /* Range checks */ // These range checks ensure that the value in the RLP columns are all byte value. // These lookups also enforce the value to be zero if the passed in length is < 0. @@ -557,7 +620,7 @@ impl MPTConfig { // TODO(Brecht): manually optimized lookups for now, but the constraint builder can // automatically do this. Shouldn't be too hard hopefully. for tag in ["mult", "mult2"] { - let lookups = cb.base.get_lookups(&[tag]); + let lookups = cb.base.consume_lookups(&[tag]); let optimize = true; if optimize { let (_, values) = merge_lookups(&mut cb.base, lookups); @@ -575,7 +638,12 @@ impl MPTConfig { require!(@"keccak" => keccak_table.columns().iter().map(|table| a!(table)).collect()); require!(@"fixed" => fixed_table.iter().map(|table| f!(table)).collect()); - row_config = RowConfig { + /* Memory banks */ + ifx!{f!(position_cols.q_enable) => { + ctx.memory.generate_constraints(&mut cb.base); + }} + + row_config = Some(RowConfig { account_leaf_key_s, account_leaf_key_c, account_leaf_nonce_balance_s, @@ -585,6 +653,7 @@ impl MPTConfig { account_leaf_key_in_added_branch, account_non_existing, branch_config, + branch_key_config, ext_node_config_s, ext_node_config_c, storage_leaf_key_s, @@ -593,7 +662,7 @@ impl MPTConfig { storage_leaf_value_c, storage_leaf_key_in_added_branch, storage_non_existing, - }; + }); }); cb.base.generate_constraints() @@ -604,9 +673,21 @@ impl MPTConfig { .parse() .expect("Cannot parse DISABLE_LOOKUPS env var as usize"); if disable_lookups == 0 { - cb.base.generate_lookups(meta, &["fixed", "keccak"]); + cb.base.generate_lookups( + meta, + &[ + vec!["fixed".to_string(), "keccak".to_string()], + ctx.memory.tags(), + ] + .concat(), + ); } else if disable_lookups == 1 { - cb.base.generate_lookups(meta, &["keccak"]); + cb.base.generate_lookups( + meta, + &[vec!["keccak".to_string()], ctx.memory.tags()].concat(), + ); + } else if disable_lookups == 2 { + cb.base.generate_lookups(meta, &ctx.memory.tags()); } println!("num lookups: {}", meta.lookups().len()); @@ -623,6 +704,7 @@ impl MPTConfig { root: inter_final_root, }; + let row_config = row_config.unwrap(); let randomness = F::zero(); MPTConfig { proof_type, @@ -638,6 +720,8 @@ impl MPTConfig { storage_leaf, accumulators, denoter, + managed_columns, + memory, keccak_table, fixed_table, address_rlc, @@ -650,6 +734,7 @@ impl MPTConfig { account_leaf_key_in_added_branch: row_config.account_leaf_key_in_added_branch, account_non_existing: row_config.account_non_existing, branch_config: row_config.branch_config, + branch_key_config: row_config.branch_key_config, ext_node_config_s: row_config.ext_node_config_s, ext_node_config_c: row_config.ext_node_config_c, storage_leaf_key_s: row_config.storage_leaf_key_s, @@ -844,28 +929,66 @@ impl MPTConfig { randomness: F, ) { self.randomness = randomness; + let mut height = 0; + + let mut memory = self.memory.clone(); layouter .assign_region( || "MPT", |mut region| { let mut offset = 0; - let mut pv = ProofValues::new(); + let mut pv = ProofValues::new(&self.memory); + + memory.clear_witness_data(); + + pv.memory["key"].witness_store_init(&[ + F::zero(), + F::one(), + F::zero(), + F::zero(), + F::zero(), + F::zero(), + ]); for (ind, row) in witness .iter() .filter(|r| r.get_type() != MptWitnessRowType::HashToBeComputed) .enumerate() { + let mut new_proof = offset == 0; if offset > 0 { let row_prev = &witness[offset - 1]; let not_first_level_prev = row_prev.not_first_level(); let not_first_level_cur = row.not_first_level(); if not_first_level_cur == 0 && not_first_level_prev == 1 { - pv = ProofValues::new(); + pv = ProofValues::new(&pv.memory); + new_proof = true; } } + if new_proof { + pv.memory[parent_memory(true)].witness_store( + offset, + &[row.s_root_bytes_rlc(self.randomness), F::from(true)], + ); + pv.memory[parent_memory(false)].witness_store( + offset, + &[row.c_root_bytes_rlc(self.randomness), F::from(true)], + ); + + //pv.parent_rlc_s = + // row.s_root_bytes_rlc(self.randomness); + // pv.parent_is_hashed_s = true; + //pv.memory[parent_memory(false)]. + // store_used_at(offset); + // pv.parent_rlc_c = + // row.c_root_bytes_rlc(self.randomness); + // pv.parent_is_hashed_c = true; + + //println!("{} -> {:?}", offset, row.get_type()); + } + //println!("{} -> {:?}", offset, row.get_type()); region.assign_fixed( @@ -874,6 +997,7 @@ impl MPTConfig { offset, || Value::known(F::one()), )?; + height += 1; if row.get_type() == MptWitnessRowType::AccountLeafKeyS { // account leaf key @@ -888,7 +1012,7 @@ impl MPTConfig { || Value::known(q_not_first), )?; - let q_not_first_ext_s = if offset < (BRANCH_ROWS_NUM as usize) - 1 { + let q_not_first_ext_s = if offset < (BRANCH_ROWS_NUM as usize) - 2 { F::zero() } else { F::one() @@ -900,7 +1024,7 @@ impl MPTConfig { || Value::known(q_not_first_ext_s), )?; - let q_not_first_ext_c = if offset < (BRANCH_ROWS_NUM as usize) - 0 { + let q_not_first_ext_c = if offset < (BRANCH_ROWS_NUM as usize) - 1 { F::zero() } else { F::one() @@ -967,6 +1091,7 @@ impl MPTConfig { pv.key_rlc_mult = F::one(); pv.key_rlc_prev = F::zero(); pv.key_rlc_mult_prev = F::one(); + pv.nibbles_num_prev = 0; pv.key_rlc_sel = true; pv.nibbles_num = 0; /* @@ -1020,7 +1145,7 @@ impl MPTConfig { &mut pv, row, offset, - ); + )?; } else if row.get_type() == MptWitnessRowType::StorageLeafCKey { self.storage_leaf_key_c.assign( &mut region, @@ -1028,7 +1153,7 @@ impl MPTConfig { &mut pv, row, offset, - ); + )?; } else if row.get_type() == MptWitnessRowType::StorageLeafSValue { self.storage_leaf_value_s.assign( &mut region, @@ -1062,7 +1187,7 @@ impl MPTConfig { &mut pv, row, offset, - ); + )?; } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { self.account_leaf_key_c.assign( &mut region, @@ -1070,7 +1195,7 @@ impl MPTConfig { &mut pv, row, offset, - ); + )?; } else if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { self.account_leaf_nonce_balance_s.assign( @@ -1127,6 +1252,9 @@ impl MPTConfig { true, ); } else if row.get_type() == MptWitnessRowType::ExtensionNodeC { + self.branch_key_config + .assign(&mut region, witness, self, &mut pv, offset) + .ok(); self.ext_node_config_c.assign( &mut region, self, @@ -1162,10 +1290,14 @@ impl MPTConfig { } } + memory = pv.memory; + Ok(()) }, ) .ok(); + + memory.assign(&mut layouter, height).ok(); } fn load_fixed_table( diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs index 089f486082..30e58e9dcd 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs @@ -1,19 +1,19 @@ use halo2_proofs::{ arithmetic::FieldExt, circuit::{Region, Value}, - plonk::VirtualCells, + plonk::{Error, VirtualCells}, poly::Rotation, }; -use std::marker::PhantomData; use crate::{ circuit, + circuit_tools::CellManager, mpt_circuit::{ helpers::BranchNodeInfo, param::{BRANCH_ROWS_NUM, S_START}, }, mpt_circuit::{ - helpers::{get_num_nibbles, AccountLeafInfo, MPTConstraintBuilder}, + helpers::{get_num_nibbles, AccountLeafInfo, KeyData, MPTConstraintBuilder}, param::{KEY_LEN_IN_NIBBLES, RLP_LIST_LONG}, FixedTableTag, }, @@ -113,9 +113,9 @@ an even number of nibbles, it turns around. */ -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(crate) struct AccountLeafKeyConfig { - _marker: PhantomData, + key_data: KeyData, } impl AccountLeafKeyConfig { @@ -133,9 +133,12 @@ impl AccountLeafKeyConfig { // key rlc is in the first branch node let rot_first_child = -BRANCH_ROWS_NUM + if is_s { 1 } else { 0 }; - let rot_first_child_prev = rot_first_child - BRANCH_ROWS_NUM; + //let rot_first_child_prev = rot_first_child - BRANCH_ROWS_NUM; let rot_branch_init = rot_first_child - 1; - let rot_branch_init_prev = rot_branch_init - BRANCH_ROWS_NUM; + //let rot_branch_init_prev = rot_branch_init - BRANCH_ROWS_NUM; + + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let ctx_key_data: Option>; circuit!([meta, cb.base], { let account = AccountLeafInfo::new(meta, ctx.clone(), 0); @@ -149,39 +152,31 @@ impl AccountLeafKeyConfig { // Calculate and store the leaf data RLC require!(a!(accs.acc_s.rlc) => ctx.rlc(meta, 0..36, 0)); - // Get the previous key data, which depends on the branch being a placeholder. + // Load the last key values, which depends on the branch being a placeholder. let is_branch_placeholder = ifx! {a!(not_first_level) => { branch.is_placeholder() }}; - let (key_rlc_prev, key_mult_prev, nibbles_count_prev, is_key_odd) = ifx! {is_branch_placeholder => { - let is_branch_in_first_level = not!(a!(not_first_level, rot_branch_init)); - ifx!{not!(is_branch_in_first_level) => { - let branch_prev = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init_prev); - (a!(accs.key.rlc, rot_first_child_prev), a!(accs.key.mult, rot_first_child_prev), branch_prev.nibbles_counter().expr(), branch_prev.is_key_odd()) - } elsex { - (0.expr(), 1.expr(), 0.expr(), false.expr()) - }} - } elsex { - ifx! {a!(not_first_level) => { - (a!(accs.key.rlc, rot_first_child), a!(accs.key.mult, rot_first_child), branch.nibbles_counter().expr(), branch.is_key_odd()) - } elsex { - (0.expr(), 1.expr(), 0.expr(), false.expr()) - }} - }}; + let offset = if is_s { 0.expr() } else { 1.expr() }; + let offset = offset + ifx! {is_branch_placeholder => { 1.expr() }}; + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], offset); // Calculate the key RLC - let key_rlc = key_rlc_prev + let key_rlc = key_data.rlc.expr() + account.key_rlc( meta, &mut cb.base, - key_mult_prev.expr(), - is_key_odd.expr(), + key_data.mult.expr(), + key_data.is_odd.expr(), 1.expr(), + 0, ); require!(a!(accs.key.rlc) => key_rlc); // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES. let key_len = account.key_len(meta); - let num_nibbles = get_num_nibbles(meta, key_len.expr(), is_key_odd.expr()); - require!(nibbles_count_prev + num_nibbles => KEY_LEN_IN_NIBBLES); + let num_nibbles = get_num_nibbles(meta, key_len.expr(), key_data.is_odd.expr()); + require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); + + // Key done, set the starting values + KeyData::store(&mut cb.base, &ctx.memory["key"], KeyData::default_values()); // Num bytes used in RLC let num_bytes = account.num_bytes_on_key_row(meta); @@ -220,10 +215,12 @@ impl AccountLeafKeyConfig { require!(or::expr([branch.contains_placeholder_leaf(meta, is_s), branch.is_placeholder()]) => true); }} } + + ctx_key_data = Some(key_data); }); AccountLeafKeyConfig { - _marker: PhantomData, + key_data: ctx_key_data.unwrap(), } } @@ -234,7 +231,7 @@ impl AccountLeafKeyConfig { pv: &mut ProofValues, row: &MptWitnessRow, offset: usize, - ) { + ) -> Result<(), Error> { // account leaf key S & C let mut acc = F::zero(); let mut acc_mult = F::one(); @@ -250,22 +247,41 @@ impl AccountLeafKeyConfig { pv.acc_mult_account_s = acc_mult; if row.get_byte_rev(IS_ACCOUNT_DELETE_MOD_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(5_u64)), /* account delete mod lookup enabled in - * this row if it is is_account_delete - * proof */ - ) - .ok(); + region.assign_advice( + || "assign lookup enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(5_u64)), /* account delete mod lookup enabled in + * this row if it is is_account_delete + * proof */ + )?; } } else { pv.acc_account_c = acc; pv.acc_mult_account_c = acc_mult; } + let is_s = row.get_type() == MptWitnessRowType::AccountLeafKeyS; + let is_branch_placeholder = if is_s { + pv.is_branch_s_placeholder + } else { + pv.is_branch_c_placeholder + }; + let load_offset = if is_s { 0 } else { 1 }; + let load_offset = load_offset + if is_branch_placeholder { 1 } else { 0 }; + self.key_data + .witness_load(region, offset, &mut pv.memory["key"], load_offset)?; + self.key_data.witness_store( + region, + offset, + &mut pv.memory["key"], + F::zero(), + F::one(), + 0, + false, + false, + )?; + // For leaf S and leaf C we need to start with the same rlc. let mut key_rlc_new = pv.key_rlc; let mut key_rlc_mult_new = pv.key_rlc_mult; @@ -278,17 +294,13 @@ impl AccountLeafKeyConfig { mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, S_START); pv.account_key_rlc = key_rlc_new; - region - .assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(key_rlc_new), - ) - .ok(); - - mpt_config - .assign_acc(region, acc, acc_mult, F::zero(), F::zero(), offset) - .ok(); + region.assign_advice( + || "assign key_rlc".to_string(), + mpt_config.accumulators.key.rlc, + offset, + || Value::known(key_rlc_new), + )?; + + mpt_config.assign_acc(region, acc, acc_mult, F::zero(), F::zero(), offset) } } diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs index f5edcac258..d6c25c624f 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs @@ -1,8 +1,8 @@ use halo2_proofs::{arithmetic::FieldExt, circuit::Region, plonk::VirtualCells, poly::Rotation}; -use std::marker::PhantomData; use crate::{ circuit, + circuit_tools::{CellManager, ConstraintBuilder}, mpt_circuit::{ helpers::BranchNodeInfo, param::{ @@ -13,7 +13,7 @@ use crate::{ }, }, mpt_circuit::{ - helpers::{get_parent_rlc_state, AccountLeafInfo, MPTConstraintBuilder}, + helpers::{get_parent_rlc_state, AccountLeafInfo, KeyData, MPTConstraintBuilder}, FixedTableTag, }, mpt_circuit::{MPTConfig, MPTContext, ProofValues}, @@ -82,9 +82,9 @@ is an extension node, we have the intermediate RLC stored in the extension node If it is a regular branch, we need to go one branch above to retrieve the RLC (if there is no level above, we take 0). */ -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(crate) struct AccountLeafKeyInAddedBranchConfig { - _marker: PhantomData, + key_data: KeyData, } impl AccountLeafKeyInAddedBranchConfig { @@ -98,6 +98,9 @@ impl AccountLeafKeyInAddedBranchConfig { let accs = ctx.accumulators; let r = ctx.r.clone(); + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let ctx_key_data: Option>; + let rot_parent = -ACCOUNT_DRIFTED_LEAF_IND - 1; let rot_branch_init = rot_parent + 1 - BRANCH_ROWS_NUM; let rot_first_child = rot_branch_init + 1; @@ -127,10 +130,20 @@ impl AccountLeafKeyInAddedBranchConfig { // position in a branch or/and nibbles of the extension node. let is_branch_in_first_level = not!(a!(not_first_level, rot_branch_init)); let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); + + // Load the last key values + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], 3.expr()); + + // TODO(Brecht): make this work with loaded key data when extension node is separate + ifx! {not!(branch.is_extension()) => { + require!(key_data.rlc => key_rlc_prev); + require!(key_data.mult => key_mult_prev); + }} + // Calculate the drifted key RLC let drifted_key_rlc = key_rlc_prev + branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + - drifted_account.key_rlc(meta, &mut cb.base, key_mult_prev.expr(), branch.is_key_odd(), r[0].expr()); + drifted_account.key_rlc(meta, &mut cb.base, key_mult_prev.expr(), branch.is_key_odd(), r[0].expr(), 0); // RLC bytes zero check let num_bytes = drifted_account.num_bytes_on_key_row(meta); @@ -140,30 +153,32 @@ impl AccountLeafKeyInAddedBranchConfig { require!((FixedTableTag::RMult, num_bytes.expr(), mult) => @"mult"); // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let mut calc_rlc = |is_s| { - let rot_key = if is_s { rot_key_s } else { rot_key_c }; - let rot_nonce = if is_s { rot_nonce_s } else { rot_nonce_c }; - let rot_storage = if is_s { rot_storage_s } else { rot_storage_c }; - - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - - // Calculate the drifted leaf rlc - // Nonce data rlc - let nonce_stored = a!(accs.s_mod_node_rlc, rot_nonce); - let nonce_rlc = account.to_data_rlc(meta, ctx.s_main, nonce_stored, account.is_nonce_long(), rot_nonce); - // Balance data rlc - let balance_stored = a!(accs.c_mod_node_rlc, rot_nonce); - let balance_rlc = account.to_data_rlc(meta, ctx.c_main, balance_stored, account.is_balance_long(), rot_nonce); - let mult_nonce = a!(accs.acc_c.rlc, rot_nonce); - let mult_balance = a!(accs.key.mult, rot_nonce); - let rlc = drifted_rlc.expr() + account.nonce_balance_rlc(meta, nonce_rlc.expr(), balance_rlc.expr(), mult.expr(), mult_nonce.expr(), rot_nonce); - // Add storage/codehash rlc - let storage_rlc = a!(accs.s_mod_node_rlc, rot_storage); - let codehash_rlc = a!(accs.c_mod_node_rlc, rot_storage); - let mult_prev = mult.expr() * mult_nonce.expr() * mult_balance.expr(); - let rlc = rlc + account.storage_codehash_rlc(meta, storage_rlc.expr(), codehash_rlc.expr(), mult_prev.expr(), rot_storage); - - (true.expr(), a!(accs.key.rlc, rot_key), rlc, a!(accs.mod_node_rlc(is_s), rot_first_child)) + let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { + circuit!([meta, cb], { + let rot_key = if is_s { rot_key_s } else { rot_key_c }; + let rot_nonce = if is_s { rot_nonce_s } else { rot_nonce_c }; + let rot_storage = if is_s { rot_storage_s } else { rot_storage_c }; + + let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); + + // Calculate the drifted leaf rlc + // Nonce data rlc + let nonce_stored = a!(accs.s_mod_node_rlc, rot_nonce); + let nonce_rlc = account.to_data_rlc(meta, ctx.s_main, nonce_stored, account.is_nonce_long(), rot_nonce); + // Balance data rlc + let balance_stored = a!(accs.c_mod_node_rlc, rot_nonce); + let balance_rlc = account.to_data_rlc(meta, ctx.c_main, balance_stored, account.is_balance_long(), rot_nonce); + let mult_nonce = a!(accs.acc_c.rlc, rot_nonce); + let mult_balance = a!(accs.key.mult, rot_nonce); + let rlc = drifted_rlc.expr() + account.nonce_balance_rlc(meta, nonce_rlc.expr(), balance_rlc.expr(), mult.expr(), mult_nonce.expr(), rot_nonce); + // Add storage/codehash rlc + let storage_rlc = a!(accs.s_mod_node_rlc, rot_storage); + let codehash_rlc = a!(accs.c_mod_node_rlc, rot_storage); + let mult_prev = mult.expr() * mult_nonce.expr() * mult_balance.expr(); + let rlc = rlc + account.storage_codehash_rlc(meta, storage_rlc.expr(), codehash_rlc.expr(), mult_prev.expr(), rot_storage); + + (true.expr(), a!(accs.key.rlc, rot_key), rlc, a!(accs.mod_node_rlc(is_s), rot_first_child)) + }) }; let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { branch.is_placeholder_s() => { @@ -173,7 +188,7 @@ impl AccountLeafKeyInAddedBranchConfig { // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. // This is because `c_mod_node_rlc` in the added branch stores the hash of // `modified_index` (the leaf that has been added). - calc_rlc(true) + calc_rlc(true, meta, &mut cb.base) }, branch.is_placeholder_c() => { // Neighbour leaf in the deleted branch @@ -182,7 +197,7 @@ impl AccountLeafKeyInAddedBranchConfig { // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. // This is because `s_mod_node_rlc` in the deleted branch stores the hash of // `modified_index` (the leaf that is to be deleted). - calc_rlc(false) + calc_rlc(false, meta, &mut cb.base) }, _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), }; @@ -192,11 +207,13 @@ impl AccountLeafKeyInAddedBranchConfig { // The drifted leaf needs to be stored in the branch at `drifted_index`. require!((1, drifted_rlc, drifted_account.num_bytes(meta), mod_hash) => @"keccak"); }} + + ctx_key_data = Some(key_data); }} }); AccountLeafKeyInAddedBranchConfig { - _marker: PhantomData, + key_data: ctx_key_data.unwrap(), } } @@ -213,6 +230,10 @@ impl AccountLeafKeyInAddedBranchConfig { let len = (row[2] - 128) as usize + 3; mpt_config.compute_acc_and_mult(row, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); + self.key_data + .witness_load(region, offset, &mut pv.memory["key"], 3) + .ok(); + mpt_config .assign_acc( region, diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_storage_codehash.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_storage_codehash.rs index b4d353d5c6..b71dee7d4e 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_storage_codehash.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_storage_codehash.rs @@ -4,13 +4,15 @@ use halo2_proofs::{ plonk::VirtualCells, poly::Rotation, }; -use std::marker::PhantomData; use crate::{ circuit, - circuit_tools::{DataTransition, RLCable}, + circuit_tools::{CellManager, DataTransition, RLCable}, + mpt_circuit::witness_row::{MptWitnessRow, MptWitnessRowType}, mpt_circuit::{ - helpers::{AccountLeafInfo, BranchNodeInfo, MPTConstraintBuilder}, + helpers::{ + parent_memory, AccountLeafInfo, BranchNodeInfo, MPTConstraintBuilder, ParentData, + }, param::{ ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, BRANCH_ROWS_NUM, C_START, HASH_WIDTH, @@ -18,10 +20,6 @@ use crate::{ }, MPTContext, }, - mpt_circuit::{ - param::ARITY, - witness_row::{MptWitnessRow, MptWitnessRowType}, - }, mpt_circuit::{MPTConfig, ProofValues}, }; @@ -67,9 +65,9 @@ Lookups: The `is_codehash_mod` lookup is enabled in `ACCOUNT_LEAF_STORAGE_CODEHASH_C` row. */ -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(crate) struct AccountLeafStorageCodehashConfig { - _marker: PhantomData, + parent_data: ParentData, } impl AccountLeafStorageCodehashConfig { @@ -80,7 +78,6 @@ impl AccountLeafStorageCodehashConfig { is_s: bool, ) -> Self { let proof_type = ctx.proof_type; - let inter_root = ctx.inter_root(is_s); let position_cols = ctx.position_cols; let s_main = ctx.s_main; let c_main = ctx.c_main; @@ -89,6 +86,9 @@ impl AccountLeafStorageCodehashConfig { let value_prev = ctx.value_prev; let value = ctx.value; + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let ctx_parent_data: Option>; + let rot_nonce_balance = -2; let rot_key = -if is_s { ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND - ACCOUNT_LEAF_KEY_S_IND @@ -100,8 +100,6 @@ impl AccountLeafStorageCodehashConfig { } else { -ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND } - BRANCH_ROWS_NUM; - let rot_last_child = rot_branch_init + (ARITY as i32); - let rot_last_child_prev = rot_last_child - BRANCH_ROWS_NUM; let rot_s = if is_s { 0 } else { @@ -142,33 +140,16 @@ impl AccountLeafStorageCodehashConfig { require!(account_rlc => rlc); // Check if the account is in its parent. - let (do_lookup, hash_rlc) = ifx!{a!(position_cols.not_first_level) => { - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - ifx!{branch.is_placeholder() => { - ifx!{a!(position_cols.not_first_level, rot_last_child) => { - // Hash of an account leaf when branch placeholder - // Check if we're in the branch above the placeholder branch. - (true.expr(), a!(accs.mod_node_rlc(is_s), rot_last_child_prev)) - } elsex { - // Hash of an account leaf compared to root when branch placeholder in the first level - (true.expr(), a!(inter_root)) - }} - } elsex { - // Hash of an account leaf in a branch - // Check is skipped for placeholder leafs which are dummy leafs - ifx!{not!(branch.contains_placeholder_leaf(meta, is_s)) => { - (true.expr(), a!(accs.mod_node_rlc(is_s), rot_last_child)) - }} - }} - } elsex { - // Account first level leaf without branch - compared to state root - (true.expr(), a!(inter_root)) - }}; - // Do the lookup - ifx!{do_lookup => { + let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + let parent_data = ParentData::load("storage load", &mut cb.base, &mut cm, &ctx.memory[parent_memory(is_s)], 0.expr()); + // Check is skipped for placeholder leafs which are dummy leafs + ifx!{not!(and::expr(&[a!(position_cols.not_first_level), not!(branch.is_placeholder()), branch.contains_placeholder_leaf(meta, is_s)])) => { let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - require!((1, account_rlc, account.num_bytes(meta), hash_rlc) => @"keccak"); + require!((1, account_rlc, account.num_bytes(meta), parent_data.rlc) => @"keccak"); }} + // Store the new parent + ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [storage_root.expr(), true.expr()]); + ctx_parent_data = Some(parent_data); if !is_s { // To enable lookups we need to have the previous/current storage root/code hash on the same row. @@ -193,7 +174,7 @@ impl AccountLeafStorageCodehashConfig { }); AccountLeafStorageCodehashConfig { - _marker: PhantomData, + parent_data: ctx_parent_data.unwrap(), } } @@ -245,6 +226,8 @@ impl AccountLeafStorageCodehashConfig { let storage_root_value_c = pv.rlc1; let codehash_value_c = pv.rlc2; + pv.storage_root_value_c = storage_root_value_c; + if row.get_byte_rev(IS_CODEHASH_MOD_POS) == 1 { region .assign_advice( @@ -300,6 +283,26 @@ impl AccountLeafStorageCodehashConfig { ) .ok(); } + + let is_s = row.get_type() == MptWitnessRowType::AccountLeafRootCodehashS; + let storage_root = if is_s { + pv.storage_root_value_s + } else { + pv.storage_root_value_c + }; + self.parent_data + .witness_load(region, offset, &mut pv.memory[parent_memory(is_s)], 0) + .ok(); + self.parent_data + .witness_store( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + storage_root, + true, + ) + .ok(); + // storage mpt_config.compute_acc_and_mult( &row.bytes, diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs index 865707d0c1..39e893e6ad 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs @@ -4,14 +4,14 @@ use halo2_proofs::{ plonk::VirtualCells, poly::Rotation, }; -use std::marker::PhantomData; use crate::{ circuit, + circuit_tools::CellManager, mpt_circuit::witness_row::MptWitnessRow, mpt_circuit::{ - helpers::{bytes_into_rlc, BranchNodeInfo}, - param::{ACCOUNT_NON_EXISTING_IND, BRANCH_ROWS_NUM}, + helpers::{bytes_into_rlc, KeyData}, + param::{ACCOUNT_NON_EXISTING_IND}, ProofValues, }, mpt_circuit::{ @@ -103,9 +103,9 @@ it automatically means the account leaf is not in the first level. */ -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(crate) struct AccountNonExistingConfig { - _marker: PhantomData, + key_data: KeyData, } impl AccountNonExistingConfig { @@ -115,13 +115,13 @@ impl AccountNonExistingConfig { ctx: MPTContext, ) -> Self { let proof_type = ctx.proof_type; - let not_first_level = ctx.position_cols.not_first_level; let accs = ctx.accumulators; let address_rlc = ctx.address_rlc; + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let ctx_key_data: Option>; + let rot_key_s = -ACCOUNT_NON_EXISTING_IND; - let rot_first_branch = -(ACCOUNT_NON_EXISTING_IND - 1 + BRANCH_ROWS_NUM); - let rot_branch_init = rot_first_branch - 1; circuit!([meta, cb.base], { let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key_s); @@ -130,17 +130,10 @@ impl AccountNonExistingConfig { require!(account.is_wrong_leaf(meta, true) => bool); ifx! {a!(proof_type.is_non_existing_account_proof) => { + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], 2.expr()); ifx! {account.is_wrong_leaf(meta, true) => { - // Note: currently, for non_existing_account proof S and C - // proofs are the same, thus there is never a placeholder branch. - let (key_rlc_prev, key_mult_prev, is_key_odd) = ifx! {a!(not_first_level) => { - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - (a!(accs.key.rlc, rot_first_branch), a!(accs.key.mult, rot_first_branch), branch.is_key_odd()) - } elsex { - (0.expr(), 1.expr(), false.expr()) - }}; // Calculate the key and check it's the address as requested in the lookup - let key_rlc_wrong = key_rlc_prev + account.key_rlc(meta, &mut cb.base, key_mult_prev, is_key_odd, 1.expr()); + let key_rlc_wrong = key_data.rlc.expr() + account.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), -rot_key_s); require!(a!(address_rlc) => key_rlc_wrong); // Now make sure this address is different than the one of the leaf let diff_inv = a!(accs.acc_s.rlc); @@ -154,9 +147,9 @@ impl AccountNonExistingConfig { cb.set_length(num_bytes); } elsex { // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - require!(branch.contains_placeholder_leaf(meta, true) => true); + require!(key_data.is_placeholder_leaf_s => true); }} + ctx_key_data = Some(key_data); } elsex { // is_wrong_leaf needs to be false when not in non_existing_account proof require!(account.is_wrong_leaf(meta, true) => false); @@ -164,7 +157,7 @@ impl AccountNonExistingConfig { }); AccountNonExistingConfig { - _marker: PhantomData, + key_data: ctx_key_data.unwrap(), } } @@ -176,6 +169,10 @@ impl AccountNonExistingConfig { witness: &[MptWitnessRow], offset: usize, ) { + self.key_data + .witness_load(region, offset, &mut pv.memory["key"], 2) + .ok(); + let row = &witness[offset]; let address_rlc = bytes_into_rlc(row.address_bytes(), mpt_config.randomness); let diff_inv = (address_rlc - pv.account_key_rlc) diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index 220f4e3cd5..e4c0d34d46 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -11,13 +11,24 @@ use halo2_proofs::{ }; use std::marker::PhantomData; -use super::{helpers::MPTConstraintBuilder, param::ARITY, MPTContext}; +use super::{ + helpers::MPTConstraintBuilder, + param::{ + ARITY, IS_C_BRANCH_NON_HASHED_POS, IS_C_EXT_NODE_NON_HASHED_POS, + IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_NODE_NON_HASHED_POS, + }, + MPTContext, +}; use crate::{ circuit, - circuit_tools::{DataTransition, RLCable}, + circuit_tools::{CellManager, DataTransition, RLCChainable, RLCable}, mpt_circuit::account_leaf::AccountLeaf, mpt_circuit::helpers::bytes_into_rlc, - mpt_circuit::{helpers::contains_placeholder_leaf, storage_leaf::StorageLeaf}, + mpt_circuit::{ + helpers::{contains_placeholder_leaf, parent_memory, ParentData}, + param::RLP_NIL, + storage_leaf::StorageLeaf, + }, mpt_circuit::{ helpers::{BranchChildInfo, BranchNodeInfo}, param::{ @@ -118,9 +129,10 @@ impl BranchCols { } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(crate) struct BranchConfig { - _marker: PhantomData, + parent_data_s: ParentData, + parent_data_c: ParentData, } impl BranchConfig { @@ -136,6 +148,10 @@ impl BranchConfig { let branch = ctx.branch; let r = ctx.r.clone(); + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let mut ctx_parent_data_s: Option> = None; + let mut ctx_parent_data_c: Option> = None; + circuit!([meta, cb.base], { let q_not_first = f!(position_cols.q_not_first); let drifted_index = DataTransition::new(meta, branch.drifted_index); @@ -266,11 +282,37 @@ impl BranchConfig { require!(sum::expr(&is_drifted_values) => 1); }} - // Check if the branch is in its parent. - // Extension node is handled in `extension_node.rs`. - ifx! {not!(branch.is_extension()) => { - branch.require_in_parent(meta, &mut cb.base); - }} + for is_s in [true, false] { + branch.set_is_s(is_s); + + // Check if the branch is in its parent. + let (rlc, num_bytes, is_not_hashed) = ifx! {branch.is_extension() => { + // Note: acc_c in both cases. + let ext_rlc = a!(branch.ctx.accumulators.acc_c.rlc, if is_s {1} else {2}); + (ext_rlc, branch.ext_num_bytes2(meta), branch.ext_is_not_hashed()) + } elsex { + let acc = branch.ctx.accumulators.acc(is_s); + // TODO: acc currently doesn't have branch ValueNode info + let branch_rlc = (a!(acc.rlc), a!(acc.mult)).rlc_chain(RLP_NIL.expr()); + (branch_rlc, branch.num_bytes(meta), branch.is_not_hashed()) + }}; + + let parent_data = ParentData::load("branch load", &mut cb.base, &mut cm, &ctx.memory[parent_memory(is_s)], 0.expr()); + ifx! {not!(branch.is_placeholder()) => { + ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { + // Hashed branch hash in parent branch + require!((1, rlc, num_bytes, parent_data.rlc) => @"keccak"); + } elsex { + // Non-hashed branch hash in parent branch + require!(rlc => parent_data.rlc); + }} + }} + if is_s { + ctx_parent_data_s = Some(parent_data); + } else { + ctx_parent_data_c = Some(parent_data); + } + } // - For a branch placeholder we do not have any constraints. However, in the parallel // (regular) branch we have an additional constraint (besides `is_modified` row @@ -289,11 +331,13 @@ impl BranchConfig { ifx!{a!(ctx.branch.is_drifted, rot) => { let branch_rlc = ctx.main(!is_s).bytes(meta, rot).rlc(&r); require!(a!(accs.mod_node_rlc(is_s), rot) => branch_rlc); + //ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [branch_rlc, false.expr()]); }} } elsex { ifx!{a!(ctx.branch.is_modified, rot) => { let branch_rlc = ctx.main(is_s).bytes(meta, rot).rlc(&r); require!(a!(accs.mod_node_rlc(is_s), rot) => branch_rlc); + ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [branch_rlc, false.expr()]); }} }} } @@ -333,7 +377,8 @@ impl BranchConfig { }); BranchConfig { - _marker: PhantomData, + parent_data_s: ctx_parent_data_s.unwrap(), + parent_data_c: ctx_parent_data_c.unwrap(), } } @@ -347,6 +392,8 @@ impl BranchConfig { ) -> Result<(), Error> { let row = &witness[offset]; + pv.nibbles_num_prev = pv.nibbles_num; + pv.modified_node = row.get_byte(BRANCH_0_KEY_POS); pv.node_index = 0; pv.drifted_pos = row.get_byte(DRIFTED_POS); @@ -363,6 +410,7 @@ impl BranchConfig { pv.c_mod_node_hash_rlc = bytes_into_rlc(&c_hash, mpt_config.randomness); if row.get_byte(IS_BRANCH_S_PLACEHOLDER_POS) == 1 { + println!("{}: s_placeholder", offset); // We put hash of a node that moved down to the added branch. // This is needed to check the hash of leaf_in_added_branch. s_hash = witness[offset + 1 + pv.drifted_pos as usize] @@ -374,6 +422,7 @@ impl BranchConfig { pv.is_branch_s_placeholder = false } if row.get_byte(IS_BRANCH_C_PLACEHOLDER_POS) == 1 { + println!("{}: c_placeholder", offset); c_hash = witness[offset + 1 + pv.drifted_pos as usize] .c_hash_bytes() .to_vec(); @@ -515,6 +564,11 @@ impl BranchConfig { || Value::known(F::from(pv.nibbles_num as u64)), )?; + pv.is_hashed_s = row.get_byte(IS_S_BRANCH_NON_HASHED_POS) != 1; + pv.is_hashed_c = row.get_byte(IS_C_BRANCH_NON_HASHED_POS) != 1; + pv.ext_is_hashed_s = row.get_byte(IS_S_EXT_NODE_NON_HASHED_POS) != 1; + pv.ext_is_hashed_c = row.get_byte(IS_C_EXT_NODE_NON_HASHED_POS) != 1; + Ok(()) } @@ -753,6 +807,50 @@ impl BranchConfig { row.assign_branch_row(region, mpt_config, pv, offset)?; } + //println!("node index: {} ({})", pv.node_index, offset); + + if pv.node_index == 15 { + self.parent_data_s.witness_load( + region, + offset, + &mut pv.memory[parent_memory(true)], + 0, + )?; + self.parent_data_c.witness_load( + region, + offset, + &mut pv.memory[parent_memory(false)], + 0, + )?; + + if !pv.is_branch_s_placeholder { + self.parent_data_s.witness_store( + region, + offset, + &mut pv.memory[parent_memory(true)], + pv.s_mod_node_hash_rlc, + false, + )?; + } else { + //self.parent_data_s.witness_store(region, offset, &mut + // pv.memory[parent_memory(true)], pv.c_mod_node_hash_rlc, + // false)?; + } + if !pv.is_branch_c_placeholder { + self.parent_data_c.witness_store( + region, + offset, + &mut pv.memory[parent_memory(false)], + pv.c_mod_node_hash_rlc, + false, + )?; + } else { + //self.parent_data_c.witness_store(region, offset, &mut + // pv.memory[parent_memory(false)], pv.s_mod_node_hash_rlc, + // false)?; + } + } + /* `sel1` is to distinguish whether the S node at `modified_node` position is empty. `sel2` is to distinguish whether the C node at `modified_node` position is empty. @@ -766,26 +864,28 @@ impl BranchConfig { is found with hash `[128, 0, ..., 0]`, but the probability is negligible. */ - let mut sel1 = F::zero(); - let mut sel2 = F::zero(); + let mut sel1 = false; + let mut sel2 = false; if pv.s_mod_node_hash_rlc == F::from(128_u64) { - sel1 = F::one(); + sel1 = true; } if pv.c_mod_node_hash_rlc == F::from(128_u64) { - sel2 = F::one(); + sel2 = true; } + pv.is_placeholder_leaf_s = sel1; + pv.is_placeholder_leaf_c = sel2; region.assign_advice( || "assign sel1".to_string(), mpt_config.denoter.sel1, offset, - || Value::known(sel1), + || Value::known(F::from(sel1)), )?; region.assign_advice( || "assign sel2".to_string(), mpt_config.denoter.sel2, offset, - || Value::known(sel2), + || Value::known(F::from(sel2)), )?; // reassign (it was assigned to 0 in assign_row) branch_acc and diff --git a/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs b/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs index 47a096284c..740672bc4b 100644 --- a/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs +++ b/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs @@ -1,11 +1,17 @@ -use halo2_proofs::{arithmetic::FieldExt, plonk::VirtualCells, poly::Rotation}; -use std::marker::PhantomData; +use halo2_proofs::{ + arithmetic::FieldExt, + circuit::Region, + plonk::{Error, VirtualCells}, + poly::Rotation, +}; use crate::{ circuit, - circuit_tools::DataTransition, - mpt_circuit::MPTContext, + circuit_tools::{CellManager, DataTransition}, mpt_circuit::{helpers::BranchNodeInfo, param::BRANCH_ROWS_NUM}, + mpt_circuit::{ + helpers::KeyData, witness_row::MptWitnessRow, MPTConfig, MPTContext, ProofValues, + }, mpt_circuit::{helpers::MPTConstraintBuilder, FixedTableTag}, }; @@ -123,11 +129,11 @@ Using this approach we do not need to store C RLP & key, but it will increase th #[derive(Clone, Debug)] pub(crate) struct BranchKeyConfig { - _marker: PhantomData, + key_data: KeyData, } impl BranchKeyConfig { - pub fn configure( + pub(crate) fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, ctx: MPTContext, @@ -137,42 +143,30 @@ impl BranchKeyConfig { let mult_diff = ctx.accumulators.mult_diff; let r = ctx.r.clone(); - let rot_branch_init = -BRANCH_ROWS_NUM + 1; - let rot_first_child = rot_branch_init + 1; - let rot_first_child_prev = rot_first_child - BRANCH_ROWS_NUM; - let rot_branch_init_prev = rot_branch_init - BRANCH_ROWS_NUM; - circuit!([meta, cb.base], { - let not_first_level = a!(position_cols.not_first_level); - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - let branch_prev = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init_prev); - let modified_index = a!(ctx.branch.modified_index, rot_first_child); - let key_rlc = - DataTransition::new_with_rot(meta, key.rlc, rot_first_child_prev, rot_first_child); - let key_mult = - DataTransition::new_with_rot(meta, key.mult, rot_first_child_prev, rot_first_child); + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let ctx_key_data: Option>; + circuit!([meta, cb.base], { ifx! {f!(position_cols.q_not_first_ext_c), a!(ctx.branch.is_extension_node_c) => { - let selectors = [branch.is_key_odd(), branch.is_key_even()]; - // Selectors need to be boolean. - for selector in selectors.iter() { - require!(selector => bool); - } - // One selector needs to be enabled. - require!(sum::expr(&selectors) => 1); - - // Get the previous values from the previous branch. In the first level use initial values. - let after_first_level = not_first_level.expr() * not!(branch.is_below_account(meta)); - let (key_rlc_prev, key_mult_prev, is_key_odd_prev) = ifx!{after_first_level => { - (key_rlc.prev(), key_mult.prev(), branch_prev.is_key_odd()) - } elsex { - (0.expr(), 1.expr(), false.expr()) - }}; + let rot_branch_init = -BRANCH_ROWS_NUM + 1; + let rot_first_child = rot_branch_init + 1; + + let branch = BranchNodeInfo::new(meta, ctx.clone(), false, rot_branch_init); + let modified_index = a!(ctx.branch.modified_index, rot_first_child); + let key_rlc = a!(key.rlc, rot_first_child); + let key_mult = a!(key.mult, rot_first_child); + + // `is_key_odd` needs to be boolean + require!(branch.is_key_odd() => bool); + + // Load the last key values + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], 0.expr()); // Calculate the extension node key RLC when in an extension node let key_rlc_post_ext = ifx!{branch.is_extension() => { let key_rlc_ext = DataTransition::new(meta, key.rlc); // Extension key rlc - let ext_key_rlc = key_rlc_prev.expr() + branch.ext_key_rlc(meta, &mut cb.base, key_mult_prev.expr()); + let ext_key_rlc = key_data.rlc.expr() + branch.ext_key_rlc(meta, &mut cb.base, key_data.mult.expr()); // Currently, the extension node S and extension node C both have the same key RLC - // however, sometimes extension node can be replaced by a shorter extension node // (in terms of nibbles), this is still to be implemented. @@ -182,21 +176,21 @@ impl BranchKeyConfig { require!(key_rlc_ext => ext_key_rlc); ext_key_rlc.expr() } elsex { - key_rlc_prev.expr() + key_data.rlc.expr() }}; // Get the length of the key let key_num_bytes_for_mult = ifx!{branch.is_extension() => { // Unless both parts of the key are odd, subtract 1 from the key length. let key_len = branch.ext_key_len(meta, -1); - key_len - ifx! {not!(is_key_odd_prev * branch.is_key_part_in_ext_odd()) => { 1.expr() }} + key_len - ifx! {not!(key_data.is_odd.expr() * branch.is_key_part_in_ext_odd()) => { 1.expr() }} }}; // Get the multiplier for this key length let mult_diff = a!(mult_diff, rot_first_child); require!((FixedTableTag::RMult, key_num_bytes_for_mult, mult_diff) => @"mult"); // Now update the key RLC and multiplier for the branch nibble. - let mult = key_mult_prev.expr() * mult_diff.expr(); + let mult = key_data.mult.expr() * mult_diff.expr(); let (nibble_mult, mult_mult) = ifx!{branch.is_key_odd() => { // The nibble will be added as the most significant nibble using the same multiplier (16.expr(), 1.expr()) @@ -208,40 +202,70 @@ impl BranchKeyConfig { require!(key_mult => mult.expr() * mult_mult.expr()); // Update key parity - ifx!{after_first_level => { - ifx!{branch.is_extension() => { - // We need to take account the nibbles of the extension node. - // The parity alternates when there's an even number of nibbles, remains the same otherwise - ifx!{branch.is_key_part_in_ext_even() => { - require!(branch.is_key_odd() => branch_prev.is_key_even()); - } elsex { - require!(branch.is_key_odd() => branch_prev.is_key_odd()); - }} + ifx!{branch.is_extension() => { + // We need to take account the nibbles of the extension node. + // The parity alternates when there's an even number of nibbles, remains the same otherwise + ifx!{branch.is_key_part_in_ext_even() => { + require!(branch.is_key_odd() => not!(key_data.is_odd)); } elsex { - // The parity simply alternates for regular branches. - require!(branch.is_key_odd() => branch_prev.is_key_even()); + require!(branch.is_key_odd() => key_data.is_odd); }} } elsex { - // In the first level we just have to ensure the initial values are set. - ifx!{branch.is_extension() => { - require!(branch.is_key_odd() => branch.is_key_part_in_ext_even()); - } elsex { - require!(branch.is_key_odd() => true); - }} + // The parity simply alternates for regular branches. + require!(branch.is_key_odd() => not!(key_data.is_odd)); }} + KeyData::store(&mut cb.base, &ctx.memory["key"], [ + key_rlc.expr(), + key_mult.expr(), + branch.nibbles_counter().expr(), + branch.is_key_odd(), + branch.contains_placeholder_leaf(meta, true), + branch.contains_placeholder_leaf(meta, false), + ]); + // We need to check that the nibbles we stored in s are between 0 and 15. cb.set_range_s(FixedTableTag::RangeKeyLen16.expr()); + + ctx_key_data = Some(key_data); }} - ifx! {f!(position_cols.q_not_first_ext_s), a!(ctx.branch.is_extension_node_s), branch.is_extension() => { - // RLC bytes zero check - cb.set_length(branch.ext_num_bytes_on_key_row(meta, 0)); + ifx! {f!(position_cols.q_not_first_ext_s), a!(ctx.branch.is_extension_node_s) => { + let rot_branch_init = -BRANCH_ROWS_NUM + 2; + let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); + ifx! {branch.is_extension() => { + // RLC bytes zero check + // TODO(Brecht): fix + //cb.set_length(1.expr() + branch.ext_num_bytes_on_key_row(meta, 0)); + }} }} }); BranchKeyConfig { - _marker: PhantomData, + key_data: ctx_key_data.unwrap(), } } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + _witness: &[MptWitnessRow], + _mpt_config: &MPTConfig, + pv: &mut ProofValues, + offset: usize, + ) -> Result<(), Error> { + self.key_data + .witness_load(region, offset, &pv.memory["key"], 0)?; + self.key_data.witness_store( + region, + offset, + &mut pv.memory["key"], + pv.key_rlc, + pv.key_rlc_mult, + pv.nibbles_num, + pv.is_placeholder_leaf_s, + pv.is_placeholder_leaf_c, + )?; + Ok(()) + } } diff --git a/zkevm-circuits/src/mpt_circuit/branch/extension_node.rs b/zkevm-circuits/src/mpt_circuit/branch/extension_node.rs index 830ec308d0..6411b0f9f2 100644 --- a/zkevm-circuits/src/mpt_circuit/branch/extension_node.rs +++ b/zkevm-circuits/src/mpt_circuit/branch/extension_node.rs @@ -246,9 +246,9 @@ impl ExtensionNodeConfig { } // For extension nodes exactly 1 type selector needs to be enabled. require!(sum::expr(&type_selectors) => 1); - // `is_key_odd` and `is_key_even` selectors are set using the extension node type selector data. + // `is_key_odd` is set using the extension node type selector data. // (while in case of a regular branch the extension node selectors do not hold this information). - require!(ext.is_key_even() => sum::expr(&type_selectors_c1)); + require!(ext.is_key_odd() => not!(sum::expr(&type_selectors_c1))); require!(ext.is_key_odd() => sum::expr(&type_selectors_c16)); }} @@ -301,9 +301,6 @@ impl ExtensionNodeConfig { require!(branch_rlc => branch_rlc_in_ext); }} - // Check if the extension node is in its parent. - ext.require_in_parent(meta, &mut cb.base); - // Update the number of nibbles processed up to this point. if is_s { // Calculate the number of bytes diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index bf99bfa6b0..614852bc3c 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -2,18 +2,22 @@ use std::{marker::PhantomData, ops::Range}; use crate::{ _cb, circuit, - circuit_tools::{Conditionable, ConstraintBuilder, DataTransition, RLCChainable, RLCable}, + circuit_tools::{ + Cell, CellManager, CellType, Conditionable, ConstraintBuilder, DataTransition, MemoryBank, + RLCChainable, RLCable, + }, evm_circuit::util::rlc, mpt_circuit::param::{ - EXTENSION_ROWS_NUM, KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN, RLP_HASH_VALUE, - RLP_LIST_LONG, RLP_LIST_SHORT, RLP_NIL, RLP_SHORT, + KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN, RLP_HASH_VALUE, RLP_LIST_LONG, RLP_LIST_SHORT, + RLP_NIL, RLP_SHORT, }, util::Expr, }; use gadgets::util::{and, not}; use halo2_proofs::{ arithmetic::FieldExt, - plonk::{Expression, VirtualCells}, + circuit::{Region, Value}, + plonk::{Error, Expression, VirtualCells}, poly::Rotation, }; @@ -28,13 +32,226 @@ use super::{ IS_C_EXT_NODE_NON_HASHED_POS, IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_LONGER_THAN_55_POS, IS_S_EXT_NODE_NON_HASHED_POS, KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, NIBBLES_COUNTER_POS, }, - FixedTableTag, MPTContext, + witness_row::MptWitnessRow, + FixedTableTag, MPTConfig, MPTContext, ProofValues, }; use crate::mpt_circuit::param::{ IS_EXT_LONG_EVEN_C16_POS, IS_EXT_LONG_EVEN_C1_POS, IS_EXT_LONG_ODD_C16_POS, IS_EXT_LONG_ODD_C1_POS, IS_EXT_SHORT_C16_POS, IS_EXT_SHORT_C1_POS, RLP_NUM, }; +pub(crate) trait Gadget { + /// Constraints + fn configure( + meta: &mut VirtualCells<'_, F>, + cb: &mut MPTConstraintBuilder, + ctx: MPTContext, + ) -> Self; + + /// Witness + fn assign( + &self, + region: &mut Region<'_, F>, + witness: &[MptWitnessRow], + mpt_config: &MPTConfig, + pv: &mut ProofValues, + offset: usize, + ) -> Result<(), Error>; +} + +#[derive(Clone, Debug)] +pub(crate) struct KeyData { + pub(crate) rlc: Cell, + pub(crate) mult: Cell, + pub(crate) num_nibbles: Cell, + pub(crate) is_odd: Cell, + pub(crate) is_placeholder_leaf_s: Cell, + pub(crate) is_placeholder_leaf_c: Cell, + pub(crate) rlc_last: Cell, + pub(crate) mult_last: Cell, +} + +impl KeyData { + pub(crate) fn load( + cb: &mut ConstraintBuilder, + cm: &mut CellManager, + memory: &MemoryBank, + offset: Expression, + ) -> Self { + let key_data = KeyData { + rlc: cm.query_cell(CellType::Storage), + mult: cm.query_cell(CellType::Storage), + num_nibbles: cm.query_cell(CellType::Storage), + is_odd: cm.query_cell(CellType::Storage), + is_placeholder_leaf_s: cm.query_cell(CellType::Storage), + is_placeholder_leaf_c: cm.query_cell(CellType::Storage), + rlc_last: cm.query_cell(CellType::Storage), + mult_last: cm.query_cell(CellType::Storage), + }; + circuit!([meta, cb], { + memory.load( + "key load", + cb, + offset, + &[ + key_data.rlc.expr(), + key_data.mult.expr(), + key_data.num_nibbles.expr(), + key_data.is_odd.expr(), + key_data.is_placeholder_leaf_s.expr(), + key_data.is_placeholder_leaf_c.expr(), + ], + ); + }); + key_data + } + + pub(crate) fn store( + cb: &mut ConstraintBuilder, + memory: &MemoryBank, + values: [Expression; 6], + ) { + memory.store(cb, &values); + } + + pub(crate) fn store_initial_values(cb: &mut ConstraintBuilder, memory: &MemoryBank) { + memory.store_with_key(cb, 0.expr(), &Self::default_values()); + } + + pub(crate) fn default_values() -> [Expression; 6] { + [0.expr(), 1.expr(), 0.expr(), false.expr(), false.expr(), false.expr()] + } + + pub(crate) fn witness_store( + &self, + _region: &mut Region<'_, F>, + offset: usize, + memory: &mut MemoryBank, + rlc: F, + mult: F, + num_nibbles: usize, + is_placeholder_leaf_s: bool, + is_placeholder_leaf_c: bool, + ) -> Result<(), Error> { + //println!("offset: {}", offset); + //println!("key_rlc_prev: {:?}", pv.key_rlc_prev); + //println!("key_mult_prev: {:?}", pv.key_rlc_mult_prev); + //println!("nibbles_num_prev: {:?}", pv.nibbles_num_prev); + + let values = [ + rlc, + mult, + F::from(num_nibbles as u64), + F::from(num_nibbles % 2 == 1), + F::from(is_placeholder_leaf_s), + F::from(is_placeholder_leaf_c), + ]; + memory.witness_store(offset, &values); + + Ok(()) + } + + pub(crate) fn witness_load( + &self, + region: &mut Region<'_, F>, + offset: usize, + memory: &MemoryBank, + load_offset: usize, + ) -> Result<(), Error> { + let values = memory.witness_load(load_offset); + + //println!("offset: {}", offset); + //println!("key_rlc_prev: {:?}", pv.key_rlc_prev); + //println!("key_mult_prev: {:?}", pv.key_rlc_mult_prev); + //println!("nibbles_num_prev: {:?}", pv.nibbles_num_prev); + + self.rlc.assign(region, offset, Value::known(values[0]))?; + self.mult.assign(region, offset, Value::known(values[1]))?; + self.num_nibbles + .assign(region, offset, Value::known(values[2]))?; + self.is_odd + .assign(region, offset, Value::known(values[3]))?; + self.is_placeholder_leaf_s + .assign(region, offset, Value::known(values[4]))?; + self.is_placeholder_leaf_c + .assign(region, offset, Value::known(values[5]))?; + + Ok(()) + } +} + +#[derive(Clone, Debug)] +pub(crate) struct ParentData { + pub(crate) rlc: Cell, + pub(crate) force_hashed: Cell, +} + +impl ParentData { + pub(crate) fn load( + description: &'static str, + cb: &mut ConstraintBuilder, + cm: &mut CellManager, + memory: &MemoryBank, + offset: Expression, + ) -> Self { + let parent_data = ParentData { + rlc: cm.query_cell(CellType::Storage), + force_hashed: cm.query_cell(CellType::Storage), + }; + circuit!([meta, cb], { + memory.load( + description, + cb, + offset, + &[parent_data.rlc.expr(), parent_data.force_hashed.expr()], + ); + }); + parent_data + } + + pub(crate) fn store( + cb: &mut ConstraintBuilder, + memory: &MemoryBank, + values: [Expression; 2], + ) { + memory.store(cb, &values); + } + + pub(crate) fn witness_store( + &self, + _region: &mut Region<'_, F>, + offset: usize, + memory: &mut MemoryBank, + rlc: F, + force_hashed: bool, + ) -> Result<(), Error> { + //println!("offset: {}", offset); + //println!("rlc: {:?}", rlc); + //println!("is_hashed: {}", is_hashed); + + let values = [rlc, F::from(force_hashed)]; + memory.witness_store(offset, &values); + + Ok(()) + } + + pub(crate) fn witness_load( + &self, + region: &mut Region<'_, F>, + offset: usize, + memory: &MemoryBank, + load_offset: usize, + ) -> Result<(), Error> { + let values = memory.witness_load(load_offset); + + self.rlc.assign(region, offset, Value::known(values[0]))?; + self.force_hashed + .assign(region, offset, Value::known(values[1]))?; + + Ok(()) + } +} + #[derive(Clone)] pub(crate) struct BranchNodeInfo { pub(crate) is_s: bool, @@ -188,11 +405,6 @@ impl BranchNodeInfo { self.is_long_even() + self.is_long_odd() } - /// Returns if the key up till and including this branch is even. - pub(crate) fn is_key_even(&self) -> Expression { - self.is_c1.expr() - } - /// Returns if the key up till and including this branch is odd. pub(crate) fn is_key_odd(&self) -> Expression { self.is_c16.expr() @@ -374,6 +586,12 @@ impl BranchNodeInfo { self.ext_num_rlp_bytes(meta) + self.ext_len(meta, rot_s) } + /// Number of bytes in the extension node + /// Uses data on the current row! + pub(crate) fn ext_num_bytes2(&self, meta: &mut VirtualCells) -> Expression { + self.ext_num_rlp_bytes(meta) + self.ext_len(meta, 1) + } + /// Length of the extension node (excluding RLP bytes) /// Uses data on the current row! pub(crate) fn ext_len(&self, _meta: &mut VirtualCells, rel_rot: i32) -> Expression { @@ -458,50 +676,6 @@ impl BranchNodeInfo { }) } - pub(crate) fn require_in_parent( - &self, - meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - ) { - circuit!([meta, cb], { - // The branch or extension node data - let (rlc, num_bytes, is_not_hashed) = ifx! {self.is_extension() => { - // Note: acc_c in both cases. - let ext_rlc = a!(self.ctx.accumulators.acc_c.rlc); - (ext_rlc, self.ext_num_bytes(meta), self.ext_is_not_hashed()) - } elsex { - let acc = self.ctx.accumulators.acc(self.is_s); - // TODO: acc currently doesn't have branch ValueNode info - let branch_rlc = (a!(acc.rlc), a!(acc.mult)).rlc_chain(RLP_NIL.expr()); - (branch_rlc, self.num_bytes(meta), self.is_not_hashed()) - }}; - // Check against the value expected in the parent - ifx! {not!(self.is_placeholder()) => { - ifx!{a!(self.ctx.position_cols.not_first_level) => { - ifx!{self.is_below_account(meta) => { - // Branch in first level of storage trie - hash compared to the storage root - let storage_root_rlc = self.storage_root_in_account_above(meta); - require!((1, rlc, num_bytes, storage_root_rlc) => @"keccak"); - } elsex { - // Here the branch is in some other branch - let rot_branch_child_prev = self.rot_branch_init - EXTENSION_ROWS_NUM - 1; - let mod_node_hash_rlc = a!(self.ctx.accumulators.mod_node_rlc(self.is_s), rot_branch_child_prev); - ifx!{is_not_hashed => { - // Non-hashed branch hash in parent branch - require!(rlc => mod_node_hash_rlc); - } elsex { - // Hashed branch hash in parent branch - require!((1, rlc, num_bytes, mod_node_hash_rlc) => @"keccak"); - }} - }} - } elsex { - // Branch in first level of account trie - hash compared to root - require!((1, rlc, num_bytes, a!(self.ctx.inter_root(self.is_s))) => @"keccak"); - }} - }} - }); - } - /// Key data is read from the current row, not at rot_key! pub(crate) fn ext_key_rlc( &self, @@ -510,7 +684,7 @@ impl BranchNodeInfo { key_mult_prev: Expression, ) -> Expression { circuit!([meta, cb], { - let mult_first_odd = ifx! {self.is_key_even() => { 16.expr() } elsex { 1.expr() }}; + let mult_first_odd = ifx! {self.is_key_odd() => { 1.expr() } elsex { 16.expr() }}; let calc_rlc = |meta: &mut VirtualCells, cb: &mut ConstraintBuilder, bytes: &[Expression], @@ -701,6 +875,10 @@ impl StorageLeafInfo { } } + pub(crate) fn set_is_s(&mut self, is_s: bool) { + self.is_s = is_s; + } + // Override the rotation while keeping the length flags intact pub(crate) fn set_rot_key(&mut self, rot_key: i32) { self.rot_key = rot_key; @@ -773,7 +951,6 @@ impl StorageLeafInfo { get_num_nibbles(meta, key_len, is_key_odd) } - /// Key data is read from the current row, not at rot_key! pub(crate) fn key_rlc( &self, meta: &mut VirtualCells, @@ -782,6 +959,7 @@ impl StorageLeafInfo { is_key_odd: Expression, key_mult_first_even: Expression, requires_longer_than_55: bool, + rot: i32, ) -> Expression { circuit!([meta, cb], { let calc_rlc = |meta: &mut VirtualCells, @@ -796,6 +974,7 @@ impl StorageLeafInfo { key_mult_prev.expr(), is_key_odd.expr(), key_mult_first_even.expr(), + self.rot_key + rot, ) }; matchx! { @@ -806,7 +985,7 @@ impl StorageLeafInfo { self.is_long() => { if requires_longer_than_55 { // `s_main.rlp1` needs to be 248. - require!(a!(self.ctx.s_main.rlp1) => (RLP_LIST_LONG + 1)); + require!(a!(self.ctx.s_main.rlp1, self.rot_key + rot) => (RLP_LIST_LONG + 1)); } // First key byte is at `s_main.bytes[1]`. calc_rlc(meta, cb, 3..36, is_key_odd.expr()) @@ -1034,6 +1213,7 @@ impl AccountLeafInfo { key_mult_prev: Expression, is_key_odd: Expression, key_mult_first_even: Expression, + rot: i32, ) -> Expression { leaf_key_rlc( meta, @@ -1043,6 +1223,7 @@ impl AccountLeafInfo { key_mult_prev.expr(), is_key_odd, key_mult_first_even, + self.rot_key + rot, ) } } @@ -1064,17 +1245,18 @@ pub(crate) fn leaf_key_rlc( key_mult_prev: Expression, is_key_odd: Expression, key_mult_first_even: Expression, + rot: i32, ) -> Expression { circuit!([meta, cb], { // Add the odd nibble first if we have one. - let first_byte = a!(ctx.s_main.rlp_bytes()[range.start]); + let first_byte = a!(ctx.s_main.rlp_bytes()[range.start], rot); let (rlc, mult) = ifx! {is_key_odd => { (get_terminal_odd_nibble(first_byte.expr()) * key_mult_prev.expr(), ctx.r[0].expr()) } elsex { require!(first_byte => KEY_TERMINAL_PREFIX_EVEN); (0.expr(), key_mult_first_even.expr()) }}; - (rlc, key_mult_prev * mult).rlc_chain(ctx.rlc(meta, range.start + 1..range.end, 0)) + (rlc, key_mult_prev * mult).rlc_chain(ctx.rlc(meta, range.start + 1..range.end, cb.get_query_offset() + rot)) }) } @@ -1143,11 +1325,7 @@ pub(crate) fn get_num_nibbles( }) } -// The key RLC of the drifted leaf needs to be the same as the key RLC of the -// leaf before the drift - the nibbles are the same in both cases, the -// difference is that before the drift some nibbles are stored in the leaf key, -// while after the drift these nibbles are used as position in a branch or/and -// nibbles of the extension node. +// Returns the RLC values stored in the parent of the current node. pub(crate) fn get_parent_rlc_state( meta: &mut VirtualCells, ctx: MPTContext, @@ -1197,6 +1375,10 @@ pub(crate) fn bytes_into_rlc(expressions: &[u8], r: F) -> F { rlc } +pub(crate) fn parent_memory(is_s: bool) -> String { + (if is_s { "parent_s" } else { "parent_c" }).to_string() +} + /// MPTConstraintBuilder pub struct MPTConstraintBuilder { pub base: ConstraintBuilder, diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index 079348d690..e2ad38555b 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -1,3 +1,4 @@ +pub mod leaf_combined; pub mod leaf_key; pub mod leaf_key_in_added_branch; pub mod leaf_non_existing; diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs new file mode 100644 index 0000000000..e456eb7705 --- /dev/null +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs @@ -0,0 +1,331 @@ +use halo2_proofs::{ + arithmetic::FieldExt, + circuit::{Region, Value}, + plonk::{Error, VirtualCells}, + poly::Rotation, +}; + +use crate::{ + circuit, + circuit_tools::{CellManager, DataTransition, RLCable, RLCChainable, ConstraintBuilder, CellType}, + mpt_circuit::{ + helpers::BranchNodeInfo, + param::{BRANCH_ROWS_NUM, S_START}, + }, + mpt_circuit::{ + helpers::{KeyData, MPTConstraintBuilder, StorageLeafInfo, get_num_bytes_short, ParentData, parent_memory, get_parent_rlc_state}, + param::{KEY_LEN_IN_NIBBLES, EMPTY_TRIE_HASH}, + FixedTableTag, + }, + mpt_circuit::{ + witness_row::{MptWitnessRow, MptWitnessRowType}, + MPTContext, + }, + mpt_circuit::{MPTConfig, ProofValues}, +}; + +#[derive(Clone, Debug)] +pub(crate) struct LeafCombinedConfig { + key_data: KeyData, +} + +impl LeafCombinedConfig { + pub fn configure( + meta: &mut VirtualCells<'_, F>, + cb: &mut MPTConstraintBuilder, + ctx: MPTContext, + ) -> Self { + let is_s = true; + let accs = ctx.accumulators; + let value_prev = ctx.value_prev; + let value = ctx.value; + let s_main = ctx.s_main; + let r = ctx.r.clone(); + + let rot_parent = -1; + let rot_branch_init = rot_parent - (BRANCH_ROWS_NUM - 1); + let rot_branch_child = rot_branch_init + 1; + + let rot_key_s = 0; + let rot_value_s = 1; + let rot_key_c = 2; + let rot_value_c = 3; + + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let mut ctx_key_data: Option> = None; + + circuit!([meta, cb.base], { + let mut branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + + let mut offset = 0; + for is_s in [true, false] { + //cb.base.set_query_offset(offset); + let storage = StorageLeafInfo::new(meta, ctx.clone(), is_s, offset); + //storage.set_is_s(is_s); + //storage.set_rot_key(offset); + branch.set_is_s(is_s); + + // Load the last key values, which depends on the branch being a placeholder. + let is_branch_placeholder = ifx! {not!(storage.is_below_account(meta)) => { branch.is_placeholder() }}; + let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], load_offset); + + // The two flag values need to be boolean. + require!(storage.flag1 => bool); + require!(storage.flag2 => bool); + + // Calculate and store the leaf data RLC + require!(a!(accs.acc_s.rlc, offset) => ctx.rlc(meta, 0..36, offset)); + + // Calculate and store the key RLC. + let key_rlc = key_data.rlc.expr() + + storage.key_rlc( + meta, + &mut cb.base, + key_data.mult.expr(), + key_data.is_odd.expr(), + 1.expr(), + true, + 0, + ); + require!(a!(accs.key.rlc, offset) => key_rlc); + + // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES (except in a + // placeholder leaf). + // TODO(Brecht): why not in placeholder leaf? + ifx! {not!(storage.is_placeholder(meta)) => { + let num_nibbles = storage.num_key_nibbles(meta, key_data.is_odd.expr()); + require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); + }} + + // Num bytes used in RLC + let num_bytes = storage.num_bytes_on_key_row(meta); + // Multiplier is number of bytes + require!((FixedTableTag::RMult, num_bytes.expr(), a!(accs.acc_s.mult, offset)) => @"fixed"); + // RLC bytes zero check + //cb.set_length(num_bytes.expr()); + + offset += 1; + + let is_long = a!(accs.s_mod_node_rlc, offset); + let is_short = a!(accs.c_mod_node_rlc, offset); + + // We need to ensure `is_long` and `is_short` are boolean. + require!(is_short => bool); + require!(is_long => bool); + // `is_short` or `is_long` needs to be true. + require!(sum::expr([is_short.expr(), is_long.expr()]) => 1); + + let rot_s = offset + if is_s { 0 } else { -2 }; + let rot_key = offset - 1; + + // We need to ensure that the stored leaf RLC and value RLC is the same as the + // computed one. + let leaf_rlc = DataTransition::new_with_rot(meta, accs.acc_s.rlc, offset - 1, offset); + let value_rlc = DataTransition::new_with_rot(meta, accs.acc_c.rlc, rot_s, offset); + let mult_prev = a!(accs.acc_s.mult, rot_key); + let (new_value_rlc, leaf_rlc_part) = ifx! {is_short => { + (a!(s_main.rlp1, offset), a!(s_main.rlp1, offset) * mult_prev.expr()) + } elsex { + let value_rlc = s_main.bytes(meta, offset).rlc(&r); + let leaf_rlc = (0.expr(), mult_prev.expr()).rlc_chain([a!(s_main.rlp1, offset), a!(s_main.rlp2, offset), value_rlc.expr()].rlc(&r)); + (value_rlc, leaf_rlc) + }}; + require!(value_rlc => new_value_rlc); + require!(leaf_rlc => leaf_rlc.prev() + leaf_rlc_part); + + // To enable external lookups we need to have the key and the previous/current + // value on the same row. + if !is_s { + require!(a!(accs.key.mult, offset) => a!(accs.key.rlc, rot_key)); + require!(a!(value_prev, offset) => value_rlc.prev()); + require!(a!(value, offset) => value_rlc); + } + + // Get the number of bytes used by the value + let value_num_bytes = matchx! { + is_short => 1.expr(), + is_long => 1.expr() + get_num_bytes_short(a!(s_main.rlp2, offset)), + }; + + // If `is_modified_node_empty = 1`, which means an empty child, we need to + // ensure that the value is set to 0 in the placeholder leaf. For + // example when adding a new storage leaf to the trie, we have an empty child in + // `S` proof and non-empty in `C` proof. + ifx! {branch.contains_placeholder_leaf(meta, is_s) => { + require!(a!(s_main.rlp1, offset) => 0); + }} + + // Make sure the RLP encoding is correct. + // storage = [key, value] + let num_bytes = storage.num_bytes(meta); + // TODO(Brecht): modify the witness for empty placeholder leafs to have valid + // RLP encoding + ifx! {not!(branch.contains_placeholder_leaf(meta, is_s)) => { + let key_num_bytes = storage.num_bytes_on_key_row(meta); + require!(num_bytes => key_num_bytes.expr() + value_num_bytes.expr()); + }}; + + // Check if the account is in its parent. + let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + let parent_data = ParentData::load( + "leaf load", + &mut cb.base, + &mut cm, + &ctx.memory[parent_memory(is_s)], + 0.expr(), + ); + // Check is skipped for placeholder leafs which are dummy leafs + ifx! {storage.is_below_account(meta), storage.is_placeholder_without_branch(meta) => { + // TODO(Brecht): Add this to the keccak table when necessary instead? + // Hash of the only storage leaf which is placeholder requires empty storage root + let empty_root_rlc = EMPTY_TRIE_HASH.iter().map(|v| v.expr()).collect::>().rlc(&r); + require!(parent_data.rlc => empty_root_rlc); + } elsex { + ifx!{not!(and::expr(&[not!(storage.is_below_account(meta)), branch.contains_placeholder_leaf(meta, is_s)])) => { + let is_not_hashed = a!(accs.acc_c.rlc, offset-1); + ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { + // Hashed branch hash in parent branch + require!((1, leaf_rlc, num_bytes, parent_data.rlc) => @"keccak"); + } elsex { + // Non-hashed branch hash in parent branch + require!(leaf_rlc => parent_data.rlc); + }} + }} + }} + // Store the new parent + /*ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [0.expr(), true.expr()], + ); + ctx_parent_data = Some(parent_data); + + // Set the number of bytes used + cb.set_length_s(value_num_bytes);*/ + + offset += 1; + + ctx_key_data = Some(key_data); + } + + + let storage = StorageLeafInfo::new(meta, ctx.clone(), true, 0); + ifx! {not!(storage.is_below_account(meta)) => { + let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); + let drifted_storage = StorageLeafInfo::new(meta, ctx.clone(), true, offset); + + // The two flag values need to be boolean. + require!(drifted_storage.flag1 => bool); + require!(drifted_storage.flag2 => bool); + + // Calculate and store the leaf RLC (RLP + key) + let drifted_rlc = a!(accs.acc_s.rlc, offset); + require!(drifted_rlc => ctx.rlc(meta, 0..36, offset)); + + // We need the intermediate key RLC right before `drifted_index` is added to it. + // If the branch parallel to the placeholder branch is an extension node, + // we have the intermediate RLC stored in the extension node `accs.key.rlc`. + let is_branch_in_first_level = branch.is_below_account(meta); + let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); + // Calculate the drifted key RLC + let drifted_key_rlc = key_rlc_prev.expr() + + branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + + drifted_storage.key_rlc(meta, &mut cb.base, key_mult_prev, branch.is_key_odd(), r[0].expr(), true, 0); + + // Check zero bytes and mult_diff + let mult = a!(accs.acc_s.mult, offset); + ifx!{branch.is_placeholder_s_or_c() => { + // Num bytes used in RLC + let num_bytes = drifted_storage.num_bytes_on_key_row(meta); + // Multiplier is number of bytes + require!((FixedTableTag::RMult, num_bytes.expr(), mult) => @"fixed"); + // RLC bytes zero check + //cb.set_length(num_bytes.expr()); + }} + + // Check that the drifted leaf is unchanged and is stored at `drifted_index`. + let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { + circuit!([meta, cb], { + let rot_key = if is_s { rot_key_s } else { rot_key_c }; + let rot_value = if is_s { rot_value_s } else { rot_value_c }; + // Complete the drifted leaf rlc by adding the bytes on the value row + let drifted_rlc = (drifted_rlc.expr(), mult.expr()).rlc_chain(s_main.rlc(meta, rot_value, &r)); + (true.expr(), a!(accs.key.rlc, rot_key), drifted_rlc, a!(accs.mod_node_rlc(is_s), rot_branch_child)) + }) + }; + let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { + branch.is_placeholder_s() => { + // Neighbour leaf in the added branch + // - `leaf_key_s_rlc` is the key RLC of the leaf before it drifted down + // in a new branch. + // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. + // This is because `c_mod_node_rlc` in the added branch stores the hash of + // `modified_index` (the leaf that has been added). + calc_rlc(true, meta, &mut cb.base) + }, + branch.is_placeholder_c() => { + // Neighbour leaf in the deleted branch + // -`leaf_key_c_rlc` is the key RLC of the leaf after its neighbour leaf + // has been deleted (and there were only two leaves, so the branch was deleted). + // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. + // This is because `s_mod_node_rlc` in the deleted branch stores the hash of + // `modified_index` (the leaf that is to be deleted). + calc_rlc(false, meta, &mut cb.base) + }, + _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), + }; + ifx! {do_checks => { + // The key of the drifted leaf needs to match the key of the leaf + require!(key_rlc => drifted_key_rlc); + // The drifted leaf needs to be stored in the branch at `drifted_index`. + require!((1, drifted_rlc, drifted_storage.num_bytes(meta), mod_hash) => @"keccak"); + }} + }} + + offset += 1; + + let storage = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); + let is_wrong_leaf = a!(s_main.rlp1, offset); + + // Make sure is_wrong_leaf is boolean + require!(is_wrong_leaf => bool); + + let diff_inv = cm.query_cell(CellType::Storage); + ifx! {a!(ctx.proof_type.is_non_existing_storage_proof, offset) => { + // Get the previous key RLC data + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], 2.expr()); + ifx! {is_wrong_leaf => { + // Calculate the key and check it's the address as requested in the lookup + let key_rlc_wrong = key_data.rlc.expr() + storage.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), false, offset - rot_key_c); + require!(a!(accs.key.mult, offset) => key_rlc_wrong); + // Now make sure this address is different than the one of the leaf + require!((a!(accs.key.mult, offset) - a!(accs.key.rlc, rot_key_c)) * diff_inv.expr() => 1); + // Make sure the lengths of the keys are the same + let mut storage_wrong = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); + storage_wrong.set_rot_key(0); + require!(storage_wrong.key_len(meta) => storage.key_len(meta)); + // RLC bytes zero check + let num_bytes = storage.num_bytes_on_key_row(meta); + //cb.set_length(num_bytes); + } elsex { + // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. + require!(key_data.is_placeholder_leaf_c => true); + }} + ctx_key_data = Some(key_data); + } elsex { + // is_wrong_leaf needs to be false when not in non_existing_account proof + require!(is_wrong_leaf => false); + }} + + // Key done, set the default values + //KeyData::store(&mut cb.base, &ctx.memory["key"], KeyData::default_values()); + + cb.base.set_query_offset(0); + }); + + LeafCombinedConfig { + key_data: ctx_key_data.unwrap(), + } + } +} diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key.rs index 5ebc1a86b9..d742738309 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key.rs @@ -1,19 +1,19 @@ use halo2_proofs::{ arithmetic::FieldExt, circuit::{Region, Value}, - plonk::VirtualCells, + plonk::{Error, VirtualCells}, poly::Rotation, }; -use std::marker::PhantomData; use crate::{ circuit, + circuit_tools::CellManager, mpt_circuit::{ helpers::BranchNodeInfo, param::{BRANCH_ROWS_NUM, S_START}, }, mpt_circuit::{ - helpers::{MPTConstraintBuilder, StorageLeafInfo}, + helpers::{KeyData, MPTConstraintBuilder, StorageLeafInfo}, param::KEY_LEN_IN_NIBBLES, FixedTableTag, }, @@ -124,15 +124,16 @@ incorporated in `key_rlc`. That means we need to ignore the first nibble here */ -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(crate) struct LeafKeyConfig { - _marker: PhantomData, + key_data: KeyData, } impl LeafKeyConfig { pub fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, + cm: &mut CellManager, ctx: MPTContext, is_s: bool, ) -> Self { @@ -140,12 +141,12 @@ impl LeafKeyConfig { let rot_parent = if is_s { -1 } else { -3 }; let rot_branch_init = rot_parent - (BRANCH_ROWS_NUM - 1); - let rot_branch_init_prev = rot_branch_init - BRANCH_ROWS_NUM; - let rot_first_child = rot_branch_init + 1; - let rot_first_child_prev = rot_first_child - BRANCH_ROWS_NUM; + + let ctx_key_data: Option>; circuit!([meta, cb.base], { let storage = StorageLeafInfo::new(meta, ctx.clone(), is_s, 0); + let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); // The two flag values need to be boolean. require!(storage.flag1 => bool); @@ -154,34 +155,23 @@ impl LeafKeyConfig { // Calculate and store the leaf data RLC require!(a!(accs.acc_s.rlc) => ctx.rlc(meta, 0..36, 0)); - // Get the key data from the branch above (if any) - let (key_rlc_prev, key_mult_prev, is_key_odd, nibbles_count_prev) = ifx! {not!(storage.is_below_account(meta)) => { - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - ifx!{branch.is_placeholder() => { - ifx!{not!(branch.is_below_account(meta)) => { - let branch_prev = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init_prev); - let rot_prev = rot_first_child_prev; - (a!(accs.key.rlc, rot_prev), a!(accs.key.mult, rot_prev), branch_prev.is_key_odd(), branch_prev.nibbles_counter().expr()) - } elsex { - (0.expr(), 1.expr(), 0.expr(), 0.expr()) - }} - } elsex { - let rot = rot_first_child; - (a!(accs.key.rlc, rot), a!(accs.key.mult, rot), branch.is_key_odd(), branch.nibbles_counter().expr()) - }} - } elsex { - (0.expr(), 1.expr(), 0.expr(), 0.expr()) - }}; + // Load the last key values, which depends on the branch being a placeholder. + let is_branch_placeholder = + ifx! {not!(storage.is_below_account(meta)) => { branch.is_placeholder() }}; + let offset = if is_s { 0.expr() } else { 1.expr() }; + let offset = offset + ifx! {is_branch_placeholder => { 1.expr() }}; + let key_data = KeyData::load(&mut cb.base, cm, &ctx.memory["key"], offset); // Calculate and store the key RLC. - let key_rlc = key_rlc_prev.expr() + let key_rlc = key_data.rlc.expr() + storage.key_rlc( meta, &mut cb.base, - key_mult_prev, - is_key_odd.expr(), + key_data.mult.expr(), + key_data.is_odd.expr(), 1.expr(), true, + 0, ); require!(a!(accs.key.rlc) => key_rlc); @@ -189,20 +179,25 @@ impl LeafKeyConfig { // placeholder leaf). // TODO(Brecht): why not in placeholder leaf? ifx! {not!(storage.is_placeholder(meta)) => { - let num_nibbles = storage.num_key_nibbles(meta, is_key_odd.expr()); - require!(nibbles_count_prev + num_nibbles => KEY_LEN_IN_NIBBLES); + let num_nibbles = storage.num_key_nibbles(meta, key_data.is_odd.expr()); + require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); }} + // Key done, set the default values + KeyData::store(&mut cb.base, &ctx.memory["key"], KeyData::default_values()); + // Num bytes used in RLC let num_bytes = storage.num_bytes_on_key_row(meta); // Multiplier is number of bytes require!((FixedTableTag::RMult, num_bytes.expr(), a!(accs.acc_s.mult)) => @"mult"); // RLC bytes zero check cb.set_length(num_bytes.expr()); + + ctx_key_data = Some(key_data); }); LeafKeyConfig { - _marker: PhantomData, + key_data: ctx_key_data.unwrap(), } } @@ -213,7 +208,7 @@ impl LeafKeyConfig { pv: &mut ProofValues, row: &MptWitnessRow, offset: usize, - ) { + ) -> Result<(), Error> { /* getProof storage leaf examples: short (one RLP byte > 128: 160): @@ -291,6 +286,47 @@ impl LeafKeyConfig { start = S_START; } + /*let key_memory = &mut pv.memory["key"]; + if row.get_type() == MptWitnessRowType::StorageLeafSKey { + if !pv.is_branch_s_placeholder { + self.key_data.assign(region, offset, key_memory, pv.key_rlc, pv.key_rlc_mult, pv.nibbles_num)?; + } else { + self.key_data.assign(region, offset, key_memory, pv.key_rlc_prev, pv.key_rlc_mult_prev, pv.nibbles_num_prev)?; + } + } + if row.get_type() == MptWitnessRowType::StorageLeafCKey { + if !pv.is_branch_c_placeholder { + self.key_data.assign(region, offset, key_memory, pv.key_rlc, pv.key_rlc_mult, pv.nibbles_num)?; + } else { + self.key_data.assign(region, offset, key_memory, pv.key_rlc_prev, pv.key_rlc_mult_prev, pv.nibbles_num_prev)?; + } + }*/ + + let is_s = row.get_type() == MptWitnessRowType::StorageLeafSKey; + let is_branch_placeholder = if is_s { + pv.is_branch_s_placeholder + } else { + pv.is_branch_c_placeholder + }; + let load_offset = if is_s { 0 } else { 1 }; + let load_offset = load_offset + if is_branch_placeholder { 1 } else { 0 }; + self.key_data + .witness_load(region, offset, &mut pv.memory["key"], load_offset)?; + // TODO(Brecht): remove + let row_offset = if is_s {offset} else {offset - 2}; + self.key_data + .witness_load(region, row_offset, &mut pv.memory["key"], load_offset)?; + self.key_data.witness_store( + region, + offset, + &mut pv.memory["key"], + F::zero(), + F::one(), + 0, + false, + false, + )?; + // For leaf S and leaf C we need to start with the same rlc. let mut key_rlc_new = pv.key_rlc; let mut key_rlc_mult_new = pv.key_rlc_mult; @@ -305,18 +341,18 @@ impl LeafKeyConfig { // the key RLC is already computed using the first two bytes above. mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, start); } - region - .assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(key_rlc_new), - ) - .ok(); + region.assign_advice( + || "assign key_rlc".to_string(), + mpt_config.accumulators.key.rlc, + offset, + || Value::known(key_rlc_new), + )?; pv.storage_key_rlc = key_rlc_new; // Store key_rlc into rlc2 to be later set in leaf value C row (to enable // lookups): pv.rlc2 = key_rlc_new; + + Ok(()) } } diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key_in_added_branch.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key_in_added_branch.rs index cabd928887..3f130500ed 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key_in_added_branch.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key_in_added_branch.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use crate::{ circuit, - circuit_tools::RLCChainable, + circuit_tools::{RLCChainable, ConstraintBuilder}, mpt_circuit::{ helpers::StorageLeafInfo, param::{BRANCH_ROWS_NUM, LEAF_DRIFTED_IND, LEAF_KEY_C_IND, LEAF_KEY_S_IND}, @@ -199,7 +199,7 @@ impl LeafKeyInAddedBranchConfig { // Calculate the drifted key RLC let drifted_key_rlc = key_rlc_prev.expr() + branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + - drifted_storage.key_rlc(meta, &mut cb.base, key_mult_prev, branch.is_key_odd(), r[0].expr(), true); + drifted_storage.key_rlc(meta, &mut cb.base, key_mult_prev, branch.is_key_odd(), r[0].expr(), true, 0); // Check zero bytes and mult_diff let mult = a!(accs.acc_s.mult); @@ -213,12 +213,14 @@ impl LeafKeyInAddedBranchConfig { }} // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let mut calc_rlc = |is_s| { - let rot_key = if is_s { rot_key_s } else { rot_key_c }; - let rot_value = if is_s { rot_value_s } else { rot_value_c }; - // Complete the drifted leaf rlc by adding the bytes on the value row - let drifted_rlc = (drifted_rlc.expr(), mult.expr()).rlc_chain(s_main.rlc(meta, rot_value, &r)); - (true.expr(), a!(accs.key.rlc, rot_key), drifted_rlc, a!(accs.mod_node_rlc(is_s), rot_branch_child)) + let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { + circuit!([meta, cb], { + let rot_key = if is_s { rot_key_s } else { rot_key_c }; + let rot_value = if is_s { rot_value_s } else { rot_value_c }; + // Complete the drifted leaf rlc by adding the bytes on the value row + let drifted_rlc = (drifted_rlc.expr(), mult.expr()).rlc_chain(s_main.rlc(meta, rot_value, &r)); + (true.expr(), a!(accs.key.rlc, rot_key), drifted_rlc, a!(accs.mod_node_rlc(is_s), rot_branch_child)) + }) }; let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { branch.is_placeholder_s() => { @@ -228,7 +230,7 @@ impl LeafKeyInAddedBranchConfig { // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. // This is because `c_mod_node_rlc` in the added branch stores the hash of // `modified_index` (the leaf that has been added). - calc_rlc(true) + calc_rlc(true, meta, &mut cb.base) }, branch.is_placeholder_c() => { // Neighbour leaf in the deleted branch @@ -237,7 +239,7 @@ impl LeafKeyInAddedBranchConfig { // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. // This is because `s_mod_node_rlc` in the deleted branch stores the hash of // `modified_index` (the leaf that is to be deleted). - calc_rlc(false) + calc_rlc(false, meta, &mut cb.base) }, _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), }; diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_non_existing.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_non_existing.rs index 348704f1be..f209676610 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_non_existing.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_non_existing.rs @@ -4,15 +4,17 @@ use halo2_proofs::{ plonk::VirtualCells, poly::Rotation, }; -use std::marker::PhantomData; use crate::{ circuit, + circuit_tools::{Cell, CellManager, CellType}, mpt_circuit::witness_row::MptWitnessRow, - mpt_circuit::{helpers::MPTConstraintBuilder, MPTContext}, mpt_circuit::{ - helpers::{BranchNodeInfo, StorageLeafInfo}, - param::BRANCH_ROWS_NUM, + helpers::{StorageLeafInfo}, + }, + mpt_circuit::{ + helpers::{KeyData, MPTConstraintBuilder}, + MPTContext, }, mpt_circuit::{ param::{IS_NON_EXISTING_STORAGE_POS, LEAF_KEY_C_IND, LEAF_NON_EXISTING_IND, S_START}, @@ -75,25 +77,27 @@ is different). */ -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(crate) struct StorageNonExistingConfig { - _marker: PhantomData, + key_data: KeyData, + diff_inv: Cell, } impl StorageNonExistingConfig { pub fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, + cm: &mut CellManager, ctx: MPTContext, ) -> Self { let proof_type = ctx.proof_type; let s_main = ctx.s_main; let accs = ctx.accumulators; + let diff_inv = cm.query_cell(CellType::Storage); + let ctx_key_data: Option>; + let rot_key_c = -(LEAF_NON_EXISTING_IND - LEAF_KEY_C_IND); - let rot_first_child = -(LEAF_NON_EXISTING_IND - 1 + BRANCH_ROWS_NUM); - let rot_branch_init = rot_first_child - 1; - let rot_last_account_row = -LEAF_NON_EXISTING_IND - 1; circuit!([meta, cb.base], { let storage = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); @@ -103,20 +107,14 @@ impl StorageNonExistingConfig { require!(is_wrong_leaf => bool); ifx! {a!(proof_type.is_non_existing_storage_proof) => { + // Get the previous key RLC data + let key_data = KeyData::load(&mut cb.base, cm, &ctx.memory["key"], 2.expr()); ifx! {is_wrong_leaf => { - // Get the previous key RLC data - let (key_rlc_prev, key_mult_prev, is_key_odd) = ifx!{not!(ctx.is_account(meta, rot_last_account_row)) => { - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - (a!(accs.key.rlc, rot_first_child), a!(accs.key.mult, rot_first_child), branch.is_key_odd()) - } elsex { - (0.expr(), 1.expr(), false.expr()) - }}; // Calculate the key and check it's the address as requested in the lookup - let key_rlc_wrong = key_rlc_prev + storage.key_rlc(meta, &mut cb.base, key_mult_prev.expr(), is_key_odd.expr(), 1.expr(), false); + let key_rlc_wrong = key_data.rlc.expr() + storage.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), false, -rot_key_c); require!(a!(accs.key.mult) => key_rlc_wrong); // Now make sure this address is different than the one of the leaf - let diff_inv = a!(accs.acc_s.rlc); - require!((a!(accs.key.mult) - a!(accs.key.rlc, rot_key_c)) * diff_inv => 1); + require!((a!(accs.key.mult) - a!(accs.key.rlc, rot_key_c)) * diff_inv.expr() => 1); // Make sure the lengths of the keys are the same let mut storage_wrong = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); storage_wrong.set_rot_key(0); @@ -126,9 +124,9 @@ impl StorageNonExistingConfig { cb.set_length(num_bytes); } elsex { // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. - let branch = BranchNodeInfo::new(meta, ctx.clone(), false, rot_branch_init); - require!(branch.contains_placeholder_leaf(meta, false) => true); + require!(key_data.is_placeholder_leaf_c => true); }} + ctx_key_data = Some(key_data); } elsex { // is_wrong_leaf needs to be false when not in non_existing_account proof require!(is_wrong_leaf => false); @@ -136,7 +134,8 @@ impl StorageNonExistingConfig { }); StorageNonExistingConfig { - _marker: PhantomData, + key_data: ctx_key_data.unwrap(), + diff_inv, } } @@ -148,6 +147,14 @@ impl StorageNonExistingConfig { witness: &[MptWitnessRow], offset: usize, ) { + self.key_data + .witness_load(region, offset, &mut pv.memory["key"], 2) + .ok(); + // TODO(Brecht): remove + self.key_data + .witness_load(region, offset - 5, &mut pv.memory["key"], 2) + .ok(); + let row = &witness[offset]; if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 0 { // No need to assign anything when not non-existing-storage proof. @@ -174,13 +181,12 @@ impl StorageNonExistingConfig { let diff_inv = (key_rlc_new - pv.storage_key_rlc) .invert() .unwrap_or(F::zero()); - region - .assign_advice( - || "assign diff inv".to_string(), - mpt_config.accumulators.acc_s.rlc, - offset, - || Value::known(diff_inv), - ) + self.diff_inv + .assign(region, offset, Value::known(diff_inv)) + .ok(); + // TODO(Brecht): remove + self.diff_inv + .assign(region, offset - 5, Value::known(diff_inv)) .ok(); if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_value.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_value.rs index bb0a0dee78..deddfd4217 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_value.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_value.rs @@ -4,13 +4,12 @@ use halo2_proofs::{ plonk::VirtualCells, poly::Rotation, }; -use std::marker::PhantomData; use crate::{ circuit, - circuit_tools::{DataTransition, RLCChainable, RLCable}, + circuit_tools::{CellManager, DataTransition, RLCChainable, RLCable}, mpt_circuit::{ - helpers::{get_num_bytes_short, MPTConstraintBuilder}, + helpers::{get_num_bytes_short, parent_memory, MPTConstraintBuilder, ParentData}, param::{ BRANCH_ROWS_NUM, EMPTY_TRIE_HASH, HASH_WIDTH, IS_STORAGE_MOD_POS, LEAF_VALUE_C_IND, LEAF_VALUE_S_IND, @@ -19,7 +18,6 @@ use crate::{ }, mpt_circuit::{ helpers::{BranchNodeInfo, StorageLeafInfo}, - param::{EXTENSION_ROWS_NUM, STORAGE_LEAF_ROWS}, witness_row::{MptWitnessRow, MptWitnessRowType}, }, mpt_circuit::{MPTConfig, ProofValues}, @@ -116,15 +114,16 @@ RLP byte means 32 bytes after it). */ -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub(crate) struct LeafValueConfig { - _marker: PhantomData, + parent_data: ParentData, } impl LeafValueConfig { pub fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, + cm: &mut CellManager, ctx: MPTContext, is_s: bool, ) -> Self { @@ -134,6 +133,8 @@ impl LeafValueConfig { let value = ctx.value; let r = ctx.r.clone(); + let ctx_parent_data: Option>; + let rot_key = -1; let rot_s = if is_s { 0 } else { -2 }; let leaf_value_pos = if is_s { @@ -141,9 +142,7 @@ impl LeafValueConfig { } else { LEAF_VALUE_C_IND }; - let rot_branch = -STORAGE_LEAF_ROWS; let rot_branch_init = -leaf_value_pos - BRANCH_ROWS_NUM; - let rot_branch_child_prev = rot_branch_init - EXTENSION_ROWS_NUM - 1; circuit!([meta, cb.base], { let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); @@ -205,54 +204,47 @@ impl LeafValueConfig { require!(num_bytes => key_num_bytes.expr() + value_num_bytes.expr()); }}; - // Check that the storage leaf is in its parent. - ifx! {storage.is_below_account(meta) => { - ifx!{storage.is_placeholder_without_branch(meta) => { - // Hash of the only storage leaf which is placeholder requires empty storage root - let empty_root_rlc = EMPTY_TRIE_HASH.iter().map(|v| v.expr()).collect::>().rlc(&r); - let storage_root_rlc = storage.storage_root_in_account_above(meta); - require!(storage_root_rlc => empty_root_rlc); - } elsex { - // Hash of the only storage leaf is storage trie root - let storage_root_rlc = storage.storage_root_in_account_above(meta); - require!((1, leaf_rlc, num_bytes, storage_root_rlc) => @"keccak"); - }} + // Check if the account is in its parent. + let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + let parent_data = ParentData::load( + "leaf load", + &mut cb.base, + cm, + &ctx.memory[parent_memory(is_s)], + 0.expr(), + ); + // Check is skipped for placeholder leafs which are dummy leafs + ifx! {storage.is_below_account(meta), storage.is_placeholder_without_branch(meta) => { + // TODO(Brecht): Add this to the keccak table when necessary instead? + // Hash of the only storage leaf which is placeholder requires empty storage root + let empty_root_rlc = EMPTY_TRIE_HASH.iter().map(|v| v.expr()).collect::>().rlc(&r); + require!(parent_data.rlc => empty_root_rlc); } elsex { - // TODO(Brecht): how does contains_placeholder_leaf really impact these checks? - ifx!{not!(branch.contains_placeholder_leaf(meta, is_s)) => { - ifx!{branch.is_placeholder() => { - ifx!{branch.is_below_account(meta) => { - // Hash of the only storage leaf which is after a placeholder is storage trie root - let storage_root_rlc = branch.storage_root_in_account_above(meta); - require!((1, leaf_rlc, num_bytes, storage_root_rlc) => @"keccak"); - } elsex { - // Leaf hash in parent (branch placeholder) - // Check if we're in the branch above the placeholder branch. - let rlc = (a!(accs.acc_s.rlc, -1), mult_prev.expr()).rlc_chain(s_main.rlc(meta, 0, &r)); - let mod_node_hash_rlc = a!(accs.mod_node_rlc(is_s), rot_branch_child_prev); - require!((1, rlc, num_bytes, mod_node_hash_rlc) => @"keccak"); - }} + ifx!{not!(and::expr(&[not!(storage.is_below_account(meta)), branch.contains_placeholder_leaf(meta, is_s)])) => { + let is_not_hashed = a!(accs.acc_c.rlc, -1); + ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { + // Hashed branch hash in parent branch + require!((1, leaf_rlc, num_bytes, parent_data.rlc) => @"keccak"); } elsex { - let mod_node_rlc = a!(accs.mod_node_rlc(is_s), rot_branch); - let not_hashed = a!(accs.acc_c.rlc, -1); - ifx!{not_hashed => { - // Non-hashed leaf in parent - // When leaf is not hashed, the `mod_node_rlc` stores the RLC of the leaf bytes. - require!(leaf_rlc => mod_node_rlc); - } elsex { - // Leaf hash in parent - require!((1, leaf_rlc, num_bytes, mod_node_rlc) => @"keccak"); - }} + // Non-hashed branch hash in parent branch + require!(leaf_rlc => parent_data.rlc); }} }} }} + // Store the new parent + ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [0.expr(), true.expr()], + ); + ctx_parent_data = Some(parent_data); // Set the number of bytes used cb.set_length_s(value_num_bytes); }); LeafValueConfig { - _marker: PhantomData, + parent_data: ctx_parent_data.unwrap(), } } @@ -397,6 +389,25 @@ impl LeafValueConfig { } } + let is_s = row.get_type() == MptWitnessRowType::StorageLeafSValue; + self.parent_data + .witness_load(region, offset, &mut pv.memory[parent_memory(is_s)], 0) + .ok(); + // TODO(Brecht): remove + let row_offset = if is_s {offset - 1} else {offset - 3}; + self.parent_data + .witness_load(region, row_offset, &mut pv.memory[parent_memory(is_s)], 0) + .ok(); + self.parent_data + .witness_store( + region, + offset, + &mut pv.memory[parent_memory(is_s)], + F::zero(), + true, + ) + .ok(); + mpt_config .assign_acc( region, diff --git a/zkevm-circuits/src/mpt_circuit/witness_row.rs b/zkevm-circuits/src/mpt_circuit/witness_row.rs index aa87175cb6..b0976bf785 100644 --- a/zkevm-circuits/src/mpt_circuit/witness_row.rs +++ b/zkevm-circuits/src/mpt_circuit/witness_row.rs @@ -95,6 +95,14 @@ impl MptWitnessRow { + HASH_WIDTH] } + pub(crate) fn s_root_bytes_rlc(&self, r: F) -> F { + bytes_into_rlc(self.s_root_bytes(), r) + } + + pub(crate) fn c_root_bytes_rlc(&self, r: F) -> F { + bytes_into_rlc(self.c_root_bytes(), r) + } + pub(crate) fn address_bytes(&self) -> &[u8] { &self.bytes[self.bytes.len() - 2 * HASH_WIDTH @@ -127,6 +135,11 @@ impl MptWitnessRow { ) -> Result<(), Error> { let row = self.main(); + // println!("row: {}", offset); + // println!("{:?}", account_leaf); + // println!("{:?}", storage_leaf); + // println!("{:?}", branch); + region.assign_advice( || "assign is_branch_init".to_string(), mpt_config.branch.is_init, @@ -383,6 +396,10 @@ impl MptWitnessRow { )?; } + /*if offset == 99 { + println!("{:?}", row); + }*/ + // not all columns may be needed let get_val = |curr_ind: usize| { let val = if curr_ind >= row.len() { @@ -528,8 +545,11 @@ impl MptWitnessRow { pv: &ProofValues, offset: usize, ) -> Result<(), Error> { - let s_root_rlc = bytes_into_rlc(self.s_root_bytes(), mpt_config.randomness); - let c_root_rlc = bytes_into_rlc(self.c_root_bytes(), mpt_config.randomness); + let s_root_rlc = self.s_root_bytes_rlc(mpt_config.randomness); + let c_root_rlc = self.c_root_bytes_rlc(mpt_config.randomness); + + //println!("{}: {:?}", offset, s_root_rlc); + //println!("{}: {:?}", offset, c_root_rlc); region.assign_advice( || "inter start root", From 14359c4415a1f53c93f483ec89b8ec86bf69c4dc Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Thu, 9 Feb 2023 00:22:07 +0100 Subject: [PATCH 02/11] Merge branch state --- zkevm-circuits/src/circuit_tools.rs | 3 + zkevm-circuits/src/mpt_circuit.rs | 390 +---- .../src/mpt_circuit/account_leaf.rs | 1108 ++++++++++++++- .../account_leaf/account_leaf_key.rs | 16 +- .../account_leaf_key_in_added_branch.rs | 6 +- .../account_leaf/account_non_existing.rs | 6 +- zkevm-circuits/src/mpt_circuit/branch.rs | 1263 +++++++++++------ .../src/mpt_circuit/branch/branch_key.rs | 46 +- zkevm-circuits/src/mpt_circuit/helpers.rs | 57 +- zkevm-circuits/src/mpt_circuit/selectors.rs | 4 +- .../mpt_circuit/storage_leaf/leaf_combined.rs | 481 ++++++- zkevm-circuits/src/mpt_circuit/witness_row.rs | 77 - 12 files changed, 2518 insertions(+), 939 deletions(-) diff --git a/zkevm-circuits/src/circuit_tools.rs b/zkevm-circuits/src/circuit_tools.rs index 0175f8ede9..4de22e69b2 100644 --- a/zkevm-circuits/src/circuit_tools.rs +++ b/zkevm-circuits/src/circuit_tools.rs @@ -1478,6 +1478,9 @@ macro_rules! circuit { ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, _ => $catch_all:expr,) => {{ _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, _ => $catch_all,) }}; + ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, $condition_c:expr => $when_c:expr, _ => $catch_all:expr,) => {{ + _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, $condition_c => $when_c, _ => $catch_all,) + }}; } #[allow(unused_macros)] diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index 7499d16cc9..d35afca06c 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -21,21 +21,16 @@ mod storage_leaf; mod witness_row; use account_leaf::{ - account_leaf_key::AccountLeafKeyConfig, - account_leaf_key_in_added_branch::AccountLeafKeyInAddedBranchConfig, - account_leaf_nonce_balance::AccountLeafNonceBalanceConfig, - account_leaf_storage_codehash::AccountLeafStorageCodehashConfig, - account_non_existing::AccountNonExistingConfig, AccountLeaf, AccountLeafCols, + AccountLeaf, AccountLeafCols, }; use branch::{ - branch_init::BranchInitConfig, branch_key::BranchKeyConfig, branch_rlc::BranchRLCConfig, + branch_key::BranchKeyConfig, extension_node::ExtensionNodeConfig, Branch, BranchCols, BranchConfig, }; use columns::{AccumulatorCols, DenoteCols, MainCols, PositionCols, ProofTypeCols}; use proof_chain::ProofChainConfig; use storage_leaf::{ - leaf_key::LeafKeyConfig, leaf_key_in_added_branch::LeafKeyInAddedBranchConfig, - leaf_value::LeafValueConfig, StorageLeaf, StorageLeafCols, + StorageLeaf, StorageLeafCols, }; use witness_row::{MptWitnessRow, MptWitnessRowType}; @@ -55,7 +50,7 @@ use crate::{ use self::{ columns::MPTTable, param::BRANCH_ROWS_NUM, - storage_leaf::leaf_non_existing::StorageNonExistingConfig, + helpers::key_memory, account_leaf::AccountCombinedConfig, }; /* @@ -88,24 +83,9 @@ use self::{ /// Merkle Patricia Trie config. #[derive(Debug)] pub struct RowConfig { - account_leaf_key_s: AccountLeafKeyConfig, - account_leaf_key_c: AccountLeafKeyConfig, - account_leaf_nonce_balance_s: AccountLeafNonceBalanceConfig, - account_leaf_nonce_balance_c: AccountLeafNonceBalanceConfig, - account_leaf_storage_codehash_s: AccountLeafStorageCodehashConfig, - account_leaf_storage_codehash_c: AccountLeafStorageCodehashConfig, - account_leaf_key_in_added_branch: AccountLeafKeyInAddedBranchConfig, - account_non_existing: AccountNonExistingConfig, branch_config: BranchConfig, - branch_key_config: BranchKeyConfig, - ext_node_config_s: ExtensionNodeConfig, - ext_node_config_c: ExtensionNodeConfig, - storage_leaf_key_s: LeafKeyConfig, - storage_leaf_key_c: LeafKeyConfig, - storage_leaf_value_s: LeafValueConfig, - storage_leaf_value_c: LeafValueConfig, - storage_leaf_key_in_added_branch: LeafKeyInAddedBranchConfig, - storage_non_existing: StorageNonExistingConfig, + super_leaf: LeafCombinedConfig, + super_account: AccountCombinedConfig, } /// Merkle Patricia Trie context @@ -200,24 +180,9 @@ pub struct MPTConfig { * enable lookup for storage key/value (to have * address RLC in * the same row as storage key/value). */ - account_leaf_key_s: AccountLeafKeyConfig, - account_leaf_key_c: AccountLeafKeyConfig, - account_leaf_nonce_balance_s: AccountLeafNonceBalanceConfig, - account_leaf_nonce_balance_c: AccountLeafNonceBalanceConfig, - account_leaf_storage_codehash_s: AccountLeafStorageCodehashConfig, - account_leaf_storage_codehash_c: AccountLeafStorageCodehashConfig, - account_leaf_key_in_added_branch: AccountLeafKeyInAddedBranchConfig, - account_non_existing: AccountNonExistingConfig, branch_config: BranchConfig, - branch_key_config: BranchKeyConfig, - ext_node_config_s: ExtensionNodeConfig, - ext_node_config_c: ExtensionNodeConfig, - storage_leaf_key_s: LeafKeyConfig, - storage_leaf_key_c: LeafKeyConfig, - storage_leaf_value_s: LeafValueConfig, - storage_leaf_value_c: LeafValueConfig, - storage_leaf_key_in_added_branch: LeafKeyInAddedBranchConfig, - storage_non_existing: StorageNonExistingConfig, + super_leaf: LeafCombinedConfig, + super_account: AccountCombinedConfig, pub(crate) randomness: F, pub(crate) mpt_table: MPTTable, } @@ -381,12 +346,13 @@ impl MPTConfig { .try_into() .unwrap(); - let managed_columns = (0..32).map(|_| meta.advice_column()).collect::>(); + let managed_columns = (0..40).map(|_| meta.advice_column()).collect::>(); let memory_columns = (0..4).map(|_| meta.advice_column()).collect::>(); let mut memory = Memory::new(memory_columns); - memory.allocate(meta, "key"); + memory.allocate(meta, key_memory(false)); + memory.allocate(meta, key_memory(true)); memory.allocate(meta, parent_memory(false)); memory.allocate(meta, parent_memory(true)); @@ -455,7 +421,8 @@ impl MPTConfig { // Initial key values ifx!{not!(f!(position_cols.q_enable)) => { //KeyData::store(&mut cb.base, &ctx.key_memory, KeyData::default_values()); - KeyData::store_initial_values(&mut cb.base, &ctx.memory["key"]); + KeyData::store_initial_values(&mut cb.base, &ctx.memory[key_memory(true)]); + KeyData::store_initial_values(&mut cb.base, &ctx.memory[key_memory(false)]); }} // Initial parent values ifx!{f!(position_cols.q_enable), not!(a!(ctx.position_cols.not_first_level)), @@ -466,115 +433,22 @@ impl MPTConfig { } }} - // TODO(Brecht): Make an actual state machine (currently close, but not yet) - /* Branch node */ - let branch_config = BranchConfig::configure(meta, &mut cb, ctx.clone()); - // BRANCH.IS_INIT - ifx!{f!(position_cols.q_enable), a!(branch.is_init) => { - BranchInitConfig::configure(meta, &mut cb, ctx.clone()); - }} - // BRANCH.IS_CHILD - ifx!{f!(position_cols.q_not_first), a!(branch.is_child) => { - BranchRLCConfig::configure(meta, &mut cb, ctx.clone(), true); - BranchRLCConfig::configure(meta, &mut cb, ctx.clone(), false); - }} - // BRANCH.IS_EXTENSION_NODE_S - let ext_node_config_s; - let is_extension_node = BranchNodeInfo::new(meta, ctx.clone(), true, -BRANCH_ROWS_NUM + 2).is_extension(); - let is_extension_node_s = a!(branch.is_extension_node_s); - ifx!{f!(position_cols.q_not_first_ext_s), is_extension_node, is_extension_node_s => { - ext_node_config_s = ExtensionNodeConfig::configure(meta, &mut cb, ctx.clone(), true); - }} - // BRANCH.IS_EXTENSION_NODE_C - let ext_node_config_c; - let is_extension_node = BranchNodeInfo::new(meta, ctx.clone(), false, -BRANCH_ROWS_NUM + 1).is_extension(); - let is_extension_node_c = a!(branch.is_extension_node_c); - ifx!{f!(position_cols.q_not_first_ext_c), is_extension_node, is_extension_node_c => { - ext_node_config_c = ExtensionNodeConfig::configure(meta, &mut cb, ctx.clone(), false); - }} - // BRANCH.IS_EXTENSION_NODE_S + BRANCH.IS_EXTENSION_NODE_C - let branch_key_config = BranchKeyConfig::configure(meta, &mut cb, ctx.clone()); - - /* Storage Leaf */ let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); - // LEAF_KEY_S - // LEAF_KEY_C - // LEAF_VALUE_S - // LEAF_VALUE_C - let storage_leaf_key_s; - let storage_leaf_key_c; - let storage_leaf_value_s; - let storage_leaf_value_c; - ifx!{f!(position_cols.q_not_first), a!(position_cols.not_first_level) => { - ifx!{a!(storage_leaf.is_s_key) => { - storage_leaf_key_s = LeafKeyConfig::configure(meta, &mut cb, &mut cm, ctx.clone(), true); - }} - ifx!{a!(ctx.storage_leaf.is_s_value) => { - storage_leaf_value_s = LeafValueConfig::configure(meta, &mut cb, &mut cm, ctx.clone(), true); - }} - ifx!{a!(storage_leaf.is_c_key) => { - storage_leaf_key_c = LeafKeyConfig::configure(meta, &mut cb, &mut cm, ctx.clone(), false); - }} - ifx!{a!(ctx.storage_leaf.is_c_value) => { - storage_leaf_value_c = LeafValueConfig::configure(meta, &mut cb, &mut cm, ctx.clone(), false); - }} - }} - // LEAF_DRIFTED - let storage_leaf_key_in_added_branch; - ifx!{f!(position_cols.q_not_first), a!(position_cols.not_first_level), a!(storage_leaf.is_in_added_branch) => { - storage_leaf_key_in_added_branch = LeafKeyInAddedBranchConfig::configure(meta, &mut cb, ctx.clone()); - }} - // LEAF_NON_EXISTING - let storage_non_existing; - ifx!{f!(position_cols.q_enable), a!(storage_leaf.is_non_existing) => { - storage_non_existing = StorageNonExistingConfig::::configure(meta, &mut cb, &mut cm, ctx.clone()); - }} - - /* Account Leaf */ - // ACCOUNT_LEAF_KEY_S - // ACCOUNT_LEAF_KEY_C - let account_leaf_key_s; - let account_leaf_key_c; + let branch_config; + let super_leaf; + let super_account; ifx!{f!(position_cols.q_enable) => { - ifx!{a!(account_leaf.is_key_s) => { - account_leaf_key_s = AccountLeafKeyConfig::configure(meta, &mut cb, ctx.clone(), true); - }} - ifx!{a!(account_leaf.is_key_c) => { - account_leaf_key_c = AccountLeafKeyConfig::configure(meta, &mut cb, ctx.clone(), false); - }} - }} - // ACCOUNT_NON_EXISTING - let account_non_existing; - ifx!{f!(position_cols.q_enable), a!(account_leaf.is_non_existing) => { - account_non_existing = AccountNonExistingConfig::configure(meta, &mut cb, ctx.clone()); - }} - // ACCOUNT_LEAF_NONCE_BALANCE_S - // ACCOUNT_LEAF_NONCE_BALANCE_C - let account_leaf_nonce_balance_s; - let account_leaf_nonce_balance_c; - ifx!{f!(position_cols.q_not_first) => { - ifx!{a!(account_leaf.is_nonce_balance_s) => { - account_leaf_nonce_balance_s = AccountLeafNonceBalanceConfig::configure(meta, &mut cb, ctx.clone(), true); - }} - ifx!{a!(account_leaf.is_nonce_balance_c) => { - account_leaf_nonce_balance_c = AccountLeafNonceBalanceConfig::configure(meta, &mut cb, ctx.clone(), false); - }} - }} - // ACCOUNT_LEAF_STORAGE_CODEHASH_S - // ACCOUNT_LEAF_STORAGE_CODEHASH_C - let account_leaf_storage_codehash_s = AccountLeafStorageCodehashConfig::configure(meta, &mut cb, ctx.clone(), true); - let account_leaf_storage_codehash_c = AccountLeafStorageCodehashConfig::configure(meta, &mut cb, ctx.clone(), false); - // ACCOUNT_DRIFTED_LEAF - let account_leaf_key_in_added_branch; - ifx!{f!(position_cols.q_not_first), a!(position_cols.not_first_level), a!(account_leaf.is_in_added_branch) => { - account_leaf_key_in_added_branch = AccountLeafKeyInAddedBranchConfig::configure(meta, &mut cb, ctx.clone()); - }} - - ifx!{f!(position_cols.q_not_first), a!(position_cols.not_first_level) => { matchx! { + a!(branch.is_init) => { + branch_config = BranchConfig::configure(meta, &mut cb, ctx.clone()); + }, + a!(account_leaf.is_key_c) => { + super_account = AccountCombinedConfig::configure(meta, &mut cb, ctx.clone()); + }, a!(storage_leaf.is_s_key) => { - LeafCombinedConfig::configure(meta, &mut cb, ctx.clone()); - () + ifx!{f!(position_cols.q_not_first), a!(position_cols.not_first_level) => { + super_leaf = LeafCombinedConfig::configure(meta, &mut cb, ctx.clone()); + }}; }, _ => (), } @@ -585,7 +459,7 @@ impl MPTConfig { // These lookups also enforce the value to be zero if the passed in length is < 0. // TODO(Brecht): would be safer/cleaner if this can be enabled everywhere even for branch child rlp1 // TODO(Brecht): do 2 bytes/lookup when circuit height >= 2**21 - ifx!{f!(position_cols.q_enable) => { + /*ifx!{f!(position_cols.q_enable) => { // Sanity checks (can be removed, here for safety) require!(cb.length_s.sum_conditions() => bool); require!(cb.length_c.sum_conditions() => bool); @@ -614,7 +488,7 @@ impl MPTConfig { for (idx, &byte) in ctx.rlp_bytes()[36..68].into_iter().enumerate() { require!((FixedTableTag::RangeKeyLen256, a!(byte), cb.get_length_c() - (idx + 1).expr()) => @"fixed"); } - }} + }}*/ /* Mult checks */ // TODO(Brecht): manually optimized lookups for now, but the constraint builder can @@ -639,29 +513,15 @@ impl MPTConfig { require!(@"fixed" => fixed_table.iter().map(|table| f!(table)).collect()); /* Memory banks */ + // TODO(Brecht): change back to q_enable ifx!{f!(position_cols.q_enable) => { ctx.memory.generate_constraints(&mut cb.base); }} row_config = Some(RowConfig { - account_leaf_key_s, - account_leaf_key_c, - account_leaf_nonce_balance_s, - account_leaf_nonce_balance_c, - account_leaf_storage_codehash_s, - account_leaf_storage_codehash_c, - account_leaf_key_in_added_branch, - account_non_existing, branch_config, - branch_key_config, - ext_node_config_s, - ext_node_config_c, - storage_leaf_key_s, - storage_leaf_key_c, - storage_leaf_value_s, - storage_leaf_value_c, - storage_leaf_key_in_added_branch, - storage_non_existing, + super_leaf, + super_account, }); }); @@ -725,24 +585,9 @@ impl MPTConfig { keccak_table, fixed_table, address_rlc, - account_leaf_key_s: row_config.account_leaf_key_s, - account_leaf_key_c: row_config.account_leaf_key_c, - account_leaf_nonce_balance_s: row_config.account_leaf_nonce_balance_s, - account_leaf_nonce_balance_c: row_config.account_leaf_nonce_balance_c, - account_leaf_storage_codehash_s: row_config.account_leaf_storage_codehash_s, - account_leaf_storage_codehash_c: row_config.account_leaf_storage_codehash_c, - account_leaf_key_in_added_branch: row_config.account_leaf_key_in_added_branch, - account_non_existing: row_config.account_non_existing, branch_config: row_config.branch_config, - branch_key_config: row_config.branch_key_config, - ext_node_config_s: row_config.ext_node_config_s, - ext_node_config_c: row_config.ext_node_config_c, - storage_leaf_key_s: row_config.storage_leaf_key_s, - storage_leaf_key_c: row_config.storage_leaf_key_c, - storage_leaf_value_s: row_config.storage_leaf_value_s, - storage_leaf_value_c: row_config.storage_leaf_value_c, - storage_leaf_key_in_added_branch: row_config.storage_leaf_key_in_added_branch, - storage_non_existing: row_config.storage_non_existing, + super_leaf: row_config.super_leaf, + super_account: row_config.super_account, randomness, mpt_table, } @@ -942,14 +787,16 @@ impl MPTConfig { memory.clear_witness_data(); - pv.memory["key"].witness_store_init(&[ - F::zero(), - F::one(), - F::zero(), - F::zero(), - F::zero(), - F::zero(), - ]); + for is_s in [true, false] { + pv.memory[key_memory(is_s)].witness_store_init(&[ + F::zero(), + F::one(), + F::zero(), + F::zero(), + F::zero(), + F::zero(), + ]); + } for (ind, row) in witness .iter() @@ -976,19 +823,8 @@ impl MPTConfig { offset, &[row.c_root_bytes_rlc(self.randomness), F::from(true)], ); - - //pv.parent_rlc_s = - // row.s_root_bytes_rlc(self.randomness); - // pv.parent_is_hashed_s = true; - //pv.memory[parent_memory(false)]. - // store_used_at(offset); - // pv.parent_rlc_c = - // row.c_root_bytes_rlc(self.randomness); - // pv.parent_is_hashed_c = true; - //println!("{} -> {:?}", offset, row.get_type()); } - //println!("{} -> {:?}", offset, row.get_type()); region.assign_fixed( @@ -1047,14 +883,11 @@ impl MPTConfig { if row.get_type() == MptWitnessRowType::InitBranch { self.branch_config - .assign_branch_init(&mut region, witness, self, &mut pv, offset) + .assign(&mut region, witness, self, &mut pv, offset) .ok(); offset += 1; } else if row.get_type() == MptWitnessRowType::BranchChild { - self.branch_config - .assign_branch_child(&mut region, witness, self, &mut pv, offset) - .ok(); offset += 1; } else { @@ -1086,6 +919,7 @@ impl MPTConfig { } else if row.get_type() == MptWitnessRowType::AccountLeafNeighbouringLeaf { + println!("[{}] reset", offset); account_leaf.is_in_added_branch = true; pv.key_rlc = F::zero(); // account address until here, storage key from here on pv.key_rlc_mult = F::one(); @@ -1139,151 +973,21 @@ impl MPTConfig { // Storage leaf key if row.get_type() == MptWitnessRowType::StorageLeafSKey { - self.storage_leaf_key_s.assign( - &mut region, - self, - &mut pv, - row, - offset, - )?; - } else if row.get_type() == MptWitnessRowType::StorageLeafCKey { - self.storage_leaf_key_c.assign( - &mut region, - self, - &mut pv, - row, - offset, - )?; - } else if row.get_type() == MptWitnessRowType::StorageLeafSValue { - self.storage_leaf_value_s.assign( - &mut region, - self, - witness, - &mut pv, - offset, - true, - ); - } else if row.get_type() == MptWitnessRowType::StorageLeafCValue { - self.storage_leaf_value_c.assign( + self.super_leaf.assign( &mut region, self, witness, &mut pv, offset, - false, - ); - } else if row.get_type() == MptWitnessRowType::StorageNonExisting { - self.storage_non_existing.assign( - &mut region, - self, - &mut pv, - witness, - offset, - ); - } else if row.get_type() == MptWitnessRowType::AccountLeafKeyS { - self.account_leaf_key_s.assign( - &mut region, - self, - &mut pv, - row, - offset, )?; } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { - self.account_leaf_key_c.assign( + self.super_account.assign( &mut region, self, + witness, &mut pv, - row, offset, )?; - } else if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS - { - self.account_leaf_nonce_balance_s.assign( - &mut region, - self, - &mut pv, - row, - offset, - ); - } else if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceC - { - self.account_leaf_nonce_balance_c.assign( - &mut region, - self, - &mut pv, - row, - offset, - ); - } else if row.get_type() == MptWitnessRowType::AccountLeafRootCodehashS - { - self.account_leaf_storage_codehash_s.assign( - &mut region, - self, - &mut pv, - row, - offset, - ); - } else if row.get_type() == MptWitnessRowType::AccountLeafRootCodehashC - { - self.account_leaf_storage_codehash_c.assign( - &mut region, - self, - &mut pv, - row, - offset, - ); - } else if row.get_type() == MptWitnessRowType::NeighbouringStorageLeaf - && row.get_byte(1) != 0 - { - self.storage_leaf_key_in_added_branch.assign( - &mut region, - self, - &mut pv, - row, - offset, - ); - } else if row.get_type() == MptWitnessRowType::ExtensionNodeS { - self.ext_node_config_s.assign( - &mut region, - self, - &mut pv, - row, - offset, - true, - ); - } else if row.get_type() == MptWitnessRowType::ExtensionNodeC { - self.branch_key_config - .assign(&mut region, witness, self, &mut pv, offset) - .ok(); - self.ext_node_config_c.assign( - &mut region, - self, - &mut pv, - row, - offset, - false, - ); - } else if row.get_type() - == MptWitnessRowType::AccountLeafNeighbouringLeaf - && row.get_byte(1) != 0 - { - // row[1] != 0 just to avoid usize problems below (when row doesn't - // need to be assigned). - self.account_leaf_key_in_added_branch.assign( - &mut region, - self, - &mut pv, - &row.bytes, - offset, - ); - } else if row.get_type() == MptWitnessRowType::AccountNonExisting { - self.account_non_existing.assign( - &mut region, - self, - &mut pv, - witness, - offset, - ); } offset += 1; diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index 369e0a9be7..654dff0c64 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -6,9 +6,36 @@ pub mod account_non_existing; use halo2_proofs::{ arithmetic::FieldExt, - plonk::{Advice, Column, ConstraintSystem}, + plonk::{Advice, Column, ConstraintSystem, Expression}, }; use std::marker::PhantomData; +use halo2_proofs::{ + circuit::{Region, Value}, + plonk::{Error, VirtualCells}, + poly::Rotation, +}; + +use crate::{ + circuit, + circuit_tools::{CellManager, DataTransition, RLCable, Cell, ConstraintBuilder}, + mpt_circuit::{ + helpers::BranchNodeInfo, + param::{BRANCH_ROWS_NUM, S_START}, + }, + mpt_circuit::{ + helpers::{get_num_nibbles, AccountLeafInfo, KeyData, MPTConstraintBuilder, key_memory, get_num_bytes_short, parent_memory, ParentData, get_parent_rlc_state}, + param::{KEY_LEN_IN_NIBBLES, RLP_LIST_LONG, RLP_LONG, RLP_HASH_VALUE}, + FixedTableTag, + }, + mpt_circuit::{param::IS_ACCOUNT_DELETE_MOD_POS, MPTConfig, ProofValues}, + mpt_circuit::{ + witness_row::{MptWitnessRow, MptWitnessRowType}, + MPTContext, + }, +}; + +use super::{param::{ACCOUNT_LEAF_NONCE_BALANCE_S_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_NONCE_BALANCE_C_IND, ACCOUNT_LEAF_KEY_C_IND, C_START, HASH_WIDTH, IS_NONCE_MOD_POS, IS_BALANCE_MOD_POS, IS_CODEHASH_MOD_POS, ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, IS_NON_EXISTING_ACCOUNT_POS}, helpers::bytes_into_rlc}; + #[derive(Clone, Debug)] pub(crate) struct AccountLeafCols { @@ -74,3 +101,1082 @@ pub(crate) struct AccountLeaf { pub(crate) is_storage_codehash_c: bool, pub(crate) is_in_added_branch: bool, } + +#[derive(Clone, Debug)] +pub(crate) struct AccountCombinedConfig { + key_data_s: KeyData, + key_data_c: KeyData, + key_data_w: KeyData, + key_data_d: KeyData, + parent_data_s: ParentData, + parent_data_c: ParentData, + //diff_inv: Cell, +} + +impl AccountCombinedConfig { + pub fn configure( + meta: &mut VirtualCells<'_, F>, + cb: &mut MPTConstraintBuilder, + ctx: MPTContext, + ) -> Self { + let proof_type = ctx.proof_type; + let not_first_level = ctx.position_cols.not_first_level; + let s_main = ctx.s_main; + let accs = ctx.accumulators; + let address_rlc = ctx.address_rlc; + let s_main = ctx.s_main; + let c_main = ctx.c_main; + let accs = ctx.accumulators; + let value_prev = ctx.value_prev; + let value = ctx.value; + let r = ctx.r.clone(); + + let mut offset = - 1; + + // key rlc is in the first branch node + let rot_parent = offset - 1; + let rot_first_child = offset - BRANCH_ROWS_NUM + 1; + let rot_branch_init = rot_first_child - 1; + + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let mut ctx_key_data_s: Option> = None; + let mut ctx_key_data_c: Option> = None; + let mut ctx_key_data_w: Option> = None; + let mut ctx_key_data_d: Option> = None; + let mut ctx_parent_data_s: Option> = None; + let mut ctx_parent_data_c: Option> = None; + let mut ctx_diff_inv: Option> = None; + + circuit!([meta, cb.base], { + for is_s in [true, false] { + let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + let account = AccountLeafInfo::new(meta, ctx.clone(), offset); + + // Account leaf always starts with RLP_LIST_LONG + 1 because its length is + // always longer than 55 bytes due to containing two hashes - + // storage root and codehash. + require!(a!(s_main.rlp1, offset) => RLP_LIST_LONG + 1); + + // Calculate and store the leaf data RLC + require!(a!(accs.acc_s.rlc, offset) => ctx.rlc(meta, 0..36, offset)); + + // Load the last key values, which depends on the branch being a placeholder. + let is_branch_placeholder = ifx! {f!(ctx.position_cols.q_not_first), a!(not_first_level) => { branch.is_placeholder() }}; + let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(is_s)], load_offset); + + // Calculate the key RLC + let key_rlc = key_data.rlc.expr() + + account.key_rlc( + meta, + &mut cb.base, + key_data.mult.expr(), + key_data.is_odd.expr(), + 1.expr(), + 0, + ); + require!(a!(accs.key.rlc, offset) => key_rlc); + + // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES. + let key_len = account.key_len(meta); + let num_nibbles = get_num_nibbles(meta, key_len.expr(), key_data.is_odd.expr()); + require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); + + // Key done, set the starting values + KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], KeyData::default_values()); + + // Num bytes used in RLC + let num_bytes = account.num_bytes_on_key_row(meta); + // Update `mult_diff` + require!((FixedTableTag::RMult, num_bytes.expr(), a!(accs.acc_s.mult, offset)) => @"fixed"); + // RLC bytes zero check + //cb.set_length(num_bytes.expr()); + + // The computed key RLC needs to be the same as the value in `address_rlc` + // column. Note that `key_rlc` is used in `account_leaf_key_in_added_branch` and + // in cases when there is a placeholder branch we have `key_rlc - + // address_rlc != 0` because `key_rlc` is computed for the branch + // that is parallel to the placeholder branch. + ifx! {not!(is_branch_placeholder), not!(a!(proof_type.is_non_existing_account_proof, offset)) => { + require!(a!(address_rlc, offset) => a!(accs.key.rlc, offset)); + }} + + // Account delete + // We need to make sure there is no leaf when account is deleted. Two possible + // cases: + // - 1. Account leaf is deleted and there is a nil object in + // branch. In this case we have a placeholder leaf. + // - 2. Account leaf is deleted from a branch with two leaves, the remaining + // leaf moves one level up and replaces the branch. In this case we + // have a branch placeholder. So we need to check there is a + // placeholder branch when we have the second case. Note: we do not + // need to cover the case when the (only) branch dissapears and only one + // leaf remains in the trie because there will always be at least two leaves + // (the genesis account) when account will be deleted, + // so there will always be a branch / extension node (and thus placeholder + // branch). + if !is_s { + // Note: this constraint suffices because the proper transition from branch to a + // leaf (2. case) is checked by constraints in account_leaf_key_in_added_branch. + ifx! {a!(proof_type.is_account_delete_mod, offset) => { + require!(or::expr([branch.contains_placeholder_leaf(meta, is_s), branch.is_placeholder()]) => true); + }} + } + + if is_s { + ctx_key_data_s = Some(key_data); + } else { + ctx_key_data_c = Some(key_data); + } + + offset += 1; + } + + let rot_key_s = offset - 2; + let rot_key_c = rot_key_s + 1; + let rot_nonce_s = rot_key_c + 2; + let rot_nonce_c = rot_nonce_s + 1; + let rot_storage_s = rot_nonce_c + 1; + let rot_storage_c = rot_storage_s + 1; + let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key_s); + // Make sure is_wrong_leaf is boolean + require!(account.is_wrong_leaf(meta, true) => bool); + + ifx! {a!(proof_type.is_non_existing_account_proof, offset) => { + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 1.expr()); + ifx! {account.is_wrong_leaf(meta, true) => { + // Calculate the key and check it's the address as requested in the lookup + let key_rlc_wrong = key_data.rlc.expr() + account.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), offset - rot_key_s); + require!(a!(address_rlc, offset) => key_rlc_wrong); + // Now make sure this address is different than the one of the leaf + let diff_inv = a!(accs.acc_s.rlc, offset); + require!((a!(address_rlc, offset) - a!(accs.key.rlc, rot_key_s)) * diff_inv => 1); + // Make sure the lengths of the keys are the same + let account_wrong = AccountLeafInfo::new(meta, ctx.clone(), offset); + require!(account_wrong.key_len(meta) => account.key_len(meta)); + // RLC bytes zero check + let leaf = AccountLeafInfo::new(meta, ctx.clone(), offset); + let num_bytes = leaf.num_bytes_on_key_row(meta); + //cb.set_length(num_bytes); + } elsex { + // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. + require!(key_data.is_placeholder_leaf_s => true); + }} + ctx_key_data_w = Some(key_data); + } elsex { + // is_wrong_leaf needs to be false when not in non_existing_account proof + require!(account.is_wrong_leaf(meta, true) => false); + }}; + + offset += 1; + + ifx! {f!(ctx.position_cols.q_not_first) => { + for is_s in [true, false] { + let rot_key = offset - 3; + let rot_s = if is_s { offset } else { offset - 1 }; + let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); + + // The two string RLP bytes stored in the s RLP bytes. + // The two list RLP bytes are stored in the c RLP bytes. + // The RLP bytes of nonce/balance are stored bytes[0]. + + // RLC calculation for nonce/balance + let nonce = DataTransition::new_with_rot(meta, accs.s_mod_node_rlc, offset - 1, offset); + let balance = DataTransition::new_with_rot(meta, accs.c_mod_node_rlc, offset - 1, offset); + let mult_diff_nonce = a!(accs.acc_c.rlc, offset); + let mult_diff_balance = a!(accs.key.mult, offset); + let mut calc_rlc = |data: Expression, + is_long: Expression, + mult_diff: Expression, + mult_offset: u64, + is_s: bool| { + // The is_long selector needs to be boolean + require!(is_long => bool); + // Calculate the RLC + let (num_bytes, value_rlc) = ifx! {is_long => { + let num_bytes = get_num_bytes_short(a!(ctx.main(is_s).bytes[0], offset)); + let value_rlc = ctx.main(is_s).bytes(meta, offset)[1..].to_vec().rlc(&r); + (num_bytes, value_rlc) + } elsex { + (1.expr(), a!(ctx.main(is_s).bytes[0], offset)) + }}; + require!(data => value_rlc); + // RLC bytes zero check (+2 because data starts at bytes[0]) + //cb.set_length_sc(is_s, 2.expr() + num_bytes.expr()); + // Get the correct multiplier for the length + require!((FixedTableTag::RMult, num_bytes.expr() + mult_offset.expr(), mult_diff) => @format!("fixed")); + + // Go from the value rlc to the data rlc + let rlc = account.to_data_rlc(meta, ctx.main(is_s), value_rlc, is_long, offset); + (rlc, num_bytes) + }; + let (nonce_rlc, nonce_num_bytes) = calc_rlc( + nonce.expr(), + account.is_nonce_long(), + mult_diff_nonce.expr(), + 4, + true, + ); + let (balance_rlc, balance_num_bytes) = calc_rlc( + balance.expr(), + account.is_balance_long(), + mult_diff_balance.expr(), + 0, + false, + ); + + // Calculate and store the combined nonce + balance multipliers + let account_rlc = DataTransition::new_with_rot(meta, accs.acc_s.rlc, rot_key, offset); + let mult_prev = a!(accs.acc_s.mult, rot_key); + // Multipliers + let mult_after_nonce = a!(accs.acc_c.mult, offset); + let mult_diff_balance = a!(accs.key.mult, offset); + let acc_mult_final = a!(accs.acc_s.mult, offset); + require!(mult_after_nonce => mult_prev.expr() * mult_diff_nonce.expr()); + require!(acc_mult_final => mult_after_nonce.expr() * mult_diff_balance.expr()); + // Store the RLP bytes + nonce + balance RLC. + let rlc = account_rlc.prev() + + account.nonce_balance_rlc( + meta, + nonce_rlc.expr(), + balance_rlc.expr(), + mult_prev.expr(), + mult_diff_nonce.expr(), + offset, + ); + require!(account_rlc => rlc); + + // Check the RLP encoding consistency. + // RlP encoding: account = [key, [nonce, balance, storage, codehash]] + // The only exception is when `is_non_existing_account_proof = 1` & + // `is_wrong_leaf = 0`. In this case the value does not matter as + // the account leaf is only a placeholder and does not use + // `s_main.rlp1` and `s_main.rlp2`. + // TODO(Brecht): Can we remove this if by just making this pass in this special + // case? + ifx! {not!(and::expr(&[a!(proof_type.is_non_existing_account_proof, offset), not!(account.is_wrong_leaf(meta, is_s))])) => { + // We always store between 55 and 256 bytes of data in the values list. + require!(a!(s_main.rlp1, offset) => RLP_LONG + 1); + // The RLP encoded list always has 2 RLP bytes (the c RLP bytes). + require!(a!(s_main.rlp2, offset) => a!(c_main.rlp2, offset) + 2.expr()); + // `c_main.rlp1` always needs to be RLP_LIST_LONG + 1. + require!(a!(c_main.rlp1, offset) => RLP_LIST_LONG + 1); + // The length of the list is `#(nonce bytes) + #(balance bytes) + 2 * (1 + #(hash))`. + require!(a!(c_main.rlp2, offset) => nonce_num_bytes.expr() + balance_num_bytes.expr() + (2 * (1 + 32)).expr()); + // Now check that the the key and value list length matches the account length. + let len = account.num_bytes(meta); + let key_num_bytes = account.num_bytes_on_key_row(meta); + // The RLP encoded string always has 2 RLP bytes (the s RLP bytes). + let value_list_num_bytes = a!(s_main.rlp2, offset) + 2.expr(); + // Account length needs to equal all key bytes and all values list bytes. + require!(len => key_num_bytes + value_list_num_bytes); + }} + + // To enable lookups we need to have the previous/current nonce/balance on the + // same row + if !is_s { + require!(a!(value_prev, rot_s) => nonce.prev()); + require!(a!(value, rot_s) => nonce); + require!(a!(value_prev, offset) => balance.prev()); + require!(a!(value, offset) => balance); + } + + // Check that there is only one modification. + if !is_s { + // Note: For `is_non_existing_account_proof` we do not need this constraint, + // `S` and `C` proofs are the same and we need to do a lookup into only one + // (the other one could really be whatever). + ifx! {not!(a!(proof_type.is_account_delete_mod, offset)) => { + // Nonce needs to remain the same when not modifying the nonce + ifx!{not!(a!(proof_type.is_nonce_mod, offset)) => { + require!(nonce => nonce.prev()); + }} + // Balance needs to remain the same when not modifying the balance + ifx!{not!(a!(proof_type.is_balance_mod, offset)) => { + require!(balance => balance.prev()); + }} + }} + } + + offset += 1; + } + + for is_s in [true, false] { + let rot_key = offset - 5; + let rot_nonce_balance = offset - 2; + let rot_s = if is_s { offset } else { offset - 1 }; + // rlp1 is not used, rlp2 is used to store the first RLP byte. + let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); + + // When non_existing_account_proof and not wrong leaf there is only a placeholder account leaf + // and the constraints in this gate are not triggered. In that case it is checked + // that there is nil in the parent branch at the proper position (see `account_non_existing.rs`), note + // that we need (placeholder) account leaf for lookups and to know when to check that parent branch + // has a nil. + // TODO(Brecht): Can we remove this if by just making this pass in this special case? + ifx! {not!(and::expr(&[a!(proof_type.is_non_existing_account_proof, offset), not!(account.is_wrong_leaf(meta, is_s))])) => { + // Storage root and codehash are always 32-byte hashes. + require!(a!(s_main.rlp2, offset) => RLP_HASH_VALUE); + require!(a!(c_main.rlp2, offset) => RLP_HASH_VALUE); + }} + + // RLC calculation + let account_rlc = DataTransition::new_with_rot(meta, accs.acc_s.rlc, rot_nonce_balance, offset); + let mult_prev = a!(accs.acc_s.mult, rot_nonce_balance); + // - Storage root + let storage_root = DataTransition::new_with_rot(meta, accs.s_mod_node_rlc, offset - 1, offset); + require!(storage_root => s_main.bytes(meta, offset).rlc(&r)); + // - Codehash + let codehash = DataTransition::new_with_rot(meta, accs.c_mod_node_rlc, offset - 1, offset); + require!(codehash => c_main.bytes(meta, offset).rlc(&r)); + // The full account leaf RLC + let rlc = account_rlc.prev() + account.storage_codehash_rlc(meta, storage_root.expr(), codehash.expr(), mult_prev.expr(), offset); + require!(account_rlc => rlc); + + // Check if the account is in its parent. + let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + let parent_data = ParentData::load("storage load", &mut cb.base, &mut cm, &ctx.memory[parent_memory(is_s)], 0.expr()); + // Check is skipped for placeholder leafs which are dummy leafs + ifx!{not!(and::expr(&[a!(ctx.position_cols.not_first_level, offset), not!(branch.is_placeholder()), branch.contains_placeholder_leaf(meta, is_s)])) => { + let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); + require!((1, account_rlc, account.num_bytes(meta), parent_data.rlc) => @"keccak"); + }} + // Store the new parent + ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [storage_root.expr(), true.expr()]); + if is_s { + ctx_parent_data_s = Some(parent_data); + } else { + ctx_parent_data_c = Some(parent_data); + } + + if !is_s { + // To enable lookups we need to have the previous/current storage root/code hash on the same row. + require!(a!(value_prev, rot_s) => storage_root.prev()); + require!(a!(value, rot_s) => storage_root); + require!(a!(value_prev, offset) => codehash.prev()); + require!(a!(value, offset) => codehash); + + // Check that there is only one modification (except when the account is being deleted). + ifx!{not!(a!(proof_type.is_account_delete_mod, offset)) => { + // Storage root needs to remain the same when not modifying the storage root + ifx!{not!(a!(proof_type.is_storage_mod, offset)) => { + require!(storage_root => storage_root.prev()); + }} + // Codehash root needs to remain the same when not modifying the codehash + ifx!{not!(a!(proof_type.is_codehash_mod, offset)) => { + require!(codehash => codehash.prev()); + }} + }} + } + + offset += 1; + } + + ifx! {a!(ctx.position_cols.not_first_level) => { + let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); + let drifted_account = AccountLeafInfo::new(meta, ctx.clone(), offset); + + // A drifted leaf appears only when there is a placeholder branch + ifx! {branch.is_placeholder_s_or_c() => { + // Calculate and store the leaf RLC (RLP + key) + let drifted_rlc = a!(accs.acc_s.rlc, offset); + require!(drifted_rlc => ctx.rlc(meta, 0..36, offset)); + + // `s_rlp1` is always RLP_LIST_LONG + 1 because the account leaf is always > 55 bytes (and < 256) + require!(a!(s_main.rlp1, offset) => RLP_LIST_LONG + 1); + + // The key RLC of the drifted leaf needs to be the same as the key RLC of the leaf before + // the drift - the nibbles are the same in both cases, the difference is that before the + // drift some nibbles are stored in the leaf key, while after the drift these nibbles are used as + // position in a branch or/and nibbles of the extension node. + let is_branch_in_first_level = not!(a!(not_first_level, rot_branch_init)); + let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); + + // Load the last key values + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 2.expr()); + + // TODO(Brecht): make this work with loaded key data when extension node is separate + ifx! {not!(branch.is_extension()) => { + require!(key_data.rlc => key_rlc_prev); + require!(key_data.mult => key_mult_prev); + }} + + // Calculate the drifted key RLC + let drifted_key_rlc = key_rlc_prev + + branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + + drifted_account.key_rlc(meta, &mut cb.base, key_mult_prev.expr(), branch.is_key_odd(), r[0].expr(), 0); + + // RLC bytes zero check + let num_bytes = drifted_account.num_bytes_on_key_row(meta); + cb.set_length(num_bytes.expr()); + // Update `mult_diff` + let mult = a!(accs.acc_s.mult, offset); + require!((FixedTableTag::RMult, num_bytes.expr(), mult) => @"mult"); + + // Check that the drifted leaf is unchanged and is stored at `drifted_index`. + let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { + circuit!([meta, cb], { + let rot_key = if is_s { rot_key_s } else { rot_key_c }; + let rot_nonce = if is_s { rot_nonce_s } else { rot_nonce_c }; + let rot_storage = if is_s { rot_storage_s } else { rot_storage_c }; + + let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); + + // Calculate the drifted leaf rlc + // Nonce data rlc + let nonce_stored = a!(accs.s_mod_node_rlc, rot_nonce); + let nonce_rlc = account.to_data_rlc(meta, ctx.s_main, nonce_stored, account.is_nonce_long(), rot_nonce); + // Balance data rlc + let balance_stored = a!(accs.c_mod_node_rlc, rot_nonce); + let balance_rlc = account.to_data_rlc(meta, ctx.c_main, balance_stored, account.is_balance_long(), rot_nonce); + let mult_nonce = a!(accs.acc_c.rlc, rot_nonce); + let mult_balance = a!(accs.key.mult, rot_nonce); + let rlc = drifted_rlc.expr() + account.nonce_balance_rlc(meta, nonce_rlc.expr(), balance_rlc.expr(), mult.expr(), mult_nonce.expr(), rot_nonce); + // Add storage/codehash rlc + let storage_rlc = a!(accs.s_mod_node_rlc, rot_storage); + let codehash_rlc = a!(accs.c_mod_node_rlc, rot_storage); + let mult_prev = mult.expr() * mult_nonce.expr() * mult_balance.expr(); + let rlc = rlc + account.storage_codehash_rlc(meta, storage_rlc.expr(), codehash_rlc.expr(), mult_prev.expr(), rot_storage); + + (true.expr(), a!(accs.key.rlc, rot_key), rlc, a!(accs.mod_node_rlc(is_s), rot_first_child)) + }) + }; + let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { + branch.is_placeholder_s() => { + // Neighbour leaf in the added branch + // - `leaf_key_s_rlc` is the key RLC of the leaf before it drifted down + // in a new branch. + // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. + // This is because `c_mod_node_rlc` in the added branch stores the hash of + // `modified_index` (the leaf that has been added). + calc_rlc(true, meta, &mut cb.base) + }, + branch.is_placeholder_c() => { + // Neighbour leaf in the deleted branch + // -`leaf_key_c_rlc` is the key RLC of the leaf after its neighbour leaf + // has been deleted (and there were only two leaves, so the branch was deleted). + // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. + // This is because `s_mod_node_rlc` in the deleted branch stores the hash of + // `modified_index` (the leaf that is to be deleted). + calc_rlc(false, meta, &mut cb.base) + }, + _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), + }; + ifx! {do_checks => { + // The key of the drifted leaf needs to match the key of the leaf + require!(key_rlc => drifted_key_rlc); + // The drifted leaf needs to be stored in the branch at `drifted_index`. + require!((1, drifted_rlc, drifted_account.num_bytes(meta), mod_hash) => @"keccak"); + }} + ctx_key_data_d = Some(key_data); + }} + }} + }} + }); + + AccountCombinedConfig { + key_data_s: ctx_key_data_s.unwrap(), + key_data_c: ctx_key_data_c.unwrap(), + key_data_w: ctx_key_data_w.unwrap(), + key_data_d: ctx_key_data_d.unwrap(), + parent_data_s: ctx_parent_data_s.unwrap(), + parent_data_c: ctx_parent_data_c.unwrap(), + //diff_inv: ctx_diff_inv.unwrap(), + } + } + + pub fn assign( + &self, + region: &mut Region<'_, F>, + mpt_config: &MPTConfig, + witness: &[MptWitnessRow], + pv: &mut ProofValues, + offset: usize, + ) -> Result<(), Error> { + + let base_offset = offset; + let mut offset = offset - 1; + + /* KEY */ + + for is_s in [true, false] { + let row = &witness[offset]; + + // account leaf key S & C + let mut acc = F::zero(); + let mut acc_mult = F::one(); + // 35 = 2 (leaf rlp) + 1 (key rlp) + key_len + let key_len = (row.get_byte(2) - 128) as usize; + for b in row.bytes.iter().take(3 + key_len) { + acc += F::from(*b as u64) * acc_mult; + acc_mult *= mpt_config.randomness; + } + + if row.get_type() == MptWitnessRowType::AccountLeafKeyS { + pv.acc_account_s = acc; + pv.acc_mult_account_s = acc_mult; + + if row.get_byte_rev(IS_ACCOUNT_DELETE_MOD_POS) == 1 { + region.assign_advice( + || "assign lookup enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(5_u64)), /* account delete mod lookup enabled in + * this row if it is is_account_delete + * proof */ + )?; + } + } else { + pv.acc_account_c = acc; + pv.acc_mult_account_c = acc_mult; + } + + let is_branch_placeholder = if is_s { + pv.is_branch_s_placeholder + } else { + pv.is_branch_c_placeholder + }; + let load_offset = if is_branch_placeholder { 1 } else { 0 }; + let key_data = if is_s { &self.key_data_s } else { &self.key_data_c }; + key_data + .witness_load(region, base_offset, &mut pv.memory[key_memory(is_s)], load_offset)?; + key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + F::zero(), + F::one(), + 0, + false, + false, + )?; + + // For leaf S and leaf C we need to start with the same rlc. + let mut key_rlc_new = pv.key_rlc; + let mut key_rlc_mult_new = pv.key_rlc_mult; + if (pv.is_branch_s_placeholder && row.get_type() == MptWitnessRowType::AccountLeafKeyS) + || (pv.is_branch_c_placeholder && row.get_type() == MptWitnessRowType::AccountLeafKeyC) + { + key_rlc_new = pv.key_rlc_prev; + key_rlc_mult_new = pv.key_rlc_mult_prev; + } + + mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, S_START); + pv.account_key_rlc = key_rlc_new; + region.assign_advice( + || "assign key_rlc".to_string(), + mpt_config.accumulators.key.rlc, + offset, + || Value::known(key_rlc_new), + )?; + + mpt_config.assign_acc(region, acc, acc_mult, F::zero(), F::zero(), offset).ok(); + + offset += 1; + } + + /* NON_EXISTING */ + { + self.key_data_w + .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) + .ok(); + + let row = &witness[offset]; + let address_rlc = bytes_into_rlc(row.address_bytes(), mpt_config.randomness); + let diff_inv = (address_rlc - pv.account_key_rlc) + .invert() + .unwrap_or(F::zero()); + region + .assign_advice( + || "assign diff inv".to_string(), + mpt_config.accumulators.acc_s.rlc, + offset, + || Value::known(diff_inv), + ) + .ok(); + + if row.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1 { + region + .assign_advice( + || "assign lookup enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(4_u64)), /* non existing account lookup enabled in + * this row if it is non_existing_account + * proof */ + ) + .ok(); + } + } + + offset += 1; + + /* NONCE/BALANCE */ + + for is_s in [true, false] { + let row = &witness[offset]; + + let mut nonce_len: usize = 1; + // Note: when nonce or balance is 0, the actual value stored in RLP encoding is + // 128. + if row.get_byte(S_START) > 128 { + nonce_len = row.get_byte(S_START) as usize - 128 + 1; // +1 for byte with length info + region + .assign_advice( + || "assign sel1".to_string(), + mpt_config.denoter.sel1, + offset - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, + || Value::known(F::one()), + ) + .ok(); + } else { + region + .assign_advice( + || "assign sel1".to_string(), + mpt_config.denoter.sel1, + offset - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, + || Value::known(F::zero()), + ) + .ok(); + } + + let mut balance_len: usize = 1; + if row.get_byte(C_START) > 128 { + balance_len = row.get_byte(C_START) as usize - 128 + 1; // +1 for byte with length info + region + .assign_advice( + || "assign sel2".to_string(), + mpt_config.denoter.sel2, + offset - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, + || Value::known(F::one()), + ) + .ok(); + } else { + region + .assign_advice( + || "assign sel2".to_string(), + mpt_config.denoter.sel2, + offset - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, + || Value::known(F::zero()), + ) + .ok(); + } + + // nonce value RLC and balance value RLC: + pv.rlc1 = F::zero(); + pv.rlc2 = F::zero(); + // Note: Below, it first computes and assigns the nonce RLC and balance RLC + // without RLP specific byte (there is a RLP specific byte when + // nonce/balance RLP length > 1). + if nonce_len == 1 && balance_len == 1 { + mpt_config + .compute_rlc_and_assign( + region, + &row.bytes, + pv, + offset, + (S_START, HASH_WIDTH), + (C_START, HASH_WIDTH), + ) + .ok(); + } else if nonce_len > 1 && balance_len == 1 { + mpt_config + .compute_rlc_and_assign( + region, + &row.bytes, + pv, + offset, + (S_START + 1, HASH_WIDTH - 1), + (C_START, HASH_WIDTH), + ) + .ok(); + } else if nonce_len == 1 && balance_len > 1 { + mpt_config + .compute_rlc_and_assign( + region, + &row.bytes, + pv, + offset, + (S_START, HASH_WIDTH), + (C_START + 1, HASH_WIDTH - 1), + ) + .ok(); + } else if nonce_len > 1 && balance_len > 1 { + mpt_config + .compute_rlc_and_assign( + region, + &row.bytes, + pv, + offset, + (S_START + 1, HASH_WIDTH - 1), + (C_START + 1, HASH_WIDTH - 1), + ) + .ok(); + } + + let mut acc_account; + let mut acc_mult_account; + if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { + pv.nonce_value_s = pv.rlc1; + pv.balance_value_s = pv.rlc2; + + acc_account = pv.acc_account_s; + acc_mult_account = pv.acc_mult_account_s; + + if row.get_byte_rev(IS_NONCE_MOD_POS) == 1 { + region + .assign_advice( + || "assign which lookup type enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(1_u64)), + ) + .ok(); + } + } else { + acc_account = pv.acc_account_c; + acc_mult_account = pv.acc_mult_account_c; + + let nonce_value_c = pv.rlc1; + let balance_value_c = pv.rlc2; + + if row.get_byte_rev(IS_BALANCE_MOD_POS) == 1 { + region + .assign_advice( + || "assign which lookup type enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(2_u64)), + ) + .ok(); + } + + let offset_s = offset + - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_NONCE_BALANCE_S_IND) as usize; + + // assign nonce S RLC in ACCOUNT_LEAF_NONCE_BALANCE_S row. + region + .assign_advice( + || "assign nonce S".to_string(), + mpt_config.value_prev, + offset_s, + || Value::known(pv.nonce_value_s), + ) + .ok(); + + // Assign nonce C RLC in ACCOUNT_LEAF_NONCE_BALANCE_S row. + region + .assign_advice( + || "assign nonce C".to_string(), + mpt_config.value, + offset_s, + || Value::known(nonce_value_c), + ) + .ok(); + + // assign balance S RLC in ACCOUNT_LEAF_NONCE_BALANCE_C row. + region + .assign_advice( + || "assign value_prev".to_string(), + mpt_config.value_prev, + offset, + || Value::known(pv.balance_value_s), + ) + .ok(); + + // Assign balance C RLC in ACCOUNT_LEAF_NONCE_BALANCE_C row. + region + .assign_advice( + || "assign balance C".to_string(), + mpt_config.value, + offset, + || Value::known(balance_value_c), + ) + .ok(); + } + + // s_rlp1, s_rlp2 + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut acc_account, + &mut acc_mult_account, + S_START - 2, + 2, + ); + // c_rlp1, c_rlp2 + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut acc_account, + &mut acc_mult_account, + C_START - 2, + 2, + ); + // nonce contribution to leaf RLC: + /* + If nonce stream length is 1, it doesn't have + the first byte with length info. Same for balance. + There are four possibilities: + - nonce is short (length 1), balance is short (length 1) + - nonce is short, balance is long + - nonce is long, balance is short + - nonce is long, balance is long + We put this info in sel1/sel2 in the key row (sel1/sel2 are + already used for other purposes in nonce balance row): + - sel1/sel2: 0/0 (how to check: (1-sel1)*(1-sel2)) + - sel1/sel2: 0/1 (how to check: (1-sel1)*sel2) + - sel1/sel2: 1/0 (how to check: sel1*(1-sel2)) + - sel1/sel2: 1/1 (how to check: sel1*sel2) + */ + + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut acc_account, + &mut acc_mult_account, + S_START, + nonce_len, + ); + + let mut mult_diff_s = F::one(); + for _ in 0..nonce_len + 4 { + // + 4 because of s_rlp1, s_rlp2, c_rlp1, c_rlp2 + mult_diff_s *= mpt_config.randomness; + } + + // It's easier to constrain (in account_leaf_nonce_balance.rs) + // the multiplier if we store acc_mult both after nonce and after + // balance. + let acc_mult_tmp = acc_mult_account; + + // balance contribution to leaf RLC + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut acc_account, + &mut acc_mult_account, + C_START, + balance_len, + ); + + let mut mult_diff_c = F::one(); + for _ in 0..balance_len { + mult_diff_c *= mpt_config.randomness; + } + + mpt_config + .assign_acc( + region, + acc_account, + acc_mult_account, + F::zero(), + acc_mult_tmp, + offset, + ) + .ok(); + + region + .assign_advice( + || "assign mult diff".to_string(), + mpt_config.accumulators.acc_c.rlc, /* assigning key_rlc leads into + * PoisonedConstraint */ + offset, + || Value::known(mult_diff_s), + ) + .ok(); + region + .assign_advice( + || "assign mult diff".to_string(), + mpt_config.accumulators.key.mult, + offset, + || Value::known(mult_diff_c), + ) + .ok(); + if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { + pv.acc_nonce_balance_s = acc_account; + pv.acc_mult_nonce_balance_s = acc_mult_account; + } else { + pv.acc_nonce_balance_c = acc_account; + pv.acc_mult_nonce_balance_c = acc_mult_account; + } + + offset += 1; + } + + /* STORAGE/CODEHASH */ + + for is_s in [true, false] { + let row = &witness[offset]; + + if is_s { + pv.acc_s = pv.acc_nonce_balance_s; + pv.acc_mult_s = pv.acc_mult_nonce_balance_s; + + // storage root RLC and code hash RLC + pv.rlc1 = F::zero(); + pv.rlc2 = F::zero(); + mpt_config + .compute_rlc_and_assign( + region, + &row.bytes, + pv, + offset, + (S_START, HASH_WIDTH), + (C_START, HASH_WIDTH), + ) + .ok(); + pv.storage_root_value_s = pv.rlc1; + pv.codehash_value_s = pv.rlc2; + } else { + pv.acc_s = pv.acc_nonce_balance_c; + pv.acc_mult_s = pv.acc_mult_nonce_balance_c; + + // assign storage root RLC and code hash RLC for this row + pv.rlc1 = F::zero(); + pv.rlc2 = F::zero(); + mpt_config + .compute_rlc_and_assign( + region, + &row.bytes, + pv, + offset, + (S_START, HASH_WIDTH), + (C_START, HASH_WIDTH), + ) + .ok(); + + let storage_root_value_c = pv.rlc1; + let codehash_value_c = pv.rlc2; + + pv.storage_root_value_c = storage_root_value_c; + + if row.get_byte_rev(IS_CODEHASH_MOD_POS) == 1 { + region + .assign_advice( + || "assign lookup enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(3_u64)), // codehash mod lookup enabled in this row if it is is_codehash_mod proof + ) + .ok(); + } + + let offset_s = offset + - (ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND) + as usize; + + // Assign storage root S + region + .assign_advice( + || "assign storage root S".to_string(), + mpt_config.value_prev, + offset_s, + || Value::known(pv.storage_root_value_s), + ) + .ok(); + + // Assign storage root C + region + .assign_advice( + || "assign code hash C".to_string(), + mpt_config.value, + offset_s, + || Value::known(storage_root_value_c), + ) + .ok(); + + // Assign code hash S + region + .assign_advice( + || "assign code hash S".to_string(), + mpt_config.value_prev, + offset, + || Value::known(pv.codehash_value_s), + ) + .ok(); + + // Assign code hash C + region + .assign_advice( + || "assign code hash C".to_string(), + mpt_config.value, + offset, + || Value::known(codehash_value_c), + ) + .ok(); + } + + let storage_root = if is_s { + pv.storage_root_value_s + } else { + pv.storage_root_value_c + }; + let parent_data = if is_s { &self.parent_data_s } else { &self.parent_data_c }; + parent_data + .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) + .ok(); + parent_data + .witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + storage_root, + true, + ) + .ok(); + + // storage + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_s, + &mut pv.acc_mult_s, + S_START - 1, + HASH_WIDTH + 1, + ); + // code hash + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_s, + &mut pv.acc_mult_s, + C_START - 1, + HASH_WIDTH + 1, + ); + mpt_config + .assign_acc( + region, + pv.acc_s, + pv.acc_mult_s, + F::zero(), + F::zero(), + offset, + ) + .ok(); + + offset += 1; + } + + /* DRIFTED */ + + let row = &witness[offset]; + if row.get_byte(1) != 0 { + pv.acc_s = F::zero(); + pv.acc_mult_s = F::one(); + let len = (row.bytes[2] - 128) as usize + 3; + mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); + + self.key_data_d + .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 2) + .ok(); + + mpt_config + .assign_acc( + region, + pv.acc_s, + pv.acc_mult_s, + F::zero(), + F::zero(), + offset, + ) + .ok(); + } + + Ok(()) + } +} diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs index 30e58e9dcd..af8e32c41a 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs @@ -13,7 +13,7 @@ use crate::{ param::{BRANCH_ROWS_NUM, S_START}, }, mpt_circuit::{ - helpers::{get_num_nibbles, AccountLeafInfo, KeyData, MPTConstraintBuilder}, + helpers::{get_num_nibbles, AccountLeafInfo, KeyData, MPTConstraintBuilder, key_memory}, param::{KEY_LEN_IN_NIBBLES, RLP_LIST_LONG}, FixedTableTag, }, @@ -154,9 +154,8 @@ impl AccountLeafKeyConfig { // Load the last key values, which depends on the branch being a placeholder. let is_branch_placeholder = ifx! {a!(not_first_level) => { branch.is_placeholder() }}; - let offset = if is_s { 0.expr() } else { 1.expr() }; - let offset = offset + ifx! {is_branch_placeholder => { 1.expr() }}; - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], offset); + let offset = ifx! {is_branch_placeholder => { 1.expr() }}; + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(is_s)], offset); // Calculate the key RLC let key_rlc = key_data.rlc.expr() @@ -176,7 +175,7 @@ impl AccountLeafKeyConfig { require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); // Key done, set the starting values - KeyData::store(&mut cb.base, &ctx.memory["key"], KeyData::default_values()); + KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], KeyData::default_values()); // Num bytes used in RLC let num_bytes = account.num_bytes_on_key_row(meta); @@ -267,14 +266,13 @@ impl AccountLeafKeyConfig { } else { pv.is_branch_c_placeholder }; - let load_offset = if is_s { 0 } else { 1 }; - let load_offset = load_offset + if is_branch_placeholder { 1 } else { 0 }; + let load_offset = if is_branch_placeholder { 1 } else { 0 }; self.key_data - .witness_load(region, offset, &mut pv.memory["key"], load_offset)?; + .witness_load(region, offset, &mut pv.memory[key_memory(is_s)], load_offset)?; self.key_data.witness_store( region, offset, - &mut pv.memory["key"], + &mut pv.memory[key_memory(is_s)], F::zero(), F::one(), 0, diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs index d6c25c624f..8f490bd53e 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs @@ -4,7 +4,7 @@ use crate::{ circuit, circuit_tools::{CellManager, ConstraintBuilder}, mpt_circuit::{ - helpers::BranchNodeInfo, + helpers::{BranchNodeInfo, key_memory}, param::{ ACCOUNT_DRIFTED_LEAF_IND, ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_NONCE_BALANCE_C_IND, ACCOUNT_LEAF_NONCE_BALANCE_S_IND, @@ -132,7 +132,7 @@ impl AccountLeafKeyInAddedBranchConfig { let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); // Load the last key values - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], 3.expr()); + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 2.expr()); // TODO(Brecht): make this work with loaded key data when extension node is separate ifx! {not!(branch.is_extension()) => { @@ -231,7 +231,7 @@ impl AccountLeafKeyInAddedBranchConfig { mpt_config.compute_acc_and_mult(row, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); self.key_data - .witness_load(region, offset, &mut pv.memory["key"], 3) + .witness_load(region, offset, &mut pv.memory[key_memory(true)], 2) .ok(); mpt_config diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs index 39e893e6ad..4d646b1637 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs @@ -10,7 +10,7 @@ use crate::{ circuit_tools::CellManager, mpt_circuit::witness_row::MptWitnessRow, mpt_circuit::{ - helpers::{bytes_into_rlc, KeyData}, + helpers::{bytes_into_rlc, KeyData, key_memory}, param::{ACCOUNT_NON_EXISTING_IND}, ProofValues, }, @@ -130,7 +130,7 @@ impl AccountNonExistingConfig { require!(account.is_wrong_leaf(meta, true) => bool); ifx! {a!(proof_type.is_non_existing_account_proof) => { - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], 2.expr()); + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 1.expr()); ifx! {account.is_wrong_leaf(meta, true) => { // Calculate the key and check it's the address as requested in the lookup let key_rlc_wrong = key_data.rlc.expr() + account.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), -rot_key_s); @@ -170,7 +170,7 @@ impl AccountNonExistingConfig { offset: usize, ) { self.key_data - .witness_load(region, offset, &mut pv.memory["key"], 2) + .witness_load(region, offset, &mut pv.memory[key_memory(true)], 1) .ok(); let row = &witness[offset]; diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index e4c0d34d46..61bff69ff0 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -17,7 +17,7 @@ use super::{ ARITY, IS_C_BRANCH_NON_HASHED_POS, IS_C_EXT_NODE_NON_HASHED_POS, IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_NODE_NON_HASHED_POS, }, - MPTContext, + MPTContext, witness_row::MptWitnessRowType, }; use crate::{ circuit, @@ -25,9 +25,9 @@ use crate::{ mpt_circuit::account_leaf::AccountLeaf, mpt_circuit::helpers::bytes_into_rlc, mpt_circuit::{ - helpers::{contains_placeholder_leaf, parent_memory, ParentData}, - param::RLP_NIL, - storage_leaf::StorageLeaf, + helpers::{contains_placeholder_leaf, parent_memory, ParentData, get_num_nibbles, KeyData, key_memory}, + param::{RLP_NIL, RLP_LIST_LONG}, + storage_leaf::StorageLeaf, FixedTableTag, }, mpt_circuit::{ helpers::{BranchChildInfo, BranchNodeInfo}, @@ -131,6 +131,7 @@ impl BranchCols { #[derive(Clone, Debug)] pub(crate) struct BranchConfig { + key_data: KeyData, parent_data_s: ParentData, parent_data_c: ParentData, } @@ -149,113 +150,150 @@ impl BranchConfig { let r = ctx.r.clone(); let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let mut ctx_key_data: Option> = None; let mut ctx_parent_data_s: Option> = None; let mut ctx_parent_data_c: Option> = None; circuit!([meta, cb.base], { - let q_not_first = f!(position_cols.q_not_first); - let drifted_index = DataTransition::new(meta, branch.drifted_index); - let node_index = DataTransition::new(meta, branch.node_index); - let modified_index = DataTransition::new(meta, branch.modified_index); - let is_modified = DataTransition::new(meta, branch.is_modified); - let is_branch_init = DataTransition::new(meta, branch.is_init); - let is_branch_child = DataTransition::new(meta, branch.is_child); - let is_last_child = DataTransition::new(meta, branch.is_last_child); - let is_drifted = DataTransition::new(meta, branch.is_drifted); - - ifx! {f!(position_cols.q_enable) => { - // These selectors are only stored in branch init rows - ifx!{is_branch_init => { - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, 0); - // Boolean checks - for selector in [branch.is_placeholder_s(), branch.is_placeholder_c(), branch.is_not_hashed_s(), branch.is_not_hashed_c()] { - require!(selector => bool); - } - // Update the nibble counter - ifx!{not!(branch.is_extension()) => { - let nibbles_counter_prev = ifx!{not!(branch.is_at_tree_top(meta)) => { - branch.nibbles_counter().prev() - }}; - require!(branch.nibbles_counter() => nibbles_counter_prev + 1.expr()); - }} - }} - }} - ifx! {q_not_first => { - ifx!{is_branch_child => { - // Keep track of how many branch bytes we've processed. - for is_s in [true, false] { - let child = BranchChildInfo::new(meta, ctx.clone(), is_s, 0); - // Get the number of bytes used by the current branch. - let num_bytes = child.num_bytes(meta); - // Fetch the number of bytes left from the previous row. - // TODO(Brecht): just store it in branch init in its own column. - let num_bytes_left = ifx!{is_branch_init.prev() => { - // Length of full branch - BranchNodeInfo::new(meta, ctx.clone(), is_s, -1).len(meta) - } elsex { - // Simply stored in rlp1 otherwise - a!(ctx.main(is_s).rlp1, -1) - }}; - // Update number of bytes left - require!(a!(ctx.main(is_s).rlp1) => num_bytes_left - num_bytes.expr()); - // In the final branch child `rlp1` needs to be 1 (because RLP length - // specifies also ValueNode which occupies 1 byte). - // TODO: ValueNode - ifx!{is_last_child => { - require!(a!(ctx.main(is_s).rlp1) => 1); - }} - } + let mut offset = 0; + let rot_branch_init = offset; + + for is_s in [true, false] { + let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, offset); + // Selector constraints + branch.init_selector_checks(meta, &mut cb.base); + // Check that stored rlc/mult values are correct. + let rlp = branch.rlp_bytes(meta); + let (rlc, mult) = matchx! { + branch.is_branch_short(meta) => (rlp[..1].rlc(&r), r[0].expr()), + branch.is_branch_long(meta) => (rlp[..2].rlc(&r), r[1].expr()), + branch.is_branch_very_long(meta) => (rlp[..3].rlc(&r), r[2].expr()), + }; + require!(a!(accs.acc(is_s).rlc) => rlc); + require!(a!(accs.acc(is_s).mult) => mult); + } - // Check that `is_modified` is enabled for the correct branch child. - ifx!{is_modified => { - require!(node_index => modified_index); - }} - // Check that `is_drifted` is enabled for the correct branch child. - ifx!{is_drifted => { - require!(node_index => drifted_index); - }} + // These selectors are only stored in branch init rows + let branch = BranchNodeInfo::new(meta, ctx.clone(), true, 0); + // Boolean checks + for selector in [branch.is_placeholder_s(), branch.is_placeholder_c(), branch.is_not_hashed_s(), branch.is_not_hashed_c()] { + require!(selector => bool); + } + // Update the nibble counter + ifx!{not!(branch.is_extension()) => { + let nibbles_counter_prev = ifx!{not!(branch.is_at_tree_top(meta)) => { + branch.nibbles_counter().prev() + }}; + require!(branch.nibbles_counter() => nibbles_counter_prev + 1.expr()); + }} - // Check values that need to remain the same for all branch children. - ifx!{a!(branch.node_index) => { - // `modified_index` needs to be the same for all branch children. - require!(modified_index => modified_index.prev()); - // `drifted_index` needs to be the same for all branch children. - require!(drifted_index => drifted_index.prev()); - for is_s in [true, false] { - // `mod_node_hash_rlc` the same for all branch children - let mod_node_hash_rlc = ctx.accumulators.mod_node_rlc(is_s); - require!(a!(mod_node_hash_rlc) => a!(mod_node_hash_rlc, -1)); - // `contains_placeholder_leaf` the same for all branch children - require!(contains_placeholder_leaf(meta, ctx.clone(), is_s, 0) - => contains_placeholder_leaf(meta, ctx.clone(), is_s, -1)); - } - }} + offset += 1; + + for node_index in 0..ARITY { + // Keep track of how many branch bytes we've processed. + for is_s in [true, false] { + let child = BranchChildInfo::new(meta, ctx.clone(), is_s, offset); + // Get the number of bytes used by the current branch. + let num_bytes = child.num_bytes(meta); + // Fetch the number of bytes left from the previous row. + // TODO(Brecht): just store it in branch init in its own column. + let num_bytes_left = if node_index == 0 { + // Length of full branch + BranchNodeInfo::new(meta, ctx.clone(), is_s, offset - 1).len(meta) + } else { + // Simply stored in rlp1 otherwise + a!(ctx.main(is_s).rlp1, offset - 1) + }; + // Update number of bytes left + require!(a!(ctx.main(is_s).rlp1, offset) => num_bytes_left - num_bytes.expr()); + // In the final branch child `rlp1` needs to be 1 (because RLP length + // specifies also ValueNode which occupies 1 byte). + // TODO: ValueNode + if node_index == ARITY - 1 { + require!(a!(ctx.main(is_s).rlp1, offset) => 1); + } - // If we have a branch child, we can only have branch child or branch init in the previous row. - require!(or::expr([is_branch_child.prev(), is_branch_init.prev()]) => true); - // When `node_index` != 0 - ifx!{node_index => { - // `node_index` increases by 1 for each branch child. - require!(node_index => node_index.prev() + 1.expr()); - }} + // RLC + { + let main = ctx.main(is_s); + let branch = ctx.accumulators.acc(is_s); + let mult_diff = ctx.accumulators.node_mult_diff(is_s); + + let child = BranchChildInfo::new(meta, ctx.clone(), is_s, offset); + let branch_mult = DataTransition::new_with_rot(meta, branch.mult, offset - 1, offset); + let branch_rlc = DataTransition::new_with_rot(meta, branch.rlc, offset - 1, offset); + // Calculate the RLC + let rlc = child.rlc(meta, &mut cb.base); + require!(branch_rlc => (branch_rlc.prev(), branch_mult.prev()).rlc_chain(rlc)); + require!(branch_mult => branch_mult.prev() * a!(mult_diff, offset)); + // RLC bytes zero check + //cb.set_length_sc(is_s, child.num_bytes_on_row(meta)); + // We need to check that the multiplier changes according to `num_bytes` and + // update it. + require!((FixedTableTag::RMult, child.num_bytes(meta), a!(mult_diff, offset)) => @format!("fixed")); + // When a value is being added (and reverse situation when deleted) to the trie + // and there is no other leaf at the position where it is to be + // added, we have empty branch child in `S` proof and hash of a + // newly added leaf at the parallel position in `C` proof. + // That means we have empty node in `S` proof at `modified_node`. + // When this happens, we denote this situation by having a placeholder leaf. + // In this case we need to make sure the node is seen as empty. + ifx! {a!(ctx.branch.is_modified, offset), contains_placeholder_leaf(meta, ctx.clone(), is_s, offset) => { + require!(child.is_hashed(meta) => true); + require!(a!(main.rlp2, offset) => 0); + }} + } + } - // We need to ensure that the only change in `S` and `C` proof occurs - // at `modified_index` so that only a single change can be done. - // We check `s_main.rlp = c_main.rlp` everywhere except at `modified_index`. - // (except rlp1, rlp1 is used to keep track of number of bytes processed). - let not_at_modification = node_index.expr() - modified_index.expr(); - ifx!{not_at_modification => { - for (s_byte, c_byte) in s_main.rlp_bytes().iter().skip(1) - .zip(c_main.rlp_bytes().iter().skip(1)) - { - require!(a!(s_byte) => a!(c_byte)); - } - }} + // Check that `is_modified` is enabled for the correct branch child. + ifx!{a!(ctx.branch.is_modified, offset) => { + require!(a!(ctx.branch.node_index, offset) => a!(ctx.branch.modified_index, offset)); }} + // Check that `is_drifted` is enabled for the correct branch child. + ifx!{a!(ctx.branch.is_drifted, offset) => { + require!(a!(ctx.branch.node_index, offset) => a!(ctx.branch.drifted_index, offset)); + }} + + // Check values that need to remain the same for all branch children. + /*ifx!{a!(branch.node_index, offset) => { + // `modified_index` needs to be the same for all branch children. + require!(modified_index => modified_index.prev()); + // `drifted_index` needs to be the same for all branch children. + require!(drifted_index => drifted_index.prev()); + for is_s in [true, false] { + // `mod_node_hash_rlc` the same for all branch children + let mod_node_hash_rlc = ctx.accumulators.mod_node_rlc(is_s); + require!(a!(mod_node_hash_rlc) => a!(mod_node_hash_rlc, -1)); + // `contains_placeholder_leaf` the same for all branch children + require!(contains_placeholder_leaf(meta, ctx.clone(), is_s, 0) + => contains_placeholder_leaf(meta, ctx.clone(), is_s, -1)); + } + }}*/ + + // If we have a branch child, we can only have branch child or branch init in the previous row. + /*require!(or::expr([is_branch_child.prev(), is_branch_init.prev()]) => true); + // When `node_index` != 0 + ifx!{node_index => { + // `node_index` increases by 1 for each branch child. + require!(node_index => node_index.prev() + 1.expr()); + }}*/ + + // We need to ensure that the only change in `S` and `C` proof occurs + // at `modified_index` so that only a single change can be done. + // We check `s_main.rlp = c_main.rlp` everywhere except at `modified_index`. + // (except rlp1, rlp1 is used to keep track of number of bytes processed). + /*let not_at_modification = node_index.expr() - modified_index.expr(); + ifx!{not_at_modification => { + for (s_byte, c_byte) in s_main.rlp_bytes().iter().skip(1) + .zip(c_main.rlp_bytes().iter().skip(1)) + { + require!(a!(s_byte) => a!(c_byte)); + } + }}*/ // Make sure `is_branch_child`, `node_index` and `is_last_child` are set correctly. - ifx!{is_branch_init.prev() => { + /*ifx!{is_branch_init.prev() => { // First child when previous row is a branch init row require!(is_branch_child => true); require!(node_index => 0); @@ -266,19 +304,19 @@ impl BranchConfig { require!(node_index.prev() => 15); require!(is_last_child.prev() => true); }} - }} + }}*/ - ifx!{is_last_child => { + if node_index == ARITY - 1 { // Rotations could be avoided but we would need additional is_branch_placeholder column. - let mut branch = BranchNodeInfo::new(meta, ctx.clone(), true, -(ARITY as i32)); + let mut branch = BranchNodeInfo::new(meta, ctx.clone(), true, offset - (ARITY as i32)); // `is_modified` needs to be set to 1 at exactly 1 branch child - let is_modified_values = (0..ARITY).map(|rot| a!(ctx.branch.is_modified, -(rot as i32))).collect::>(); + let is_modified_values = (0..ARITY).map(|rot| a!(ctx.branch.is_modified, offset - (rot as i32))).collect::>(); require!(sum::expr(&is_modified_values) => 1); ifx!{branch.is_placeholder() => { // `is_drifted` needs to be set to 1 at exactly 1 branch child - let is_drifted_values = (0..ARITY).map(|rot| a!(ctx.branch.is_drifted, -(rot as i32))).collect::>(); + let is_drifted_values = (0..ARITY).map(|rot| a!(ctx.branch.is_drifted, offset - (rot as i32))).collect::>(); require!(sum::expr(&is_drifted_values) => 1); }} @@ -288,12 +326,12 @@ impl BranchConfig { // Check if the branch is in its parent. let (rlc, num_bytes, is_not_hashed) = ifx! {branch.is_extension() => { // Note: acc_c in both cases. - let ext_rlc = a!(branch.ctx.accumulators.acc_c.rlc, if is_s {1} else {2}); - (ext_rlc, branch.ext_num_bytes2(meta), branch.ext_is_not_hashed()) + let ext_rlc = a!(branch.ctx.accumulators.acc_c.rlc, offset + if is_s {1} else {2}); + (ext_rlc, branch.ext_num_bytes(meta, offset + 1), branch.ext_is_not_hashed()) } elsex { let acc = branch.ctx.accumulators.acc(is_s); // TODO: acc currently doesn't have branch ValueNode info - let branch_rlc = (a!(acc.rlc), a!(acc.mult)).rlc_chain(RLP_NIL.expr()); + let branch_rlc = (a!(acc.rlc, offset), a!(acc.mult, offset)).rlc_chain(RLP_NIL.expr()); (branch_rlc, branch.num_bytes(meta), branch.is_not_hashed()) }}; @@ -301,7 +339,8 @@ impl BranchConfig { ifx! {not!(branch.is_placeholder()) => { ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { // Hashed branch hash in parent branch - require!((1, rlc, num_bytes, parent_data.rlc) => @"keccak"); + // TODO(Brecht): fix + //require!((1, rlc, num_bytes, parent_data.rlc) => @"keccak"); } elsex { // Non-hashed branch hash in parent branch require!(rlc => parent_data.rlc); @@ -328,15 +367,15 @@ impl BranchConfig { for is_s in [true, false] { branch.set_is_s(is_s); ifx!{branch.is_placeholder() => { - ifx!{a!(ctx.branch.is_drifted, rot) => { - let branch_rlc = ctx.main(!is_s).bytes(meta, rot).rlc(&r); - require!(a!(accs.mod_node_rlc(is_s), rot) => branch_rlc); + ifx!{a!(ctx.branch.is_drifted, offset + rot) => { + let branch_rlc = ctx.main(!is_s).bytes(meta, offset + rot).rlc(&r); + require!(a!(accs.mod_node_rlc(is_s), offset + rot) => branch_rlc); //ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [branch_rlc, false.expr()]); }} } elsex { - ifx!{a!(ctx.branch.is_modified, rot) => { - let branch_rlc = ctx.main(is_s).bytes(meta, rot).rlc(&r); - require!(a!(accs.mod_node_rlc(is_s), rot) => branch_rlc); + ifx!{a!(ctx.branch.is_modified, offset + rot) => { + let branch_rlc = ctx.main(is_s).bytes(meta, offset + rot).rlc(&r); + require!(a!(accs.mod_node_rlc(is_s), offset + rot) => branch_rlc); ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [branch_rlc, false.expr()]); }} }} @@ -362,27 +401,242 @@ impl BranchConfig { // only in branch init). Another alternative would be to have a column where we // add `rlp2` value from the current row in each of the 16 // rows. Both alternative would require additional column. - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, -(ARITY as i32)); + let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, offset - (ARITY as i32)); ifx!{branch.is_placeholder() => { let sum_rlp2 = (0..ARITY).into_iter().fold(0.expr(), |acc, idx| { - acc + a!(ctx.main(is_s).rlp2, -(idx as i32)) + acc + a!(ctx.main(is_s).rlp2, offset - (idx as i32)) }); // There are constraints which ensure there is only 0 or 160 at rlp2 for // branch children. require!(sum_rlp2 => (RLP_HASH_VALUE as u64) * 2); }} } + } + offset += 1; + } + + for is_s in [true, false] { + let rot_s = offset - if is_s { 0 } else { 1 }; + let rot_last_child = rot_s - 1; + + let not_first_level = a!(position_cols.not_first_level, offset); + let ext = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + + ifx!{ext.is_extension() => { + let ext_rlc = DataTransition::from(a!(accs.acc_s.rlc, rot_s), a!(accs.acc_c.rlc, offset)); + + // There are two cases: + // - hashed branch has RLP_HASH_VALUE at c_rlp2 and hash in c_advices, + // - non-hashed branch has 0 at c_rlp2 and all the bytes in c_advices + // TODO(Brecht): why different layout for hashed values? If for hash detection + // just do == 32? + require!(a!(c_main.rlp2, offset) => [0, RLP_HASH_VALUE]); + + // `short` means there is only one nibble in the extension node, `long` means + // there are at least two. `even` means the number of nibbles is + // even, `odd` means the number of nibbles is odd. `c16` means that + // above the branch there are even number of nibbles, `c1` means that above + // the branch there are odd number of nibbles. + let type_selectors_c1 = [ + ext.is_short_c1.expr(), + ext.is_long_even_c1.expr(), + ext.is_long_odd_c1.expr(), + ]; + let type_selectors_c16 = [ + ext.is_short_c16.expr(), + ext.is_long_even_c16.expr(), + ext.is_long_odd_c16.expr(), + ]; + let type_selectors = [type_selectors_c1.clone(), type_selectors_c16.clone()].concat(); + let misc_selectors = [ + ext.is_longer_than_55_s.expr(), + ext.is_ext_not_hashed_s.expr(), + ]; + + // Check that the selectors are boolean + for selector in type_selectors.iter().chain(misc_selectors.iter()) { + require!(selector => bool); + } + // For extension nodes exactly 1 type selector needs to be enabled. + require!(sum::expr(&type_selectors) => 1); + // `is_key_odd` is set using the extension node type selector data. + // (while in case of a regular branch the extension node selectors do not hold this information). + require!(ext.is_key_odd() => not!(sum::expr(&type_selectors_c1))); + require!(ext.is_key_odd() => sum::expr(&type_selectors_c16)); + + // RLP encoding checks: [key, branch] + // In C we have nibbles, we check below only for S. + if is_s { + ifx! {ext.is_longer_than_55_s => { + require!(a!(s_main.rlp1, offset) => RLP_LIST_LONG + 1); + }} + // Verify that the lenghts are consistent. + require!(ext.ext_len(meta, offset) => ext.ext_key_num_bytes(meta, offset) + ext.ext_branch_num_bytes(meta, offset)); + } + + // Calculate the extension node RLC. + // The intermediate RLC after `s_main` bytes needs to be properly computed. + // s_rlp1, s_rlp2, s_bytes need to be the same in both extension rows. + // However, to make space for nibble witnesses, we put nibbles in + // extension row C s_bytes. So we use s_bytes from S row. + // TODO(Brecht): Do we need to store the RLC here? we can just use `rlc` + // directly below... + require!(ext_rlc.prev() => s_main.expr(meta, rot_s).rlc(&r)); + // Update the multiplier with the number of bytes on the first row + let mult = a!(accs.acc_s.mult, offset); + require!((FixedTableTag::RMult, ext.ext_num_bytes_on_key_row(meta, rot_s), mult) => @"fixed"); + + let rlc = ifx! {ext.contains_hashed_branch(meta, offset) => { + c_main.expr(meta, offset)[1..].rlc(&r) + } elsex { + // RLC bytes zero check (+2 because data starts at bytes[0]) + //cb.set_length_c(2.expr() + ext.ext_branch_num_bytes(meta)); + + c_main.expr(meta, offset)[2..].rlc(&r) + }}; + require!(ext_rlc => (ext_rlc.prev(), mult.expr()).rlc_chain(rlc)); + + // We check that the branch hash RLC corresponds to the extension node RLC + // stored in the extension node row. TODO: acc currently doesn't + // have branch ValueNode info (which 128 if nil) + let branch_rlc = ( + a!(accs.acc(is_s).rlc, rot_last_child), + a!(accs.acc(is_s).mult, rot_last_child), + ) + .rlc_chain(RLP_NIL.expr()); + let branch_rlc_in_ext = c_main.bytes(meta, offset).rlc(&r); + ifx! {ext.contains_hashed_branch(meta, offset) => { + // Check that `(branch_rlc, extension_node_hash_rlc`) is in the keccak table. + require!((1, branch_rlc, ext.num_bytes(meta), branch_rlc_in_ext) => @"keccak"); + } elsex { + // Check if the RLC matches + require!(branch_rlc => branch_rlc_in_ext); + }} + + // Update the number of nibbles processed up to this point. + if is_s { + // Calculate the number of bytes + let key_len = ext.ext_key_len(meta, offset); + // Calculate the number of nibbles + let num_nibbles = + get_num_nibbles(meta, key_len.expr(), ext.is_key_part_in_ext_odd()); + // Make sure the nibble counter is updated correctly + let nibbles_count_prev = ifx! {f!(ctx.position_cols.q_not_first), not!(ext.is_below_account(meta)), not_first_level.expr() => { + ext.nibbles_counter().prev() + }}; + require!(ext.nibbles_counter() => nibbles_count_prev.expr() + num_nibbles.expr() + 1.expr()); + } }} + + offset += 1; + } + + offset -= 2; + + let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); + ifx! {branch.is_extension() => { + // RLC bytes zero check + // TODO(Brecht): fix + //cb.set_length(1.expr() + branch.ext_num_bytes_on_key_row(meta, 0)); }} + + offset += 1; + + + let key = ctx.accumulators.key; + let mult_diff = ctx.accumulators.mult_diff; + + let rot_first_child = rot_branch_init + 1; + + let branch = BranchNodeInfo::new(meta, ctx.clone(), false, rot_branch_init); + let modified_index = a!(ctx.branch.modified_index, rot_first_child); + let key_rlc = a!(key.rlc, rot_first_child); + let key_mult = a!(key.mult, rot_first_child); + + // `is_key_odd` needs to be boolean + require!(branch.is_key_odd() => bool); + + // Load the last key values + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 0.expr()); + + // Calculate the extension node key RLC when in an extension node + let key_rlc_post_ext = ifx!{branch.is_extension() => { + let key_rlc_ext = DataTransition::new_with_rot(meta, key.rlc, offset - 1, offset); + // Extension key rlc + let ext_key_rlc = key_data.rlc.expr() + branch.ext_key_rlc(meta, &mut cb.base, key_data.mult.expr(), offset); + // Currently, the extension node S and extension node C both have the same key RLC - + // however, sometimes extension node can be replaced by a shorter extension node + // (in terms of nibbles), this is still to be implemented. + // TODO: extension nodes of different nibbles length + require!(key_rlc_ext => key_rlc_ext.prev()); + // Store it + require!(key_rlc_ext => ext_key_rlc); + ext_key_rlc.expr() + } elsex { + key_data.rlc.expr() + }}; + + // Get the length of the key + let key_num_bytes_for_mult = ifx!{branch.is_extension() => { + // Unless both parts of the key are odd, subtract 1 from the key length. + let key_len = branch.ext_key_len(meta, offset - 1); + key_len - ifx! {not!(key_data.is_odd.expr() * branch.is_key_part_in_ext_odd()) => { 1.expr() }} + }}; + // Get the multiplier for this key length + let mult_diff = a!(mult_diff, rot_first_child); + require!((FixedTableTag::RMult, key_num_bytes_for_mult, mult_diff) => @"fixed"); + + // Now update the key RLC and multiplier for the branch nibble. + let mult = key_data.mult.expr() * mult_diff.expr(); + let (nibble_mult, mult_mult) = ifx!{branch.is_key_odd() => { + // The nibble will be added as the most significant nibble using the same multiplier + (16.expr(), 1.expr()) + } elsex { + // The nibble will be added as the least significant nibble, the multiplier needs to advance + (1.expr(), r[0].expr()) + }}; + require!(key_rlc => key_rlc_post_ext.expr() + modified_index.expr() * nibble_mult.expr() * mult.expr()); + require!(key_mult => mult.expr() * mult_mult.expr()); + + // Update key parity + ifx!{branch.is_extension() => { + // We need to take account the nibbles of the extension node. + // The parity alternates when there's an even number of nibbles, remains the same otherwise + ifx!{branch.is_key_part_in_ext_even() => { + require!(branch.is_key_odd() => not!(key_data.is_odd)); + } elsex { + require!(branch.is_key_odd() => key_data.is_odd); + }} + } elsex { + // The parity simply alternates for regular branches. + require!(branch.is_key_odd() => not!(key_data.is_odd)); + }} + + for is_s in [true, false] { + KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], [ + key_rlc.expr(), + key_mult.expr(), + branch.nibbles_counter().expr(), + branch.is_key_odd(), + branch.contains_placeholder_leaf(meta, true), + branch.contains_placeholder_leaf(meta, false), + ]); + } + + // We need to check that the nibbles we stored in s are between 0 and 15. + //cb.set_range_s(FixedTableTag::RangeKeyLen16.expr()); + + ctx_key_data = Some(key_data); }); BranchConfig { + key_data: ctx_key_data.unwrap(), parent_data_s: ctx_parent_data_s.unwrap(), parent_data_c: ctx_parent_data_c.unwrap(), } } - pub(crate) fn assign_branch_init( + pub(crate) fn assign( &self, region: &mut Region<'_, F>, witness: &[MptWitnessRow], @@ -390,6 +644,11 @@ impl BranchConfig { pv: &mut ProofValues, offset: usize, ) -> Result<(), Error> { + + let base_offset = offset; + let mut offset = offset; + + /* INIT */ let row = &witness[offset]; pv.nibbles_num_prev = pv.nibbles_num; @@ -569,125 +828,161 @@ impl BranchConfig { pv.ext_is_hashed_s = row.get_byte(IS_S_EXT_NODE_NON_HASHED_POS) != 1; pv.ext_is_hashed_c = row.get_byte(IS_C_EXT_NODE_NON_HASHED_POS) != 1; - Ok(()) - } + offset += 1; - pub(crate) fn assign_branch_child( - &self, - region: &mut Region<'_, F>, - witness: &[MptWitnessRow], - mpt_config: &MPTConfig, - pv: &mut ProofValues, - offset: usize, - ) -> Result<(), Error> { - let row = &witness[offset]; + /* CHILD */ - let mut node_mult_diff_s = F::one(); - let mut node_mult_diff_c = F::one(); - - let len = if row.get_byte(S_RLP_START + 1) == 160 { - pv.rlp_len_rem_s -= 33; - 33 - } else if row.get_byte(S_RLP_START + 1) == 0 && row.get_byte(S_START) > 192 { - let len = 1 + (row.get_byte(S_START) as i32 - 192); - pv.rlp_len_rem_s -= len; - len - } else if row.get_byte(S_RLP_START + 1) == 0 { - pv.rlp_len_rem_s -= 1; - 1 - } else { - 0 - }; - for _ in 0..len { - node_mult_diff_s *= mpt_config.randomness; - } + for node_index in 0..ARITY { - let len = if row.get_byte(C_RLP_START + 1) == 160 { - pv.rlp_len_rem_c -= 33; - 33 - } else if row.get_byte(C_RLP_START + 1) == 0 && row.get_byte(C_START) > 192 { - let len = 1 + (row.get_byte(C_START) as i32 - 192); - pv.rlp_len_rem_c -= len; - len - } else if row.get_byte(C_RLP_START + 1) == 0 { - pv.rlp_len_rem_c -= 1; - 1 - } else { - 0 - }; - for _ in 0..len { - node_mult_diff_c *= mpt_config.randomness; - } + let row = &witness[offset]; - region.assign_advice( - || "node_mult_diff_s".to_string(), - mpt_config.accumulators.node_mult_diff_s, - offset, - || Value::known(node_mult_diff_s), - )?; - region.assign_advice( - || "node_mult_diff_c".to_string(), - mpt_config.accumulators.node_mult_diff_c, - offset, - || Value::known(node_mult_diff_c), - )?; + let mut node_mult_diff_s = F::one(); + let mut node_mult_diff_c = F::one(); - if pv.node_index == 0 { - // If it's not extension node, rlc and rlc_mult in extension row - // will be the same as for branch rlc. - pv.extension_node_rlc = pv.key_rlc; - - pv.key_rlc_prev = pv.key_rlc; - pv.key_rlc_mult_prev = pv.key_rlc_mult; - - // Extension node - // We need nibbles here to be able to compute key RLC - if pv.is_extension_node { - // For key RLC, we need to first take into account - // extension node key. - // witness[offset + 16] - let ext_row = &witness[offset + 16]; - let mut key_len_pos = 1; - if ext_row.get_byte(0) == 248 { - key_len_pos = 2; - } + let len = if row.get_byte(S_RLP_START + 1) == 160 { + pv.rlp_len_rem_s -= 33; + 33 + } else if row.get_byte(S_RLP_START + 1) == 0 && row.get_byte(S_START) > 192 { + let len = 1 + (row.get_byte(S_START) as i32 - 192); + pv.rlp_len_rem_s -= len; + len + } else if row.get_byte(S_RLP_START + 1) == 0 { + pv.rlp_len_rem_s -= 1; + 1 + } else { + 0 + }; + for _ in 0..len { + node_mult_diff_s *= mpt_config.randomness; + } - if pv.key_rlc_sel { - // Note: it can't be is_even = 1 && is_short = 1. - if pv.is_even && pv.is_long { - // extension node part: - let key_len = ext_row.get_byte(key_len_pos) as usize - 128 - 1; // -1 because the first byte is 0 (is_even) - mpt_config.compute_acc_and_mult( - &ext_row.bytes, - &mut pv.extension_node_rlc, - &mut pv.key_rlc_mult, - key_len_pos + 2, /* first position behind key_len_pos - * is 0 (because is_even), we start - * with the next one */ - key_len, - ); - pv.mult_diff = F::one(); - for _ in 0..key_len { - pv.mult_diff *= mpt_config.randomness; - } - pv.key_rlc = pv.extension_node_rlc; - // branch part: - pv.key_rlc += - F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; - // key_rlc_mult stays the same - pv.key_rlc_sel = !pv.key_rlc_sel; - } else if pv.is_odd && pv.is_long { - // extension node part: - pv.extension_node_rlc += - F::from((ext_row.get_byte(key_len_pos + 1) - 16) as u64) + let len = if row.get_byte(C_RLP_START + 1) == 160 { + pv.rlp_len_rem_c -= 33; + 33 + } else if row.get_byte(C_RLP_START + 1) == 0 && row.get_byte(C_START) > 192 { + let len = 1 + (row.get_byte(C_START) as i32 - 192); + pv.rlp_len_rem_c -= len; + len + } else if row.get_byte(C_RLP_START + 1) == 0 { + pv.rlp_len_rem_c -= 1; + 1 + } else { + 0 + }; + for _ in 0..len { + node_mult_diff_c *= mpt_config.randomness; + } + + region.assign_advice( + || "node_mult_diff_s".to_string(), + mpt_config.accumulators.node_mult_diff_s, + offset, + || Value::known(node_mult_diff_s), + )?; + region.assign_advice( + || "node_mult_diff_c".to_string(), + mpt_config.accumulators.node_mult_diff_c, + offset, + || Value::known(node_mult_diff_c), + )?; + + if pv.node_index == 0 { + // If it's not extension node, rlc and rlc_mult in extension row + // will be the same as for branch rlc. + pv.extension_node_rlc = pv.key_rlc; + + pv.key_rlc_prev = pv.key_rlc; + pv.key_rlc_mult_prev = pv.key_rlc_mult; + + // Extension node + // We need nibbles here to be able to compute key RLC + if pv.is_extension_node { + // For key RLC, we need to first take into account + // extension node key. + // witness[offset + 16] + let ext_row = &witness[offset + 16]; + let mut key_len_pos = 1; + if ext_row.get_byte(0) == 248 { + key_len_pos = 2; + } + + if pv.key_rlc_sel { + // Note: it can't be is_even = 1 && is_short = 1. + if pv.is_even && pv.is_long { + // extension node part: + let key_len = ext_row.get_byte(key_len_pos) as usize - 128 - 1; // -1 because the first byte is 0 (is_even) + mpt_config.compute_acc_and_mult( + &ext_row.bytes, + &mut pv.extension_node_rlc, + &mut pv.key_rlc_mult, + key_len_pos + 2, /* first position behind key_len_pos + * is 0 (because is_even), we start + * with the next one */ + key_len, + ); + pv.mult_diff = F::one(); + for _ in 0..key_len { + pv.mult_diff *= mpt_config.randomness; + } + pv.key_rlc = pv.extension_node_rlc; + // branch part: + pv.key_rlc += + F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; + // key_rlc_mult stays the same + pv.key_rlc_sel = !pv.key_rlc_sel; + } else if pv.is_odd && pv.is_long { + // extension node part: + pv.extension_node_rlc += + F::from((ext_row.get_byte(key_len_pos + 1) - 16) as u64) + * F::from(16) + * pv.key_rlc_mult; + + let ext_row_c = &witness[offset + 17]; + let key_len = ext_row.get_byte(key_len_pos) as usize - 128; + + pv.mult_diff = F::one(); + for k in 0..key_len - 1 { + let second_nibble = ext_row_c.get_byte(S_START + k); + let first_nibble = + (ext_row.get_byte(key_len_pos + 2 + k) - second_nibble) / 16; + assert_eq!( + first_nibble * 16 + second_nibble, + ext_row.get_byte(key_len_pos + 2 + k), + ); + pv.extension_node_rlc += F::from(first_nibble as u64) * pv.key_rlc_mult; + + pv.key_rlc_mult *= mpt_config.randomness; + pv.mult_diff *= mpt_config.randomness; + + pv.extension_node_rlc += + F::from(second_nibble as u64) * F::from(16) * pv.key_rlc_mult; + } + + pv.key_rlc = pv.extension_node_rlc; + // branch part: + pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; + pv.key_rlc_mult *= mpt_config.randomness; + } else if pv.is_short { + pv.extension_node_rlc += F::from((ext_row.get_byte(1) - 16) as u64) * F::from(16) * pv.key_rlc_mult; - + pv.key_rlc = pv.extension_node_rlc; + // branch part: + pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; + pv.key_rlc_mult *= mpt_config.randomness; + pv.mult_diff = if pv.is_short_c1 { + F::one() + } else { + mpt_config.randomness + }; + } + } else if pv.is_even && pv.is_long { + // extension node part: let ext_row_c = &witness[offset + 17]; - let key_len = ext_row.get_byte(key_len_pos) as usize - 128; + let key_len = ext_row.get_byte(key_len_pos) as usize - 128 - 1; // -1 because the first byte is 0 (is_even) pv.mult_diff = F::one(); - for k in 0..key_len - 1 { + for k in 0..key_len { let second_nibble = ext_row_c.get_byte(S_START + k); let first_nibble = (ext_row.get_byte(key_len_pos + 2 + k) - second_nibble) / 16; @@ -701,254 +996,366 @@ impl BranchConfig { pv.mult_diff *= mpt_config.randomness; pv.extension_node_rlc += - F::from(second_nibble as u64) * F::from(16) * pv.key_rlc_mult; + F::from(16) * F::from(second_nibble as u64) * pv.key_rlc_mult; } pv.key_rlc = pv.extension_node_rlc; // branch part: pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; pv.key_rlc_mult *= mpt_config.randomness; - } else if pv.is_short { - pv.extension_node_rlc += F::from((ext_row.get_byte(1) - 16) as u64) - * F::from(16) - * pv.key_rlc_mult; + pv.key_rlc_sel = !pv.key_rlc_sel; + } else if pv.is_odd && pv.is_long { + pv.extension_node_rlc += + F::from((ext_row.get_byte(key_len_pos + 1) - 16) as u64) * pv.key_rlc_mult; + + pv.key_rlc_mult *= mpt_config.randomness; + + let key_len = ext_row.get_byte(key_len_pos) as usize - 128; + + mpt_config.compute_acc_and_mult( + &ext_row.bytes, + &mut pv.extension_node_rlc, + &mut pv.key_rlc_mult, + key_len_pos + 2, /* the first position after key_len_pos + * is single nibble which is taken into + * account above, we start + * with fourth */ + key_len - 1, // one byte is occupied by single nibble + ); + pv.mult_diff = F::one(); + for _ in 0..key_len { + pv.mult_diff *= mpt_config.randomness; + } pv.key_rlc = pv.extension_node_rlc; // branch part: - pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; + pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; + // key_rlc_mult stays the same + } else if pv.is_short { + pv.extension_node_rlc += + F::from((ext_row.get_byte(1) - 16) as u64) * pv.key_rlc_mult; + + pv.key_rlc = pv.extension_node_rlc; + pv.key_rlc_mult *= mpt_config.randomness; + // branch part: + pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; pv.mult_diff = if pv.is_short_c1 { F::one() } else { mpt_config.randomness }; } - } else if pv.is_even && pv.is_long { - // extension node part: - let ext_row_c = &witness[offset + 17]; - let key_len = ext_row.get_byte(key_len_pos) as usize - 128 - 1; // -1 because the first byte is 0 (is_even) - - pv.mult_diff = F::one(); - for k in 0..key_len { - let second_nibble = ext_row_c.get_byte(S_START + k); - let first_nibble = - (ext_row.get_byte(key_len_pos + 2 + k) - second_nibble) / 16; - assert_eq!( - first_nibble * 16 + second_nibble, - ext_row.get_byte(key_len_pos + 2 + k), - ); - pv.extension_node_rlc += F::from(first_nibble as u64) * pv.key_rlc_mult; - + } else { + if pv.key_rlc_sel { + pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; + // key_rlc_mult stays the same + } else { + pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; pv.key_rlc_mult *= mpt_config.randomness; - pv.mult_diff *= mpt_config.randomness; - - pv.extension_node_rlc += - F::from(16) * F::from(second_nibble as u64) * pv.key_rlc_mult; } - - pv.key_rlc = pv.extension_node_rlc; - // branch part: - pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; - pv.key_rlc_mult *= mpt_config.randomness; pv.key_rlc_sel = !pv.key_rlc_sel; - } else if pv.is_odd && pv.is_long { - pv.extension_node_rlc += - F::from((ext_row.get_byte(key_len_pos + 1) - 16) as u64) * pv.key_rlc_mult; - - pv.key_rlc_mult *= mpt_config.randomness; - - let key_len = ext_row.get_byte(key_len_pos) as usize - 128; - - mpt_config.compute_acc_and_mult( - &ext_row.bytes, - &mut pv.extension_node_rlc, - &mut pv.key_rlc_mult, - key_len_pos + 2, /* the first position after key_len_pos - * is single nibble which is taken into - * account above, we start - * with fourth */ - key_len - 1, // one byte is occupied by single nibble - ); pv.mult_diff = F::one(); - for _ in 0..key_len { - pv.mult_diff *= mpt_config.randomness; - } - pv.key_rlc = pv.extension_node_rlc; - // branch part: - pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; - // key_rlc_mult stays the same - } else if pv.is_short { - pv.extension_node_rlc += - F::from((ext_row.get_byte(1) - 16) as u64) * pv.key_rlc_mult; - - pv.key_rlc = pv.extension_node_rlc; - - pv.key_rlc_mult *= mpt_config.randomness; - // branch part: - pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; - pv.mult_diff = if pv.is_short_c1 { - F::one() - } else { - mpt_config.randomness - }; } + row.assign_branch_row(region, mpt_config, pv, offset)?; } else { - if pv.key_rlc_sel { - pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; - // key_rlc_mult stays the same - } else { - pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; - pv.key_rlc_mult *= mpt_config.randomness; - } - pv.key_rlc_sel = !pv.key_rlc_sel; - pv.mult_diff = F::one(); + row.assign_branch_row(region, mpt_config, pv, offset)?; } - row.assign_branch_row(region, mpt_config, pv, offset)?; - } else { - row.assign_branch_row(region, mpt_config, pv, offset)?; - } - //println!("node index: {} ({})", pv.node_index, offset); + //println!("node index: {} ({})", pv.node_index, offset); - if pv.node_index == 15 { - self.parent_data_s.witness_load( - region, - offset, - &mut pv.memory[parent_memory(true)], - 0, - )?; - self.parent_data_c.witness_load( - region, - offset, - &mut pv.memory[parent_memory(false)], - 0, - )?; - - if !pv.is_branch_s_placeholder { - self.parent_data_s.witness_store( + if pv.node_index == 15 { + self.parent_data_s.witness_load( region, offset, &mut pv.memory[parent_memory(true)], - pv.s_mod_node_hash_rlc, - false, + 0, )?; - } else { - //self.parent_data_s.witness_store(region, offset, &mut - // pv.memory[parent_memory(true)], pv.c_mod_node_hash_rlc, - // false)?; - } - if !pv.is_branch_c_placeholder { - self.parent_data_c.witness_store( + self.parent_data_c.witness_load( region, offset, &mut pv.memory[parent_memory(false)], - pv.c_mod_node_hash_rlc, - false, + 0, )?; - } else { - //self.parent_data_c.witness_store(region, offset, &mut - // pv.memory[parent_memory(false)], pv.s_mod_node_hash_rlc, - // false)?; + + if !pv.is_branch_s_placeholder { + self.parent_data_s.witness_store( + region, + offset, + &mut pv.memory[parent_memory(true)], + pv.s_mod_node_hash_rlc, + false, + )?; + } else { + //self.parent_data_s.witness_store(region, offset, &mut + // pv.memory[parent_memory(true)], pv.c_mod_node_hash_rlc, + // false)?; + } + if !pv.is_branch_c_placeholder { + self.parent_data_c.witness_store( + region, + offset, + &mut pv.memory[parent_memory(false)], + pv.c_mod_node_hash_rlc, + false, + )?; + } else { + //self.parent_data_c.witness_store(region, offset, &mut + // pv.memory[parent_memory(false)], pv.s_mod_node_hash_rlc, + // false)?; + } } - } - /* - `sel1` is to distinguish whether the S node at `modified_node` position is empty. - `sel2` is to distinguish whether the C node at `modified_node` position is empty. - Note that 128 comes from the RLP byte denoting empty leaf. - Having 128 for `*_mod_node_hash_rlc` means there is no node at - this position in branch - for example, - `s_mode_node_hash_rlc = 128` and `c_words` is some other value - when new value is added to the trie - (as opposed to just updating the value). - Note that there is a potential attack if a leaf node - is found with hash `[128, 0, ..., 0]`, - but the probability is negligible. - */ - let mut sel1 = false; - let mut sel2 = false; - if pv.s_mod_node_hash_rlc == F::from(128_u64) { - sel1 = true; - } - if pv.c_mod_node_hash_rlc == F::from(128_u64) { - sel2 = true; - } - pv.is_placeholder_leaf_s = sel1; - pv.is_placeholder_leaf_c = sel2; + /* + `sel1` is to distinguish whether the S node at `modified_node` position is empty. + `sel2` is to distinguish whether the C node at `modified_node` position is empty. + Note that 128 comes from the RLP byte denoting empty leaf. + Having 128 for `*_mod_node_hash_rlc` means there is no node at + this position in branch - for example, + `s_mode_node_hash_rlc = 128` and `c_words` is some other value + when new value is added to the trie + (as opposed to just updating the value). + Note that there is a potential attack if a leaf node + is found with hash `[128, 0, ..., 0]`, + but the probability is negligible. + */ + let mut sel1 = false; + let mut sel2 = false; + if pv.s_mod_node_hash_rlc == F::from(128_u64) { + sel1 = true; + } + if pv.c_mod_node_hash_rlc == F::from(128_u64) { + sel2 = true; + } + pv.is_placeholder_leaf_s = sel1; + pv.is_placeholder_leaf_c = sel2; - region.assign_advice( - || "assign sel1".to_string(), - mpt_config.denoter.sel1, - offset, - || Value::known(F::from(sel1)), - )?; - region.assign_advice( - || "assign sel2".to_string(), - mpt_config.denoter.sel2, - offset, - || Value::known(F::from(sel2)), - )?; + region.assign_advice( + || "assign sel1".to_string(), + mpt_config.denoter.sel1, + offset, + || Value::known(F::from(sel1)), + )?; + region.assign_advice( + || "assign sel2".to_string(), + mpt_config.denoter.sel2, + offset, + || Value::known(F::from(sel2)), + )?; - // reassign (it was assigned to 0 in assign_row) branch_acc and - // branch_mult to proper values + // reassign (it was assigned to 0 in assign_row) branch_acc and + // branch_mult to proper values + + // We need to distinguish between empty and non-empty node: + // empty node at position 1: 0 + // non-empty node at position 1: 160 - // We need to distinguish between empty and non-empty node: - // empty node at position 1: 0 - // non-empty node at position 1: 160 - - let c128 = F::from(128_u64); - let c160 = F::from(160_u64); - - let compute_branch_acc_and_mult = - |branch_acc: &mut F, branch_mult: &mut F, rlp_start: usize, start: usize| { - if row.get_byte(rlp_start + 1) == 0 && row.get_byte(start) == 128 { - *branch_acc += c128 * *branch_mult; - *branch_mult *= mpt_config.randomness; - } else if row.get_byte(rlp_start + 1) == 160 { - *branch_acc += c160 * *branch_mult; - *branch_mult *= mpt_config.randomness; - for i in 0..HASH_WIDTH { - *branch_acc += F::from(row.get_byte(start + i) as u64) * *branch_mult; + let c128 = F::from(128_u64); + let c160 = F::from(160_u64); + + let compute_branch_acc_and_mult = + |branch_acc: &mut F, branch_mult: &mut F, rlp_start: usize, start: usize| { + if row.get_byte(rlp_start + 1) == 0 && row.get_byte(start) == 128 { + *branch_acc += c128 * *branch_mult; + *branch_mult *= mpt_config.randomness; + } else if row.get_byte(rlp_start + 1) == 160 { + *branch_acc += c160 * *branch_mult; *branch_mult *= mpt_config.randomness; + for i in 0..HASH_WIDTH { + *branch_acc += F::from(row.get_byte(start + i) as u64) * *branch_mult; + *branch_mult *= mpt_config.randomness; + } + } else { + *branch_acc += F::from(row.get_byte(start) as u64) * *branch_mult; + *branch_mult *= mpt_config.randomness; + let len = row.get_byte(start) as usize - 192; + for i in 0..len { + *branch_acc += F::from(row.get_byte(start + 1 + i) as u64) * *branch_mult; + *branch_mult *= mpt_config.randomness; + } + } + }; + + // TODO: add branch ValueNode info + + compute_branch_acc_and_mult(&mut pv.acc_s, &mut pv.acc_mult_s, S_RLP_START, S_START); + compute_branch_acc_and_mult(&mut pv.acc_c, &mut pv.acc_mult_c, C_RLP_START, C_START); + mpt_config.assign_acc( + region, + pv.acc_s, + pv.acc_mult_s, + pv.acc_c, + pv.acc_mult_c, + offset, + )?; + + // This is to avoid Poisoned Constraint in extension_node_key. + region.assign_advice( + || "assign key_rlc".to_string(), + mpt_config.accumulators.key.rlc, + offset, + || Value::known(pv.key_rlc), + )?; + region.assign_advice( + || "assign key_rlc_mult".to_string(), + mpt_config.accumulators.key.mult, + offset, + || Value::known(pv.key_rlc_mult), + )?; + + pv.node_index += 1; + + offset += 1; + } + + /*let row = &witness[offset]; + if row.get_type() == MptWitnessRowType::AccountLeafNeighbouringLeaf { + println!("[{}] reset", offset); + //account_leaf.is_in_added_branch = true; + pv.key_rlc = F::zero(); // account address until here, storage key from here on + pv.key_rlc_mult = F::one(); + pv.key_rlc_prev = F::zero(); + pv.key_rlc_mult_prev = F::one(); + pv.nibbles_num_prev = 0; + pv.key_rlc_sel = true; + pv.nibbles_num = 0; + }*/ + + /* EXTENSION */ + + if pv.is_extension_node { + println!("[{}] extension", base_offset); + for is_s in [true, false] { + let row = &witness[offset]; + if is_s { + // [228,130,0,149,160,114,253,150,133,18,192,156,19,241,162,51,210,24,1,151,16, + // 48,7,177,42,60,49,34,230,254,242,79,132,165,90,75,249] + + // One nibble: + // [226,16,160,172,105,12... + // Could also be non-hashed branch: + // [223,16,221,198,132,32,0,0,0,1,198,132,32,0,0,0,1,128,128,128,128,128,128, + // 128,128,128,128,128,128,128,128,128] + + // [247,160,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + // 213,128,194,32,1,128,194,32,1,128,128,128,128,128,128,128,128,128,128,128, + // 128,128] [248,58,159,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + // 0,0,0,0,0,0,0,0,0,0,0,0,217,128,196,130,32,0,1,128,196,130,32,0,1,128,128, + // 128,128,128,128,128,128,128,128,128,128,128] + + // Intermediate RLC value and mult (after key) + // to know which mult we need to use in c_advices. + pv.acc_s = F::zero(); + pv.acc_mult_s = F::one(); + let len: usize; + if row.get_byte(1) <= 32 { + // key length is 1 + len = 2 // [length byte, key] + } else if row.get_byte(0) < 248 { + len = (row.get_byte(1) - 128) as usize + 2; + } else { + len = (row.get_byte(2) - 128) as usize + 3; } + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_s, + &mut pv.acc_mult_s, + 0, + len, + ); + + // Final RLC value. + pv.acc_c = pv.acc_s; + pv.acc_mult_c = pv.acc_mult_s; + let mut start = C_RLP_START + 1; + let mut len = HASH_WIDTH + 1; + if row.get_byte(C_RLP_START + 1) == 0 { + // non-hashed branch in extension node + start = C_START; + len = HASH_WIDTH; + } + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_c, + &mut pv.acc_mult_c, + start, + len, + ); + + mpt_config + .assign_acc(region, pv.acc_s, pv.acc_mult_s, pv.acc_c, F::zero(), offset) + .ok(); } else { - *branch_acc += F::from(row.get_byte(start) as u64) * *branch_mult; - *branch_mult *= mpt_config.randomness; - let len = row.get_byte(start) as usize - 192; - for i in 0..len { - *branch_acc += F::from(row.get_byte(start + 1 + i) as u64) * *branch_mult; - *branch_mult *= mpt_config.randomness; + self.key_data + .witness_load(region, base_offset, &pv.memory[key_memory(true)], 0)?; + for is_s in [true, false] { + self.key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + pv.key_rlc, + pv.key_rlc_mult, + pv.nibbles_num, + pv.is_placeholder_leaf_s, + pv.is_placeholder_leaf_c, + )?; } - } - }; - // TODO: add branch ValueNode info + // We use intermediate value from previous row (because + // up to acc_s it's about key and this is the same + // for both S and C). + pv.acc_c = pv.acc_s; + pv.acc_mult_c = pv.acc_mult_s; + let mut start = C_RLP_START + 1; + let mut len = HASH_WIDTH + 1; + if row.get_byte(C_RLP_START + 1) == 0 { + // non-hashed branch in extension node + start = C_START; + len = HASH_WIDTH; + } + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_c, + &mut pv.acc_mult_c, + start, + len, + ); - compute_branch_acc_and_mult(&mut pv.acc_s, &mut pv.acc_mult_s, S_RLP_START, S_START); - compute_branch_acc_and_mult(&mut pv.acc_c, &mut pv.acc_mult_c, C_RLP_START, C_START); - mpt_config.assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - pv.acc_c, - pv.acc_mult_c, - offset, - )?; + mpt_config + .assign_acc(region, pv.acc_s, pv.acc_mult_s, pv.acc_c, F::zero(), offset) + .ok(); + } + region + .assign_advice( + || "assign key_rlc".to_string(), + mpt_config.accumulators.key.rlc, + offset, + || Value::known(pv.extension_node_rlc), + ) + .ok(); + + offset += 1; + } + } else { - // This is to avoid Poisoned Constraint in extension_node_key. - region.assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(pv.key_rlc), - )?; - region.assign_advice( - || "assign key_rlc_mult".to_string(), - mpt_config.accumulators.key.mult, - offset, - || Value::known(pv.key_rlc_mult), - )?; + offset += 1; + + self.key_data + .witness_load(region, base_offset, &pv.memory[key_memory(true)], 0)?; + for is_s in [true, false] { + self.key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + pv.key_rlc, + pv.key_rlc_mult, + pv.nibbles_num, + pv.is_placeholder_leaf_s, + pv.is_placeholder_leaf_c, + )?; + } + } - pv.node_index += 1; + println!("offset: {}", offset); Ok(()) } diff --git a/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs b/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs index 740672bc4b..600aa8f0d5 100644 --- a/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs +++ b/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs @@ -8,7 +8,7 @@ use halo2_proofs::{ use crate::{ circuit, circuit_tools::{CellManager, DataTransition}, - mpt_circuit::{helpers::BranchNodeInfo, param::BRANCH_ROWS_NUM}, + mpt_circuit::{helpers::{BranchNodeInfo, key_memory}, param::BRANCH_ROWS_NUM}, mpt_circuit::{ helpers::KeyData, witness_row::MptWitnessRow, MPTConfig, MPTContext, ProofValues, }, @@ -160,7 +160,7 @@ impl BranchKeyConfig { require!(branch.is_key_odd() => bool); // Load the last key values - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], 0.expr()); + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 0.expr()); // Calculate the extension node key RLC when in an extension node let key_rlc_post_ext = ifx!{branch.is_extension() => { @@ -215,14 +215,16 @@ impl BranchKeyConfig { require!(branch.is_key_odd() => not!(key_data.is_odd)); }} - KeyData::store(&mut cb.base, &ctx.memory["key"], [ - key_rlc.expr(), - key_mult.expr(), - branch.nibbles_counter().expr(), - branch.is_key_odd(), - branch.contains_placeholder_leaf(meta, true), - branch.contains_placeholder_leaf(meta, false), - ]); + for is_s in [true, false] { + KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], [ + key_rlc.expr(), + key_mult.expr(), + branch.nibbles_counter().expr(), + branch.is_key_odd(), + branch.contains_placeholder_leaf(meta, true), + branch.contains_placeholder_leaf(meta, false), + ]); + } // We need to check that the nibbles we stored in s are between 0 and 15. cb.set_range_s(FixedTableTag::RangeKeyLen16.expr()); @@ -255,17 +257,19 @@ impl BranchKeyConfig { offset: usize, ) -> Result<(), Error> { self.key_data - .witness_load(region, offset, &pv.memory["key"], 0)?; - self.key_data.witness_store( - region, - offset, - &mut pv.memory["key"], - pv.key_rlc, - pv.key_rlc_mult, - pv.nibbles_num, - pv.is_placeholder_leaf_s, - pv.is_placeholder_leaf_c, - )?; + .witness_load(region, offset, &pv.memory[key_memory(true)], 0)?; + for is_s in [true, false] { + self.key_data.witness_store( + region, + offset, + &mut pv.memory[key_memory(is_s)], + pv.key_rlc, + pv.key_rlc_mult, + pv.nibbles_num, + pv.is_placeholder_leaf_s, + pv.is_placeholder_leaf_c, + )?; + } Ok(()) } } diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index 614852bc3c..2810513178 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -160,7 +160,7 @@ impl KeyData { ) -> Result<(), Error> { let values = memory.witness_load(load_offset); - //println!("offset: {}", offset); + //println!("offset: {}, values: {:?}", offset, values); //println!("key_rlc_prev: {:?}", pv.key_rlc_prev); //println!("key_mult_prev: {:?}", pv.key_rlc_mult_prev); //println!("nibbles_num_prev: {:?}", pv.nibbles_num_prev); @@ -580,25 +580,16 @@ impl BranchNodeInfo { } /// Number of bytes in the extension node - /// Uses data on the current row! - pub(crate) fn ext_num_bytes(&self, meta: &mut VirtualCells) -> Expression { - let rot_s = if self.is_s { 0 } else { -1 }; - self.ext_num_rlp_bytes(meta) + self.ext_len(meta, rot_s) - } - - /// Number of bytes in the extension node - /// Uses data on the current row! - pub(crate) fn ext_num_bytes2(&self, meta: &mut VirtualCells) -> Expression { - self.ext_num_rlp_bytes(meta) + self.ext_len(meta, 1) + pub(crate) fn ext_num_bytes(&self, meta: &mut VirtualCells, rot_c: i32) -> Expression { + self.ext_num_rlp_bytes(meta) + self.ext_len(meta, rot_c) } /// Length of the extension node (excluding RLP bytes) - /// Uses data on the current row! - pub(crate) fn ext_len(&self, _meta: &mut VirtualCells, rel_rot: i32) -> Expression { + pub(crate) fn ext_len(&self, _meta: &mut VirtualCells, rot_c: i32) -> Expression { circuit!([_meta, _cb!()], { matchx! { - self.is_short() + self.is_long() => get_len_list_short(a!(self.ctx.s_main.rlp1, rel_rot)), - self.is_longer_than_55_s => get_len_short(a!(self.ctx.s_main.bytes[0], rel_rot)), + self.is_short() + self.is_long() => get_len_list_short(a!(self.ctx.s_main.rlp1, rot_c)), + self.is_longer_than_55_s => get_len_short(a!(self.ctx.s_main.bytes[0], rot_c)), } }) } @@ -652,27 +643,27 @@ impl BranchNodeInfo { /// Length of the included branch (excluding RLP bytes) /// Uses data on the current row! - pub(crate) fn ext_branch_len(&self, meta: &mut VirtualCells) -> Expression { + pub(crate) fn ext_branch_len(&self, meta: &mut VirtualCells, rot_ext_s: i32) -> Expression { circuit!([meta, _cb!()], { - ifx! {self.contains_hashed_branch(meta) => { + ifx! {self.contains_hashed_branch(meta, rot_ext_s) => { 32.expr() } elsex { - get_len_list_short(a!(self.ctx.c_main.bytes[0])) + get_len_list_short(a!(self.ctx.c_main.bytes[0], rot_ext_s)) }} }) } /// Length of the included branch (excluding RLP bytes) /// Uses data on the current row! - pub(crate) fn ext_branch_num_bytes(&self, meta: &mut VirtualCells) -> Expression { - 1.expr() + self.ext_branch_len(meta) + pub(crate) fn ext_branch_num_bytes(&self, meta: &mut VirtualCells, rot_ext_s: i32) -> Expression { + 1.expr() + self.ext_branch_len(meta, rot_ext_s) } /// Length of the key (excluding RLP bytes) /// Uses data on the current row! - pub(crate) fn contains_hashed_branch(&self, meta: &mut VirtualCells) -> Expression { + pub(crate) fn contains_hashed_branch(&self, meta: &mut VirtualCells, rot_ext_s: i32) -> Expression { circuit!([meta, _cb!()], { - a!(self.ctx.c_main.rlp2) * invert!(RLP_HASH_VALUE) + a!(self.ctx.c_main.rlp2, rot_ext_s) * invert!(RLP_HASH_VALUE) }) } @@ -682,6 +673,7 @@ impl BranchNodeInfo { meta: &mut VirtualCells, cb: &mut ConstraintBuilder, key_mult_prev: Expression, + rot_ext_c: i32, ) -> Expression { circuit!([meta, cb], { let mult_first_odd = ifx! {self.is_key_odd() => { 1.expr() } elsex { 16.expr() }}; @@ -707,10 +699,10 @@ impl BranchNodeInfo { // the two keys being the same - update operation, not splitting into extension node. // So, we do not need to look further than `s_main.bytes` even if `s_main.bytes[0]` // is not used (when even number of nibbles). - let mut key_bytes = vec![a!(self.ctx.s_main.bytes[0], -1)]; + let mut key_bytes = vec![a!(self.ctx.s_main.bytes[0], rot_ext_c - 1)]; key_bytes.append(&mut self.ctx.s_main.bytes.iter().skip(1).zip(self.ctx.s_main.bytes.iter()).map(|(byte, byte_hi)| { - let byte = a!(byte, -1); - let nibble_hi = a!(byte_hi); + let byte = a!(byte, rot_ext_c - 1); + let nibble_hi = a!(byte_hi, rot_ext_c); let nibble_lo = (byte.expr() - nibble_hi.expr()) * invert!(16); // Check that `nibble_hi` is correct. require!(byte => nibble_lo.expr() * 16.expr() + nibble_hi.expr()); @@ -721,11 +713,11 @@ impl BranchNodeInfo { }, self.is_long_odd_c16.expr() + self.is_long_even_c16.expr() => { let additional_mult = ifx! {self.is_long_odd_c16 => { self.ctx.r[0].expr() } elsex { 1.expr() }}; - let key_bytes = self.ctx.s_main.bytes(meta, -1); + let key_bytes = self.ctx.s_main.bytes(meta, rot_ext_c - 1); calc_rlc(meta, cb, &key_bytes, additional_mult) }, self.is_short() => { - let key_bytes = vec![a!(self.ctx.s_main.rlp2, -1)]; + let key_bytes = vec![a!(self.ctx.s_main.rlp2, rot_ext_c - 1)]; calc_rlc(meta, cb, &key_bytes, 1.expr()) }, } @@ -776,9 +768,9 @@ impl BranchChildInfo { ifx! {self.is_hashed(meta) => { // There is `s_rlp2 = 0` when there is a nil node and `s_rlp2 = 160` when // non-nil node (1 or 33 respectively). - a!(self.ctx.main(self.is_s).rlp2) * invert!(RLP_HASH_VALUE) * 32.expr() + 1.expr() + a!(self.ctx.main(self.is_s).rlp2, self.rot_branch) * invert!(RLP_HASH_VALUE) * 32.expr() + 1.expr() } elsex { - get_num_bytes_list_short(a!(self.ctx.main(self.is_s).bytes[0])) + get_num_bytes_list_short(a!(self.ctx.main(self.is_s).bytes[0], self.rot_branch)) }} }) } @@ -807,7 +799,7 @@ impl BranchChildInfo { main.expr(meta, self.rot_branch)[2..34].rlc(&r) } elsex { ifx!{self.is_empty(meta) => { - require!(a!(main.bytes[0]) => RLP_NIL); + require!(a!(main.bytes[0], self.rot_branch) => RLP_NIL); // There's only one byte (128 at `bytes[0]`) that needs to be added to the RLC. main.expr(meta, self.rot_branch)[2..3].rlc(&r) } elsex { @@ -1205,7 +1197,6 @@ impl AccountLeafInfo { .rlc(&self.ctx.r) } - // Will use data on the current row! pub(crate) fn key_rlc( &self, meta: &mut VirtualCells, @@ -1379,6 +1370,10 @@ pub(crate) fn parent_memory(is_s: bool) -> String { (if is_s { "parent_s" } else { "parent_c" }).to_string() } +pub(crate) fn key_memory(is_s: bool) -> String { + (if is_s { "key_s" } else { "key_c" }).to_string() +} + /// MPTConstraintBuilder pub struct MPTConstraintBuilder { pub base: ConstraintBuilder, diff --git a/zkevm-circuits/src/mpt_circuit/selectors.rs b/zkevm-circuits/src/mpt_circuit/selectors.rs index 8150a04b85..938ef0e160 100644 --- a/zkevm-circuits/src/mpt_circuit/selectors.rs +++ b/zkevm-circuits/src/mpt_circuit/selectors.rs @@ -131,7 +131,7 @@ impl SelectorsConfig { require!(sum::expr(row_type_selectors.iter()) => 1); // The type of the proof needs to be set. - require!(sum::expr(proof_type_selectors.iter()) => 1); + /*require!(sum::expr(proof_type_selectors.iter()) => 1); // We need to prevent lookups into non-lookup rows and we need to prevent for // example nonce lookup into balance lookup row. @@ -158,7 +158,7 @@ impl SelectorsConfig { require!(proof_type_id => 0); }} }} - } + }*/ }}; // First row diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs index e456eb7705..d1c414f277 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs @@ -7,14 +7,14 @@ use halo2_proofs::{ use crate::{ circuit, - circuit_tools::{CellManager, DataTransition, RLCable, RLCChainable, ConstraintBuilder, CellType}, + circuit_tools::{CellManager, DataTransition, RLCable, RLCChainable, ConstraintBuilder, CellType, Cell}, mpt_circuit::{ helpers::BranchNodeInfo, param::{BRANCH_ROWS_NUM, S_START}, }, mpt_circuit::{ - helpers::{KeyData, MPTConstraintBuilder, StorageLeafInfo, get_num_bytes_short, ParentData, parent_memory, get_parent_rlc_state}, - param::{KEY_LEN_IN_NIBBLES, EMPTY_TRIE_HASH}, + helpers::{KeyData, MPTConstraintBuilder, StorageLeafInfo, get_num_bytes_short, ParentData, parent_memory, get_parent_rlc_state, key_memory}, + param::{KEY_LEN_IN_NIBBLES, EMPTY_TRIE_HASH, HASH_WIDTH, IS_STORAGE_MOD_POS, LEAF_NON_EXISTING_IND, LEAF_KEY_C_IND, IS_NON_EXISTING_STORAGE_POS}, FixedTableTag, }, mpt_circuit::{ @@ -26,7 +26,12 @@ use crate::{ #[derive(Clone, Debug)] pub(crate) struct LeafCombinedConfig { - key_data: KeyData, + key_data_s: KeyData, + key_data_c: KeyData, + key_data_w: KeyData, + parent_data_s: ParentData, + parent_data_c: ParentData, + diff_inv: Cell, } impl LeafCombinedConfig { @@ -52,23 +57,26 @@ impl LeafCombinedConfig { let rot_value_c = 3; let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); - let mut ctx_key_data: Option> = None; + let mut ctx_key_data_c: Option> = None; + let mut ctx_key_data_s: Option> = None; + let mut ctx_key_data_w: Option> = None; + let mut ctx_parent_data_s: Option> = None; + let mut ctx_parent_data_c: Option> = None; + let mut ctx_diff_inv: Option> = None; + circuit!([meta, cb.base], { let mut branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); let mut offset = 0; for is_s in [true, false] { - //cb.base.set_query_offset(offset); let storage = StorageLeafInfo::new(meta, ctx.clone(), is_s, offset); - //storage.set_is_s(is_s); - //storage.set_rot_key(offset); branch.set_is_s(is_s); // Load the last key values, which depends on the branch being a placeholder. let is_branch_placeholder = ifx! {not!(storage.is_below_account(meta)) => { branch.is_placeholder() }}; let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], load_offset); + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(is_s)], load_offset); // The two flag values need to be boolean. require!(storage.flag1 => bool); @@ -105,6 +113,15 @@ impl LeafCombinedConfig { // RLC bytes zero check //cb.set_length(num_bytes.expr()); + // Key done, set the default values + KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], KeyData::default_values()); + + if is_s { + ctx_key_data_s = Some(key_data); + } else { + ctx_key_data_c = Some(key_data); + } + offset += 1; let is_long = a!(accs.s_mod_node_rlc, offset); @@ -194,19 +211,22 @@ impl LeafCombinedConfig { }} }} // Store the new parent - /*ParentData::store( + ParentData::store( &mut cb.base, &ctx.memory[parent_memory(is_s)], [0.expr(), true.expr()], ); - ctx_parent_data = Some(parent_data); // Set the number of bytes used - cb.set_length_s(value_num_bytes);*/ + //cb.set_length_s(value_num_bytes); offset += 1; - ctx_key_data = Some(key_data); + if is_s { + ctx_parent_data_s = Some(parent_data); + } else { + ctx_parent_data_c = Some(parent_data); + } } @@ -294,7 +314,7 @@ impl LeafCombinedConfig { let diff_inv = cm.query_cell(CellType::Storage); ifx! {a!(ctx.proof_type.is_non_existing_storage_proof, offset) => { // Get the previous key RLC data - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory["key"], 2.expr()); + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 1.expr()); ifx! {is_wrong_leaf => { // Calculate the key and check it's the address as requested in the lookup let key_rlc_wrong = key_data.rlc.expr() + storage.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), false, offset - rot_key_c); @@ -312,20 +332,439 @@ impl LeafCombinedConfig { // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. require!(key_data.is_placeholder_leaf_c => true); }} - ctx_key_data = Some(key_data); + ctx_key_data_w = Some(key_data); } elsex { // is_wrong_leaf needs to be false when not in non_existing_account proof require!(is_wrong_leaf => false); }} - - // Key done, set the default values - //KeyData::store(&mut cb.base, &ctx.memory["key"], KeyData::default_values()); - - cb.base.set_query_offset(0); + ctx_diff_inv = Some(diff_inv); }); LeafCombinedConfig { - key_data: ctx_key_data.unwrap(), + key_data_s: ctx_key_data_s.unwrap(), + key_data_c: ctx_key_data_c.unwrap(), + key_data_w: ctx_key_data_w.unwrap(), + parent_data_s: ctx_parent_data_s.unwrap(), + parent_data_c: ctx_parent_data_c.unwrap(), + diff_inv: ctx_diff_inv.unwrap(), + } + } + + pub fn assign( + &self, + region: &mut Region<'_, F>, + mpt_config: &MPTConfig, + witness: &[MptWitnessRow], + pv: &mut ProofValues, + offset: usize, + ) -> Result<(), Error> { + + println!("offset: {}", offset); + + let base_offset = offset; + let mut offset = offset; + + for is_s in [true, false] { + + /* KEY */ + + { + let row = &witness[offset]; + + // Info whether leaf rlp is long or short: + // - long means the key length is at position 2. + // - short means the key length is at position 1. + let mut typ = "short"; + if row.get_byte(0) == 248 { + typ = "long"; + } else if row.get_byte(1) == 32 { + typ = "last_level"; + } else if row.get_byte(1) < 128 { + typ = "one_nibble"; + } + mpt_config.assign_long_short(region, typ, offset).ok(); + + pv.acc_s = F::zero(); + pv.acc_mult_s = F::one(); + let len: usize; + if typ == "long" { + len = (row.get_byte(2) - 128) as usize + 3; + } else if typ == "short" { + len = (row.get_byte(1) - 128) as usize + 2; + } else { + // last_level or one_nibble + len = 2 + } + mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); + + mpt_config + .assign_acc( + region, + pv.acc_s, + pv.acc_mult_s, + F::zero(), + F::zero(), + offset, + ) + .ok(); + + // note that this assignment needs to be after assign_acc call + if row.get_byte(0) < 223 { + // when shorter than 32 bytes, the node doesn't get hashed + // not_hashed + region + .assign_advice( + || "assign not_hashed".to_string(), + mpt_config.accumulators.acc_c.rlc, + offset, + || Value::known(F::one()), + ) + .ok(); + } + + // TODO: handle if branch or extension node is added + let mut start = S_START - 1; + if row.get_byte(0) == 248 { + // long RLP + start = S_START; + } + + let is_branch_placeholder = if is_s { + pv.is_branch_s_placeholder + } else { + pv.is_branch_c_placeholder + }; + let load_offset = if is_branch_placeholder { 1 } else { 0 }; + + let key_data = if is_s { &self.key_data_s } else { &self.key_data_c }; + key_data + .witness_load(region, base_offset, &mut pv.memory[key_memory(is_s)], load_offset)?; + key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + F::zero(), + F::one(), + 0, + false, + false, + )?; + + // For leaf S and leaf C we need to start with the same rlc. + let mut key_rlc_new = pv.key_rlc; + let mut key_rlc_mult_new = pv.key_rlc_mult; + if (pv.is_branch_s_placeholder && row.get_type() == MptWitnessRowType::StorageLeafSKey) + || (pv.is_branch_c_placeholder && row.get_type() == MptWitnessRowType::StorageLeafCKey) + { + key_rlc_new = pv.key_rlc_prev; + key_rlc_mult_new = pv.key_rlc_mult_prev; + } + if typ != "last_level" && typ != "one_nibble" { + // If in last level or having only one nibble, + // the key RLC is already computed using the first two bytes above. + mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, start); + } + region.assign_advice( + || "assign key_rlc".to_string(), + mpt_config.accumulators.key.rlc, + offset, + || Value::known(key_rlc_new), + )?; + pv.storage_key_rlc = key_rlc_new; + + // Store key_rlc into rlc2 to be later set in leaf value C row (to enable + // lookups): + pv.rlc2 = key_rlc_new; + } + + + + /* VALUE */ + + offset += 1; + println!("offset value: {}", offset); + + { + + let row_prev = &witness[offset - 1]; + let row = &witness[offset]; + + // Info whether leaf value is 1 byte or more: + let mut is_long = false; + if row_prev.get_byte(0) == 248 { + // whole leaf is in long format (3 RLP meta bytes) + let key_len = row_prev.get_byte(2) - 128; + if row_prev.get_byte(1) - key_len - 1 > 1 { + is_long = true; + } + } else if row_prev.get_byte(1) < 128 { + // last_level or one_nibble + let leaf_len = row_prev.get_byte(0) - 192; + if leaf_len - 1 > 1 { + is_long = true; + } + } else { + let leaf_len = row_prev.get_byte(0) - 192; + let key_len = row_prev.get_byte(1) - 128; + if leaf_len - key_len - 1 > 1 { + is_long = true; + } + } + // Short means there is only one byte for value (no RLP specific bytes). + // Long means there is more than one byte for value which brings two + // RLP specific bytes, like: 161 160 ... for 32-long value. + let mut typ = "short"; + if is_long { + typ = "long"; + } + mpt_config.assign_long_short(region, typ, offset).ok(); + + // Leaf RLC + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_s, + &mut pv.acc_mult_s, + 0, + HASH_WIDTH + 2, + ); + + pv.acc_c = F::zero(); + pv.acc_mult_c = F::one(); + // Leaf value RLC + let mut start = 0; + if is_long { + start = 2; + } + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_c, + &mut pv.acc_mult_c, + start, + HASH_WIDTH + 2, + ); + + let empty_trie_hash: Vec = vec![ + 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, + 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, + ]; + if is_s { + // Store leaf value RLC into rlc1 to be later set in leaf value C row (to enable + // lookups): + pv.rlc1 = pv.acc_c; + + /* + account leaf storage codehash S <- rotate here + account leaf storage codehash C + account leaf in added branch + leaf key S + leaf value S <- we are here + leaf key C + leaf value C + */ + let row_prev = &witness[offset - 4]; + if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashS + && row_prev.s_hash_bytes() == empty_trie_hash + { + // Leaf is without branch and it is just a placeholder. + region + .assign_advice( + || "assign sel1".to_string(), + mpt_config.denoter.sel1, + offset, + || Value::known(F::one()), + ) + .ok(); + } + } else { + region + .assign_advice( + || "assign key_rlc into key_rlc_mult".to_string(), + mpt_config.accumulators.key.mult, + offset, + || Value::known(pv.rlc2), + ) + .ok(); + region + .assign_advice( + || "assign leaf value S into value_prev".to_string(), + mpt_config.value_prev, + offset, + || Value::known(pv.rlc1), + ) + .ok(); + + /* + account leaf storage codehash S + account leaf storage codehash C <- rotate here + account leaf in added branch + leaf key S + leaf value S + leaf key C + leaf value C <- we are here + */ + let row_prev = &witness[offset - 5]; + if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashC + && row_prev.s_hash_bytes() == empty_trie_hash + { + // Leaf is without branch and it is just a placeholder. + region + .assign_advice( + || "assign sel2".to_string(), + mpt_config.denoter.sel2, + offset, + || Value::known(F::one()), + ) + .ok(); + } + } + + let parent_data = if is_s { &self.parent_data_s } else { &self.parent_data_c }; + parent_data + .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) + .ok(); + parent_data + .witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + F::zero(), + true, + ) + .ok(); + + mpt_config + .assign_acc( + region, + pv.acc_s, // leaf RLC + pv.acc_mult_s, + pv.acc_c, // leaf value RLC + F::zero(), + offset, + ) + .ok(); + + region + .assign_advice( + || "assign leaf value C into value".to_string(), + mpt_config.value, + offset, + || Value::known(pv.acc_c), + ) + .ok(); + + if !is_s && row.get_byte_rev(IS_STORAGE_MOD_POS) == 1 { + region + .assign_advice( + || "assign lookup enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(6_u64)), /* storage mod lookup enabled in this row + * if it is is_storage_mod proof */ + ) + .ok(); + } + } + + offset += 1; } + + { + let row = &witness[offset]; + + /* + row[1] != 0 just to avoid usize problems below (when row doesn't + need to be assigned) Info whether leaf rlp is long or short. + */ + /* + Info whether leaf rlp is long or short: + - long means the key length is at position 2. + - short means the key length is at position 1. + */ + let mut typ = "short"; + if row.get_byte(0) == 248 { + typ = "long"; + } else if row.get_byte(1) == 32 { + typ = "last_level"; + } else if row.get_byte(1) < 128 { + typ = "one_nibble"; + } + mpt_config.assign_long_short(region, typ, offset).ok(); + + pv.acc_s = F::zero(); + pv.acc_mult_s = F::one(); + let len: usize; + if typ == "long" { + len = (row.get_byte(2) - 128) as usize + 3; + } else if typ == "short" { + len = (row.get_byte(1) - 128) as usize + 2; + } else { + // last_level or one_nibble + len = 2 + } + mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); + + mpt_config + .assign_acc( + region, + pv.acc_s, + pv.acc_mult_s, + F::zero(), + F::zero(), + offset, + ) + .ok(); + + offset += 1; + } + + { + self.key_data_w + .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) + .ok(); + + let row = &witness[offset]; + if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { + let row_key_c = &witness[offset - (LEAF_NON_EXISTING_IND - LEAF_KEY_C_IND) as usize]; + let mut start = S_START - 1; + if row_key_c.get_byte(0) == 248 { + start = S_START; + } + let mut key_rlc_new = pv.key_rlc; + let mut key_rlc_mult_new = pv.key_rlc_mult; + mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, start); + region + .assign_advice( + || "assign key_rlc".to_string(), + mpt_config.accumulators.key.mult, // lookup uses `key.mult` + offset, + || Value::known(key_rlc_new), + ) + .ok(); + + let diff_inv = (key_rlc_new - pv.storage_key_rlc) + .invert() + .unwrap_or(F::zero()); + self.diff_inv + .assign(region, base_offset, Value::known(diff_inv)) + .ok(); + + if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { + region + .assign_advice( + || "assign lookup enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(7_u64)), /* non existing storage lookup enabled in + * this row if it is non_existing_storage + * proof */ + ) + .ok(); + } + } + } + + println!("offset post: {}", offset); + + Ok(()) } } diff --git a/zkevm-circuits/src/mpt_circuit/witness_row.rs b/zkevm-circuits/src/mpt_circuit/witness_row.rs index b0976bf785..7275d9665e 100644 --- a/zkevm-circuits/src/mpt_circuit/witness_row.rs +++ b/zkevm-circuits/src/mpt_circuit/witness_row.rs @@ -154,49 +154,6 @@ impl MptWitnessRow { || Value::known(F::from(branch.is_branch_child as u64)), )?; - region.assign_advice( - || "assign acc_s".to_string(), - mpt_config.accumulators.acc_s.rlc, - offset, - || Value::known(F::zero()), - )?; - - region.assign_advice( - || "assign acc_mult_s".to_string(), - mpt_config.accumulators.acc_s.mult, - offset, - || Value::known(F::zero()), - )?; - - region.assign_advice( - || "assign acc_c".to_string(), - mpt_config.accumulators.acc_c.rlc, - offset, - || Value::known(F::zero()), - )?; - - region.assign_advice( - || "assign acc_mult_c".to_string(), - mpt_config.accumulators.acc_c.mult, - offset, - || Value::known(F::zero()), - )?; - - // because used for is_long - region.assign_advice( - || "assign s_modified_node_rlc".to_string(), - mpt_config.accumulators.s_mod_node_rlc, - offset, - || Value::known(F::zero()), - )?; - // because used for is_short - region.assign_advice( - || "assign c_modified_node_rlc".to_string(), - mpt_config.accumulators.c_mod_node_rlc, - offset, - || Value::known(F::zero()), - )?; - region.assign_advice( || "assign is_last_branch_child".to_string(), mpt_config.branch.is_last_child, @@ -232,40 +189,6 @@ impl MptWitnessRow { || Value::known(F::from((branch.drifted_index == branch.node_index) as u64)), )?; - region.assign_advice( - || "assign key rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(F::zero()), - )?; - - region.assign_advice( - || "assign key rlc mult".to_string(), - mpt_config.accumulators.key.mult, - offset, - || Value::known(F::zero()), - )?; - - region.assign_advice( - || "assign mult diff".to_string(), - mpt_config.accumulators.mult_diff, - offset, - || Value::known(F::zero()), - )?; - - region.assign_advice( - || "assign sel1".to_string(), - mpt_config.denoter.sel1, - offset, - || Value::known(F::zero()), - )?; - region.assign_advice( - || "assign sel2".to_string(), - mpt_config.denoter.sel2, - offset, - || Value::known(F::zero()), - )?; - region.assign_advice( || "assign is_modified".to_string(), mpt_config.branch.is_modified, From 27a59dd1409bd080705884181bacf46976408cd7 Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Thu, 9 Feb 2023 03:05:58 +0100 Subject: [PATCH 03/11] Reduce state machine to three states --- zkevm-circuits/src/circuit_tools.rs | 4 +- zkevm-circuits/src/mpt_circuit.rs | 117 +-- .../src/mpt_circuit/account_leaf.rs | 139 +-- .../account_leaf/account_leaf_key.rs | 304 ------- .../account_leaf_key_in_added_branch.rs | 248 ------ .../account_leaf_nonce_balance.rs | 565 ------------ .../account_leaf_storage_codehash.rs | 333 ------- .../account_leaf/account_non_existing.rs | 203 ----- zkevm-circuits/src/mpt_circuit/branch.rs | 246 +++--- .../src/mpt_circuit/branch/branch_init.rs | 111 --- .../src/mpt_circuit/branch/branch_key.rs | 275 ------ .../src/mpt_circuit/branch/branch_rlc.rs | 129 --- .../src/mpt_circuit/branch/extension_node.rs | 427 --------- zkevm-circuits/src/mpt_circuit/columns.rs | 4 - zkevm-circuits/src/mpt_circuit/helpers.rs | 33 +- zkevm-circuits/src/mpt_circuit/selectors.rs | 4 +- .../src/mpt_circuit/storage_leaf.rs | 816 +++++++++++++++++- .../mpt_circuit/storage_leaf/leaf_combined.rs | 770 ----------------- .../src/mpt_circuit/storage_leaf/leaf_key.rs | 358 -------- .../storage_leaf/leaf_key_in_added_branch.rs | 311 ------- .../storage_leaf/leaf_non_existing.rs | 205 ----- .../mpt_circuit/storage_leaf/leaf_value.rs | 443 ---------- 22 files changed, 1079 insertions(+), 4966 deletions(-) delete mode 100644 zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_nonce_balance.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_storage_codehash.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/branch/branch_init.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/branch/branch_key.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/branch/branch_rlc.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/branch/extension_node.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key_in_added_branch.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_non_existing.rs delete mode 100644 zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_value.rs diff --git a/zkevm-circuits/src/circuit_tools.rs b/zkevm-circuits/src/circuit_tools.rs index 4de22e69b2..651903cf3b 100644 --- a/zkevm-circuits/src/circuit_tools.rs +++ b/zkevm-circuits/src/circuit_tools.rs @@ -277,7 +277,6 @@ impl Memory { pub(crate) fn generate_constraints(&self, cb: &mut ConstraintBuilder) { for bank in self.banks.iter() { bank.generate_constraints(cb); - cb.generate_lookup_table_checks(bank.tag()); /*let lookups = cb.consume_lookups(&[bank.tag()]); @@ -432,7 +431,8 @@ impl MemoryBank { pub(crate) fn generate_constraints(&self, cb: &mut ConstraintBuilder) { let lookup_table = cb.get_lookup_table(self.tag()); crate::circuit!([meta, cb], { - require!(self.next => self.cur.expr() + lookup_table.0); + // TODO(Brecht): fix + //require!(self.next => self.cur.expr() + lookup_table.0); }); } diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index d35afca06c..613370ab48 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -20,18 +20,11 @@ mod selectors; mod storage_leaf; mod witness_row; -use account_leaf::{ - AccountLeaf, AccountLeafCols, -}; -use branch::{ - branch_key::BranchKeyConfig, - extension_node::ExtensionNodeConfig, Branch, BranchCols, BranchConfig, -}; +use account_leaf::{AccountLeaf, AccountLeafCols}; +use branch::{Branch, BranchCols, BranchConfig}; use columns::{AccumulatorCols, DenoteCols, MainCols, PositionCols, ProofTypeCols}; use proof_chain::ProofChainConfig; -use storage_leaf::{ - StorageLeaf, StorageLeafCols, -}; +use storage_leaf::{StorageLeaf, StorageLeafCols}; use witness_row::{MptWitnessRow, MptWitnessRowType}; use param::HASH_WIDTH; @@ -39,19 +32,17 @@ use selectors::SelectorsConfig; use crate::{ circuit, - circuit_tools::{merge_lookups, Memory, CellManager}, + circuit_tools::{merge_lookups, Memory}, evm_circuit::util::rlc, - mpt_circuit::{helpers::{ - extend_rand, parent_memory, BranchNodeInfo, KeyData, MPTConstraintBuilder, ParentData, - }, storage_leaf::leaf_combined::LeafCombinedConfig}, + mpt_circuit::{ + helpers::{extend_rand, parent_memory, KeyData, MPTConstraintBuilder, ParentData}, + storage_leaf::StorageLeafConfig, + }, table::{DynamicTableColumns, KeccakTable}, util::{power_of_randomness_from_instance, Challenges}, }; -use self::{ - columns::MPTTable, param::BRANCH_ROWS_NUM, - helpers::key_memory, account_leaf::AccountCombinedConfig, -}; +use self::{account_leaf::AccountLeafConfig, columns::MPTTable, helpers::key_memory}; /* MPT circuit contains S and C columns (other columns are mostly selectors). @@ -84,8 +75,8 @@ use self::{ #[derive(Debug)] pub struct RowConfig { branch_config: BranchConfig, - super_leaf: LeafCombinedConfig, - super_account: AccountCombinedConfig, + storage_config: StorageLeafConfig, + account_config: AccountLeafConfig, } /// Merkle Patricia Trie context @@ -181,8 +172,8 @@ pub struct MPTConfig { * address RLC in * the same row as storage key/value). */ branch_config: BranchConfig, - super_leaf: LeafCombinedConfig, - super_account: AccountCombinedConfig, + storage_config: StorageLeafConfig, + account_config: AccountLeafConfig, pub(crate) randomness: F, pub(crate) mpt_table: MPTTable, } @@ -420,7 +411,6 @@ impl MPTConfig { /* Initial values */ // Initial key values ifx!{not!(f!(position_cols.q_enable)) => { - //KeyData::store(&mut cb.base, &ctx.key_memory, KeyData::default_values()); KeyData::store_initial_values(&mut cb.base, &ctx.memory[key_memory(true)]); KeyData::store_initial_values(&mut cb.base, &ctx.memory[key_memory(false)]); }} @@ -433,21 +423,21 @@ impl MPTConfig { } }} - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + //let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); let branch_config; - let super_leaf; - let super_account; + let storage_config; + let account_config; ifx!{f!(position_cols.q_enable) => { matchx! { - a!(branch.is_init) => { + and::expr(&[a!(branch.is_init, -1), f!(position_cols.q_not_first)]) => { branch_config = BranchConfig::configure(meta, &mut cb, ctx.clone()); }, a!(account_leaf.is_key_c) => { - super_account = AccountCombinedConfig::configure(meta, &mut cb, ctx.clone()); + account_config = AccountLeafConfig::configure(meta, &mut cb, ctx.clone()); }, a!(storage_leaf.is_s_key) => { ifx!{f!(position_cols.q_not_first), a!(position_cols.not_first_level) => { - super_leaf = LeafCombinedConfig::configure(meta, &mut cb, ctx.clone()); + storage_config = StorageLeafConfig::configure(meta, &mut cb, ctx.clone()); }}; }, _ => (), @@ -513,15 +503,14 @@ impl MPTConfig { require!(@"fixed" => fixed_table.iter().map(|table| f!(table)).collect()); /* Memory banks */ - // TODO(Brecht): change back to q_enable ifx!{f!(position_cols.q_enable) => { ctx.memory.generate_constraints(&mut cb.base); }} row_config = Some(RowConfig { branch_config, - super_leaf, - super_account, + storage_config, + account_config, }); }); @@ -586,8 +575,8 @@ impl MPTConfig { fixed_table, address_rlc, branch_config: row_config.branch_config, - super_leaf: row_config.super_leaf, - super_account: row_config.super_account, + storage_config: row_config.storage_config, + account_config: row_config.account_config, randomness, mpt_table, } @@ -798,7 +787,7 @@ impl MPTConfig { ]); } - for (ind, row) in witness + for (idx, row) in witness .iter() .filter(|r| r.get_type() != MptWitnessRowType::HashToBeComputed) .enumerate() @@ -840,7 +829,7 @@ impl MPTConfig { pv.before_account_leaf = false; } - let q_not_first = if ind == 0 { F::zero() } else { F::one() }; + let q_not_first = if idx == 0 { F::zero() } else { F::one() }; region.assign_fixed( || "not first", self.position_cols.q_not_first, @@ -848,30 +837,6 @@ impl MPTConfig { || Value::known(q_not_first), )?; - let q_not_first_ext_s = if offset < (BRANCH_ROWS_NUM as usize) - 2 { - F::zero() - } else { - F::one() - }; - region.assign_fixed( - || "not first ext s", - self.position_cols.q_not_first_ext_s, - offset, - || Value::known(q_not_first_ext_s), - )?; - - let q_not_first_ext_c = if offset < (BRANCH_ROWS_NUM as usize) - 1 { - F::zero() - } else { - F::one() - }; - region.assign_fixed( - || "not first ext c", - self.position_cols.q_not_first_ext_c, - offset, - || Value::known(q_not_first_ext_c), - )?; - region.assign_advice( || "not first level", self.position_cols.not_first_level, @@ -881,14 +846,19 @@ impl MPTConfig { row.assign_lookup_columns(&mut region, self, &pv, offset)?; - if row.get_type() == MptWitnessRowType::InitBranch { + let prev_row = if offset > 0 { + &witness[offset - 1] + } else { + row + }; + + if offset > 0 && prev_row.get_type() == MptWitnessRowType::InitBranch { self.branch_config .assign(&mut region, witness, self, &mut pv, offset) .ok(); offset += 1; } else if row.get_type() == MptWitnessRowType::BranchChild { - offset += 1; } else { // leaf s or leaf c or leaf key s or leaf key c @@ -919,7 +889,6 @@ impl MPTConfig { } else if row.get_type() == MptWitnessRowType::AccountLeafNeighbouringLeaf { - println!("[{}] reset", offset); account_leaf.is_in_added_branch = true; pv.key_rlc = F::zero(); // account address until here, storage key from here on pv.key_rlc_mult = F::one(); @@ -928,24 +897,6 @@ impl MPTConfig { pv.nibbles_num_prev = 0; pv.key_rlc_sel = true; pv.nibbles_num = 0; - /* - Note: The constraints for ensuring that in the first account and first storage level - the key RLC is 0 and the key RLC mult is 1 are in: - - `account_leaf_key.rs` for when the node in the first level is an account leaf - - `branch_key.rs` for when the node in the first level is a branch - - `extension_node_key.rs` for when the node in the first level is an extension node. - - Similarly for `sel`. For `key_rlc_prev` and `key_rlc_mult_prev` there are no - columns, these values are used for internal computation, like for `key_rlc` - after the branch placeholder (when we need to reach back to the branch above - the placeholder). - - The constraints for ensuring that in the first account and first storage level - `nibbles_num` is 0 are in: - - `account_leaf_key.rs` for when the node in the first level is an account leaf - - `branch.rs` for when the node in the first level is a branch - - `extension_node.rs` for when the node in the first level is an extension node. - */ } else if row.get_type() == MptWitnessRowType::StorageLeafSValue { storage_leaf.is_s_value = true; } else if row.get_type() == MptWitnessRowType::StorageLeafCValue { @@ -973,7 +924,7 @@ impl MPTConfig { // Storage leaf key if row.get_type() == MptWitnessRowType::StorageLeafSKey { - self.super_leaf.assign( + self.storage_config.assign( &mut region, self, witness, @@ -981,7 +932,7 @@ impl MPTConfig { offset, )?; } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { - self.super_account.assign( + self.account_config.assign( &mut region, self, witness, diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index 654dff0c64..a2316b9e86 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -1,30 +1,27 @@ -pub mod account_leaf_key; -pub mod account_leaf_key_in_added_branch; -pub mod account_leaf_nonce_balance; -pub mod account_leaf_storage_codehash; -pub mod account_non_existing; - use halo2_proofs::{ arithmetic::FieldExt, plonk::{Advice, Column, ConstraintSystem, Expression}, }; -use std::marker::PhantomData; use halo2_proofs::{ circuit::{Region, Value}, plonk::{Error, VirtualCells}, poly::Rotation, }; +use std::marker::PhantomData; use crate::{ circuit, - circuit_tools::{CellManager, DataTransition, RLCable, Cell, ConstraintBuilder}, + circuit_tools::{Cell, CellManager, CellType, ConstraintBuilder, DataTransition, RLCable}, mpt_circuit::{ helpers::BranchNodeInfo, param::{BRANCH_ROWS_NUM, S_START}, }, mpt_circuit::{ - helpers::{get_num_nibbles, AccountLeafInfo, KeyData, MPTConstraintBuilder, key_memory, get_num_bytes_short, parent_memory, ParentData, get_parent_rlc_state}, - param::{KEY_LEN_IN_NIBBLES, RLP_LIST_LONG, RLP_LONG, RLP_HASH_VALUE}, + helpers::{ + get_num_bytes_short, get_num_nibbles, get_parent_rlc_state, key_memory, parent_memory, + AccountLeafInfo, KeyData, MPTConstraintBuilder, ParentData, + }, + param::{KEY_LEN_IN_NIBBLES, RLP_HASH_VALUE, RLP_LIST_LONG, RLP_LONG}, FixedTableTag, }, mpt_circuit::{param::IS_ACCOUNT_DELETE_MOD_POS, MPTConfig, ProofValues}, @@ -34,8 +31,15 @@ use crate::{ }, }; -use super::{param::{ACCOUNT_LEAF_NONCE_BALANCE_S_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_NONCE_BALANCE_C_IND, ACCOUNT_LEAF_KEY_C_IND, C_START, HASH_WIDTH, IS_NONCE_MOD_POS, IS_BALANCE_MOD_POS, IS_CODEHASH_MOD_POS, ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, IS_NON_EXISTING_ACCOUNT_POS}, helpers::bytes_into_rlc}; - +use super::{ + helpers::bytes_into_rlc, + param::{ + ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_NONCE_BALANCE_C_IND, + ACCOUNT_LEAF_NONCE_BALANCE_S_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND, + ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, C_START, HASH_WIDTH, IS_BALANCE_MOD_POS, + IS_CODEHASH_MOD_POS, IS_NONCE_MOD_POS, IS_NON_EXISTING_ACCOUNT_POS, + }, +}; #[derive(Clone, Debug)] pub(crate) struct AccountLeafCols { @@ -103,17 +107,17 @@ pub(crate) struct AccountLeaf { } #[derive(Clone, Debug)] -pub(crate) struct AccountCombinedConfig { +pub(crate) struct AccountLeafConfig { key_data_s: KeyData, key_data_c: KeyData, key_data_w: KeyData, key_data_d: KeyData, parent_data_s: ParentData, parent_data_c: ParentData, - //diff_inv: Cell, + diff_inv: Cell, } -impl AccountCombinedConfig { +impl AccountLeafConfig { pub fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, @@ -131,7 +135,7 @@ impl AccountCombinedConfig { let value = ctx.value; let r = ctx.r.clone(); - let mut offset = - 1; + let mut offset = -1; // key rlc is in the first branch node let rot_parent = offset - 1; @@ -145,7 +149,7 @@ impl AccountCombinedConfig { let mut ctx_key_data_d: Option> = None; let mut ctx_parent_data_s: Option> = None; let mut ctx_parent_data_c: Option> = None; - let mut ctx_diff_inv: Option> = None; + let ctx_diff_inv: Cell; circuit!([meta, cb.base], { for is_s in [true, false] { @@ -163,7 +167,12 @@ impl AccountCombinedConfig { // Load the last key values, which depends on the branch being a placeholder. let is_branch_placeholder = ifx! {f!(ctx.position_cols.q_not_first), a!(not_first_level) => { branch.is_placeholder() }}; let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(is_s)], load_offset); + let key_data = KeyData::load( + &mut cb.base, + &mut cm, + &ctx.memory[key_memory(is_s)], + load_offset, + ); // Calculate the key RLC let key_rlc = key_data.rlc.expr() @@ -183,7 +192,11 @@ impl AccountCombinedConfig { require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); // Key done, set the starting values - KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], KeyData::default_values()); + KeyData::store( + &mut cb.base, + &ctx.memory[key_memory(is_s)], + KeyData::default_values(), + ); // Num bytes used in RLC let num_bytes = account.num_bytes_on_key_row(meta); @@ -249,8 +262,8 @@ impl AccountCombinedConfig { let key_rlc_wrong = key_data.rlc.expr() + account.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), offset - rot_key_s); require!(a!(address_rlc, offset) => key_rlc_wrong); // Now make sure this address is different than the one of the leaf - let diff_inv = a!(accs.acc_s.rlc, offset); - require!((a!(address_rlc, offset) - a!(accs.key.rlc, rot_key_s)) * diff_inv => 1); + let diff_inv = cm.query_cell(CellType::Storage); + require!((a!(address_rlc, offset) - a!(accs.key.rlc, rot_key_s)) * diff_inv.expr() => 1); // Make sure the lengths of the keys are the same let account_wrong = AccountLeafInfo::new(meta, ctx.clone(), offset); require!(account_wrong.key_len(meta) => account.key_len(meta)); @@ -258,6 +271,7 @@ impl AccountCombinedConfig { let leaf = AccountLeafInfo::new(meta, ctx.clone(), offset); let num_bytes = leaf.num_bytes_on_key_row(meta); //cb.set_length(num_bytes); + ctx_diff_inv = diff_inv; } elsex { // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. require!(key_data.is_placeholder_leaf_s => true); @@ -574,14 +588,14 @@ impl AccountCombinedConfig { }} }); - AccountCombinedConfig { + AccountLeafConfig { key_data_s: ctx_key_data_s.unwrap(), key_data_c: ctx_key_data_c.unwrap(), key_data_w: ctx_key_data_w.unwrap(), key_data_d: ctx_key_data_d.unwrap(), parent_data_s: ctx_parent_data_s.unwrap(), parent_data_c: ctx_parent_data_c.unwrap(), - //diff_inv: ctx_diff_inv.unwrap(), + diff_inv: ctx_diff_inv, } } @@ -593,7 +607,6 @@ impl AccountCombinedConfig { pv: &mut ProofValues, offset: usize, ) -> Result<(), Error> { - let base_offset = offset; let mut offset = offset - 1; @@ -622,8 +635,8 @@ impl AccountCombinedConfig { mpt_config.proof_type.proof_type, offset, || Value::known(F::from(5_u64)), /* account delete mod lookup enabled in - * this row if it is is_account_delete - * proof */ + * this row if it is is_account_delete + * proof */ )?; } } else { @@ -637,9 +650,17 @@ impl AccountCombinedConfig { pv.is_branch_c_placeholder }; let load_offset = if is_branch_placeholder { 1 } else { 0 }; - let key_data = if is_s { &self.key_data_s } else { &self.key_data_c }; - key_data - .witness_load(region, base_offset, &mut pv.memory[key_memory(is_s)], load_offset)?; + let key_data = if is_s { + &self.key_data_s + } else { + &self.key_data_c + }; + key_data.witness_load( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + load_offset, + )?; key_data.witness_store( region, base_offset, @@ -655,13 +676,19 @@ impl AccountCombinedConfig { let mut key_rlc_new = pv.key_rlc; let mut key_rlc_mult_new = pv.key_rlc_mult; if (pv.is_branch_s_placeholder && row.get_type() == MptWitnessRowType::AccountLeafKeyS) - || (pv.is_branch_c_placeholder && row.get_type() == MptWitnessRowType::AccountLeafKeyC) + || (pv.is_branch_c_placeholder + && row.get_type() == MptWitnessRowType::AccountLeafKeyC) { key_rlc_new = pv.key_rlc_prev; key_rlc_mult_new = pv.key_rlc_mult_prev; } - mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, S_START); + mpt_config.compute_key_rlc( + &row.bytes, + &mut key_rlc_new, + &mut key_rlc_mult_new, + S_START, + ); pv.account_key_rlc = key_rlc_new; region.assign_advice( || "assign key_rlc".to_string(), @@ -670,7 +697,9 @@ impl AccountCombinedConfig { || Value::known(key_rlc_new), )?; - mpt_config.assign_acc(region, acc, acc_mult, F::zero(), F::zero(), offset).ok(); + mpt_config + .assign_acc(region, acc, acc_mult, F::zero(), F::zero(), offset) + .ok(); offset += 1; } @@ -686,13 +715,8 @@ impl AccountCombinedConfig { let diff_inv = (address_rlc - pv.account_key_rlc) .invert() .unwrap_or(F::zero()); - region - .assign_advice( - || "assign diff inv".to_string(), - mpt_config.accumulators.acc_s.rlc, - offset, - || Value::known(diff_inv), - ) + self.diff_inv + .assign(region, base_offset, Value::known(diff_inv)) .ok(); if row.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1 { @@ -701,12 +725,14 @@ impl AccountCombinedConfig { || "assign lookup enabled".to_string(), mpt_config.proof_type.proof_type, offset, - || Value::known(F::from(4_u64)), /* non existing account lookup enabled in - * this row if it is non_existing_account - * proof */ + || Value::known(F::from(4_u64)), /* non existing account lookup enabled + * in + * this row if it is + * non_existing_account + * proof */ ) .ok(); - } + } } offset += 1; @@ -725,7 +751,8 @@ impl AccountCombinedConfig { .assign_advice( || "assign sel1".to_string(), mpt_config.denoter.sel1, - offset - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, + offset + - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, || Value::known(F::one()), ) .ok(); @@ -734,7 +761,8 @@ impl AccountCombinedConfig { .assign_advice( || "assign sel1".to_string(), mpt_config.denoter.sel1, - offset - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, + offset + - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, || Value::known(F::zero()), ) .ok(); @@ -747,7 +775,8 @@ impl AccountCombinedConfig { .assign_advice( || "assign sel2".to_string(), mpt_config.denoter.sel2, - offset - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, + offset + - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, || Value::known(F::one()), ) .ok(); @@ -756,7 +785,8 @@ impl AccountCombinedConfig { .assign_advice( || "assign sel2".to_string(), mpt_config.denoter.sel2, - offset - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, + offset + - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, || Value::known(F::zero()), ) .ok(); @@ -852,7 +882,8 @@ impl AccountCombinedConfig { } let offset_s = offset - - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_NONCE_BALANCE_S_IND) as usize; + - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_NONCE_BALANCE_S_IND) + as usize; // assign nonce S RLC in ACCOUNT_LEAF_NONCE_BALANCE_S row. region @@ -1053,7 +1084,9 @@ impl AccountCombinedConfig { || "assign lookup enabled".to_string(), mpt_config.proof_type.proof_type, offset, - || Value::known(F::from(3_u64)), // codehash mod lookup enabled in this row if it is is_codehash_mod proof + || Value::known(F::from(3_u64)), /* codehash mod lookup enabled in + * this row if it is + * is_codehash_mod proof */ ) .ok(); } @@ -1108,7 +1141,11 @@ impl AccountCombinedConfig { } else { pv.storage_root_value_c }; - let parent_data = if is_s { &self.parent_data_s } else { &self.parent_data_c }; + let parent_data = if is_s { + &self.parent_data_s + } else { + &self.parent_data_c + }; parent_data .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) .ok(); @@ -1175,7 +1212,7 @@ impl AccountCombinedConfig { offset, ) .ok(); - } + } Ok(()) } diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs deleted file mode 100644 index af8e32c41a..0000000000 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key.rs +++ /dev/null @@ -1,304 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, - plonk::{Error, VirtualCells}, - poly::Rotation, -}; - -use crate::{ - circuit, - circuit_tools::CellManager, - mpt_circuit::{ - helpers::BranchNodeInfo, - param::{BRANCH_ROWS_NUM, S_START}, - }, - mpt_circuit::{ - helpers::{get_num_nibbles, AccountLeafInfo, KeyData, MPTConstraintBuilder, key_memory}, - param::{KEY_LEN_IN_NIBBLES, RLP_LIST_LONG}, - FixedTableTag, - }, - mpt_circuit::{param::IS_ACCOUNT_DELETE_MOD_POS, MPTConfig, ProofValues}, - mpt_circuit::{ - witness_row::{MptWitnessRow, MptWitnessRowType}, - MPTContext, - }, -}; - -/* -An account leaf occupies 8 rows. -Contrary as in the branch rows, the `S` and `C` leaves are not positioned parallel to each other. -The rows are the following: -ACCOUNT_LEAF_KEY_S -ACCOUNT_LEAF_KEY_C -ACCOUNT_NON_EXISTING -ACCOUNT_LEAF_NONCE_BALANCE_S -ACCOUNT_LEAF_NONCE_BALANCE_C -ACCOUNT_LEAF_STORAGE_CODEHASH_S -ACCOUNT_LEAF_STORAGE_CODEHASH_C -ACCOUNT_DRIFTED_LEAF - -The constraints in this file apply to ACCOUNT_LEAF_KEY_S and ACCOUNT_LEAF_KEY_C rows. - -For example, the two rows might be: -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - -Here, in `ACCOUNT_LEAF_KEY_S` example row, there are key nibbles for `S` proof stored in compact form. -The nibbles start at `s_main.bytes[1]` and can go to `c_main.rlp2`. - -In `ACCOUNT_LEAF_KEY_C` example row, there are key nibbles for `C` proof stored in compact form. -The nibbles start at `s_main.bytes[1]` and can go to `c_main.rlp2`. - -The whole account leaf looks like: -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[0,0,0,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[184,70,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] -[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - -There are two main scenarios when an account is added to the trie: - 1. There exists another account which has the same address to the some point as the one that - is being added, including the position of this account in the branch. - In this case a new branch is added to the trie. - The existing account drifts down one level to the new branch. The newly - added account will also appear in this branch. For example, let us say that we have the account `A` - with nibbles `[3, 12, 3]` in the trie. We then add the account `A1` with nibbles `[3, 12, 5]` - to the trie. The branch will appear (at position `[3, 12]`) which will have `A` at position 3 - and `A1` at position 5. This means there will be an additional branch in `C` proof (or in `S` - proof when the situation is reversed - we are deleting the leaf instead of adding) and - for this reason we add a placeholder branch for `S` proof (for `C` proof in reversed situation) - to preserve the circuit layout (more details about this technicality are given below). - - 2. The branch where the new account is to be added has nil node at the position where the new account - is to be added. For example, let us have a branch at `[3, 12]`, we are adding a leaf with the - first three nibbles as `[3, 12, 5]`, and the position 5 in our branch is not occupied. - There does not exist an account which has the same address to the some point. - In this case, the `getProof` response does not end with a leaf, but with a branch. - To preserve the layout, a placeholder account leaf is added. - -Lookups: -The `is_account_delete_mod` lookup is enabled in `ACCOUNT_LEAF_KEY_S` row. - -[248,112,157,59,158,160,175,159,65,212,107,23,98,208,38,205,150,63,244,2,185, -236,246,95,240,224,191,229,27,102,202,231,184,80 There are 112 -bytes after the first two bytes. 157 means the key is 29 (157 - -128) bytes long. - -The example layout for a branch placeholder looks like (placeholder could be in `C` proof too): - Branch 1S || Branch 1C - Branch 2S (placeholder) || Branch 2C - Leaf S - Leaf C -Using `Previous key RLC` constraint we ensured that we copied the key RLC from Branch 1S -to Leaf S `accs.acc_c.rlc` column. So when add nibbles to compute the key RLC (address RLC) -of the account, we start with `accs.acc_c.rlc` value from the current row. -sel1/sel2 tells us whether there is an even or odd number of nibbles in the leaf. -sel1/sel2 info is need for the computation of the key RLC (see below), in case of a leaf -after branch placeholder, sel1/sel2 can be computed as follows. -Note that we cannot rotate back into Branch 1S because we get PoisonedConstraint -in extension_node_key. -Instead, we can rotate into branch parallel to the placeholder branch and compute sel1/sel2 with info from there. -Let's denote sel1/sel2 from this branch by sel1p/sel2p. -There are a couple of different cases, for example when branch/extension node parallel -to the placeholder branch is a regular branch. -There is only one nibble taken by Branch 2C, so sel1/sel2 simply turns around compared to sel1p/sel2p: -sel1 = sel2p -sel2 = sel1p -When branch/extension node parallel to the placeholder branch is an extension node, it depends on the -number of nibbles. If there is an odd number of nibbles: sel1 = sel1p, sel2 = sel2p. If there is -an even number of nibbles, it turns around. - -*/ - -#[derive(Clone, Debug)] -pub(crate) struct AccountLeafKeyConfig { - key_data: KeyData, -} - -impl AccountLeafKeyConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - is_s: bool, - ) -> Self { - let proof_type = ctx.proof_type; - let not_first_level = ctx.position_cols.not_first_level; - let s_main = ctx.s_main; - let accs = ctx.accumulators; - let address_rlc = ctx.address_rlc; - - // key rlc is in the first branch node - let rot_first_child = -BRANCH_ROWS_NUM + if is_s { 1 } else { 0 }; - //let rot_first_child_prev = rot_first_child - BRANCH_ROWS_NUM; - let rot_branch_init = rot_first_child - 1; - //let rot_branch_init_prev = rot_branch_init - BRANCH_ROWS_NUM; - - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); - let ctx_key_data: Option>; - - circuit!([meta, cb.base], { - let account = AccountLeafInfo::new(meta, ctx.clone(), 0); - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - - // Account leaf always starts with RLP_LIST_LONG + 1 because its length is - // always longer than 55 bytes due to containing two hashes - - // storage root and codehash. - require!(a!(s_main.rlp1) => RLP_LIST_LONG + 1); - - // Calculate and store the leaf data RLC - require!(a!(accs.acc_s.rlc) => ctx.rlc(meta, 0..36, 0)); - - // Load the last key values, which depends on the branch being a placeholder. - let is_branch_placeholder = ifx! {a!(not_first_level) => { branch.is_placeholder() }}; - let offset = ifx! {is_branch_placeholder => { 1.expr() }}; - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(is_s)], offset); - - // Calculate the key RLC - let key_rlc = key_data.rlc.expr() - + account.key_rlc( - meta, - &mut cb.base, - key_data.mult.expr(), - key_data.is_odd.expr(), - 1.expr(), - 0, - ); - require!(a!(accs.key.rlc) => key_rlc); - - // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES. - let key_len = account.key_len(meta); - let num_nibbles = get_num_nibbles(meta, key_len.expr(), key_data.is_odd.expr()); - require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); - - // Key done, set the starting values - KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], KeyData::default_values()); - - // Num bytes used in RLC - let num_bytes = account.num_bytes_on_key_row(meta); - // Update `mult_diff` - require!((FixedTableTag::RMult, num_bytes.expr(), a!(accs.acc_s.mult)) => @"mult"); - // RLC bytes zero check - cb.set_length(num_bytes.expr()); - - // The computed key RLC needs to be the same as the value in `address_rlc` - // column. Note that `key_rlc` is used in `account_leaf_key_in_added_branch` and - // in cases when there is a placeholder branch we have `key_rlc - - // address_rlc != 0` because `key_rlc` is computed for the branch - // that is parallel to the placeholder branch. - ifx! {not!(is_branch_placeholder), not!(a!(proof_type.is_non_existing_account_proof)) => { - require!(a!(address_rlc) => a!(accs.key.rlc)); - }} - - // Account delete - // We need to make sure there is no leaf when account is deleted. Two possible - // cases: - // - 1. Account leaf is deleted and there is a nil object in - // branch. In this case we have a placeholder leaf. - // - 2. Account leaf is deleted from a branch with two leaves, the remaining - // leaf moves one level up and replaces the branch. In this case we - // have a branch placeholder. So we need to check there is a - // placeholder branch when we have the second case. Note: we do not - // need to cover the case when the (only) branch dissapears and only one - // leaf remains in the trie because there will always be at least two leaves - // (the genesis account) when account will be deleted, - // so there will always be a branch / extension node (and thus placeholder - // branch). - if !is_s { - // Note: this constraint suffices because the proper transition from branch to a - // leaf (2. case) is checked by constraints in account_leaf_key_in_added_branch. - ifx! {a!(proof_type.is_account_delete_mod) => { - require!(or::expr([branch.contains_placeholder_leaf(meta, is_s), branch.is_placeholder()]) => true); - }} - } - - ctx_key_data = Some(key_data); - }); - - AccountLeafKeyConfig { - key_data: ctx_key_data.unwrap(), - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &mut ProofValues, - row: &MptWitnessRow, - offset: usize, - ) -> Result<(), Error> { - // account leaf key S & C - let mut acc = F::zero(); - let mut acc_mult = F::one(); - // 35 = 2 (leaf rlp) + 1 (key rlp) + key_len - let key_len = (row.get_byte(2) - 128) as usize; - for b in row.bytes.iter().take(3 + key_len) { - acc += F::from(*b as u64) * acc_mult; - acc_mult *= mpt_config.randomness; - } - - if row.get_type() == MptWitnessRowType::AccountLeafKeyS { - pv.acc_account_s = acc; - pv.acc_mult_account_s = acc_mult; - - if row.get_byte_rev(IS_ACCOUNT_DELETE_MOD_POS) == 1 { - region.assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(5_u64)), /* account delete mod lookup enabled in - * this row if it is is_account_delete - * proof */ - )?; - } - } else { - pv.acc_account_c = acc; - pv.acc_mult_account_c = acc_mult; - } - - let is_s = row.get_type() == MptWitnessRowType::AccountLeafKeyS; - let is_branch_placeholder = if is_s { - pv.is_branch_s_placeholder - } else { - pv.is_branch_c_placeholder - }; - let load_offset = if is_branch_placeholder { 1 } else { 0 }; - self.key_data - .witness_load(region, offset, &mut pv.memory[key_memory(is_s)], load_offset)?; - self.key_data.witness_store( - region, - offset, - &mut pv.memory[key_memory(is_s)], - F::zero(), - F::one(), - 0, - false, - false, - )?; - - // For leaf S and leaf C we need to start with the same rlc. - let mut key_rlc_new = pv.key_rlc; - let mut key_rlc_mult_new = pv.key_rlc_mult; - if (pv.is_branch_s_placeholder && row.get_type() == MptWitnessRowType::AccountLeafKeyS) - || (pv.is_branch_c_placeholder && row.get_type() == MptWitnessRowType::AccountLeafKeyC) - { - key_rlc_new = pv.key_rlc_prev; - key_rlc_mult_new = pv.key_rlc_mult_prev; - } - - mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, S_START); - pv.account_key_rlc = key_rlc_new; - region.assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(key_rlc_new), - )?; - - mpt_config.assign_acc(region, acc, acc_mult, F::zero(), F::zero(), offset) - } -} diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs deleted file mode 100644 index 8f490bd53e..0000000000 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_key_in_added_branch.rs +++ /dev/null @@ -1,248 +0,0 @@ -use halo2_proofs::{arithmetic::FieldExt, circuit::Region, plonk::VirtualCells, poly::Rotation}; - -use crate::{ - circuit, - circuit_tools::{CellManager, ConstraintBuilder}, - mpt_circuit::{ - helpers::{BranchNodeInfo, key_memory}, - param::{ - ACCOUNT_DRIFTED_LEAF_IND, ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, - ACCOUNT_LEAF_NONCE_BALANCE_C_IND, ACCOUNT_LEAF_NONCE_BALANCE_S_IND, - ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, - BRANCH_ROWS_NUM, RLP_LIST_LONG, - }, - }, - mpt_circuit::{ - helpers::{get_parent_rlc_state, AccountLeafInfo, KeyData, MPTConstraintBuilder}, - FixedTableTag, - }, - mpt_circuit::{MPTConfig, MPTContext, ProofValues}, -}; - -/* -An account leaf occupies 8 rows. -Contrary as in the branch rows, the `S` and `C` leaves are not positioned parallel to each other. -The rows are the following: -ACCOUNT_LEAF_KEY_S -ACCOUNT_LEAF_KEY_C -ACCOUNT_NON_EXISTING -ACCOUNT_LEAF_NONCE_BALANCE_S -ACCOUNT_LEAF_NONCE_BALANCE_C -ACCOUNT_LEAF_STORAGE_CODEHASH_S -ACCOUNT_LEAF_STORAGE_CODEHASH_C -ACCOUNT_DRIFTED_LEAF - -An example of leaf rows: -[248 102 157 55 236 125 29 155 142 209 241 75 145 144 143 254 65 81 209 56 13 192 157 236 195 213 73 132 11 251 149 241 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6] -[248 102 157 32 133 130 180 167 143 97 28 115 102 25 94 62 148 249 8 6 55 244 16 75 187 208 208 127 251 120 61 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4] -[0 0 157 32 133 130 180 167 143 97 28 115 102 25 94 62 148 249 8 6 55 244 16 75 187 208 208 127 251 120 61 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18] -[184 70 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 248 68 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7] -[184 70 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 248 68 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8] -[0 160 112 158 181 221 162 20 124 79 184 25 162 13 167 162 146 25 237 242 59 120 184 154 118 137 92 181 187 152 115 82 223 48 0 160 7 190 1 231 231 32 111 227 30 206 233 26 215 93 173 166 90 214 186 67 58 230 71 161 185 51 4 105 247 198 103 124 0 9] -[0 160 112 158 181 221 162 20 124 79 184 25 162 13 167 162 146 25 237 242 59 120 184 154 118 137 92 181 187 152 115 82 223 48 0 160 7 190 1 231 231 32 111 227 30 206 233 26 215 93 173 166 90 214 186 67 58 230 71 161 185 51 4 105 247 198 103 124 0 11] -[248 102 157 32 236 125 29 155 142 209 241 75 145 144 143 254 65 81 209 56 13 192 157 236 195 213 73 132 11 251 149 241 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 10] - -The `ACCOUNT_LEAF_DRIFTED` row is nonempty when a leaf is added (or deleted) to the position in trie where there is already -an existing leaf. This appears when an existing leaf and a newly added leaf have the same initial key nibbles. -In this case, a new branch is created and both leaves (existing and newly added) appear in the new branch. -`ACCOUNT_LEAF_DRIFTED` row contains the key bytes of the existing leaf once it drifted down to the new branch. - -Add case (S branch is placeholder): -Branch S || Branch C -Placeholder branch || Added branch -Leaf S || Leaf C - || Drifted leaf (this is Leaf S drifted into Added branch) - -Leaf S needs to have the same RLC as Drifted leaf. -Note that Leaf S RLC is computed by taking the key RLC from Branch S and then adding -the bytes in Leaf key S row. -Drifted leaf RLC is computed by taking the key RLC from Added branch and then adding the bytes -in Drifted leaf row. - -Delete case (C branch is placeholder): -Branch S || Branch C -Branch to be deleted || Placeholder branch -Leaf S (leaf to be deleted) || Leaf C -Leaf to be drifted one level up || - -Drifted leaf in added branch has the same key as it had it before it drifted -down to the new branch. - -We obtain the key RLC from the branch / extension node above the placeholder branch. -We then add the remaining key nibbles that are stored in the drifted leaf key and the final RLC -needs to be the same as the one stored in `accumulators.key.rlc` in the account leaf key row -(not the drifted leaf). This means the storage leaf has the same key RLC before and after -it drifts into a new branch. - -Note: Branch key RLC is in the first branch child row (not in branch init). We need to go -in the branch above the placeholder branch. - -We need the intermediate key RLC right before `drifted_pos` is added to it. If the branch parallel to the placeholder branch -is an extension node, we have the intermediate RLC stored in the extension node `accumulators.key.rlc`. -If it is a regular branch, we need to go one branch above to retrieve the RLC (if there is no level above, we take 0). -*/ - -#[derive(Clone, Debug)] -pub(crate) struct AccountLeafKeyInAddedBranchConfig { - key_data: KeyData, -} - -impl AccountLeafKeyInAddedBranchConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - ) -> Self { - let not_first_level = ctx.position_cols.not_first_level; - let s_main = ctx.s_main; - let accs = ctx.accumulators; - let r = ctx.r.clone(); - - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); - let ctx_key_data: Option>; - - let rot_parent = -ACCOUNT_DRIFTED_LEAF_IND - 1; - let rot_branch_init = rot_parent + 1 - BRANCH_ROWS_NUM; - let rot_first_child = rot_branch_init + 1; - let rot_key_s = -(ACCOUNT_DRIFTED_LEAF_IND - ACCOUNT_LEAF_KEY_S_IND); - let rot_key_c = -(ACCOUNT_DRIFTED_LEAF_IND - ACCOUNT_LEAF_KEY_C_IND); - let rot_nonce_s = -(ACCOUNT_DRIFTED_LEAF_IND - ACCOUNT_LEAF_NONCE_BALANCE_S_IND); - let rot_nonce_c = -(ACCOUNT_DRIFTED_LEAF_IND - ACCOUNT_LEAF_NONCE_BALANCE_C_IND); - let rot_storage_s = -(ACCOUNT_DRIFTED_LEAF_IND - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND); - let rot_storage_c = -(ACCOUNT_DRIFTED_LEAF_IND - ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND); - - circuit!([meta, cb.base], { - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - let drifted_account = AccountLeafInfo::new(meta, ctx.clone(), 0); - - // A drifted leaf appears only when there is a placeholder branch - ifx! {branch.is_placeholder_s_or_c() => { - // Calculate and store the leaf RLC (RLP + key) - let drifted_rlc = a!(accs.acc_s.rlc); - require!(drifted_rlc => ctx.rlc(meta, 0..36, 0)); - - // `s_rlp1` is always RLP_LIST_LONG + 1 because the account leaf is always > 55 bytes (and < 256) - require!(a!(s_main.rlp1) => RLP_LIST_LONG + 1); - - // The key RLC of the drifted leaf needs to be the same as the key RLC of the leaf before - // the drift - the nibbles are the same in both cases, the difference is that before the - // drift some nibbles are stored in the leaf key, while after the drift these nibbles are used as - // position in a branch or/and nibbles of the extension node. - let is_branch_in_first_level = not!(a!(not_first_level, rot_branch_init)); - let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); - - // Load the last key values - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 2.expr()); - - // TODO(Brecht): make this work with loaded key data when extension node is separate - ifx! {not!(branch.is_extension()) => { - require!(key_data.rlc => key_rlc_prev); - require!(key_data.mult => key_mult_prev); - }} - - // Calculate the drifted key RLC - let drifted_key_rlc = key_rlc_prev + - branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + - drifted_account.key_rlc(meta, &mut cb.base, key_mult_prev.expr(), branch.is_key_odd(), r[0].expr(), 0); - - // RLC bytes zero check - let num_bytes = drifted_account.num_bytes_on_key_row(meta); - cb.set_length(num_bytes.expr()); - // Update `mult_diff` - let mult = a!(accs.acc_s.mult); - require!((FixedTableTag::RMult, num_bytes.expr(), mult) => @"mult"); - - // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { - circuit!([meta, cb], { - let rot_key = if is_s { rot_key_s } else { rot_key_c }; - let rot_nonce = if is_s { rot_nonce_s } else { rot_nonce_c }; - let rot_storage = if is_s { rot_storage_s } else { rot_storage_c }; - - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - - // Calculate the drifted leaf rlc - // Nonce data rlc - let nonce_stored = a!(accs.s_mod_node_rlc, rot_nonce); - let nonce_rlc = account.to_data_rlc(meta, ctx.s_main, nonce_stored, account.is_nonce_long(), rot_nonce); - // Balance data rlc - let balance_stored = a!(accs.c_mod_node_rlc, rot_nonce); - let balance_rlc = account.to_data_rlc(meta, ctx.c_main, balance_stored, account.is_balance_long(), rot_nonce); - let mult_nonce = a!(accs.acc_c.rlc, rot_nonce); - let mult_balance = a!(accs.key.mult, rot_nonce); - let rlc = drifted_rlc.expr() + account.nonce_balance_rlc(meta, nonce_rlc.expr(), balance_rlc.expr(), mult.expr(), mult_nonce.expr(), rot_nonce); - // Add storage/codehash rlc - let storage_rlc = a!(accs.s_mod_node_rlc, rot_storage); - let codehash_rlc = a!(accs.c_mod_node_rlc, rot_storage); - let mult_prev = mult.expr() * mult_nonce.expr() * mult_balance.expr(); - let rlc = rlc + account.storage_codehash_rlc(meta, storage_rlc.expr(), codehash_rlc.expr(), mult_prev.expr(), rot_storage); - - (true.expr(), a!(accs.key.rlc, rot_key), rlc, a!(accs.mod_node_rlc(is_s), rot_first_child)) - }) - }; - let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { - branch.is_placeholder_s() => { - // Neighbour leaf in the added branch - // - `leaf_key_s_rlc` is the key RLC of the leaf before it drifted down - // in a new branch. - // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `c_mod_node_rlc` in the added branch stores the hash of - // `modified_index` (the leaf that has been added). - calc_rlc(true, meta, &mut cb.base) - }, - branch.is_placeholder_c() => { - // Neighbour leaf in the deleted branch - // -`leaf_key_c_rlc` is the key RLC of the leaf after its neighbour leaf - // has been deleted (and there were only two leaves, so the branch was deleted). - // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `s_mod_node_rlc` in the deleted branch stores the hash of - // `modified_index` (the leaf that is to be deleted). - calc_rlc(false, meta, &mut cb.base) - }, - _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), - }; - ifx! {do_checks => { - // The key of the drifted leaf needs to match the key of the leaf - require!(key_rlc => drifted_key_rlc); - // The drifted leaf needs to be stored in the branch at `drifted_index`. - require!((1, drifted_rlc, drifted_account.num_bytes(meta), mod_hash) => @"keccak"); - }} - - ctx_key_data = Some(key_data); - }} - }); - - AccountLeafKeyInAddedBranchConfig { - key_data: ctx_key_data.unwrap(), - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &mut ProofValues, - row: &[u8], - offset: usize, - ) { - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - let len = (row[2] - 128) as usize + 3; - mpt_config.compute_acc_and_mult(row, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); - - self.key_data - .witness_load(region, offset, &mut pv.memory[key_memory(true)], 2) - .ok(); - - mpt_config - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) - .ok(); - } -} diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_nonce_balance.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_nonce_balance.rs deleted file mode 100644 index 35755549b2..0000000000 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_nonce_balance.rs +++ /dev/null @@ -1,565 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, - plonk::{Expression, VirtualCells}, - poly::Rotation, -}; -use std::marker::PhantomData; - -use crate::{ - circuit, - circuit_tools::{DataTransition, RLCable}, - mpt_circuit::MPTContext, - mpt_circuit::{helpers::get_num_bytes_short, FixedTableTag}, - mpt_circuit::{ - helpers::AccountLeafInfo, - param::{ - ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_NONCE_BALANCE_C_IND, - ACCOUNT_LEAF_NONCE_BALANCE_S_IND, C_START, HASH_WIDTH, RLP_LIST_LONG, RLP_LONG, - S_START, - }, - }, - mpt_circuit::{ - helpers::MPTConstraintBuilder, - witness_row::{MptWitnessRow, MptWitnessRowType}, - }, - mpt_circuit::{ - param::{IS_BALANCE_MOD_POS, IS_NONCE_MOD_POS}, - MPTConfig, ProofValues, - }, -}; - -/* -An account leaf occupies 8 rows. -Contrary as in the branch rows, the `S` and `C` leaves are not positioned parallel to each other. -The rows are the following: -ACCOUNT_LEAF_KEY_S -ACCOUNT_LEAF_KEY_C -ACCOUNT_NON_EXISTING -ACCOUNT_LEAF_NONCE_BALANCE_S -ACCOUNT_LEAF_NONCE_BALANCE_C -ACCOUNT_LEAF_STORAGE_CODEHASH_S -ACCOUNT_LEAF_STORAGE_CODEHASH_C -ACCOUNT_DRIFTED_LEAF - -The constraints in this file apply to ACCOUNT_LEAF_NONCE_BALANCE_S and -ACCOUNT_LEAF_NONCE_BALANCE_C rows. - -For example, the two rows might be: -[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[184,70,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - -Here, in `ACCOUNT_LEAF_NONCE_BALANCE_S` example row, there is `S` nonce stored in `s_main` and `S` balance -in `c_main`. We can see nonce in `S` proof is `0 = 128 - 128`. - -In `ACCOUNT_LEAF_NONCE_BALANCE_C` example row, there is `C` nonce stored in `s_main` and `C` balance in -`c_main`. We can see nonce in `C` proof is `1`. - -The whole account leaf looks like: -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[0,0,0,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[184,70,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] -[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - -[248,112,157,59,158,160,175,159,65,212,107,23,98,208,38,205,150,63,244,2,185, -236,246,95,240,224,191,229,27,102,202,231,184,80 There are 112 -bytes after the first two bytes. 157 means the key is 29 (157 - -128) bytes long. Nonce, balance, storage, codehash are string in -RLP: s_rlp1 and s_rlp2 contains the length of this string, for -example 184 80 means the second part is of length 1 (183 + 1 = -184) and there are 80 bytes in this string. Then there is a list -rlp meta data 248 78 where (this is stored in c_rlp1 and -c_rlp2) 78 = 3 (nonce) + 9 (balance) + 33 (storage) + 33 -(codehash). We have nonce in s_main.bytes and balance in c_main.bytes. -s_rlp1 s_rlp2 c_rlp1 c_rlp2 s_main.bytes c_main.bytes -184 80 248 78 nonce balance - -If nonce (same holds for balance) is smaller or equal to 128, then it will -occupy only one byte: `s_main.bytes[0]` (`c_main.bytes[0]` for -balance). For example, the row [184,70,128,0,...,0] holds 128 in -bytes[0] which means nonce = 128 - 128 = 0. For example, the row -[184,70,1,0,...,0] holds 1 in bytes[0] which means nonce = 1. -In case nonce (same for balance) is bigger than 128, it will occupy more than -1 byte. The example row below shows nonce value 142, while 129 -means there is a nonce of byte length `1 = 129 - 128`. -Balance in the example row below is: 28 + 5 * 256 + 107 * 256^2 + ... + 59 * -256^6, while 135 means there are 7 = 135 - 128 bytes. -``` -[rlp1 rlp2 bytes[0] bytes[1]] rlp1 rlp2 bytes[0] bytes[1] ... ] -[184 78 129 142 0 0 ... 0 248 76 135 28 5 107 201 118 120 59 0 0 ... 0] -The `sel1` column in the `ACCOUNT_LEAF_KEY_S` or `ACCOUNT_LEAF_KEY_C` row -is used to mark whether nonce is of 1 byte (short) or more than 1 byte (long). -`sel1 = 1` means long, `sel1 = 0` means short. -`Bool check is_nonce_long` constraint ensures the `sel1` value is boolean. -Analogously, `sel2` holds the information whether balance is long or short. -`Bool check is_balance_long` constraint ensures the `sel2` value is boolean. - - -Lookups: -We have nonce and balance in the same row - to enable lookups into the same columns (`value_prev`, `value`), -we enable nonce lookup in `ACCOUNT_LEAF_NONCE_BALANCE_S` row and balance lookup in `ACCOUNT_LEAF_NONCE_BALANCE_C` row. -This means we copy nonce C RLC to `ACCOUNT_LEAF_NONCE_BALANCE_S` row, -and balance S RLC to `ACCOUNT_LEAF_NONCE_BALANCE_C` row. -Constraints are added to ensure everything is properly copied. - -Note: when nonce or balance is 0, the actual value in the RLP encoding is -128! TODO: when finalizing lookups, having 128 instead of 0 -needs to be taken into account. - -*/ -#[derive(Clone, Debug, Default)] -pub(crate) struct AccountLeafNonceBalanceConfig { - _marker: PhantomData, -} - -impl AccountLeafNonceBalanceConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - is_s: bool, - ) -> Self { - let proof_type = ctx.proof_type; - let s_main = ctx.s_main; - let c_main = ctx.c_main; - let accs = ctx.accumulators; - let value_prev = ctx.value_prev; - let value = ctx.value; - let r = ctx.r.clone(); - - let rot_key = if is_s { - -(ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) - } else { - -(ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) - }; - let rot_s = if is_s { - 0 - } else { - -(ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_NONCE_BALANCE_S_IND) - }; - - circuit!([meta, cb.base], { - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - - // The two string RLP bytes stored in the s RLP bytes. - // The two list RLP bytes are stored in the c RLP bytes. - // The RLP bytes of nonce/balance are stored bytes[0]. - - // RLC calculation for nonce/balance - let nonce = DataTransition::new(meta, accs.s_mod_node_rlc); - let balance = DataTransition::new(meta, accs.c_mod_node_rlc); - let mult_diff_nonce = a!(accs.acc_c.rlc); - let mult_diff_balance = a!(accs.key.mult); - let mut calc_rlc = |data: Expression, - is_long: Expression, - mult_diff: Expression, - mult_offset: u64, - is_s: bool| { - // The is_long selector needs to be boolean - require!(is_long => bool); - // Calculate the RLC - let (num_bytes, value_rlc) = ifx! {is_long => { - let num_bytes = get_num_bytes_short(a!(ctx.main(is_s).bytes[0])); - let value_rlc = ctx.main(is_s).bytes(meta, 0)[1..].to_vec().rlc(&r); - (num_bytes, value_rlc) - } elsex { - (1.expr(), a!(ctx.main(is_s).bytes[0])) - }}; - require!(data => value_rlc); - // RLC bytes zero check (+2 because data starts at bytes[0]) - cb.set_length_sc(is_s, 2.expr() + num_bytes.expr()); - // Get the correct multiplier for the length - require!((FixedTableTag::RMult, num_bytes.expr() + mult_offset.expr(), mult_diff) => @format!("mult{}", if is_s {""} else {"2"})); - - // Go from the value rlc to the data rlc - let rlc = account.to_data_rlc(meta, ctx.main(is_s), value_rlc, is_long, 0); - (rlc, num_bytes) - }; - let (nonce_rlc, nonce_num_bytes) = calc_rlc( - nonce.expr(), - account.is_nonce_long(), - mult_diff_nonce.expr(), - 4, - true, - ); - let (balance_rlc, balance_num_bytes) = calc_rlc( - balance.expr(), - account.is_balance_long(), - mult_diff_balance.expr(), - 0, - false, - ); - - // Calculate and store the combined nonce + balance multipliers - let account_rlc = DataTransition::new_with_rot(meta, accs.acc_s.rlc, rot_key, 0); - let mult_prev = a!(accs.acc_s.mult, rot_key); - // Multipliers - let mult_after_nonce = a!(accs.acc_c.mult); - let mult_diff_balance = a!(accs.key.mult); - let acc_mult_final = a!(accs.acc_s.mult); - require!(mult_after_nonce => mult_prev.expr() * mult_diff_nonce.expr()); - require!(acc_mult_final => mult_after_nonce.expr() * mult_diff_balance.expr()); - // Store the RLP bytes + nonce + balance RLC. - let rlc = account_rlc.prev() - + account.nonce_balance_rlc( - meta, - nonce_rlc.expr(), - balance_rlc.expr(), - mult_prev.expr(), - mult_diff_nonce.expr(), - 0, - ); - require!(account_rlc => rlc); - - // Check the RLP encoding consistency. - // RlP encoding: account = [key, [nonce, balance, storage, codehash]] - // The only exception is when `is_non_existing_account_proof = 1` & - // `is_wrong_leaf = 0`. In this case the value does not matter as - // the account leaf is only a placeholder and does not use - // `s_main.rlp1` and `s_main.rlp2`. - // TODO(Brecht): Can we remove this if by just making this pass in this special - // case? - ifx! {not!(and::expr(&[a!(proof_type.is_non_existing_account_proof), not!(account.is_wrong_leaf(meta, is_s))])) => { - // We always store between 55 and 256 bytes of data in the values list. - require!(a!(s_main.rlp1) => RLP_LONG + 1); - // The RLP encoded list always has 2 RLP bytes (the c RLP bytes). - require!(a!(s_main.rlp2) => a!(c_main.rlp2) + 2.expr()); - // `c_main.rlp1` always needs to be RLP_LIST_LONG + 1. - require!(a!(c_main.rlp1) => RLP_LIST_LONG + 1); - // The length of the list is `#(nonce bytes) + #(balance bytes) + 2 * (1 + #(hash))`. - require!(a!(c_main.rlp2) => nonce_num_bytes.expr() + balance_num_bytes.expr() + (2 * (1 + 32)).expr()); - // Now check that the the key and value list length matches the account length. - let len = account.num_bytes(meta); - let key_num_bytes = account.num_bytes_on_key_row(meta); - // The RLP encoded string always has 2 RLP bytes (the s RLP bytes). - let value_list_num_bytes = a!(s_main.rlp2) + 2.expr(); - // Account length needs to equal all key bytes and all values list bytes. - require!(len => key_num_bytes + value_list_num_bytes); - }} - - // To enable lookups we need to have the previous/current nonce/balance on the - // same row - if !is_s { - require!(a!(value_prev, rot_s) => nonce.prev()); - require!(a!(value, rot_s) => nonce); - require!(a!(value_prev) => balance.prev()); - require!(a!(value) => balance); - } - - // Check that there is only one modification. - if !is_s { - // Note: For `is_non_existing_account_proof` we do not need this constraint, - // `S` and `C` proofs are the same and we need to do a lookup into only one - // (the other one could really be whatever). - ifx! {not!(a!(proof_type.is_account_delete_mod)) => { - // Nonce needs to remain the same when not modifying the nonce - ifx!{not!(a!(proof_type.is_nonce_mod)) => { - require!(nonce => nonce.prev()); - }} - // Balance needs to remain the same when not modifying the balance - ifx!{not!(a!(proof_type.is_balance_mod)) => { - require!(balance => balance.prev()); - }} - }} - } - }); - - AccountLeafNonceBalanceConfig { - _marker: PhantomData, - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &mut ProofValues, - row: &MptWitnessRow, - offset: usize, - ) { - let mut nonce_len: usize = 1; - // Note: when nonce or balance is 0, the actual value stored in RLP encoding is - // 128. - if row.get_byte(S_START) > 128 { - nonce_len = row.get_byte(S_START) as usize - 128 + 1; // +1 for byte with length info - region - .assign_advice( - || "assign sel1".to_string(), - mpt_config.denoter.sel1, - offset - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, - || Value::known(F::one()), - ) - .ok(); - } else { - region - .assign_advice( - || "assign sel1".to_string(), - mpt_config.denoter.sel1, - offset - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, - || Value::known(F::zero()), - ) - .ok(); - } - - let mut balance_len: usize = 1; - if row.get_byte(C_START) > 128 { - balance_len = row.get_byte(C_START) as usize - 128 + 1; // +1 for byte with length info - region - .assign_advice( - || "assign sel2".to_string(), - mpt_config.denoter.sel2, - offset - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, - || Value::known(F::one()), - ) - .ok(); - } else { - region - .assign_advice( - || "assign sel2".to_string(), - mpt_config.denoter.sel2, - offset - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, - || Value::known(F::zero()), - ) - .ok(); - } - - // nonce value RLC and balance value RLC: - pv.rlc1 = F::zero(); - pv.rlc2 = F::zero(); - // Note: Below, it first computes and assigns the nonce RLC and balance RLC - // without RLP specific byte (there is a RLP specific byte when - // nonce/balance RLP length > 1). - if nonce_len == 1 && balance_len == 1 { - mpt_config - .compute_rlc_and_assign( - region, - &row.bytes, - pv, - offset, - (S_START, HASH_WIDTH), - (C_START, HASH_WIDTH), - ) - .ok(); - } else if nonce_len > 1 && balance_len == 1 { - mpt_config - .compute_rlc_and_assign( - region, - &row.bytes, - pv, - offset, - (S_START + 1, HASH_WIDTH - 1), - (C_START, HASH_WIDTH), - ) - .ok(); - } else if nonce_len == 1 && balance_len > 1 { - mpt_config - .compute_rlc_and_assign( - region, - &row.bytes, - pv, - offset, - (S_START, HASH_WIDTH), - (C_START + 1, HASH_WIDTH - 1), - ) - .ok(); - } else if nonce_len > 1 && balance_len > 1 { - mpt_config - .compute_rlc_and_assign( - region, - &row.bytes, - pv, - offset, - (S_START + 1, HASH_WIDTH - 1), - (C_START + 1, HASH_WIDTH - 1), - ) - .ok(); - } - - let mut acc_account; - let mut acc_mult_account; - if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { - pv.nonce_value_s = pv.rlc1; - pv.balance_value_s = pv.rlc2; - - acc_account = pv.acc_account_s; - acc_mult_account = pv.acc_mult_account_s; - - if row.get_byte_rev(IS_NONCE_MOD_POS) == 1 { - region - .assign_advice( - || "assign which lookup type enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(1_u64)), - ) - .ok(); - } - } else { - acc_account = pv.acc_account_c; - acc_mult_account = pv.acc_mult_account_c; - - let nonce_value_c = pv.rlc1; - let balance_value_c = pv.rlc2; - - if row.get_byte_rev(IS_BALANCE_MOD_POS) == 1 { - region - .assign_advice( - || "assign which lookup type enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(2_u64)), - ) - .ok(); - } - - let offset_s = offset - - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_NONCE_BALANCE_S_IND) as usize; - - // assign nonce S RLC in ACCOUNT_LEAF_NONCE_BALANCE_S row. - region - .assign_advice( - || "assign nonce S".to_string(), - mpt_config.value_prev, - offset_s, - || Value::known(pv.nonce_value_s), - ) - .ok(); - - // Assign nonce C RLC in ACCOUNT_LEAF_NONCE_BALANCE_S row. - region - .assign_advice( - || "assign nonce C".to_string(), - mpt_config.value, - offset_s, - || Value::known(nonce_value_c), - ) - .ok(); - - // assign balance S RLC in ACCOUNT_LEAF_NONCE_BALANCE_C row. - region - .assign_advice( - || "assign value_prev".to_string(), - mpt_config.value_prev, - offset, - || Value::known(pv.balance_value_s), - ) - .ok(); - - // Assign balance C RLC in ACCOUNT_LEAF_NONCE_BALANCE_C row. - region - .assign_advice( - || "assign balance C".to_string(), - mpt_config.value, - offset, - || Value::known(balance_value_c), - ) - .ok(); - } - - // s_rlp1, s_rlp2 - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut acc_account, - &mut acc_mult_account, - S_START - 2, - 2, - ); - // c_rlp1, c_rlp2 - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut acc_account, - &mut acc_mult_account, - C_START - 2, - 2, - ); - // nonce contribution to leaf RLC: - /* - If nonce stream length is 1, it doesn't have - the first byte with length info. Same for balance. - There are four possibilities: - - nonce is short (length 1), balance is short (length 1) - - nonce is short, balance is long - - nonce is long, balance is short - - nonce is long, balance is long - We put this info in sel1/sel2 in the key row (sel1/sel2 are - already used for other purposes in nonce balance row): - - sel1/sel2: 0/0 (how to check: (1-sel1)*(1-sel2)) - - sel1/sel2: 0/1 (how to check: (1-sel1)*sel2) - - sel1/sel2: 1/0 (how to check: sel1*(1-sel2)) - - sel1/sel2: 1/1 (how to check: sel1*sel2) - */ - - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut acc_account, - &mut acc_mult_account, - S_START, - nonce_len, - ); - - let mut mult_diff_s = F::one(); - for _ in 0..nonce_len + 4 { - // + 4 because of s_rlp1, s_rlp2, c_rlp1, c_rlp2 - mult_diff_s *= mpt_config.randomness; - } - - // It's easier to constrain (in account_leaf_nonce_balance.rs) - // the multiplier if we store acc_mult both after nonce and after - // balance. - let acc_mult_tmp = acc_mult_account; - - // balance contribution to leaf RLC - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut acc_account, - &mut acc_mult_account, - C_START, - balance_len, - ); - - let mut mult_diff_c = F::one(); - for _ in 0..balance_len { - mult_diff_c *= mpt_config.randomness; - } - - mpt_config - .assign_acc( - region, - acc_account, - acc_mult_account, - F::zero(), - acc_mult_tmp, - offset, - ) - .ok(); - - region - .assign_advice( - || "assign mult diff".to_string(), - mpt_config.accumulators.acc_c.rlc, /* assigning key_rlc leads into - * PoisonedConstraint */ - offset, - || Value::known(mult_diff_s), - ) - .ok(); - region - .assign_advice( - || "assign mult diff".to_string(), - mpt_config.accumulators.key.mult, - offset, - || Value::known(mult_diff_c), - ) - .ok(); - if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { - pv.acc_nonce_balance_s = acc_account; - pv.acc_mult_nonce_balance_s = acc_mult_account; - } else { - pv.acc_nonce_balance_c = acc_account; - pv.acc_mult_nonce_balance_c = acc_mult_account; - } - } -} diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_storage_codehash.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_storage_codehash.rs deleted file mode 100644 index b71dee7d4e..0000000000 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_leaf_storage_codehash.rs +++ /dev/null @@ -1,333 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, - plonk::VirtualCells, - poly::Rotation, -}; - -use crate::{ - circuit, - circuit_tools::{CellManager, DataTransition, RLCable}, - mpt_circuit::witness_row::{MptWitnessRow, MptWitnessRowType}, - mpt_circuit::{ - helpers::{ - parent_memory, AccountLeafInfo, BranchNodeInfo, MPTConstraintBuilder, ParentData, - }, - param::{ - ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND, - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, BRANCH_ROWS_NUM, C_START, HASH_WIDTH, - IS_CODEHASH_MOD_POS, RLP_HASH_VALUE, S_START, - }, - MPTContext, - }, - mpt_circuit::{MPTConfig, ProofValues}, -}; - -/* -An account leaf occupies 8 rows. -Contrary as in the branch rows, the `S` and `C` leaves are not positioned parallel to each other. -The rows are the following: -ACCOUNT_LEAF_KEY_S -ACCOUNT_LEAF_KEY_C -ACCOUNT_NON_EXISTING -ACCOUNT_LEAF_NONCE_BALANCE_S -ACCOUNT_LEAF_NONCE_BALANCE_C -ACCOUNT_LEAF_STORAGE_CODEHASH_S -ACCOUNT_LEAF_STORAGE_CODEHASH_C -ACCOUNT_DRIFTED_LEAF - -The constraints in this file apply to ACCOUNT_LEAF_STORAGE_CODEHASH_S and -ACCOUNT_LEAF_STORAGE_CODEHASH_C rows. - -For example, the two rows might be: -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] - -Here, in `ACCOUNT_LEAF_STORAGE_CODEHASH_S` example row, there is `S` storage root stored in `s_main.bytes` -and `S` codehash in `c_main.bytes`. Both these values are hash outputs. -We can see `s_main.rlp2 = 160` which specifies that the length of the following string is `32 = 160 - 128` -(which is hash output). Similarly, `c_main.rlp2 = 160`. - -In `ACCOUNT_LEAF_STORAGE_CODEHASH_C` example row, there is `C` storage root stored in `s_main.bytes` -and `C` codehash in `c_main.bytes`. Both these values are hash outputs. - -The whole account leaf looks like: -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[0,0,0,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[184,70,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] -[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - -Lookups: -The `is_codehash_mod` lookup is enabled in `ACCOUNT_LEAF_STORAGE_CODEHASH_C` row. -*/ - -#[derive(Clone, Debug)] -pub(crate) struct AccountLeafStorageCodehashConfig { - parent_data: ParentData, -} - -impl AccountLeafStorageCodehashConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - is_s: bool, - ) -> Self { - let proof_type = ctx.proof_type; - let position_cols = ctx.position_cols; - let s_main = ctx.s_main; - let c_main = ctx.c_main; - let r = ctx.r.clone(); - let accs = ctx.accumulators; - let value_prev = ctx.value_prev; - let value = ctx.value; - - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); - let ctx_parent_data: Option>; - - let rot_nonce_balance = -2; - let rot_key = -if is_s { - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND - ACCOUNT_LEAF_KEY_S_IND - } else { - ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND - ACCOUNT_LEAF_KEY_C_IND - }; - let rot_branch_init = if is_s { - -ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND - } else { - -ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND - } - BRANCH_ROWS_NUM; - let rot_s = if is_s { - 0 - } else { - -(ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND) - }; - - // Note: differently as in storage leaf value (see empty_trie - // there), the placeholder leaf never appears in the first level here, - // because there is always at least a genesis account. - circuit!([meta, cb.base], { - ifx! {f!(position_cols.q_not_first), a!(ctx.account_leaf.is_storage_codehash(is_s)) => { - // rlp1 is not used, rlp2 is used to store the first RLP byte. - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - - // When non_existing_account_proof and not wrong leaf there is only a placeholder account leaf - // and the constraints in this gate are not triggered. In that case it is checked - // that there is nil in the parent branch at the proper position (see `account_non_existing.rs`), note - // that we need (placeholder) account leaf for lookups and to know when to check that parent branch - // has a nil. - // TODO(Brecht): Can we remove this if by just making this pass in this special case? - ifx! {not!(and::expr(&[a!(proof_type.is_non_existing_account_proof), not!(account.is_wrong_leaf(meta, is_s))])) => { - // Storage root and codehash are always 32-byte hashes. - require!(a!(s_main.rlp2) => RLP_HASH_VALUE); - require!(a!(c_main.rlp2) => RLP_HASH_VALUE); - }} - - // RLC calculation - let account_rlc = DataTransition::new_with_rot(meta, accs.acc_s.rlc, rot_nonce_balance, 0); - let mult_prev = a!(accs.acc_s.mult, rot_nonce_balance); - // - Storage root - let storage_root = DataTransition::new(meta, accs.s_mod_node_rlc); - require!(storage_root => s_main.bytes(meta, 0).rlc(&r)); - // - Codehash - let codehash = DataTransition::new(meta, accs.c_mod_node_rlc); - require!(codehash => c_main.bytes(meta, 0).rlc(&r)); - // The full account leaf RLC - let rlc = account_rlc.prev() + account.storage_codehash_rlc(meta, storage_root.expr(), codehash.expr(), mult_prev.expr(), 0); - require!(account_rlc => rlc); - - // Check if the account is in its parent. - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let parent_data = ParentData::load("storage load", &mut cb.base, &mut cm, &ctx.memory[parent_memory(is_s)], 0.expr()); - // Check is skipped for placeholder leafs which are dummy leafs - ifx!{not!(and::expr(&[a!(position_cols.not_first_level), not!(branch.is_placeholder()), branch.contains_placeholder_leaf(meta, is_s)])) => { - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - require!((1, account_rlc, account.num_bytes(meta), parent_data.rlc) => @"keccak"); - }} - // Store the new parent - ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [storage_root.expr(), true.expr()]); - ctx_parent_data = Some(parent_data); - - if !is_s { - // To enable lookups we need to have the previous/current storage root/code hash on the same row. - require!(a!(value_prev, rot_s) => storage_root.prev()); - require!(a!(value, rot_s) => storage_root); - require!(a!(value_prev) => codehash.prev()); - require!(a!(value) => codehash); - - // Check that there is only one modification (except when the account is being deleted). - ifx!{not!(a!(proof_type.is_account_delete_mod)) => { - // Storage root needs to remain the same when not modifying the storage root - ifx!{not!(a!(proof_type.is_storage_mod)) => { - require!(storage_root => storage_root.prev()); - }} - // Codehash root needs to remain the same when not modifying the codehash - ifx!{not!(a!(proof_type.is_codehash_mod)) => { - require!(codehash => codehash.prev()); - }} - }} - } - }} - }); - - AccountLeafStorageCodehashConfig { - parent_data: ctx_parent_data.unwrap(), - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &mut ProofValues, - row: &MptWitnessRow, - offset: usize, - ) { - if row.get_type() == MptWitnessRowType::AccountLeafRootCodehashS { - pv.acc_s = pv.acc_nonce_balance_s; - pv.acc_mult_s = pv.acc_mult_nonce_balance_s; - - // storage root RLC and code hash RLC - pv.rlc1 = F::zero(); - pv.rlc2 = F::zero(); - mpt_config - .compute_rlc_and_assign( - region, - &row.bytes, - pv, - offset, - (S_START, HASH_WIDTH), - (C_START, HASH_WIDTH), - ) - .ok(); - pv.storage_root_value_s = pv.rlc1; - pv.codehash_value_s = pv.rlc2; - } else { - pv.acc_s = pv.acc_nonce_balance_c; - pv.acc_mult_s = pv.acc_mult_nonce_balance_c; - - // assign storage root RLC and code hash RLC for this row - pv.rlc1 = F::zero(); - pv.rlc2 = F::zero(); - mpt_config - .compute_rlc_and_assign( - region, - &row.bytes, - pv, - offset, - (S_START, HASH_WIDTH), - (C_START, HASH_WIDTH), - ) - .ok(); - - let storage_root_value_c = pv.rlc1; - let codehash_value_c = pv.rlc2; - - pv.storage_root_value_c = storage_root_value_c; - - if row.get_byte_rev(IS_CODEHASH_MOD_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(3_u64)), // codehash mod lookup enabled in this row if it is is_codehash_mod proof - ) - .ok(); - } - - let offset_s = offset - - (ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND) - as usize; - - // Assign storage root S - region - .assign_advice( - || "assign storage root S".to_string(), - mpt_config.value_prev, - offset_s, - || Value::known(pv.storage_root_value_s), - ) - .ok(); - - // Assign storage root C - region - .assign_advice( - || "assign code hash C".to_string(), - mpt_config.value, - offset_s, - || Value::known(storage_root_value_c), - ) - .ok(); - - // Assign code hash S - region - .assign_advice( - || "assign code hash S".to_string(), - mpt_config.value_prev, - offset, - || Value::known(pv.codehash_value_s), - ) - .ok(); - - // Assign code hash C - region - .assign_advice( - || "assign code hash C".to_string(), - mpt_config.value, - offset, - || Value::known(codehash_value_c), - ) - .ok(); - } - - let is_s = row.get_type() == MptWitnessRowType::AccountLeafRootCodehashS; - let storage_root = if is_s { - pv.storage_root_value_s - } else { - pv.storage_root_value_c - }; - self.parent_data - .witness_load(region, offset, &mut pv.memory[parent_memory(is_s)], 0) - .ok(); - self.parent_data - .witness_store( - region, - offset, - &mut pv.memory[parent_memory(is_s)], - storage_root, - true, - ) - .ok(); - - // storage - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - S_START - 1, - HASH_WIDTH + 1, - ); - // code hash - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - C_START - 1, - HASH_WIDTH + 1, - ); - mpt_config - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) - .ok(); - } -} diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs b/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs deleted file mode 100644 index 4d646b1637..0000000000 --- a/zkevm-circuits/src/mpt_circuit/account_leaf/account_non_existing.rs +++ /dev/null @@ -1,203 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, - plonk::VirtualCells, - poly::Rotation, -}; - -use crate::{ - circuit, - circuit_tools::CellManager, - mpt_circuit::witness_row::MptWitnessRow, - mpt_circuit::{ - helpers::{bytes_into_rlc, KeyData, key_memory}, - param::{ACCOUNT_NON_EXISTING_IND}, - ProofValues, - }, - mpt_circuit::{ - helpers::{AccountLeafInfo, MPTConstraintBuilder}, - MPTContext, - }, - mpt_circuit::{param::IS_NON_EXISTING_ACCOUNT_POS, MPTConfig}, -}; - -/* -An account leaf occupies 8 rows. -Contrary as in the branch rows, the `S` and `C` leaves are not positioned parallel to each other. -The rows are the following: -ACCOUNT_LEAF_KEY_S -ACCOUNT_LEAF_KEY_C -ACCOUNT_NON_EXISTING -ACCOUNT_LEAF_NONCE_BALANCE_S -ACCOUNT_LEAF_NONCE_BALANCE_C -ACCOUNT_LEAF_STORAGE_CODEHASH_S -ACCOUNT_LEAF_STORAGE_CODEHASH_C -ACCOUNT_DRIFTED_LEAF - -The constraints in this file apply to ACCOUNT_NON_EXISTING. - -For example, the row might be: -[0,0,0,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - -We are proving that there is no account at the specified address. There are two versions of proof: - 1. A leaf is returned by getProof that is not at the required address (we call this a wrong leaf). - In this case, the `ACCOUNT_NON_EXISTING` row contains the nibbles of the address (the nibbles that remain - after the nibbles used for traversing through the branches are removed) that was enquired - while `ACCOUNT_LEAF_KEY` row contains the nibbles of the wrong leaf. We need to prove that - the difference is nonzero. This way we prove that there exists some account which has some - number of the starting nibbles the same as the enquired address (the path through branches - above the leaf), but at the same time the full address is not the same - the nibbles stored in a leaf differ. - 2. A branch is the last element of the getProof response and there is a nil object - at the address position. Placeholder account leaf is added in this case. - In this case, the `ACCOUNT_NON_EXISTING` row contains the same nibbles as `ACCOUNT_LEAF_KEY` and it is - not needed. We just need to prove that the branch contains nil object (128) at the enquired address. - -The whole account leaf looks like: -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[248,106,161,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[0,0,0,32,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[184,70,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] -[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,122] -[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - -We can observe that the example account leaf above is not for non-existing account proof as the first and third -rows contain the same nibbles (the difference is solely in RLP specific bytes which are not needed -in `ACCOUNT_NON_EXISTING` row). - -For the example of non-existing account proof account leaf see below: - -[248 102 157 55 236 125 29 155 142 209 241 75 145 144 143 254 65 81 209 56 13 192 157 236 195 213 73 132 11 251 149 241 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6] -[248 102 157 55 236 125 29 155 142 209 241 75 145 144 143 254 65 81 209 56 13 192 157 236 195 213 73 132 11 251 149 241 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4] -[1 0 157 56 133 130 180 167 143 97 28 115 102 25 94 62 148 249 8 6 55 244 16 75 187 208 208 127 251 120 61 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18] -[184 70 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 248 68 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7] -[184 70 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 248 68 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8] -[0 160 112 158 181 221 162 20 124 79 184 25 162 13 167 162 146 25 237 242 59 120 184 154 118 137 92 181 187 152 115 82 223 48 0 160 7 190 1 231 231 32 111 227 30 206 233 26 215 93 173 166 90 214 186 67 58 230 71 161 185 51 4 105 247 198 103 124 0 9] -[0 160 112 158 181 221 162 20 124 79 184 25 162 13 167 162 146 25 237 242 59 120 184 154 118 137 92 181 187 152 115 82 223 48 0 160 7 190 1 231 231 32 111 227 30 206 233 26 215 93 173 166 90 214 186 67 58 230 71 161 185 51 4 105 247 198 103 124 0 11] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10] - -In this case, the nibbles in the third row are different from the nibbles in the first or second row. Here, we are -proving that the account does not exist at the address which starts with the same nibbles as the leaf that is -in the rows above (except for the `ACCOUNT_NON_EXISTING` row) and continues with nibbles `ACCOUNT_NON_EXISTING` row. - -Note that the selector (being 1 in this case) at `s_main.rlp1` specifies whether it is wrong leaf or nil case. - -Lookups: -The `non_existing_account_proof` lookup is enabled in `ACCOUNT_NON_EXISTING` row. - -Differently than for the other proofs, the account-non-existing proof compares `address_rlc` -with the address stored in `ACCOUNT_NON_EXISTING` row, not in `ACCOUNT_LEAF_KEY` row. -The crucial thing is that we have a wrong leaf at the address (not exactly the same, just some starting -set of nibbles is the same) where we are proving there is no account. -If there would be an account at the specified address, it would be positioned in the branch where -the wrong account is positioned. Note that the position is determined by the starting set of nibbles. -Once we add the remaining nibbles to the starting ones, we need to obtain the enquired address. - -/* Non existing account proof leaf address RLC (leaf in first level) */ -Ensuring that the account does not exist when there is only one account in the state trie. -Note 1: The hash of the only account is checked to be the state root. -Note 2: There is no nil_object case checked in this gate, because it is covered in the gate -above. That is because when there is a branch (with nil object) in the first level, -it automatically means the account leaf is not in the first level. - -*/ - -#[derive(Clone, Debug)] -pub(crate) struct AccountNonExistingConfig { - key_data: KeyData, -} - -impl AccountNonExistingConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - ) -> Self { - let proof_type = ctx.proof_type; - let accs = ctx.accumulators; - let address_rlc = ctx.address_rlc; - - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); - let ctx_key_data: Option>; - - let rot_key_s = -ACCOUNT_NON_EXISTING_IND; - - circuit!([meta, cb.base], { - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key_s); - - // Make sure is_wrong_leaf is boolean - require!(account.is_wrong_leaf(meta, true) => bool); - - ifx! {a!(proof_type.is_non_existing_account_proof) => { - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 1.expr()); - ifx! {account.is_wrong_leaf(meta, true) => { - // Calculate the key and check it's the address as requested in the lookup - let key_rlc_wrong = key_data.rlc.expr() + account.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), -rot_key_s); - require!(a!(address_rlc) => key_rlc_wrong); - // Now make sure this address is different than the one of the leaf - let diff_inv = a!(accs.acc_s.rlc); - require!((a!(address_rlc) - a!(accs.key.rlc, rot_key_s)) * diff_inv => 1); - // Make sure the lengths of the keys are the same - let account_wrong = AccountLeafInfo::new(meta, ctx.clone(), 0); - require!(account_wrong.key_len(meta) => account.key_len(meta)); - // RLC bytes zero check - let leaf = AccountLeafInfo::new(meta, ctx.clone(), 0); - let num_bytes = leaf.num_bytes_on_key_row(meta); - cb.set_length(num_bytes); - } elsex { - // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. - require!(key_data.is_placeholder_leaf_s => true); - }} - ctx_key_data = Some(key_data); - } elsex { - // is_wrong_leaf needs to be false when not in non_existing_account proof - require!(account.is_wrong_leaf(meta, true) => false); - }}; - }); - - AccountNonExistingConfig { - key_data: ctx_key_data.unwrap(), - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &mut ProofValues, - witness: &[MptWitnessRow], - offset: usize, - ) { - self.key_data - .witness_load(region, offset, &mut pv.memory[key_memory(true)], 1) - .ok(); - - let row = &witness[offset]; - let address_rlc = bytes_into_rlc(row.address_bytes(), mpt_config.randomness); - let diff_inv = (address_rlc - pv.account_key_rlc) - .invert() - .unwrap_or(F::zero()); - region - .assign_advice( - || "assign diff inv".to_string(), - mpt_config.accumulators.acc_s.rlc, - offset, - || Value::known(diff_inv), - ) - .ok(); - - if row.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(4_u64)), /* non existing account lookup enabled in - * this row if it is non_existing_account - * proof */ - ) - .ok(); - } - } -} diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index 61bff69ff0..73f9e8fb2f 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -1,8 +1,3 @@ -pub mod branch_init; -pub mod branch_key; -pub mod branch_rlc; -pub mod extension_node; - use halo2_proofs::{ arithmetic::FieldExt, circuit::{Region, Value}, @@ -17,7 +12,7 @@ use super::{ ARITY, IS_C_BRANCH_NON_HASHED_POS, IS_C_EXT_NODE_NON_HASHED_POS, IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_NODE_NON_HASHED_POS, }, - MPTContext, witness_row::MptWitnessRowType, + MPTContext, }; use crate::{ circuit, @@ -25,9 +20,13 @@ use crate::{ mpt_circuit::account_leaf::AccountLeaf, mpt_circuit::helpers::bytes_into_rlc, mpt_circuit::{ - helpers::{contains_placeholder_leaf, parent_memory, ParentData, get_num_nibbles, KeyData, key_memory}, - param::{RLP_NIL, RLP_LIST_LONG}, - storage_leaf::StorageLeaf, FixedTableTag, + helpers::{ + contains_placeholder_leaf, get_num_nibbles, key_memory, parent_memory, KeyData, + ParentData, + }, + param::{RLP_LIST_LONG, RLP_NIL}, + storage_leaf::StorageLeaf, + FixedTableTag, }, mpt_circuit::{ helpers::{BranchChildInfo, BranchNodeInfo}, @@ -43,41 +42,6 @@ use crate::{ mpt_circuit::{MPTConfig, ProofValues}, }; -/* -A branch occupies 19 rows: -BRANCH.IS_INIT -BRANCH.IS_CHILD 0 -... -BRANCH.IS_CHILD 15 -BRANCH.IS_EXTENSION_NODE_S -BRANCH.IS_EXTENSION_NODE_C - -Example: - -[1 0 1 0 248 241 0 248 241 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 164 92 78 34 81 137 173 236 78 208 145 118 128 60 46 5 176 8 229 165 42 222 110 4 252 228 93 243 26 160 241 85 0 160 95 174 59 239 229 74 221 53 227 115 207 137 94 29 119 126 56 209 55 198 212 179 38 213 219 36 111 62 46 43 176 168 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 60 157 212 182 167 69 206 32 151 2 14 23 149 67 58 187 84 249 195 159 106 68 203 199 199 65 194 33 215 102 71 138 0 160 60 157 212 182 167 69 206 32 151 2 14 23 149 67 58 187 84 249 195 159 106 68 203 199 199 65 194 33 215 102 71 138 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 21 230 18 20 253 84 192 151 178 53 157 0 9 105 229 121 222 71 120 109 159 109 9 218 254 1 50 139 117 216 194 252 0 160 21 230 18 20 253 84 192 151 178 53 157 0 9 105 229 121 222 71 120 109 159 109 9 218 254 1 50 139 117 216 194 252 1] -[0 160 229 29 220 149 183 173 68 40 11 103 39 76 251 20 162 242 21 49 103 245 160 99 143 218 74 196 2 61 51 34 105 123 0 160 229 29 220 149 183 173 68 40 11 103 39 76 251 20 162 242 21 49 103 245 160 99 143 218 74 196 2 61 51 34 105 123 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 0 140 67 252 58 164 68 143 34 163 138 133 54 27 218 38 80 20 142 115 221 100 73 161 165 75 83 53 8 58 236 1 0 160 0 140 67 252 58 164 68 143 34 163 138 133 54 27 218 38 80 20 142 115 221 100 73 161 165 75 83 53 8 58 236 1 1] -[0 160 149 169 206 0 129 86 168 48 42 127 100 73 109 90 171 56 216 28 132 44 167 14 46 189 224 213 37 0 234 165 140 236 0 160 149 169 206 0 129 86 168 48 42 127 100 73 109 90 171 56 216 28 132 44 167 14 46 189 224 213 37 0 234 165 140 236 1] -[0 160 42 63 45 28 165 209 201 220 231 99 153 208 48 174 250 66 196 18 123 250 55 107 64 178 159 49 190 84 159 179 138 235 0 160 42 63 45 28 165 209 201 220 231 99 153 208 48 174 250 66 196 18 123 250 55 107 64 178 159 49 190 84 159 179 138 235 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17] - -Note that when `BRANCH.IS_CHILD` row presents a nil node, there is only one byte non-zero: -128 at `s_main.bytes[0] / c_main.bytes[0]`. -*/ - #[derive(Default, Debug)] pub(crate) struct Branch { pub(crate) is_branch_init: bool, @@ -146,7 +110,6 @@ impl BranchConfig { let s_main = ctx.s_main; let c_main = ctx.c_main; let accs = ctx.accumulators; - let branch = ctx.branch; let r = ctx.r.clone(); let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); @@ -155,8 +118,7 @@ impl BranchConfig { let mut ctx_parent_data_c: Option> = None; circuit!([meta, cb.base], { - - let mut offset = 0; + let mut offset = -1; let rot_branch_init = offset; for is_s in [true, false] { @@ -170,18 +132,23 @@ impl BranchConfig { branch.is_branch_long(meta) => (rlp[..2].rlc(&r), r[1].expr()), branch.is_branch_very_long(meta) => (rlp[..3].rlc(&r), r[2].expr()), }; - require!(a!(accs.acc(is_s).rlc) => rlc); - require!(a!(accs.acc(is_s).mult) => mult); + require!(a!(accs.acc(is_s).rlc, offset) => rlc); + require!(a!(accs.acc(is_s).mult, offset) => mult); } // These selectors are only stored in branch init rows - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, 0); + let branch = BranchNodeInfo::new(meta, ctx.clone(), true, offset); // Boolean checks - for selector in [branch.is_placeholder_s(), branch.is_placeholder_c(), branch.is_not_hashed_s(), branch.is_not_hashed_c()] { + for selector in [ + branch.is_placeholder_s(), + branch.is_placeholder_c(), + branch.is_not_hashed_s(), + branch.is_not_hashed_c(), + ] { require!(selector => bool); } // Update the nibble counter - ifx!{not!(branch.is_extension()) => { + ifx! {not!(branch.is_extension()) => { let nibbles_counter_prev = ifx!{not!(branch.is_at_tree_top(meta)) => { branch.nibbles_counter().prev() }}; @@ -221,8 +188,10 @@ impl BranchConfig { let mult_diff = ctx.accumulators.node_mult_diff(is_s); let child = BranchChildInfo::new(meta, ctx.clone(), is_s, offset); - let branch_mult = DataTransition::new_with_rot(meta, branch.mult, offset - 1, offset); - let branch_rlc = DataTransition::new_with_rot(meta, branch.rlc, offset - 1, offset); + let branch_mult = + DataTransition::new_with_rot(meta, branch.mult, offset - 1, offset); + let branch_rlc = + DataTransition::new_with_rot(meta, branch.rlc, offset - 1, offset); // Calculate the RLC let rlc = child.rlc(meta, &mut cb.base); require!(branch_rlc => (branch_rlc.prev(), branch_mult.prev()).rlc_chain(rlc)); @@ -232,11 +201,12 @@ impl BranchConfig { // We need to check that the multiplier changes according to `num_bytes` and // update it. require!((FixedTableTag::RMult, child.num_bytes(meta), a!(mult_diff, offset)) => @format!("fixed")); - // When a value is being added (and reverse situation when deleted) to the trie - // and there is no other leaf at the position where it is to be - // added, we have empty branch child in `S` proof and hash of a - // newly added leaf at the parallel position in `C` proof. - // That means we have empty node in `S` proof at `modified_node`. + // When a value is being added (and reverse situation when deleted) to the + // trie and there is no other leaf at the position + // where it is to be added, we have empty branch + // child in `S` proof and hash of a newly added leaf + // at the parallel position in `C` proof. That means + // we have empty node in `S` proof at `modified_node`. // When this happens, we denote this situation by having a placeholder leaf. // In this case we need to make sure the node is seen as empty. ifx! {a!(ctx.branch.is_modified, offset), contains_placeholder_leaf(meta, ctx.clone(), is_s, offset) => { @@ -247,11 +217,11 @@ impl BranchConfig { } // Check that `is_modified` is enabled for the correct branch child. - ifx!{a!(ctx.branch.is_modified, offset) => { + ifx! {a!(ctx.branch.is_modified, offset) => { require!(a!(ctx.branch.node_index, offset) => a!(ctx.branch.modified_index, offset)); }} // Check that `is_drifted` is enabled for the correct branch child. - ifx!{a!(ctx.branch.is_drifted, offset) => { + ifx! {a!(ctx.branch.is_drifted, offset) => { require!(a!(ctx.branch.node_index, offset) => a!(ctx.branch.drifted_index, offset)); }} @@ -271,7 +241,8 @@ impl BranchConfig { } }}*/ - // If we have a branch child, we can only have branch child or branch init in the previous row. + // If we have a branch child, we can only have branch child or branch init in + // the previous row. /*require!(or::expr([is_branch_child.prev(), is_branch_init.prev()]) => true); // When `node_index` != 0 ifx!{node_index => { @@ -292,7 +263,8 @@ impl BranchConfig { } }}*/ - // Make sure `is_branch_child`, `node_index` and `is_last_child` are set correctly. + // Make sure `is_branch_child`, `node_index` and `is_last_child` are set + // correctly. /*ifx!{is_branch_init.prev() => { // First child when previous row is a branch init row require!(is_branch_child => true); @@ -307,14 +279,18 @@ impl BranchConfig { }}*/ if node_index == ARITY - 1 { - // Rotations could be avoided but we would need additional is_branch_placeholder column. - let mut branch = BranchNodeInfo::new(meta, ctx.clone(), true, offset - (ARITY as i32)); + // Rotations could be avoided but we would need additional is_branch_placeholder + // column. + let mut branch = + BranchNodeInfo::new(meta, ctx.clone(), true, offset - (ARITY as i32)); // `is_modified` needs to be set to 1 at exactly 1 branch child - let is_modified_values = (0..ARITY).map(|rot| a!(ctx.branch.is_modified, offset - (rot as i32))).collect::>(); + let is_modified_values = (0..ARITY) + .map(|rot| a!(ctx.branch.is_modified, offset - (rot as i32))) + .collect::>(); require!(sum::expr(&is_modified_values) => 1); - ifx!{branch.is_placeholder() => { + ifx! {branch.is_placeholder() => { // `is_drifted` needs to be set to 1 at exactly 1 branch child let is_drifted_values = (0..ARITY).map(|rot| a!(ctx.branch.is_drifted, offset - (rot as i32))).collect::>(); require!(sum::expr(&is_drifted_values) => 1); @@ -335,7 +311,13 @@ impl BranchConfig { (branch_rlc, branch.num_bytes(meta), branch.is_not_hashed()) }}; - let parent_data = ParentData::load("branch load", &mut cb.base, &mut cm, &ctx.memory[parent_memory(is_s)], 0.expr()); + let parent_data = ParentData::load( + "branch load", + &mut cb.base, + &mut cm, + &ctx.memory[parent_memory(is_s)], + 0.expr(), + ); ifx! {not!(branch.is_placeholder()) => { ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { // Hashed branch hash in parent branch @@ -353,20 +335,22 @@ impl BranchConfig { } } - // - For a branch placeholder we do not have any constraints. However, in the parallel + // - For a branch placeholder we do not have any constraints. However, in the + // parallel // (regular) branch we have an additional constraint (besides `is_modified` row - // corresponding to `mod_nod_hash_rlc`) in this case: `is_drifted` `main.bytes` RLC - // is stored in the placeholder `mod_node_hash_rlc`. For example, if there is a placeholder - // branch in `S` proof, we have: + // corresponding to `mod_nod_hash_rlc`) in this case: `is_drifted` `main.bytes` + // RLC is stored in the placeholder `mod_node_hash_rlc`. For + // example, if there is a placeholder branch in `S` proof, + // we have: // - c_mod_node_hash_rlc := `is_modified` `c_main.bytes RLC` // - s_mod_node_hash_rlc := `is_drifted` `c_main.bytes RLC` // - When `S` branch is NOT a placeholder: // - s_mod_node_rlc := `is_modified` `s_main.bytes RLC` // Run over all branch children - for rot in -(ARITY as i32)+1..=0 { + for rot in -(ARITY as i32) + 1..=0 { for is_s in [true, false] { branch.set_is_s(is_s); - ifx!{branch.is_placeholder() => { + ifx! {branch.is_placeholder() => { ifx!{a!(ctx.branch.is_drifted, offset + rot) => { let branch_rlc = ctx.main(!is_s).bytes(meta, offset + rot).rlc(&r); require!(a!(accs.mod_node_rlc(is_s), offset + rot) => branch_rlc); @@ -382,9 +366,10 @@ impl BranchConfig { } } - // When in a placeholder branch, both branches are the same - the placeholder branch and its - // parallel counterpart, which is not a placeholder, but a regular branch (newly - // added branch). The regular branch has only two non-nil nodes, + // When in a placeholder branch, both branches are the same - the placeholder + // branch and its parallel counterpart, which is not a + // placeholder, but a regular branch (newly added branch). + // The regular branch has only two non-nil nodes, // because the placeholder branch appears only when an existing // leaf drifts down into a newly added branch. Besides an // existing leaf, we have a leaf that was being added and that caused @@ -398,11 +383,13 @@ impl BranchConfig { // elsewhere, so it should not be much of an overhead. // Alternative approach would be to have a column specifying // whether there is a placeholder branch or not (we currently have this info - // only in branch init). Another alternative would be to have a column where we - // add `rlp2` value from the current row in each of the 16 - // rows. Both alternative would require additional column. - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, offset - (ARITY as i32)); - ifx!{branch.is_placeholder() => { + // only in branch init). Another alternative would be to have a column where + // we add `rlp2` value from the current row in each + // of the 16 rows. Both alternative would require + // additional column. + let branch = + BranchNodeInfo::new(meta, ctx.clone(), is_s, offset - (ARITY as i32)); + ifx! {branch.is_placeholder() => { let sum_rlp2 = (0..ARITY).into_iter().fold(0.expr(), |acc, idx| { acc + a!(ctx.main(is_s).rlp2, offset - (idx as i32)) }); @@ -422,7 +409,7 @@ impl BranchConfig { let not_first_level = a!(position_cols.not_first_level, offset); let ext = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - ifx!{ext.is_extension() => { + ifx! {ext.is_extension() => { let ext_rlc = DataTransition::from(a!(accs.acc_s.rlc, rot_s), a!(accs.acc_c.rlc, offset)); // There are two cases: @@ -542,7 +529,6 @@ impl BranchConfig { offset += 1; - let key = ctx.accumulators.key; let mult_diff = ctx.accumulators.mult_diff; @@ -557,10 +543,15 @@ impl BranchConfig { require!(branch.is_key_odd() => bool); // Load the last key values - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 0.expr()); + let key_data = KeyData::load( + &mut cb.base, + &mut cm, + &ctx.memory[key_memory(true)], + 0.expr(), + ); // Calculate the extension node key RLC when in an extension node - let key_rlc_post_ext = ifx!{branch.is_extension() => { + let key_rlc_post_ext = ifx! {branch.is_extension() => { let key_rlc_ext = DataTransition::new_with_rot(meta, key.rlc, offset - 1, offset); // Extension key rlc let ext_key_rlc = key_data.rlc.expr() + branch.ext_key_rlc(meta, &mut cb.base, key_data.mult.expr(), offset); @@ -577,7 +568,7 @@ impl BranchConfig { }}; // Get the length of the key - let key_num_bytes_for_mult = ifx!{branch.is_extension() => { + let key_num_bytes_for_mult = ifx! {branch.is_extension() => { // Unless both parts of the key are odd, subtract 1 from the key length. let key_len = branch.ext_key_len(meta, offset - 1); key_len - ifx! {not!(key_data.is_odd.expr() * branch.is_key_part_in_ext_odd()) => { 1.expr() }} @@ -588,7 +579,7 @@ impl BranchConfig { // Now update the key RLC and multiplier for the branch nibble. let mult = key_data.mult.expr() * mult_diff.expr(); - let (nibble_mult, mult_mult) = ifx!{branch.is_key_odd() => { + let (nibble_mult, mult_mult) = ifx! {branch.is_key_odd() => { // The nibble will be added as the most significant nibble using the same multiplier (16.expr(), 1.expr()) } elsex { @@ -599,7 +590,7 @@ impl BranchConfig { require!(key_mult => mult.expr() * mult_mult.expr()); // Update key parity - ifx!{branch.is_extension() => { + ifx! {branch.is_extension() => { // We need to take account the nibbles of the extension node. // The parity alternates when there's an even number of nibbles, remains the same otherwise ifx!{branch.is_key_part_in_ext_even() => { @@ -613,14 +604,18 @@ impl BranchConfig { }} for is_s in [true, false] { - KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], [ - key_rlc.expr(), - key_mult.expr(), - branch.nibbles_counter().expr(), - branch.is_key_odd(), - branch.contains_placeholder_leaf(meta, true), - branch.contains_placeholder_leaf(meta, false), - ]); + KeyData::store( + &mut cb.base, + &ctx.memory[key_memory(is_s)], + [ + key_rlc.expr(), + key_mult.expr(), + branch.nibbles_counter().expr(), + branch.is_key_odd(), + branch.contains_placeholder_leaf(meta, true), + branch.contains_placeholder_leaf(meta, false), + ], + ); } // We need to check that the nibbles we stored in s are between 0 and 15. @@ -644,9 +639,8 @@ impl BranchConfig { pv: &mut ProofValues, offset: usize, ) -> Result<(), Error> { - let base_offset = offset; - let mut offset = offset; + let mut offset = offset - 1; /* INIT */ let row = &witness[offset]; @@ -833,7 +827,6 @@ impl BranchConfig { /* CHILD */ for node_index in 0..ARITY { - let row = &witness[offset]; let mut node_mult_diff_s = F::one(); @@ -916,8 +909,8 @@ impl BranchConfig { &mut pv.extension_node_rlc, &mut pv.key_rlc_mult, key_len_pos + 2, /* first position behind key_len_pos - * is 0 (because is_even), we start - * with the next one */ + * is 0 (because is_even), we start + * with the next one */ key_len, ); pv.mult_diff = F::one(); @@ -949,7 +942,8 @@ impl BranchConfig { first_nibble * 16 + second_nibble, ext_row.get_byte(key_len_pos + 2 + k), ); - pv.extension_node_rlc += F::from(first_nibble as u64) * pv.key_rlc_mult; + pv.extension_node_rlc += + F::from(first_nibble as u64) * pv.key_rlc_mult; pv.key_rlc_mult *= mpt_config.randomness; pv.mult_diff *= mpt_config.randomness; @@ -1006,7 +1000,8 @@ impl BranchConfig { pv.key_rlc_sel = !pv.key_rlc_sel; } else if pv.is_odd && pv.is_long { pv.extension_node_rlc += - F::from((ext_row.get_byte(key_len_pos + 1) - 16) as u64) * pv.key_rlc_mult; + F::from((ext_row.get_byte(key_len_pos + 1) - 16) as u64) + * pv.key_rlc_mult; pv.key_rlc_mult *= mpt_config.randomness; @@ -1017,9 +1012,9 @@ impl BranchConfig { &mut pv.extension_node_rlc, &mut pv.key_rlc_mult, key_len_pos + 2, /* the first position after key_len_pos - * is single nibble which is taken into - * account above, we start - * with fourth */ + * is single nibble which is taken into + * account above, we start + * with fourth */ key_len - 1, // one byte is occupied by single nibble ); pv.mult_diff = F::one(); @@ -1028,7 +1023,8 @@ impl BranchConfig { } pv.key_rlc = pv.extension_node_rlc; // branch part: - pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; + pv.key_rlc += + F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; // key_rlc_mult stays the same } else if pv.is_short { pv.extension_node_rlc += @@ -1038,7 +1034,8 @@ impl BranchConfig { pv.key_rlc_mult *= mpt_config.randomness; // branch part: - pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; + pv.key_rlc += + F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; pv.mult_diff = if pv.is_short_c1 { F::one() } else { @@ -1047,7 +1044,8 @@ impl BranchConfig { } } else { if pv.key_rlc_sel { - pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; + pv.key_rlc += + F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; // key_rlc_mult stays the same } else { pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; @@ -1169,7 +1167,8 @@ impl BranchConfig { *branch_mult *= mpt_config.randomness; let len = row.get_byte(start) as usize - 192; for i in 0..len { - *branch_acc += F::from(row.get_byte(start + 1 + i) as u64) * *branch_mult; + *branch_acc += + F::from(row.get_byte(start + 1 + i) as u64) * *branch_mult; *branch_mult *= mpt_config.randomness; } } @@ -1207,23 +1206,9 @@ impl BranchConfig { offset += 1; } - /*let row = &witness[offset]; - if row.get_type() == MptWitnessRowType::AccountLeafNeighbouringLeaf { - println!("[{}] reset", offset); - //account_leaf.is_in_added_branch = true; - pv.key_rlc = F::zero(); // account address until here, storage key from here on - pv.key_rlc_mult = F::one(); - pv.key_rlc_prev = F::zero(); - pv.key_rlc_mult_prev = F::one(); - pv.nibbles_num_prev = 0; - pv.key_rlc_sel = true; - pv.nibbles_num = 0; - }*/ - /* EXTENSION */ if pv.is_extension_node { - println!("[{}] extension", base_offset); for is_s in [true, false] { let row = &witness[offset]; if is_s { @@ -1285,8 +1270,12 @@ impl BranchConfig { .assign_acc(region, pv.acc_s, pv.acc_mult_s, pv.acc_c, F::zero(), offset) .ok(); } else { - self.key_data - .witness_load(region, base_offset, &pv.memory[key_memory(true)], 0)?; + self.key_data.witness_load( + region, + base_offset, + &pv.memory[key_memory(true)], + 0, + )?; for is_s in [true, false] { self.key_data.witness_store( region, @@ -1336,7 +1325,6 @@ impl BranchConfig { offset += 1; } } else { - offset += 1; self.key_data @@ -1355,8 +1343,6 @@ impl BranchConfig { } } - println!("offset: {}", offset); - Ok(()) } } diff --git a/zkevm-circuits/src/mpt_circuit/branch/branch_init.rs b/zkevm-circuits/src/mpt_circuit/branch/branch_init.rs deleted file mode 100644 index f8838f80b2..0000000000 --- a/zkevm-circuits/src/mpt_circuit/branch/branch_init.rs +++ /dev/null @@ -1,111 +0,0 @@ -use halo2_proofs::{arithmetic::FieldExt, plonk::VirtualCells, poly::Rotation}; -use std::marker::PhantomData; - -use crate::{ - circuit, - circuit_tools::RLCable, - mpt_circuit::helpers::MPTConstraintBuilder, - mpt_circuit::{helpers::BranchNodeInfo, MPTContext}, -}; - -/* -A branch occupies 19 rows: -BRANCH.IS_INIT -BRANCH.IS_CHILD 0 -... -BRANCH.IS_CHILD 15 -BRANCH.IS_EXTENSION_NODE_S -BRANCH.IS_EXTENSION_NODE_C - -Example: - -[1 0 1 0 248 241 0 248 241 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 164 92 78 34 81 137 173 236 78 208 145 118 128 60 46 5 176 8 229 165 42 222 110 4 252 228 93 243 26 160 241 85 0 160 95 174 59 239 229 74 221 53 227 115 207 137 94 29 119 126 56 209 55 198 212 179 38 213 219 36 111 62 46 43 176 168 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 60 157 212 182 167 69 206 32 151 2 14 23 149 67 58 187 84 249 195 159 106 68 203 199 199 65 194 33 215 102 71 138 0 160 60 157 212 182 167 69 206 32 151 2 14 23 149 67 58 187 84 249 195 159 106 68 203 199 199 65 194 33 215 102 71 138 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 21 230 18 20 253 84 192 151 178 53 157 0 9 105 229 121 222 71 120 109 159 109 9 218 254 1 50 139 117 216 194 252 0 160 21 230 18 20 253 84 192 151 178 53 157 0 9 105 229 121 222 71 120 109 159 109 9 218 254 1 50 139 117 216 194 252 1] -[0 160 229 29 220 149 183 173 68 40 11 103 39 76 251 20 162 242 21 49 103 245 160 99 143 218 74 196 2 61 51 34 105 123 0 160 229 29 220 149 183 173 68 40 11 103 39 76 251 20 162 242 21 49 103 245 160 99 143 218 74 196 2 61 51 34 105 123 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 0 140 67 252 58 164 68 143 34 163 138 133 54 27 218 38 80 20 142 115 221 100 73 161 165 75 83 53 8 58 236 1 0 160 0 140 67 252 58 164 68 143 34 163 138 133 54 27 218 38 80 20 142 115 221 100 73 161 165 75 83 53 8 58 236 1 1] -[0 160 149 169 206 0 129 86 168 48 42 127 100 73 109 90 171 56 216 28 132 44 167 14 46 189 224 213 37 0 234 165 140 236 0 160 149 169 206 0 129 86 168 48 42 127 100 73 109 90 171 56 216 28 132 44 167 14 46 189 224 213 37 0 234 165 140 236 1] -[0 160 42 63 45 28 165 209 201 220 231 99 153 208 48 174 250 66 196 18 123 250 55 107 64 178 159 49 190 84 159 179 138 235 0 160 42 63 45 28 165 209 201 220 231 99 153 208 48 174 250 66 196 18 123 250 55 107 64 178 159 49 190 84 159 179 138 235 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17] - -The constraints in this file check whether the RLC of the branch init row (first branch row) -is computed correctly. - -There are three possible cases: -1. Branch (length 21 = 213 - 192) with one byte of RLP meta data - [213,128,194,32,1,128,194,32,1,128,128,128,128,128,128,128,128,128,128,128,128,128] - In this case the init row looks like (specifying only for `S`, we put `x` for `C`): - [1,1,x,x,213,0,0,...] - The RLC is simply `213`. - -2. Branch (length 83) with two bytes of RLP meta data - [248,81,128,128,... - In this case the init row looks like (specifying only for `S`, we put `x` for `C`): - [1,0,x,x,248,81,0,...] - The RLC is `248 + 81*r`. - -3. Branch (length 340) with three bytes of RLP meta data - [249,1,81,128,16,... - In this case the init row looks like (specifying only for `S`, we put `x` for `C`): - [1,0,x,x,249,1,81,...] - The RLC is `249 + 1*r + 81*r^2`. - -We specify the case as (note that `S` branch and -`C` branch can be of different length. `s_rlp1, s_rlp2` is used for `S` and -`s_main.bytes[0], s_main.bytes[1]` is used for `C`): - rlp1, rlp2: 1, 1 means 1 RLP byte - rlp1, rlp2: 1, 0 means 2 RLP bytes - rlp1, rlp2: 0, 1 means 3 RLP bytes - -The example branch init above is the second case (two RLP meta bytes). - -Note: the constraints for the selectors in branch init row to be boolean are in `branch.rs` -and `extension_node.rs`. -*/ - -#[derive(Clone, Debug)] -pub(crate) struct BranchInitConfig { - _marker: PhantomData, -} - -impl BranchInitConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - ) -> Self { - let accs = ctx.accumulators; - let r = ctx.r.clone(); - circuit!([meta, cb.base], { - for is_s in [true, false] { - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, 0); - // Selector constraints - branch.init_selector_checks(meta, &mut cb.base); - // Check that stored rlc/mult values are correct. - let rlp = branch.rlp_bytes(meta); - let (rlc, mult) = matchx! { - branch.is_branch_short(meta) => (rlp[..1].rlc(&r), r[0].expr()), - branch.is_branch_long(meta) => (rlp[..2].rlc(&r), r[1].expr()), - branch.is_branch_very_long(meta) => (rlp[..3].rlc(&r), r[2].expr()), - }; - require!(a!(accs.acc(is_s).rlc) => rlc); - require!(a!(accs.acc(is_s).mult) => mult); - } - }); - - BranchInitConfig { - _marker: PhantomData, - } - } -} diff --git a/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs b/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs deleted file mode 100644 index 600aa8f0d5..0000000000 --- a/zkevm-circuits/src/mpt_circuit/branch/branch_key.rs +++ /dev/null @@ -1,275 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::Region, - plonk::{Error, VirtualCells}, - poly::Rotation, -}; - -use crate::{ - circuit, - circuit_tools::{CellManager, DataTransition}, - mpt_circuit::{helpers::{BranchNodeInfo, key_memory}, param::BRANCH_ROWS_NUM}, - mpt_circuit::{ - helpers::KeyData, witness_row::MptWitnessRow, MPTConfig, MPTContext, ProofValues, - }, - mpt_circuit::{helpers::MPTConstraintBuilder, FixedTableTag}, -}; - -/* -A branch occupies 19 rows: -BRANCH.IS_INIT -BRANCH.IS_CHILD 0 -... -BRANCH.IS_CHILD 15 -BRANCH.IS_EXTENSION_NODE_S -BRANCH.IS_EXTENSION_NODE_C - -Example: - -[1 0 1 0 248 81 0 248 81 0 14 1 0 6 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 29 143 36 49 6 106 55 88 195 10 34 208 147 134 155 181 100 142 66 21 255 171 228 168 85 11 239 170 233 241 171 242 0 160 29 143 36 49 6 106 55 88 195 10 34 208 147 134 155 181 100 142 66 21 255 171 228 168 85 11 239 170 233 241 171 242 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 135 117 154 48 1 221 143 224 133 179 90 254 130 41 47 5 101 84 204 111 220 62 215 253 155 107 212 69 138 221 91 174 0 160 135 117 154 48 1 221 143 224 133 179 90 254 130 41 47 5 101 84 204 111 220 62 215 253 155 107 212 69 138 221 91 174 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[226 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 160 30 252 7 160 150 158 68 221 229 48 73 181 91 223 120 156 43 93 5 199 95 184 42 20 87 178 65 243 228 156 123 174 0 16] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 160 30 252 7 160 150 158 68 221 229 48 73 181 91 223 120 156 43 93 5 199 95 184 42 20 87 178 65 243 228 156 123 174 0 17] - -The last two rows present the extension node. This might be a bit misleading, because the extension -node appears in the trie above the branch (the first 17 rows). - -The constraints in `branch_key.rs` checks whether the key RLC is being properly -computed using `modified_node`. Note that `modified_node` presents the branch node -to be modified and is one of the nibbles of a key. - -Let us have the following scenario: - -``` -Branch1: - node1_0 - node1_1 <- modified_node - ... - node1_15 -Branch2 - node2_0 - ... - node2_7 <- modified_node - ... - node2_15 -Branch3 - node3_0 - ... - node3_5 <- modified_node - ... - node3_15 -Branch4 - node4_0 - ... - node4_11 <- modified_node - ... - node4_15 -Leaf1 -``` - -We have four branches and finally a leaf in the fourth branch. The modified nodes are: `1, 7, 5, 11`. -The modified nodes occupy two bytes, the remaining 30 bytes are stored in `Leaf1`: -`b_0, ..., b_29`. - -The key at which the change occurs is thus: `1 * 16 + 7, 5 * 16 + 11, b_0, ..., b_29`. -The RLC of the key is: `(1 * 16 + 7) + (5 * 16 + 11) * r + b_0 * r^2 + b_29 * r^31`. - -In each branch we check whether the intermediate RLC is computed correctly. The intermediate -values are stored in `accumulators.key`. There is always the actual RLC value and the multiplier -that is to be used when adding the next summand: `accumulators.key.rlc, accumulators.key.mult`. - -For example, in `Branch1` we check whether the intermediate RLC is `1 * 16`. -In `Branch2`, we check whether the intermediate RLC is `rlc_prev_branch_init_row + 7`. -In `Branch3`, we check whether the intermediate RLC is `rlc_prev_branch_init_row + 5 * 16 * r`. -In `Branch4`, we check whether the intermediate RLC is `rlc_prev_branch_init_row + 11 * r`. - -There are auxiliary columns `sel1` and `sel2` which specify whether we are in branch where -the nibble has to be multiplied by 16 or by 1. `sel1 = 1` means multiplying by 16, -`sel2 = 1` means multiplying by 1. - -TODO: extension node longer than 55 bytes - we leave this for now as it is very unlikely to happen. - -ExtensionNodeConfig supports extension nodes longer than 55 bytes, however ExtensionNodeKeyConfig -currently does not. See below. - -Currently, we do not store key for the C extension node - it is always the same as key for -the S extension node. However, it can happen that one extension node is longer than 55 bytes and one not -(being longer than 55 bytes is very unlikely because that would mean the extension need to be at least -22 bytes long - adding 32 for branch hash and 2 RLP bytes would give us 56). -In this case the longer than 55 bytes extension node starts as: [248, remaining_length, extension_bytes_length, ...], -while the shorter than 55 bytes extension node starts as: [247, extension_bytes_length, ...]. - -We do not have space to store C RLP & key into extension node C row as we already store key nibbles there (same -for both extension nodes). - -The best seems to be to handle four different cases: - - s_short, c_short (not to be confused with short/long meaning nibbles, here it means the whole ext. node longer or shorter than 55 bytes) - - s_short, c_long - - s_long, c_short - - s_long, c_long - -Using this approach we do not need to store C RLP & key, but it will increase the degree -(unless we pack this info together with short/long nibbles & c1/c16). -*/ - -#[derive(Clone, Debug)] -pub(crate) struct BranchKeyConfig { - key_data: KeyData, -} - -impl BranchKeyConfig { - pub(crate) fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - ) -> Self { - let position_cols = ctx.position_cols; - let key = ctx.accumulators.key; - let mult_diff = ctx.accumulators.mult_diff; - let r = ctx.r.clone(); - - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); - let ctx_key_data: Option>; - - circuit!([meta, cb.base], { - ifx! {f!(position_cols.q_not_first_ext_c), a!(ctx.branch.is_extension_node_c) => { - let rot_branch_init = -BRANCH_ROWS_NUM + 1; - let rot_first_child = rot_branch_init + 1; - - let branch = BranchNodeInfo::new(meta, ctx.clone(), false, rot_branch_init); - let modified_index = a!(ctx.branch.modified_index, rot_first_child); - let key_rlc = a!(key.rlc, rot_first_child); - let key_mult = a!(key.mult, rot_first_child); - - // `is_key_odd` needs to be boolean - require!(branch.is_key_odd() => bool); - - // Load the last key values - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 0.expr()); - - // Calculate the extension node key RLC when in an extension node - let key_rlc_post_ext = ifx!{branch.is_extension() => { - let key_rlc_ext = DataTransition::new(meta, key.rlc); - // Extension key rlc - let ext_key_rlc = key_data.rlc.expr() + branch.ext_key_rlc(meta, &mut cb.base, key_data.mult.expr()); - // Currently, the extension node S and extension node C both have the same key RLC - - // however, sometimes extension node can be replaced by a shorter extension node - // (in terms of nibbles), this is still to be implemented. - // TODO: extension nodes of different nibbles length - require!(key_rlc_ext => key_rlc_ext.prev()); - // Store it - require!(key_rlc_ext => ext_key_rlc); - ext_key_rlc.expr() - } elsex { - key_data.rlc.expr() - }}; - - // Get the length of the key - let key_num_bytes_for_mult = ifx!{branch.is_extension() => { - // Unless both parts of the key are odd, subtract 1 from the key length. - let key_len = branch.ext_key_len(meta, -1); - key_len - ifx! {not!(key_data.is_odd.expr() * branch.is_key_part_in_ext_odd()) => { 1.expr() }} - }}; - // Get the multiplier for this key length - let mult_diff = a!(mult_diff, rot_first_child); - require!((FixedTableTag::RMult, key_num_bytes_for_mult, mult_diff) => @"mult"); - - // Now update the key RLC and multiplier for the branch nibble. - let mult = key_data.mult.expr() * mult_diff.expr(); - let (nibble_mult, mult_mult) = ifx!{branch.is_key_odd() => { - // The nibble will be added as the most significant nibble using the same multiplier - (16.expr(), 1.expr()) - } elsex { - // The nibble will be added as the least significant nibble, the multiplier needs to advance - (1.expr(), r[0].expr()) - }}; - require!(key_rlc => key_rlc_post_ext.expr() + modified_index.expr() * nibble_mult.expr() * mult.expr()); - require!(key_mult => mult.expr() * mult_mult.expr()); - - // Update key parity - ifx!{branch.is_extension() => { - // We need to take account the nibbles of the extension node. - // The parity alternates when there's an even number of nibbles, remains the same otherwise - ifx!{branch.is_key_part_in_ext_even() => { - require!(branch.is_key_odd() => not!(key_data.is_odd)); - } elsex { - require!(branch.is_key_odd() => key_data.is_odd); - }} - } elsex { - // The parity simply alternates for regular branches. - require!(branch.is_key_odd() => not!(key_data.is_odd)); - }} - - for is_s in [true, false] { - KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], [ - key_rlc.expr(), - key_mult.expr(), - branch.nibbles_counter().expr(), - branch.is_key_odd(), - branch.contains_placeholder_leaf(meta, true), - branch.contains_placeholder_leaf(meta, false), - ]); - } - - // We need to check that the nibbles we stored in s are between 0 and 15. - cb.set_range_s(FixedTableTag::RangeKeyLen16.expr()); - - ctx_key_data = Some(key_data); - }} - - ifx! {f!(position_cols.q_not_first_ext_s), a!(ctx.branch.is_extension_node_s) => { - let rot_branch_init = -BRANCH_ROWS_NUM + 2; - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - ifx! {branch.is_extension() => { - // RLC bytes zero check - // TODO(Brecht): fix - //cb.set_length(1.expr() + branch.ext_num_bytes_on_key_row(meta, 0)); - }} - }} - }); - - BranchKeyConfig { - key_data: ctx_key_data.unwrap(), - } - } - - pub(crate) fn assign( - &self, - region: &mut Region<'_, F>, - _witness: &[MptWitnessRow], - _mpt_config: &MPTConfig, - pv: &mut ProofValues, - offset: usize, - ) -> Result<(), Error> { - self.key_data - .witness_load(region, offset, &pv.memory[key_memory(true)], 0)?; - for is_s in [true, false] { - self.key_data.witness_store( - region, - offset, - &mut pv.memory[key_memory(is_s)], - pv.key_rlc, - pv.key_rlc_mult, - pv.nibbles_num, - pv.is_placeholder_leaf_s, - pv.is_placeholder_leaf_c, - )?; - } - Ok(()) - } -} diff --git a/zkevm-circuits/src/mpt_circuit/branch/branch_rlc.rs b/zkevm-circuits/src/mpt_circuit/branch/branch_rlc.rs deleted file mode 100644 index e4044389ff..0000000000 --- a/zkevm-circuits/src/mpt_circuit/branch/branch_rlc.rs +++ /dev/null @@ -1,129 +0,0 @@ -use halo2_proofs::{arithmetic::FieldExt, plonk::VirtualCells, poly::Rotation}; -use std::marker::PhantomData; - -use crate::{ - circuit, - circuit_tools::{DataTransition, RLCChainable}, - mpt_circuit::{helpers::contains_placeholder_leaf, FixedTableTag}, - mpt_circuit::{ - helpers::{BranchChildInfo, MPTConstraintBuilder}, - MPTContext, - }, -}; - -/* -A branch occupies 19 rows: -BRANCH.IS_INIT -BRANCH.IS_CHILD 0 -... -BRANCH.IS_CHILD 15 -BRANCH.IS_EXTENSION_NODE_S -BRANCH.IS_EXTENSION_NODE_C - -Example: - -[1 0 1 0 248 241 0 248 241 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 164 92 78 34 81 137 173 236 78 208 145 118 128 60 46 5 176 8 229 165 42 222 110 4 252 228 93 243 26 160 241 85 0 160 95 174 59 239 229 74 221 53 227 115 207 137 94 29 119 126 56 209 55 198 212 179 38 213 219 36 111 62 46 43 176 168 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 60 157 212 182 167 69 206 32 151 2 14 23 149 67 58 187 84 249 195 159 106 68 203 199 199 65 194 33 215 102 71 138 0 160 60 157 212 182 167 69 206 32 151 2 14 23 149 67 58 187 84 249 195 159 106 68 203 199 199 65 194 33 215 102 71 138 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 21 230 18 20 253 84 192 151 178 53 157 0 9 105 229 121 222 71 120 109 159 109 9 218 254 1 50 139 117 216 194 252 0 160 21 230 18 20 253 84 192 151 178 53 157 0 9 105 229 121 222 71 120 109 159 109 9 218 254 1 50 139 117 216 194 252 1] -[0 160 229 29 220 149 183 173 68 40 11 103 39 76 251 20 162 242 21 49 103 245 160 99 143 218 74 196 2 61 51 34 105 123 0 160 229 29 220 149 183 173 68 40 11 103 39 76 251 20 162 242 21 49 103 245 160 99 143 218 74 196 2 61 51 34 105 123 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 0 140 67 252 58 164 68 143 34 163 138 133 54 27 218 38 80 20 142 115 221 100 73 161 165 75 83 53 8 58 236 1 0 160 0 140 67 252 58 164 68 143 34 163 138 133 54 27 218 38 80 20 142 115 221 100 73 161 165 75 83 53 8 58 236 1 1] -[0 160 149 169 206 0 129 86 168 48 42 127 100 73 109 90 171 56 216 28 132 44 167 14 46 189 224 213 37 0 234 165 140 236 0 160 149 169 206 0 129 86 168 48 42 127 100 73 109 90 171 56 216 28 132 44 167 14 46 189 224 213 37 0 234 165 140 236 1] -[0 160 42 63 45 28 165 209 201 220 231 99 153 208 48 174 250 66 196 18 123 250 55 107 64 178 159 49 190 84 159 179 138 235 0 160 42 63 45 28 165 209 201 220 231 99 153 208 48 174 250 66 196 18 123 250 55 107 64 178 159 49 190 84 159 179 138 235 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17] - -The constraints in `branch_rlc.rs` check whether the branch RLC is being properly computed row by row. -There are three type of branch children rows: empty children, non-empty hashed children, -non-empty non-hashed children. We need to take into account these three types when computing -the intermediate RLC of the current row. - -For example, in a an empty row (nil branch child) like -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -we need to check that `rlp2 = 0`, `bytes[0] = 128`, and `bytes[i] = 0` for `i > 0`. - -Also, we check that the RLC corresponding to the `modified_node` is stored in `mod_node_hash_rlc` column. -In the above example we have `modified_node = 2` which corresponds to the row: -[0 160 164 92 78 34 81 137 173 236 78 208 145 118 128 60 46 5 176 8 229 165 42 222 110 4 252 228 93 243 26 160 241 85 0 160 95 174 59 239 229 74 221 53 227 115 207 137 94 29 119 126 56 209 55 198 212 179 38 213 219 36 111 62 46 43 176 168 1] - -So the `S` RLC of the `modified_node` is: `164 + 92 * r + 78 * r^2 + ... + 85 * r^31` -The `C` RLC is: `95 + 174*r + 59* r^2 + ... + 168 * r^31` - -The `S` RLC is stored in `s_mod_node_hash_rlc` column, in all 16 branch children rows. -The `C` RLC is stored in `c_mod_node_hash_rlc` column, in all 16 branch children rows. - -Having the values stored in all 16 rows makes it easier to check whether it is really the value that -corresponds to the `modified_node`. Otherwise, having this value stored for example only in branch init row -we would not know what rotation to use into branch init when in `modified_node` row. - -Note that the constraints about having the RLC value corresponds to the `modified_node` row are -implemented in `branch.rs`. This is because we do not have full symmetry between `S` and `C` proofs -in the case of branch placeholders. - -Finally, when there is a non-hashed branch child, we need to check that there are 0s after the last -branch child byte. The example is: -[0,0,198,132,48,0,0,0,1,...] -In this case the branch child is of length `6 = 198 - 192`: `[132, 48, 0, 0, 0, 1]`. -We need to make sure there are 0s after these 6 bytes. - -Note that the RLC for branch init row is checked in `branch_init.rs`. -*/ - -#[derive(Clone, Debug)] -pub(crate) struct BranchRLCConfig { - _marker: PhantomData, -} - -impl BranchRLCConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - is_s: bool, - ) -> Self { - let main = ctx.main(is_s); - let branch = ctx.accumulators.acc(is_s); - let mult_diff = ctx.accumulators.node_mult_diff(is_s); - circuit!([meta, cb.base], { - let child = BranchChildInfo::new(meta, ctx.clone(), is_s, 0); - let branch_mult = DataTransition::new(meta, branch.mult); - let branch_rlc = DataTransition::new(meta, branch.rlc); - - // Calculate the RLC - let rlc = child.rlc(meta, &mut cb.base); - require!(branch_rlc => (branch_rlc.prev(), branch_mult.prev()).rlc_chain(rlc)); - require!(branch_mult => branch_mult.prev() * a!(mult_diff)); - - // RLC bytes zero check - cb.set_length_sc(is_s, child.num_bytes_on_row(meta)); - // We need to check that the multiplier changes according to `num_bytes` and - // update it. - require!((FixedTableTag::RMult, child.num_bytes(meta), a!(mult_diff)) => @format!("mult{}", if is_s {""} else {"2"})); - - // When a value is being added (and reverse situation when deleted) to the trie - // and there is no other leaf at the position where it is to be - // added, we have empty branch child in `S` proof and hash of a - // newly added leaf at the parallel position in `C` proof. - // That means we have empty node in `S` proof at `modified_node`. - // When this happens, we denote this situation by having a placeholder leaf. - // In this case we need to make sure the node is seen as empty. - ifx! {a!(ctx.branch.is_modified), contains_placeholder_leaf(meta, ctx.clone(), is_s, 0) => { - require!(child.is_hashed(meta) => true); - require!(a!(main.rlp2) => 0); - }} - }); - - BranchRLCConfig { - _marker: PhantomData, - } - } -} diff --git a/zkevm-circuits/src/mpt_circuit/branch/extension_node.rs b/zkevm-circuits/src/mpt_circuit/branch/extension_node.rs deleted file mode 100644 index 6411b0f9f2..0000000000 --- a/zkevm-circuits/src/mpt_circuit/branch/extension_node.rs +++ /dev/null @@ -1,427 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, - plonk::VirtualCells, - poly::Rotation, -}; -use std::marker::PhantomData; - -use crate::{ - circuit, - circuit_tools::{DataTransition, RLCChainable, RLCable}, - mpt_circuit::{ - helpers::get_num_nibbles, - param::{ARITY, C_RLP_START, C_START, HASH_WIDTH, RLP_HASH_VALUE, RLP_LIST_LONG, RLP_NIL}, - FixedTableTag, - }, - mpt_circuit::{ - helpers::{BranchNodeInfo, MPTConstraintBuilder}, - witness_row::MptWitnessRow, - MPTContext, - }, - mpt_circuit::{MPTConfig, ProofValues}, -}; - -/* -A branch occupies 19 rows: -BRANCH.IS_INIT -BRANCH.IS_CHILD 0 -... -BRANCH.IS_CHILD 15 -BRANCH.IS_EXTENSION_NODE_S -BRANCH.IS_EXTENSION_NODE_C - -Example: - -[1 0 1 0 248 81 0 248 81 0 14 1 0 6 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 29 143 36 49 6 106 55 88 195 10 34 208 147 134 155 181 100 142 66 21 255 171 228 168 85 11 239 170 233 241 171 242 0 160 29 143 36 49 6 106 55 88 195 10 34 208 147 134 155 181 100 142 66 21 255 171 228 168 85 11 239 170 233 241 171 242 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[0 160 135 117 154 48 1 221 143 224 133 179 90 254 130 41 47 5 101 84 204 111 220 62 215 253 155 107 212 69 138 221 91 174 0 160 135 117 154 48 1 221 143 224 133 179 90 254 130 41 47 5 101 84 204 111 220 62 215 253 155 107 212 69 138 221 91 174 1] -[0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] -[226 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 160 30 252 7 160 150 158 68 221 229 48 73 181 91 223 120 156 43 93 5 199 95 184 42 20 87 178 65 243 228 156 123 174 0 16] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 160 30 252 7 160 150 158 68 221 229 48 73 181 91 223 120 156 43 93 5 199 95 184 42 20 87 178 65 243 228 156 123 174 0 17] - -The last two rows present the extension node. This might be a bit misleading, because the extension -node appears in the trie above the branch (the first 17 rows). - -The constraints in `extension_node.rs` check: - - RLP of the node - - that the branch hash is in the extension node (the bytes `[30 252 ... 174]` in extension node rows present the hash -of the underlying branch) - - that the hash of the extension is in the parent node. - -Note that an attacker can set `is_extension_node = 1` -for a regular branch (or `is_extension_node = 0` for the extension node), -the final key RLC check fails because key RLC is computed differently -for extension nodes and regular branches - a regular branch occupies only one -key nibble (`modified_node`), while extension node occupies at least one additional -nibble (the actual extension of the extension node). - -Some observations: - -[228,130,0,149,160,114,253,150,133,18,192,156,19,241,162,51,210,24,1,151,16, -48,7,177,42,60,49,34,230,254,242,79,132,165,90,75,249] -Note that the first element (228 in this case) can go much higher - for -example, if there are 40 nibbles, this would take 20 bytes which -would make the first element 248. - -If only one byte in key: -[226,16,160,172,105,12... - -Extension node with non-hashed branch: -List contains up to 55 bytes (192 + 55) -[247,160,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -213,128,194,32,1,128,194,32,1,128,128,128,128,128,128,128,128,128,128,128, -128,128] - -List contains more than 55 bytes -[248,58,159,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -217,128,196,130,32,0,1,128,196,130,32,0,1,128,128,128,128,128,128,128,128, -128,128,128,128,128] - -Note that the extension node can be much shorter than the one above - in case -when there are less nibbles, so we cannot say that 226 appears as -the first byte only when there are hashed nodes in the branch and -there is only one nibble. Branch with two non-hashed nodes -(that's the shortest possible branch): [217,128,196,130,32,0,1, -128,196,130,32,0,1,128,128,128,128,128,128,128,128,128,128,128,128,128] -Note: branch contains at least 26 bytes. 192 + 26 = 218 - -If proofEl[0] <= 247 (length at most 55, so proofEl[1] doesn't specify the -length of the whole remaining stream, only of the next -substream) If proofEl[1] <= 128: - There is only 1 byte for nibbles (keyLen = 1) and this is proofEl[1]. -Else: - Nibbles are stored in more than 1 byte, proofEl[1] specifies the length -of bytes. Else: -proofEl[1] contains the length of the remaining stream. -proofEl[2] specifies the length of the bytes (for storing nibbles). -Note that we can't have only one nibble in this case. -*/ - -#[derive(Clone, Debug, Default)] -pub(crate) struct ExtensionNodeConfig { - _marker: PhantomData, -} - -/* -Let's say we have branch1 and branch2 below it. - -branch1 S row 0 || branch1 C row 0 -... -branch1 S row 15 || branch1 C row 15 - -branch2 S row 0 || branch2 C row 0 -... -branch2 S row 15 || branch2 C row 15 - -Hash of branch2 S is in one of the branch1 rows (in S columns). -Hash of branch2 C is in one of the branch1 rows (in C columns). - -In what follows, we write branch without S and C - it is the same for both cases. - -Key key1 determines the position of branch2 hash in branch1 (0-15). -To check this, branch2 RLC (over all RLP bytes - all 1+16 rows, 1 is for branch init row) -is checked to have a hash in branch1, at modified_node index -(modified_node depends on key key1). - -However, with extension node it's a bit different. - -branch1 S row 0 || branch1 C row 0 -... -branch1 S row 15 || branch1 C row 15 -extension1 S -extension1 C - -branch2 S row 0 || branch2 C row 0 -... -branch2 S row 15 || branch2 C row 15 -extension2 S -extension2 C - -There are additional rows immediately after branch 16 rows - one row for -extension node S and one row for extension node C. These rows are empty when -we have a regular branch. - -Let's say branch2 is extension node. In this case, extension2 row contains: - - key bytes that present the extension - - hash of branch2 - ---- -Example 1: - -Key extension of length 2: -[228, 130, 0, 149, 160, 114, 253, 150,133,18,192,156,19,241,162,51,210,24,1,151,16,48,7,177,42,60,49,34,230,254,242,79,132,165,90,75,249] -[rlp, rlp, key byte 1, key byte 2, rlp, hash of branch2 byte 0, hash of branch2 byte 1, ...] -[0, 149] presents key extension: - - 0 because it's even length (in branch it would be 16, see terminator) - - 149 = 9*16 + 5 -Key extension is [9, 5]. - -Two constraints are needed: - - the hash of extension node (extension node RLC is needed) needs to be - checked whether it's in branch1 - - the hash of branch2 is in extension node. - -Also, it needs to be checked that key extension corresponds to key1 (not in this chip). - ---- -Example 2: - -Key extension of length 1: -[226, 16, 160,172,105,12... -[rlp, key byte1, ... -[16] presents key extension: - - 16 = 0 + 16 -Key extension is [0]. - -*/ - -impl ExtensionNodeConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - is_s: bool, - ) -> Self { - let position_cols = ctx.position_cols; - let s_main = ctx.s_main; - let c_main = ctx.c_main; - let accs = ctx.accumulators; - let r = ctx.r.clone(); - - let rot_s = if is_s { 0 } else { -1 }; - let rot_last_child = rot_s - 1; - let rot_branch_init = rot_last_child - (ARITY as i32); - - circuit!([meta, cb.base], { - let not_first_level = a!(position_cols.not_first_level); - let ext = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let ext_rlc = DataTransition::from(a!(accs.acc_s.rlc, rot_s), a!(accs.acc_c.rlc)); - - // There are two cases: - // - hashed branch has RLP_HASH_VALUE at c_rlp2 and hash in c_advices, - // - non-hashed branch has 0 at c_rlp2 and all the bytes in c_advices - // TODO(Brecht): why different layout for hashed values? If for hash detection - // just do == 32? - require!(a!(c_main.rlp2) => [0, RLP_HASH_VALUE]); - - // `short` means there is only one nibble in the extension node, `long` means - // there are at least two. `even` means the number of nibbles is - // even, `odd` means the number of nibbles is odd. `c16` means that - // above the branch there are even number of nibbles, `c1` means that above - // the branch there are odd number of nibbles. - let type_selectors_c1 = [ - ext.is_short_c1.expr(), - ext.is_long_even_c1.expr(), - ext.is_long_odd_c1.expr(), - ]; - let type_selectors_c16 = [ - ext.is_short_c16.expr(), - ext.is_long_even_c16.expr(), - ext.is_long_odd_c16.expr(), - ]; - let type_selectors = [type_selectors_c1.clone(), type_selectors_c16.clone()].concat(); - let misc_selectors = [ - ext.is_longer_than_55_s.expr(), - ext.is_ext_not_hashed_s.expr(), - ]; - - ifx! {a!(ctx.branch.is_init) => { - // Check that the selectors are boolean - for selector in type_selectors.iter().chain(misc_selectors.iter()) { - require!(selector => bool); - } - // For extension nodes exactly 1 type selector needs to be enabled. - require!(sum::expr(&type_selectors) => 1); - // `is_key_odd` is set using the extension node type selector data. - // (while in case of a regular branch the extension node selectors do not hold this information). - require!(ext.is_key_odd() => not!(sum::expr(&type_selectors_c1))); - require!(ext.is_key_odd() => sum::expr(&type_selectors_c16)); - }} - - // RLP encoding checks: [key, branch] - // In C we have nibbles, we check below only for S. - if is_s { - ifx! {ext.is_longer_than_55_s => { - require!(a!(s_main.rlp1) => RLP_LIST_LONG + 1); - }} - // Verify that the lenghts are consistent. - require!(ext.ext_len(meta, 0) => ext.ext_key_num_bytes(meta, 0) + ext.ext_branch_num_bytes(meta)); - } - - // Calculate the extension node RLC. - // The intermediate RLC after `s_main` bytes needs to be properly computed. - // s_rlp1, s_rlp2, s_bytes need to be the same in both extension rows. - // However, to make space for nibble witnesses, we put nibbles in - // extension row C s_bytes. So we use s_bytes from S row. - // TODO(Brecht): Do we need to store the RLC here? we can just use `rlc` - // directly below... - require!(ext_rlc.prev() => s_main.expr(meta, rot_s).rlc(&r)); - // Update the multiplier with the number of bytes on the first row - let mult = a!(accs.acc_s.mult); - require!((FixedTableTag::RMult, ext.ext_num_bytes_on_key_row(meta, rot_s), mult) => @"mult2"); - - let rlc = ifx! {ext.contains_hashed_branch(meta) => { - c_main.expr(meta, 0)[1..].rlc(&r) - } elsex { - // RLC bytes zero check (+2 because data starts at bytes[0]) - cb.set_length_c(2.expr() + ext.ext_branch_num_bytes(meta)); - - c_main.expr(meta, 0)[2..].rlc(&r) - }}; - require!(ext_rlc => (ext_rlc.prev(), mult.expr()).rlc_chain(rlc)); - - // We check that the branch hash RLC corresponds to the extension node RLC - // stored in the extension node row. TODO: acc currently doesn't - // have branch ValueNode info (which 128 if nil) - let branch_rlc = ( - a!(accs.acc(is_s).rlc, rot_last_child), - a!(accs.acc(is_s).mult, rot_last_child), - ) - .rlc_chain(RLP_NIL.expr()); - let branch_rlc_in_ext = c_main.bytes(meta, 0).rlc(&r); - ifx! {ext.contains_hashed_branch(meta) => { - // Check that `(branch_rlc, extension_node_hash_rlc`) is in the keccak table. - require!((1, branch_rlc, ext.num_bytes(meta), branch_rlc_in_ext) => @"keccak"); - } elsex { - // Check if the RLC matches - require!(branch_rlc => branch_rlc_in_ext); - }} - - // Update the number of nibbles processed up to this point. - if is_s { - // Calculate the number of bytes - let key_len = ext.ext_key_len(meta, 0); - // Calculate the number of nibbles - let num_nibbles = - get_num_nibbles(meta, key_len.expr(), ext.is_key_part_in_ext_odd()); - // Make sure the nibble counter is updated correctly - let nibbles_count_prev = ifx! {not!(ext.is_below_account(meta)), not_first_level.expr() => { - ext.nibbles_counter().prev() - }}; - require!(ext.nibbles_counter() => nibbles_count_prev.expr() + num_nibbles.expr() + 1.expr()); - } - }); - - ExtensionNodeConfig { - _marker: PhantomData, - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &mut ProofValues, - row: &MptWitnessRow, - offset: usize, - is_s: bool, - ) { - if pv.is_extension_node { - if is_s { - // [228,130,0,149,160,114,253,150,133,18,192,156,19,241,162,51,210,24,1,151,16, - // 48,7,177,42,60,49,34,230,254,242,79,132,165,90,75,249] - - // One nibble: - // [226,16,160,172,105,12... - // Could also be non-hashed branch: - // [223,16,221,198,132,32,0,0,0,1,198,132,32,0,0,0,1,128,128,128,128,128,128, - // 128,128,128,128,128,128,128,128,128] - - // [247,160,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - // 213,128,194,32,1,128,194,32,1,128,128,128,128,128,128,128,128,128,128,128, - // 128,128] [248,58,159,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - // 0,0,0,0,0,0,0,0,0,0,0,0,217,128,196,130,32,0,1,128,196,130,32,0,1,128,128, - // 128,128,128,128,128,128,128,128,128,128,128] - - // Intermediate RLC value and mult (after key) - // to know which mult we need to use in c_advices. - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - let len: usize; - if row.get_byte(1) <= 32 { - // key length is 1 - len = 2 // [length byte, key] - } else if row.get_byte(0) < 248 { - len = (row.get_byte(1) - 128) as usize + 2; - } else { - len = (row.get_byte(2) - 128) as usize + 3; - } - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - 0, - len, - ); - - // Final RLC value. - pv.acc_c = pv.acc_s; - pv.acc_mult_c = pv.acc_mult_s; - let mut start = C_RLP_START + 1; - let mut len = HASH_WIDTH + 1; - if row.get_byte(C_RLP_START + 1) == 0 { - // non-hashed branch in extension node - start = C_START; - len = HASH_WIDTH; - } - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_c, - &mut pv.acc_mult_c, - start, - len, - ); - - mpt_config - .assign_acc(region, pv.acc_s, pv.acc_mult_s, pv.acc_c, F::zero(), offset) - .ok(); - } else { - // We use intermediate value from previous row (because - // up to acc_s it's about key and this is the same - // for both S and C). - pv.acc_c = pv.acc_s; - pv.acc_mult_c = pv.acc_mult_s; - let mut start = C_RLP_START + 1; - let mut len = HASH_WIDTH + 1; - if row.get_byte(C_RLP_START + 1) == 0 { - // non-hashed branch in extension node - start = C_START; - len = HASH_WIDTH; - } - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_c, - &mut pv.acc_mult_c, - start, - len, - ); - - mpt_config - .assign_acc(region, pv.acc_s, pv.acc_mult_s, pv.acc_c, F::zero(), offset) - .ok(); - } - region - .assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(pv.extension_node_rlc), - ) - .ok(); - } - } -} diff --git a/zkevm-circuits/src/mpt_circuit/columns.rs b/zkevm-circuits/src/mpt_circuit/columns.rs index f2995c8129..ef4ff0dd64 100644 --- a/zkevm-circuits/src/mpt_circuit/columns.rs +++ b/zkevm-circuits/src/mpt_circuit/columns.rs @@ -247,8 +247,6 @@ impl DenoteCols { pub(crate) struct PositionCols { pub(crate) q_enable: Column, pub(crate) q_not_first: Column, // not first row - pub(crate) q_not_first_ext_s: Column, // not first ext - pub(crate) q_not_first_ext_c: Column, // not first ext pub(crate) not_first_level: Column, _marker: PhantomData, @@ -259,8 +257,6 @@ impl PositionCols { Self { q_enable: meta.fixed_column(), q_not_first: meta.fixed_column(), - q_not_first_ext_s: meta.fixed_column(), - q_not_first_ext_c: meta.fixed_column(), not_first_level: meta.advice_column(), _marker: PhantomData, } diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index 2810513178..c49ce237a7 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -119,7 +119,14 @@ impl KeyData { } pub(crate) fn default_values() -> [Expression; 6] { - [0.expr(), 1.expr(), 0.expr(), false.expr(), false.expr(), false.expr()] + [ + 0.expr(), + 1.expr(), + 0.expr(), + false.expr(), + false.expr(), + false.expr(), + ] } pub(crate) fn witness_store( @@ -643,7 +650,11 @@ impl BranchNodeInfo { /// Length of the included branch (excluding RLP bytes) /// Uses data on the current row! - pub(crate) fn ext_branch_len(&self, meta: &mut VirtualCells, rot_ext_s: i32) -> Expression { + pub(crate) fn ext_branch_len( + &self, + meta: &mut VirtualCells, + rot_ext_s: i32, + ) -> Expression { circuit!([meta, _cb!()], { ifx! {self.contains_hashed_branch(meta, rot_ext_s) => { 32.expr() @@ -655,13 +666,21 @@ impl BranchNodeInfo { /// Length of the included branch (excluding RLP bytes) /// Uses data on the current row! - pub(crate) fn ext_branch_num_bytes(&self, meta: &mut VirtualCells, rot_ext_s: i32) -> Expression { + pub(crate) fn ext_branch_num_bytes( + &self, + meta: &mut VirtualCells, + rot_ext_s: i32, + ) -> Expression { 1.expr() + self.ext_branch_len(meta, rot_ext_s) } /// Length of the key (excluding RLP bytes) /// Uses data on the current row! - pub(crate) fn contains_hashed_branch(&self, meta: &mut VirtualCells, rot_ext_s: i32) -> Expression { + pub(crate) fn contains_hashed_branch( + &self, + meta: &mut VirtualCells, + rot_ext_s: i32, + ) -> Expression { circuit!([meta, _cb!()], { a!(self.ctx.c_main.rlp2, rot_ext_s) * invert!(RLP_HASH_VALUE) }) @@ -1247,7 +1266,11 @@ pub(crate) fn leaf_key_rlc( require!(first_byte => KEY_TERMINAL_PREFIX_EVEN); (0.expr(), key_mult_first_even.expr()) }}; - (rlc, key_mult_prev * mult).rlc_chain(ctx.rlc(meta, range.start + 1..range.end, cb.get_query_offset() + rot)) + (rlc, key_mult_prev * mult).rlc_chain(ctx.rlc( + meta, + range.start + 1..range.end, + cb.get_query_offset() + rot, + )) }) } diff --git a/zkevm-circuits/src/mpt_circuit/selectors.rs b/zkevm-circuits/src/mpt_circuit/selectors.rs index 938ef0e160..8150a04b85 100644 --- a/zkevm-circuits/src/mpt_circuit/selectors.rs +++ b/zkevm-circuits/src/mpt_circuit/selectors.rs @@ -131,7 +131,7 @@ impl SelectorsConfig { require!(sum::expr(row_type_selectors.iter()) => 1); // The type of the proof needs to be set. - /*require!(sum::expr(proof_type_selectors.iter()) => 1); + require!(sum::expr(proof_type_selectors.iter()) => 1); // We need to prevent lookups into non-lookup rows and we need to prevent for // example nonce lookup into balance lookup row. @@ -158,7 +158,7 @@ impl SelectorsConfig { require!(proof_type_id => 0); }} }} - }*/ + } }}; // First row diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index e2ad38555b..6657a845a9 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -1,15 +1,39 @@ -pub mod leaf_combined; -pub mod leaf_key; -pub mod leaf_key_in_added_branch; -pub mod leaf_non_existing; -pub mod leaf_value; - +use halo2_proofs::plonk::{Advice, Column, ConstraintSystem}; use halo2_proofs::{ arithmetic::FieldExt, - plonk::{Advice, Column, ConstraintSystem}, + circuit::{Region, Value}, + plonk::{Error, VirtualCells}, + poly::Rotation, }; use std::marker::PhantomData; +use crate::{ + circuit, + circuit_tools::{ + Cell, CellManager, CellType, ConstraintBuilder, DataTransition, RLCChainable, RLCable, + }, + mpt_circuit::{ + helpers::BranchNodeInfo, + param::{BRANCH_ROWS_NUM, S_START}, + }, + mpt_circuit::{ + helpers::{ + get_num_bytes_short, get_parent_rlc_state, key_memory, parent_memory, KeyData, + MPTConstraintBuilder, ParentData, StorageLeafInfo, + }, + param::{ + EMPTY_TRIE_HASH, HASH_WIDTH, IS_NON_EXISTING_STORAGE_POS, IS_STORAGE_MOD_POS, + KEY_LEN_IN_NIBBLES, LEAF_KEY_C_IND, LEAF_NON_EXISTING_IND, + }, + FixedTableTag, + }, + mpt_circuit::{ + witness_row::{MptWitnessRow, MptWitnessRowType}, + MPTContext, + }, + mpt_circuit::{MPTConfig, ProofValues}, +}; + #[derive(Clone, Debug)] pub(crate) struct StorageLeafCols { pub(crate) is_s_key: Column, @@ -66,3 +90,781 @@ pub(crate) struct StorageLeaf { pub(crate) is_in_added_branch: bool, pub(crate) is_non_existing: bool, } + +#[derive(Clone, Debug)] +pub(crate) struct StorageLeafConfig { + key_data_s: KeyData, + key_data_c: KeyData, + key_data_w: KeyData, + parent_data_s: ParentData, + parent_data_c: ParentData, + diff_inv: Cell, +} + +impl StorageLeafConfig { + pub fn configure( + meta: &mut VirtualCells<'_, F>, + cb: &mut MPTConstraintBuilder, + ctx: MPTContext, + ) -> Self { + let is_s = true; + let accs = ctx.accumulators; + let value_prev = ctx.value_prev; + let value = ctx.value; + let s_main = ctx.s_main; + let r = ctx.r.clone(); + + let rot_parent = -1; + let rot_branch_init = rot_parent - (BRANCH_ROWS_NUM - 1); + let rot_branch_child = rot_branch_init + 1; + + let rot_key_s = 0; + let rot_value_s = 1; + let rot_key_c = 2; + let rot_value_c = 3; + + let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + let mut ctx_key_data_c: Option> = None; + let mut ctx_key_data_s: Option> = None; + let ctx_key_data_w: KeyData; + let mut ctx_parent_data_s: Option> = None; + let mut ctx_parent_data_c: Option> = None; + let ctx_diff_inv: Cell; + + circuit!([meta, cb.base], { + let mut branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + + let mut offset = 0; + for is_s in [true, false] { + let storage = StorageLeafInfo::new(meta, ctx.clone(), is_s, offset); + branch.set_is_s(is_s); + + // Load the last key values, which depends on the branch being a placeholder. + let is_branch_placeholder = + ifx! {not!(storage.is_below_account(meta)) => { branch.is_placeholder() }}; + let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; + let key_data = KeyData::load( + &mut cb.base, + &mut cm, + &ctx.memory[key_memory(is_s)], + load_offset, + ); + + // The two flag values need to be boolean. + require!(storage.flag1 => bool); + require!(storage.flag2 => bool); + + // Calculate and store the leaf data RLC + require!(a!(accs.acc_s.rlc, offset) => ctx.rlc(meta, 0..36, offset)); + + // Calculate and store the key RLC. + let key_rlc = key_data.rlc.expr() + + storage.key_rlc( + meta, + &mut cb.base, + key_data.mult.expr(), + key_data.is_odd.expr(), + 1.expr(), + true, + 0, + ); + require!(a!(accs.key.rlc, offset) => key_rlc); + + // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES (except in a + // placeholder leaf). + // TODO(Brecht): why not in placeholder leaf? + ifx! {not!(storage.is_placeholder(meta)) => { + let num_nibbles = storage.num_key_nibbles(meta, key_data.is_odd.expr()); + require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); + }} + + // Num bytes used in RLC + let num_bytes = storage.num_bytes_on_key_row(meta); + // Multiplier is number of bytes + require!((FixedTableTag::RMult, num_bytes.expr(), a!(accs.acc_s.mult, offset)) => @"fixed"); + // RLC bytes zero check + //cb.set_length(num_bytes.expr()); + + // Key done, set the default values + KeyData::store( + &mut cb.base, + &ctx.memory[key_memory(is_s)], + KeyData::default_values(), + ); + + if is_s { + ctx_key_data_s = Some(key_data); + } else { + ctx_key_data_c = Some(key_data); + } + + offset += 1; + + let is_long = a!(accs.s_mod_node_rlc, offset); + let is_short = a!(accs.c_mod_node_rlc, offset); + + // We need to ensure `is_long` and `is_short` are boolean. + require!(is_short => bool); + require!(is_long => bool); + // `is_short` or `is_long` needs to be true. + require!(sum::expr([is_short.expr(), is_long.expr()]) => 1); + + let rot_s = offset + if is_s { 0 } else { -2 }; + let rot_key = offset - 1; + + // We need to ensure that the stored leaf RLC and value RLC is the same as the + // computed one. + let leaf_rlc = + DataTransition::new_with_rot(meta, accs.acc_s.rlc, offset - 1, offset); + let value_rlc = DataTransition::new_with_rot(meta, accs.acc_c.rlc, rot_s, offset); + let mult_prev = a!(accs.acc_s.mult, rot_key); + let (new_value_rlc, leaf_rlc_part) = ifx! {is_short => { + (a!(s_main.rlp1, offset), a!(s_main.rlp1, offset) * mult_prev.expr()) + } elsex { + let value_rlc = s_main.bytes(meta, offset).rlc(&r); + let leaf_rlc = (0.expr(), mult_prev.expr()).rlc_chain([a!(s_main.rlp1, offset), a!(s_main.rlp2, offset), value_rlc.expr()].rlc(&r)); + (value_rlc, leaf_rlc) + }}; + require!(value_rlc => new_value_rlc); + require!(leaf_rlc => leaf_rlc.prev() + leaf_rlc_part); + + // To enable external lookups we need to have the key and the previous/current + // value on the same row. + if !is_s { + require!(a!(accs.key.mult, offset) => a!(accs.key.rlc, rot_key)); + require!(a!(value_prev, offset) => value_rlc.prev()); + require!(a!(value, offset) => value_rlc); + } + + // Get the number of bytes used by the value + let value_num_bytes = matchx! { + is_short => 1.expr(), + is_long => 1.expr() + get_num_bytes_short(a!(s_main.rlp2, offset)), + }; + + // If `is_modified_node_empty = 1`, which means an empty child, we need to + // ensure that the value is set to 0 in the placeholder leaf. For + // example when adding a new storage leaf to the trie, we have an empty child in + // `S` proof and non-empty in `C` proof. + ifx! {branch.contains_placeholder_leaf(meta, is_s) => { + require!(a!(s_main.rlp1, offset) => 0); + }} + + // Make sure the RLP encoding is correct. + // storage = [key, value] + let num_bytes = storage.num_bytes(meta); + // TODO(Brecht): modify the witness for empty placeholder leafs to have valid + // RLP encoding + ifx! {not!(branch.contains_placeholder_leaf(meta, is_s)) => { + let key_num_bytes = storage.num_bytes_on_key_row(meta); + require!(num_bytes => key_num_bytes.expr() + value_num_bytes.expr()); + }}; + + // Check if the account is in its parent. + let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + let parent_data = ParentData::load( + "leaf load", + &mut cb.base, + &mut cm, + &ctx.memory[parent_memory(is_s)], + 0.expr(), + ); + // Check is skipped for placeholder leafs which are dummy leafs + ifx! {storage.is_below_account(meta), storage.is_placeholder_without_branch(meta) => { + // TODO(Brecht): Add this to the keccak table when necessary instead? + // Hash of the only storage leaf which is placeholder requires empty storage root + let empty_root_rlc = EMPTY_TRIE_HASH.iter().map(|v| v.expr()).collect::>().rlc(&r); + require!(parent_data.rlc => empty_root_rlc); + } elsex { + ifx!{not!(and::expr(&[not!(storage.is_below_account(meta)), branch.contains_placeholder_leaf(meta, is_s)])) => { + let is_not_hashed = a!(accs.acc_c.rlc, offset-1); + ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { + // Hashed branch hash in parent branch + require!((1, leaf_rlc, num_bytes, parent_data.rlc) => @"keccak"); + } elsex { + // Non-hashed branch hash in parent branch + require!(leaf_rlc => parent_data.rlc); + }} + }} + }} + // Store the new parent + ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [0.expr(), true.expr()], + ); + + // Set the number of bytes used + //cb.set_length_s(value_num_bytes); + + offset += 1; + + if is_s { + ctx_parent_data_s = Some(parent_data); + } else { + ctx_parent_data_c = Some(parent_data); + } + } + + let storage = StorageLeafInfo::new(meta, ctx.clone(), true, 0); + ifx! {not!(storage.is_below_account(meta)) => { + let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); + let drifted_storage = StorageLeafInfo::new(meta, ctx.clone(), true, offset); + + // The two flag values need to be boolean. + require!(drifted_storage.flag1 => bool); + require!(drifted_storage.flag2 => bool); + + // Calculate and store the leaf RLC (RLP + key) + let drifted_rlc = a!(accs.acc_s.rlc, offset); + require!(drifted_rlc => ctx.rlc(meta, 0..36, offset)); + + // We need the intermediate key RLC right before `drifted_index` is added to it. + // If the branch parallel to the placeholder branch is an extension node, + // we have the intermediate RLC stored in the extension node `accs.key.rlc`. + let is_branch_in_first_level = branch.is_below_account(meta); + let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); + // Calculate the drifted key RLC + let drifted_key_rlc = key_rlc_prev.expr() + + branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + + drifted_storage.key_rlc(meta, &mut cb.base, key_mult_prev, branch.is_key_odd(), r[0].expr(), true, 0); + + // Check zero bytes and mult_diff + let mult = a!(accs.acc_s.mult, offset); + ifx!{branch.is_placeholder_s_or_c() => { + // Num bytes used in RLC + let num_bytes = drifted_storage.num_bytes_on_key_row(meta); + // Multiplier is number of bytes + require!((FixedTableTag::RMult, num_bytes.expr(), mult) => @"fixed"); + // RLC bytes zero check + //cb.set_length(num_bytes.expr()); + }} + + // Check that the drifted leaf is unchanged and is stored at `drifted_index`. + let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { + circuit!([meta, cb], { + let rot_key = if is_s { rot_key_s } else { rot_key_c }; + let rot_value = if is_s { rot_value_s } else { rot_value_c }; + // Complete the drifted leaf rlc by adding the bytes on the value row + let drifted_rlc = (drifted_rlc.expr(), mult.expr()).rlc_chain(s_main.rlc(meta, rot_value, &r)); + (true.expr(), a!(accs.key.rlc, rot_key), drifted_rlc, a!(accs.mod_node_rlc(is_s), rot_branch_child)) + }) + }; + let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { + branch.is_placeholder_s() => { + // Neighbour leaf in the added branch + // - `leaf_key_s_rlc` is the key RLC of the leaf before it drifted down + // in a new branch. + // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. + // This is because `c_mod_node_rlc` in the added branch stores the hash of + // `modified_index` (the leaf that has been added). + calc_rlc(true, meta, &mut cb.base) + }, + branch.is_placeholder_c() => { + // Neighbour leaf in the deleted branch + // -`leaf_key_c_rlc` is the key RLC of the leaf after its neighbour leaf + // has been deleted (and there were only two leaves, so the branch was deleted). + // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. + // This is because `s_mod_node_rlc` in the deleted branch stores the hash of + // `modified_index` (the leaf that is to be deleted). + calc_rlc(false, meta, &mut cb.base) + }, + _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), + }; + ifx! {do_checks => { + // The key of the drifted leaf needs to match the key of the leaf + require!(key_rlc => drifted_key_rlc); + // The drifted leaf needs to be stored in the branch at `drifted_index`. + require!((1, drifted_rlc, drifted_storage.num_bytes(meta), mod_hash) => @"keccak"); + }} + }} + + offset += 1; + + let storage = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); + let is_wrong_leaf = a!(s_main.rlp1, offset); + + // Make sure is_wrong_leaf is boolean + require!(is_wrong_leaf => bool); + + let diff_inv = cm.query_cell(CellType::Storage); + ifx! {a!(ctx.proof_type.is_non_existing_storage_proof, offset) => { + // Get the previous key RLC data + let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 1.expr()); + ifx! {is_wrong_leaf => { + // Calculate the key and check it's the address as requested in the lookup + let key_rlc_wrong = key_data.rlc.expr() + storage.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), false, offset - rot_key_c); + require!(a!(accs.key.mult, offset) => key_rlc_wrong); + // Now make sure this address is different than the one of the leaf + require!((a!(accs.key.mult, offset) - a!(accs.key.rlc, rot_key_c)) * diff_inv.expr() => 1); + // Make sure the lengths of the keys are the same + let mut storage_wrong = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); + storage_wrong.set_rot_key(0); + require!(storage_wrong.key_len(meta) => storage.key_len(meta)); + // RLC bytes zero check + let num_bytes = storage.num_bytes_on_key_row(meta); + //cb.set_length(num_bytes); + } elsex { + // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. + require!(key_data.is_placeholder_leaf_c => true); + }} + ctx_key_data_w = key_data; + } elsex { + // is_wrong_leaf needs to be false when not in non_existing_account proof + require!(is_wrong_leaf => false); + }} + ctx_diff_inv = diff_inv; + }); + + StorageLeafConfig { + key_data_s: ctx_key_data_s.unwrap(), + key_data_c: ctx_key_data_c.unwrap(), + key_data_w: ctx_key_data_w, + parent_data_s: ctx_parent_data_s.unwrap(), + parent_data_c: ctx_parent_data_c.unwrap(), + diff_inv: ctx_diff_inv, + } + } + + pub fn assign( + &self, + region: &mut Region<'_, F>, + mpt_config: &MPTConfig, + witness: &[MptWitnessRow], + pv: &mut ProofValues, + offset: usize, + ) -> Result<(), Error> { + let base_offset = offset; + let mut offset = offset; + + for is_s in [true, false] { + /* KEY */ + + { + let row = &witness[offset]; + + // Info whether leaf rlp is long or short: + // - long means the key length is at position 2. + // - short means the key length is at position 1. + let mut typ = "short"; + if row.get_byte(0) == 248 { + typ = "long"; + } else if row.get_byte(1) == 32 { + typ = "last_level"; + } else if row.get_byte(1) < 128 { + typ = "one_nibble"; + } + mpt_config.assign_long_short(region, typ, offset).ok(); + + pv.acc_s = F::zero(); + pv.acc_mult_s = F::one(); + let len: usize; + if typ == "long" { + len = (row.get_byte(2) - 128) as usize + 3; + } else if typ == "short" { + len = (row.get_byte(1) - 128) as usize + 2; + } else { + // last_level or one_nibble + len = 2 + } + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_s, + &mut pv.acc_mult_s, + 0, + len, + ); + + mpt_config + .assign_acc( + region, + pv.acc_s, + pv.acc_mult_s, + F::zero(), + F::zero(), + offset, + ) + .ok(); + + // note that this assignment needs to be after assign_acc call + if row.get_byte(0) < 223 { + // when shorter than 32 bytes, the node doesn't get hashed + // not_hashed + region + .assign_advice( + || "assign not_hashed".to_string(), + mpt_config.accumulators.acc_c.rlc, + offset, + || Value::known(F::one()), + ) + .ok(); + } + + // TODO: handle if branch or extension node is added + let mut start = S_START - 1; + if row.get_byte(0) == 248 { + // long RLP + start = S_START; + } + + let is_branch_placeholder = if is_s { + pv.is_branch_s_placeholder + } else { + pv.is_branch_c_placeholder + }; + let load_offset = if is_branch_placeholder { 1 } else { 0 }; + + let key_data = if is_s { + &self.key_data_s + } else { + &self.key_data_c + }; + key_data.witness_load( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + load_offset, + )?; + key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + F::zero(), + F::one(), + 0, + false, + false, + )?; + + // For leaf S and leaf C we need to start with the same rlc. + let mut key_rlc_new = pv.key_rlc; + let mut key_rlc_mult_new = pv.key_rlc_mult; + if (pv.is_branch_s_placeholder + && row.get_type() == MptWitnessRowType::StorageLeafSKey) + || (pv.is_branch_c_placeholder + && row.get_type() == MptWitnessRowType::StorageLeafCKey) + { + key_rlc_new = pv.key_rlc_prev; + key_rlc_mult_new = pv.key_rlc_mult_prev; + } + if typ != "last_level" && typ != "one_nibble" { + // If in last level or having only one nibble, + // the key RLC is already computed using the first two bytes above. + mpt_config.compute_key_rlc( + &row.bytes, + &mut key_rlc_new, + &mut key_rlc_mult_new, + start, + ); + } + region.assign_advice( + || "assign key_rlc".to_string(), + mpt_config.accumulators.key.rlc, + offset, + || Value::known(key_rlc_new), + )?; + pv.storage_key_rlc = key_rlc_new; + + // Store key_rlc into rlc2 to be later set in leaf value C row (to enable + // lookups): + pv.rlc2 = key_rlc_new; + } + + /* VALUE */ + + offset += 1; + + { + let row_prev = &witness[offset - 1]; + let row = &witness[offset]; + + // Info whether leaf value is 1 byte or more: + let mut is_long = false; + if row_prev.get_byte(0) == 248 { + // whole leaf is in long format (3 RLP meta bytes) + let key_len = row_prev.get_byte(2) - 128; + if row_prev.get_byte(1) - key_len - 1 > 1 { + is_long = true; + } + } else if row_prev.get_byte(1) < 128 { + // last_level or one_nibble + let leaf_len = row_prev.get_byte(0) - 192; + if leaf_len - 1 > 1 { + is_long = true; + } + } else { + let leaf_len = row_prev.get_byte(0) - 192; + let key_len = row_prev.get_byte(1) - 128; + if leaf_len - key_len - 1 > 1 { + is_long = true; + } + } + // Short means there is only one byte for value (no RLP specific bytes). + // Long means there is more than one byte for value which brings two + // RLP specific bytes, like: 161 160 ... for 32-long value. + let mut typ = "short"; + if is_long { + typ = "long"; + } + mpt_config.assign_long_short(region, typ, offset).ok(); + + // Leaf RLC + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_s, + &mut pv.acc_mult_s, + 0, + HASH_WIDTH + 2, + ); + + pv.acc_c = F::zero(); + pv.acc_mult_c = F::one(); + // Leaf value RLC + let mut start = 0; + if is_long { + start = 2; + } + mpt_config.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_c, + &mut pv.acc_mult_c, + start, + HASH_WIDTH + 2, + ); + + let empty_trie_hash: Vec = vec![ + 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, + 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, + ]; + if is_s { + // Store leaf value RLC into rlc1 to be later set in leaf value C row (to enable + // lookups): + pv.rlc1 = pv.acc_c; + + /* + account leaf storage codehash S <- rotate here + account leaf storage codehash C + account leaf in added branch + leaf key S + leaf value S <- we are here + leaf key C + leaf value C + */ + let row_prev = &witness[offset - 4]; + if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashS + && row_prev.s_hash_bytes() == empty_trie_hash + { + // Leaf is without branch and it is just a placeholder. + region + .assign_advice( + || "assign sel1".to_string(), + mpt_config.denoter.sel1, + offset, + || Value::known(F::one()), + ) + .ok(); + } + } else { + region + .assign_advice( + || "assign key_rlc into key_rlc_mult".to_string(), + mpt_config.accumulators.key.mult, + offset, + || Value::known(pv.rlc2), + ) + .ok(); + region + .assign_advice( + || "assign leaf value S into value_prev".to_string(), + mpt_config.value_prev, + offset, + || Value::known(pv.rlc1), + ) + .ok(); + + /* + account leaf storage codehash S + account leaf storage codehash C <- rotate here + account leaf in added branch + leaf key S + leaf value S + leaf key C + leaf value C <- we are here + */ + let row_prev = &witness[offset - 5]; + if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashC + && row_prev.s_hash_bytes() == empty_trie_hash + { + // Leaf is without branch and it is just a placeholder. + region + .assign_advice( + || "assign sel2".to_string(), + mpt_config.denoter.sel2, + offset, + || Value::known(F::one()), + ) + .ok(); + } + } + + let parent_data = if is_s { + &self.parent_data_s + } else { + &self.parent_data_c + }; + parent_data + .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) + .ok(); + parent_data + .witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + F::zero(), + true, + ) + .ok(); + + mpt_config + .assign_acc( + region, + pv.acc_s, // leaf RLC + pv.acc_mult_s, + pv.acc_c, // leaf value RLC + F::zero(), + offset, + ) + .ok(); + + region + .assign_advice( + || "assign leaf value C into value".to_string(), + mpt_config.value, + offset, + || Value::known(pv.acc_c), + ) + .ok(); + + if !is_s && row.get_byte_rev(IS_STORAGE_MOD_POS) == 1 { + region + .assign_advice( + || "assign lookup enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(6_u64)), /* storage mod lookup enabled in + * this row + * if it is is_storage_mod proof */ + ) + .ok(); + } + } + + offset += 1; + } + + { + let row = &witness[offset]; + + /* + row[1] != 0 just to avoid usize problems below (when row doesn't + need to be assigned) Info whether leaf rlp is long or short. + */ + /* + Info whether leaf rlp is long or short: + - long means the key length is at position 2. + - short means the key length is at position 1. + */ + let mut typ = "short"; + if row.get_byte(0) == 248 { + typ = "long"; + } else if row.get_byte(1) == 32 { + typ = "last_level"; + } else if row.get_byte(1) < 128 { + typ = "one_nibble"; + } + mpt_config.assign_long_short(region, typ, offset).ok(); + + pv.acc_s = F::zero(); + pv.acc_mult_s = F::one(); + let len: usize; + if typ == "long" { + len = (row.get_byte(2) - 128) as usize + 3; + } else if typ == "short" { + len = (row.get_byte(1) - 128) as usize + 2; + } else { + // last_level or one_nibble + len = 2 + } + mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); + + mpt_config + .assign_acc( + region, + pv.acc_s, + pv.acc_mult_s, + F::zero(), + F::zero(), + offset, + ) + .ok(); + + offset += 1; + } + + { + self.key_data_w + .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) + .ok(); + + let row = &witness[offset]; + if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { + let row_key_c = + &witness[offset - (LEAF_NON_EXISTING_IND - LEAF_KEY_C_IND) as usize]; + let mut start = S_START - 1; + if row_key_c.get_byte(0) == 248 { + start = S_START; + } + let mut key_rlc_new = pv.key_rlc; + let mut key_rlc_mult_new = pv.key_rlc_mult; + mpt_config.compute_key_rlc( + &row.bytes, + &mut key_rlc_new, + &mut key_rlc_mult_new, + start, + ); + region + .assign_advice( + || "assign key_rlc".to_string(), + mpt_config.accumulators.key.mult, // lookup uses `key.mult` + offset, + || Value::known(key_rlc_new), + ) + .ok(); + + let diff_inv = (key_rlc_new - pv.storage_key_rlc) + .invert() + .unwrap_or(F::zero()); + self.diff_inv + .assign(region, base_offset, Value::known(diff_inv)) + .ok(); + + if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { + region + .assign_advice( + || "assign lookup enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(7_u64)), /* non existing storage lookup + * enabled in + * this row if it is + * non_existing_storage + * proof */ + ) + .ok(); + } + } + } + + Ok(()) + } +} diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs deleted file mode 100644 index d1c414f277..0000000000 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_combined.rs +++ /dev/null @@ -1,770 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, - plonk::{Error, VirtualCells}, - poly::Rotation, -}; - -use crate::{ - circuit, - circuit_tools::{CellManager, DataTransition, RLCable, RLCChainable, ConstraintBuilder, CellType, Cell}, - mpt_circuit::{ - helpers::BranchNodeInfo, - param::{BRANCH_ROWS_NUM, S_START}, - }, - mpt_circuit::{ - helpers::{KeyData, MPTConstraintBuilder, StorageLeafInfo, get_num_bytes_short, ParentData, parent_memory, get_parent_rlc_state, key_memory}, - param::{KEY_LEN_IN_NIBBLES, EMPTY_TRIE_HASH, HASH_WIDTH, IS_STORAGE_MOD_POS, LEAF_NON_EXISTING_IND, LEAF_KEY_C_IND, IS_NON_EXISTING_STORAGE_POS}, - FixedTableTag, - }, - mpt_circuit::{ - witness_row::{MptWitnessRow, MptWitnessRowType}, - MPTContext, - }, - mpt_circuit::{MPTConfig, ProofValues}, -}; - -#[derive(Clone, Debug)] -pub(crate) struct LeafCombinedConfig { - key_data_s: KeyData, - key_data_c: KeyData, - key_data_w: KeyData, - parent_data_s: ParentData, - parent_data_c: ParentData, - diff_inv: Cell, -} - -impl LeafCombinedConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - ) -> Self { - let is_s = true; - let accs = ctx.accumulators; - let value_prev = ctx.value_prev; - let value = ctx.value; - let s_main = ctx.s_main; - let r = ctx.r.clone(); - - let rot_parent = -1; - let rot_branch_init = rot_parent - (BRANCH_ROWS_NUM - 1); - let rot_branch_child = rot_branch_init + 1; - - let rot_key_s = 0; - let rot_value_s = 1; - let rot_key_c = 2; - let rot_value_c = 3; - - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); - let mut ctx_key_data_c: Option> = None; - let mut ctx_key_data_s: Option> = None; - let mut ctx_key_data_w: Option> = None; - let mut ctx_parent_data_s: Option> = None; - let mut ctx_parent_data_c: Option> = None; - let mut ctx_diff_inv: Option> = None; - - - circuit!([meta, cb.base], { - let mut branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - - let mut offset = 0; - for is_s in [true, false] { - let storage = StorageLeafInfo::new(meta, ctx.clone(), is_s, offset); - branch.set_is_s(is_s); - - // Load the last key values, which depends on the branch being a placeholder. - let is_branch_placeholder = ifx! {not!(storage.is_below_account(meta)) => { branch.is_placeholder() }}; - let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(is_s)], load_offset); - - // The two flag values need to be boolean. - require!(storage.flag1 => bool); - require!(storage.flag2 => bool); - - // Calculate and store the leaf data RLC - require!(a!(accs.acc_s.rlc, offset) => ctx.rlc(meta, 0..36, offset)); - - // Calculate and store the key RLC. - let key_rlc = key_data.rlc.expr() - + storage.key_rlc( - meta, - &mut cb.base, - key_data.mult.expr(), - key_data.is_odd.expr(), - 1.expr(), - true, - 0, - ); - require!(a!(accs.key.rlc, offset) => key_rlc); - - // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES (except in a - // placeholder leaf). - // TODO(Brecht): why not in placeholder leaf? - ifx! {not!(storage.is_placeholder(meta)) => { - let num_nibbles = storage.num_key_nibbles(meta, key_data.is_odd.expr()); - require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); - }} - - // Num bytes used in RLC - let num_bytes = storage.num_bytes_on_key_row(meta); - // Multiplier is number of bytes - require!((FixedTableTag::RMult, num_bytes.expr(), a!(accs.acc_s.mult, offset)) => @"fixed"); - // RLC bytes zero check - //cb.set_length(num_bytes.expr()); - - // Key done, set the default values - KeyData::store(&mut cb.base, &ctx.memory[key_memory(is_s)], KeyData::default_values()); - - if is_s { - ctx_key_data_s = Some(key_data); - } else { - ctx_key_data_c = Some(key_data); - } - - offset += 1; - - let is_long = a!(accs.s_mod_node_rlc, offset); - let is_short = a!(accs.c_mod_node_rlc, offset); - - // We need to ensure `is_long` and `is_short` are boolean. - require!(is_short => bool); - require!(is_long => bool); - // `is_short` or `is_long` needs to be true. - require!(sum::expr([is_short.expr(), is_long.expr()]) => 1); - - let rot_s = offset + if is_s { 0 } else { -2 }; - let rot_key = offset - 1; - - // We need to ensure that the stored leaf RLC and value RLC is the same as the - // computed one. - let leaf_rlc = DataTransition::new_with_rot(meta, accs.acc_s.rlc, offset - 1, offset); - let value_rlc = DataTransition::new_with_rot(meta, accs.acc_c.rlc, rot_s, offset); - let mult_prev = a!(accs.acc_s.mult, rot_key); - let (new_value_rlc, leaf_rlc_part) = ifx! {is_short => { - (a!(s_main.rlp1, offset), a!(s_main.rlp1, offset) * mult_prev.expr()) - } elsex { - let value_rlc = s_main.bytes(meta, offset).rlc(&r); - let leaf_rlc = (0.expr(), mult_prev.expr()).rlc_chain([a!(s_main.rlp1, offset), a!(s_main.rlp2, offset), value_rlc.expr()].rlc(&r)); - (value_rlc, leaf_rlc) - }}; - require!(value_rlc => new_value_rlc); - require!(leaf_rlc => leaf_rlc.prev() + leaf_rlc_part); - - // To enable external lookups we need to have the key and the previous/current - // value on the same row. - if !is_s { - require!(a!(accs.key.mult, offset) => a!(accs.key.rlc, rot_key)); - require!(a!(value_prev, offset) => value_rlc.prev()); - require!(a!(value, offset) => value_rlc); - } - - // Get the number of bytes used by the value - let value_num_bytes = matchx! { - is_short => 1.expr(), - is_long => 1.expr() + get_num_bytes_short(a!(s_main.rlp2, offset)), - }; - - // If `is_modified_node_empty = 1`, which means an empty child, we need to - // ensure that the value is set to 0 in the placeholder leaf. For - // example when adding a new storage leaf to the trie, we have an empty child in - // `S` proof and non-empty in `C` proof. - ifx! {branch.contains_placeholder_leaf(meta, is_s) => { - require!(a!(s_main.rlp1, offset) => 0); - }} - - // Make sure the RLP encoding is correct. - // storage = [key, value] - let num_bytes = storage.num_bytes(meta); - // TODO(Brecht): modify the witness for empty placeholder leafs to have valid - // RLP encoding - ifx! {not!(branch.contains_placeholder_leaf(meta, is_s)) => { - let key_num_bytes = storage.num_bytes_on_key_row(meta); - require!(num_bytes => key_num_bytes.expr() + value_num_bytes.expr()); - }}; - - // Check if the account is in its parent. - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let parent_data = ParentData::load( - "leaf load", - &mut cb.base, - &mut cm, - &ctx.memory[parent_memory(is_s)], - 0.expr(), - ); - // Check is skipped for placeholder leafs which are dummy leafs - ifx! {storage.is_below_account(meta), storage.is_placeholder_without_branch(meta) => { - // TODO(Brecht): Add this to the keccak table when necessary instead? - // Hash of the only storage leaf which is placeholder requires empty storage root - let empty_root_rlc = EMPTY_TRIE_HASH.iter().map(|v| v.expr()).collect::>().rlc(&r); - require!(parent_data.rlc => empty_root_rlc); - } elsex { - ifx!{not!(and::expr(&[not!(storage.is_below_account(meta)), branch.contains_placeholder_leaf(meta, is_s)])) => { - let is_not_hashed = a!(accs.acc_c.rlc, offset-1); - ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { - // Hashed branch hash in parent branch - require!((1, leaf_rlc, num_bytes, parent_data.rlc) => @"keccak"); - } elsex { - // Non-hashed branch hash in parent branch - require!(leaf_rlc => parent_data.rlc); - }} - }} - }} - // Store the new parent - ParentData::store( - &mut cb.base, - &ctx.memory[parent_memory(is_s)], - [0.expr(), true.expr()], - ); - - // Set the number of bytes used - //cb.set_length_s(value_num_bytes); - - offset += 1; - - if is_s { - ctx_parent_data_s = Some(parent_data); - } else { - ctx_parent_data_c = Some(parent_data); - } - } - - - let storage = StorageLeafInfo::new(meta, ctx.clone(), true, 0); - ifx! {not!(storage.is_below_account(meta)) => { - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - let drifted_storage = StorageLeafInfo::new(meta, ctx.clone(), true, offset); - - // The two flag values need to be boolean. - require!(drifted_storage.flag1 => bool); - require!(drifted_storage.flag2 => bool); - - // Calculate and store the leaf RLC (RLP + key) - let drifted_rlc = a!(accs.acc_s.rlc, offset); - require!(drifted_rlc => ctx.rlc(meta, 0..36, offset)); - - // We need the intermediate key RLC right before `drifted_index` is added to it. - // If the branch parallel to the placeholder branch is an extension node, - // we have the intermediate RLC stored in the extension node `accs.key.rlc`. - let is_branch_in_first_level = branch.is_below_account(meta); - let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); - // Calculate the drifted key RLC - let drifted_key_rlc = key_rlc_prev.expr() + - branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + - drifted_storage.key_rlc(meta, &mut cb.base, key_mult_prev, branch.is_key_odd(), r[0].expr(), true, 0); - - // Check zero bytes and mult_diff - let mult = a!(accs.acc_s.mult, offset); - ifx!{branch.is_placeholder_s_or_c() => { - // Num bytes used in RLC - let num_bytes = drifted_storage.num_bytes_on_key_row(meta); - // Multiplier is number of bytes - require!((FixedTableTag::RMult, num_bytes.expr(), mult) => @"fixed"); - // RLC bytes zero check - //cb.set_length(num_bytes.expr()); - }} - - // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { - circuit!([meta, cb], { - let rot_key = if is_s { rot_key_s } else { rot_key_c }; - let rot_value = if is_s { rot_value_s } else { rot_value_c }; - // Complete the drifted leaf rlc by adding the bytes on the value row - let drifted_rlc = (drifted_rlc.expr(), mult.expr()).rlc_chain(s_main.rlc(meta, rot_value, &r)); - (true.expr(), a!(accs.key.rlc, rot_key), drifted_rlc, a!(accs.mod_node_rlc(is_s), rot_branch_child)) - }) - }; - let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { - branch.is_placeholder_s() => { - // Neighbour leaf in the added branch - // - `leaf_key_s_rlc` is the key RLC of the leaf before it drifted down - // in a new branch. - // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `c_mod_node_rlc` in the added branch stores the hash of - // `modified_index` (the leaf that has been added). - calc_rlc(true, meta, &mut cb.base) - }, - branch.is_placeholder_c() => { - // Neighbour leaf in the deleted branch - // -`leaf_key_c_rlc` is the key RLC of the leaf after its neighbour leaf - // has been deleted (and there were only two leaves, so the branch was deleted). - // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `s_mod_node_rlc` in the deleted branch stores the hash of - // `modified_index` (the leaf that is to be deleted). - calc_rlc(false, meta, &mut cb.base) - }, - _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), - }; - ifx! {do_checks => { - // The key of the drifted leaf needs to match the key of the leaf - require!(key_rlc => drifted_key_rlc); - // The drifted leaf needs to be stored in the branch at `drifted_index`. - require!((1, drifted_rlc, drifted_storage.num_bytes(meta), mod_hash) => @"keccak"); - }} - }} - - offset += 1; - - let storage = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); - let is_wrong_leaf = a!(s_main.rlp1, offset); - - // Make sure is_wrong_leaf is boolean - require!(is_wrong_leaf => bool); - - let diff_inv = cm.query_cell(CellType::Storage); - ifx! {a!(ctx.proof_type.is_non_existing_storage_proof, offset) => { - // Get the previous key RLC data - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 1.expr()); - ifx! {is_wrong_leaf => { - // Calculate the key and check it's the address as requested in the lookup - let key_rlc_wrong = key_data.rlc.expr() + storage.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), false, offset - rot_key_c); - require!(a!(accs.key.mult, offset) => key_rlc_wrong); - // Now make sure this address is different than the one of the leaf - require!((a!(accs.key.mult, offset) - a!(accs.key.rlc, rot_key_c)) * diff_inv.expr() => 1); - // Make sure the lengths of the keys are the same - let mut storage_wrong = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); - storage_wrong.set_rot_key(0); - require!(storage_wrong.key_len(meta) => storage.key_len(meta)); - // RLC bytes zero check - let num_bytes = storage.num_bytes_on_key_row(meta); - //cb.set_length(num_bytes); - } elsex { - // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. - require!(key_data.is_placeholder_leaf_c => true); - }} - ctx_key_data_w = Some(key_data); - } elsex { - // is_wrong_leaf needs to be false when not in non_existing_account proof - require!(is_wrong_leaf => false); - }} - ctx_diff_inv = Some(diff_inv); - }); - - LeafCombinedConfig { - key_data_s: ctx_key_data_s.unwrap(), - key_data_c: ctx_key_data_c.unwrap(), - key_data_w: ctx_key_data_w.unwrap(), - parent_data_s: ctx_parent_data_s.unwrap(), - parent_data_c: ctx_parent_data_c.unwrap(), - diff_inv: ctx_diff_inv.unwrap(), - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - witness: &[MptWitnessRow], - pv: &mut ProofValues, - offset: usize, - ) -> Result<(), Error> { - - println!("offset: {}", offset); - - let base_offset = offset; - let mut offset = offset; - - for is_s in [true, false] { - - /* KEY */ - - { - let row = &witness[offset]; - - // Info whether leaf rlp is long or short: - // - long means the key length is at position 2. - // - short means the key length is at position 1. - let mut typ = "short"; - if row.get_byte(0) == 248 { - typ = "long"; - } else if row.get_byte(1) == 32 { - typ = "last_level"; - } else if row.get_byte(1) < 128 { - typ = "one_nibble"; - } - mpt_config.assign_long_short(region, typ, offset).ok(); - - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - let len: usize; - if typ == "long" { - len = (row.get_byte(2) - 128) as usize + 3; - } else if typ == "short" { - len = (row.get_byte(1) - 128) as usize + 2; - } else { - // last_level or one_nibble - len = 2 - } - mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); - - mpt_config - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) - .ok(); - - // note that this assignment needs to be after assign_acc call - if row.get_byte(0) < 223 { - // when shorter than 32 bytes, the node doesn't get hashed - // not_hashed - region - .assign_advice( - || "assign not_hashed".to_string(), - mpt_config.accumulators.acc_c.rlc, - offset, - || Value::known(F::one()), - ) - .ok(); - } - - // TODO: handle if branch or extension node is added - let mut start = S_START - 1; - if row.get_byte(0) == 248 { - // long RLP - start = S_START; - } - - let is_branch_placeholder = if is_s { - pv.is_branch_s_placeholder - } else { - pv.is_branch_c_placeholder - }; - let load_offset = if is_branch_placeholder { 1 } else { 0 }; - - let key_data = if is_s { &self.key_data_s } else { &self.key_data_c }; - key_data - .witness_load(region, base_offset, &mut pv.memory[key_memory(is_s)], load_offset)?; - key_data.witness_store( - region, - base_offset, - &mut pv.memory[key_memory(is_s)], - F::zero(), - F::one(), - 0, - false, - false, - )?; - - // For leaf S and leaf C we need to start with the same rlc. - let mut key_rlc_new = pv.key_rlc; - let mut key_rlc_mult_new = pv.key_rlc_mult; - if (pv.is_branch_s_placeholder && row.get_type() == MptWitnessRowType::StorageLeafSKey) - || (pv.is_branch_c_placeholder && row.get_type() == MptWitnessRowType::StorageLeafCKey) - { - key_rlc_new = pv.key_rlc_prev; - key_rlc_mult_new = pv.key_rlc_mult_prev; - } - if typ != "last_level" && typ != "one_nibble" { - // If in last level or having only one nibble, - // the key RLC is already computed using the first two bytes above. - mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, start); - } - region.assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(key_rlc_new), - )?; - pv.storage_key_rlc = key_rlc_new; - - // Store key_rlc into rlc2 to be later set in leaf value C row (to enable - // lookups): - pv.rlc2 = key_rlc_new; - } - - - - /* VALUE */ - - offset += 1; - println!("offset value: {}", offset); - - { - - let row_prev = &witness[offset - 1]; - let row = &witness[offset]; - - // Info whether leaf value is 1 byte or more: - let mut is_long = false; - if row_prev.get_byte(0) == 248 { - // whole leaf is in long format (3 RLP meta bytes) - let key_len = row_prev.get_byte(2) - 128; - if row_prev.get_byte(1) - key_len - 1 > 1 { - is_long = true; - } - } else if row_prev.get_byte(1) < 128 { - // last_level or one_nibble - let leaf_len = row_prev.get_byte(0) - 192; - if leaf_len - 1 > 1 { - is_long = true; - } - } else { - let leaf_len = row_prev.get_byte(0) - 192; - let key_len = row_prev.get_byte(1) - 128; - if leaf_len - key_len - 1 > 1 { - is_long = true; - } - } - // Short means there is only one byte for value (no RLP specific bytes). - // Long means there is more than one byte for value which brings two - // RLP specific bytes, like: 161 160 ... for 32-long value. - let mut typ = "short"; - if is_long { - typ = "long"; - } - mpt_config.assign_long_short(region, typ, offset).ok(); - - // Leaf RLC - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - 0, - HASH_WIDTH + 2, - ); - - pv.acc_c = F::zero(); - pv.acc_mult_c = F::one(); - // Leaf value RLC - let mut start = 0; - if is_long { - start = 2; - } - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_c, - &mut pv.acc_mult_c, - start, - HASH_WIDTH + 2, - ); - - let empty_trie_hash: Vec = vec![ - 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, - 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, - ]; - if is_s { - // Store leaf value RLC into rlc1 to be later set in leaf value C row (to enable - // lookups): - pv.rlc1 = pv.acc_c; - - /* - account leaf storage codehash S <- rotate here - account leaf storage codehash C - account leaf in added branch - leaf key S - leaf value S <- we are here - leaf key C - leaf value C - */ - let row_prev = &witness[offset - 4]; - if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashS - && row_prev.s_hash_bytes() == empty_trie_hash - { - // Leaf is without branch and it is just a placeholder. - region - .assign_advice( - || "assign sel1".to_string(), - mpt_config.denoter.sel1, - offset, - || Value::known(F::one()), - ) - .ok(); - } - } else { - region - .assign_advice( - || "assign key_rlc into key_rlc_mult".to_string(), - mpt_config.accumulators.key.mult, - offset, - || Value::known(pv.rlc2), - ) - .ok(); - region - .assign_advice( - || "assign leaf value S into value_prev".to_string(), - mpt_config.value_prev, - offset, - || Value::known(pv.rlc1), - ) - .ok(); - - /* - account leaf storage codehash S - account leaf storage codehash C <- rotate here - account leaf in added branch - leaf key S - leaf value S - leaf key C - leaf value C <- we are here - */ - let row_prev = &witness[offset - 5]; - if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashC - && row_prev.s_hash_bytes() == empty_trie_hash - { - // Leaf is without branch and it is just a placeholder. - region - .assign_advice( - || "assign sel2".to_string(), - mpt_config.denoter.sel2, - offset, - || Value::known(F::one()), - ) - .ok(); - } - } - - let parent_data = if is_s { &self.parent_data_s } else { &self.parent_data_c }; - parent_data - .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) - .ok(); - parent_data - .witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(is_s)], - F::zero(), - true, - ) - .ok(); - - mpt_config - .assign_acc( - region, - pv.acc_s, // leaf RLC - pv.acc_mult_s, - pv.acc_c, // leaf value RLC - F::zero(), - offset, - ) - .ok(); - - region - .assign_advice( - || "assign leaf value C into value".to_string(), - mpt_config.value, - offset, - || Value::known(pv.acc_c), - ) - .ok(); - - if !is_s && row.get_byte_rev(IS_STORAGE_MOD_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(6_u64)), /* storage mod lookup enabled in this row - * if it is is_storage_mod proof */ - ) - .ok(); - } - } - - offset += 1; - } - - { - let row = &witness[offset]; - - /* - row[1] != 0 just to avoid usize problems below (when row doesn't - need to be assigned) Info whether leaf rlp is long or short. - */ - /* - Info whether leaf rlp is long or short: - - long means the key length is at position 2. - - short means the key length is at position 1. - */ - let mut typ = "short"; - if row.get_byte(0) == 248 { - typ = "long"; - } else if row.get_byte(1) == 32 { - typ = "last_level"; - } else if row.get_byte(1) < 128 { - typ = "one_nibble"; - } - mpt_config.assign_long_short(region, typ, offset).ok(); - - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - let len: usize; - if typ == "long" { - len = (row.get_byte(2) - 128) as usize + 3; - } else if typ == "short" { - len = (row.get_byte(1) - 128) as usize + 2; - } else { - // last_level or one_nibble - len = 2 - } - mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); - - mpt_config - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) - .ok(); - - offset += 1; - } - - { - self.key_data_w - .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) - .ok(); - - let row = &witness[offset]; - if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { - let row_key_c = &witness[offset - (LEAF_NON_EXISTING_IND - LEAF_KEY_C_IND) as usize]; - let mut start = S_START - 1; - if row_key_c.get_byte(0) == 248 { - start = S_START; - } - let mut key_rlc_new = pv.key_rlc; - let mut key_rlc_mult_new = pv.key_rlc_mult; - mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, start); - region - .assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.mult, // lookup uses `key.mult` - offset, - || Value::known(key_rlc_new), - ) - .ok(); - - let diff_inv = (key_rlc_new - pv.storage_key_rlc) - .invert() - .unwrap_or(F::zero()); - self.diff_inv - .assign(region, base_offset, Value::known(diff_inv)) - .ok(); - - if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(7_u64)), /* non existing storage lookup enabled in - * this row if it is non_existing_storage - * proof */ - ) - .ok(); - } - } - } - - println!("offset post: {}", offset); - - Ok(()) - } -} diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key.rs deleted file mode 100644 index d742738309..0000000000 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key.rs +++ /dev/null @@ -1,358 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, - plonk::{Error, VirtualCells}, - poly::Rotation, -}; - -use crate::{ - circuit, - circuit_tools::CellManager, - mpt_circuit::{ - helpers::BranchNodeInfo, - param::{BRANCH_ROWS_NUM, S_START}, - }, - mpt_circuit::{ - helpers::{KeyData, MPTConstraintBuilder, StorageLeafInfo}, - param::KEY_LEN_IN_NIBBLES, - FixedTableTag, - }, - mpt_circuit::{ - witness_row::{MptWitnessRow, MptWitnessRowType}, - MPTContext, - }, - mpt_circuit::{MPTConfig, ProofValues}, -}; - -/* -A storage leaf occupies 6 rows. -Contrary as in the branch rows, the `S` and `C` leaves are not positioned parallel to each other. -The rows are the following: -LEAF_KEY_S -LEAF_VALUE_S -LEAF_KEY_C -LEAF_VALUE_C -LEAF_DRIFTED -LEAF_NON_EXISTING - -An example of leaf rows: -[226 160 59 138 106 70 105 186 37 13 38 205 122 69 158 202 157 33 95 131 7 227 58 235 229 3 121 188 90 54 23 236 52 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[226 160 59 138 106 70 105 186 37 13 38 205 122 69 158 202 157 33 95 131 7 227 58 235 229 3 121 188 90 54 23 236 52 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -In the above example the value has been changed from 1 (`LEAF_VALUE_S`) to 17 (`LEAF_VALUE_C`). - -In the example below the value in `LEAF_VALUE_C` takes more than 1 byte: `[187 239 170 ...]` -This has two consequences: - - Two additional RLP bytes: `[161 160]` where `33 = 161 - 128` means there are `31` bytes behind `161`, - `32 = 160 - 128` means there are `30` bytes behind `160`. - - `LEAF_KEY_S` starts with `248` because the leaf has more than 55 bytes, `1 = 248 - 247` means - there is 1 byte after `248` which specifies the length - the length is `67`. We can see that - that the leaf key is shifted by 1 position compared to the example above. - -For this reason we need to distinguish two cases: 1 byte in leaf value, more than 1 byte in leaf value. -These two cases are denoted by `is_short` and `is_long`. There are two other cases we need to -distinguish: `last_level` when the leaf is in the last level and has no nibbles, `one_nibble` when -the leaf has only one nibble. - -`is_long`: -[226 160 59 138 106 70 105 186 37 13 38 205 122 69 158 202 157 33 95 131 7 227 58 235 229 3 121 188 90 54 23 236 52 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[248 67 160 59 138 106 70 105 186 37 13 38 205 122 69 158 202 157 33 95 131 7 227 58 235 229 3 121 188 90 54 23 236 52 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[161 160 187 239 170 18 88 1 56 188 38 60 149 117 120 38 223 78 36 235 129 201 170 170 170 170 170 170 170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -`last_level` -[194 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[194 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -`one_nibble`: -[194 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[194 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -`s_mod_node_rlc` (`flag1`) and `c_mod_node_rlc` (`flag2`) columns store the information of what -kind of case we have: - `flag1: 1, flag2: 0`: `is_long` - `flag1: 0, flag2: 1`: `is_short` - `flag1: 1, flag2: 1`: `last_level` - `flag1: 0, flag0: 1`: `one_nibble` - -The constraints in `leaf_key.rs` apply to `LEAF_KEY_S` and `LEAF_KEY_C` rows. - -- We need to ensure that the storage leaf is at the key specified in `key_rlc` column (used -by MPT lookup). To do this we take the key RLC computed in the branches above the leaf -and add the remaining bytes (nibbles) stored in the leaf. -We also ensure that the number of all nibbles (in branches / extension nodes above -the leaf and in the leaf) is 64. -- For leaf under the placeholder branch we would not need to check the key RLC - -this leaf is something we did not ask for, it is just a leaf that happened to be -at the place where adding a new leaf causes adding a new branch. -For example, when adding a leaf `L` causes that a leaf `L1` -(this will be the leaf under the branch placeholder) -is replaced by a branch, we get a placeholder branch at `S` side -and leaf `L1` under it. However, the key RLC needs to be compared for leaf `L`, -because this is where the modification takes place. -In delete, the situation is turned around. -However, we also check that the key RLC for `L1` is computed properly because -we need `L1` key RLC for the constraints for checking that leaf `L1` is the same -as the drifted leaf in the branch parallel. This can be checked by -comparing the key RLC of the leaf before being replaced by branch and the key RLC -of this same leaf after it drifted into a branch. -Constraints for this are in `leaf_key_in_added_branch.rs`. -Note that the hash of a leaf `L1` needs to be checked to be in the branch -above the placeholder branch - this is checked in `leaf_value.rs`. -Note: `last_level` cannot occur in a leaf after placeholder branch, because being -after placeholder branch means this leaf drifted down into a new branch (in a parallel -proof) and thus cannot be in the last level. -- key rlc is in the first branch node (not branch init) -- If the last branch is placeholder (the placeholder branch is the same as its -parallel counterpart), there is a branch `modified_node` nibble already -incorporated in `key_rlc`. That means we need to ignore the first nibble here -(in leaf key). - -*/ - -#[derive(Clone, Debug)] -pub(crate) struct LeafKeyConfig { - key_data: KeyData, -} - -impl LeafKeyConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - cm: &mut CellManager, - ctx: MPTContext, - is_s: bool, - ) -> Self { - let accs = ctx.accumulators; - - let rot_parent = if is_s { -1 } else { -3 }; - let rot_branch_init = rot_parent - (BRANCH_ROWS_NUM - 1); - - let ctx_key_data: Option>; - - circuit!([meta, cb.base], { - let storage = StorageLeafInfo::new(meta, ctx.clone(), is_s, 0); - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - - // The two flag values need to be boolean. - require!(storage.flag1 => bool); - require!(storage.flag2 => bool); - - // Calculate and store the leaf data RLC - require!(a!(accs.acc_s.rlc) => ctx.rlc(meta, 0..36, 0)); - - // Load the last key values, which depends on the branch being a placeholder. - let is_branch_placeholder = - ifx! {not!(storage.is_below_account(meta)) => { branch.is_placeholder() }}; - let offset = if is_s { 0.expr() } else { 1.expr() }; - let offset = offset + ifx! {is_branch_placeholder => { 1.expr() }}; - let key_data = KeyData::load(&mut cb.base, cm, &ctx.memory["key"], offset); - - // Calculate and store the key RLC. - let key_rlc = key_data.rlc.expr() - + storage.key_rlc( - meta, - &mut cb.base, - key_data.mult.expr(), - key_data.is_odd.expr(), - 1.expr(), - true, - 0, - ); - require!(a!(accs.key.rlc) => key_rlc); - - // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES (except in a - // placeholder leaf). - // TODO(Brecht): why not in placeholder leaf? - ifx! {not!(storage.is_placeholder(meta)) => { - let num_nibbles = storage.num_key_nibbles(meta, key_data.is_odd.expr()); - require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); - }} - - // Key done, set the default values - KeyData::store(&mut cb.base, &ctx.memory["key"], KeyData::default_values()); - - // Num bytes used in RLC - let num_bytes = storage.num_bytes_on_key_row(meta); - // Multiplier is number of bytes - require!((FixedTableTag::RMult, num_bytes.expr(), a!(accs.acc_s.mult)) => @"mult"); - // RLC bytes zero check - cb.set_length(num_bytes.expr()); - - ctx_key_data = Some(key_data); - }); - - LeafKeyConfig { - key_data: ctx_key_data.unwrap(), - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &mut ProofValues, - row: &MptWitnessRow, - offset: usize, - ) -> Result<(), Error> { - /* - getProof storage leaf examples: - short (one RLP byte > 128: 160): - [226,160,59,138,106,70,105,186,37,13,38,205,122,69,158,202,157,33,95,131,7,227,58,235,229,3,121,188,90,54,23,236,52,68,1] - - long (two RLP bytes: 67, 160): - [248,67,160,59,138,106,70,105,186,37,13,38,205,122,69,158,202,157,33,95,131,7,227,58,235,229,3,121,188,90,54,23,236,52,68,161,160,187,239,170,18,88,1,56,188,38,60,149,117,120,38,223,78,36,235,129,201,170,170,170,170,170,17 - - last_level (one RLP byte: 32) - 32 at position 1 means there are no key nibbles (last level): - [227,32,161,160,187,239,170,18,88,1,56,188,38,60,149,117,120,38,223,78,36,235,129,201,170,170,170,170,170,170,170,170,170,170,170,170] - [194,32,1] - - this one falls into short again: - [196,130,32,0,1] - */ - - /* - Info whether leaf rlp is long or short: - - long means the key length is at position 2. - - short means the key length is at position 1. - */ - let mut typ = "short"; - if row.get_byte(0) == 248 { - typ = "long"; - } else if row.get_byte(1) == 32 { - typ = "last_level"; - } else if row.get_byte(1) < 128 { - typ = "one_nibble"; - } - mpt_config.assign_long_short(region, typ, offset).ok(); - - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - let len: usize; - if typ == "long" { - len = (row.get_byte(2) - 128) as usize + 3; - } else if typ == "short" { - len = (row.get_byte(1) - 128) as usize + 2; - } else { - // last_level or one_nibble - len = 2 - } - mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); - - mpt_config - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) - .ok(); - - // note that this assignment needs to be after assign_acc call - if row.get_byte(0) < 223 { - // when shorter than 32 bytes, the node doesn't get hashed - // not_hashed - region - .assign_advice( - || "assign not_hashed".to_string(), - mpt_config.accumulators.acc_c.rlc, - offset, - || Value::known(F::one()), - ) - .ok(); - } - - // TODO: handle if branch or extension node is added - let mut start = S_START - 1; - if row.get_byte(0) == 248 { - // long RLP - start = S_START; - } - - /*let key_memory = &mut pv.memory["key"]; - if row.get_type() == MptWitnessRowType::StorageLeafSKey { - if !pv.is_branch_s_placeholder { - self.key_data.assign(region, offset, key_memory, pv.key_rlc, pv.key_rlc_mult, pv.nibbles_num)?; - } else { - self.key_data.assign(region, offset, key_memory, pv.key_rlc_prev, pv.key_rlc_mult_prev, pv.nibbles_num_prev)?; - } - } - if row.get_type() == MptWitnessRowType::StorageLeafCKey { - if !pv.is_branch_c_placeholder { - self.key_data.assign(region, offset, key_memory, pv.key_rlc, pv.key_rlc_mult, pv.nibbles_num)?; - } else { - self.key_data.assign(region, offset, key_memory, pv.key_rlc_prev, pv.key_rlc_mult_prev, pv.nibbles_num_prev)?; - } - }*/ - - let is_s = row.get_type() == MptWitnessRowType::StorageLeafSKey; - let is_branch_placeholder = if is_s { - pv.is_branch_s_placeholder - } else { - pv.is_branch_c_placeholder - }; - let load_offset = if is_s { 0 } else { 1 }; - let load_offset = load_offset + if is_branch_placeholder { 1 } else { 0 }; - self.key_data - .witness_load(region, offset, &mut pv.memory["key"], load_offset)?; - // TODO(Brecht): remove - let row_offset = if is_s {offset} else {offset - 2}; - self.key_data - .witness_load(region, row_offset, &mut pv.memory["key"], load_offset)?; - self.key_data.witness_store( - region, - offset, - &mut pv.memory["key"], - F::zero(), - F::one(), - 0, - false, - false, - )?; - - // For leaf S and leaf C we need to start with the same rlc. - let mut key_rlc_new = pv.key_rlc; - let mut key_rlc_mult_new = pv.key_rlc_mult; - if (pv.is_branch_s_placeholder && row.get_type() == MptWitnessRowType::StorageLeafSKey) - || (pv.is_branch_c_placeholder && row.get_type() == MptWitnessRowType::StorageLeafCKey) - { - key_rlc_new = pv.key_rlc_prev; - key_rlc_mult_new = pv.key_rlc_mult_prev; - } - if typ != "last_level" && typ != "one_nibble" { - // If in last level or having only one nibble, - // the key RLC is already computed using the first two bytes above. - mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, start); - } - region.assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(key_rlc_new), - )?; - pv.storage_key_rlc = key_rlc_new; - - // Store key_rlc into rlc2 to be later set in leaf value C row (to enable - // lookups): - pv.rlc2 = key_rlc_new; - - Ok(()) - } -} diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key_in_added_branch.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key_in_added_branch.rs deleted file mode 100644 index 3f130500ed..0000000000 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_key_in_added_branch.rs +++ /dev/null @@ -1,311 +0,0 @@ -use halo2_proofs::{arithmetic::FieldExt, circuit::Region, plonk::VirtualCells, poly::Rotation}; -use std::marker::PhantomData; - -use crate::{ - circuit, - circuit_tools::{RLCChainable, ConstraintBuilder}, - mpt_circuit::{ - helpers::StorageLeafInfo, - param::{BRANCH_ROWS_NUM, LEAF_DRIFTED_IND, LEAF_KEY_C_IND, LEAF_KEY_S_IND}, - }, - mpt_circuit::{ - helpers::{get_parent_rlc_state, BranchNodeInfo, MPTConstraintBuilder}, - param::{LEAF_VALUE_C_IND, LEAF_VALUE_S_IND}, - witness_row::MptWitnessRow, - FixedTableTag, MPTContext, - }, - mpt_circuit::{MPTConfig, ProofValues}, -}; - -/* -A storage leaf occupies 6 rows. -Contrary as in the branch rows, the `S` and `C` leaves are not positioned parallel to each other. -The rows are the following: -LEAF_KEY_S -LEAF_VALUE_S -LEAF_KEY_C -LEAF_VALUE_C -LEAF_DRIFTED -LEAF_NON_EXISTING - -An example of leaf rows: -[226 160 32 235 117 17 208 2 186 74 12 134 238 103 127 37 240 27 164 245 42 218 188 162 9 151 17 57 90 177 190 250 180 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[225 159 63 117 31 216 242 20 172 137 89 10 84 218 35 38 178 182 67 5 68 54 127 178 216 248 46 67 173 108 157 55 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[225 159 59 117 17 208 2 186 74 12 134 238 103 127 37 240 27 164 245 42 218 188 162 9 151 17 57 90 177 190 250 180 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -The `LEAF_DRIFTED` row is nonempty when a leaf is added (or deleted) to the position in trie where there is already -an existing leaf. This appears when an existing leaf and a newly added leaf have the same initial key nibbles. -In this case, a new branch is created and both leaves (existing and newly added) appear in the new branch. -`LEAF_DRIFTED` row contains the key bytes of the existing leaf once it drifted down to the new branch. - -The constraints for `LEAF_DRIFTED` row are very similar to the ones for `LEAF_KEY` rows, but we have -different selectors (different row) and there are some scenarios that do not appear here, like being in -the first level of the trie. Also, when computing the leaf RLC, we need to take a different approach because -the leaf value for the drifted leaf is stored in a parallel proof. - - -Note: The leaf value is not stored in this row, but it needs to be the same -as the leaf value before it drifted down to the new branch, so we can -retrieve it from the row of a leaf before a drift. We need the leaf value to -build the leaf RLC to check that the hash of a drifted leaf is in the -new branch. -It needs to be ensured that the leaf intermediate RLC (containing the leaf -key bytes) is properly computed. The intermediate RLC is then used to -compute the final leaf RLC (containing the leaf value bytes too). -Finally, the lookup is used to check that the hash that -corresponds to the leaf RLC is in the parent branch at `drifted_pos` -position. -drifted leaf appears only when there is a placeholder branch - -We obtain the key RLC from the branch / extension node above the placeholder branch. -We then add the remaining key nibbles that are stored in the drifted leaf key and the final RLC -needs to be the same as the one stored in `accumulators.key.rlc` in the storage leaf key row -(not the drifted leaf). This means the storage leaf has the same key RLC before and after -it drifts into a new branch. - -We need to ensure that the drifted leaf has the proper key RLC. It needs to be the same as the key RLC -of this same leaf before it drifted to the new branch. The difference is that after being drifted the leaf -has one nibble less stored in the key - `drifted_pos` nibble that is in a branch parallel to the branch -placeholder (if it is an extension node there are more nibbles of a difference). -Leaf key S -Leaf value S -Leaf key C -Leaf value C -Drifted leaf (leaf in added branch) -Add case (S branch is placeholder): -Branch S || Branch C -Placeholder branch || Added branch -Leaf S || Leaf C - || Drifted leaf (this is Leaf S drifted into Added branch) -Leaf S needs to have the same key RLC as Drifted leaf. -Note that Leaf S key RLC is computed by taking the key RLC from Branch S and -then adding the bytes in Leaf key S row. -Drifted leaf RLC is computed by taking the key RLC from Added branch and -then adding the bytes in Drifted leaf row. -Delete case (C branch is placeholder): -Branch S || Branch C -Branch to be deleted || Placeholder branch -Leaf S (leaf to be deleted) || Leaf C -Leaf to be drifted one level up || - -/* Leaf key in added branch: neighbour leaf in the added branch (S) */ -It needs to be ensured that the hash of the drifted leaf is in the parent branch -at `drifted_pos` position. -Rows: -Leaf key S -Leaf value S -Leaf key C -Leaf value C -Drifted leaf (leaf in added branch) -Add case (S branch is placeholder): - Branch S || Branch C - Placeholder branch || Added branch - Leaf S || Leaf C - || Drifted leaf (this is Leaf S drifted into Added branch) -We need to compute the RLC of the drifted leaf. We compute the intermediate RLC -from the bytes in `LEAF_DRIFTED` row. And we retrieve the value from `LEAF_VALUE_S` row -(where there is the same leaf, but before it drifted down into a new branch). -Then we execute the lookup into a keccak table: `lookup(leaf_rlc, branch_child_at_drifted_pos_rlc)`. - -`s_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. -This is because `c_mod_node_hash_rlc` in the added branch stores the hash of -`modified_node` (the leaf that has been added): -Add case (S branch is placeholder): - Branch S || Branch C - Placeholder branch (`s_mod_node_hash_rlc` stores `drifted_pos` node hash) || Added branch (`c_mod_node_hash_rlc` stores `modified_node` hash) - Leaf S || Leaf C - || Drifted leaf (this is Leaf S drifted into Added branch) -That the stored value corresponds to the value in the non-placeholder branch at `drifted_pos` -is checked in `branch_rlc.rs`. - -/* Leaf key in added branch: neighbour leaf in the deleted branch (C) */ -It needs to be ensured that the hash of the drifted leaf is in the parent branch -at `drifted_pos` position. -Rows: -Leaf key S -Leaf value S -Leaf key C -Leaf value C -Drifted leaf (leaf in added branch) -Delete case (C branch is placeholder): -Branch S || Branch C -Branch to be deleted || Placeholder branch -Leaf S (leaf to be deleted) || Leaf C -Leaf to be drifted one level up || -We need to compute the RLC of the leaf that is a neighbour leaf of the leaf that is to be deleted. -We compute the intermediate RLC from the bytes in `LEAF_DRIFTED` row. -And we retrieve the value from `LEAF_VALUE_C` row -(where there is the same leaf, but after it was moved one level up because of the deleted branch). -Then we execute the lookup into a keccak table: `lookup(leaf_rlc, branch_child_at_drifted_pos_rlc)`. - -`c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. -This is because `s_mod_node_hash_rlc` in the deleted branch stores the hash of -`modified_node` (the leaf that is to be deleted): -Delete case (C branch is placeholder): - Branch S || Branch C - Branch to be deleted (`s_mod_node_hash_rlc` stores `modified_node` hash) || Placeholder branch (`c_mod_node_hash_rlc` stores `drifted_pos` node hash) - Leaf S (leaf to be deleted) || Leaf C - Leaf to be drifted one level up || -That the stored value corresponds to the value in the non-placeholder branch at `drifted_pos` -is checked in `branch_rlc.rs`. - -*/ - -#[derive(Clone, Debug, Default)] -pub(crate) struct LeafKeyInAddedBranchConfig { - _marker: PhantomData, -} - -impl LeafKeyInAddedBranchConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - ctx: MPTContext, - ) -> Self { - let s_main = ctx.s_main; - let accs = ctx.accumulators; - let r = ctx.r.clone(); - - let rot_branch_init = -LEAF_DRIFTED_IND - BRANCH_ROWS_NUM; - let rot_parent = -LEAF_DRIFTED_IND - 1; - let rot_branch_child = -BRANCH_ROWS_NUM + 2; - let rot_key_s = -(LEAF_DRIFTED_IND - LEAF_KEY_S_IND); - let rot_value_s = -(LEAF_DRIFTED_IND - LEAF_VALUE_S_IND); - let rot_key_c = -(LEAF_DRIFTED_IND - LEAF_KEY_C_IND); - let rot_value_c = -(LEAF_DRIFTED_IND - LEAF_VALUE_C_IND); - - circuit!([meta, cb.base], { - let storage = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_s); - ifx! {not!(storage.is_below_account(meta)) => { - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - let drifted_storage = StorageLeafInfo::new(meta, ctx.clone(), true, 0); - - // The two flag values need to be boolean. - require!(drifted_storage.flag1 => bool); - require!(drifted_storage.flag2 => bool); - - // Calculate and store the leaf RLC (RLP + key) - let drifted_rlc = a!(accs.acc_s.rlc); - require!(drifted_rlc => ctx.rlc(meta, 0..36, 0)); - - // We need the intermediate key RLC right before `drifted_index` is added to it. - // If the branch parallel to the placeholder branch is an extension node, - // we have the intermediate RLC stored in the extension node `accs.key.rlc`. - let is_branch_in_first_level = branch.is_below_account(meta); - let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); - // Calculate the drifted key RLC - let drifted_key_rlc = key_rlc_prev.expr() + - branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + - drifted_storage.key_rlc(meta, &mut cb.base, key_mult_prev, branch.is_key_odd(), r[0].expr(), true, 0); - - // Check zero bytes and mult_diff - let mult = a!(accs.acc_s.mult); - ifx!{branch.is_placeholder_s_or_c() => { - // Num bytes used in RLC - let num_bytes = drifted_storage.num_bytes_on_key_row(meta); - // Multiplier is number of bytes - require!((FixedTableTag::RMult, num_bytes.expr(), mult) => @"mult"); - // RLC bytes zero check - cb.set_length(num_bytes.expr()); - }} - - // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { - circuit!([meta, cb], { - let rot_key = if is_s { rot_key_s } else { rot_key_c }; - let rot_value = if is_s { rot_value_s } else { rot_value_c }; - // Complete the drifted leaf rlc by adding the bytes on the value row - let drifted_rlc = (drifted_rlc.expr(), mult.expr()).rlc_chain(s_main.rlc(meta, rot_value, &r)); - (true.expr(), a!(accs.key.rlc, rot_key), drifted_rlc, a!(accs.mod_node_rlc(is_s), rot_branch_child)) - }) - }; - let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { - branch.is_placeholder_s() => { - // Neighbour leaf in the added branch - // - `leaf_key_s_rlc` is the key RLC of the leaf before it drifted down - // in a new branch. - // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `c_mod_node_rlc` in the added branch stores the hash of - // `modified_index` (the leaf that has been added). - calc_rlc(true, meta, &mut cb.base) - }, - branch.is_placeholder_c() => { - // Neighbour leaf in the deleted branch - // -`leaf_key_c_rlc` is the key RLC of the leaf after its neighbour leaf - // has been deleted (and there were only two leaves, so the branch was deleted). - // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `s_mod_node_rlc` in the deleted branch stores the hash of - // `modified_index` (the leaf that is to be deleted). - calc_rlc(false, meta, &mut cb.base) - }, - _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), - }; - ifx! {do_checks => { - // The key of the drifted leaf needs to match the key of the leaf - require!(key_rlc => drifted_key_rlc); - // The drifted leaf needs to be stored in the branch at `drifted_index`. - require!((1, drifted_rlc, drifted_storage.num_bytes(meta), mod_hash) => @"keccak"); - }} - }} - }); - - LeafKeyInAddedBranchConfig { - _marker: PhantomData, - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &mut ProofValues, - row: &MptWitnessRow, - offset: usize, - ) { - /* - row[1] != 0 just to avoid usize problems below (when row doesn't - need to be assigned) Info whether leaf rlp is long or short. - */ - /* - Info whether leaf rlp is long or short: - - long means the key length is at position 2. - - short means the key length is at position 1. - */ - let mut typ = "short"; - if row.get_byte(0) == 248 { - typ = "long"; - } else if row.get_byte(1) == 32 { - typ = "last_level"; - } else if row.get_byte(1) < 128 { - typ = "one_nibble"; - } - mpt_config.assign_long_short(region, typ, offset).ok(); - - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - let len: usize; - if typ == "long" { - len = (row.get_byte(2) - 128) as usize + 3; - } else if typ == "short" { - len = (row.get_byte(1) - 128) as usize + 2; - } else { - // last_level or one_nibble - len = 2 - } - mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); - - mpt_config - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) - .ok(); - } -} diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_non_existing.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_non_existing.rs deleted file mode 100644 index f209676610..0000000000 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_non_existing.rs +++ /dev/null @@ -1,205 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, - plonk::VirtualCells, - poly::Rotation, -}; - -use crate::{ - circuit, - circuit_tools::{Cell, CellManager, CellType}, - mpt_circuit::witness_row::MptWitnessRow, - mpt_circuit::{ - helpers::{StorageLeafInfo}, - }, - mpt_circuit::{ - helpers::{KeyData, MPTConstraintBuilder}, - MPTContext, - }, - mpt_circuit::{ - param::{IS_NON_EXISTING_STORAGE_POS, LEAF_KEY_C_IND, LEAF_NON_EXISTING_IND, S_START}, - MPTConfig, ProofValues, - }, -}; - -/* -A storage leaf occupies 6 rows. -Contrary as in the branch rows, the `S` and `C` leaves are not positioned parallel to each other. -The rows are the following: -LEAF_KEY_S -LEAF_VALUE_S -LEAF_KEY_C -LEAF_VALUE_C -LEAF_DRIFTED -LEAF_NON_EXISTING - -An example of leaf rows: -[226 160 49 236 194 26 116 94 57 104 160 78 149 112 228 66 91 193 143 168 1 156 104 2 129 150 181 70 209 102 156 32 12 104 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[226 160 49 236 194 26 116 94 57 104 160 78 149 112 228 66 91 193 143 168 1 156 104 2 129 150 181 70 209 102 156 32 12 104 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[1 160 58 99 87 1 44 26 58 224 161 125 48 76 153 32 49 3 130 217 104 235 204 75 23 113 244 28 107 48 66 5 181 112 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -In the above example, there is a wrong leaf case (see `s_rlp1` being 1 in the last row). -The constrainst here are analogue to the ones in `account_non_existing.rs`, but here it is for the -non existing storage instead of non existing account. However, more cases need to be handled for storage -because there can appear 1 or 2 RLP bytes (for account there are always 2). Also, the selectors need -to be obtained differently - for example, when we are checking the leaf in the first (storage) level, -we are checking whether we are behind the account leaf (for account proof we are checking whether we -are in the first level). - -Lookups: -The `non_existing_storage_proof` lookup is enabled in `LEAF_NON_EXISTING` row. - -Wrong leaf has a meaning only for non existing storage proof. For this proof, -there are two cases: 1. A leaf is returned that is not at the -required key (wrong leaf). 2. A branch is returned as the last -element of getProof and there is nil object at key position. -Placeholder leaf is added in this case. - -Ensuring that the storage does not exist when there is only one storage key in the storage trie. -Note 1: The hash of the only storage is checked to be the storage root in `leaf_value.rs`. -Note 2: There is no nil_object case checked in this gate, because it is covered in the gate -above. That is because when there is a branch (with nil object) in the first level, -it automatically means the leaf is not in the first level. - -Differently as for the other proofs, the storage-non-existing proof compares `key_rlc` -with the key stored in `STORAGE_NON_EXISTING` row, not in `LEAF_KEY` row. -The crucial thing is that we have a wrong leaf at the key (not exactly the same, just some starting -set of nibbles is the same) where we are proving there is no leaf. -If there would be a leaf at the specified key, it would be positioned in the branch where -the wrong leaf is positioned. Note that the position is determined by the starting set of nibbles. -Once we add the remaining nibbles to the starting ones, we need to obtain the enquired key. -There is a complementary constraint which makes sure the remaining nibbles are different for wrong leaf -and the non-existing leaf (in the case of wrong leaf, while the case with nil being in branch -is different). - -*/ - -#[derive(Clone, Debug)] -pub(crate) struct StorageNonExistingConfig { - key_data: KeyData, - diff_inv: Cell, -} - -impl StorageNonExistingConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - cm: &mut CellManager, - ctx: MPTContext, - ) -> Self { - let proof_type = ctx.proof_type; - let s_main = ctx.s_main; - let accs = ctx.accumulators; - - let diff_inv = cm.query_cell(CellType::Storage); - let ctx_key_data: Option>; - - let rot_key_c = -(LEAF_NON_EXISTING_IND - LEAF_KEY_C_IND); - - circuit!([meta, cb.base], { - let storage = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); - let is_wrong_leaf = a!(s_main.rlp1); - - // Make sure is_wrong_leaf is boolean - require!(is_wrong_leaf => bool); - - ifx! {a!(proof_type.is_non_existing_storage_proof) => { - // Get the previous key RLC data - let key_data = KeyData::load(&mut cb.base, cm, &ctx.memory["key"], 2.expr()); - ifx! {is_wrong_leaf => { - // Calculate the key and check it's the address as requested in the lookup - let key_rlc_wrong = key_data.rlc.expr() + storage.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), false, -rot_key_c); - require!(a!(accs.key.mult) => key_rlc_wrong); - // Now make sure this address is different than the one of the leaf - require!((a!(accs.key.mult) - a!(accs.key.rlc, rot_key_c)) * diff_inv.expr() => 1); - // Make sure the lengths of the keys are the same - let mut storage_wrong = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); - storage_wrong.set_rot_key(0); - require!(storage_wrong.key_len(meta) => storage.key_len(meta)); - // RLC bytes zero check - let num_bytes = storage.num_bytes_on_key_row(meta); - cb.set_length(num_bytes); - } elsex { - // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. - require!(key_data.is_placeholder_leaf_c => true); - }} - ctx_key_data = Some(key_data); - } elsex { - // is_wrong_leaf needs to be false when not in non_existing_account proof - require!(is_wrong_leaf => false); - }} - }); - - StorageNonExistingConfig { - key_data: ctx_key_data.unwrap(), - diff_inv, - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &mut ProofValues, - witness: &[MptWitnessRow], - offset: usize, - ) { - self.key_data - .witness_load(region, offset, &mut pv.memory["key"], 2) - .ok(); - // TODO(Brecht): remove - self.key_data - .witness_load(region, offset - 5, &mut pv.memory["key"], 2) - .ok(); - - let row = &witness[offset]; - if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 0 { - // No need to assign anything when not non-existing-storage proof. - return; - } - - let row_key_c = &witness[offset - (LEAF_NON_EXISTING_IND - LEAF_KEY_C_IND) as usize]; - let mut start = S_START - 1; - if row_key_c.get_byte(0) == 248 { - start = S_START; - } - let mut key_rlc_new = pv.key_rlc; - let mut key_rlc_mult_new = pv.key_rlc_mult; - mpt_config.compute_key_rlc(&row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, start); - region - .assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.mult, // lookup uses `key.mult` - offset, - || Value::known(key_rlc_new), - ) - .ok(); - - let diff_inv = (key_rlc_new - pv.storage_key_rlc) - .invert() - .unwrap_or(F::zero()); - self.diff_inv - .assign(region, offset, Value::known(diff_inv)) - .ok(); - // TODO(Brecht): remove - self.diff_inv - .assign(region, offset - 5, Value::known(diff_inv)) - .ok(); - - if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(7_u64)), /* non existing storage lookup enabled in - * this row if it is non_existing_storage - * proof */ - ) - .ok(); - } - } -} diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_value.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_value.rs deleted file mode 100644 index deddfd4217..0000000000 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf/leaf_value.rs +++ /dev/null @@ -1,443 +0,0 @@ -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, - plonk::VirtualCells, - poly::Rotation, -}; - -use crate::{ - circuit, - circuit_tools::{CellManager, DataTransition, RLCChainable, RLCable}, - mpt_circuit::{ - helpers::{get_num_bytes_short, parent_memory, MPTConstraintBuilder, ParentData}, - param::{ - BRANCH_ROWS_NUM, EMPTY_TRIE_HASH, HASH_WIDTH, IS_STORAGE_MOD_POS, LEAF_VALUE_C_IND, - LEAF_VALUE_S_IND, - }, - MPTContext, - }, - mpt_circuit::{ - helpers::{BranchNodeInfo, StorageLeafInfo}, - witness_row::{MptWitnessRow, MptWitnessRowType}, - }, - mpt_circuit::{MPTConfig, ProofValues}, -}; - -/* -A storage leaf occupies 6 rows. -Contrary as in the branch rows, the `S` and `C` leaves are not positioned parallel to each other. -The rows are the following: -LEAF_KEY_S -LEAF_VALUE_S -LEAF_KEY_C -LEAF_VALUE_C -LEAF_DRIFTED -LEAF_NON_EXISTING - -An example of leaf rows: -[226 160 59 138 106 70 105 186 37 13 38 205 122 69 158 202 157 33 95 131 7 227 58 235 229 3 121 188 90 54 23 236 52 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[226 160 59 138 106 70 105 186 37 13 38 205 122 69 158 202 157 33 95 131 7 227 58 235 229 3 121 188 90 54 23 236 52 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -In the above example the value has been changed from 1 (`LEAF_VALUE_S`) to 17 (`LEAF_VALUE_C`). - -In the example below the value in `LEAF_VALUE_C` takes more than 1 byte: `[187 239 170 ...]` -This has two consequences: - - Two additional RLP bytes: `[161 160]` where `33 = 161 - 128` means there are `31` bytes behind `161`, - `32 = 160 - 128` means there are `30` bytes behind `160`. - - `LEAF_KEY_S` starts with `248` because the leaf has more than 55 bytes, `1 = 248 - 247` means - there is 1 byte after `248` which specifies the length - the length is `67`. We can see that - that the leaf key is shifted by 1 position compared to the example above. - -For this reason we need to distinguish two cases: 1 byte in leaf value, more than 1 byte in leaf value. -These two cases are denoted by `is_short` and `is_long`. There are two other cases we need to -distinguish: `last_level` when the leaf is in the last level and has no nibbles, `one_nibble` when -the leaf has only one nibble. - -`is_long` (`C` is long, while `S` is short): -[226 160 59 138 106 70 105 186 37 13 38 205 122 69 158 202 157 33 95 131 7 227 58 235 229 3 121 188 90 54 23 236 52 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[248 67 160 59 138 106 70 105 186 37 13 38 205 122 69 158 202 157 33 95 131 7 227 58 235 229 3 121 188 90 54 23 236 52 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[161 160 187 239 170 18 88 1 56 188 38 60 149 117 120 38 223 78 36 235 129 201 170 170 170 170 170 170 170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -`last_level` -[194 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[194 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -`one_nibble`: -[194 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2] -[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13] -[194 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3] -[17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15] -[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19] - -`s_mod_node_rlc` (`flag1`) and `c_mod_node_rlc` (`flag2`) columns store the information of what -kind of case we have: - `flag1: 1, flag2: 0`: `is_long` - `flag1: 0, flag2: 1`: `is_short` - `flag1: 1, flag2: 1`: `last_level` - `flag1: 0, flag0: 1`: `one_nibble` - -The constraints in `leaf_value.rs` apply to `LEAF_VALUE_S` and `LEAF_VALUE_C` rows. -The constraints ensure the hash of a storage leaf is in a parent branch and that the RLP -of the leaf is correct. - -Lookups: -The `is_storage_mod` lookup is enabled in `LEAF_VALUE_C` row. - -Note that there are no checks for example for the root as the constraints to ensure `start_root` -and `final_root` does not change (except in the first row of the modification) are in `proof_chain.rs` -and the constraints to ensure the lookup roots correspond to the roots of the trie are in the first -level nodes (`account_leaf_storage_codehash.rs` or `branch_hash_in_parent.rs`). - -We need the RLC of the whole leaf for a lookup that ensures the leaf is in the parent branch. -We need the leaf value RLC for external lookups that ensure the value has been set correctly. -`is_short` means value has only one byte and consequently, the RLP of -the value is only this byte itself. If there are more bytes, the value is -equipped with two RLP meta bytes, like 161 160 if there is a -value of length 32 (the first RLP byte means 33 bytes after it, the second -RLP byte means 32 bytes after it). -`is_short` example: -`[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13]` -`is_long` example: -`[161 160 187 239 170 18 88 1 56 188 38 60 149 117 120 38 223 78 36 235 129 201 170 170 170 170 170 170 170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14]` - -*/ - -#[derive(Clone, Debug)] -pub(crate) struct LeafValueConfig { - parent_data: ParentData, -} - -impl LeafValueConfig { - pub fn configure( - meta: &mut VirtualCells<'_, F>, - cb: &mut MPTConstraintBuilder, - cm: &mut CellManager, - ctx: MPTContext, - is_s: bool, - ) -> Self { - let s_main = ctx.s_main; - let accs = ctx.accumulators; - let value_prev = ctx.value_prev; - let value = ctx.value; - let r = ctx.r.clone(); - - let ctx_parent_data: Option>; - - let rot_key = -1; - let rot_s = if is_s { 0 } else { -2 }; - let leaf_value_pos = if is_s { - LEAF_VALUE_S_IND - } else { - LEAF_VALUE_C_IND - }; - let rot_branch_init = -leaf_value_pos - BRANCH_ROWS_NUM; - - circuit!([meta, cb.base], { - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let storage = StorageLeafInfo::new(meta, ctx.clone(), is_s, rot_key); - - let is_long = a!(accs.s_mod_node_rlc); - let is_short = a!(accs.c_mod_node_rlc); - - // We need to ensure `is_long` and `is_short` are boolean. - require!(is_short => bool); - require!(is_long => bool); - // `is_short` or `is_long` needs to be true. - require!(sum::expr([is_short.expr(), is_long.expr()]) => 1); - - // We need to ensure that the stored leaf RLC and value RLC is the same as the - // computed one. - let leaf_rlc = DataTransition::new(meta, accs.acc_s.rlc); - let value_rlc = DataTransition::new_with_rot(meta, accs.acc_c.rlc, rot_s, 0); - let mult_prev = a!(accs.acc_s.mult, rot_key); - let (new_value_rlc, leaf_rlc_part) = ifx! {is_short => { - (a!(s_main.rlp1), a!(s_main.rlp1) * mult_prev.expr()) - } elsex { - let value_rlc = s_main.bytes(meta, 0).rlc(&r); - let leaf_rlc = (0.expr(), mult_prev.expr()).rlc_chain([a!(s_main.rlp1), a!(s_main.rlp2), value_rlc.expr()].rlc(&r)); - (value_rlc, leaf_rlc) - }}; - require!(value_rlc => new_value_rlc); - require!(leaf_rlc => leaf_rlc.prev() + leaf_rlc_part); - - // To enable external lookups we need to have the key and the previous/current - // value on the same row. - if !is_s { - require!(a!(accs.key.mult) => a!(accs.key.rlc, rot_key)); - require!(a!(value_prev) => value_rlc.prev()); - require!(a!(value) => value_rlc); - } - - // Get the number of bytes used by the value - let value_num_bytes = matchx! { - is_short => 1.expr(), - is_long => 1.expr() + get_num_bytes_short(a!(s_main.rlp2)), - }; - - // If `is_modified_node_empty = 1`, which means an empty child, we need to - // ensure that the value is set to 0 in the placeholder leaf. For - // example when adding a new storage leaf to the trie, we have an empty child in - // `S` proof and non-empty in `C` proof. - ifx! {branch.contains_placeholder_leaf(meta, is_s) => { - require!(a!(s_main.rlp1) => 0); - }} - - // Make sure the RLP encoding is correct. - // storage = [key, value] - let num_bytes = storage.num_bytes(meta); - // TODO(Brecht): modify the witness for empty placeholder leafs to have valid - // RLP encoding - ifx! {not!(branch.contains_placeholder_leaf(meta, is_s)) => { - let key_num_bytes = storage.num_bytes_on_key_row(meta); - require!(num_bytes => key_num_bytes.expr() + value_num_bytes.expr()); - }}; - - // Check if the account is in its parent. - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let parent_data = ParentData::load( - "leaf load", - &mut cb.base, - cm, - &ctx.memory[parent_memory(is_s)], - 0.expr(), - ); - // Check is skipped for placeholder leafs which are dummy leafs - ifx! {storage.is_below_account(meta), storage.is_placeholder_without_branch(meta) => { - // TODO(Brecht): Add this to the keccak table when necessary instead? - // Hash of the only storage leaf which is placeholder requires empty storage root - let empty_root_rlc = EMPTY_TRIE_HASH.iter().map(|v| v.expr()).collect::>().rlc(&r); - require!(parent_data.rlc => empty_root_rlc); - } elsex { - ifx!{not!(and::expr(&[not!(storage.is_below_account(meta)), branch.contains_placeholder_leaf(meta, is_s)])) => { - let is_not_hashed = a!(accs.acc_c.rlc, -1); - ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { - // Hashed branch hash in parent branch - require!((1, leaf_rlc, num_bytes, parent_data.rlc) => @"keccak"); - } elsex { - // Non-hashed branch hash in parent branch - require!(leaf_rlc => parent_data.rlc); - }} - }} - }} - // Store the new parent - ParentData::store( - &mut cb.base, - &ctx.memory[parent_memory(is_s)], - [0.expr(), true.expr()], - ); - ctx_parent_data = Some(parent_data); - - // Set the number of bytes used - cb.set_length_s(value_num_bytes); - }); - - LeafValueConfig { - parent_data: ctx_parent_data.unwrap(), - } - } - - pub fn assign( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - witness: &[MptWitnessRow], - pv: &mut ProofValues, - offset: usize, - is_s: bool, - ) { - let row_prev = &witness[offset - 1]; - let row = &witness[offset]; - - // Info whether leaf value is 1 byte or more: - let mut is_long = false; - if row_prev.get_byte(0) == 248 { - // whole leaf is in long format (3 RLP meta bytes) - let key_len = row_prev.get_byte(2) - 128; - if row_prev.get_byte(1) - key_len - 1 > 1 { - is_long = true; - } - } else if row_prev.get_byte(1) < 128 { - // last_level or one_nibble - let leaf_len = row_prev.get_byte(0) - 192; - if leaf_len - 1 > 1 { - is_long = true; - } - } else { - let leaf_len = row_prev.get_byte(0) - 192; - let key_len = row_prev.get_byte(1) - 128; - if leaf_len - key_len - 1 > 1 { - is_long = true; - } - } - // Short means there is only one byte for value (no RLP specific bytes). - // Long means there is more than one byte for value which brings two - // RLP specific bytes, like: 161 160 ... for 32-long value. - let mut typ = "short"; - if is_long { - typ = "long"; - } - mpt_config.assign_long_short(region, typ, offset).ok(); - - // Leaf RLC - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - 0, - HASH_WIDTH + 2, - ); - - pv.acc_c = F::zero(); - pv.acc_mult_c = F::one(); - // Leaf value RLC - let mut start = 0; - if is_long { - start = 2; - } - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_c, - &mut pv.acc_mult_c, - start, - HASH_WIDTH + 2, - ); - - let empty_trie_hash: Vec = vec![ - 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, - 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, - ]; - if is_s { - // Store leaf value RLC into rlc1 to be later set in leaf value C row (to enable - // lookups): - pv.rlc1 = pv.acc_c; - - /* - account leaf storage codehash S <- rotate here - account leaf storage codehash C - account leaf in added branch - leaf key S - leaf value S <- we are here - leaf key C - leaf value C - */ - let row_prev = &witness[offset - 4]; - if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashS - && row_prev.s_hash_bytes() == empty_trie_hash - { - // Leaf is without branch and it is just a placeholder. - region - .assign_advice( - || "assign sel1".to_string(), - mpt_config.denoter.sel1, - offset, - || Value::known(F::one()), - ) - .ok(); - } - } else { - region - .assign_advice( - || "assign key_rlc into key_rlc_mult".to_string(), - mpt_config.accumulators.key.mult, - offset, - || Value::known(pv.rlc2), - ) - .ok(); - region - .assign_advice( - || "assign leaf value S into value_prev".to_string(), - mpt_config.value_prev, - offset, - || Value::known(pv.rlc1), - ) - .ok(); - - /* - account leaf storage codehash S - account leaf storage codehash C <- rotate here - account leaf in added branch - leaf key S - leaf value S - leaf key C - leaf value C <- we are here - */ - let row_prev = &witness[offset - 5]; - if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashC - && row_prev.s_hash_bytes() == empty_trie_hash - { - // Leaf is without branch and it is just a placeholder. - region - .assign_advice( - || "assign sel2".to_string(), - mpt_config.denoter.sel2, - offset, - || Value::known(F::one()), - ) - .ok(); - } - } - - let is_s = row.get_type() == MptWitnessRowType::StorageLeafSValue; - self.parent_data - .witness_load(region, offset, &mut pv.memory[parent_memory(is_s)], 0) - .ok(); - // TODO(Brecht): remove - let row_offset = if is_s {offset - 1} else {offset - 3}; - self.parent_data - .witness_load(region, row_offset, &mut pv.memory[parent_memory(is_s)], 0) - .ok(); - self.parent_data - .witness_store( - region, - offset, - &mut pv.memory[parent_memory(is_s)], - F::zero(), - true, - ) - .ok(); - - mpt_config - .assign_acc( - region, - pv.acc_s, // leaf RLC - pv.acc_mult_s, - pv.acc_c, // leaf value RLC - F::zero(), - offset, - ) - .ok(); - - region - .assign_advice( - || "assign leaf value C into value".to_string(), - mpt_config.value, - offset, - || Value::known(pv.acc_c), - ) - .ok(); - - if !is_s && row.get_byte_rev(IS_STORAGE_MOD_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(6_u64)), /* storage mod lookup enabled in this row - * if it is is_storage_mod proof */ - ) - .ok(); - } - } -} From c106ce01c30db4a797525ea4066cfd548173f55b Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Tue, 14 Feb 2023 02:53:43 +0100 Subject: [PATCH 04/11] StorageLeaf refactor --- zkevm-circuits/src/circuit_tools.rs | 1502 +---------------- .../src/circuit_tools/cell_manager.rs | 254 +++ .../src/circuit_tools/constraint_builder.rs | 1116 ++++++++++++ zkevm-circuits/src/circuit_tools/gadgets.rs | 189 +++ zkevm-circuits/src/circuit_tools/memory.rs | 258 +++ zkevm-circuits/src/lib.rs | 1 - zkevm-circuits/src/mpt_circuit.rs | 218 +-- .../src/mpt_circuit/account_leaf.rs | 39 +- zkevm-circuits/src/mpt_circuit/branch.rs | 24 +- zkevm-circuits/src/mpt_circuit/columns.rs | 16 +- zkevm-circuits/src/mpt_circuit/helpers.rs | 934 +++++++--- zkevm-circuits/src/mpt_circuit/proof_chain.rs | 7 +- zkevm-circuits/src/mpt_circuit/selectors.rs | 7 +- .../src/mpt_circuit/storage_leaf.rs | 544 ++---- zkevm-circuits/src/mpt_circuit/witness_row.rs | 4 +- 15 files changed, 2844 insertions(+), 2269 deletions(-) create mode 100644 zkevm-circuits/src/circuit_tools/cell_manager.rs create mode 100644 zkevm-circuits/src/circuit_tools/constraint_builder.rs create mode 100644 zkevm-circuits/src/circuit_tools/gadgets.rs create mode 100644 zkevm-circuits/src/circuit_tools/memory.rs diff --git a/zkevm-circuits/src/circuit_tools.rs b/zkevm-circuits/src/circuit_tools.rs index 651903cf3b..b22beed8de 100644 --- a/zkevm-circuits/src/circuit_tools.rs +++ b/zkevm-circuits/src/circuit_tools.rs @@ -1,1498 +1,6 @@ //! Circuit utilities -use std::{ - collections::BTreeMap, - marker::PhantomData, - ops::{Index, IndexMut}, -}; - -use crate::{ - evm_circuit::util::rlc, - util::{query_expression, Expr}, -}; -use gadgets::util::{and, select, sum}; -use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{AssignedCell, Layouter, Region, Value}, - plonk::{Advice, Column, ConstraintSystem, Error, Expression, VirtualCells}, - poly::Rotation, -}; -use itertools::Itertools; - -#[derive(Clone)] -pub(crate) struct DataTransition { - prev: Expression, - cur: Expression, -} - -impl DataTransition { - pub(crate) fn new(meta: &mut VirtualCells, column: Column) -> DataTransition { - DataTransition { - prev: meta.query_advice(column, Rotation::prev()), - cur: meta.query_advice(column, Rotation::cur()), - } - } - - pub(crate) fn new_with_rot( - meta: &mut VirtualCells, - column: Column, - rot_prev: i32, - rot_cur: i32, - ) -> DataTransition { - DataTransition { - prev: meta.query_advice(column, Rotation(rot_prev)), - cur: meta.query_advice(column, Rotation(rot_cur)), - } - } - - pub(crate) fn from(prev: Expression, cur: Expression) -> DataTransition { - DataTransition { prev, cur } - } - - pub(crate) fn cur(&self) -> Expression { - self.cur.clone() - } - - pub(crate) fn prev(&self) -> Expression { - self.prev.clone() - } - - pub(crate) fn delta(&self) -> Expression { - self.prev() - self.cur() - } -} - -impl Expr for DataTransition { - fn expr(&self) -> Expression { - self.cur.clone() - } -} - -#[derive(Clone, Debug)] -pub(crate) struct Cell { - // expression for constraint - expression: Expression, - column: Column, - // relative position to selector for synthesis - rotation: usize, -} - -impl Cell { - pub(crate) fn new(meta: &mut VirtualCells, column: Column, rotation: usize) -> Self { - Self { - expression: meta.query_advice(column, Rotation(rotation as i32)), - column, - rotation, - } - } - - pub(crate) fn assign( - &self, - region: &mut Region<'_, F>, - offset: usize, - value: Value, - ) -> Result, Error> { - region.assign_advice( - || { - format!( - "Cell column: {:?} and rotation: {}", - self.column, self.rotation - ) - }, - self.column, - offset + self.rotation, - || value, - ) - } -} - -impl Expr for Cell { - fn expr(&self) -> Expression { - self.expression.clone() - } -} - -impl Expr for &Cell { - fn expr(&self) -> Expression { - self.expression.clone() - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub(crate) enum CellType { - Storage, -} - -#[derive(Clone, Debug)] -pub(crate) struct CellColumn { - pub(crate) index: usize, - pub(crate) cell_type: CellType, - pub(crate) height: usize, - pub(crate) expr: Expression, -} - -impl Expr for CellColumn { - fn expr(&self) -> Expression { - self.expr.clone() - } -} - -#[derive(Clone, Debug)] -pub(crate) struct CellManager { - width: usize, - height: usize, - cells: Vec>, - columns: Vec>, -} - -impl CellManager { - pub(crate) fn new( - meta: &mut VirtualCells, - height: usize, - advices: &[Column], - height_offset: usize, - ) -> Self { - // Setup the columns and query the cells - let width = advices.len(); - let mut cells = Vec::with_capacity(height * width); - let mut columns = Vec::with_capacity(width); - for c in 0..width { - for r in 0..height { - cells.push(Cell::new(meta, advices[c], height_offset + r)); - } - columns.push(CellColumn { - index: c, - cell_type: CellType::Storage, - height: 0, - expr: cells[c * height].expr(), - }); - } - - Self { - width, - height, - cells, - columns, - } - } - - pub(crate) fn query_cells(&mut self, cell_type: CellType, count: usize) -> Vec> { - let mut cells = Vec::with_capacity(count); - while cells.len() < count { - let column_idx = self.next_column(cell_type); - let column = &mut self.columns[column_idx]; - cells.push(self.cells[column_idx * self.height + column.height].clone()); - column.height += 1; - } - cells - } - - pub(crate) fn query_cell(&mut self, cell_type: CellType) -> Cell { - self.query_cells(cell_type, 1)[0].clone() - } - - fn next_column(&self, cell_type: CellType) -> usize { - let mut best_index: Option = None; - let mut best_height = self.height; - for column in self.columns.iter() { - if column.cell_type == cell_type && column.height < best_height { - best_index = Some(column.index); - best_height = column.height; - } - } - match best_index { - Some(index) => index, - None => unreachable!("not enough cells for query: {:?}", cell_type), - } - } - - pub(crate) fn get_height(&self) -> usize { - self.columns - .iter() - .map(|column| column.height) - .max() - .unwrap() - } - - /// Returns a map of CellType -> (width, height, num_cells) - pub(crate) fn get_stats(&self) -> BTreeMap { - let mut data = BTreeMap::new(); - for column in self.columns.iter() { - let (mut count, mut height, mut num_cells) = - data.get(&column.cell_type).unwrap_or(&(0, 0, 0)); - count += 1; - height = height.max(column.height); - num_cells += column.height; - data.insert(column.cell_type, (count, height, num_cells)); - } - data - } - - pub(crate) fn columns(&self) -> &[CellColumn] { - &self.columns - } -} - -#[derive(Clone, Debug, Default)] -pub(crate) struct Memory { - columns: Vec>, - banks: Vec>, -} - -impl Memory { - pub(crate) fn new(columns: Vec>) -> Self { - Self { - columns, - banks: Vec::new(), - } - } - - pub(crate) fn allocate>( - &mut self, - meta: &mut ConstraintSystem, - tag: S, - ) -> &MemoryBank { - self.banks - .push(MemoryBank::new(meta, self.columns[self.banks.len()], tag)); - self.banks.last().unwrap() - } - - pub(crate) fn get>(&self, tag: S) -> &MemoryBank { - for bank in self.banks.iter() { - if bank.tag() == tag.as_ref() { - return bank; - } - } - unreachable!() - } - - pub(crate) fn get_mut>(&mut self, tag: S) -> &mut MemoryBank { - for bank in self.banks.iter_mut() { - if bank.tag() == tag.as_ref() { - return bank; - } - } - unreachable!() - } - - pub(crate) fn generate_constraints(&self, cb: &mut ConstraintBuilder) { - for bank in self.banks.iter() { - bank.generate_constraints(cb); - cb.generate_lookup_table_checks(bank.tag()); - - /*let lookups = cb.consume_lookups(&[bank.tag()]); - if !lookups.is_empty() { - //println!("{}: {}", tag, lookups.len()); - let (_, values) = merge_lookups(cb, lookups); - crate::circuit!([meta, cb], { - require!(values => @bank.tag()); - }) - }*/ - } - } - - pub(crate) fn clear_witness_data(&mut self) { - for bank in self.banks.iter_mut() { - bank.clear_witness_data(); - } - } - - pub(crate) fn assign( - &self, - layouter: &mut impl Layouter, - height: usize, - ) -> Result<(), Error> { - for bank in self.banks.iter() { - bank.assign(layouter, height)?; - } - Ok(()) - } - - pub(crate) fn tags(&self) -> Vec { - self.banks.iter().map(|bank| bank.tag()).collect() - } -} - -impl> Index for Memory { - type Output = MemoryBank; - - fn index(&self, tag: S) -> &Self::Output { - for bank in self.banks.iter() { - if bank.tag() == tag.as_ref() { - return bank; - } - } - unreachable!() - } -} - -impl> IndexMut for Memory { - fn index_mut(&mut self, tag: S) -> &mut Self::Output { - for bank in self.banks.iter_mut() { - if bank.tag() == tag.as_ref() { - return bank; - } - } - unreachable!() - } -} - -#[derive(Clone, Debug)] -pub(crate) struct MemoryBank { - column: Column, - tag: String, - cur: Expression, - next: Expression, - store_offsets: Vec, - stored_values: Vec>, - _marker: PhantomData, -} - -impl MemoryBank { - pub(crate) fn new>( - meta: &mut ConstraintSystem, - column: Column, - tag: S, - ) -> Self { - let mut cur = 0.expr(); - let mut next = 0.expr(); - query_expression(meta, |meta| { - cur = meta.query_advice(column, Rotation::cur()); - next = meta.query_advice(column, Rotation::next()); - }); - Self { - column, - tag: tag.as_ref().to_owned(), - cur, - next, - store_offsets: Vec::new(), - stored_values: Vec::new(), - _marker: PhantomData, - } - } - - pub(crate) fn key(&self) -> Expression { - self.cur.expr() - } - - pub(crate) fn load( - &self, - description: &'static str, - cb: &mut ConstraintBuilder, - offset: Expression, - values: &[Expression], - ) { - self.load_with_key(description, cb, self.key() - offset, values); - } - - pub(crate) fn load_with_key( - &self, - description: &'static str, - cb: &mut ConstraintBuilder, - key: Expression, - values: &[Expression], - ) { - let mut key_values = values.to_vec(); - key_values.insert(0, key); - cb.lookup(description, self.tag(), values.to_vec()); - } - - pub(crate) fn store(&self, cb: &mut ConstraintBuilder, values: &[Expression]) { - self.store_with_key(cb, self.key() + 1.expr(), values); - } - - pub(crate) fn store_with_key( - &self, - cb: &mut ConstraintBuilder, - key: Expression, - values: &[Expression], - ) { - let mut key_values = values.to_vec(); - key_values.insert(0, key); - cb.lookup_table("memory store", self.tag(), values.to_vec()); - } - - pub(crate) fn witness_store(&mut self, offset: usize, values: &[F]) { - self.stored_values.push(values.to_vec()); - self.store_offsets.push(offset); - } - - pub(crate) fn witness_store_init(&mut self, values: &[F]) { - self.stored_values.push(values.to_vec()); - } - - pub(crate) fn witness_load(&self, offset: usize) -> Vec { - self.stored_values[self.stored_values.len() - 1 - offset].clone() - } - - pub(crate) fn clear_witness_data(&mut self) { - self.store_offsets.clear(); - } - - pub(crate) fn generate_constraints(&self, cb: &mut ConstraintBuilder) { - let lookup_table = cb.get_lookup_table(self.tag()); - crate::circuit!([meta, cb], { - // TODO(Brecht): fix - //require!(self.next => self.cur.expr() + lookup_table.0); - }); - } - - pub(crate) fn assign( - &self, - layouter: &mut impl Layouter, - height: usize, - ) -> Result<(), Error> { - layouter.assign_region( - || "memory bank", - |mut region| { - // Pad to the full circuit (necessary for reads) - let mut store_offsets = self.store_offsets.clone(); - store_offsets.push(height); - - //println!("offsets: {:?}", self.store_offsets); - - //println!("height: {}", height); - let mut store_index = 0; - let mut offset = 0; - for &stored_offset in store_offsets.iter() { - while offset <= stored_offset { - region.assign_advice( - || "assign memory index".to_string(), - self.column, - offset, - || Value::known(F::from(store_index as u64)), - )?; - //println!("[{}] {}: {}", self.tag(), offset, store_index); - offset += 1; - } - store_index += 1; - } - Ok(()) - }, - ) - } - - pub(crate) fn tag(&self) -> String { - self.tag.clone() - } -} - -/// Lookup data -#[derive(Clone)] -pub struct LookupData { - /// Desciption - pub description: &'static str, - /// Lookup tag - pub tag: String, - /// Condition under which the lookup needs to be done - pub condition: Expression, - /// The values to lookup - pub values: Vec>, -} - -/// Constraint builder -pub struct ConstraintBuilder { - constraints: Vec<(&'static str, Expression)>, - max_degree: usize, - conditions: Vec>, - /// The lookups - pub lookups: Vec>, - /// The lookup tables - pub lookup_tables: Vec>, - /// Query offset - pub query_offset: i32, -} - -impl ConstraintBuilder { - pub(crate) fn new(max_degree: usize) -> Self { - ConstraintBuilder { - constraints: Vec::new(), - max_degree, - conditions: Vec::new(), - lookups: Vec::new(), - lookup_tables: Vec::new(), - query_offset: 0, - } - } - - pub(crate) fn require_zero(&mut self, name: &'static str, constraint: Expression) { - self.add_constraint(name, constraint); - } - - pub(crate) fn require_equal( - &mut self, - name: &'static str, - lhs: Expression, - rhs: Expression, - ) { - self.add_constraint(name, lhs - rhs); - } - - pub(crate) fn require_boolean(&mut self, name: &'static str, value: Expression) { - self.add_constraint(name, value.clone() * (1.expr() - value)); - } - - pub(crate) fn require_in_set( - &mut self, - name: &'static str, - value: Expression, - set: Vec>, - ) { - self.add_constraint( - name, - set.iter() - .fold(1.expr(), |acc, item| acc * (value.clone() - item.clone())), - ); - } - - pub(crate) fn condition( - &mut self, - condition: Expression, - constraint: impl FnOnce(&mut Self) -> R, - ) -> R { - self.push_condition(condition); - let ret = constraint(self); - self.pop_condition(); - ret - } - - pub(crate) fn push_condition(&mut self, condition: Expression) { - self.conditions.push(condition); - } - - pub(crate) fn pop_condition(&mut self) { - self.conditions.pop(); - } - - pub(crate) fn add_constraints(&mut self, constraints: Vec<(&'static str, Expression)>) { - for (name, constraint) in constraints { - self.add_constraint(name, constraint); - } - } - - pub(crate) fn add_constraint(&mut self, name: &'static str, constraint: Expression) { - let constraint = match self.get_condition() { - Some(condition) => condition * constraint, - None => constraint, - }; - self.validate_degree(constraint.degree(), name); - self.constraints.push((name, constraint)); - } - - pub(crate) fn validate_degree(&self, degree: usize, name: &'static str) { - if self.max_degree > 0 { - debug_assert!( - degree <= self.max_degree, - "Expression {} degree too high: {} > {}", - name, - degree, - self.max_degree, - ); - } - } - - pub(crate) fn generate_constraints(&self) -> Vec<(&'static str, Expression)> { - self.constraints.clone() - } - - pub(crate) fn generate_lookups>( - &self, - meta: &mut ConstraintSystem, - lookup_names: &[S], - ) { - for lookup_name in lookup_names.iter() { - let lookups = self - .lookups - .iter() - .cloned() - .filter(|lookup| lookup.tag == lookup_name.as_ref()) - .collect::>(); - for lookup in lookups.iter() { - meta.lookup_any(lookup.description, |_meta| { - let table = self.get_lookup_table_values(lookup_name); - let mut values: Vec<_> = lookup - .values - .iter() - .map(|value| lookup.condition.expr() * value.expr()) - .collect(); - assert!(table.len() >= values.len()); - while values.len() < table.len() { - values.push(0.expr()); - } - table - .iter() - .zip(values.iter()) - .map(|(table, value)| (value.expr(), table.expr())) - .collect() - }); - } - } - } - - pub(crate) fn get_condition(&self) -> Option> { - if self.conditions.is_empty() { - None - } else { - Some(and::expr(self.conditions.iter())) - } - } - - pub(crate) fn get_condition_expr(&self) -> Expression { - self.get_condition().unwrap_or_else(|| 1.expr()) - } - - pub(crate) fn lookup_table>( - &mut self, - description: &'static str, - tag: S, - values: Vec>, - ) { - let condition = self.get_condition_expr(); - self.lookup_tables.push(LookupData { - description, - tag: tag.as_ref().to_owned(), - condition, - values, - }); - } - - pub(crate) fn lookup>( - &mut self, - description: &'static str, - tag: S, - values: Vec>, - ) { - let condition = self.get_condition_expr(); - self.lookups.push(LookupData { - description, - tag: tag.as_ref().to_owned(), - condition, - values, - }); - } - - pub(crate) fn get_lookups>(&self, tags: &[S]) -> Vec> { - self.lookups - .iter() - .cloned() - .filter(|lookup| tags.iter().any(|tag| lookup.tag == tag.as_ref())) - .collect::>() - } - - pub(crate) fn consume_lookups>(&mut self, tags: &[S]) -> Vec> { - let lookups = self.get_lookups(tags); - self.lookups - .retain(|lookup| tags.iter().any(|tag| lookup.tag != tag.as_ref())); - lookups - } - - pub(crate) fn get_lookup_table>( - &self, - tag: S, - ) -> (Expression, Vec>) { - let lookups = self - .lookup_tables - .iter() - .filter(|lookup| lookup.tag == tag.as_ref()) - .collect::>(); - - merge_values_unsafe( - lookups - .iter() - .map(|lookup| (lookup.condition.clone(), lookup.values.clone())) - .collect::>(), - ) - } - - pub(crate) fn get_lookup_table_values>(&self, tag: S) -> Vec> { - let lookup_table = self.get_lookup_table(tag); - // Combine with the merged selector as well - lookup_table - .1 - .iter() - .map(|v| v.expr() * lookup_table.0.expr()) - .collect::>() - } - - pub(crate) fn generate_lookup_table_checks>(&mut self, tag: S) { - let lookups = self - .lookup_tables - .iter() - .filter(|lookup| lookup.tag == tag.as_ref()) - .collect::>(); - let selectors = lookups - .iter() - .map(|lookup| lookup.condition.expr()) - .collect::>(); - for selector in selectors.iter() { - self.require_boolean( - "lookup table condition needs to be boolean", - selector.expr(), - ); - } - let selector = sum::expr(&selectors); - self.require_boolean( - "lookup table conditions sum needs to be boolean", - selector.expr(), - ); - } - - pub(crate) fn print_stats(&self) { - let mut expressions = self.constraints.clone(); - expressions.sort_by(|a, b| a.1.degree().cmp(&b.1.degree())); - for (name, expr) in expressions.iter() { - println!("'{}': {}", name, expr.degree()); - } - } - - pub(crate) fn get_query_offset(&self) -> i32 { - self.query_offset - } - - pub(crate) fn set_query_offset(&mut self, query_offset: i32) { - self.query_offset = query_offset; - } -} - -pub(crate) fn merge_lookups( - cb: &mut ConstraintBuilder, - lookups: Vec>, -) -> (Expression, Vec>) { - merge_values( - cb, - lookups - .iter() - .map(|lookup| (lookup.condition.clone(), lookup.values.clone())) - .collect::>(), - ) -} - -pub(crate) fn merge_values( - cb: &mut ConstraintBuilder, - values: Vec<(Expression, Vec>)>, -) -> (Expression, Vec>) { - let selector = sum::expr(values.iter().map(|(condition, _)| condition.expr())); - // Sanity checks (can be removed, here for safety) - crate::circuit!([meta, cb], { - require!(selector => bool); - }); - merge_values_unsafe(values) -} - -pub(crate) fn merge_values_unsafe( - values: Vec<(Expression, Vec>)>, -) -> (Expression, Vec>) { - if values.is_empty() { - return (0.expr(), Vec::new()); - } - let selector = sum::expr(values.iter().map(|(condition, _)| condition.expr())); - // Merge - let max_length = values.iter().map(|(_, values)| values.len()).max().unwrap(); - let mut merged_values = vec![0.expr(); max_length]; - let default_value = 0.expr(); - for (idx, value) in merged_values.iter_mut().enumerate() { - *value = sum::expr(values.iter().map(|(condition, values)| { - condition.expr() * values.get(idx).unwrap_or_else(|| &default_value).expr() - })); - } - (selector, merged_values) -} - -pub(crate) fn select( - condition: Expression, - when_true: &[Expression], - when_false: &[Expression], -) -> Vec> { - when_true - .into_iter() - .zip(when_false.into_iter()) - .map(|(when_true, when_false)| { - select::expr(condition.expr(), when_true.expr(), when_false.expr()) - }) - .collect() -} - -/// Trait that generates a vector of expressions -pub trait Expressable { - /// Returns a vector of the expressions from itself - fn to_expr_vec(&self) -> Vec>; -} - -impl Expressable for std::ops::Range { - fn to_expr_vec(&self) -> Vec> { - self.clone() - .map(|e| e.to_expr_vec()[0].expr()) - .collect::>() - } -} - -impl> Expressable for Vec { - fn to_expr_vec(&self) -> Vec> { - self.iter() - .map(|e| e.to_expr_vec()[0].expr()) - .collect::>() - } -} - -impl> Expressable for [E] { - fn to_expr_vec(&self) -> Vec> { - self.iter() - .map(|e| e.to_expr_vec()[0].expr()) - .collect::>() - } -} - -impl> Expressable for &[E] { - fn to_expr_vec(&self) -> Vec> { - self.iter() - .map(|e| e.to_expr_vec()[0].expr()) - .collect::>() - } -} - -impl> Expressable for (E, E) { - fn to_expr_vec(&self) -> Vec> { - let mut res = self.0.to_expr_vec(); - res.append(&mut self.1.to_expr_vec()); - res - } -} - -impl> Expressable for (E, E, E) { - fn to_expr_vec(&self) -> Vec> { - let mut res = self.0.to_expr_vec(); - res.append(&mut self.1.to_expr_vec()); - res.append(&mut self.2.to_expr_vec()); - res - } -} - -impl> Expressable for (E, E, E, E) { - fn to_expr_vec(&self) -> Vec> { - let mut res = self.0.to_expr_vec(); - res.append(&mut self.1.to_expr_vec()); - res.append(&mut self.2.to_expr_vec()); - res.append(&mut self.3.to_expr_vec()); - res - } -} - -/// Implementation trait `Expressable` for type able to be casted to an -/// Expression -#[macro_export] -macro_rules! impl_expressable { - ($type:ty) => { - impl Expressable for $type { - #[inline] - fn to_expr_vec(&self) -> Vec> { - vec![self.expr()] - } - } - }; -} - -impl_expressable!(bool); -impl_expressable!(u8); -impl_expressable!(i32); -impl_expressable!(u64); -impl_expressable!(usize); -impl_expressable!(isize); -impl_expressable!(Expression); -impl_expressable!(DataTransition); -impl_expressable!(Cell); - -/// Trait around select -pub trait Selectable { - /// Selects between itself and another value using the given condition - fn select(&self, condition: Expression, other: &Self) -> Self; - /// Returns itself if the condition holds, else zero - fn conditional(&self, condition: Expression) -> Self; - /// Adds 2 Selectables together - fn add_expr(&self, other: &Self) -> Self; - /// Creates a vector of Expressions representing itself - fn to_vec(&self) -> Vec>; -} - -impl Selectable for () { - fn select(&self, _condition: Expression, _when_false: &Self) -> Self { - () - } - fn conditional(&self, _condition: Expression) -> Self { - () - } - fn add_expr(&self, _other: &Self) -> Self { - () - } - fn to_vec(&self) -> Vec> { - vec![] - } -} - -impl Selectable for Expression { - fn select(&self, condition: Expression, when_false: &Self) -> Self { - gadgets::util::select::expr(condition, self.expr(), when_false.expr()) - } - fn conditional(&self, condition: Expression) -> Self { - condition * self.expr() - } - fn add_expr(&self, other: &Self) -> Self { - self.expr() + other.expr() - } - fn to_vec(&self) -> Vec> { - vec![self.expr()] - } -} - -/// Implementation trait `Selectable` for type able to be casted to an -/// expression -#[macro_export] -macro_rules! impl_selectable { - ($type:ty, $v:expr) => { - impl Selectable for $type { - fn select(&self, condition: Expression, when_false: &Self) -> Self { - select(condition, &self.to_vec(), &when_false.to_vec()) - .into_iter() - .collect_tuple() - .unwrap() - } - fn conditional(&self, condition: Expression) -> Self { - self.to_vec() - .into_iter() - .map(|when_true| condition.expr() * when_true.expr()) - .collect_tuple() - .unwrap() - } - fn add_expr(&self, other: &Self) -> Self { - self.to_vec() - .iter() - .zip(other.to_vec().iter()) - .map(|(a, b)| a.expr() + b.expr()) - .collect_tuple() - .unwrap() - } - fn to_vec(&self) -> Vec> { - $v(self) - } - } - }; -} - -impl_selectable!((Expression, Expression), |t: &( - Expression, - Expression -)| { - vec![t.0.expr(), t.1.expr()] -}); -impl_selectable!((Expression, Expression, Expression), |t: &( - Expression, - Expression, - Expression -)| { - vec![t.0.expr(), t.1.expr(), t.2.expr()] -}); -impl_selectable!( - (Expression, Expression, Expression, Expression), - |t: &(Expression, Expression, Expression, Expression)| { - vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr()] - } -); -impl_selectable!( - ( - Expression, - Expression, - Expression, - Expression, - Expression - ), - |t: &( - Expression, - Expression, - Expression, - Expression, - Expression - )| { vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr(), t.4.expr()] } -); - -/// Trait that conditionally combines multiple types -pub trait Conditionable { - /// Conditionally combines multiple values - fn apply_conditions(&self) -> E; - /// Gets the list of all conditions - fn get_conditions(&self) -> Vec>; - /// Gets the sum of all conditions - fn sum_conditions(&self) -> Expression; -} - -impl> Conditionable for Vec<(Expression, E)> { - fn apply_conditions(&self) -> E { - let mut res = self[0].1.conditional(self[0].0.expr()); - for pair in self.iter().skip(1) { - res = res.add_expr(&pair.1.conditional(pair.0.expr())); - } - res - } - - fn get_conditions(&self) -> Vec> { - self.iter().map(|v| v.0.expr()).collect() - } - - fn sum_conditions(&self) -> Expression { - sum::expr(&self.get_conditions()) - } -} - -/// Trait around RLC -pub trait RLCable { - /// Returns the RLC of itself - fn rlc(&self, r: &[Expression]) -> Expression; -} - -impl> RLCable for Vec { - fn rlc(&self, r: &[Expression]) -> Expression { - rlc::expr(&self.to_expr_vec(), r) - } -} - -impl> RLCable for [E] { - fn rlc(&self, r: &[Expression]) -> Expression { - rlc::expr(&self.to_expr_vec(), r) - } -} - -/// Trait around RLC -pub trait RLCChainable { - /// Returns the RLC of itself with a starting rlc/multiplier - fn rlc_chain(&self, other: Expression) -> Expression; -} - -impl RLCChainable for (Expression, Expression) { - fn rlc_chain(&self, other: Expression) -> Expression { - self.0.expr() + self.1.expr() * other.expr() - } -} - -/// require_parser -#[macro_export] -macro_rules! require_parser { - { - $cb:expr, - lhs = ($($lhs:tt)*) - rest = (== $($rhs:tt)*) - } => { - let description = $crate::concat_with_preamble!( - stringify!($($lhs)*), - " == ", - stringify!($($rhs)*) - ); - $crate::_require!($cb, description, $($lhs)* => $($rhs)*) - }; - - { - $cb:expr, - lhs = ($($lhs:tt)*) - rest = ($next:tt $($rest:tt)*) - } => { - $crate::require_parser! { - $cb, - lhs = ($($lhs)* $next) - rest = ($($rest)*) - } - }; -} - -/// _require2 -#[macro_export] -macro_rules! _require2 { - ($cb:expr, $($rest:tt)*) => {{ - $crate::require_parser! { - $cb, - lhs = () - rest = ($($rest)*) - } - }}; -} - -/// Creates a dummy constraint builder that cannot be used to add constraints. -#[macro_export] -macro_rules! _cb { - () => {{ - ConstraintBuilder::::new(0) - }}; -} - -/// Concats arguments with preamble consisting of the originating file and line. -#[macro_export] -macro_rules! concat_with_preamble { - ($($args:expr),* $(,)?) => {{ - concat!( - file!(), - ":", - line!(), - ": ", - $( - $args, - )* - ) - }}; -} - -/// Can be used to mark a specific branch as unreachable -#[macro_export] -macro_rules! _unreachablex { - ($cb:expr $(,$descr:expr)?) => {{ - let descr = concat_with_preamble!( - "unreachable executed", - $( - ": ", - $descr, - )* - ); - _require!($cb, descr, true => false) - }}; -} - -/// _require -#[macro_export] -macro_rules! _require { - ($cb:expr, $lhs:expr => bool) => {{ - $cb.require_boolean( - concat_with_preamble!( - stringify!($lhs), - " => ", - "bool", - ), - $lhs.expr(), - ); - }}; - - ($cb:expr, $lhs:expr => $rhs:expr) => {{ - let description = concat_with_preamble!( - stringify!($lhs), - " => ", - stringify!($rhs) - ); - _require!($cb, description, $lhs => $rhs) - }}; - - ($cb:expr, $descr:expr, $lhs:expr => $rhs:expr) => {{ - let rhs = $rhs.to_expr_vec(); - if rhs.len() == 1 { - $cb.require_equal( - Box::leak($descr.to_string().into_boxed_str()), - $lhs.expr(), - rhs[0].expr(), - ); - } else { - $cb.require_in_set( - Box::leak($descr.to_string().into_boxed_str()), - $lhs.expr(), - rhs.clone(), - ); - } - }}; - - // Lookup using a tuple - ($cb:expr, ($($v:expr),+) => @$tag:expr) => {{ - $cb.lookup( - concat_with_preamble!( - "(", - $( - stringify!($v), - ", ", - )* - ") => @", - stringify!($tag), - ), - $tag.to_string(), - vec![$($v.expr(),)*], - ); - }}; - ($cb:expr, $descr:expr, ($($v:expr),+) => @$tag:expr) => {{ - $cb.lookup( - Box::leak($descr.into_boxed_str()), - $tag.to_string(), - vec![$($v.expr(),)*], - ); - }}; - - // Lookup using an array - ($cb:expr, $values:expr => @$tag:expr) => {{ - $cb.lookup( - concat_with_preamble!( - stringify!($values), - " => @", - stringify!($tag), - ), - $tag.to_string(), - $values.clone(), - ); - }}; - ($cb:expr, $descr:expr, $values:expr => @$tag:expr) => {{ - $cb.lookup( - Box::leak($descr.to_string().into_boxed_str()), - $tag.to_string(), - $values.clone(), - ); - }}; - - // Put values in a lookup table using a tuple - ($cb:expr, @$tag:expr => ($($v:expr),+)) => {{ - $cb.lookup_table( - concat_with_preamble!( - "@", - stringify!($tag), - " => (", - $( - stringify!($v), - ", ", - )* - ")", - ), - $tag.to_string(), - vec![$($v.expr(),)*], - ); - }}; - // Put values in a lookup table using an array - ($cb:expr, @$tag:expr => $values:expr) => {{ - $cb.lookup_table( - concat_with_preamble!( - "@", - stringify!($tag), - " => (", - stringify!($values), - ")", - ), - $tag.to_string(), - $values, - ); - }}; -} - -/// matchx -/// Supports `_` which works the same as in the normal `match`: if none of the -/// other arms are active the `_` arm will be executed and so can be used to -/// return some default values or could also be marked as unreachable (using the -/// unreachablex! macro). -#[macro_export] -macro_rules! _matchx { - ($cb:expr, $($condition:expr => $when:expr),* $(, _ => $catch_all:expr)? $(,)?) => {{ - let mut conditions = Vec::new(); - let mut cases = Vec::new(); - $( - $cb.push_condition($condition.expr()); - let ret = $when.clone(); - $cb.pop_condition(); - cases.push(($condition.expr(), ret)); - conditions.push($condition.expr()); - )* - - $( - let catch_all_condition = not::expr(sum::expr(&conditions)); - $cb.push_condition(catch_all_condition.expr()); - let ret = $catch_all; - $cb.pop_condition(); - cases.push((catch_all_condition.expr(), ret)); - conditions.push(catch_all_condition.expr()); - )* - - // All conditions need to be boolean - for condition in conditions.iter() { - _require!($cb, condition => bool); - } - // Exactly 1 case needs to be enabled - _require!($cb, sum::expr(&conditions) => 1); - - cases.apply_conditions() - }}; -} - -/// ifx -#[macro_export] -macro_rules! _ifx { - ($cb:expr, $($condition:expr),* => $when_true:block $(elsex $when_false:block)?) => {{ - let condition = and::expr([$($condition.expr()),*]); - - $cb.push_condition(condition.expr()); - let ret_true = $when_true.clone(); - $cb.pop_condition(); - - #[allow(unused_assignments, unused_mut)] - let mut ret = ret_true.conditional(condition.expr()); - $( - // In if/else cases, the condition needs to be boolean - _require!($cb, condition => bool); - - $cb.push_condition(not::expr(condition.expr())); - let ret_false = $when_false; - $cb.pop_condition(); - - ret = ret_true.select(condition.expr(), &ret_false); - )* - ret - }}; -} - -/// Circuit builder macros -/// Nested macro's can't do repetition (https://github.com/rust-lang/rust/issues/35853) -/// so we expose a couple of permutations here manually. -#[macro_export] -macro_rules! circuit { - ([$meta:expr, $cb:expr], $content:block) => {{ - #[allow(unused_imports)] - use $crate::{concat_with_preamble, _require, _matchx, _ifx, _unreachablex}; - #[allow(unused_imports)] - use gadgets::util::{and, not, or, sum, Expr}; - #[allow(unused_imports)] - use crate::circuit_tools::{Conditionable, Expressable, Selectable}; - - #[allow(unused_macros)] - macro_rules! f { - ($column:expr, $rot:expr) => {{ - $meta.query_fixed($column.clone(), Rotation($cb.get_query_offset() + ($rot as i32))) - }}; - ($column:expr) => {{ - $meta.query_fixed($column.clone(), Rotation($cb.get_query_offset())) - }}; - } - - #[allow(unused_macros)] - macro_rules! a { - ($column:expr, $rot:expr) => {{ - $meta.query_advice($column.clone(), Rotation($cb.get_query_offset() + ($rot as i32))) - }}; - ($column:expr) => {{ - $meta.query_advice($column.clone(), Rotation($cb.get_query_offset())) - }}; - } - - #[allow(unused_macros)] - macro_rules! not { - ($expr:expr) => {{ - gadgets::util::not::expr($expr.expr()) - }}; - } - - #[allow(unused_macros)] - macro_rules! invert { - ($expr:expr) => {{ - Expression::Constant(F::from($expr as u64).invert().unwrap()) - }}; - } - - #[allow(unused_macros)] - macro_rules! require { - ($lhs:expr => bool) => {{ - _require!($cb, $lhs => bool); - }}; - - ($lhs:expr => $rhs:expr) => {{ - _require!($cb, $lhs => $rhs); - }}; - - ($name:expr, $lhs:expr => $rhs:expr) => {{ - _require!($cb, $name, $lhs => $rhs); - }}; - - (($a:expr) => @$tag:expr) => {{ - _require!($cb, ($a) => @$tag); - }}; - - (($a:expr, $b:expr) => @$tag:expr) => {{ - _require!($cb, ($a, $b) => @$tag); - }}; - - (($a:expr, $b:expr, $c:expr) => @$tag:expr) => {{ - _require!($cb, ($a, $b, $c) => @$tag); - }}; - - (($a:expr, $b:expr, $c:expr, $d:expr) => @$tag:expr) => {{ - _require!($cb, ($a, $b, $c, $d) => @$tag); - }}; - - ($values:expr => @$tag:expr) => {{ - _require!($cb, $values => @$tag); - }}; - - ($descr:expr, $values:expr => @$tag:expr) => {{ - _require!($cb, $descr, $values => @$tag); - }}; - - (@$tag:expr => ($a:expr, $b:expr, $c:expr)) => {{ - _require!($cb, @$tag => ($a, $b, $c)); - }}; - - (@$tag:expr => $values:expr) => {{ - _require!($cb, @$tag => $values); - }}; - } - - #[allow(unused_macros)] - macro_rules! ifx { - ($condition:expr => $when_true:block elsex $when_false:block) => {{ - _ifx!($cb, $condition => $when_true elsex $when_false) - }}; - ($condition_a:expr, $condition_b:expr => $when_true:block elsex $when_false:block) => {{ - _ifx!($cb, $condition_a, $condition_b => $when_true elsex $when_false) - }}; - ($condition_a:expr, $condition_b:expr, $condition_c:expr => $when_true:block elsex $when_false:block) => {{ - _ifx!($cb, $condition_a, $condition_b, $condition_c => $when_true elsex $when_false) - }}; - ($condition_a:expr, $condition_b:expr, $condition_c:expr, $condition_d:expr => $when_true:block elsex $when_false:block) => {{ - _ifx!($cb, $condition_a, $condition_b, $condition_c, $condition_d => $when_true elsex $when_false) - }}; - - ($condition:expr => $when_true:block) => {{ - _ifx!($cb, $condition => $when_true) - }}; - ($condition_a:expr, $condition_b:expr => $when_true:block) => {{ - _ifx!($cb, $condition_a, $condition_b => $when_true) - }}; - ($condition_a:expr, $condition_b:expr, $condition_c:expr => $when_true:block) => {{ - _ifx!($cb, $condition_a, $condition_b, $condition_c => $when_true) - }}; - ($condition_a:expr, $condition_b:expr, $condition_c:expr, $condition_d:expr => $when_true:block) => {{ - _ifx!($cb, $condition_a, $condition_b, $condition_c, $condition_d => $when_true) - }}; - ($condition_a:expr, $condition_b:expr, $condition_c:expr, $condition_d:expr, $condition_e:expr => $when_true:block) => {{ - _ifx!($cb, $condition_a, $condition_b, $condition_c, $condition_d, $condition_e => $when_true) - }}; - } - - #[allow(unused_macros)] - macro_rules! matchx { - ($condition_a:expr => $when_a:expr,) => {{ - _matchx!($cb, $condition_a => $when_a) - }}; - ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr,) => {{ - _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b) - }}; - ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, $condition_c:expr => $when_c:expr,) => {{ - _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, $condition_c => $when_c) - }}; - ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, $condition_c:expr => $when_c:expr, $condition_d:expr => $when_d:expr,) => {{ - _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, $condition_c => $when_c, $condition_d => $when_d,) - }}; - - ($condition_a:expr => $when_a:expr, _ => $catch_all:expr,) => {{ - _matchx!($cb, $condition_a => $when_a, _ => $catch_all,) - }}; - ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, _ => $catch_all:expr,) => {{ - _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, _ => $catch_all,) - }}; - ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, $condition_c:expr => $when_c:expr, _ => $catch_all:expr,) => {{ - _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, $condition_c => $when_c, _ => $catch_all,) - }}; - } - - #[allow(unused_macros)] - macro_rules! unreachablex { - () => {{ - _unreachablex!($cb) - }}; - ($arg:expr) => {{ - _unreachablex!($cb, $arg) - }}; - } - - $content - }}; -} +#[macro_use] +pub mod constraint_builder; +pub mod cell_manager; +pub mod memory; +pub mod gadgets; \ No newline at end of file diff --git a/zkevm-circuits/src/circuit_tools/cell_manager.rs b/zkevm-circuits/src/circuit_tools/cell_manager.rs new file mode 100644 index 0000000000..d3ba2c695b --- /dev/null +++ b/zkevm-circuits/src/circuit_tools/cell_manager.rs @@ -0,0 +1,254 @@ +//! Cell manager +use crate::util::Expr; +use eth_types::Field; +use halo2_proofs::{ + circuit::{AssignedCell, Region, Value}, + plonk::{Advice, Column, Error, Expression, VirtualCells}, + poly::Rotation, +}; +use std::{any::Any, collections::BTreeMap}; + +#[derive(Clone)] +pub(crate) struct DataTransition { + prev: Expression, + cur: Expression, +} + +impl DataTransition { + pub(crate) fn new(meta: &mut VirtualCells, column: Column) -> DataTransition { + DataTransition { + prev: meta.query_advice(column, Rotation::prev()), + cur: meta.query_advice(column, Rotation::cur()), + } + } + + pub(crate) fn new_with_rot( + meta: &mut VirtualCells, + column: Column, + rot_prev: i32, + rot_cur: i32, + ) -> DataTransition { + DataTransition { + prev: meta.query_advice(column, Rotation(rot_prev)), + cur: meta.query_advice(column, Rotation(rot_cur)), + } + } + + pub(crate) fn from(prev: Expression, cur: Expression) -> DataTransition { + DataTransition { prev, cur } + } + + pub(crate) fn cur(&self) -> Expression { + self.cur.clone() + } + + pub(crate) fn prev(&self) -> Expression { + self.prev.clone() + } + + pub(crate) fn delta(&self) -> Expression { + self.prev() - self.cur() + } +} + +impl Expr for DataTransition { + fn expr(&self) -> Expression { + self.cur.clone() + } +} + +/// Trackable object +pub trait Trackable { + /// To allow downcasting + fn as_any(&self) -> &dyn Any; + + /// Cloning + fn clone_box(&self) -> Box; +} + +// We can now implement Clone manually by forwarding to clone_box. +impl Clone for Box { + fn clone(&self) -> Box { + self.clone_box() + } +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct Cell { + // expression for constraint + expression: Option>, + column: Option>, + // relative position to selector for synthesis + rotation: usize, +} + +impl Trackable for Cell { + fn as_any(&self) -> &dyn Any { + self + } + fn clone_box(&self) -> Box { + Box::new(self.clone()) + } +} + +impl Cell { + pub(crate) fn new(meta: &mut VirtualCells, column: Column, rotation: usize) -> Self { + Self { + expression: Some(meta.query_advice(column, Rotation(rotation as i32))), + column: Some(column), + rotation, + } + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + value: F, + ) -> Result, Error> { + region.assign_advice( + || { + format!( + "Cell column: {:?} and rotation: {}", + self.column, self.rotation + ) + }, + self.column.unwrap(), + offset + self.rotation, + || Value::known(value), + ) + } +} + +impl Expr for Cell { + fn expr(&self) -> Expression { + self.expression.as_ref().unwrap().clone() + } +} + +impl Expr for &Cell { + fn expr(&self) -> Expression { + self.expression.as_ref().unwrap().clone() + } +} + +/// CellType +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum CellType { + /// General + Storage, +} + +/// CellColumn +#[derive(Clone, Debug)] +pub struct CellColumn { + pub(crate) index: usize, + pub(crate) cell_type: CellType, + pub(crate) height: usize, + pub(crate) expr: Expression, +} + +impl Expr for CellColumn { + fn expr(&self) -> Expression { + self.expr.clone() + } +} + +/// CellManager +#[derive(Clone, Debug)] +pub struct CellManager { + width: usize, + height: usize, + cells: Vec>, + columns: Vec>, +} + +impl CellManager { + pub(crate) fn new(meta: &mut VirtualCells, advice_columns: &[Column]) -> Self { + // Setup the columns and query the cells + let width = advice_columns.len(); + let height = 32; + let mut cells = Vec::with_capacity(height * width); + let mut columns = Vec::with_capacity(width); + for c in 0..width { + for r in 0..height { + cells.push(Cell::new(meta, advice_columns[c], r)); + } + columns.push(CellColumn { + index: c, + cell_type: CellType::Storage, + height: 0, + expr: cells[c * height].expr(), + }); + } + + Self { + width, + height, + cells, + columns, + } + } + + pub(crate) fn query_cells(&mut self, cell_type: CellType, count: usize) -> Vec> { + let mut cells = Vec::with_capacity(count); + while cells.len() < count { + let column_idx = self.next_column(cell_type); + let column = &mut self.columns[column_idx]; + cells.push(self.cells[column_idx * self.height + column.height].clone()); + column.height += 1; + } + cells + } + + pub(crate) fn query_cell(&mut self, cell_type: CellType) -> Cell { + self.query_cells(cell_type, 1)[0].clone() + } + + pub(crate) fn reset(&mut self) { + for column in self.columns.iter_mut() { + column.height = 0; + } + } + + fn next_column(&self, cell_type: CellType) -> usize { + let mut best_index: Option = None; + let mut best_height = self.height; + for column in self.columns.iter() { + if column.cell_type == cell_type && column.height < best_height { + best_index = Some(column.index); + best_height = column.height; + } + } + match best_index { + Some(index) => index, + None => unreachable!("not enough cells for query: {:?}", cell_type), + } + } + + pub(crate) fn get_height(&self) -> usize { + self.columns + .iter() + .map(|column| column.height) + .max() + .unwrap() + } + + /// Returns a map of CellType -> (width, height, num_cells) + pub(crate) fn get_stats(&self) -> BTreeMap { + let mut data = BTreeMap::new(); + for column in self.columns.iter() { + let (mut count, mut height, mut num_cells) = + data.get(&column.cell_type).unwrap_or(&(0, 0, 0)); + count += 1; + height = height.max(column.height); + num_cells += column.height; + data.insert(column.cell_type, (count, height, num_cells)); + } + data + } + + pub(crate) fn columns(&self) -> &[CellColumn] { + &self.columns + } +} diff --git a/zkevm-circuits/src/circuit_tools/constraint_builder.rs b/zkevm-circuits/src/circuit_tools/constraint_builder.rs new file mode 100644 index 0000000000..d0c1c4c28d --- /dev/null +++ b/zkevm-circuits/src/circuit_tools/constraint_builder.rs @@ -0,0 +1,1116 @@ +//! Circuit utilities +use crate::{evm_circuit::util::rlc, util::Expr}; +use eth_types::Field; +use gadgets::util::{and, select, sum}; +use halo2_proofs::{ + plonk::{ConstraintSystem, Expression}, +}; +use itertools::Itertools; + +use super::cell_manager::{Cell, CellManager, CellType, DataTransition, Trackable}; + +/// Lookup data +#[derive(Clone)] +pub struct LookupData { + /// Desciption + pub description: &'static str, + /// Lookup tag + pub tag: String, + /// Condition under which the lookup needs to be done + pub condition: Expression, + /// The values to lookup + pub values: Vec>, +} + +/// Constraint builder +#[derive(Clone)] +pub struct ConstraintBuilder { + constraints: Vec<(&'static str, Expression)>, + max_degree: usize, + conditions: Vec>, + /// The lookups + pub lookups: Vec>, + /// The lookup tables + pub lookup_tables: Vec>, + /// Query offset + pub query_offset: i32, + /// CellManager + pub cell_manager: Option>, + /// Tracked objects + objects: Vec>, +} + +impl ConstraintBuilder { + pub(crate) fn new(max_degree: usize, cell_manager: Option>) -> Self { + ConstraintBuilder { + constraints: Vec::new(), + max_degree, + conditions: Vec::new(), + lookups: Vec::new(), + lookup_tables: Vec::new(), + query_offset: 0, + cell_manager, + objects: Vec::new(), + } + } + + pub(crate) fn set_cell_manager(&mut self, cell_manager: CellManager) { + self.cell_manager = Some(cell_manager); + } + + pub(crate) fn require_zero(&mut self, name: &'static str, constraint: Expression) { + self.add_constraint(name, constraint); + } + + pub(crate) fn require_equal( + &mut self, + name: &'static str, + lhs: Expression, + rhs: Expression, + ) { + self.add_constraint(name, lhs - rhs); + } + + pub(crate) fn require_boolean(&mut self, name: &'static str, value: Expression) { + self.add_constraint(name, value.clone() * (1.expr() - value)); + } + + pub(crate) fn require_in_set( + &mut self, + name: &'static str, + value: Expression, + set: Vec>, + ) { + self.add_constraint( + name, + set.iter() + .fold(1.expr(), |acc, item| acc * (value.clone() - item.clone())), + ); + } + + pub(crate) fn condition( + &mut self, + condition: Expression, + constraint: impl FnOnce(&mut Self) -> R, + ) -> R { + self.push_condition(condition); + let ret = constraint(self); + self.pop_condition(); + ret + } + + pub(crate) fn push_condition(&mut self, condition: Expression) { + self.conditions.push(condition); + } + + pub(crate) fn pop_condition(&mut self) { + self.conditions.pop(); + } + + pub(crate) fn add_constraints(&mut self, constraints: Vec<(&'static str, Expression)>) { + for (name, constraint) in constraints { + self.add_constraint(name, constraint); + } + } + + pub(crate) fn add_constraint(&mut self, name: &'static str, constraint: Expression) { + let constraint = match self.get_condition() { + Some(condition) => condition * constraint, + None => constraint, + }; + self.validate_degree(constraint.degree(), name); + self.constraints.push((name, constraint)); + } + + // Query + + pub(crate) fn query_bool(&mut self) -> Cell { + let cell = self.query_cell(); + self.require_boolean("Constrain cell to be a bool", cell.expr()); + cell + } + + pub(crate) fn query_byte(&mut self) -> Cell { + // TODO(Brecht): fix + self.query_cell_with_type(CellType::Storage) + } + + pub(crate) fn query_bytes(&mut self) -> [Cell; N] { + self.query_bytes_dyn(N).try_into().unwrap() + } + + pub(crate) fn query_bytes_dyn(&mut self, count: usize) -> Vec> { + self.query_cells(CellType::Storage, count) + } + + pub(crate) fn query_cell(&mut self) -> Cell { + self.query_cell_with_type(CellType::Storage) + } + + pub(crate) fn query_cell_with_type(&mut self, cell_type: CellType) -> Cell { + self.query_cells(cell_type, 1).first().unwrap().clone() + } + + fn query_cells(&mut self, cell_type: CellType, count: usize) -> Vec> { + self.cell_manager.as_mut().unwrap().query_cells(cell_type, count) + } + + pub(crate) fn validate_degree(&self, degree: usize, name: &'static str) { + if self.max_degree > 0 { + debug_assert!( + degree <= self.max_degree, + "Expression {} degree too high: {} > {}", + name, + degree, + self.max_degree, + ); + } + } + + pub(crate) fn generate_constraints(&self) -> Vec<(&'static str, Expression)> { + self.constraints.clone() + } + + pub(crate) fn generate_lookups>( + &self, + meta: &mut ConstraintSystem, + lookup_names: &[S], + ) { + for lookup_name in lookup_names.iter() { + let lookups = self + .lookups + .iter() + .cloned() + .filter(|lookup| lookup.tag == lookup_name.as_ref()) + .collect::>(); + for lookup in lookups.iter() { + meta.lookup_any(lookup.description, |_meta| { + let table = self.get_lookup_table_values(lookup_name); + let mut values: Vec<_> = lookup + .values + .iter() + .map(|value| lookup.condition.expr() * value.expr()) + .collect(); + assert!(table.len() >= values.len()); + while values.len() < table.len() { + values.push(0.expr()); + } + table + .iter() + .zip(values.iter()) + .map(|(table, value)| (value.expr(), table.expr())) + .collect() + }); + } + } + } + + pub(crate) fn get_condition(&self) -> Option> { + if self.conditions.is_empty() { + None + } else { + Some(and::expr(self.conditions.iter())) + } + } + + pub(crate) fn get_condition_expr(&self) -> Expression { + self.get_condition().unwrap_or_else(|| 1.expr()) + } + + pub(crate) fn lookup_table>( + &mut self, + description: &'static str, + tag: S, + values: Vec>, + ) { + let condition = self.get_condition_expr(); + self.lookup_tables.push(LookupData { + description, + tag: tag.as_ref().to_owned(), + condition, + values, + }); + } + + pub(crate) fn lookup>( + &mut self, + description: &'static str, + tag: S, + values: Vec>, + ) { + let condition = self.get_condition_expr(); + self.lookups.push(LookupData { + description, + tag: tag.as_ref().to_owned(), + condition, + values, + }); + } + + pub(crate) fn get_lookups>(&self, tags: &[S]) -> Vec> { + self.lookups + .iter() + .cloned() + .filter(|lookup| tags.iter().any(|tag| lookup.tag == tag.as_ref())) + .collect::>() + } + + pub(crate) fn consume_lookups>(&mut self, tags: &[S]) -> Vec> { + let lookups = self.get_lookups(tags); + self.lookups + .retain(|lookup| tags.iter().any(|tag| lookup.tag != tag.as_ref())); + lookups + } + + pub(crate) fn get_lookup_table>( + &self, + tag: S, + ) -> (Expression, Vec>) { + let lookups = self + .lookup_tables + .iter() + .filter(|lookup| lookup.tag == tag.as_ref()) + .collect::>(); + + merge_values_unsafe( + lookups + .iter() + .map(|lookup| (lookup.condition.clone(), lookup.values.clone())) + .collect::>(), + ) + } + + pub(crate) fn get_lookup_table_values>(&self, tag: S) -> Vec> { + let lookup_table = self.get_lookup_table(tag); + // Combine with the merged selector as well + lookup_table + .1 + .iter() + .map(|v| v.expr() * lookup_table.0.expr()) + .collect::>() + } + + pub(crate) fn generate_lookup_table_checks>(&mut self, tag: S) { + let lookups = self + .lookup_tables + .iter() + .filter(|lookup| lookup.tag == tag.as_ref()) + .collect::>(); + let selectors = lookups + .iter() + .map(|lookup| lookup.condition.expr()) + .collect::>(); + for selector in selectors.iter() { + self.require_boolean( + "lookup table condition needs to be boolean", + selector.expr(), + ); + } + let selector = sum::expr(&selectors); + self.require_boolean( + "lookup table conditions sum needs to be boolean", + selector.expr(), + ); + } + + pub(crate) fn print_stats(&self) { + let mut expressions = self.constraints.clone(); + expressions.sort_by(|a, b| a.1.degree().cmp(&b.1.degree())); + for (name, expr) in expressions.iter() { + println!("'{}': {}", name, expr.degree()); + } + } + + pub(crate) fn get_query_offset(&self) -> i32 { + self.query_offset + } + + pub(crate) fn set_query_offset(&mut self, query_offset: i32) { + self.query_offset = query_offset; + } +} + +pub(crate) fn merge_lookups( + cb: &mut ConstraintBuilder, + lookups: Vec>, +) -> (Expression, Vec>) { + merge_values( + cb, + lookups + .iter() + .map(|lookup| (lookup.condition.clone(), lookup.values.clone())) + .collect::>(), + ) +} + +pub(crate) fn merge_values( + cb: &mut ConstraintBuilder, + values: Vec<(Expression, Vec>)>, +) -> (Expression, Vec>) { + let selector = sum::expr(values.iter().map(|(condition, _)| condition.expr())); + // Sanity checks (can be removed, here for safety) + crate::circuit!([meta, cb], { + require!(selector => bool); + }); + merge_values_unsafe(values) +} + +pub(crate) fn merge_values_unsafe( + values: Vec<(Expression, Vec>)>, +) -> (Expression, Vec>) { + if values.is_empty() { + return (0.expr(), Vec::new()); + } + let selector = sum::expr(values.iter().map(|(condition, _)| condition.expr())); + // Merge + let max_length = values.iter().map(|(_, values)| values.len()).max().unwrap(); + let mut merged_values = vec![0.expr(); max_length]; + let default_value = 0.expr(); + for (idx, value) in merged_values.iter_mut().enumerate() { + *value = sum::expr(values.iter().map(|(condition, values)| { + condition.expr() * values.get(idx).unwrap_or_else(|| &default_value).expr() + })); + } + (selector, merged_values) +} + +pub(crate) fn select( + condition: Expression, + when_true: &[Expression], + when_false: &[Expression], +) -> Vec> { + when_true + .into_iter() + .zip(when_false.into_iter()) + .map(|(when_true, when_false)| { + select::expr(condition.expr(), when_true.expr(), when_false.expr()) + }) + .collect() +} + +/// Trait that generates a vector of expressions +pub trait Expressable { + /// Returns a vector of the expressions from itself + fn to_expr_vec(&self) -> Vec>; +} + +impl Expressable for std::ops::Range { + fn to_expr_vec(&self) -> Vec> { + self.clone() + .map(|e| e.to_expr_vec()[0].expr()) + .collect::>() + } +} + +impl> Expressable for Vec { + fn to_expr_vec(&self) -> Vec> { + self.iter() + .map(|e| e.to_expr_vec()[0].expr()) + .collect::>() + } +} + +impl> Expressable for [E] { + fn to_expr_vec(&self) -> Vec> { + self.iter() + .map(|e| e.to_expr_vec()[0].expr()) + .collect::>() + } +} + +impl> Expressable for &[E] { + fn to_expr_vec(&self) -> Vec> { + self.iter() + .map(|e| e.to_expr_vec()[0].expr()) + .collect::>() + } +} + +impl> Expressable for (E, E) { + fn to_expr_vec(&self) -> Vec> { + let mut res = self.0.to_expr_vec(); + res.append(&mut self.1.to_expr_vec()); + res + } +} + +impl> Expressable for (E, E, E) { + fn to_expr_vec(&self) -> Vec> { + let mut res = self.0.to_expr_vec(); + res.append(&mut self.1.to_expr_vec()); + res.append(&mut self.2.to_expr_vec()); + res + } +} + +impl> Expressable for (E, E, E, E) { + fn to_expr_vec(&self) -> Vec> { + let mut res = self.0.to_expr_vec(); + res.append(&mut self.1.to_expr_vec()); + res.append(&mut self.2.to_expr_vec()); + res.append(&mut self.3.to_expr_vec()); + res + } +} + +/// Implementation trait `Expressable` for type able to be casted to an +/// Expression +#[macro_export] +macro_rules! impl_expressable { + ($type:ty) => { + impl Expressable for $type { + #[inline] + fn to_expr_vec(&self) -> Vec> { + vec![self.expr()] + } + } + }; +} + +impl_expressable!(bool); +impl_expressable!(u8); +impl_expressable!(i32); +impl_expressable!(u64); +impl_expressable!(usize); +impl_expressable!(isize); +impl_expressable!(Expression); +impl_expressable!(DataTransition); +impl_expressable!(Cell); + +/// Trait around select +pub trait Selectable { + /// Selects between itself and another value using the given condition + fn select(&self, condition: Expression, other: &Self) -> Self; + /// Returns itself if the condition holds, else zero + fn conditional(&self, condition: Expression) -> Self; + /// Adds 2 Selectables together + fn add_expr(&self, other: &Self) -> Self; + /// Creates a vector of Expressions representing itself + fn to_vec(&self) -> Vec>; +} + +impl Selectable for () { + fn select(&self, _condition: Expression, _when_false: &Self) -> Self { + () + } + fn conditional(&self, _condition: Expression) -> Self { + () + } + fn add_expr(&self, _other: &Self) -> Self { + () + } + fn to_vec(&self) -> Vec> { + vec![] + } +} + +impl Selectable for Expression { + fn select(&self, condition: Expression, when_false: &Self) -> Self { + gadgets::util::select::expr(condition, self.expr(), when_false.expr()) + } + fn conditional(&self, condition: Expression) -> Self { + condition * self.expr() + } + fn add_expr(&self, other: &Self) -> Self { + self.expr() + other.expr() + } + fn to_vec(&self) -> Vec> { + vec![self.expr()] + } +} + +/// Implementation trait `Selectable` for type able to be casted to an +/// expression +#[macro_export] +macro_rules! impl_selectable { + ($type:ty, $v:expr) => { + impl Selectable for $type { + fn select(&self, condition: Expression, when_false: &Self) -> Self { + select(condition, &self.to_vec(), &when_false.to_vec()) + .into_iter() + .collect_tuple() + .unwrap() + } + fn conditional(&self, condition: Expression) -> Self { + self.to_vec() + .into_iter() + .map(|when_true| condition.expr() * when_true.expr()) + .collect_tuple() + .unwrap() + } + fn add_expr(&self, other: &Self) -> Self { + self.to_vec() + .iter() + .zip(other.to_vec().iter()) + .map(|(a, b)| a.expr() + b.expr()) + .collect_tuple() + .unwrap() + } + fn to_vec(&self) -> Vec> { + $v(self) + } + } + }; +} + +impl_selectable!((Expression, Expression), |t: &( + Expression, + Expression +)| { + vec![t.0.expr(), t.1.expr()] +}); +impl_selectable!((Expression, Expression, Expression), |t: &( + Expression, + Expression, + Expression +)| { + vec![t.0.expr(), t.1.expr(), t.2.expr()] +}); +impl_selectable!( + (Expression, Expression, Expression, Expression), + |t: &(Expression, Expression, Expression, Expression)| { + vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr()] + } +); +impl_selectable!( + ( + Expression, + Expression, + Expression, + Expression, + Expression + ), + |t: &( + Expression, + Expression, + Expression, + Expression, + Expression + )| { vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr(), t.4.expr()] } +); + +/// Trait that conditionally combines multiple types +pub trait Conditionable { + /// Conditionally combines multiple values + fn apply_conditions(&self) -> E; + /// Gets the list of all conditions + fn get_conditions(&self) -> Vec>; + /// Gets the sum of all conditions + fn sum_conditions(&self) -> Expression; +} + +impl> Conditionable for Vec<(Expression, E)> { + fn apply_conditions(&self) -> E { + let mut res = self[0].1.conditional(self[0].0.expr()); + for pair in self.iter().skip(1) { + res = res.add_expr(&pair.1.conditional(pair.0.expr())); + } + res + } + + fn get_conditions(&self) -> Vec> { + self.iter().map(|v| v.0.expr()).collect() + } + + fn sum_conditions(&self) -> Expression { + sum::expr(&self.get_conditions()) + } +} + +/// Trait around RLC +pub trait RLCable { + /// Returns the RLC of itself + fn rlc(&self, r: &[Expression]) -> Expression; +} + +impl> RLCable for Vec { + fn rlc(&self, r: &[Expression]) -> Expression { + rlc::expr(&self.to_expr_vec(), r) + } +} + +impl> RLCable for [E] { + fn rlc(&self, r: &[Expression]) -> Expression { + rlc::expr(&self.to_expr_vec(), r) + } +} + +/// Trait around RLC +pub trait RLCChainable { + /// Returns the RLC of itself with a starting rlc/multiplier + fn rlc_chain(&self, other: Expression) -> Expression; +} + +impl RLCChainable for (Expression, Expression) { + fn rlc_chain(&self, other: Expression) -> Expression { + self.0.expr() + self.1.expr() * other.expr() + } +} + +/// require_parser +#[macro_export] +macro_rules! require_parser { + { + $cb:expr, + lhs = ($($lhs:tt)*) + rest = (== $($rhs:tt)*) + } => { + let description = $crate::concat_with_preamble!( + stringify!($($lhs)*), + " == ", + stringify!($($rhs)*) + ); + $crate::_require!($cb, description, $($lhs)* => $($rhs)*) + }; + + { + $cb:expr, + lhs = ($($lhs:tt)*) + rest = ($next:tt $($rest:tt)*) + } => { + $crate::require_parser! { + $cb, + lhs = ($($lhs)* $next) + rest = ($($rest)*) + } + }; +} + +/// _require2 +#[macro_export] +macro_rules! _require2 { + ($cb:expr, $($rest:tt)*) => {{ + $crate::require_parser! { + $cb, + lhs = () + rest = ($($rest)*) + } + }}; +} + +/// Creates a dummy constraint builder that cannot be used to add constraints. +#[macro_export] +macro_rules! _cb { + () => {{ + ConstraintBuilder::::new(0, None) + }}; +} + +/// Concats arguments with preamble consisting of the originating file and line. +#[macro_export] +macro_rules! concat_with_preamble { + ($($args:expr),* $(,)?) => {{ + concat!( + file!(), + ":", + line!(), + ": ", + $( + $args, + )* + ) + }}; +} + +/// Can be used to mark a specific branch as unreachable +#[macro_export] +macro_rules! _unreachablex { + ($cb:expr $(,$descr:expr)?) => {{ + let descr = concat_with_preamble!( + "unreachable executed", + $( + ": ", + $descr, + )* + ); + _require!($cb, descr, true => false) + }}; +} + +/// _require +#[macro_export] +macro_rules! _require { + ($cb:expr, $lhs:expr => bool) => {{ + $cb.require_boolean( + concat_with_preamble!( + stringify!($lhs), + " => ", + "bool", + ), + $lhs.expr(), + ); + }}; + + ($cb:expr, $lhs:expr => $rhs:expr) => {{ + let description = concat_with_preamble!( + stringify!($lhs), + " => ", + stringify!($rhs) + ); + _require!($cb, description, $lhs => $rhs) + }}; + + ($cb:expr, $descr:expr, $lhs:expr => $rhs:expr) => {{ + let rhs = $rhs.to_expr_vec(); + if rhs.len() == 1 { + $cb.require_equal( + Box::leak($descr.to_string().into_boxed_str()), + $lhs.expr(), + rhs[0].expr(), + ); + } else { + $cb.require_in_set( + Box::leak($descr.to_string().into_boxed_str()), + $lhs.expr(), + rhs.clone(), + ); + } + }}; + + // Lookup using a tuple + ($cb:expr, ($($v:expr),+) => @$tag:expr) => {{ + $cb.lookup( + concat_with_preamble!( + "(", + $( + stringify!($v), + ", ", + )* + ") => @", + stringify!($tag), + ), + $tag.to_string(), + vec![$($v.expr(),)*], + ); + }}; + ($cb:expr, $descr:expr, ($($v:expr),+) => @$tag:expr) => {{ + $cb.lookup( + Box::leak($descr.into_boxed_str()), + $tag.to_string(), + vec![$($v.expr(),)*], + ); + }}; + + // Lookup using an array + ($cb:expr, $values:expr => @$tag:expr) => {{ + $cb.lookup( + concat_with_preamble!( + stringify!($values), + " => @", + stringify!($tag), + ), + $tag.to_string(), + $values.clone(), + ); + }}; + ($cb:expr, $descr:expr, $values:expr => @$tag:expr) => {{ + $cb.lookup( + Box::leak($descr.to_string().into_boxed_str()), + $tag.to_string(), + $values.clone(), + ); + }}; + + // Put values in a lookup table using a tuple + ($cb:expr, @$tag:expr => ($($v:expr),+)) => {{ + $cb.lookup_table( + concat_with_preamble!( + "@", + stringify!($tag), + " => (", + $( + stringify!($v), + ", ", + )* + ")", + ), + $tag.to_string(), + vec![$($v.expr(),)*], + ); + }}; + // Put values in a lookup table using an array + ($cb:expr, @$tag:expr => $values:expr) => {{ + $cb.lookup_table( + concat_with_preamble!( + "@", + stringify!($tag), + " => (", + stringify!($values), + ")", + ), + $tag.to_string(), + $values, + ); + }}; +} + +/// matchx +/// Supports `_` which works the same as in the normal `match`: if none of the +/// other arms are active the `_` arm will be executed and so can be used to +/// return some default values or could also be marked as unreachable (using the +/// unreachablex! macro). +#[macro_export] +macro_rules! _matchx { + ($cb:expr, $($condition:expr => $when:expr),* $(, _ => $catch_all:expr)? $(,)?) => {{ + let mut conditions = Vec::new(); + let mut cases = Vec::new(); + $( + $cb.push_condition($condition.expr()); + let ret = $when.clone(); + $cb.pop_condition(); + cases.push(($condition.expr(), ret)); + conditions.push($condition.expr()); + )* + + $( + let catch_all_condition = not::expr(sum::expr(&conditions)); + $cb.push_condition(catch_all_condition.expr()); + let ret = $catch_all; + $cb.pop_condition(); + cases.push((catch_all_condition.expr(), ret)); + conditions.push(catch_all_condition.expr()); + )* + + // All conditions need to be boolean + for condition in conditions.iter() { + _require!($cb, condition => bool); + } + // Exactly 1 case needs to be enabled + _require!($cb, sum::expr(&conditions) => 1); + + cases.apply_conditions() + }}; +} + +/// ifx +#[macro_export] +macro_rules! _ifx { + ($cb:expr, $($condition:expr),* => $when_true:block $(elsex $when_false:block)?) => {{ + let condition = and::expr([$($condition.expr()),*]); + + $cb.push_condition(condition.expr()); + let ret_true = $when_true.clone(); + $cb.pop_condition(); + + #[allow(unused_assignments, unused_mut)] + let mut ret = ret_true.conditional(condition.expr()); + $( + // In if/else cases, the condition needs to be boolean + _require!($cb, condition => bool); + + $cb.push_condition(not::expr(condition.expr())); + let ret_false = $when_false; + $cb.pop_condition(); + + ret = ret_true.select(condition.expr(), &ret_false); + )* + ret + }}; +} + +/// matchr +#[macro_export] +macro_rules! matchr { + ($($condition:expr => $when:expr),* $(, _ => $catch_all:expr)? $(,)?) => {{ + $( + if $condition { + return $when; + } + )* + $( + return $catch_all; + )* + unreachable!(); + }}; +} + +/// matchw +#[macro_export] +macro_rules! matchw { + ($($condition:expr => $when:expr),* $(, _ => $catch_all:expr)? $(,)?) => {{ + $( + if $condition { + $when + } + )* + $( + $catch_all + )* + }}; +} + + +/// Circuit builder macros +/// Nested macro's can't do repetition (https://github.com/rust-lang/rust/issues/35853) +/// so we expose a couple of permutations here manually. +#[macro_export] +macro_rules! circuit { + ([$meta:expr, $cb:expr], $content:block) => {{ + #[allow(unused_imports)] + use $crate::{concat_with_preamble, _require, _matchx, _ifx, _unreachablex}; + #[allow(unused_imports)] + use gadgets::util::{and, not, or, sum, Expr}; + #[allow(unused_imports)] + use $crate::circuit_tools::constraint_builder::{Conditionable, Expressable, Selectable}; + + #[allow(unused_macros)] + macro_rules! f { + ($column:expr, $rot:expr) => {{ + $meta.query_fixed($column.clone(), Rotation($cb.get_query_offset() + ($rot as i32))) + }}; + ($column:expr) => {{ + $meta.query_fixed($column.clone(), Rotation($cb.get_query_offset())) + }}; + } + + #[allow(unused_macros)] + macro_rules! a { + ($column:expr, $rot:expr) => {{ + $meta.query_advice($column.clone(), Rotation($cb.get_query_offset() + ($rot as i32))) + }}; + ($column:expr) => {{ + $meta.query_advice($column.clone(), Rotation($cb.get_query_offset())) + }}; + } + + #[allow(unused_macros)] + macro_rules! not { + ($expr:expr) => {{ + gadgets::util::not::expr($expr.expr()) + }}; + } + + #[allow(unused_macros)] + macro_rules! invert { + ($expr:expr) => {{ + Expression::Constant(F::from($expr as u64).invert().unwrap()) + }}; + } + + #[allow(unused_macros)] + macro_rules! require { + ($lhs:expr => bool) => {{ + _require!($cb, $lhs => bool); + }}; + + ($lhs:expr => $rhs:expr) => {{ + _require!($cb, $lhs => $rhs); + }}; + + ($name:expr, $lhs:expr => $rhs:expr) => {{ + _require!($cb, $name, $lhs => $rhs); + }}; + + (($a:expr) => @$tag:expr) => {{ + _require!($cb, ($a) => @$tag); + }}; + + (($a:expr, $b:expr) => @$tag:expr) => {{ + _require!($cb, ($a, $b) => @$tag); + }}; + + (($a:expr, $b:expr, $c:expr) => @$tag:expr) => {{ + _require!($cb, ($a, $b, $c) => @$tag); + }}; + + (($a:expr, $b:expr, $c:expr, $d:expr) => @$tag:expr) => {{ + _require!($cb, ($a, $b, $c, $d) => @$tag); + }}; + + ($values:expr => @$tag:expr) => {{ + _require!($cb, $values => @$tag); + }}; + + ($descr:expr, $values:expr => @$tag:expr) => {{ + _require!($cb, $descr, $values => @$tag); + }}; + + (@$tag:expr => ($a:expr, $b:expr, $c:expr)) => {{ + _require!($cb, @$tag => ($a, $b, $c)); + }}; + + (@$tag:expr => $values:expr) => {{ + _require!($cb, @$tag => $values); + }}; + } + + #[allow(unused_macros)] + macro_rules! ifx { + ($condition:expr => $when_true:block elsex $when_false:block) => {{ + _ifx!($cb, $condition => $when_true elsex $when_false) + }}; + ($condition_a:expr, $condition_b:expr => $when_true:block elsex $when_false:block) => {{ + _ifx!($cb, $condition_a, $condition_b => $when_true elsex $when_false) + }}; + ($condition_a:expr, $condition_b:expr, $condition_c:expr => $when_true:block elsex $when_false:block) => {{ + _ifx!($cb, $condition_a, $condition_b, $condition_c => $when_true elsex $when_false) + }}; + ($condition_a:expr, $condition_b:expr, $condition_c:expr, $condition_d:expr => $when_true:block elsex $when_false:block) => {{ + _ifx!($cb, $condition_a, $condition_b, $condition_c, $condition_d => $when_true elsex $when_false) + }}; + + ($condition:expr => $when_true:block) => {{ + _ifx!($cb, $condition => $when_true) + }}; + ($condition_a:expr, $condition_b:expr => $when_true:block) => {{ + _ifx!($cb, $condition_a, $condition_b => $when_true) + }}; + ($condition_a:expr, $condition_b:expr, $condition_c:expr => $when_true:block) => {{ + _ifx!($cb, $condition_a, $condition_b, $condition_c => $when_true) + }}; + ($condition_a:expr, $condition_b:expr, $condition_c:expr, $condition_d:expr => $when_true:block) => {{ + _ifx!($cb, $condition_a, $condition_b, $condition_c, $condition_d => $when_true) + }}; + ($condition_a:expr, $condition_b:expr, $condition_c:expr, $condition_d:expr, $condition_e:expr => $when_true:block) => {{ + _ifx!($cb, $condition_a, $condition_b, $condition_c, $condition_d, $condition_e => $when_true) + }}; + } + + #[allow(unused_macros)] + macro_rules! matchx { + ($condition_a:expr => $when_a:expr,) => {{ + _matchx!($cb, $condition_a => $when_a) + }}; + ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr,) => {{ + _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b) + }}; + ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, $condition_c:expr => $when_c:expr,) => {{ + _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, $condition_c => $when_c) + }}; + ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, $condition_c:expr => $when_c:expr, $condition_d:expr => $when_d:expr,) => {{ + _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, $condition_c => $when_c, $condition_d => $when_d,) + }}; + + ($condition_a:expr => $when_a:expr, _ => $catch_all:expr,) => {{ + _matchx!($cb, $condition_a => $when_a, _ => $catch_all,) + }}; + ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, _ => $catch_all:expr,) => {{ + _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, _ => $catch_all,) + }}; + ($condition_a:expr => $when_a:expr, $condition_b:expr => $when_b:expr, $condition_c:expr => $when_c:expr, _ => $catch_all:expr,) => {{ + _matchx!($cb, $condition_a => $when_a, $condition_b => $when_b, $condition_c => $when_c, _ => $catch_all,) + }}; + } + + #[allow(unused_macros)] + macro_rules! unreachablex { + () => {{ + _unreachablex!($cb) + }}; + ($arg:expr) => {{ + _unreachablex!($cb, $arg) + }}; + } + + $content + }}; +} + +macro_rules! witness { + ($name:ident, $t:ty) => {{ + match objects[0].as_any().downcast_ref::<$t>() { + Some(b) => b, + None => panic!("&a isn't a B!"), + } + }}; +} diff --git a/zkevm-circuits/src/circuit_tools/gadgets.rs b/zkevm-circuits/src/circuit_tools/gadgets.rs new file mode 100644 index 0000000000..95e6732221 --- /dev/null +++ b/zkevm-circuits/src/circuit_tools/gadgets.rs @@ -0,0 +1,189 @@ +//! Circuit gadgets +use eth_types::Field; +use gadgets::util::Expr; +use halo2_proofs::{ + circuit::{Region}, + plonk::{Error, Expression}, +}; + +use crate::evm_circuit::util::{from_bytes, pow_of_two}; + +use super::{constraint_builder::ConstraintBuilder, cell_manager::{Cell}}; + +/// Returns `1` when `value == 0`, and returns `0` otherwise. +#[derive(Clone, Debug, Default)] +pub struct IsZeroGadget { + inverse: Cell, + is_zero: Option>, +} + +impl IsZeroGadget { + pub(crate) fn construct(cb: &mut ConstraintBuilder, value: Expression) -> Self { + circuit!([meta, cb], { + let inverse = cb.query_cell(); + + let is_zero = 1.expr() - (value.expr() * inverse.expr()); + // `value != 0` => check `inverse = a.invert()`: value * (1 - value * inverse) + require!(value * is_zero.clone() => 0); + // `value == 0` => check `inverse = 0`: `inverse â‹… (1 - value * inverse)` + require!(inverse.expr() * is_zero.expr() => 0); + + Self { inverse, is_zero: Some(is_zero) } + }) + + } + + pub(crate) fn expr(&self) -> Expression { + self.is_zero.as_ref().unwrap().clone() + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + value: F, + ) -> Result { + let inverse = value.invert().unwrap_or(F::zero()); + self.inverse.assign(region, offset, inverse)?; + Ok(if value.is_zero().into() { + F::one() + } else { + F::zero() + }) + } +} + +/// Verifies that the value is non-zero. +#[derive(Clone, Debug, Default)] +pub struct RequireNotZeroGadget { + inverse: Cell, +} + +impl RequireNotZeroGadget { + pub(crate) fn construct(cb: &mut ConstraintBuilder, value: Expression) -> Self { + circuit!([meta, cb], { + let inverse = cb.query_cell(); + require!(value.expr() * inverse.expr() =>1); + Self { inverse } + }) + + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + value: F, + ) -> Result<(), Error> { + let inverse = value.invert().unwrap_or(F::zero()); + self.inverse.assign(region, offset, inverse)?; + Ok(()) + } +} + +/// Returns `1` when `lhs == rhs`, and returns `0` otherwise. +#[derive(Clone, Debug, Default)] +pub struct IsEqualGadget { + is_zero: IsZeroGadget, +} + +impl IsEqualGadget { + pub(crate) fn construct( + cb: &mut ConstraintBuilder, + lhs: Expression, + rhs: Expression, + ) -> Self { + let is_zero = IsZeroGadget::construct(cb, lhs - rhs); + + Self { is_zero } + } + + pub(crate) fn expr(&self) -> Expression { + self.is_zero.expr() + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + lhs: F, + rhs: F, + ) -> Result { + self.is_zero.assign(region, offset, lhs - rhs) + } +} + +/// Returns `1` when `lhs < rhs`, and returns `0` otherwise. +/// lhs and rhs `< 256**N_BYTES` +/// `N_BYTES` is required to be `<= MAX_N_BYTES_INTEGER` to prevent overflow: +/// values are stored in a single field element and two of these are added +/// together. +/// The equation that is enforced is `lhs - rhs == diff - (lt * range)`. +/// Because all values are `<= 256**N_BYTES` and `lt` is boolean, `lt` can only +/// be `1` when `lhs < rhs`. +#[derive(Clone, Debug, Default)] +pub struct LtGadget { + lt: Cell, // `1` when `lhs < rhs`, `0` otherwise. + diff: Option<[Cell; N_BYTES]>, /* The byte values of `diff`. + * `diff` equals `lhs - rhs` if `lhs >= rhs`, + * `lhs - rhs + range` otherwise. */ + range: F, // The range of the inputs, `256**N_BYTES` +} + +impl LtGadget { + pub(crate) fn construct( + cb: &mut ConstraintBuilder, + lhs: Expression, + rhs: Expression, + ) -> Self { + let lt = cb.query_bool(); + let diff = cb.query_bytes(); + let range = pow_of_two(N_BYTES * 8); + + // The equation we require to hold: `lhs - rhs == diff - (lt * range)`. + cb.require_equal( + "lhs - rhs == diff - (lt â‹… range)", + lhs - rhs, + from_bytes::expr(&diff) - (lt.expr() * range), + ); + + Self { lt, diff: Some(diff), range } + } + + pub(crate) fn expr(&self) -> Expression { + self.lt.expr() + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + lhs: F, + rhs: F, + ) -> Result<(F, Vec), Error> { + // Set `lt` + let lt = lhs < rhs; + self.lt.assign( + region, + offset, + if lt { F::one() } else { F::zero() }, + )?; + + // Set the bytes of diff + let diff = (lhs - rhs) + (if lt { self.range } else { F::zero() }); + let diff_bytes = diff.to_repr(); + for (idx, diff) in self.diff.as_ref().unwrap().iter().enumerate() { + diff.assign( + region, + offset, + F::from(diff_bytes[idx] as u64), + )?; + } + + Ok((if lt { F::one() } else { F::zero() }, diff_bytes.to_vec())) + } + + pub(crate) fn diff_bytes(&self) -> Vec> { + self.diff.as_ref().unwrap().to_vec() + } +} \ No newline at end of file diff --git a/zkevm-circuits/src/circuit_tools/memory.rs b/zkevm-circuits/src/circuit_tools/memory.rs new file mode 100644 index 0000000000..e68dcf637a --- /dev/null +++ b/zkevm-circuits/src/circuit_tools/memory.rs @@ -0,0 +1,258 @@ +//! Memory +use crate::util::{query_expression, Expr}; +use eth_types::Field; +use halo2_proofs::{ + circuit::{Layouter, Value}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression}, + poly::Rotation, +}; +use std::{ + marker::PhantomData, + ops::{Index, IndexMut}, +}; + +use super::constraint_builder::ConstraintBuilder; + +#[derive(Clone, Debug, Default)] +pub(crate) struct Memory { + columns: Vec>, + banks: Vec>, +} + +impl Memory { + pub(crate) fn new(columns: Vec>) -> Self { + Self { + columns, + banks: Vec::new(), + } + } + + pub(crate) fn allocate>( + &mut self, + meta: &mut ConstraintSystem, + tag: S, + ) -> &MemoryBank { + self.banks + .push(MemoryBank::new(meta, self.columns[self.banks.len()], tag)); + self.banks.last().unwrap() + } + + pub(crate) fn get>(&self, tag: S) -> &MemoryBank { + for bank in self.banks.iter() { + if bank.tag() == tag.as_ref() { + return bank; + } + } + unreachable!() + } + + pub(crate) fn get_mut>(&mut self, tag: S) -> &mut MemoryBank { + for bank in self.banks.iter_mut() { + if bank.tag() == tag.as_ref() { + return bank; + } + } + unreachable!() + } + + pub(crate) fn generate_constraints(&self, cb: &mut ConstraintBuilder) { + for bank in self.banks.iter() { + bank.generate_constraints(cb); + cb.generate_lookup_table_checks(bank.tag()); + + /*let lookups = cb.consume_lookups(&[bank.tag()]); + if !lookups.is_empty() { + //println!("{}: {}", tag, lookups.len()); + let (_, values) = merge_lookups(cb, lookups); + crate::circuit!([meta, cb], { + require!(values => @bank.tag()); + }) + }*/ + } + } + + pub(crate) fn clear_witness_data(&mut self) { + for bank in self.banks.iter_mut() { + bank.clear_witness_data(); + } + } + + pub(crate) fn assign( + &self, + layouter: &mut impl Layouter, + height: usize, + ) -> Result<(), Error> { + for bank in self.banks.iter() { + bank.assign(layouter, height)?; + } + Ok(()) + } + + pub(crate) fn tags(&self) -> Vec { + self.banks.iter().map(|bank| bank.tag()).collect() + } +} + +impl> Index for Memory { + type Output = MemoryBank; + + fn index(&self, tag: S) -> &Self::Output { + for bank in self.banks.iter() { + if bank.tag() == tag.as_ref() { + return bank; + } + } + unreachable!() + } +} + +impl> IndexMut for Memory { + fn index_mut(&mut self, tag: S) -> &mut Self::Output { + for bank in self.banks.iter_mut() { + if bank.tag() == tag.as_ref() { + return bank; + } + } + unreachable!() + } +} + +#[derive(Clone, Debug)] +pub(crate) struct MemoryBank { + column: Column, + tag: String, + cur: Expression, + next: Expression, + store_offsets: Vec, + stored_values: Vec>, + _marker: PhantomData, +} + +impl MemoryBank { + pub(crate) fn new>( + meta: &mut ConstraintSystem, + column: Column, + tag: S, + ) -> Self { + let mut cur = 0.expr(); + let mut next = 0.expr(); + query_expression(meta, |meta| { + cur = meta.query_advice(column, Rotation::cur()); + next = meta.query_advice(column, Rotation::next()); + }); + Self { + column, + tag: tag.as_ref().to_owned(), + cur, + next, + store_offsets: Vec::new(), + stored_values: Vec::new(), + _marker: PhantomData, + } + } + + pub(crate) fn key(&self) -> Expression { + self.cur.expr() + } + + pub(crate) fn load( + &self, + description: &'static str, + cb: &mut ConstraintBuilder, + offset: Expression, + values: &[Expression], + ) { + self.load_with_key(description, cb, self.key() - offset, values); + } + + pub(crate) fn load_with_key( + &self, + description: &'static str, + cb: &mut ConstraintBuilder, + key: Expression, + values: &[Expression], + ) { + let mut key_values = values.to_vec(); + key_values.insert(0, key); + cb.lookup(description, self.tag(), values.to_vec()); + } + + pub(crate) fn store(&self, cb: &mut ConstraintBuilder, values: &[Expression]) { + self.store_with_key(cb, self.key() + 1.expr(), values); + } + + pub(crate) fn store_with_key( + &self, + cb: &mut ConstraintBuilder, + key: Expression, + values: &[Expression], + ) { + let mut key_values = values.to_vec(); + key_values.insert(0, key); + cb.lookup_table("memory store", self.tag(), values.to_vec()); + } + + pub(crate) fn witness_store(&mut self, offset: usize, values: &[F]) { + self.stored_values.push(values.to_vec()); + self.store_offsets.push(offset); + } + + pub(crate) fn witness_store_init(&mut self, values: &[F]) { + self.stored_values.push(values.to_vec()); + } + + pub(crate) fn witness_load(&self, offset: usize) -> Vec { + self.stored_values[self.stored_values.len() - 1 - offset].clone() + } + + pub(crate) fn clear_witness_data(&mut self) { + self.store_offsets.clear(); + } + + pub(crate) fn generate_constraints(&self, cb: &mut ConstraintBuilder) { + let lookup_table = cb.get_lookup_table(self.tag()); + crate::circuit!([meta, cb], { + // TODO(Brecht): fix + //require!(self.next => self.cur.expr() + lookup_table.0); + }); + } + + pub(crate) fn assign( + &self, + layouter: &mut impl Layouter, + height: usize, + ) -> Result<(), Error> { + layouter.assign_region( + || "memory bank", + |mut region| { + // Pad to the full circuit (necessary for reads) + let mut store_offsets = self.store_offsets.clone(); + store_offsets.push(height); + + //println!("offsets: {:?}", self.store_offsets); + + //println!("height: {}", height); + let mut store_index = 0; + let mut offset = 0; + for &stored_offset in store_offsets.iter() { + while offset <= stored_offset { + region.assign_advice( + || "assign memory index".to_string(), + self.column, + offset, + || Value::known(F::from(store_index as u64)), + )?; + //println!("[{}] {}: {}", self.tag(), offset, store_index); + offset += 1; + } + store_index += 1; + } + Ok(()) + }, + ) + } + + pub(crate) fn tag(&self) -> String { + self.tag.clone() + } +} diff --git a/zkevm-circuits/src/lib.rs b/zkevm-circuits/src/lib.rs index 6eef9b7436..1419a8a729 100644 --- a/zkevm-circuits/src/lib.rs +++ b/zkevm-circuits/src/lib.rs @@ -29,7 +29,6 @@ pub mod table; #[cfg(any(feature = "test", test))] pub mod test_util; -#[macro_use] pub mod circuit_tools; pub mod tx_circuit; pub mod util; diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index 613370ab48..efa337a99a 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -2,7 +2,6 @@ use eth_types::Field; use gadgets::impl_expr; use halo2_proofs::{ - arithmetic::FieldExt, circuit::{Layouter, Region, SimpleFloorPlanner, Value}, plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells}, poly::Rotation, @@ -32,8 +31,7 @@ use selectors::SelectorsConfig; use crate::{ circuit, - circuit_tools::{merge_lookups, Memory}, - evm_circuit::util::rlc, + circuit_tools::{cell_manager::CellManager, constraint_builder::{merge_lookups, RLCable}, memory::Memory}, mpt_circuit::{ helpers::{extend_rand, parent_memory, KeyData, MPTConstraintBuilder, ParentData}, storage_leaf::StorageLeafConfig, @@ -72,7 +70,6 @@ use self::{account_leaf::AccountLeafConfig, columns::MPTTable, helpers::key_memo */ /// Merkle Patricia Trie config. -#[derive(Debug)] pub struct RowConfig { branch_config: BranchConfig, storage_config: StorageLeafConfig, @@ -82,6 +79,7 @@ pub struct RowConfig { /// Merkle Patricia Trie context #[derive(Clone, Debug)] pub struct MPTContext { + pub(crate) mpt_table: MPTTable, pub(crate) proof_type: ProofTypeCols, pub(crate) position_cols: PositionCols, pub(crate) inter_start_root: Column, @@ -101,7 +99,7 @@ pub struct MPTContext { pub(crate) memory: Memory, } -impl MPTContext { +impl MPTContext { pub(crate) fn main(&self, is_s: bool) -> MainCols { if is_s { self.s_main @@ -124,19 +122,24 @@ impl MPTContext { .to_vec() } + pub(crate) fn expr( + &self, + meta: &mut VirtualCells, + rot: i32, + ) -> Vec> { + self.rlp_bytes() + .iter() + .map(|&byte| meta.query_advice(byte, Rotation(rot))) + .collect::>() + } + pub(crate) fn rlc( &self, meta: &mut VirtualCells, range: Range, rot: i32, ) -> Expression { - rlc::expr( - &self.rlp_bytes()[range] - .iter() - .map(|&byte| meta.query_advice(byte, Rotation(rot))) - .collect::>(), - &self.r, - ) + self.expr(meta, rot)[range].rlc(&self.r) } pub(crate) fn is_account(&self, meta: &mut VirtualCells, rot_above: i32) -> Expression { @@ -145,7 +148,7 @@ impl MPTContext { } /// Merkle Patricia Trie config. -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct MPTConfig { pub(crate) proof_type: ProofTypeCols, pub(crate) position_cols: PositionCols, @@ -176,6 +179,7 @@ pub struct MPTConfig { account_config: AccountLeafConfig, pub(crate) randomness: F, pub(crate) mpt_table: MPTTable, + cb: MPTConstraintBuilder, } /// Enumerator to determine the type of row in the fixed table. @@ -285,7 +289,7 @@ pub(crate) struct ProofValues { pub(crate) memory: Memory, } -impl ProofValues { +impl ProofValues { fn new(memory: &Memory) -> Self { Self { memory: memory.clone(), @@ -299,7 +303,7 @@ impl ProofValues { } } -impl MPTConfig { +impl MPTConfig { /// Configure MPT Circuit pub fn configure( meta: &mut ConstraintSystem, @@ -379,7 +383,18 @@ impl MPTConfig { let address_rlc = meta.advice_column(); + let mpt_table = MPTTable { + address_rlc, + proof_type: proof_type.proof_type, + key_rlc: accumulators.key.mult, + value_prev, + value, + root_prev: inter_start_root, + root: inter_final_root, + }; + let ctx = MPTContext { + mpt_table: mpt_table.clone(), proof_type: proof_type.clone(), position_cols: position_cols.clone(), inter_start_root: inter_start_root.clone(), @@ -401,8 +416,11 @@ impl MPTConfig { let mut row_config: Option> = None; - let mut cb = MPTConstraintBuilder::new(17); + let mut cb = MPTConstraintBuilder::new(17, None); meta.create_gate("MPT", |meta| { + let cell_manager = CellManager::new(meta, &ctx.managed_columns); + cb.base.set_cell_manager(cell_manager); + circuit!([meta, cb.base], { /* General */ SelectorsConfig::configure(meta, &mut cb, ctx.clone()); @@ -537,22 +555,16 @@ impl MPTConfig { ); } else if disable_lookups == 2 { cb.base.generate_lookups(meta, &ctx.memory.tags()); + } else if disable_lookups == 3 { + cb.base.generate_lookups(meta, &vec!["fixed".to_string(), "keccak".to_string()]); + } else if disable_lookups == 4 { + cb.base.generate_lookups(meta, &vec!["keccak".to_string()]); } println!("num lookups: {}", meta.lookups().len()); println!("num advices: {}", meta.num_advice_columns()); println!("num fixed: {}", meta.num_fixed_columns()); - let mpt_table = MPTTable { - address_rlc, - proof_type: proof_type.proof_type, - key_rlc: accumulators.key.mult, - value_prev, - value, - root_prev: inter_start_root, - root: inter_final_root, - }; - let row_config = row_config.unwrap(); let randomness = F::zero(); MPTConfig { @@ -579,6 +591,7 @@ impl MPTConfig { account_config: row_config.account_config, randomness, mpt_table, + cb, } } @@ -852,67 +865,55 @@ impl MPTConfig { row }; - if offset > 0 && prev_row.get_type() == MptWitnessRowType::InitBranch { - self.branch_config - .assign(&mut region, witness, self, &mut pv, offset) - .ok(); - - offset += 1; - } else if row.get_type() == MptWitnessRowType::BranchChild { - offset += 1; - } else { - // leaf s or leaf c or leaf key s or leaf key c - let mut account_leaf = AccountLeaf::default(); - let mut storage_leaf = StorageLeaf::default(); - let mut branch = Branch::default(); - - if row.get_type() == MptWitnessRowType::StorageLeafSKey { - storage_leaf.is_s_key = true; - } else if row.get_type() == MptWitnessRowType::StorageLeafCKey { - storage_leaf.is_c_key = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafKeyS { - account_leaf.is_key_s = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { - account_leaf.is_key_c = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS - { - account_leaf.is_nonce_balance_s = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceC - { - account_leaf.is_nonce_balance_c = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafRootCodehashS - { - account_leaf.is_storage_codehash_s = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafRootCodehashC - { - account_leaf.is_storage_codehash_c = true; - } else if row.get_type() - == MptWitnessRowType::AccountLeafNeighbouringLeaf - { - account_leaf.is_in_added_branch = true; - pv.key_rlc = F::zero(); // account address until here, storage key from here on - pv.key_rlc_mult = F::one(); - pv.key_rlc_prev = F::zero(); - pv.key_rlc_mult_prev = F::one(); - pv.nibbles_num_prev = 0; - pv.key_rlc_sel = true; - pv.nibbles_num = 0; - } else if row.get_type() == MptWitnessRowType::StorageLeafSValue { - storage_leaf.is_s_value = true; - } else if row.get_type() == MptWitnessRowType::StorageLeafCValue { - storage_leaf.is_c_value = true; - } else if row.get_type() == MptWitnessRowType::NeighbouringStorageLeaf { - storage_leaf.is_in_added_branch = true; - } else if row.get_type() == MptWitnessRowType::StorageNonExisting { - storage_leaf.is_non_existing = true; - } else if row.get_type() == MptWitnessRowType::ExtensionNodeS { - branch.is_extension_node_s = true; - } else if row.get_type() == MptWitnessRowType::ExtensionNodeC { - branch.is_extension_node_c = true; - } else if row.get_type() == MptWitnessRowType::AccountNonExisting { - account_leaf.is_non_existing_account_row = true; - } + // leaf s or leaf c or leaf key s or leaf key c + let mut account_leaf = AccountLeaf::default(); + let mut storage_leaf = StorageLeaf::default(); + let mut branch = Branch::default(); + + if row.get_type() == MptWitnessRowType::StorageLeafSKey { + storage_leaf.is_s_key = true; + } else if row.get_type() == MptWitnessRowType::StorageLeafCKey { + storage_leaf.is_c_key = true; + } else if row.get_type() == MptWitnessRowType::AccountLeafKeyS { + account_leaf.is_key_s = true; + } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { + account_leaf.is_key_c = true; + } else if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { + account_leaf.is_nonce_balance_s = true; + } else if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceC { + account_leaf.is_nonce_balance_c = true; + } else if row.get_type() == MptWitnessRowType::AccountLeafRootCodehashS { + account_leaf.is_storage_codehash_s = true; + } else if row.get_type() == MptWitnessRowType::AccountLeafRootCodehashC { + account_leaf.is_storage_codehash_c = true; + } else if row.get_type() == MptWitnessRowType::AccountLeafNeighbouringLeaf { + account_leaf.is_in_added_branch = true; + pv.key_rlc = F::zero(); // account address until here, storage key from here on + pv.key_rlc_mult = F::one(); + pv.key_rlc_prev = F::zero(); + pv.key_rlc_mult_prev = F::one(); + pv.nibbles_num_prev = 0; + pv.key_rlc_sel = true; + pv.nibbles_num = 0; + } else if row.get_type() == MptWitnessRowType::StorageLeafSValue { + storage_leaf.is_s_value = true; + } else if row.get_type() == MptWitnessRowType::StorageLeafCValue { + storage_leaf.is_c_value = true; + } else if row.get_type() == MptWitnessRowType::NeighbouringStorageLeaf { + storage_leaf.is_in_added_branch = true; + } else if row.get_type() == MptWitnessRowType::StorageNonExisting { + storage_leaf.is_non_existing = true; + } else if row.get_type() == MptWitnessRowType::ExtensionNodeS { + branch.is_extension_node_s = true; + } else if row.get_type() == MptWitnessRowType::ExtensionNodeC { + branch.is_extension_node_c = true; + } else if row.get_type() == MptWitnessRowType::AccountNonExisting { + account_leaf.is_non_existing_account_row = true; + } + if !(row.get_type() == MptWitnessRowType::InitBranch + || row.get_type() == MptWitnessRowType::BranchChild) + { row.assign( &mut region, self, @@ -921,28 +922,31 @@ impl MPTConfig { branch, offset, )?; + } - // Storage leaf key - if row.get_type() == MptWitnessRowType::StorageLeafSKey { - self.storage_config.assign( - &mut region, - self, - witness, - &mut pv, - offset, - )?; - } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { - self.account_config.assign( - &mut region, - self, - witness, - &mut pv, - offset, - )?; - } - - offset += 1; + if offset > 0 && prev_row.get_type() == MptWitnessRowType::InitBranch { + self.branch_config + .assign(&mut region, witness, self, &mut pv, offset) + .ok(); + } else if row.get_type() == MptWitnessRowType::StorageLeafSKey { + self.storage_config.assign( + &mut region, + self, + witness, + &mut pv, + offset, + )?; + } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { + self.account_config.assign( + &mut region, + self, + witness, + &mut pv, + offset, + )?; } + + offset += 1; } memory = pv.memory; @@ -1140,7 +1144,7 @@ mod tests { use super::*; - use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr}; + use halo2_proofs::{dev::MockProver, halo2curves::{bn256::Fr, FieldExt}}; use std::fs; diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index a2316b9e86..fd5933813e 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -1,5 +1,5 @@ +use eth_types::Field; use halo2_proofs::{ - arithmetic::FieldExt, plonk::{Advice, Column, ConstraintSystem, Expression}, }; use halo2_proofs::{ @@ -11,14 +11,15 @@ use std::marker::PhantomData; use crate::{ circuit, - circuit_tools::{Cell, CellManager, CellType, ConstraintBuilder, DataTransition, RLCable}, + circuit_tools::cell_manager::{Cell, DataTransition}, + circuit_tools::constraint_builder::{ConstraintBuilder, RLCable}, mpt_circuit::{ - helpers::BranchNodeInfo, + helpers::{BranchNodeInfo, get_num_bytes_short}, param::{BRANCH_ROWS_NUM, S_START}, }, mpt_circuit::{ helpers::{ - get_num_bytes_short, get_num_nibbles, get_parent_rlc_state, key_memory, parent_memory, + get_num_nibbles, get_parent_rlc_state, key_memory, parent_memory, AccountLeafInfo, KeyData, MPTConstraintBuilder, ParentData, }, param::{KEY_LEN_IN_NIBBLES, RLP_HASH_VALUE, RLP_LIST_LONG, RLP_LONG}, @@ -54,7 +55,7 @@ pub(crate) struct AccountLeafCols { _marker: PhantomData, } -impl AccountLeafCols { +impl AccountLeafCols { pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { Self { is_key_s: meta.advice_column(), @@ -117,7 +118,7 @@ pub(crate) struct AccountLeafConfig { diff_inv: Cell, } -impl AccountLeafConfig { +impl AccountLeafConfig { pub fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, @@ -142,7 +143,7 @@ impl AccountLeafConfig { let rot_first_child = offset - BRANCH_ROWS_NUM + 1; let rot_branch_init = rot_first_child - 1; - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + cb.base.cell_manager.as_mut().unwrap().reset(); let mut ctx_key_data_s: Option> = None; let mut ctx_key_data_c: Option> = None; let mut ctx_key_data_w: Option> = None; @@ -167,12 +168,8 @@ impl AccountLeafConfig { // Load the last key values, which depends on the branch being a placeholder. let is_branch_placeholder = ifx! {f!(ctx.position_cols.q_not_first), a!(not_first_level) => { branch.is_placeholder() }}; let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; - let key_data = KeyData::load( - &mut cb.base, - &mut cm, - &ctx.memory[key_memory(is_s)], - load_offset, - ); + let key_data = + KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], load_offset); // Calculate the key RLC let key_rlc = key_data.rlc.expr() @@ -188,7 +185,7 @@ impl AccountLeafConfig { // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES. let key_len = account.key_len(meta); - let num_nibbles = get_num_nibbles(meta, key_len.expr(), key_data.is_odd.expr()); + let num_nibbles = get_num_nibbles(key_len.expr(), key_data.is_odd.expr()); require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); // Key done, set the starting values @@ -256,13 +253,13 @@ impl AccountLeafConfig { require!(account.is_wrong_leaf(meta, true) => bool); ifx! {a!(proof_type.is_non_existing_account_proof, offset) => { - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 1.expr()); + let key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 1.expr()); ifx! {account.is_wrong_leaf(meta, true) => { // Calculate the key and check it's the address as requested in the lookup let key_rlc_wrong = key_data.rlc.expr() + account.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), offset - rot_key_s); require!(a!(address_rlc, offset) => key_rlc_wrong); // Now make sure this address is different than the one of the leaf - let diff_inv = cm.query_cell(CellType::Storage); + let diff_inv = cb.base.query_cell(); require!((a!(address_rlc, offset) - a!(accs.key.rlc, rot_key_s)) * diff_inv.expr() => 1); // Make sure the lengths of the keys are the same let account_wrong = AccountLeafInfo::new(meta, ctx.clone(), offset); @@ -308,7 +305,7 @@ impl AccountLeafConfig { require!(is_long => bool); // Calculate the RLC let (num_bytes, value_rlc) = ifx! {is_long => { - let num_bytes = get_num_bytes_short(a!(ctx.main(is_s).bytes[0], offset)); + let num_bytes = get_num_bytes_short::expr(a!(ctx.main(is_s).bytes[0], offset)); let value_rlc = ctx.main(is_s).bytes(meta, offset)[1..].to_vec().rlc(&r); (num_bytes, value_rlc) } elsex { @@ -449,7 +446,7 @@ impl AccountLeafConfig { // Check if the account is in its parent. let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let parent_data = ParentData::load("storage load", &mut cb.base, &mut cm, &ctx.memory[parent_memory(is_s)], 0.expr()); + let parent_data = ParentData::load("storage load", &mut cb.base, &ctx.memory[parent_memory(is_s)], 0.expr()); // Check is skipped for placeholder leafs which are dummy leafs ifx!{not!(and::expr(&[a!(ctx.position_cols.not_first_level, offset), not!(branch.is_placeholder()), branch.contains_placeholder_leaf(meta, is_s)])) => { let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); @@ -507,7 +504,7 @@ impl AccountLeafConfig { let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); // Load the last key values - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 2.expr()); + let key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 2.expr()); // TODO(Brecht): make this work with loaded key data when extension node is separate ifx! {not!(branch.is_extension()) => { @@ -715,9 +712,7 @@ impl AccountLeafConfig { let diff_inv = (address_rlc - pv.account_key_rlc) .invert() .unwrap_or(F::zero()); - self.diff_inv - .assign(region, base_offset, Value::known(diff_inv)) - .ok(); + self.diff_inv.assign(region, base_offset, diff_inv).ok(); if row.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1 { region diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index 73f9e8fb2f..b39e914ce8 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -1,5 +1,6 @@ +use eth_types::Field; use halo2_proofs::{ - arithmetic::FieldExt, + circuit::{Region, Value}, plonk::{Advice, Column, ConstraintSystem, Error, VirtualCells}, poly::Rotation, @@ -16,7 +17,10 @@ use super::{ }; use crate::{ circuit, - circuit_tools::{CellManager, DataTransition, RLCChainable, RLCable}, + circuit_tools::{ + cell_manager::{CellManager, DataTransition}, + constraint_builder::{RLCChainable, RLCable}, + }, mpt_circuit::account_leaf::AccountLeaf, mpt_circuit::helpers::bytes_into_rlc, mpt_circuit::{ @@ -75,7 +79,7 @@ pub(crate) struct BranchCols { _marker: PhantomData, } -impl BranchCols { +impl BranchCols { pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { Self { is_init: meta.advice_column(), @@ -100,7 +104,7 @@ pub(crate) struct BranchConfig { parent_data_c: ParentData, } -impl BranchConfig { +impl BranchConfig { pub fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, @@ -112,7 +116,7 @@ impl BranchConfig { let accs = ctx.accumulators; let r = ctx.r.clone(); - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); + cb.base.cell_manager.as_mut().unwrap().reset(); let mut ctx_key_data: Option> = None; let mut ctx_parent_data_s: Option> = None; let mut ctx_parent_data_c: Option> = None; @@ -314,7 +318,6 @@ impl BranchConfig { let parent_data = ParentData::load( "branch load", &mut cb.base, - &mut cm, &ctx.memory[parent_memory(is_s)], 0.expr(), ); @@ -506,7 +509,7 @@ impl BranchConfig { let key_len = ext.ext_key_len(meta, offset); // Calculate the number of nibbles let num_nibbles = - get_num_nibbles(meta, key_len.expr(), ext.is_key_part_in_ext_odd()); + get_num_nibbles(key_len.expr(), ext.is_key_part_in_ext_odd()); // Make sure the nibble counter is updated correctly let nibbles_count_prev = ifx! {f!(ctx.position_cols.q_not_first), not!(ext.is_below_account(meta)), not_first_level.expr() => { ext.nibbles_counter().prev() @@ -543,12 +546,7 @@ impl BranchConfig { require!(branch.is_key_odd() => bool); // Load the last key values - let key_data = KeyData::load( - &mut cb.base, - &mut cm, - &ctx.memory[key_memory(true)], - 0.expr(), - ); + let key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 0.expr()); // Calculate the extension node key RLC when in an extension node let key_rlc_post_ext = ifx! {branch.is_extension() => { diff --git a/zkevm-circuits/src/mpt_circuit/columns.rs b/zkevm-circuits/src/mpt_circuit/columns.rs index ef4ff0dd64..fe7965eab4 100644 --- a/zkevm-circuits/src/mpt_circuit/columns.rs +++ b/zkevm-circuits/src/mpt_circuit/columns.rs @@ -1,11 +1,11 @@ +use eth_types::Field; use halo2_proofs::{ - arithmetic::FieldExt, plonk::{Advice, Column, ConstraintSystem, Expression, Fixed, VirtualCells}, poly::Rotation, }; use std::{convert::TryInto, marker::PhantomData}; -use crate::{circuit_tools::RLCable, mpt_circuit::param::HASH_WIDTH}; +use crate::{circuit_tools::constraint_builder::RLCable, mpt_circuit::param::HASH_WIDTH}; /* This file contains columns that are not specific to any of account leaf, storage leaf, branch, @@ -38,7 +38,7 @@ pub(crate) struct ProofTypeCols { _marker: PhantomData, } -impl ProofTypeCols { +impl ProofTypeCols { pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { Self { proof_type: meta.advice_column(), @@ -63,7 +63,7 @@ pub(crate) struct MainCols { _marker: PhantomData, } -impl MainCols { +impl MainCols { pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { Self { rlp1: meta.advice_column(), @@ -114,7 +114,7 @@ pub(crate) struct AccumulatorPair { _marker: PhantomData, } -impl AccumulatorPair { +impl AccumulatorPair { pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { Self { rlc: meta.advice_column(), @@ -148,7 +148,7 @@ pub(crate) struct AccumulatorCols { _marker: PhantomData, } -impl AccumulatorCols { +impl AccumulatorCols { pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { Self { acc_s: AccumulatorPair::new(meta), @@ -215,7 +215,7 @@ pub(crate) struct DenoteCols { // TODO: check whether sel1, sel2 are sometimes used for accumulated values and // fix it. -impl DenoteCols { +impl DenoteCols { pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { Self { sel1: meta.advice_column(), @@ -252,7 +252,7 @@ pub(crate) struct PositionCols { _marker: PhantomData, } -impl PositionCols { +impl PositionCols { pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { Self { q_enable: meta.fixed_column(), diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index c49ce237a7..ec5fe68521 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -1,22 +1,23 @@ -use std::{marker::PhantomData, ops::Range}; +use std::{any::Any, marker::PhantomData, ops::Range}; use crate::{ _cb, circuit, circuit_tools::{ - Cell, CellManager, CellType, Conditionable, ConstraintBuilder, DataTransition, MemoryBank, - RLCChainable, RLCable, + cell_manager::{Cell, CellManager, DataTransition, Trackable}, + constraint_builder::{Conditionable, ConstraintBuilder, RLCChainable, RLCable}, + memory::MemoryBank, gadgets::IsEqualGadget, }, evm_circuit::util::rlc, mpt_circuit::param::{ KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN, RLP_HASH_VALUE, RLP_LIST_LONG, RLP_LIST_SHORT, RLP_NIL, RLP_SHORT, }, - util::Expr, + util::Expr, matchw, matchr, }; +use eth_types::Field; use gadgets::util::{and, not}; use halo2_proofs::{ - arithmetic::FieldExt, - circuit::{Region, Value}, + circuit::{Region}, plonk::{Error, Expression, VirtualCells}, poly::Rotation, }; @@ -24,13 +25,13 @@ use halo2_proofs::{ use super::{ columns::MainCols, param::{ - ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_ROWS, - ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, + ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, + ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, ACCOUNT_NON_EXISTING_IND, ARITY, BRANCH_0_C_START, BRANCH_0_S_START, BRANCH_ROWS_NUM, IS_BRANCH_C16_POS, IS_BRANCH_C1_POS, IS_BRANCH_C_PLACEHOLDER_POS, IS_BRANCH_S_PLACEHOLDER_POS, IS_C_BRANCH_NON_HASHED_POS, IS_C_EXT_LONGER_THAN_55_POS, IS_C_EXT_NODE_NON_HASHED_POS, IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_LONGER_THAN_55_POS, - IS_S_EXT_NODE_NON_HASHED_POS, KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, NIBBLES_COUNTER_POS, + IS_S_EXT_NODE_NON_HASHED_POS, KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, NIBBLES_COUNTER_POS, RLP_LONG, }, witness_row::MptWitnessRow, FixedTableTag, MPTConfig, MPTContext, ProofValues, @@ -40,7 +41,23 @@ use crate::mpt_circuit::param::{ IS_EXT_LONG_ODD_C1_POS, IS_EXT_SHORT_C16_POS, IS_EXT_SHORT_C1_POS, RLP_NUM, }; -pub(crate) trait Gadget { +/// Indexale object +pub trait Indexable { + /// Convert to index + fn idx(&self) -> usize; +} + +impl Indexable for bool { + fn idx(&self) -> usize { + if *self { + 0 + } else { + 1 + } + } +} + +pub(crate) trait Gadget { /// Constraints fn configure( meta: &mut VirtualCells<'_, F>, @@ -59,7 +76,546 @@ pub(crate) trait Gadget { ) -> Result<(), Error>; } -#[derive(Clone, Debug)] + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPListGadget { + pub(crate) is_short: Cell, + pub(crate) is_long: Cell, + pub(crate) bytes: Vec>, +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPListWitness { + pub(crate) is_short: bool, + pub(crate) is_long: bool, + pub(crate) bytes: Vec, +} + +impl RLPListGadget { + pub(crate) fn construct( + cb: &mut ConstraintBuilder, + bytes: &[Expression], + ) -> Self { + // TODO(Brecht): add lookup + RLPListGadget { + is_short: cb.query_cell(), + is_long: cb.query_cell(), + bytes: bytes.to_vec(), + } + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + bytes: &[u8], + ) -> Result { + const RLP_LIST_LONG_INCLUSIVE: u8 = RLP_LIST_LONG - 1; + const RLP_LIST_VALUE_MAX: u8 = 255; + + let mut is_short = false; + let mut is_long = false; + match bytes[0] { + RLP_LIST_SHORT..=RLP_LIST_LONG_INCLUSIVE => is_short = true, + RLP_LIST_LONG..=RLP_LIST_VALUE_MAX => is_long = true, + _ => { + println!("bytes: {:?}", bytes); + unreachable!(); + } + } + + self.is_short.assign(region, offset, F::from(is_short))?; + self.is_long.assign(region, offset, F::from(is_long))?; + + Ok(RLPListWitness { + is_short, + is_long, + bytes: bytes.to_vec(), + }) + } + + // Single RLP byte, length at most 55 bytes + pub(crate) fn is_short(&self) -> Expression { + self.is_short.expr() + } + + // RLP byte followed by the number of bytes in length, followed by the length + pub(crate) fn is_long(&self) -> Expression { + self.is_long.expr() + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => 1.expr(), + self.is_long() => 2.expr(), + } + }) + } + + /// Returns the total length of the list (including RLP bytes) + pub(crate) fn num_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => get_num_bytes_list_short::expr(self.bytes[0].expr()), + self.is_long() => 2.expr() + self.bytes[1].expr(), + } + }) + } + + /// Returns the length of the list (excluding RLP bytes) + pub(crate) fn len(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => get_len_list_short::expr(self.bytes[0].expr()), + self.is_long() => self.bytes[1].expr(), + } + }) + } +} + +impl RLPListWitness { + // Single RLP byte, length at most 55 bytes + pub(crate) fn is_short(&self) -> bool { + self.is_short + } + + // RLP byte followed by the number of bytes in length, followed by the length + pub(crate) fn is_long(&self) -> bool { + self.is_long + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> u64 { + matchr! { + self.is_short() => 1, + self.is_long() => 2, + } + } + + /// Returns the total length of the list (including RLP bytes) + pub(crate) fn num_bytes(&self) -> u64 { + matchr! { + self.is_short() => get_num_bytes_list_short::value(self.bytes[0]), + self.is_long() => 2 + (self.bytes[1] as u64), + } + } + + /// Returns the length of the list (excluding RLP bytes) + pub(crate) fn len(&self) -> u64 { + matchr! { + self.is_short() => get_len_list_short::value(self.bytes[0]), + self.is_long() => self.bytes[1] as u64, + } + } +} + + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPValueGadget { + pub(crate) is_short: Cell, + pub(crate) is_long: Cell, + pub(crate) is_very_long: Cell, + pub(crate) bytes: Vec>, +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPValueWitness { + pub(crate) is_short: bool, + pub(crate) is_long: bool, + pub(crate) is_very_long: bool, + pub(crate) bytes: Vec, +} + +impl RLPValueGadget { + pub(crate) fn construct( + cb: &mut ConstraintBuilder, + bytes: &[Expression], + ) -> Self { + // TODO(Brecht): add lookup + RLPValueGadget { + is_short: cb.query_cell(), + is_long: cb.query_cell(), + is_very_long: cb.query_cell(), + bytes: bytes.to_vec(), + } + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + bytes: &[u8], + ) -> Result { + const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT - 1; + const RLP_LONG_INCLUSIVE: u8 = RLP_LONG - 1; + const RLP_VALUE_MAX: u8 = RLP_LIST_SHORT - 1; + + let mut is_short = false; + let mut is_long = false; + let mut is_very_long = false; + match bytes[0] { + 0..=RLP_SHORT_INCLUSIVE => is_short = true, + RLP_SHORT..=RLP_LONG_INCLUSIVE => is_long = true, + RLP_LONG..=RLP_VALUE_MAX => is_very_long = true, + _ => unreachable!(), + } + + self.is_short.assign(region, offset, F::from(is_short))?; + self.is_long.assign(region, offset, F::from(is_long))?; + self.is_very_long.assign(region, offset, F::from(is_very_long))?; + + Ok(RLPValueWitness { + is_short, + is_long, + is_very_long, + bytes: bytes.to_vec(), + }) + } + + // Single RLP byte containing the byte value + pub(crate) fn is_short(&self) -> Expression { + self.is_short.expr() + } + + // Single RLP byte containing the length of the value + pub(crate) fn is_long(&self) -> Expression { + self.is_long.expr() + } + + // RLP byte containing the lenght of the length, + // followed by the length, followed by the actual data + pub(crate) fn is_very_long(&self) -> Expression { + self.is_very_long.expr() + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => 0.expr(), + self.is_long() => 1.expr(), + self.is_very_long() => 2.expr(), + } + }) + } + + /// Number of bytes in total (including RLP bytes) + pub(crate) fn num_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => 1.expr(), + self.is_long() => get_num_bytes_short::expr(self.bytes[0].expr()), + self.is_very_long() => { + unreachablex!(); + 0.expr() + }, + } + }) + } + + /// Length of the value (excluding RLP bytes) + pub(crate) fn len(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => 1.expr(), + self.is_long() => get_len_short::expr(self.bytes[0].expr()), + self.is_very_long() => { + unreachablex!(); + 0.expr() + }, + } + }) + } + + /// RLC data + pub(crate) fn rlc(&self, r: &[Expression]) -> (Expression, Expression) { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => { + let value_rlc = self.bytes[0].expr(); + (value_rlc.expr(), value_rlc.expr()) + }, + self.is_long() => { + let value_rlc = self.bytes[1..].rlc(&r); + (value_rlc, self.bytes.rlc(&r)) + }, + self.is_very_long() => { + unreachablex!(); + (0.expr(), 0.expr()) + }, + } + }) + } +} + + +impl RLPValueWitness { + // Single RLP byte containing the byte value + pub(crate) fn is_short(&self) -> bool { + self.is_short + } + + // Single RLP byte containing the length of the value + pub(crate) fn is_long(&self) -> bool { + self.is_long + } + + // RLP byte containing the lenght of the length, + // followed by the length, followed by the actual data + pub(crate) fn is_very_long(&self) -> bool { + self.is_very_long + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> u64 { + matchr! { + self.is_short() => 0, + self.is_long() => 1, + self.is_very_long() => 2, + } + } + + /// Number of bytes in total (including RLP bytes) + pub(crate) fn num_bytes(&self) -> u64 { + matchr! { + self.is_short() => 1, + self.is_long() => get_num_bytes_short::value(self.bytes[0]), + self.is_very_long() => { + unreachable!(); + }, + } + } + + /// Length of the value (excluding RLP bytes) + pub(crate) fn len(&self) -> u64 { + matchr! { + self.is_short() => 1, + self.is_long() => get_len_short::value(self.bytes[0]), + self.is_very_long() => { + unreachable!(); + }, + } + } +} + + +#[derive(Clone, Debug, Default)] +pub(crate) struct LeafKeyGadget { + rlp_list: RLPListGadget, + short_list_value: RLPValueGadget, + long_list_value: RLPValueGadget, + short_list_has_no_nibbles: IsEqualGadget, + long_list_has_no_nibbles: IsEqualGadget, + bytes: Vec>, +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct LeafKeyWitness { + rlp_list: RLPListWitness, + short_list_value: RLPValueWitness, + long_list_value: RLPValueWitness, + bytes: Vec, +} + +impl LeafKeyGadget { + pub(crate) fn construct( + cb: &mut ConstraintBuilder, + bytes: &[Expression], + ) -> Self { + LeafKeyGadget { + rlp_list: RLPListGadget::construct(cb, bytes), + short_list_value: RLPValueGadget::construct(cb, &bytes[1..]), + long_list_value: RLPValueGadget::construct(cb, &bytes[2..]), + short_list_has_no_nibbles: IsEqualGadget::::construct(cb, bytes[1].expr(), KEY_TERMINAL_PREFIX_EVEN.expr()), + long_list_has_no_nibbles: IsEqualGadget::::construct(cb, bytes[2].expr(), KEY_TERMINAL_PREFIX_EVEN.expr()), + bytes: bytes.to_vec(), + } + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + bytes: &[u8], + ) -> Result { + let rlp_list = self.rlp_list.assign(region, offset, bytes)?; + let short_list_value = self.short_list_value.assign(region, offset, &bytes[1..])?; + let long_list_value = self.long_list_value.assign(region, offset, &bytes[2..])?; + self.short_list_has_no_nibbles.assign(region, offset, F::from(bytes[1] as u64), F::from(KEY_TERMINAL_PREFIX_EVEN as u64))?; + self.long_list_has_no_nibbles.assign(region, offset, F::from(bytes[2] as u64), F::from(KEY_TERMINAL_PREFIX_EVEN as u64))?; + Ok(LeafKeyWitness { + rlp_list, + short_list_value, + long_list_value, + bytes: bytes.to_vec(), + }) + } + + pub(crate) fn key_rlc( + &self, + cb: &mut ConstraintBuilder, + key_mult_prev: Expression, + is_key_odd: Expression, + key_mult_first_even: Expression, + requires_longer_than_55: bool, + r: &[Expression], + ) -> Expression { + circuit!([meta, cb], { + let calc_rlc = |cb: &mut ConstraintBuilder, + bytes: &[Expression], + is_key_odd: Expression| { + leaf_key_rlc( + cb, + bytes, + key_mult_prev.expr(), + is_key_odd.expr(), + key_mult_first_even.expr(), + r, + ) + }; + matchx! { + self.rlp_list.is_short() => { + matchx! { + self.short_list_value.is_short() => { + // When no nibbles: only terminal prefix at `bytes[1]`. + // Else: Terminal prefix + single nibble at `bytes[1]` + let is_odd = not!(self.short_list_has_no_nibbles); + calc_rlc(cb, &self.bytes[1..2], is_odd) + }, + self.short_list_value.is_long() => { + // First key byte is at `s_main.bytes[0]`. + calc_rlc(cb, &self.bytes[2..35], is_key_odd.expr()) + }, + } + }, + self.rlp_list.is_long() => { + matchx! { + self.long_list_value.is_short() => { + // When no nibbles: only terminal prefix at `bytes[2]`. + // Else: Terminal prefix + single nibble at `bytes[2]` + let is_odd = not!(self.long_list_has_no_nibbles); + calc_rlc(cb, &self.bytes[2..3], is_odd) + }, + self.long_list_value.is_long() => { + if requires_longer_than_55 { + // rlp1 needs to be 248. + require!(self.bytes[0] => (RLP_LIST_LONG + 1)); + } + // First key byte is at `s_main.bytes[1]`. + calc_rlc(cb, &self.bytes[3..36], is_key_odd.expr()) + }, + } + }, + } + }) + } + + + /// Returns the total length of the leaf (including RLP bytes) + pub(crate) fn num_bytes(&self) -> Expression { + self.rlp_list.num_bytes() + } + + /// Number of RLP bytes for leaf and key + pub(crate) fn num_rlp_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + self.rlp_list.num_rlp_bytes() + matchx! { + self.rlp_list.is_short() => { + self.short_list_value.num_rlp_bytes() + }, + self.rlp_list.is_long() => { + self.long_list_value.num_rlp_bytes() + }, + } + }) + } + + /// Length of the key (excluding RLP bytes) + pub(crate) fn key_len(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.rlp_list.is_short() => { + self.short_list_value.len() + }, + self.rlp_list.is_long() => { + self.long_list_value.len() + }, + } + }) + } + + /// Number of bytes of RLP (including list RLP bytes) and key + pub(crate) fn num_bytes_on_key_row(&self) -> Expression { + circuit!([meta, _cb!()], { + self.rlp_list.num_rlp_bytes() + matchx! { + self.rlp_list.is_short() => { + self.short_list_value.num_bytes() + }, + self.rlp_list.is_long() => { + self.long_list_value.num_bytes() + }, + } + }) + } + + pub(crate) fn num_key_nibbles( + &self, + is_key_odd: Expression, + ) -> Expression { + get_num_nibbles(self.key_len(), is_key_odd) + } +} + +impl LeafKeyWitness { + /// Returns the total length of the leaf (including RLP bytes) + pub(crate) fn num_bytes(&self) -> u64 { + self.rlp_list.num_bytes() + } + + /// Number of RLP bytes for leaf and key + pub(crate) fn num_rlp_bytes_list(&self) -> u64 { + self.rlp_list.num_rlp_bytes() + } + + /// Number of RLP bytes for leaf and key + pub(crate) fn num_rlp_bytes(&self) -> u64 { + self.rlp_list.num_rlp_bytes() + if self.rlp_list.is_short() { + self.short_list_value.num_rlp_bytes() + } else if self.rlp_list.is_long() { + self.long_list_value.num_rlp_bytes() + } else { + unreachable!(); + } + } + + /// Length of the key (excluding RLP bytes) + pub(crate) fn key_len(&self) -> u64 { + matchr! { + self.rlp_list.is_short() => { + self.short_list_value.len() + }, + self.rlp_list.is_long() => { + self.long_list_value.len() + }, + } + } + + /// Number of bytes of RLP (including list RLP bytes) and key + pub(crate) fn num_bytes_on_key_row(&self) -> u64 { + self.rlp_list.num_rlp_bytes() + if self.rlp_list.is_short() { + self.short_list_value.num_bytes() + } else if self.rlp_list.is_long() { + self.long_list_value.num_bytes() + } else { + unreachable!(); + } + } +} + + +#[derive(Clone, Debug, Default)] pub(crate) struct KeyData { pub(crate) rlc: Cell, pub(crate) mult: Cell, @@ -71,22 +627,30 @@ pub(crate) struct KeyData { pub(crate) mult_last: Cell, } -impl KeyData { +impl Trackable for KeyData { + fn as_any(&self) -> &dyn Any { + self + } + fn clone_box(&self) -> Box { + Box::new(self.clone()) + } +} + +impl KeyData { pub(crate) fn load( cb: &mut ConstraintBuilder, - cm: &mut CellManager, memory: &MemoryBank, offset: Expression, ) -> Self { let key_data = KeyData { - rlc: cm.query_cell(CellType::Storage), - mult: cm.query_cell(CellType::Storage), - num_nibbles: cm.query_cell(CellType::Storage), - is_odd: cm.query_cell(CellType::Storage), - is_placeholder_leaf_s: cm.query_cell(CellType::Storage), - is_placeholder_leaf_c: cm.query_cell(CellType::Storage), - rlc_last: cm.query_cell(CellType::Storage), - mult_last: cm.query_cell(CellType::Storage), + rlc: cb.query_cell(), + mult: cb.query_cell(), + num_nibbles: cb.query_cell(), + is_odd: cb.query_cell(), + is_placeholder_leaf_s: cb.query_cell(), + is_placeholder_leaf_c: cb.query_cell(), + rlc_last: cb.query_cell(), + mult_last: cb.query_cell(), }; circuit!([meta, cb], { memory.load( @@ -172,38 +736,35 @@ impl KeyData { //println!("key_mult_prev: {:?}", pv.key_rlc_mult_prev); //println!("nibbles_num_prev: {:?}", pv.nibbles_num_prev); - self.rlc.assign(region, offset, Value::known(values[0]))?; - self.mult.assign(region, offset, Value::known(values[1]))?; - self.num_nibbles - .assign(region, offset, Value::known(values[2]))?; - self.is_odd - .assign(region, offset, Value::known(values[3]))?; + self.rlc.assign(region, offset, values[0])?; + self.mult.assign(region, offset, values[1])?; + self.num_nibbles.assign(region, offset, values[2])?; + self.is_odd.assign(region, offset, values[3])?; self.is_placeholder_leaf_s - .assign(region, offset, Value::known(values[4]))?; + .assign(region, offset, values[4])?; self.is_placeholder_leaf_c - .assign(region, offset, Value::known(values[5]))?; + .assign(region, offset, values[5])?; Ok(()) } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub(crate) struct ParentData { pub(crate) rlc: Cell, pub(crate) force_hashed: Cell, } -impl ParentData { +impl ParentData { pub(crate) fn load( description: &'static str, cb: &mut ConstraintBuilder, - cm: &mut CellManager, memory: &MemoryBank, offset: Expression, ) -> Self { let parent_data = ParentData { - rlc: cm.query_cell(CellType::Storage), - force_hashed: cm.query_cell(CellType::Storage), + rlc: cb.query_cell(), + force_hashed: cb.query_cell(), }; circuit!([meta, cb], { memory.load( @@ -251,9 +812,8 @@ impl ParentData { ) -> Result<(), Error> { let values = memory.witness_load(load_offset); - self.rlc.assign(region, offset, Value::known(values[0]))?; - self.force_hashed - .assign(region, offset, Value::known(values[1]))?; + self.rlc.assign(region, offset, values[0])?; + self.force_hashed.assign(region, offset, values[1])?; Ok(()) } @@ -283,7 +843,7 @@ pub(crate) struct BranchNodeInfo { pub(crate) nibbles_counter: DataTransition, } -impl BranchNodeInfo { +impl BranchNodeInfo { pub(crate) fn new( meta: &mut VirtualCells, ctx: MPTContext, @@ -495,23 +1055,6 @@ impl BranchNodeInfo { }) } - pub(crate) fn storage_root_in_account_above( - &self, - meta: &mut VirtualCells, - ) -> Expression { - let storage_offset = if self.is_s { - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND - } else { - ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND - }; - let rot_storage_root = self.rot_branch_init - ACCOUNT_LEAF_ROWS + storage_offset; - // Note: storage root is always in s_main.bytes. - self.ctx - .s_main - .bytes(meta, rot_storage_root) - .rlc(&self.ctx.r) - } - pub(crate) fn get_selectors(&self, meta: &mut VirtualCells) -> [Expression; 2] { //`s_rlp1, s_rlp2` is used for `S` and `s_main.bytes[0], s_main.bytes[1]` is //`s_rlp1, used for `C` @@ -579,7 +1122,7 @@ impl BranchNodeInfo { let rlp_bytes = self.rlp_bytes(meta); circuit!([meta, _cb!()], { matchx! { - self.is_branch_short(meta) => get_len_list_short(rlp_bytes[0].expr()), + self.is_branch_short(meta) => get_len_list_short::expr(rlp_bytes[0].expr()), self.is_branch_long(meta) => rlp_bytes[1].expr(), self.is_branch_very_long(meta) => rlp_bytes[1].expr() * 256.expr() + rlp_bytes[2].expr(), } @@ -595,8 +1138,8 @@ impl BranchNodeInfo { pub(crate) fn ext_len(&self, _meta: &mut VirtualCells, rot_c: i32) -> Expression { circuit!([_meta, _cb!()], { matchx! { - self.is_short() + self.is_long() => get_len_list_short(a!(self.ctx.s_main.rlp1, rot_c)), - self.is_longer_than_55_s => get_len_short(a!(self.ctx.s_main.bytes[0], rot_c)), + self.is_short() + self.is_long() => get_len_list_short::expr(a!(self.ctx.s_main.rlp1, rot_c)), + self.is_longer_than_55_s => get_len_short::expr(a!(self.ctx.s_main.bytes[0], rot_c)), } }) } @@ -617,8 +1160,8 @@ impl BranchNodeInfo { circuit!([_meta, _cb!()], { matchx! { self.is_short() => 1.expr(), // Only a single nibble (stored in s_rlp2) - self.is_long() => get_len_short(a!(self.ctx.s_main.rlp2, rel_rot)), - self.is_longer_than_55_s => get_len_short(a!(self.ctx.s_main.bytes[0], rel_rot)), + self.is_long() => get_len_short::expr(a!(self.ctx.s_main.rlp2, rel_rot)), + self.is_longer_than_55_s => get_len_short::expr(a!(self.ctx.s_main.bytes[0], rel_rot)), } }) } @@ -659,7 +1202,7 @@ impl BranchNodeInfo { ifx! {self.contains_hashed_branch(meta, rot_ext_s) => { 32.expr() } elsex { - get_len_list_short(a!(self.ctx.c_main.bytes[0], rot_ext_s)) + get_len_list_short::expr(a!(self.ctx.c_main.bytes[0], rot_ext_s)) }} }) } @@ -767,7 +1310,7 @@ pub(crate) struct BranchChildInfo { pub(crate) rot_branch: i32, } -impl BranchChildInfo { +impl BranchChildInfo { pub(crate) fn new( _meta: &mut VirtualCells, ctx: MPTContext, @@ -789,7 +1332,7 @@ impl BranchChildInfo { // non-nil node (1 or 33 respectively). a!(self.ctx.main(self.is_s).rlp2, self.rot_branch) * invert!(RLP_HASH_VALUE) * 32.expr() + 1.expr() } elsex { - get_num_bytes_list_short(a!(self.ctx.main(self.is_s).bytes[0], self.rot_branch)) + get_num_bytes_list_short::expr(a!(self.ctx.main(self.is_s).bytes[0], self.rot_branch)) }} }) } @@ -863,26 +1406,18 @@ pub(crate) struct StorageLeafInfo { pub(crate) is_s: bool, pub(crate) ctx: MPTContext, pub(crate) rot_key: i32, - pub(crate) flag1: Expression, - pub(crate) flag2: Expression, } -impl StorageLeafInfo { +impl StorageLeafInfo { pub(crate) fn new( - meta: &mut VirtualCells, ctx: MPTContext, is_s: bool, rot_key: i32, ) -> Self { - let rot = Rotation(rot_key); - let flag1 = meta.query_advice(ctx.accumulators.s_mod_node_rlc, rot); - let flag2 = meta.query_advice(ctx.accumulators.c_mod_node_rlc, rot); StorageLeafInfo { is_s, ctx: ctx.clone(), rot_key, - flag1, - flag2, } } @@ -890,152 +1425,11 @@ impl StorageLeafInfo { self.is_s = is_s; } - // Override the rotation while keeping the length flags intact - pub(crate) fn set_rot_key(&mut self, rot_key: i32) { - self.rot_key = rot_key; - } - - pub(crate) fn has_no_nibble(&self) -> Expression { - self.flag1.expr() * self.flag2.expr() - } - - pub(crate) fn has_one_nibble(&self) -> Expression { - not::expr(self.flag1.expr()) * not::expr(self.flag2.expr()) - } - - pub(crate) fn is_long(&self) -> Expression { - self.flag1.expr() * not::expr(self.flag2.expr()) - } - - pub(crate) fn is_short(&self) -> Expression { - not::expr(self.flag1.expr()) * self.flag2.expr() - } - - pub(crate) fn is_very_short(&self) -> Expression { - self.has_no_nibble() + self.has_one_nibble() - } - - /// Returns the total length of the leaf (including RLP bytes) - pub(crate) fn num_bytes(&self, meta: &mut VirtualCells) -> Expression { - circuit!([meta, _cb!()], { - ifx! {self.is_long() => { - 2.expr() + a!(self.ctx.s_main.rlp2, self.rot_key) - } elsex { - get_num_bytes_list_short(a!(self.ctx.s_main.rlp1, self.rot_key)) - }} - }) - } - - /// Number of RLP bytes for leaf and key - pub(crate) fn num_rlp_bytes(&self, _meta: &mut VirtualCells) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.is_very_short() => 1.expr(), - self.is_short() => 2.expr(), - self.is_long() => 3.expr(), - } - }) - } - - /// Length of the key (excluding RLP bytes) - pub(crate) fn key_len(&self, _meta: &mut VirtualCells) -> Expression { - circuit!([_meta, _cb!()], { - matchx! { - self.is_very_short() => 1.expr(), // 1 byte in s_rlp2 - self.is_short() => get_len_short(a!(self.ctx.s_main.rlp2, self.rot_key)), - self.is_long() => get_len_short(a!(self.ctx.s_main.bytes[0], self.rot_key)), - } - }) - } - - /// Number of bytes of RLP (including list RLP bytes) and key - pub(crate) fn num_bytes_on_key_row(&self, meta: &mut VirtualCells) -> Expression { - self.num_rlp_bytes(meta) + self.key_len(meta) - } - - pub(crate) fn num_key_nibbles( - &self, - meta: &mut VirtualCells, - is_key_odd: Expression, - ) -> Expression { - let key_len = self.key_len(meta); - get_num_nibbles(meta, key_len, is_key_odd) - } - - pub(crate) fn key_rlc( - &self, - meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - key_mult_prev: Expression, - is_key_odd: Expression, - key_mult_first_even: Expression, - requires_longer_than_55: bool, - rot: i32, - ) -> Expression { - circuit!([meta, cb], { - let calc_rlc = |meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - range: Range, - is_key_odd: Expression| { - leaf_key_rlc( - meta, - cb, - self.ctx.clone(), - range, - key_mult_prev.expr(), - is_key_odd.expr(), - key_mult_first_even.expr(), - self.rot_key + rot, - ) - }; - matchx! { - self.is_short() => { - // First key byte is at `s_main.bytes[0]`. - calc_rlc(meta, cb, 2..35, is_key_odd.expr()) - }, - self.is_long() => { - if requires_longer_than_55 { - // `s_main.rlp1` needs to be 248. - require!(a!(self.ctx.s_main.rlp1, self.rot_key + rot) => (RLP_LIST_LONG + 1)); - } - // First key byte is at `s_main.bytes[1]`. - calc_rlc(meta, cb, 3..36, is_key_odd.expr()) - }, - self.has_no_nibble() => { - // Single byte is at `s_main.rlp2` - calc_rlc(meta, cb, 1..2, false.expr()) - }, - self.has_one_nibble() => { - // Single byte is at `s_main.rlp2` - calc_rlc(meta, cb, 1..2, true.expr()) - }, - } - }) - } - pub(crate) fn is_below_account(&self, meta: &mut VirtualCells) -> Expression { let rot_parent = if self.is_s { -1 } else { -3 }; self.ctx.is_account(meta, self.rot_key + rot_parent) } - pub(crate) fn storage_root_in_account_above( - &self, - meta: &mut VirtualCells, - ) -> Expression { - let rot_parent = if self.is_s { -1 } else { -3 }; - let storage_offset = if self.is_s { - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND - } else { - ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND - }; - let rot_storage_root = self.rot_key + 1 + rot_parent - ACCOUNT_LEAF_ROWS + storage_offset; - // Note: storage root is always in s_main.bytes. - self.ctx - .s_main - .bytes(meta, rot_storage_root) - .rlc(&self.ctx.r) - } - pub(crate) fn is_placeholder(&self, meta: &mut VirtualCells) -> Expression { let rot_parent = if self.is_s { -1 } else { -3 }; let rot_branch_init = rot_parent - (BRANCH_ROWS_NUM - 1); @@ -1069,7 +1463,7 @@ pub(crate) struct AccountLeafInfo { is_balance_long: Expression, } -impl AccountLeafInfo { +impl AccountLeafInfo { pub(crate) fn new(meta: &mut VirtualCells, ctx: MPTContext, rot_key: i32) -> Self { let rot = Rotation(rot_key); let is_nonce_long = meta.query_advice(ctx.denoter.sel1, rot); @@ -1120,7 +1514,7 @@ impl AccountLeafInfo { /// Returns the length of the key pub(crate) fn key_len(&self, _meta: &mut VirtualCells) -> Expression { circuit!([_meta, _cb!()], { - get_len_short(a!(self.ctx.s_main.bytes[0], self.rot_key)) + get_len_short::expr(a!(self.ctx.s_main.bytes[0], self.rot_key)) }) } @@ -1226,19 +1620,17 @@ impl AccountLeafInfo { rot: i32, ) -> Expression { leaf_key_rlc( - meta, cb, - self.ctx.clone(), - 3..36, + &self.ctx.expr(meta, self.rot_key + rot)[3..36], key_mult_prev.expr(), is_key_odd, key_mult_first_even, - self.rot_key + rot, + &self.ctx.r, ) } } -pub(crate) fn contains_placeholder_leaf( +pub(crate) fn contains_placeholder_leaf( meta: &mut VirtualCells, ctx: MPTContext, is_s: bool, @@ -1247,34 +1639,27 @@ pub(crate) fn contains_placeholder_leaf( meta.query_advice(ctx.denoter.sel(is_s), Rotation(rot_branch_child)) } -pub(crate) fn leaf_key_rlc( - meta: &mut VirtualCells, +pub(crate) fn leaf_key_rlc( cb: &mut ConstraintBuilder, - ctx: MPTContext, - range: Range, + bytes: &[Expression], key_mult_prev: Expression, is_key_odd: Expression, key_mult_first_even: Expression, - rot: i32, + r: &[Expression], ) -> Expression { circuit!([meta, cb], { // Add the odd nibble first if we have one. - let first_byte = a!(ctx.s_main.rlp_bytes()[range.start], rot); let (rlc, mult) = ifx! {is_key_odd => { - (get_terminal_odd_nibble(first_byte.expr()) * key_mult_prev.expr(), ctx.r[0].expr()) + (get_terminal_odd_nibble(bytes[0].expr()) * key_mult_prev.expr(), r[0].expr()) } elsex { - require!(first_byte => KEY_TERMINAL_PREFIX_EVEN); + require!(bytes[0] => KEY_TERMINAL_PREFIX_EVEN); (0.expr(), key_mult_first_even.expr()) }}; - (rlc, key_mult_prev * mult).rlc_chain(ctx.rlc( - meta, - range.start + 1..range.end, - cb.get_query_offset() + rot, - )) + (rlc, key_mult_prev * mult).rlc_chain(bytes[1..].rlc(r)) }) } -pub(crate) fn ext_key_rlc( +pub(crate) fn ext_key_rlc( _meta: &mut VirtualCells, cb: &mut ConstraintBuilder, ctx: MPTContext, @@ -1297,36 +1682,76 @@ pub(crate) fn ext_key_rlc( }) } -pub(crate) fn get_terminal_odd_nibble(byte: Expression) -> Expression { +pub(crate) fn get_terminal_odd_nibble(byte: Expression) -> Expression { // The odd nible is stored in the same byte as the prefix byte - KEY_TERMINAL_PREFIX_ODD.expr() } -pub(crate) fn get_ext_odd_nibble(byte: Expression) -> Expression { +pub(crate) fn get_ext_odd_nibble(byte: Expression) -> Expression { // The odd nible is stored in the same byte as the prefix byte - KEY_PREFIX_ODD.expr() } -pub(crate) fn get_len_short(byte: Expression) -> Expression { - byte - RLP_SHORT.expr() +// A single RLP byte +pub(crate) mod get_len_short { + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::{plonk::Expression}; + use crate::mpt_circuit::param::RLP_SHORT; + + pub(crate) fn expr(byte: Expression) -> Expression { + byte - RLP_SHORT.expr() + } + pub(crate) fn value(byte: u8) -> u64 { + (byte - RLP_SHORT) as u64 + } } -pub(crate) fn get_num_bytes_short(byte: Expression) -> Expression { - // A single RLP byte + the encoded length - 1.expr() + get_len_short(byte) +// A single RLP byte + the encoded length +pub(crate) mod get_num_bytes_short { + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::{plonk::Expression}; + use super::get_len_short; + + pub(crate) fn expr(byte: Expression) -> Expression { + 1.expr() + get_len_short::expr(byte) + } + pub(crate) fn value(byte: u8) -> u64 { + 1 + get_len_short::value(byte) + } } -pub(crate) fn get_len_list_short(byte: Expression) -> Expression { - byte - RLP_LIST_SHORT.expr() +pub(crate) mod get_len_list_short { + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::{plonk::Expression}; + use crate::mpt_circuit::param::RLP_LIST_SHORT; + + pub(crate) fn expr(byte: Expression) -> Expression { + byte - RLP_LIST_SHORT.expr() + } + pub(crate) fn value(byte: u8) -> u64 { + (byte - RLP_LIST_SHORT) as u64 + } } -pub(crate) fn get_num_bytes_list_short(byte: Expression) -> Expression { - // A single RLP byte + the encoded length - 1.expr() + get_len_list_short(byte) +// A single RLP byte + the encoded length +pub(crate) mod get_num_bytes_list_short { + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::{plonk::Expression}; + use super::get_len_list_short; + + pub(crate) fn expr(byte: Expression) -> Expression { + 1.expr() + get_len_list_short::expr(byte) + } + pub(crate) fn value(byte: u8) -> u64 { + 1 + get_len_list_short::value(byte) + } } -pub(crate) fn get_num_nibbles( - _meta: &mut VirtualCells, +pub(crate) fn get_num_nibbles( key_len: Expression, is_key_odd: Expression, ) -> Expression { @@ -1340,7 +1765,7 @@ pub(crate) fn get_num_nibbles( } // Returns the RLC values stored in the parent of the current node. -pub(crate) fn get_parent_rlc_state( +pub(crate) fn get_parent_rlc_state( meta: &mut VirtualCells, ctx: MPTContext, is_first_level: Expression, @@ -1369,7 +1794,7 @@ pub(crate) fn get_parent_rlc_state( }) } -pub(crate) fn extend_rand(r: &[Expression]) -> Vec> { +pub(crate) fn extend_rand(r: &[Expression]) -> Vec> { [ r.to_vec(), r.iter() @@ -1379,7 +1804,7 @@ pub(crate) fn extend_rand(r: &[Expression]) -> Vec .concat() } -pub(crate) fn bytes_into_rlc(expressions: &[u8], r: F) -> F { +pub(crate) fn bytes_into_rlc(expressions: &[u8], r: F) -> F { let mut rlc = F::zero(); let mut mult = F::one(); for expr in expressions.iter() { @@ -1398,6 +1823,7 @@ pub(crate) fn key_memory(is_s: bool) -> String { } /// MPTConstraintBuilder +#[derive(Clone)] pub struct MPTConstraintBuilder { pub base: ConstraintBuilder, /// Number of non-zero s bytes @@ -1410,15 +1836,15 @@ pub struct MPTConstraintBuilder { pub range_s: Vec<(Expression, Expression)>, } -impl MPTConstraintBuilder { +impl MPTConstraintBuilder { const DEFAULT_LENGTH_S: usize = 34; const DEFAULT_LENGTH_C: usize = 32; const NUM_BYTES_SKIP: usize = 2; // RLP bytes never need to be zero checked const DEFAULT_RANGE: FixedTableTag = FixedTableTag::RangeKeyLen256; - pub(crate) fn new(max_degree: usize) -> Self { + pub(crate) fn new(max_degree: usize, cell_manager: Option>) -> Self { MPTConstraintBuilder { - base: ConstraintBuilder::new(max_degree), + base: ConstraintBuilder::new(max_degree, cell_manager), length_s: Vec::new(), length_sc: 0.expr(), length_c: Vec::new(), diff --git a/zkevm-circuits/src/mpt_circuit/proof_chain.rs b/zkevm-circuits/src/mpt_circuit/proof_chain.rs index 71516a1c44..5a003cae18 100644 --- a/zkevm-circuits/src/mpt_circuit/proof_chain.rs +++ b/zkevm-circuits/src/mpt_circuit/proof_chain.rs @@ -1,8 +1,9 @@ -use halo2_proofs::{arithmetic::FieldExt, plonk::VirtualCells, poly::Rotation}; +use eth_types::Field; +use halo2_proofs::{plonk::VirtualCells, poly::Rotation}; use std::marker::PhantomData; use super::{helpers::MPTConstraintBuilder, MPTContext}; -use crate::{circuit, circuit_tools::DataTransition}; +use crate::{circuit, circuit_tools::cell_manager::DataTransition}; /* The selector `not_first_level` denotes whether the node is not in the first account trie level. @@ -39,7 +40,7 @@ pub(crate) struct ProofChainConfig { _marker: PhantomData, } -impl ProofChainConfig { +impl ProofChainConfig { pub fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, diff --git a/zkevm-circuits/src/mpt_circuit/selectors.rs b/zkevm-circuits/src/mpt_circuit/selectors.rs index 8150a04b85..db50e92eb0 100644 --- a/zkevm-circuits/src/mpt_circuit/selectors.rs +++ b/zkevm-circuits/src/mpt_circuit/selectors.rs @@ -1,6 +1,7 @@ use super::{helpers::MPTConstraintBuilder, MPTContext}; -use crate::{circuit, circuit_tools::DataTransition}; -use halo2_proofs::{arithmetic::FieldExt, plonk::VirtualCells, poly::Rotation}; +use crate::{circuit, circuit_tools::cell_manager::DataTransition}; +use eth_types::Field; +use halo2_proofs::{plonk::VirtualCells, poly::Rotation}; use std::marker::PhantomData; #[derive(Clone, Debug)] @@ -8,7 +9,7 @@ pub(crate) struct SelectorsConfig { _marker: PhantomData, } -impl SelectorsConfig { +impl SelectorsConfig { pub fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index 6657a845a9..9ca0631527 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -1,24 +1,24 @@ +use eth_types::Field; use halo2_proofs::plonk::{Advice, Column, ConstraintSystem}; use halo2_proofs::{ - arithmetic::FieldExt, circuit::{Region, Value}, plonk::{Error, VirtualCells}, poly::Rotation, }; use std::marker::PhantomData; +use crate::circuit_tools::cell_manager::{Cell}; +use crate::circuit_tools::constraint_builder::{ConstraintBuilder, RLCChainable, RLCable}; +use crate::circuit_tools::gadgets::{RequireNotZeroGadget, LtGadget}; use crate::{ circuit, - circuit_tools::{ - Cell, CellManager, CellType, ConstraintBuilder, DataTransition, RLCChainable, RLCable, - }, mpt_circuit::{ helpers::BranchNodeInfo, param::{BRANCH_ROWS_NUM, S_START}, }, mpt_circuit::{ helpers::{ - get_num_bytes_short, get_parent_rlc_state, key_memory, parent_memory, KeyData, + get_parent_rlc_state, key_memory, parent_memory, KeyData, MPTConstraintBuilder, ParentData, StorageLeafInfo, }, param::{ @@ -34,6 +34,8 @@ use crate::{ mpt_circuit::{MPTConfig, ProofValues}, }; +use super::helpers::{Indexable, RLPValueGadget, LeafKeyGadget}; + #[derive(Clone, Debug)] pub(crate) struct StorageLeafCols { pub(crate) is_s_key: Column, @@ -51,7 +53,7 @@ pub(crate) struct StorageLeafCols { _marker: PhantomData, } -impl StorageLeafCols { +impl StorageLeafCols { pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { Self { is_s_key: meta.advice_column(), @@ -91,17 +93,23 @@ pub(crate) struct StorageLeaf { pub(crate) is_non_existing: bool, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub(crate) struct StorageLeafConfig { - key_data_s: KeyData, - key_data_c: KeyData, + key_data: [KeyData; 2], key_data_w: KeyData, - parent_data_s: ParentData, - parent_data_c: ParentData, - diff_inv: Cell, + parent_data: [ParentData; 2], + mult: [Cell; 2], + drifted_mult: Cell, + rlp_key: [LeafKeyGadget; 2], + rlp_value: [RLPValueGadget; 2], + drifted_rlp_key: LeafKeyGadget, + wrong_rlp_key: LeafKeyGadget, + is_wrong_leaf: Cell, + check_is_wrong_leaf: RequireNotZeroGadget, + is_not_hashed: [LtGadget; 2], } -impl StorageLeafConfig { +impl StorageLeafConfig { pub fn configure( meta: &mut VirtualCells<'_, F>, cb: &mut MPTConstraintBuilder, @@ -109,8 +117,6 @@ impl StorageLeafConfig { ) -> Self { let is_s = true; let accs = ctx.accumulators; - let value_prev = ctx.value_prev; - let value = ctx.value; let s_main = ctx.s_main; let r = ctx.r.clone(); @@ -118,70 +124,55 @@ impl StorageLeafConfig { let rot_branch_init = rot_parent - (BRANCH_ROWS_NUM - 1); let rot_branch_child = rot_branch_init + 1; - let rot_key_s = 0; - let rot_value_s = 1; - let rot_key_c = 2; - let rot_value_c = 3; - - let mut cm = CellManager::new(meta, 1, &ctx.managed_columns, 0); - let mut ctx_key_data_c: Option> = None; - let mut ctx_key_data_s: Option> = None; - let ctx_key_data_w: KeyData; - let mut ctx_parent_data_s: Option> = None; - let mut ctx_parent_data_c: Option> = None; - let ctx_diff_inv: Cell; + cb.base.cell_manager.as_mut().unwrap().reset(); + let mut config = StorageLeafConfig::default(); circuit!([meta, cb.base], { let mut branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); let mut offset = 0; + let mut key_rlc = vec![0.expr(); 2]; + let mut value_rlc = vec![0.expr(); 2]; + let mut leaf_rlc_value = vec![0.expr(); 2]; for is_s in [true, false] { - let storage = StorageLeafInfo::new(meta, ctx.clone(), is_s, offset); + let storage = StorageLeafInfo::new(ctx.clone(), is_s, offset); branch.set_is_s(is_s); // Load the last key values, which depends on the branch being a placeholder. let is_branch_placeholder = ifx! {not!(storage.is_below_account(meta)) => { branch.is_placeholder() }}; let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; - let key_data = KeyData::load( - &mut cb.base, - &mut cm, - &ctx.memory[key_memory(is_s)], - load_offset, - ); + let key_data = &mut config.key_data[is_s.idx()]; + *key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], load_offset); - // The two flag values need to be boolean. - require!(storage.flag1 => bool); - require!(storage.flag2 => bool); + let rlp_key = &mut config.rlp_key[is_s.idx()] ; + *rlp_key = LeafKeyGadget::construct(&mut cb.base, &ctx.expr(meta, offset)); // Calculate and store the leaf data RLC - require!(a!(accs.acc_s.rlc, offset) => ctx.rlc(meta, 0..36, offset)); + let leaf_rlc_key = ctx.rlc(meta, 0..36, offset); - // Calculate and store the key RLC. - let key_rlc = key_data.rlc.expr() - + storage.key_rlc( - meta, - &mut cb.base, - key_data.mult.expr(), - key_data.is_odd.expr(), - 1.expr(), - true, - 0, - ); - require!(a!(accs.key.rlc, offset) => key_rlc); + key_rlc[is_s.idx()] = key_data.rlc.expr() + rlp_key.key_rlc( + &mut cb.base, + key_data.mult.expr(), + key_data.is_odd.expr(), + 1.expr(), + true, + &r, + ); // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES (except in a // placeholder leaf). // TODO(Brecht): why not in placeholder leaf? ifx! {not!(storage.is_placeholder(meta)) => { - let num_nibbles = storage.num_key_nibbles(meta, key_data.is_odd.expr()); + let num_nibbles = rlp_key.num_key_nibbles(key_data.is_odd.expr()); require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); }} // Num bytes used in RLC - let num_bytes = storage.num_bytes_on_key_row(meta); + let num_bytes = rlp_key.num_bytes_on_key_row(); // Multiplier is number of bytes - require!((FixedTableTag::RMult, num_bytes.expr(), a!(accs.acc_s.mult, offset)) => @"fixed"); + config.mult[is_s.idx()] = cb.base.query_cell(); + require!((FixedTableTag::RMult, num_bytes.expr(), config.mult[is_s.idx()].expr()) => @"fixed"); // RLC bytes zero check //cb.set_length(num_bytes.expr()); @@ -192,55 +183,14 @@ impl StorageLeafConfig { KeyData::default_values(), ); - if is_s { - ctx_key_data_s = Some(key_data); - } else { - ctx_key_data_c = Some(key_data); - } - offset += 1; - let is_long = a!(accs.s_mod_node_rlc, offset); - let is_short = a!(accs.c_mod_node_rlc, offset); - - // We need to ensure `is_long` and `is_short` are boolean. - require!(is_short => bool); - require!(is_long => bool); - // `is_short` or `is_long` needs to be true. - require!(sum::expr([is_short.expr(), is_long.expr()]) => 1); - - let rot_s = offset + if is_s { 0 } else { -2 }; - let rot_key = offset - 1; - - // We need to ensure that the stored leaf RLC and value RLC is the same as the - // computed one. - let leaf_rlc = - DataTransition::new_with_rot(meta, accs.acc_s.rlc, offset - 1, offset); - let value_rlc = DataTransition::new_with_rot(meta, accs.acc_c.rlc, rot_s, offset); - let mult_prev = a!(accs.acc_s.mult, rot_key); - let (new_value_rlc, leaf_rlc_part) = ifx! {is_short => { - (a!(s_main.rlp1, offset), a!(s_main.rlp1, offset) * mult_prev.expr()) - } elsex { - let value_rlc = s_main.bytes(meta, offset).rlc(&r); - let leaf_rlc = (0.expr(), mult_prev.expr()).rlc_chain([a!(s_main.rlp1, offset), a!(s_main.rlp2, offset), value_rlc.expr()].rlc(&r)); - (value_rlc, leaf_rlc) - }}; - require!(value_rlc => new_value_rlc); - require!(leaf_rlc => leaf_rlc.prev() + leaf_rlc_part); - - // To enable external lookups we need to have the key and the previous/current - // value on the same row. - if !is_s { - require!(a!(accs.key.mult, offset) => a!(accs.key.rlc, rot_key)); - require!(a!(value_prev, offset) => value_rlc.prev()); - require!(a!(value, offset) => value_rlc); - } - - // Get the number of bytes used by the value - let value_num_bytes = matchx! { - is_short => 1.expr(), - is_long => 1.expr() + get_num_bytes_short(a!(s_main.rlp2, offset)), - }; + let rlp_value = &mut config.rlp_value[is_s.idx()] ; + *rlp_value = RLPValueGadget::construct(&mut cb.base, &s_main.expr(meta, offset)); + let (rlp_new_value_rlc, rlp_leaf_rlc_value_part) = rlp_value.rlc(&r); + value_rlc[is_s.idx()] = rlp_new_value_rlc.expr(); + leaf_rlc_value[is_s.idx()] = rlp_leaf_rlc_value_part.expr(); + let leaf_rlc = (leaf_rlc_key, config.mult[is_s.idx()].expr()).rlc_chain(rlp_leaf_rlc_value_part.expr()); // If `is_modified_node_empty = 1`, which means an empty child, we need to // ensure that the value is set to 0 in the placeholder leaf. For @@ -250,22 +200,26 @@ impl StorageLeafConfig { require!(a!(s_main.rlp1, offset) => 0); }} + // Number of bytes used by the leaf in total + let num_bytes = rlp_key.num_bytes(); + // Get the number of bytes used by the value + let value_num_bytes = rlp_value.num_bytes(); + // Make sure the RLP encoding is correct. // storage = [key, value] - let num_bytes = storage.num_bytes(meta); // TODO(Brecht): modify the witness for empty placeholder leafs to have valid // RLP encoding ifx! {not!(branch.contains_placeholder_leaf(meta, is_s)) => { - let key_num_bytes = storage.num_bytes_on_key_row(meta); + let key_num_bytes = rlp_key.num_bytes_on_key_row(); require!(num_bytes => key_num_bytes.expr() + value_num_bytes.expr()); }}; // Check if the account is in its parent. let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let parent_data = ParentData::load( + let parent_data = &mut config.parent_data[is_s.idx()]; + *parent_data = ParentData::load( "leaf load", &mut cb.base, - &mut cm, &ctx.memory[parent_memory(is_s)], 0.expr(), ); @@ -277,8 +231,8 @@ impl StorageLeafConfig { require!(parent_data.rlc => empty_root_rlc); } elsex { ifx!{not!(and::expr(&[not!(storage.is_below_account(meta)), branch.contains_placeholder_leaf(meta, is_s)])) => { - let is_not_hashed = a!(accs.acc_c.rlc, offset-1); - ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { + config.is_not_hashed[is_s.idx()] = LtGadget::construct(&mut cb.base, num_bytes.expr(), 32.expr()); + ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(config.is_not_hashed[is_s.idx()])]) => { // Hashed branch hash in parent branch require!((1, leaf_rlc, num_bytes, parent_data.rlc) => @"keccak"); } elsex { @@ -298,26 +252,22 @@ impl StorageLeafConfig { //cb.set_length_s(value_num_bytes); offset += 1; - - if is_s { - ctx_parent_data_s = Some(parent_data); - } else { - ctx_parent_data_c = Some(parent_data); - } } - let storage = StorageLeafInfo::new(meta, ctx.clone(), true, 0); - ifx! {not!(storage.is_below_account(meta)) => { + // Put the data in the lookup table + require!(a!(ctx.mpt_table.key_rlc, offset-1) => key_rlc[false.idx()]); + require!(a!(ctx.mpt_table.value_prev, offset-1) => value_rlc[true.idx()]); + require!(a!(ctx.mpt_table.value, offset-1) => value_rlc[false.idx()]); + + // Drifted leaf + let storage = StorageLeafInfo::new(ctx.clone(), true, 0); + ifx! {branch.is_placeholder_s_or_c(), not!(storage.is_below_account(meta)) => { let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - let drifted_storage = StorageLeafInfo::new(meta, ctx.clone(), true, offset); - // The two flag values need to be boolean. - require!(drifted_storage.flag1 => bool); - require!(drifted_storage.flag2 => bool); + config.drifted_rlp_key = LeafKeyGadget::construct(&mut cb.base, &ctx.expr(meta, offset)); // Calculate and store the leaf RLC (RLP + key) - let drifted_rlc = a!(accs.acc_s.rlc, offset); - require!(drifted_rlc => ctx.rlc(meta, 0..36, offset)); + let drifted_rlc_key = ctx.rlc(meta, 0..36, offset); // We need the intermediate key RLC right before `drifted_index` is added to it. // If the branch parallel to the placeholder branch is an extension node, @@ -327,30 +277,26 @@ impl StorageLeafConfig { // Calculate the drifted key RLC let drifted_key_rlc = key_rlc_prev.expr() + branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + - drifted_storage.key_rlc(meta, &mut cb.base, key_mult_prev, branch.is_key_odd(), r[0].expr(), true, 0); + config.drifted_rlp_key.key_rlc(&mut cb.base, key_mult_prev, branch.is_key_odd(), r[0].expr(), true, &r); // Check zero bytes and mult_diff - let mult = a!(accs.acc_s.mult, offset); - ifx!{branch.is_placeholder_s_or_c() => { - // Num bytes used in RLC - let num_bytes = drifted_storage.num_bytes_on_key_row(meta); - // Multiplier is number of bytes - require!((FixedTableTag::RMult, num_bytes.expr(), mult) => @"fixed"); - // RLC bytes zero check - //cb.set_length(num_bytes.expr()); - }} + config.drifted_mult = cb.base.query_cell(); + // Num bytes used in RLC + let num_bytes = config.drifted_rlp_key.num_bytes_on_key_row(); + // Multiplier is number of bytes + require!((FixedTableTag::RMult, num_bytes.expr(), config.drifted_mult.expr()) => @"fixed"); + // RLC bytes zero check + //cb.set_length(num_bytes.expr()); // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { + let calc_rlc = |is_s: bool, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { circuit!([meta, cb], { - let rot_key = if is_s { rot_key_s } else { rot_key_c }; - let rot_value = if is_s { rot_value_s } else { rot_value_c }; // Complete the drifted leaf rlc by adding the bytes on the value row - let drifted_rlc = (drifted_rlc.expr(), mult.expr()).rlc_chain(s_main.rlc(meta, rot_value, &r)); - (true.expr(), a!(accs.key.rlc, rot_key), drifted_rlc, a!(accs.mod_node_rlc(is_s), rot_branch_child)) + let drifted_rlc = (drifted_rlc_key.expr(), config.drifted_mult.expr()).rlc_chain(leaf_rlc_value[is_s.idx()].expr()); + (key_rlc[is_s.idx()].expr(), drifted_rlc, a!(accs.mod_node_rlc(is_s), rot_branch_child)) }) }; - let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { + let (key_rlc, drifted_rlc, mod_hash) = matchx! { branch.is_placeholder_s() => { // Neighbour leaf in the added branch // - `leaf_key_s_rlc` is the key RLC of the leaf before it drifted down @@ -369,61 +315,52 @@ impl StorageLeafConfig { // `modified_index` (the leaf that is to be deleted). calc_rlc(false, meta, &mut cb.base) }, - _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), }; - ifx! {do_checks => { - // The key of the drifted leaf needs to match the key of the leaf - require!(key_rlc => drifted_key_rlc); - // The drifted leaf needs to be stored in the branch at `drifted_index`. - require!((1, drifted_rlc, drifted_storage.num_bytes(meta), mod_hash) => @"keccak"); - }} + // The key of the drifted leaf needs to match the key of the leaf + require!(key_rlc => drifted_key_rlc); + // The drifted leaf needs to be stored in the branch at `drifted_index`. + require!((1, drifted_rlc, config.drifted_rlp_key.num_bytes(), mod_hash) => @"keccak"); }} offset += 1; - let storage = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); - let is_wrong_leaf = a!(s_main.rlp1, offset); - + config.is_wrong_leaf = cb.base.query_cell(); // Make sure is_wrong_leaf is boolean - require!(is_wrong_leaf => bool); - - let diff_inv = cm.query_cell(CellType::Storage); + require!(config.is_wrong_leaf => bool); ifx! {a!(ctx.proof_type.is_non_existing_storage_proof, offset) => { // Get the previous key RLC data - let key_data = KeyData::load(&mut cb.base, &mut cm, &ctx.memory[key_memory(true)], 1.expr()); - ifx! {is_wrong_leaf => { + config.key_data_w = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 1.expr()); + ifx! {config.is_wrong_leaf => { + config.wrong_rlp_key = LeafKeyGadget::construct(&mut cb.base, &ctx.expr(meta, offset)); // Calculate the key and check it's the address as requested in the lookup - let key_rlc_wrong = key_data.rlc.expr() + storage.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), false, offset - rot_key_c); - require!(a!(accs.key.mult, offset) => key_rlc_wrong); + let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.key_rlc( + &mut cb.base, + config.key_data_w.mult.expr(), + config.key_data_w.is_odd.expr(), + 1.expr(), + false, + &ctx.r, + ); + require!(a!(ctx.mpt_table.key_rlc, offset) => key_rlc_wrong); // Now make sure this address is different than the one of the leaf - require!((a!(accs.key.mult, offset) - a!(accs.key.rlc, rot_key_c)) * diff_inv.expr() => 1); + let key_rlc_lookup = a!(ctx.mpt_table.key_rlc, offset); + config.check_is_wrong_leaf = RequireNotZeroGadget::construct(&mut cb.base, key_rlc_lookup - key_rlc[false.idx()].expr()); // Make sure the lengths of the keys are the same - let mut storage_wrong = StorageLeafInfo::new(meta, ctx.clone(), true, rot_key_c); - storage_wrong.set_rot_key(0); - require!(storage_wrong.key_len(meta) => storage.key_len(meta)); + require!(config.wrong_rlp_key.key_len() => config.rlp_key[false.idx()].key_len()); // RLC bytes zero check - let num_bytes = storage.num_bytes_on_key_row(meta); + let num_bytes = config.wrong_rlp_key.num_bytes_on_key_row(); //cb.set_length(num_bytes); } elsex { // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. - require!(key_data.is_placeholder_leaf_c => true); + require!(config.key_data_w.is_placeholder_leaf_c => true); }} - ctx_key_data_w = key_data; } elsex { // is_wrong_leaf needs to be false when not in non_existing_account proof - require!(is_wrong_leaf => false); + require!(config.is_wrong_leaf => false); }} - ctx_diff_inv = diff_inv; }); - StorageLeafConfig { - key_data_s: ctx_key_data_s.unwrap(), - key_data_c: ctx_key_data_c.unwrap(), - key_data_w: ctx_key_data_w, - parent_data_s: ctx_parent_data_s.unwrap(), - parent_data_c: ctx_parent_data_c.unwrap(), - diff_inv: ctx_diff_inv, - } + config } pub fn assign( @@ -439,73 +376,26 @@ impl StorageLeafConfig { for is_s in [true, false] { /* KEY */ - { - let row = &witness[offset]; - - // Info whether leaf rlp is long or short: - // - long means the key length is at position 2. - // - short means the key length is at position 1. - let mut typ = "short"; - if row.get_byte(0) == 248 { - typ = "long"; - } else if row.get_byte(1) == 32 { - typ = "last_level"; - } else if row.get_byte(1) < 128 { - typ = "one_nibble"; - } - mpt_config.assign_long_short(region, typ, offset).ok(); + let key_row = &witness[offset]; + + let rlp_key_witness = self.rlp_key[is_s.idx()].assign(region, base_offset, &key_row.bytes).ok().unwrap(); pv.acc_s = F::zero(); pv.acc_mult_s = F::one(); - let len: usize; - if typ == "long" { - len = (row.get_byte(2) - 128) as usize + 3; - } else if typ == "short" { - len = (row.get_byte(1) - 128) as usize + 2; - } else { - // last_level or one_nibble - len = 2 - } mpt_config.compute_acc_and_mult( - &row.bytes, + &key_row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, - len, + rlp_key_witness.num_bytes_on_key_row() as usize, ); - mpt_config - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) + self.mult[is_s.idx()] + .assign(region, base_offset, pv.acc_mult_s) .ok(); - // note that this assignment needs to be after assign_acc call - if row.get_byte(0) < 223 { - // when shorter than 32 bytes, the node doesn't get hashed - // not_hashed - region - .assign_advice( - || "assign not_hashed".to_string(), - mpt_config.accumulators.acc_c.rlc, - offset, - || Value::known(F::one()), - ) - .ok(); - } - - // TODO: handle if branch or extension node is added - let mut start = S_START - 1; - if row.get_byte(0) == 248 { - // long RLP - start = S_START; - } + self.is_not_hashed[is_s.idx()].assign(region, base_offset, F::from(rlp_key_witness.num_bytes()), F::from(32)).ok(); let is_branch_placeholder = if is_s { pv.is_branch_s_placeholder @@ -513,19 +403,13 @@ impl StorageLeafConfig { pv.is_branch_c_placeholder }; let load_offset = if is_branch_placeholder { 1 } else { 0 }; - - let key_data = if is_s { - &self.key_data_s - } else { - &self.key_data_c - }; - key_data.witness_load( + self.key_data[is_s.idx()].witness_load( region, base_offset, &mut pv.memory[key_memory(is_s)], load_offset, )?; - key_data.witness_store( + self.key_data[is_s.idx()].witness_store( region, base_offset, &mut pv.memory[key_memory(is_s)], @@ -540,21 +424,21 @@ impl StorageLeafConfig { let mut key_rlc_new = pv.key_rlc; let mut key_rlc_mult_new = pv.key_rlc_mult; if (pv.is_branch_s_placeholder - && row.get_type() == MptWitnessRowType::StorageLeafSKey) + && key_row.get_type() == MptWitnessRowType::StorageLeafSKey) || (pv.is_branch_c_placeholder - && row.get_type() == MptWitnessRowType::StorageLeafCKey) + && key_row.get_type() == MptWitnessRowType::StorageLeafCKey) { key_rlc_new = pv.key_rlc_prev; key_rlc_mult_new = pv.key_rlc_mult_prev; } - if typ != "last_level" && typ != "one_nibble" { + if rlp_key_witness.num_bytes_on_key_row() != 2 { // If in last level or having only one nibble, // the key RLC is already computed using the first two bytes above. mpt_config.compute_key_rlc( - &row.bytes, + &key_row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, - start, + rlp_key_witness.num_rlp_bytes_list() as usize, ); } region.assign_advice( @@ -575,67 +459,63 @@ impl StorageLeafConfig { offset += 1; { - let row_prev = &witness[offset - 1]; - let row = &witness[offset]; + //let key_row = &witness[offset - 1]; + let value_row = &witness[offset]; + + let value_witness = self.rlp_value[is_s.idx()].assign(region, base_offset, &value_row.bytes).ok().unwrap(); // Info whether leaf value is 1 byte or more: - let mut is_long = false; - if row_prev.get_byte(0) == 248 { + /*let mut is_long = false; + if key_row.get_byte(0) == 248 { // whole leaf is in long format (3 RLP meta bytes) - let key_len = row_prev.get_byte(2) - 128; - if row_prev.get_byte(1) - key_len - 1 > 1 { + let key_len = key_row.get_byte(2) - 128; + if key_row.get_byte(1) - key_len - 1 > 1 { is_long = true; } - } else if row_prev.get_byte(1) < 128 { + } else if key_row.get_byte(1) < 128 { // last_level or one_nibble - let leaf_len = row_prev.get_byte(0) - 192; + let leaf_len = key_row.get_byte(0) - 192; if leaf_len - 1 > 1 { is_long = true; } } else { - let leaf_len = row_prev.get_byte(0) - 192; - let key_len = row_prev.get_byte(1) - 128; + let leaf_len = key_row.get_byte(0) - 192; + let key_len = key_row.get_byte(1) - 128; if leaf_len - key_len - 1 > 1 { is_long = true; } - } - // Short means there is only one byte for value (no RLP specific bytes). - // Long means there is more than one byte for value which brings two - // RLP specific bytes, like: 161 160 ... for 32-long value. - let mut typ = "short"; - if is_long { - typ = "long"; - } - mpt_config.assign_long_short(region, typ, offset).ok(); + }*/ // Leaf RLC mpt_config.compute_acc_and_mult( - &row.bytes, + &value_row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, HASH_WIDTH + 2, ); - pv.acc_c = F::zero(); - pv.acc_mult_c = F::one(); + // Leaf value RLC - let mut start = 0; + /*let mut start = 0; if is_long { start = 2; - } + }*/ + + //let start = value_witness.num_rlp_bytes(); + //println!("{} == {}", start, start); + //assert!(start == test_start); + + pv.acc_c = F::zero(); + pv.acc_mult_c = F::one(); mpt_config.compute_acc_and_mult( - &row.bytes, + &value_row.bytes, &mut pv.acc_c, &mut pv.acc_mult_c, - start, + value_witness.num_rlp_bytes() as usize, HASH_WIDTH + 2, ); - let empty_trie_hash: Vec = vec![ - 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, - 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, - ]; if is_s { // Store leaf value RLC into rlc1 to be later set in leaf value C row (to enable // lookups): @@ -652,7 +532,7 @@ impl StorageLeafConfig { */ let row_prev = &witness[offset - 4]; if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashS - && row_prev.s_hash_bytes() == empty_trie_hash + && row_prev.s_hash_bytes() == EMPTY_TRIE_HASH { // Leaf is without branch and it is just a placeholder. region @@ -693,7 +573,7 @@ impl StorageLeafConfig { */ let row_prev = &witness[offset - 5]; if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashC - && row_prev.s_hash_bytes() == empty_trie_hash + && row_prev.s_hash_bytes() == EMPTY_TRIE_HASH { // Leaf is without branch and it is just a placeholder. region @@ -707,15 +587,10 @@ impl StorageLeafConfig { } } - let parent_data = if is_s { - &self.parent_data_s - } else { - &self.parent_data_c - }; - parent_data + self.parent_data[is_s.idx()] .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) .ok(); - parent_data + self.parent_data[is_s.idx()] .witness_store( region, base_offset, @@ -725,17 +600,6 @@ impl StorageLeafConfig { ) .ok(); - mpt_config - .assign_acc( - region, - pv.acc_s, // leaf RLC - pv.acc_mult_s, - pv.acc_c, // leaf value RLC - F::zero(), - offset, - ) - .ok(); - region .assign_advice( || "assign leaf value C into value".to_string(), @@ -745,7 +609,7 @@ impl StorageLeafConfig { ) .ok(); - if !is_s && row.get_byte_rev(IS_STORAGE_MOD_POS) == 1 { + if !is_s && value_row.get_byte_rev(IS_STORAGE_MOD_POS) == 1 { region .assign_advice( || "assign lookup enabled".to_string(), @@ -762,106 +626,68 @@ impl StorageLeafConfig { offset += 1; } - { + + if pv.is_branch_s_placeholder || pv.is_branch_c_placeholder { let row = &witness[offset]; - /* - row[1] != 0 just to avoid usize problems below (when row doesn't - need to be assigned) Info whether leaf rlp is long or short. - */ - /* - Info whether leaf rlp is long or short: - - long means the key length is at position 2. - - short means the key length is at position 1. - */ - let mut typ = "short"; - if row.get_byte(0) == 248 { - typ = "long"; - } else if row.get_byte(1) == 32 { - typ = "last_level"; - } else if row.get_byte(1) < 128 { - typ = "one_nibble"; - } - mpt_config.assign_long_short(region, typ, offset).ok(); + let drifted_key_witness = self.drifted_rlp_key.assign(region, base_offset, &row.bytes).ok().unwrap(); pv.acc_s = F::zero(); pv.acc_mult_s = F::one(); - let len: usize; - if typ == "long" { - len = (row.get_byte(2) - 128) as usize + 3; - } else if typ == "short" { - len = (row.get_byte(1) - 128) as usize + 2; - } else { - // last_level or one_nibble - len = 2 - } - mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); + mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, drifted_key_witness.num_bytes_on_key_row() as usize); - mpt_config - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) + self.drifted_mult + .assign(region, base_offset, pv.acc_mult_s) .ok(); - - offset += 1; } + offset += 1; { - self.key_data_w - .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) - .ok(); - let row = &witness[offset]; if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { + + self.key_data_w + .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) + .ok(); + + // TODO(Brecht): Change how the witness is generated + let is_wrong = row.bytes[0] != 0; + self.is_wrong_leaf.assign(region, base_offset, F::from(is_wrong)).ok(); + let row_key_c = &witness[offset - (LEAF_NON_EXISTING_IND - LEAF_KEY_C_IND) as usize]; - let mut start = S_START - 1; - if row_key_c.get_byte(0) == 248 { - start = S_START; - } + let mut row_bytes = row.bytes.clone(); + row_bytes[0] = row_key_c.bytes[0]; + + let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes).ok().unwrap(); + let mut key_rlc_new = pv.key_rlc; let mut key_rlc_mult_new = pv.key_rlc_mult; mpt_config.compute_key_rlc( &row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, - start, + wrong_witness.num_rlp_bytes_list() as usize, ); region .assign_advice( || "assign key_rlc".to_string(), - mpt_config.accumulators.key.mult, // lookup uses `key.mult` + mpt_config.mpt_table.key_rlc, offset, || Value::known(key_rlc_new), ) .ok(); - let diff_inv = (key_rlc_new - pv.storage_key_rlc) - .invert() - .unwrap_or(F::zero()); - self.diff_inv - .assign(region, base_offset, Value::known(diff_inv)) - .ok(); + self.check_is_wrong_leaf.assign(region, base_offset, key_rlc_new - pv.storage_key_rlc).ok(); - if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(7_u64)), /* non existing storage lookup - * enabled in - * this row if it is - * non_existing_storage - * proof */ - ) - .ok(); - } + region + .assign_advice( + || "assign lookup enabled".to_string(), + mpt_config.proof_type.proof_type, + offset, + || Value::known(F::from(7_u64)), + ) + .ok(); } } diff --git a/zkevm-circuits/src/mpt_circuit/witness_row.rs b/zkevm-circuits/src/mpt_circuit/witness_row.rs index 7275d9665e..455c203c8d 100644 --- a/zkevm-circuits/src/mpt_circuit/witness_row.rs +++ b/zkevm-circuits/src/mpt_circuit/witness_row.rs @@ -1,5 +1,5 @@ +use eth_types::Field; use halo2_proofs::{ - arithmetic::FieldExt, circuit::{Region, Value}, plonk::Error, }; @@ -49,7 +49,7 @@ pub struct MptWitnessRow { _marker: PhantomData, } -impl MptWitnessRow { +impl MptWitnessRow { pub fn new(bytes: Vec) -> Self { Self { bytes, From 63ce1a99c993ae69cb459a0e378e60e5a4453b11 Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Wed, 15 Feb 2023 03:15:11 +0100 Subject: [PATCH 05/11] Storage root improvements --- gadgets/src/util.rs | 65 +++- zkevm-circuits/src/circuit_tools.rs | 2 +- .../src/circuit_tools/constraint_builder.rs | 27 +- zkevm-circuits/src/circuit_tools/gadgets.rs | 32 +- zkevm-circuits/src/mpt_circuit.rs | 23 +- .../src/mpt_circuit/account_leaf.rs | 10 +- zkevm-circuits/src/mpt_circuit/branch.rs | 3 +- zkevm-circuits/src/mpt_circuit/helpers.rs | 190 +++++----- zkevm-circuits/src/mpt_circuit/param.rs | 2 +- .../src/mpt_circuit/storage_leaf.rs | 342 ++++++------------ zkevm-circuits/src/table.rs | 2 + 11 files changed, 319 insertions(+), 379 deletions(-) diff --git a/gadgets/src/util.rs b/gadgets/src/util.rs index 0deec25432..95402314ef 100644 --- a/gadgets/src/util.rs +++ b/gadgets/src/util.rs @@ -132,6 +132,35 @@ pub mod select { } } + +/// Trait that implements functionality to get a scalar from +/// commonly used types. +pub trait Scalar { + /// Returns a scalar for the type. + fn scalar(&self) -> F; +} + +/// Implementation trait `Scalar` for type able to be casted to u64 +#[macro_export] +macro_rules! impl_scalar { + ($type:ty) => { + impl $crate::util::Scalar for $type { + #[inline] + fn scalar(&self) -> F { + F::from(*self as u64) + } + } + }; + ($type:ty, $method:path) => { + impl $crate::util::Scalar for $type { + #[inline] + fn scalar(&self) -> F { + F::from($method(self) as u64) + } + } + }; +} + /// Trait that implements functionality to get a constant expression from /// commonly used types. pub trait Expr { @@ -143,6 +172,7 @@ pub trait Expr { #[macro_export] macro_rules! impl_expr { ($type:ty) => { + $crate::impl_scalar!($type); impl $crate::util::Expr for $type { #[inline] fn expr(&self) -> Expression { @@ -151,6 +181,7 @@ macro_rules! impl_expr { } }; ($type:ty, $method:path) => { + $crate::impl_scalar!($type, $method); impl $crate::util::Expr for $type { #[inline] fn expr(&self) -> Expression { @@ -168,6 +199,25 @@ impl_expr!(isize); impl_expr!(OpcodeId, OpcodeId::as_u8); impl_expr!(GasCost, GasCost::as_u64); +impl Scalar for i32 { + #[inline] + fn scalar(&self) -> F { + F::from(self.unsigned_abs() as u64) + * if self.is_negative() { + -F::one() + } else { + F::one() + } + } +} + +impl Expr for i32 { + #[inline] + fn expr(&self) -> Expression { + Expression::Constant(self.scalar()) + } +} + impl Expr for Expression { #[inline] fn expr(&self) -> Expression { @@ -182,19 +232,12 @@ impl Expr for &Expression { } } -impl Expr for i32 { +/*impl Scalar for FieldExt { #[inline] - fn expr(&self) -> Expression { - Expression::Constant( - F::from(self.unsigned_abs() as u64) - * if self.is_negative() { - -F::one() - } else { - F::one() - }, - ) + fn scalar(&self) -> FieldExt { + self.clone() } -} +}*/ /// Given a bytes-representation of an expression, it computes and returns the /// single expression. diff --git a/zkevm-circuits/src/circuit_tools.rs b/zkevm-circuits/src/circuit_tools.rs index b22beed8de..25519a2ba0 100644 --- a/zkevm-circuits/src/circuit_tools.rs +++ b/zkevm-circuits/src/circuit_tools.rs @@ -2,5 +2,5 @@ #[macro_use] pub mod constraint_builder; pub mod cell_manager; +pub mod gadgets; pub mod memory; -pub mod gadgets; \ No newline at end of file diff --git a/zkevm-circuits/src/circuit_tools/constraint_builder.rs b/zkevm-circuits/src/circuit_tools/constraint_builder.rs index d0c1c4c28d..6a23a7722d 100644 --- a/zkevm-circuits/src/circuit_tools/constraint_builder.rs +++ b/zkevm-circuits/src/circuit_tools/constraint_builder.rs @@ -2,9 +2,7 @@ use crate::{evm_circuit::util::rlc, util::Expr}; use eth_types::Field; use gadgets::util::{and, select, sum}; -use halo2_proofs::{ - plonk::{ConstraintSystem, Expression}, -}; +use halo2_proofs::plonk::{ConstraintSystem, Expression}; use itertools::Itertools; use super::cell_manager::{Cell, CellManager, CellType, DataTransition, Trackable}; @@ -152,7 +150,10 @@ impl ConstraintBuilder { } fn query_cells(&mut self, cell_type: CellType, count: usize) -> Vec> { - self.cell_manager.as_mut().unwrap().query_cells(cell_type, count) + self.cell_manager + .as_mut() + .unwrap() + .query_cells(cell_type, count) } pub(crate) fn validate_degree(&self, degree: usize, name: &'static str) { @@ -939,6 +940,24 @@ macro_rules! matchw { }}; } +/// assign +#[macro_export] +macro_rules! assign { + ($region:expr, ($column:expr, $offset:expr) => $value:expr) => {{ + let description = $crate::concat_with_preamble!( + stringify!($column), + " => ", + stringify!($value) + ); + let value: F = $value; + $region.assign_advice( + || description, + $column, + $offset, + || Value::known(value), + ) + }}; +} /// Circuit builder macros /// Nested macro's can't do repetition (https://github.com/rust-lang/rust/issues/35853) diff --git a/zkevm-circuits/src/circuit_tools/gadgets.rs b/zkevm-circuits/src/circuit_tools/gadgets.rs index 95e6732221..7b39319e7e 100644 --- a/zkevm-circuits/src/circuit_tools/gadgets.rs +++ b/zkevm-circuits/src/circuit_tools/gadgets.rs @@ -2,13 +2,13 @@ use eth_types::Field; use gadgets::util::Expr; use halo2_proofs::{ - circuit::{Region}, + circuit::Region, plonk::{Error, Expression}, }; use crate::evm_circuit::util::{from_bytes, pow_of_two}; -use super::{constraint_builder::ConstraintBuilder, cell_manager::{Cell}}; +use super::{cell_manager::Cell, constraint_builder::ConstraintBuilder}; /// Returns `1` when `value == 0`, and returns `0` otherwise. #[derive(Clone, Debug, Default)] @@ -28,9 +28,11 @@ impl IsZeroGadget { // `value == 0` => check `inverse = 0`: `inverse â‹… (1 - value * inverse)` require!(inverse.expr() * is_zero.expr() => 0); - Self { inverse, is_zero: Some(is_zero) } + Self { + inverse, + is_zero: Some(is_zero), + } }) - } pub(crate) fn expr(&self) -> Expression { @@ -66,7 +68,6 @@ impl RequireNotZeroGadget { require!(value.expr() * inverse.expr() =>1); Self { inverse } }) - } pub(crate) fn assign( @@ -147,7 +148,11 @@ impl LtGadget { from_bytes::expr(&diff) - (lt.expr() * range), ); - Self { lt, diff: Some(diff), range } + Self { + lt, + diff: Some(diff), + range, + } } pub(crate) fn expr(&self) -> Expression { @@ -163,21 +168,14 @@ impl LtGadget { ) -> Result<(F, Vec), Error> { // Set `lt` let lt = lhs < rhs; - self.lt.assign( - region, - offset, - if lt { F::one() } else { F::zero() }, - )?; + self.lt + .assign(region, offset, if lt { F::one() } else { F::zero() })?; // Set the bytes of diff let diff = (lhs - rhs) + (if lt { self.range } else { F::zero() }); let diff_bytes = diff.to_repr(); for (idx, diff) in self.diff.as_ref().unwrap().iter().enumerate() { - diff.assign( - region, - offset, - F::from(diff_bytes[idx] as u64), - )?; + diff.assign(region, offset, F::from(diff_bytes[idx] as u64))?; } Ok((if lt { F::one() } else { F::zero() }, diff_bytes.to_vec())) @@ -186,4 +184,4 @@ impl LtGadget { pub(crate) fn diff_bytes(&self) -> Vec> { self.diff.as_ref().unwrap().to_vec() } -} \ No newline at end of file +} diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index efa337a99a..1f1fc8c945 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -31,7 +31,11 @@ use selectors::SelectorsConfig; use crate::{ circuit, - circuit_tools::{cell_manager::CellManager, constraint_builder::{merge_lookups, RLCable}, memory::Memory}, + circuit_tools::{ + cell_manager::CellManager, + constraint_builder::{merge_lookups, RLCable}, + memory::Memory, + }, mpt_circuit::{ helpers::{extend_rand, parent_memory, KeyData, MPTConstraintBuilder, ParentData}, storage_leaf::StorageLeafConfig, @@ -122,11 +126,7 @@ impl MPTContext { .to_vec() } - pub(crate) fn expr( - &self, - meta: &mut VirtualCells, - rot: i32, - ) -> Vec> { + pub(crate) fn expr(&self, meta: &mut VirtualCells, rot: i32) -> Vec> { self.rlp_bytes() .iter() .map(|&byte| meta.query_advice(byte, Rotation(rot))) @@ -269,7 +269,6 @@ pub(crate) struct ProofValues { pub(crate) nibbles_num: usize, pub(crate) account_key_rlc: F, - pub(crate) storage_key_rlc: F, pub(crate) is_hashed_s: bool, pub(crate) is_hashed_c: bool, @@ -556,8 +555,9 @@ impl MPTConfig { } else if disable_lookups == 2 { cb.base.generate_lookups(meta, &ctx.memory.tags()); } else if disable_lookups == 3 { - cb.base.generate_lookups(meta, &vec!["fixed".to_string(), "keccak".to_string()]); - } else if disable_lookups == 4 { + cb.base + .generate_lookups(meta, &vec!["fixed".to_string(), "keccak".to_string()]); + } else if disable_lookups == 4 { cb.base.generate_lookups(meta, &vec!["keccak".to_string()]); } @@ -1144,7 +1144,10 @@ mod tests { use super::*; - use halo2_proofs::{dev::MockProver, halo2curves::{bn256::Fr, FieldExt}}; + use halo2_proofs::{ + dev::MockProver, + halo2curves::{bn256::Fr, FieldExt}, + }; use std::fs; diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index fd5933813e..0d61c81558 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -1,7 +1,5 @@ use eth_types::Field; -use halo2_proofs::{ - plonk::{Advice, Column, ConstraintSystem, Expression}, -}; +use halo2_proofs::plonk::{Advice, Column, ConstraintSystem, Expression}; use halo2_proofs::{ circuit::{Region, Value}, plonk::{Error, VirtualCells}, @@ -14,13 +12,13 @@ use crate::{ circuit_tools::cell_manager::{Cell, DataTransition}, circuit_tools::constraint_builder::{ConstraintBuilder, RLCable}, mpt_circuit::{ - helpers::{BranchNodeInfo, get_num_bytes_short}, + helpers::{get_num_bytes_short, BranchNodeInfo}, param::{BRANCH_ROWS_NUM, S_START}, }, mpt_circuit::{ helpers::{ - get_num_nibbles, get_parent_rlc_state, key_memory, parent_memory, - AccountLeafInfo, KeyData, MPTConstraintBuilder, ParentData, + get_num_nibbles, get_parent_rlc_state, key_memory, parent_memory, AccountLeafInfo, + KeyData, MPTConstraintBuilder, ParentData, }, param::{KEY_LEN_IN_NIBBLES, RLP_HASH_VALUE, RLP_LIST_LONG, RLP_LONG}, FixedTableTag, diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index b39e914ce8..827059aaea 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -1,6 +1,5 @@ use eth_types::Field; use halo2_proofs::{ - circuit::{Region, Value}, plonk::{Advice, Column, ConstraintSystem, Error, VirtualCells}, poly::Rotation, @@ -322,7 +321,7 @@ impl BranchConfig { 0.expr(), ); ifx! {not!(branch.is_placeholder()) => { - ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(is_not_hashed)]) => { + ifx!{or::expr(&[parent_data.is_root.expr(), not!(is_not_hashed)]) => { // Hashed branch hash in parent branch // TODO(Brecht): fix //require!((1, rlc, num_bytes, parent_data.rlc) => @"keccak"); diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index ec5fe68521..76403f0260 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -5,19 +5,21 @@ use crate::{ circuit_tools::{ cell_manager::{Cell, CellManager, DataTransition, Trackable}, constraint_builder::{Conditionable, ConstraintBuilder, RLCChainable, RLCable}, - memory::MemoryBank, gadgets::IsEqualGadget, + gadgets::IsEqualGadget, + memory::MemoryBank, }, evm_circuit::util::rlc, + matchr, matchw, mpt_circuit::param::{ KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN, RLP_HASH_VALUE, RLP_LIST_LONG, RLP_LIST_SHORT, RLP_NIL, RLP_SHORT, }, - util::Expr, matchw, matchr, + util::Expr, }; use eth_types::Field; use gadgets::util::{and, not}; use halo2_proofs::{ - circuit::{Region}, + circuit::Region, plonk::{Error, Expression, VirtualCells}, poly::Rotation, }; @@ -25,13 +27,13 @@ use halo2_proofs::{ use super::{ columns::MainCols, param::{ - ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, + ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, ACCOUNT_NON_EXISTING_IND, ARITY, BRANCH_0_C_START, BRANCH_0_S_START, BRANCH_ROWS_NUM, IS_BRANCH_C16_POS, IS_BRANCH_C1_POS, IS_BRANCH_C_PLACEHOLDER_POS, IS_BRANCH_S_PLACEHOLDER_POS, IS_C_BRANCH_NON_HASHED_POS, IS_C_EXT_LONGER_THAN_55_POS, IS_C_EXT_NODE_NON_HASHED_POS, IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_LONGER_THAN_55_POS, - IS_S_EXT_NODE_NON_HASHED_POS, KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, NIBBLES_COUNTER_POS, RLP_LONG, + IS_S_EXT_NODE_NON_HASHED_POS, KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, NIBBLES_COUNTER_POS, + RLP_LONG, }, witness_row::MptWitnessRow, FixedTableTag, MPTConfig, MPTContext, ProofValues, @@ -76,7 +78,6 @@ pub(crate) trait Gadget { ) -> Result<(), Error>; } - #[derive(Clone, Debug, Default)] pub(crate) struct RLPListGadget { pub(crate) is_short: Cell, @@ -92,10 +93,7 @@ pub(crate) struct RLPListWitness { } impl RLPListGadget { - pub(crate) fn construct( - cb: &mut ConstraintBuilder, - bytes: &[Expression], - ) -> Self { + pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { // TODO(Brecht): add lookup RLPListGadget { is_short: cb.query_cell(), @@ -211,7 +209,6 @@ impl RLPListWitness { } } - #[derive(Clone, Debug, Default)] pub(crate) struct RLPValueGadget { pub(crate) is_short: Cell, @@ -229,10 +226,7 @@ pub(crate) struct RLPValueWitness { } impl RLPValueGadget { - pub(crate) fn construct( - cb: &mut ConstraintBuilder, - bytes: &[Expression], - ) -> Self { + pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { // TODO(Brecht): add lookup RLPValueGadget { is_short: cb.query_cell(), @@ -264,7 +258,8 @@ impl RLPValueGadget { self.is_short.assign(region, offset, F::from(is_short))?; self.is_long.assign(region, offset, F::from(is_long))?; - self.is_very_long.assign(region, offset, F::from(is_very_long))?; + self.is_very_long + .assign(region, offset, F::from(is_very_long))?; Ok(RLPValueWitness { is_short, @@ -350,7 +345,6 @@ impl RLPValueGadget { } } - impl RLPValueWitness { // Single RLP byte containing the byte value pub(crate) fn is_short(&self) -> bool { @@ -400,7 +394,6 @@ impl RLPValueWitness { } } - #[derive(Clone, Debug, Default)] pub(crate) struct LeafKeyGadget { rlp_list: RLPListGadget, @@ -420,16 +413,21 @@ pub(crate) struct LeafKeyWitness { } impl LeafKeyGadget { - pub(crate) fn construct( - cb: &mut ConstraintBuilder, - bytes: &[Expression], - ) -> Self { + pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { LeafKeyGadget { rlp_list: RLPListGadget::construct(cb, bytes), short_list_value: RLPValueGadget::construct(cb, &bytes[1..]), long_list_value: RLPValueGadget::construct(cb, &bytes[2..]), - short_list_has_no_nibbles: IsEqualGadget::::construct(cb, bytes[1].expr(), KEY_TERMINAL_PREFIX_EVEN.expr()), - long_list_has_no_nibbles: IsEqualGadget::::construct(cb, bytes[2].expr(), KEY_TERMINAL_PREFIX_EVEN.expr()), + short_list_has_no_nibbles: IsEqualGadget::::construct( + cb, + bytes[1].expr(), + KEY_TERMINAL_PREFIX_EVEN.expr(), + ), + long_list_has_no_nibbles: IsEqualGadget::::construct( + cb, + bytes[2].expr(), + KEY_TERMINAL_PREFIX_EVEN.expr(), + ), bytes: bytes.to_vec(), } } @@ -443,8 +441,18 @@ impl LeafKeyGadget { let rlp_list = self.rlp_list.assign(region, offset, bytes)?; let short_list_value = self.short_list_value.assign(region, offset, &bytes[1..])?; let long_list_value = self.long_list_value.assign(region, offset, &bytes[2..])?; - self.short_list_has_no_nibbles.assign(region, offset, F::from(bytes[1] as u64), F::from(KEY_TERMINAL_PREFIX_EVEN as u64))?; - self.long_list_has_no_nibbles.assign(region, offset, F::from(bytes[2] as u64), F::from(KEY_TERMINAL_PREFIX_EVEN as u64))?; + self.short_list_has_no_nibbles.assign( + region, + offset, + F::from(bytes[1] as u64), + F::from(KEY_TERMINAL_PREFIX_EVEN as u64), + )?; + self.long_list_has_no_nibbles.assign( + region, + offset, + F::from(bytes[2] as u64), + F::from(KEY_TERMINAL_PREFIX_EVEN as u64), + )?; Ok(LeafKeyWitness { rlp_list, short_list_value, @@ -512,7 +520,6 @@ impl LeafKeyGadget { }) } - /// Returns the total length of the leaf (including RLP bytes) pub(crate) fn num_bytes(&self) -> Expression { self.rlp_list.num_bytes() @@ -521,14 +528,15 @@ impl LeafKeyGadget { /// Number of RLP bytes for leaf and key pub(crate) fn num_rlp_bytes(&self) -> Expression { circuit!([meta, _cb!()], { - self.rlp_list.num_rlp_bytes() + matchx! { - self.rlp_list.is_short() => { - self.short_list_value.num_rlp_bytes() - }, - self.rlp_list.is_long() => { - self.long_list_value.num_rlp_bytes() - }, - } + self.rlp_list.num_rlp_bytes() + + matchx! { + self.rlp_list.is_short() => { + self.short_list_value.num_rlp_bytes() + }, + self.rlp_list.is_long() => { + self.long_list_value.num_rlp_bytes() + }, + } }) } @@ -549,21 +557,19 @@ impl LeafKeyGadget { /// Number of bytes of RLP (including list RLP bytes) and key pub(crate) fn num_bytes_on_key_row(&self) -> Expression { circuit!([meta, _cb!()], { - self.rlp_list.num_rlp_bytes() + matchx! { - self.rlp_list.is_short() => { - self.short_list_value.num_bytes() - }, - self.rlp_list.is_long() => { - self.long_list_value.num_bytes() - }, - } + self.rlp_list.num_rlp_bytes() + + matchx! { + self.rlp_list.is_short() => { + self.short_list_value.num_bytes() + }, + self.rlp_list.is_long() => { + self.long_list_value.num_bytes() + }, + } }) } - pub(crate) fn num_key_nibbles( - &self, - is_key_odd: Expression, - ) -> Expression { + pub(crate) fn num_key_nibbles(&self, is_key_odd: Expression) -> Expression { get_num_nibbles(self.key_len(), is_key_odd) } } @@ -581,13 +587,14 @@ impl LeafKeyWitness { /// Number of RLP bytes for leaf and key pub(crate) fn num_rlp_bytes(&self) -> u64 { - self.rlp_list.num_rlp_bytes() + if self.rlp_list.is_short() { - self.short_list_value.num_rlp_bytes() - } else if self.rlp_list.is_long() { - self.long_list_value.num_rlp_bytes() - } else { - unreachable!(); - } + self.rlp_list.num_rlp_bytes() + + if self.rlp_list.is_short() { + self.short_list_value.num_rlp_bytes() + } else if self.rlp_list.is_long() { + self.long_list_value.num_rlp_bytes() + } else { + unreachable!(); + } } /// Length of the key (excluding RLP bytes) @@ -604,17 +611,17 @@ impl LeafKeyWitness { /// Number of bytes of RLP (including list RLP bytes) and key pub(crate) fn num_bytes_on_key_row(&self) -> u64 { - self.rlp_list.num_rlp_bytes() + if self.rlp_list.is_short() { - self.short_list_value.num_bytes() - } else if self.rlp_list.is_long() { - self.long_list_value.num_bytes() - } else { - unreachable!(); - } + self.rlp_list.num_rlp_bytes() + + if self.rlp_list.is_short() { + self.short_list_value.num_bytes() + } else if self.rlp_list.is_long() { + self.long_list_value.num_bytes() + } else { + unreachable!(); + } } } - #[derive(Clone, Debug, Default)] pub(crate) struct KeyData { pub(crate) rlc: Cell, @@ -752,7 +759,7 @@ impl KeyData { #[derive(Clone, Debug, Default)] pub(crate) struct ParentData { pub(crate) rlc: Cell, - pub(crate) force_hashed: Cell, + pub(crate) is_root: Cell, } impl ParentData { @@ -764,14 +771,14 @@ impl ParentData { ) -> Self { let parent_data = ParentData { rlc: cb.query_cell(), - force_hashed: cb.query_cell(), + is_root: cb.query_cell(), }; circuit!([meta, cb], { memory.load( description, cb, offset, - &[parent_data.rlc.expr(), parent_data.force_hashed.expr()], + &[parent_data.rlc.expr(), parent_data.is_root.expr()], ); }); parent_data @@ -809,13 +816,13 @@ impl ParentData { offset: usize, memory: &MemoryBank, load_offset: usize, - ) -> Result<(), Error> { + ) -> Result, Error> { let values = memory.witness_load(load_offset); self.rlc.assign(region, offset, values[0])?; - self.force_hashed.assign(region, offset, values[1])?; + self.is_root.assign(region, offset, values[1])?; - Ok(()) + Ok(values) } } @@ -1409,11 +1416,7 @@ pub(crate) struct StorageLeafInfo { } impl StorageLeafInfo { - pub(crate) fn new( - ctx: MPTContext, - is_s: bool, - rot_key: i32, - ) -> Self { + pub(crate) fn new(ctx: MPTContext, is_s: bool, rot_key: i32) -> Self { StorageLeafInfo { is_s, ctx: ctx.clone(), @@ -1429,29 +1432,6 @@ impl StorageLeafInfo { let rot_parent = if self.is_s { -1 } else { -3 }; self.ctx.is_account(meta, self.rot_key + rot_parent) } - - pub(crate) fn is_placeholder(&self, meta: &mut VirtualCells) -> Expression { - let rot_parent = if self.is_s { -1 } else { -3 }; - let rot_branch_init = rot_parent - (BRANCH_ROWS_NUM - 1); - circuit!([meta, _cb!()], { - ifx! {self.is_below_account(meta) => { - self.is_placeholder_without_branch(meta) - } elsex { - let branch = BranchNodeInfo::new(meta, self.ctx.clone(), self.is_s, self.rot_key + rot_branch_init); - branch.contains_placeholder_leaf(meta, self.is_s) - }} - }) - } - - pub(crate) fn is_placeholder_without_branch( - &self, - meta: &mut VirtualCells, - ) -> Expression { - let rot_value = 1; - circuit!([meta, _cb!()], { - a!(self.ctx.denoter.sel(self.is_s), self.rot_key + rot_value) - }) - } } #[derive(Clone)] @@ -1694,10 +1674,10 @@ pub(crate) fn get_ext_odd_nibble(byte: Expression) -> Expression // A single RLP byte pub(crate) mod get_len_short { + use crate::mpt_circuit::param::RLP_SHORT; use eth_types::Field; use gadgets::util::Expr; - use halo2_proofs::{plonk::Expression}; - use crate::mpt_circuit::param::RLP_SHORT; + use halo2_proofs::plonk::Expression; pub(crate) fn expr(byte: Expression) -> Expression { byte - RLP_SHORT.expr() @@ -1709,10 +1689,10 @@ pub(crate) mod get_len_short { // A single RLP byte + the encoded length pub(crate) mod get_num_bytes_short { + use super::get_len_short; use eth_types::Field; use gadgets::util::Expr; - use halo2_proofs::{plonk::Expression}; - use super::get_len_short; + use halo2_proofs::plonk::Expression; pub(crate) fn expr(byte: Expression) -> Expression { 1.expr() + get_len_short::expr(byte) @@ -1723,10 +1703,10 @@ pub(crate) mod get_num_bytes_short { } pub(crate) mod get_len_list_short { + use crate::mpt_circuit::param::RLP_LIST_SHORT; use eth_types::Field; use gadgets::util::Expr; - use halo2_proofs::{plonk::Expression}; - use crate::mpt_circuit::param::RLP_LIST_SHORT; + use halo2_proofs::plonk::Expression; pub(crate) fn expr(byte: Expression) -> Expression { byte - RLP_LIST_SHORT.expr() @@ -1738,10 +1718,10 @@ pub(crate) mod get_len_list_short { // A single RLP byte + the encoded length pub(crate) mod get_num_bytes_list_short { + use super::get_len_list_short; use eth_types::Field; use gadgets::util::Expr; - use halo2_proofs::{plonk::Expression}; - use super::get_len_list_short; + use halo2_proofs::plonk::Expression; pub(crate) fn expr(byte: Expression) -> Expression { 1.expr() + get_len_list_short::expr(byte) diff --git a/zkevm-circuits/src/mpt_circuit/param.rs b/zkevm-circuits/src/mpt_circuit/param.rs index 35e7d1bdde..b10631e501 100644 --- a/zkevm-circuits/src/mpt_circuit/param.rs +++ b/zkevm-circuits/src/mpt_circuit/param.rs @@ -147,4 +147,4 @@ pub const KEY_LEN_IN_NIBBLES: usize = KEY_LEN * 2; pub const EMPTY_TRIE_HASH: [u8; 32] = [ 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, -]; +]; \ No newline at end of file diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index 9ca0631527..330c719b7b 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -1,4 +1,5 @@ use eth_types::Field; +use gadgets::util::Scalar; use halo2_proofs::plonk::{Advice, Column, ConstraintSystem}; use halo2_proofs::{ circuit::{Region, Value}, @@ -7,19 +8,21 @@ use halo2_proofs::{ }; use std::marker::PhantomData; -use crate::circuit_tools::cell_manager::{Cell}; +use crate::circuit_tools::cell_manager::Cell; use crate::circuit_tools::constraint_builder::{ConstraintBuilder, RLCChainable, RLCable}; -use crate::circuit_tools::gadgets::{RequireNotZeroGadget, LtGadget}; +use crate::circuit_tools::gadgets::{LtGadget, RequireNotZeroGadget, IsEqualGadget}; +use crate::table::ProofType; use crate::{ + assign, circuit, mpt_circuit::{ helpers::BranchNodeInfo, - param::{BRANCH_ROWS_NUM, S_START}, + param::{BRANCH_ROWS_NUM}, }, mpt_circuit::{ helpers::{ - get_parent_rlc_state, key_memory, parent_memory, KeyData, - MPTConstraintBuilder, ParentData, StorageLeafInfo, + get_parent_rlc_state, key_memory, parent_memory, KeyData, MPTConstraintBuilder, + ParentData, StorageLeafInfo, }, param::{ EMPTY_TRIE_HASH, HASH_WIDTH, IS_NON_EXISTING_STORAGE_POS, IS_STORAGE_MOD_POS, @@ -34,7 +37,7 @@ use crate::{ mpt_circuit::{MPTConfig, ProofValues}, }; -use super::helpers::{Indexable, RLPValueGadget, LeafKeyGadget}; +use super::helpers::{Indexable, LeafKeyGadget, RLPValueGadget, bytes_into_rlc}; #[derive(Clone, Debug)] pub(crate) struct StorageLeafCols { @@ -107,6 +110,8 @@ pub(crate) struct StorageLeafConfig { is_wrong_leaf: Cell, check_is_wrong_leaf: RequireNotZeroGadget, is_not_hashed: [LtGadget; 2], + is_in_empty_trie: [IsEqualGadget; 2], + is_in_empty_branch: [IsEqualGadget; 2], } impl StorageLeafConfig { @@ -135,35 +140,49 @@ impl StorageLeafConfig { let mut value_rlc = vec![0.expr(); 2]; let mut leaf_rlc_value = vec![0.expr(); 2]; for is_s in [true, false] { - let storage = StorageLeafInfo::new(ctx.clone(), is_s, offset); + // Parent data + let parent_data = &mut config.parent_data[is_s.idx()]; + *parent_data = ParentData::load( + "leaf load", + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + 0.expr(), + ); + branch.set_is_s(is_s); - // Load the last key values, which depends on the branch being a placeholder. - let is_branch_placeholder = - ifx! {not!(storage.is_below_account(meta)) => { branch.is_placeholder() }}; + // Key data + let is_branch_placeholder = ifx! {not!(parent_data.is_root) => { branch.is_placeholder() }}; let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; let key_data = &mut config.key_data[is_s.idx()]; *key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], load_offset); - let rlp_key = &mut config.rlp_key[is_s.idx()] ; - *rlp_key = LeafKeyGadget::construct(&mut cb.base, &ctx.expr(meta, offset)); + // Placeholder checks + let empty_root_rlc = EMPTY_TRIE_HASH.iter().map(|v| v.expr()).collect::>().rlc(&r); + config.is_in_empty_trie[is_s.idx()] = IsEqualGadget::construct(&mut cb.base, parent_data.rlc.expr(), empty_root_rlc.expr()); + config.is_in_empty_branch[is_s.idx()] = IsEqualGadget::construct(&mut cb.base, parent_data.rlc.expr(), 128.expr()); + let is_placeholder = or::expr(&[config.is_in_empty_trie[is_s.idx()].expr(), config.is_in_empty_branch[is_s.idx()].expr()]); // Calculate and store the leaf data RLC let leaf_rlc_key = ctx.rlc(meta, 0..36, offset); - key_rlc[is_s.idx()] = key_data.rlc.expr() + rlp_key.key_rlc( - &mut cb.base, - key_data.mult.expr(), - key_data.is_odd.expr(), - 1.expr(), - true, - &r, - ); + let rlp_key = &mut config.rlp_key[is_s.idx()]; + *rlp_key = LeafKeyGadget::construct(&mut cb.base, &ctx.expr(meta, offset)); + + key_rlc[is_s.idx()] = key_data.rlc.expr() + + rlp_key.key_rlc( + &mut cb.base, + key_data.mult.expr(), + key_data.is_odd.expr(), + 1.expr(), + true, + &r, + ); // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES (except in a // placeholder leaf). // TODO(Brecht): why not in placeholder leaf? - ifx! {not!(storage.is_placeholder(meta)) => { + ifx! {not!(is_placeholder) => { let num_nibbles = rlp_key.num_key_nibbles(key_data.is_odd.expr()); require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); }} @@ -185,19 +204,18 @@ impl StorageLeafConfig { offset += 1; - let rlp_value = &mut config.rlp_value[is_s.idx()] ; + let rlp_value = &mut config.rlp_value[is_s.idx()]; *rlp_value = RLPValueGadget::construct(&mut cb.base, &s_main.expr(meta, offset)); - let (rlp_new_value_rlc, rlp_leaf_rlc_value_part) = rlp_value.rlc(&r); - value_rlc[is_s.idx()] = rlp_new_value_rlc.expr(); - leaf_rlc_value[is_s.idx()] = rlp_leaf_rlc_value_part.expr(); - let leaf_rlc = (leaf_rlc_key, config.mult[is_s.idx()].expr()).rlc_chain(rlp_leaf_rlc_value_part.expr()); + (value_rlc[is_s.idx()], leaf_rlc_value[is_s.idx()]) = rlp_value.rlc(&r); + let leaf_rlc = (leaf_rlc_key, config.mult[is_s.idx()].expr()) + .rlc_chain(leaf_rlc_value[is_s.idx()].expr()); // If `is_modified_node_empty = 1`, which means an empty child, we need to // ensure that the value is set to 0 in the placeholder leaf. For // example when adding a new storage leaf to the trie, we have an empty child in // `S` proof and non-empty in `C` proof. - ifx! {branch.contains_placeholder_leaf(meta, is_s) => { - require!(a!(s_main.rlp1, offset) => 0); + ifx! {is_placeholder => { + require!(value_rlc[is_s.idx()] => 0); }} // Number of bytes used by the leaf in total @@ -209,36 +227,21 @@ impl StorageLeafConfig { // storage = [key, value] // TODO(Brecht): modify the witness for empty placeholder leafs to have valid // RLP encoding - ifx! {not!(branch.contains_placeholder_leaf(meta, is_s)) => { + ifx! {not!(is_placeholder) => { let key_num_bytes = rlp_key.num_bytes_on_key_row(); require!(num_bytes => key_num_bytes.expr() + value_num_bytes.expr()); }}; // Check if the account is in its parent. - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let parent_data = &mut config.parent_data[is_s.idx()]; - *parent_data = ParentData::load( - "leaf load", - &mut cb.base, - &ctx.memory[parent_memory(is_s)], - 0.expr(), - ); // Check is skipped for placeholder leafs which are dummy leafs - ifx! {storage.is_below_account(meta), storage.is_placeholder_without_branch(meta) => { - // TODO(Brecht): Add this to the keccak table when necessary instead? - // Hash of the only storage leaf which is placeholder requires empty storage root - let empty_root_rlc = EMPTY_TRIE_HASH.iter().map(|v| v.expr()).collect::>().rlc(&r); - require!(parent_data.rlc => empty_root_rlc); - } elsex { - ifx!{not!(and::expr(&[not!(storage.is_below_account(meta)), branch.contains_placeholder_leaf(meta, is_s)])) => { - config.is_not_hashed[is_s.idx()] = LtGadget::construct(&mut cb.base, num_bytes.expr(), 32.expr()); - ifx!{or::expr(&[parent_data.force_hashed.expr(), not!(config.is_not_hashed[is_s.idx()])]) => { - // Hashed branch hash in parent branch - require!((1, leaf_rlc, num_bytes, parent_data.rlc) => @"keccak"); - } elsex { - // Non-hashed branch hash in parent branch - require!(leaf_rlc => parent_data.rlc); - }} + ifx! {not!(is_placeholder) => { + config.is_not_hashed[is_s.idx()] = LtGadget::construct(&mut cb.base, num_bytes.expr(), 32.expr()); + ifx!{or::expr(&[parent_data.is_root.expr(), not!(config.is_not_hashed[is_s.idx()])]) => { + // Hashed branch hash in parent branch + require!((1, leaf_rlc, num_bytes, parent_data.rlc) => @"keccak"); + } elsex { + // Non-hashed branch hash in parent branch + require!(leaf_rlc => parent_data.rlc); }} }} // Store the new parent @@ -262,8 +265,6 @@ impl StorageLeafConfig { // Drifted leaf let storage = StorageLeafInfo::new(ctx.clone(), true, 0); ifx! {branch.is_placeholder_s_or_c(), not!(storage.is_below_account(meta)) => { - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - config.drifted_rlp_key = LeafKeyGadget::construct(&mut cb.base, &ctx.expr(meta, offset)); // Calculate and store the leaf RLC (RLP + key) @@ -341,9 +342,11 @@ impl StorageLeafConfig { false, &ctx.r, ); - require!(a!(ctx.mpt_table.key_rlc, offset) => key_rlc_wrong); - // Now make sure this address is different than the one of the leaf + // TODO(Brecht): only checks the key, not prev_value/value? let key_rlc_lookup = a!(ctx.mpt_table.key_rlc, offset); + require!(key_rlc_lookup => key_rlc_wrong); + + // Now make sure this address is different than the one of the leaf config.check_is_wrong_leaf = RequireNotZeroGadget::construct(&mut cb.base, key_rlc_lookup - key_rlc[false.idx()].expr()); // Make sure the lengths of the keys are the same require!(config.wrong_rlp_key.key_len() => config.rlp_key[false.idx()].key_len()); @@ -366,7 +369,7 @@ impl StorageLeafConfig { pub fn assign( &self, region: &mut Region<'_, F>, - mpt_config: &MPTConfig, + ctx: &MPTConfig, witness: &[MptWitnessRow], pv: &mut ProofValues, offset: usize, @@ -374,16 +377,21 @@ impl StorageLeafConfig { let base_offset = offset; let mut offset = offset; + let mut key_rlc = vec![0.scalar(); 2]; + let mut value_rlc = vec![0.scalar(); 2]; for is_s in [true, false] { /* KEY */ { let key_row = &witness[offset]; - let rlp_key_witness = self.rlp_key[is_s.idx()].assign(region, base_offset, &key_row.bytes).ok().unwrap(); + let rlp_key_witness = self.rlp_key[is_s.idx()] + .assign(region, base_offset, &key_row.bytes) + .ok() + .unwrap(); pv.acc_s = F::zero(); pv.acc_mult_s = F::one(); - mpt_config.compute_acc_and_mult( + ctx.compute_acc_and_mult( &key_row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, @@ -395,7 +403,14 @@ impl StorageLeafConfig { .assign(region, base_offset, pv.acc_mult_s) .ok(); - self.is_not_hashed[is_s.idx()].assign(region, base_offset, F::from(rlp_key_witness.num_bytes()), F::from(32)).ok(); + self.is_not_hashed[is_s.idx()] + .assign( + region, + base_offset, + F::from(rlp_key_witness.num_bytes()), + F::from(32), + ) + .ok(); let is_branch_placeholder = if is_s { pv.is_branch_s_placeholder @@ -434,24 +449,14 @@ impl StorageLeafConfig { if rlp_key_witness.num_bytes_on_key_row() != 2 { // If in last level or having only one nibble, // the key RLC is already computed using the first two bytes above. - mpt_config.compute_key_rlc( + ctx.compute_key_rlc( &key_row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, rlp_key_witness.num_rlp_bytes_list() as usize, ); } - region.assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(key_rlc_new), - )?; - pv.storage_key_rlc = key_rlc_new; - - // Store key_rlc into rlc2 to be later set in leaf value C row (to enable - // lookups): - pv.rlc2 = key_rlc_new; + key_rlc[is_s.idx()] = key_rlc_new; } /* VALUE */ @@ -459,35 +464,15 @@ impl StorageLeafConfig { offset += 1; { - //let key_row = &witness[offset - 1]; let value_row = &witness[offset]; - let value_witness = self.rlp_value[is_s.idx()].assign(region, base_offset, &value_row.bytes).ok().unwrap(); - - // Info whether leaf value is 1 byte or more: - /*let mut is_long = false; - if key_row.get_byte(0) == 248 { - // whole leaf is in long format (3 RLP meta bytes) - let key_len = key_row.get_byte(2) - 128; - if key_row.get_byte(1) - key_len - 1 > 1 { - is_long = true; - } - } else if key_row.get_byte(1) < 128 { - // last_level or one_nibble - let leaf_len = key_row.get_byte(0) - 192; - if leaf_len - 1 > 1 { - is_long = true; - } - } else { - let leaf_len = key_row.get_byte(0) - 192; - let key_len = key_row.get_byte(1) - 128; - if leaf_len - key_len - 1 > 1 { - is_long = true; - } - }*/ + let value_witness = self.rlp_value[is_s.idx()] + .assign(region, base_offset, &value_row.bytes) + .ok() + .unwrap(); // Leaf RLC - mpt_config.compute_acc_and_mult( + ctx.compute_acc_and_mult( &value_row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, @@ -495,20 +480,9 @@ impl StorageLeafConfig { HASH_WIDTH + 2, ); - - // Leaf value RLC - /*let mut start = 0; - if is_long { - start = 2; - }*/ - - //let start = value_witness.num_rlp_bytes(); - //println!("{} == {}", start, start); - //assert!(start == test_start); - pv.acc_c = F::zero(); pv.acc_mult_c = F::one(); - mpt_config.compute_acc_and_mult( + ctx.compute_acc_and_mult( &value_row.bytes, &mut pv.acc_c, &mut pv.acc_mult_c, @@ -516,80 +490,11 @@ impl StorageLeafConfig { HASH_WIDTH + 2, ); - if is_s { - // Store leaf value RLC into rlc1 to be later set in leaf value C row (to enable - // lookups): - pv.rlc1 = pv.acc_c; - - /* - account leaf storage codehash S <- rotate here - account leaf storage codehash C - account leaf in added branch - leaf key S - leaf value S <- we are here - leaf key C - leaf value C - */ - let row_prev = &witness[offset - 4]; - if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashS - && row_prev.s_hash_bytes() == EMPTY_TRIE_HASH - { - // Leaf is without branch and it is just a placeholder. - region - .assign_advice( - || "assign sel1".to_string(), - mpt_config.denoter.sel1, - offset, - || Value::known(F::one()), - ) - .ok(); - } - } else { - region - .assign_advice( - || "assign key_rlc into key_rlc_mult".to_string(), - mpt_config.accumulators.key.mult, - offset, - || Value::known(pv.rlc2), - ) - .ok(); - region - .assign_advice( - || "assign leaf value S into value_prev".to_string(), - mpt_config.value_prev, - offset, - || Value::known(pv.rlc1), - ) - .ok(); - - /* - account leaf storage codehash S - account leaf storage codehash C <- rotate here - account leaf in added branch - leaf key S - leaf value S - leaf key C - leaf value C <- we are here - */ - let row_prev = &witness[offset - 5]; - if row_prev.get_type() == MptWitnessRowType::AccountLeafRootCodehashC - && row_prev.s_hash_bytes() == EMPTY_TRIE_HASH - { - // Leaf is without branch and it is just a placeholder. - region - .assign_advice( - || "assign sel2".to_string(), - mpt_config.denoter.sel2, - offset, - || Value::known(F::one()), - ) - .ok(); - } - } + value_rlc[is_s.idx()] = pv.acc_c; - self.parent_data[is_s.idx()] + let parent_values = self.parent_data[is_s.idx()] .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) - .ok(); + .ok().unwrap(); self.parent_data[is_s.idx()] .witness_store( region, @@ -600,41 +505,41 @@ impl StorageLeafConfig { ) .ok(); - region - .assign_advice( - || "assign leaf value C into value".to_string(), - mpt_config.value, - offset, - || Value::known(pv.acc_c), - ) - .ok(); + self.is_in_empty_trie[is_s.idx()].assign(region, base_offset, parent_values[0], bytes_into_rlc(&EMPTY_TRIE_HASH, ctx.randomness)).ok(); + self.is_in_empty_branch[is_s.idx()].assign(region, base_offset, parent_values[0], 128.scalar()).ok(); if !is_s && value_row.get_byte_rev(IS_STORAGE_MOD_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(6_u64)), /* storage mod lookup enabled in - * this row - * if it is is_storage_mod proof */ - ) - .ok(); + assign!(region, (ctx.proof_type.proof_type, offset) => ProofType::StorageChanged.scalar()).ok(); } } offset += 1; } + // Put the data in the lookup table + assign!(region, (ctx.mpt_table.key_rlc, offset - 1) => key_rlc[false.idx()]).ok(); + assign!(region, (ctx.mpt_table.value_prev, offset - 1) => value_rlc[true.idx()]).ok(); + assign!(region, (ctx.mpt_table.value, offset - 1) => value_rlc[false.idx()]).ok(); + // Drifted leaf handling if pv.is_branch_s_placeholder || pv.is_branch_c_placeholder { let row = &witness[offset]; - let drifted_key_witness = self.drifted_rlp_key.assign(region, base_offset, &row.bytes).ok().unwrap(); + let drifted_key_witness = self + .drifted_rlp_key + .assign(region, base_offset, &row.bytes) + .ok() + .unwrap(); pv.acc_s = F::zero(); pv.acc_mult_s = F::one(); - mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, drifted_key_witness.num_bytes_on_key_row() as usize); + ctx.compute_acc_and_mult( + &row.bytes, + &mut pv.acc_s, + &mut pv.acc_mult_s, + 0, + drifted_key_witness.num_bytes_on_key_row() as usize, + ); self.drifted_mult .assign(region, base_offset, pv.acc_mult_s) @@ -645,49 +550,42 @@ impl StorageLeafConfig { { let row = &witness[offset]; if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { - self.key_data_w .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) .ok(); // TODO(Brecht): Change how the witness is generated let is_wrong = row.bytes[0] != 0; - self.is_wrong_leaf.assign(region, base_offset, F::from(is_wrong)).ok(); + self.is_wrong_leaf + .assign(region, base_offset, F::from(is_wrong)) + .ok(); let row_key_c = &witness[offset - (LEAF_NON_EXISTING_IND - LEAF_KEY_C_IND) as usize]; let mut row_bytes = row.bytes.clone(); row_bytes[0] = row_key_c.bytes[0]; - let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes).ok().unwrap(); + let wrong_witness = self + .wrong_rlp_key + .assign(region, base_offset, &row_bytes) + .ok() + .unwrap(); let mut key_rlc_new = pv.key_rlc; let mut key_rlc_mult_new = pv.key_rlc_mult; - mpt_config.compute_key_rlc( + ctx.compute_key_rlc( &row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, wrong_witness.num_rlp_bytes_list() as usize, ); - region - .assign_advice( - || "assign key_rlc".to_string(), - mpt_config.mpt_table.key_rlc, - offset, - || Value::known(key_rlc_new), - ) - .ok(); + assign!(region, (ctx.mpt_table.key_rlc, offset) => key_rlc_new).ok(); - self.check_is_wrong_leaf.assign(region, base_offset, key_rlc_new - pv.storage_key_rlc).ok(); - - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(7_u64)), - ) + self.check_is_wrong_leaf + .assign(region, base_offset, key_rlc_new - key_rlc[false.idx()]) .ok(); + + assign!(region, (ctx.proof_type.proof_type, offset) => ProofType::StorageDoesNotExist.scalar()).ok(); } } diff --git a/zkevm-circuits/src/table.rs b/zkevm-circuits/src/table.rs index e8f62c2980..e361367910 100644 --- a/zkevm-circuits/src/table.rs +++ b/zkevm-circuits/src/table.rs @@ -442,6 +442,8 @@ pub enum ProofType { AccountDoesNotExist, /// Storage updated StorageChanged, + /// Storage does not exist + StorageDoesNotExist, } impl_expr!(ProofType); From 4ecbd0f4630e55442e43c9bc16c31d4e048bc670 Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Thu, 16 Feb 2023 03:16:09 +0100 Subject: [PATCH 06/11] More storage leaf improvements --- gadgets/src/util.rs | 1 - .../src/circuit_tools/constraint_builder.rs | 22 +- zkevm-circuits/src/circuit_tools/memory.rs | 13 +- zkevm-circuits/src/mpt_circuit.rs | 64 ++++- .../src/mpt_circuit/account_leaf.rs | 28 +- zkevm-circuits/src/mpt_circuit/branch.rs | 270 ++++++++++++------ zkevm-circuits/src/mpt_circuit/helpers.rs | 90 ++++-- zkevm-circuits/src/mpt_circuit/param.rs | 2 +- .../src/mpt_circuit/storage_leaf.rs | 234 +++++++-------- zkevm-circuits/src/table.rs | 1 + 10 files changed, 464 insertions(+), 261 deletions(-) diff --git a/gadgets/src/util.rs b/gadgets/src/util.rs index 95402314ef..7c2bc6cae1 100644 --- a/gadgets/src/util.rs +++ b/gadgets/src/util.rs @@ -132,7 +132,6 @@ pub mod select { } } - /// Trait that implements functionality to get a scalar from /// commonly used types. pub trait Scalar { diff --git a/zkevm-circuits/src/circuit_tools/constraint_builder.rs b/zkevm-circuits/src/circuit_tools/constraint_builder.rs index 6a23a7722d..f720fdeaf7 100644 --- a/zkevm-circuits/src/circuit_tools/constraint_builder.rs +++ b/zkevm-circuits/src/circuit_tools/constraint_builder.rs @@ -944,18 +944,10 @@ macro_rules! matchw { #[macro_export] macro_rules! assign { ($region:expr, ($column:expr, $offset:expr) => $value:expr) => {{ - let description = $crate::concat_with_preamble!( - stringify!($column), - " => ", - stringify!($value) - ); + let description = + $crate::concat_with_preamble!(stringify!($column), " => ", stringify!($value)); let value: F = $value; - $region.assign_advice( - || description, - $column, - $offset, - || Value::known(value), - ) + $region.assign_advice(|| description, $column, $offset, || Value::known(value)) }}; } @@ -975,20 +967,20 @@ macro_rules! circuit { #[allow(unused_macros)] macro_rules! f { ($column:expr, $rot:expr) => {{ - $meta.query_fixed($column.clone(), Rotation($cb.get_query_offset() + ($rot as i32))) + $meta.query_fixed($column.clone(), Rotation($rot as i32)) }}; ($column:expr) => {{ - $meta.query_fixed($column.clone(), Rotation($cb.get_query_offset())) + $meta.query_fixed($column.clone(), Rotation::cur()) }}; } #[allow(unused_macros)] macro_rules! a { ($column:expr, $rot:expr) => {{ - $meta.query_advice($column.clone(), Rotation($cb.get_query_offset() + ($rot as i32))) + $meta.query_advice($column.clone(), Rotation($rot as i32)) }}; ($column:expr) => {{ - $meta.query_advice($column.clone(), Rotation($cb.get_query_offset())) + $meta.query_advice($column.clone(), Rotation::cur()) }}; } diff --git a/zkevm-circuits/src/circuit_tools/memory.rs b/zkevm-circuits/src/circuit_tools/memory.rs index e68dcf637a..01f9569a71 100644 --- a/zkevm-circuits/src/circuit_tools/memory.rs +++ b/zkevm-circuits/src/circuit_tools/memory.rs @@ -11,7 +11,7 @@ use std::{ ops::{Index, IndexMut}, }; -use super::constraint_builder::ConstraintBuilder; +use super::constraint_builder::{merge_lookups, ConstraintBuilder}; #[derive(Clone, Debug, Default)] pub(crate) struct Memory { @@ -212,8 +212,7 @@ impl MemoryBank { pub(crate) fn generate_constraints(&self, cb: &mut ConstraintBuilder) { let lookup_table = cb.get_lookup_table(self.tag()); crate::circuit!([meta, cb], { - // TODO(Brecht): fix - //require!(self.next => self.cur.expr() + lookup_table.0); + require!(self.tag(), self.next => self.cur.expr() + lookup_table.0); }); } @@ -229,7 +228,9 @@ impl MemoryBank { let mut store_offsets = self.store_offsets.clone(); store_offsets.push(height); - //println!("offsets: {:?}", self.store_offsets); + /*if self.tag().starts_with("parent") { + println!("offsets: {:?}", self.store_offsets); + }*/ //println!("height: {}", height); let mut store_index = 0; @@ -242,7 +243,9 @@ impl MemoryBank { offset, || Value::known(F::from(store_index as u64)), )?; - //println!("[{}] {}: {}", self.tag(), offset, store_index); + /*if self.tag().starts_with("parent") { + println!("[{}] {}: {}", self.tag(), offset, store_index); + }*/ offset += 1; } store_index += 1; diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index 1f1fc8c945..f3533b788f 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -1,6 +1,6 @@ //! The MPT circuit implementation. use eth_types::Field; -use gadgets::impl_expr; +use gadgets::{impl_expr, util::Scalar}; use halo2_proofs::{ circuit::{Layouter, Region, SimpleFloorPlanner, Value}, plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells}, @@ -230,13 +230,15 @@ pub(crate) struct ProofValues { pub(crate) acc_mult_nonce_balance_c: F, pub(crate) acc_c: F, /* RLC accumulator for the whole node (taking into account all RLP * bytes of the node) */ - pub(crate) acc_mult_c: F, // multiplier for acc_c - pub(crate) key_rlc: F, /* used first for account address, then for storage key */ - pub(crate) key_rlc_mult: F, // multiplier for key_rlc - pub(crate) extension_node_rlc: F, // RLC accumulator for extension node - pub(crate) key_rlc_prev: F, /* for leaf after placeholder extension/branch, we need to - * go one level back - * to get previous key_rlc */ + pub(crate) acc_mult_c: F, // multiplier for acc_c + pub(crate) key_rlc: F, /* used first for account address, then for storage key */ + pub(crate) key_rlc_mult: F, // multiplier for key_rlc + pub(crate) extension_node_rlc: F, // RLC accumulator for extension node + pub(crate) extension_node_mult: F, // RLC multiplier for extension node + pub(crate) key_rlc_prev: F, /* for leaf after placeholder extension/branch, we need + * to go one level + * back + * to get previous key_rlc */ pub(crate) key_rlc_mult_prev: F, pub(crate) nibbles_num_prev: usize, pub(crate) mult_diff: F, /* power of randomness r: multiplier_curr = multiplier_prev * @@ -297,6 +299,7 @@ impl ProofValues { mult_diff: F::one(), key_rlc_sel: true, before_account_leaf: true, + extension_node_mult: F::one(), ..Default::default() } } @@ -436,7 +439,7 @@ impl MPTConfig { a!(branch.is_init) + a!(storage_leaf.is_s_key) + a!(account_leaf.is_key_s) => { for is_s in [true, false] { let root = a!(ctx.inter_root(is_s)); - ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [root, true.expr()]); + ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [root.expr(), true.expr(), false.expr(), root.expr()]); } }} @@ -520,7 +523,8 @@ impl MPTConfig { require!(@"fixed" => fixed_table.iter().map(|table| f!(table)).collect()); /* Memory banks */ - ifx!{f!(position_cols.q_enable) => { + //TODO(Brecht): change back to q_enable + ifx!{f!(position_cols.q_not_first) => { ctx.memory.generate_constraints(&mut cb.base); }} @@ -797,6 +801,10 @@ impl MPTConfig { F::zero(), F::zero(), F::zero(), + F::zero(), + F::zero(), + F::zero(), + F::one(), ]); } @@ -805,6 +813,7 @@ impl MPTConfig { .filter(|r| r.get_type() != MptWitnessRowType::HashToBeComputed) .enumerate() { + //println!("offset: {}", offset); let mut new_proof = offset == 0; if offset > 0 { let row_prev = &witness[offset - 1]; @@ -816,16 +825,28 @@ impl MPTConfig { } } + //println!("not_first_level: {}", row.not_first_level()); if new_proof { pv.memory[parent_memory(true)].witness_store( offset, - &[row.s_root_bytes_rlc(self.randomness), F::from(true)], + &[ + row.s_root_bytes_rlc(self.randomness), + true.scalar(), + false.scalar(), + row.s_root_bytes_rlc(self.randomness), + ], ); pv.memory[parent_memory(false)].witness_store( offset, - &[row.c_root_bytes_rlc(self.randomness), F::from(true)], + &[ + row.c_root_bytes_rlc(self.randomness), + true.scalar(), + false.scalar(), + row.c_root_bytes_rlc(self.randomness), + ], ); - //println!("{} -> {:?}", offset, row.get_type()); + //println!("set root: {} -> {:?}", offset, + // row.get_type()); } //println!("{} -> {:?}", offset, row.get_type()); @@ -911,6 +932,20 @@ impl MPTConfig { account_leaf.is_non_existing_account_row = true; } + /*if row.not_first_level() == 0 && (row.get_type() == MptWitnessRowType::InitBranch || + row.get_type() == MptWitnessRowType::StorageLeafSKey || + row.get_type() == MptWitnessRowType::AccountLeafKeyC) { + pv.memory[parent_memory(true)].witness_store( + offset, + &[row.s_root_bytes_rlc(self.randomness), true.scalar(), false.scalar()], + ); + pv.memory[parent_memory(false)].witness_store( + offset, + &[row.c_root_bytes_rlc(self.randomness), true.scalar(), false.scalar()], + ); + println!("set new parent: {}", offset); + }*/ + if !(row.get_type() == MptWitnessRowType::InitBranch || row.get_type() == MptWitnessRowType::BranchChild) { @@ -925,10 +960,12 @@ impl MPTConfig { } if offset > 0 && prev_row.get_type() == MptWitnessRowType::InitBranch { + println!("{}: branch", offset); self.branch_config .assign(&mut region, witness, self, &mut pv, offset) .ok(); } else if row.get_type() == MptWitnessRowType::StorageLeafSKey { + println!("{}: storage", offset); self.storage_config.assign( &mut region, self, @@ -937,6 +974,7 @@ impl MPTConfig { offset, )?; } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { + println!("{}: account", offset); self.account_config.assign( &mut region, self, diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index 0d61c81558..7ba1898dde 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -163,11 +163,10 @@ impl AccountLeafConfig { // Calculate and store the leaf data RLC require!(a!(accs.acc_s.rlc, offset) => ctx.rlc(meta, 0..36, offset)); - // Load the last key values, which depends on the branch being a placeholder. let is_branch_placeholder = ifx! {f!(ctx.position_cols.q_not_first), a!(not_first_level) => { branch.is_placeholder() }}; - let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; - let key_data = - KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], load_offset); + + // Load the last key values + let key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], 0.expr()); // Calculate the key RLC let key_rlc = key_data.rlc.expr() @@ -451,7 +450,7 @@ impl AccountLeafConfig { require!((1, account_rlc, account.num_bytes(meta), parent_data.rlc) => @"keccak"); }} // Store the new parent - ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [storage_root.expr(), true.expr()]); + ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [storage_root.expr(), true.expr(), false.expr(), storage_root.expr()]); if is_s { ctx_parent_data_s = Some(parent_data); } else { @@ -639,23 +638,12 @@ impl AccountLeafConfig { pv.acc_mult_account_c = acc_mult; } - let is_branch_placeholder = if is_s { - pv.is_branch_s_placeholder - } else { - pv.is_branch_c_placeholder - }; - let load_offset = if is_branch_placeholder { 1 } else { 0 }; let key_data = if is_s { &self.key_data_s } else { &self.key_data_c }; - key_data.witness_load( - region, - base_offset, - &mut pv.memory[key_memory(is_s)], - load_offset, - )?; + key_data.witness_load(region, base_offset, &mut pv.memory[key_memory(is_s)], 0)?; key_data.witness_store( region, base_offset, @@ -665,6 +653,10 @@ impl AccountLeafConfig { 0, false, false, + 0, + false, + F::zero(), + F::one(), )?; // For leaf S and leaf C we need to start with the same rlc. @@ -1149,6 +1141,8 @@ impl AccountLeafConfig { &mut pv.memory[parent_memory(is_s)], storage_root, true, + false, + storage_root, ) .ok(); diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index 827059aaea..7ae3111560 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -24,8 +24,8 @@ use crate::{ mpt_circuit::helpers::bytes_into_rlc, mpt_circuit::{ helpers::{ - contains_placeholder_leaf, get_num_nibbles, key_memory, parent_memory, KeyData, - ParentData, + contains_placeholder_leaf, get_num_nibbles, key_memory, parent_memory, Indexable, + KeyData, ParentData, }, param::{RLP_LIST_LONG, RLP_NIL}, storage_leaf::StorageLeaf, @@ -96,11 +96,10 @@ impl BranchCols { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub(crate) struct BranchConfig { key_data: KeyData, - parent_data_s: ParentData, - parent_data_c: ParentData, + parent_data: [ParentData; 2], } impl BranchConfig { @@ -116,9 +115,7 @@ impl BranchConfig { let r = ctx.r.clone(); cb.base.cell_manager.as_mut().unwrap().reset(); - let mut ctx_key_data: Option> = None; - let mut ctx_parent_data_s: Option> = None; - let mut ctx_parent_data_c: Option> = None; + let mut config = BranchConfig::default(); circuit!([meta, cb.base], { let mut offset = -1; @@ -314,27 +311,22 @@ impl BranchConfig { (branch_rlc, branch.num_bytes(meta), branch.is_not_hashed()) }}; - let parent_data = ParentData::load( + config.parent_data[is_s.idx()] = ParentData::load( "branch load", &mut cb.base, &ctx.memory[parent_memory(is_s)], 0.expr(), ); ifx! {not!(branch.is_placeholder()) => { - ifx!{or::expr(&[parent_data.is_root.expr(), not!(is_not_hashed)]) => { + ifx!{or::expr(&[config.parent_data[is_s.idx()].is_root.expr(), not!(is_not_hashed)]) => { // Hashed branch hash in parent branch // TODO(Brecht): fix - //require!((1, rlc, num_bytes, parent_data.rlc) => @"keccak"); + //require!((1, rlc, num_bytes, config.parent_data[is_s.idx()].rlc) => @"keccak"); } elsex { // Non-hashed branch hash in parent branch - require!(rlc => parent_data.rlc); + require!(rlc => config.parent_data[is_s.idx()].rlc); }} }} - if is_s { - ctx_parent_data_s = Some(parent_data); - } else { - ctx_parent_data_c = Some(parent_data); - } } // - For a branch placeholder we do not have any constraints. However, in the @@ -356,13 +348,21 @@ impl BranchConfig { ifx!{a!(ctx.branch.is_drifted, offset + rot) => { let branch_rlc = ctx.main(!is_s).bytes(meta, offset + rot).rlc(&r); require!(a!(accs.mod_node_rlc(is_s), offset + rot) => branch_rlc); - //ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [branch_rlc, false.expr()]); + ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [config.parent_data[is_s.idx()].rlc.expr(), config.parent_data[is_s.idx()].is_root.expr(), true.expr(), branch_rlc] + ); }} } elsex { ifx!{a!(ctx.branch.is_modified, offset + rot) => { let branch_rlc = ctx.main(is_s).bytes(meta, offset + rot).rlc(&r); require!(a!(accs.mod_node_rlc(is_s), offset + rot) => branch_rlc); - ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [branch_rlc, false.expr()]); + ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [branch_rlc.expr(), false.expr(), false.expr(), branch_rlc.expr()] + ); }} }} } @@ -536,7 +536,7 @@ impl BranchConfig { let rot_first_child = rot_branch_init + 1; - let branch = BranchNodeInfo::new(meta, ctx.clone(), false, rot_branch_init); + let mut branch = BranchNodeInfo::new(meta, ctx.clone(), false, rot_branch_init); let modified_index = a!(ctx.branch.modified_index, rot_first_child); let key_rlc = a!(key.rlc, rot_first_child); let key_mult = a!(key.mult, rot_first_child); @@ -545,13 +545,13 @@ impl BranchConfig { require!(branch.is_key_odd() => bool); // Load the last key values - let key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 0.expr()); + config.key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 0.expr()); // Calculate the extension node key RLC when in an extension node let key_rlc_post_ext = ifx! {branch.is_extension() => { let key_rlc_ext = DataTransition::new_with_rot(meta, key.rlc, offset - 1, offset); // Extension key rlc - let ext_key_rlc = key_data.rlc.expr() + branch.ext_key_rlc(meta, &mut cb.base, key_data.mult.expr(), offset); + let ext_key_rlc = config.key_data.rlc.expr() + branch.ext_key_rlc(meta, &mut cb.base, config.key_data.mult.expr(), offset); // Currently, the extension node S and extension node C both have the same key RLC - // however, sometimes extension node can be replaced by a shorter extension node // (in terms of nibbles), this is still to be implemented. @@ -561,21 +561,21 @@ impl BranchConfig { require!(key_rlc_ext => ext_key_rlc); ext_key_rlc.expr() } elsex { - key_data.rlc.expr() + config.key_data.rlc.expr() }}; // Get the length of the key let key_num_bytes_for_mult = ifx! {branch.is_extension() => { // Unless both parts of the key are odd, subtract 1 from the key length. let key_len = branch.ext_key_len(meta, offset - 1); - key_len - ifx! {not!(key_data.is_odd.expr() * branch.is_key_part_in_ext_odd()) => { 1.expr() }} + key_len - ifx! {not!(config.key_data.is_odd.expr() * branch.is_key_part_in_ext_odd()) => { 1.expr() }} }}; // Get the multiplier for this key length let mult_diff = a!(mult_diff, rot_first_child); require!((FixedTableTag::RMult, key_num_bytes_for_mult, mult_diff) => @"fixed"); // Now update the key RLC and multiplier for the branch nibble. - let mult = key_data.mult.expr() * mult_diff.expr(); + let mult = config.key_data.mult.expr() * mult_diff.expr(); let (nibble_mult, mult_mult) = ifx! {branch.is_key_odd() => { // The nibble will be added as the most significant nibble using the same multiplier (16.expr(), 1.expr()) @@ -591,41 +591,65 @@ impl BranchConfig { // We need to take account the nibbles of the extension node. // The parity alternates when there's an even number of nibbles, remains the same otherwise ifx!{branch.is_key_part_in_ext_even() => { - require!(branch.is_key_odd() => not!(key_data.is_odd)); + require!(branch.is_key_odd() => not!(config.key_data.is_odd)); } elsex { - require!(branch.is_key_odd() => key_data.is_odd); + require!(branch.is_key_odd() => config.key_data.is_odd); }} } elsex { // The parity simply alternates for regular branches. - require!(branch.is_key_odd() => not!(key_data.is_odd)); + require!(branch.is_key_odd() => not!(config.key_data.is_odd)); }} for is_s in [true, false] { - KeyData::store( - &mut cb.base, - &ctx.memory[key_memory(is_s)], - [ - key_rlc.expr(), - key_mult.expr(), - branch.nibbles_counter().expr(), - branch.is_key_odd(), - branch.contains_placeholder_leaf(meta, true), - branch.contains_placeholder_leaf(meta, false), - ], - ); + branch.set_is_s(is_s); + ifx! {not!(branch.is_placeholder()) => { + KeyData::store( + &mut cb.base, + &ctx.memory[key_memory(is_s)], + [ + key_rlc.expr(), + key_mult.expr(), + branch.nibbles_counter().expr(), + branch.is_key_odd(), + branch.contains_placeholder_leaf(meta, true), + branch.contains_placeholder_leaf(meta, false), + 0.expr(), + branch.is_key_odd(), + key_rlc.expr(), + key_mult.expr(), + ], + ); + } elsex { + let (parent_rlc, parent_mult) = ifx! {branch.is_extension() => { + (key_rlc_post_ext.expr(), mult.expr()) + } elsex { + (config.key_data.rlc.expr(), config.key_data.mult.expr()) + }}; + KeyData::store( + &mut cb.base, + &ctx.memory[key_memory(is_s)], + [ + config.key_data.rlc.expr(), + config.key_data.mult.expr(), + config.key_data.num_nibbles.expr(), + config.key_data.is_odd.expr(), + branch.contains_placeholder_leaf(meta, true), + branch.contains_placeholder_leaf(meta, false), + a!(ctx.branch.drifted_index, rot_first_child), + branch.is_key_odd(), + parent_rlc, + parent_mult, + ], + ); + }} } - // We need to check that the nibbles we stored in s are between 0 and 15. - //cb.set_range_s(FixedTableTag::RangeKeyLen16.expr()); - - ctx_key_data = Some(key_data); + // We need to check that the nibbles we stored in s are between 0 + // and 15. cb.set_range_s(FixedTableTag::RangeKeyLen16. + // expr()); }); - BranchConfig { - key_data: ctx_key_data.unwrap(), - parent_data_s: ctx_parent_data_s.unwrap(), - parent_data_c: ctx_parent_data_c.unwrap(), - } + config } pub(crate) fn assign( @@ -915,6 +939,7 @@ impl BranchConfig { pv.mult_diff *= mpt_config.randomness; } pv.key_rlc = pv.extension_node_rlc; + pv.extension_node_mult = pv.key_rlc_mult; // branch part: pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; @@ -950,6 +975,7 @@ impl BranchConfig { } pv.key_rlc = pv.extension_node_rlc; + pv.extension_node_mult = pv.key_rlc_mult; // branch part: pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; pv.key_rlc_mult *= mpt_config.randomness; @@ -958,6 +984,7 @@ impl BranchConfig { * F::from(16) * pv.key_rlc_mult; pv.key_rlc = pv.extension_node_rlc; + pv.extension_node_mult = pv.key_rlc_mult; // branch part: pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; pv.key_rlc_mult *= mpt_config.randomness; @@ -991,6 +1018,7 @@ impl BranchConfig { } pv.key_rlc = pv.extension_node_rlc; + pv.extension_node_mult = pv.key_rlc_mult; // branch part: pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; pv.key_rlc_mult *= mpt_config.randomness; @@ -1019,6 +1047,7 @@ impl BranchConfig { pv.mult_diff *= mpt_config.randomness; } pv.key_rlc = pv.extension_node_rlc; + pv.extension_node_mult = pv.key_rlc_mult; // branch part: pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; @@ -1030,6 +1059,7 @@ impl BranchConfig { pv.key_rlc = pv.extension_node_rlc; pv.key_rlc_mult *= mpt_config.randomness; + pv.extension_node_mult = pv.key_rlc_mult; // branch part: pv.key_rlc += F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; @@ -1059,41 +1089,66 @@ impl BranchConfig { //println!("node index: {} ({})", pv.node_index, offset); if pv.node_index == 15 { - self.parent_data_s.witness_load( + let parent_values_s = self.parent_data[true.idx()].witness_load( region, - offset, + base_offset, &mut pv.memory[parent_memory(true)], 0, )?; - self.parent_data_c.witness_load( + let parent_values_c = self.parent_data[false.idx()].witness_load( region, - offset, + base_offset, &mut pv.memory[parent_memory(false)], 0, )?; if !pv.is_branch_s_placeholder { - self.parent_data_s.witness_store( + self.parent_data[true.idx()].witness_store( region, - offset, + base_offset, &mut pv.memory[parent_memory(true)], pv.s_mod_node_hash_rlc, false, + false, + pv.s_mod_node_hash_rlc, )?; } else { + //println!("placeholder store s"); + self.parent_data[true.idx()].witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(true)], + parent_values_s[0], + parent_values_s[1] != F::zero(), + true, + pv.s_mod_node_hash_rlc, + )?; //self.parent_data_s.witness_store(region, offset, &mut // pv.memory[parent_memory(true)], pv.c_mod_node_hash_rlc, // false)?; } if !pv.is_branch_c_placeholder { - self.parent_data_c.witness_store( + self.parent_data[false.idx()].witness_store( region, - offset, + base_offset, &mut pv.memory[parent_memory(false)], pv.c_mod_node_hash_rlc, false, + false, + pv.c_mod_node_hash_rlc, )?; } else { + //println!("placeholder store c: {:?}", parent_values_c); + self.parent_data[false.idx()].witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(false)], + parent_values_c[0], + parent_values_c[1] != F::zero(), + true, + pv.c_mod_node_hash_rlc, + )?; + //self.parent_data_c.witness_store(region, offset, &mut // pv.memory[parent_memory(false)], pv.s_mod_node_hash_rlc, // false)?; @@ -1267,23 +1322,50 @@ impl BranchConfig { .assign_acc(region, pv.acc_s, pv.acc_mult_s, pv.acc_c, F::zero(), offset) .ok(); } else { - self.key_data.witness_load( + let key_values = self.key_data.witness_load( region, base_offset, &pv.memory[key_memory(true)], 0, )?; for is_s in [true, false] { - self.key_data.witness_store( - region, - base_offset, - &mut pv.memory[key_memory(is_s)], - pv.key_rlc, - pv.key_rlc_mult, - pv.nibbles_num, - pv.is_placeholder_leaf_s, - pv.is_placeholder_leaf_c, - )?; + let is_placeholder = if is_s { + pv.is_branch_s_placeholder + } else { + pv.is_branch_c_placeholder + }; + if !is_placeholder { + self.key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + pv.key_rlc, + pv.key_rlc_mult, + pv.nibbles_num, + pv.is_placeholder_leaf_s, + pv.is_placeholder_leaf_c, + 0, + pv.nibbles_num % 2 == 1, + pv.key_rlc, + pv.key_rlc_mult, + )?; + } else { + println!("ext drifted pos: {}", pv.drifted_pos); + self.key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + key_values[0], + key_values[1], + key_values[2].get_lower_32() as usize, + pv.is_placeholder_leaf_s, + pv.is_placeholder_leaf_c, + pv.drifted_pos, + pv.nibbles_num % 2 == 1, + pv.extension_node_rlc, + pv.extension_node_mult, + )?; + } } // We use intermediate value from previous row (because @@ -1324,19 +1406,47 @@ impl BranchConfig { } else { offset += 1; - self.key_data - .witness_load(region, base_offset, &pv.memory[key_memory(true)], 0)?; + let key_values = + self.key_data + .witness_load(region, base_offset, &pv.memory[key_memory(true)], 0)?; for is_s in [true, false] { - self.key_data.witness_store( - region, - base_offset, - &mut pv.memory[key_memory(is_s)], - pv.key_rlc, - pv.key_rlc_mult, - pv.nibbles_num, - pv.is_placeholder_leaf_s, - pv.is_placeholder_leaf_c, - )?; + let is_placeholder = if is_s { + pv.is_branch_s_placeholder + } else { + pv.is_branch_c_placeholder + }; + if !is_placeholder { + self.key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + pv.key_rlc, + pv.key_rlc_mult, + pv.nibbles_num, + pv.is_placeholder_leaf_s, + pv.is_placeholder_leaf_c, + 0, + pv.nibbles_num % 2 == 1, + pv.key_rlc, + pv.key_rlc_mult, + )?; + } else { + println!("bra drifted pos: {}", pv.drifted_pos); + self.key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + key_values[0], + key_values[1], + key_values[2].get_lower_32() as usize, + pv.is_placeholder_leaf_s, + pv.is_placeholder_leaf_c, + pv.drifted_pos, + pv.nibbles_num % 2 == 1, + key_values[0], + key_values[1], + )?; + } } } diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index 76403f0260..2f9be82439 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -17,7 +17,7 @@ use crate::{ util::Expr, }; use eth_types::Field; -use gadgets::util::{and, not}; +use gadgets::util::{and, not, Scalar}; use halo2_proofs::{ circuit::Region, plonk::{Error, Expression, VirtualCells}, @@ -630,8 +630,10 @@ pub(crate) struct KeyData { pub(crate) is_odd: Cell, pub(crate) is_placeholder_leaf_s: Cell, pub(crate) is_placeholder_leaf_c: Cell, - pub(crate) rlc_last: Cell, - pub(crate) mult_last: Cell, + pub(crate) placeholder_nibble: Cell, + pub(crate) placeholder_is_odd: Cell, + pub(crate) parent_rlc: Cell, + pub(crate) parent_mult: Cell, } impl Trackable for KeyData { @@ -656,8 +658,10 @@ impl KeyData { is_odd: cb.query_cell(), is_placeholder_leaf_s: cb.query_cell(), is_placeholder_leaf_c: cb.query_cell(), - rlc_last: cb.query_cell(), - mult_last: cb.query_cell(), + placeholder_nibble: cb.query_cell(), + placeholder_is_odd: cb.query_cell(), + parent_rlc: cb.query_cell(), + parent_mult: cb.query_cell(), }; circuit!([meta, cb], { memory.load( @@ -671,6 +675,10 @@ impl KeyData { key_data.is_odd.expr(), key_data.is_placeholder_leaf_s.expr(), key_data.is_placeholder_leaf_c.expr(), + key_data.placeholder_nibble.expr(), + key_data.placeholder_is_odd.expr(), + key_data.parent_rlc.expr(), + key_data.parent_mult.expr(), ], ); }); @@ -680,7 +688,7 @@ impl KeyData { pub(crate) fn store( cb: &mut ConstraintBuilder, memory: &MemoryBank, - values: [Expression; 6], + values: [Expression; 10], ) { memory.store(cb, &values); } @@ -689,7 +697,7 @@ impl KeyData { memory.store_with_key(cb, 0.expr(), &Self::default_values()); } - pub(crate) fn default_values() -> [Expression; 6] { + pub(crate) fn default_values() -> [Expression; 10] { [ 0.expr(), 1.expr(), @@ -697,6 +705,10 @@ impl KeyData { false.expr(), false.expr(), false.expr(), + 0.expr(), + false.expr(), + 0.expr(), + 1.expr(), ] } @@ -710,6 +722,10 @@ impl KeyData { num_nibbles: usize, is_placeholder_leaf_s: bool, is_placeholder_leaf_c: bool, + placeholder_nibble: u8, + placeholder_is_odd: bool, + parent_rlc: F, + parent_mult: F, ) -> Result<(), Error> { //println!("offset: {}", offset); //println!("key_rlc_prev: {:?}", pv.key_rlc_prev); @@ -719,10 +735,14 @@ impl KeyData { let values = [ rlc, mult, - F::from(num_nibbles as u64), - F::from(num_nibbles % 2 == 1), - F::from(is_placeholder_leaf_s), - F::from(is_placeholder_leaf_c), + num_nibbles.scalar(), + (num_nibbles % 2 == 1).scalar(), + is_placeholder_leaf_s.scalar(), + is_placeholder_leaf_c.scalar(), + placeholder_nibble.scalar(), + placeholder_is_odd.scalar(), + parent_rlc, + parent_mult, ]; memory.witness_store(offset, &values); @@ -735,7 +755,7 @@ impl KeyData { offset: usize, memory: &MemoryBank, load_offset: usize, - ) -> Result<(), Error> { + ) -> Result, Error> { let values = memory.witness_load(load_offset); //println!("offset: {}, values: {:?}", offset, values); @@ -751,8 +771,12 @@ impl KeyData { .assign(region, offset, values[4])?; self.is_placeholder_leaf_c .assign(region, offset, values[5])?; + self.placeholder_nibble.assign(region, offset, values[6])?; + self.placeholder_is_odd.assign(region, offset, values[7])?; + self.parent_rlc.assign(region, offset, values[8])?; + self.parent_mult.assign(region, offset, values[9])?; - Ok(()) + Ok(values) } } @@ -760,6 +784,8 @@ impl KeyData { pub(crate) struct ParentData { pub(crate) rlc: Cell, pub(crate) is_root: Cell, + pub(crate) is_placeholder: Cell, + pub(crate) placeholder_rlc: Cell, } impl ParentData { @@ -772,13 +798,20 @@ impl ParentData { let parent_data = ParentData { rlc: cb.query_cell(), is_root: cb.query_cell(), + is_placeholder: cb.query_cell(), + placeholder_rlc: cb.query_cell(), }; circuit!([meta, cb], { memory.load( description, cb, offset, - &[parent_data.rlc.expr(), parent_data.is_root.expr()], + &[ + parent_data.rlc.expr(), + parent_data.is_root.expr(), + parent_data.is_placeholder.expr(), + parent_data.placeholder_rlc.expr(), + ], ); }); parent_data @@ -787,7 +820,7 @@ impl ParentData { pub(crate) fn store( cb: &mut ConstraintBuilder, memory: &MemoryBank, - values: [Expression; 2], + values: [Expression; 4], ) { memory.store(cb, &values); } @@ -799,12 +832,19 @@ impl ParentData { memory: &mut MemoryBank, rlc: F, force_hashed: bool, + is_placeholder: bool, + placeholder_rlc: F, ) -> Result<(), Error> { //println!("offset: {}", offset); //println!("rlc: {:?}", rlc); //println!("is_hashed: {}", is_hashed); - let values = [rlc, F::from(force_hashed)]; + let values = [ + rlc, + force_hashed.scalar(), + is_placeholder.scalar(), + placeholder_rlc, + ]; memory.witness_store(offset, &values); Ok(()) @@ -821,6 +861,8 @@ impl ParentData { self.rlc.assign(region, offset, values[0])?; self.is_root.assign(region, offset, values[1])?; + self.is_placeholder.assign(region, offset, values[2])?; + self.placeholder_rlc.assign(region, offset, values[3])?; Ok(values) } @@ -1310,6 +1352,22 @@ impl BranchNodeInfo { } } +/// Add the nibble from the drifted branch +pub(crate) fn drifted_nibble_rlc( + cb: &mut ConstraintBuilder, + difted_index: Expression, + key_mult_prev: Expression, + is_key_odd: Expression, +) -> Expression { + circuit!([meta, cb], { + // Add the nibble from the branch (drifted_index is set to the same value for + // all children) + let drifted_mult = + key_mult_prev.expr() * ifx! {is_key_odd => { 16.expr() } elsex { 1.expr() }}; + difted_index * drifted_mult + }) +} + #[derive(Clone)] pub(crate) struct BranchChildInfo { pub(crate) is_s: bool, diff --git a/zkevm-circuits/src/mpt_circuit/param.rs b/zkevm-circuits/src/mpt_circuit/param.rs index b10631e501..35e7d1bdde 100644 --- a/zkevm-circuits/src/mpt_circuit/param.rs +++ b/zkevm-circuits/src/mpt_circuit/param.rs @@ -147,4 +147,4 @@ pub const KEY_LEN_IN_NIBBLES: usize = KEY_LEN * 2; pub const EMPTY_TRIE_HASH: [u8; 32] = [ 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, -]; \ No newline at end of file +]; diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index 330c719b7b..2d45eeb3e7 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -10,15 +10,12 @@ use std::marker::PhantomData; use crate::circuit_tools::cell_manager::Cell; use crate::circuit_tools::constraint_builder::{ConstraintBuilder, RLCChainable, RLCable}; -use crate::circuit_tools::gadgets::{LtGadget, RequireNotZeroGadget, IsEqualGadget}; +use crate::circuit_tools::gadgets::{IsEqualGadget, LtGadget, RequireNotZeroGadget}; +use crate::mpt_circuit::helpers::drifted_nibble_rlc; use crate::table::ProofType; use crate::{ - assign, - circuit, - mpt_circuit::{ - helpers::BranchNodeInfo, - param::{BRANCH_ROWS_NUM}, - }, + assign, circuit, + mpt_circuit::{helpers::BranchNodeInfo, param::BRANCH_ROWS_NUM}, mpt_circuit::{ helpers::{ get_parent_rlc_state, key_memory, parent_memory, KeyData, MPTConstraintBuilder, @@ -37,7 +34,7 @@ use crate::{ mpt_circuit::{MPTConfig, ProofValues}, }; -use super::helpers::{Indexable, LeafKeyGadget, RLPValueGadget, bytes_into_rlc}; +use super::helpers::{bytes_into_rlc, Indexable, LeafKeyGadget, RLPValueGadget}; #[derive(Clone, Debug)] pub(crate) struct StorageLeafCols { @@ -120,22 +117,19 @@ impl StorageLeafConfig { cb: &mut MPTConstraintBuilder, ctx: MPTContext, ) -> Self { - let is_s = true; - let accs = ctx.accumulators; - let s_main = ctx.s_main; let r = ctx.r.clone(); - let rot_parent = -1; - let rot_branch_init = rot_parent - (BRANCH_ROWS_NUM - 1); - let rot_branch_child = rot_branch_init + 1; - cb.base.cell_manager.as_mut().unwrap().reset(); let mut config = StorageLeafConfig::default(); circuit!([meta, cb.base], { - let mut branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); + let key_bytes = [ctx.expr(meta, 0), ctx.expr(meta, 2)]; + let value_bytes = [ctx.expr(meta, 1), ctx.expr(meta, 3)]; + let drifted_bytes = ctx.expr(meta, 4); + let wrong_bytes = ctx.expr(meta, 5); + let lookup_offset = 3; + let wrong_offset = 5; - let mut offset = 0; let mut key_rlc = vec![0.expr(); 2]; let mut value_rlc = vec![0.expr(); 2]; let mut leaf_rlc_value = vec![0.expr(); 2]; @@ -149,26 +143,34 @@ impl StorageLeafConfig { 0.expr(), ); - branch.set_is_s(is_s); - // Key data - let is_branch_placeholder = ifx! {not!(parent_data.is_root) => { branch.is_placeholder() }}; - let load_offset = ifx! {is_branch_placeholder => { 1.expr() }}; let key_data = &mut config.key_data[is_s.idx()]; - *key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], load_offset); - - // Placeholder checks - let empty_root_rlc = EMPTY_TRIE_HASH.iter().map(|v| v.expr()).collect::>().rlc(&r); - config.is_in_empty_trie[is_s.idx()] = IsEqualGadget::construct(&mut cb.base, parent_data.rlc.expr(), empty_root_rlc.expr()); - config.is_in_empty_branch[is_s.idx()] = IsEqualGadget::construct(&mut cb.base, parent_data.rlc.expr(), 128.expr()); - let is_placeholder = or::expr(&[config.is_in_empty_trie[is_s.idx()].expr(), config.is_in_empty_branch[is_s.idx()].expr()]); + *key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], 0.expr()); + + // Placeholder leaf checks + let empty_root_rlc = EMPTY_TRIE_HASH + .iter() + .map(|v| v.expr()) + .collect::>() + .rlc(&r); + config.is_in_empty_trie[is_s.idx()] = IsEqualGadget::construct( + &mut cb.base, + parent_data.rlc.expr(), + empty_root_rlc.expr(), + ); + config.is_in_empty_branch[is_s.idx()] = + IsEqualGadget::construct(&mut cb.base, parent_data.rlc.expr(), 128.expr()); + let is_placeholder = or::expr(&[ + config.is_in_empty_trie[is_s.idx()].expr(), + config.is_in_empty_branch[is_s.idx()].expr(), + ]); // Calculate and store the leaf data RLC - let leaf_rlc_key = ctx.rlc(meta, 0..36, offset); + let leaf_rlc_key = key_bytes[is_s.idx()][0..36].rlc(&r); + // Calculate the key let rlp_key = &mut config.rlp_key[is_s.idx()]; - *rlp_key = LeafKeyGadget::construct(&mut cb.base, &ctx.expr(meta, offset)); - + *rlp_key = LeafKeyGadget::construct(&mut cb.base, &key_bytes[is_s.idx()]); key_rlc[is_s.idx()] = key_data.rlc.expr() + rlp_key.key_rlc( &mut cb.base, @@ -202,10 +204,10 @@ impl StorageLeafConfig { KeyData::default_values(), ); - offset += 1; - + // Decode the storage value let rlp_value = &mut config.rlp_value[is_s.idx()]; - *rlp_value = RLPValueGadget::construct(&mut cb.base, &s_main.expr(meta, offset)); + *rlp_value = + RLPValueGadget::construct(&mut cb.base, &value_bytes[is_s.idx()][0..36]); (value_rlc[is_s.idx()], leaf_rlc_value[is_s.idx()]) = rlp_value.rlc(&r); let leaf_rlc = (leaf_rlc_key, config.mult[is_s.idx()].expr()) .rlc_chain(leaf_rlc_value[is_s.idx()].expr()); @@ -248,37 +250,47 @@ impl StorageLeafConfig { ParentData::store( &mut cb.base, &ctx.memory[parent_memory(is_s)], - [0.expr(), true.expr()], + [0.expr(), true.expr(), false.expr(), 0.expr()], ); // Set the number of bytes used //cb.set_length_s(value_num_bytes); - - offset += 1; } // Put the data in the lookup table - require!(a!(ctx.mpt_table.key_rlc, offset-1) => key_rlc[false.idx()]); - require!(a!(ctx.mpt_table.value_prev, offset-1) => value_rlc[true.idx()]); - require!(a!(ctx.mpt_table.value, offset-1) => value_rlc[false.idx()]); + require!(a!(ctx.mpt_table.key_rlc, lookup_offset) => key_rlc[false.idx()]); + require!(a!(ctx.mpt_table.value_prev, lookup_offset) => value_rlc[true.idx()]); + require!(a!(ctx.mpt_table.value, lookup_offset) => value_rlc[false.idx()]); // Drifted leaf - let storage = StorageLeafInfo::new(ctx.clone(), true, 0); - ifx! {branch.is_placeholder_s_or_c(), not!(storage.is_below_account(meta)) => { - config.drifted_rlp_key = LeafKeyGadget::construct(&mut cb.base, &ctx.expr(meta, offset)); + ifx! {config.parent_data[true.idx()].is_placeholder.expr() + config.parent_data[false.idx()].is_placeholder.expr() => { + config.drifted_rlp_key = LeafKeyGadget::construct(&mut cb.base, &drifted_bytes); // Calculate and store the leaf RLC (RLP + key) - let drifted_rlc_key = ctx.rlc(meta, 0..36, offset); + let drifted_rlc_key = drifted_bytes[0..36].rlc(&r); // We need the intermediate key RLC right before `drifted_index` is added to it. - // If the branch parallel to the placeholder branch is an extension node, - // we have the intermediate RLC stored in the extension node `accs.key.rlc`. - let is_branch_in_first_level = branch.is_below_account(meta); - let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); + let (key_rlc_prev, key_mult_prev, placeholder_nibble, placeholder_is_odd) = ifx!{config.parent_data[true.idx()].is_placeholder.expr() => { + ( + config.key_data[true.idx()].parent_rlc.expr(), + config.key_data[true.idx()].parent_mult.expr(), + config.key_data[true.idx()].placeholder_nibble.expr(), + config.key_data[true.idx()].placeholder_is_odd.expr(), + ) + } elsex { + ( + config.key_data[false.idx()].parent_rlc.expr(), + config.key_data[false.idx()].parent_mult.expr(), + config.key_data[false.idx()].placeholder_nibble.expr(), + config.key_data[false.idx()].placeholder_is_odd.expr(), + ) + }}; + // Calculate the drifted key RLC let drifted_key_rlc = key_rlc_prev.expr() + - branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + - config.drifted_rlp_key.key_rlc(&mut cb.base, key_mult_prev, branch.is_key_odd(), r[0].expr(), true, &r); + drifted_nibble_rlc(&mut cb.base, placeholder_nibble.expr(), key_mult_prev.expr(), placeholder_is_odd.expr()) + + config.drifted_rlp_key.key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), true, &r); + // Check zero bytes and mult_diff config.drifted_mult = cb.base.query_cell(); @@ -290,31 +302,19 @@ impl StorageLeafConfig { //cb.set_length(num_bytes.expr()); // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let calc_rlc = |is_s: bool, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { - circuit!([meta, cb], { - // Complete the drifted leaf rlc by adding the bytes on the value row - let drifted_rlc = (drifted_rlc_key.expr(), config.drifted_mult.expr()).rlc_chain(leaf_rlc_value[is_s.idx()].expr()); - (key_rlc[is_s.idx()].expr(), drifted_rlc, a!(accs.mod_node_rlc(is_s), rot_branch_child)) - }) + let calc_rlc = |is_s: bool| { + // Complete the drifted leaf rlc by adding the bytes on the value row + let drifted_rlc = (drifted_rlc_key.expr(), config.drifted_mult.expr()).rlc_chain(leaf_rlc_value[is_s.idx()].expr()); + (key_rlc[is_s.idx()].expr(), drifted_rlc, config.parent_data[is_s.idx()].placeholder_rlc.expr()) }; let (key_rlc, drifted_rlc, mod_hash) = matchx! { - branch.is_placeholder_s() => { + config.parent_data[true.idx()].is_placeholder => { // Neighbour leaf in the added branch - // - `leaf_key_s_rlc` is the key RLC of the leaf before it drifted down - // in a new branch. - // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `c_mod_node_rlc` in the added branch stores the hash of - // `modified_index` (the leaf that has been added). - calc_rlc(true, meta, &mut cb.base) + calc_rlc(true) }, - branch.is_placeholder_c() => { + config.parent_data[false.idx()].is_placeholder => { // Neighbour leaf in the deleted branch - // -`leaf_key_c_rlc` is the key RLC of the leaf after its neighbour leaf - // has been deleted (and there were only two leaves, so the branch was deleted). - // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `s_mod_node_rlc` in the deleted branch stores the hash of - // `modified_index` (the leaf that is to be deleted). - calc_rlc(false, meta, &mut cb.base) + calc_rlc(false) }, }; // The key of the drifted leaf needs to match the key of the leaf @@ -323,17 +323,16 @@ impl StorageLeafConfig { require!((1, drifted_rlc, config.drifted_rlp_key.num_bytes(), mod_hash) => @"keccak"); }} - offset += 1; - + // Wrong leaf config.is_wrong_leaf = cb.base.query_cell(); // Make sure is_wrong_leaf is boolean require!(config.is_wrong_leaf => bool); - ifx! {a!(ctx.proof_type.is_non_existing_storage_proof, offset) => { - // Get the previous key RLC data + ifx! {a!(ctx.proof_type.is_non_existing_storage_proof, wrong_offset) => { + // Get the previous key data config.key_data_w = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 1.expr()); ifx! {config.is_wrong_leaf => { - config.wrong_rlp_key = LeafKeyGadget::construct(&mut cb.base, &ctx.expr(meta, offset)); - // Calculate the key and check it's the address as requested in the lookup + // Calculate the key + config.wrong_rlp_key = LeafKeyGadget::construct(&mut cb.base, &wrong_bytes); let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.key_rlc( &mut cb.base, config.key_data_w.mult.expr(), @@ -342,8 +341,9 @@ impl StorageLeafConfig { false, &ctx.r, ); - // TODO(Brecht): only checks the key, not prev_value/value? - let key_rlc_lookup = a!(ctx.mpt_table.key_rlc, offset); + + // Check that it's the key as requested in the lookup + let key_rlc_lookup = a!(ctx.mpt_table.key_rlc, wrong_offset); require!(key_rlc_lookup => key_rlc_wrong); // Now make sure this address is different than the one of the leaf @@ -375,14 +375,20 @@ impl StorageLeafConfig { offset: usize, ) -> Result<(), Error> { let base_offset = offset; - let mut offset = offset; + + let key_bytes = [&witness[offset + 0], &witness[offset + 2]]; + let value_bytes = [&witness[offset + 1], &witness[offset + 3]]; + let drifted_bytes = &witness[offset + 4]; + let wrong_bytes = &witness[offset + 5]; + let lookup_offset = offset + 3; + let wrong_offset = offset + 5; let mut key_rlc = vec![0.scalar(); 2]; let mut value_rlc = vec![0.scalar(); 2]; for is_s in [true, false] { - /* KEY */ + // Key { - let key_row = &witness[offset]; + let key_row = &key_bytes[is_s.idx()]; let rlp_key_witness = self.rlp_key[is_s.idx()] .assign(region, base_offset, &key_row.bytes) @@ -412,17 +418,11 @@ impl StorageLeafConfig { ) .ok(); - let is_branch_placeholder = if is_s { - pv.is_branch_s_placeholder - } else { - pv.is_branch_c_placeholder - }; - let load_offset = if is_branch_placeholder { 1 } else { 0 }; self.key_data[is_s.idx()].witness_load( region, base_offset, &mut pv.memory[key_memory(is_s)], - load_offset, + 0, )?; self.key_data[is_s.idx()].witness_store( region, @@ -433,6 +433,10 @@ impl StorageLeafConfig { 0, false, false, + 0, + false, + F::zero(), + F::one(), )?; // For leaf S and leaf C we need to start with the same rlc. @@ -459,12 +463,9 @@ impl StorageLeafConfig { key_rlc[is_s.idx()] = key_rlc_new; } - /* VALUE */ - - offset += 1; - + // Value { - let value_row = &witness[offset]; + let value_row = &value_bytes[is_s.idx()]; let value_witness = self.rlp_value[is_s.idx()] .assign(region, base_offset, &value_row.bytes) @@ -494,7 +495,8 @@ impl StorageLeafConfig { let parent_values = self.parent_data[is_s.idx()] .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) - .ok().unwrap(); + .ok() + .unwrap(); self.parent_data[is_s.idx()] .witness_store( region, @@ -502,28 +504,36 @@ impl StorageLeafConfig { &mut pv.memory[parent_memory(is_s)], F::zero(), true, + false, + F::zero(), ) .ok(); - self.is_in_empty_trie[is_s.idx()].assign(region, base_offset, parent_values[0], bytes_into_rlc(&EMPTY_TRIE_HASH, ctx.randomness)).ok(); - self.is_in_empty_branch[is_s.idx()].assign(region, base_offset, parent_values[0], 128.scalar()).ok(); - - if !is_s && value_row.get_byte_rev(IS_STORAGE_MOD_POS) == 1 { - assign!(region, (ctx.proof_type.proof_type, offset) => ProofType::StorageChanged.scalar()).ok(); - } + self.is_in_empty_trie[is_s.idx()] + .assign( + region, + base_offset, + parent_values[0], + bytes_into_rlc(&EMPTY_TRIE_HASH, ctx.randomness), + ) + .ok(); + self.is_in_empty_branch[is_s.idx()] + .assign(region, base_offset, parent_values[0], 128.scalar()) + .ok(); } - - offset += 1; } // Put the data in the lookup table - assign!(region, (ctx.mpt_table.key_rlc, offset - 1) => key_rlc[false.idx()]).ok(); - assign!(region, (ctx.mpt_table.value_prev, offset - 1) => value_rlc[true.idx()]).ok(); - assign!(region, (ctx.mpt_table.value, offset - 1) => value_rlc[false.idx()]).ok(); + if value_bytes[false.idx()].get_byte_rev(IS_STORAGE_MOD_POS) == 1 { + assign!(region, (ctx.proof_type.proof_type, lookup_offset) => ProofType::StorageChanged.scalar()).ok(); + } + assign!(region, (ctx.mpt_table.key_rlc, lookup_offset) => key_rlc[false.idx()]).ok(); + assign!(region, (ctx.mpt_table.value_prev, lookup_offset) => value_rlc[true.idx()]).ok(); + assign!(region, (ctx.mpt_table.value, lookup_offset) => value_rlc[false.idx()]).ok(); // Drifted leaf handling if pv.is_branch_s_placeholder || pv.is_branch_c_placeholder { - let row = &witness[offset]; + let row = &drifted_bytes; let drifted_key_witness = self .drifted_rlp_key @@ -545,10 +555,10 @@ impl StorageLeafConfig { .assign(region, base_offset, pv.acc_mult_s) .ok(); } - offset += 1; + // Wrong leaf handling { - let row = &witness[offset]; + let row = &wrong_bytes; if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { self.key_data_w .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) @@ -560,10 +570,8 @@ impl StorageLeafConfig { .assign(region, base_offset, F::from(is_wrong)) .ok(); - let row_key_c = - &witness[offset - (LEAF_NON_EXISTING_IND - LEAF_KEY_C_IND) as usize]; let mut row_bytes = row.bytes.clone(); - row_bytes[0] = row_key_c.bytes[0]; + row_bytes[0] = key_bytes[false.idx()].bytes[0]; let wrong_witness = self .wrong_rlp_key @@ -579,13 +587,13 @@ impl StorageLeafConfig { &mut key_rlc_mult_new, wrong_witness.num_rlp_bytes_list() as usize, ); - assign!(region, (ctx.mpt_table.key_rlc, offset) => key_rlc_new).ok(); + assign!(region, (ctx.mpt_table.key_rlc, wrong_offset) => key_rlc_new).ok(); self.check_is_wrong_leaf .assign(region, base_offset, key_rlc_new - key_rlc[false.idx()]) .ok(); - assign!(region, (ctx.proof_type.proof_type, offset) => ProofType::StorageDoesNotExist.scalar()).ok(); + assign!(region, (ctx.proof_type.proof_type, wrong_offset) => ProofType::StorageDoesNotExist.scalar()).ok(); } } diff --git a/zkevm-circuits/src/table.rs b/zkevm-circuits/src/table.rs index e361367910..cf3b26e071 100644 --- a/zkevm-circuits/src/table.rs +++ b/zkevm-circuits/src/table.rs @@ -429,6 +429,7 @@ impl RwTable { } /// The types of proofs in the MPT table +#[derive(Clone, Copy, Debug)] pub enum ProofType { /// Nonce updated NonceChanged = AccountFieldTag::Nonce as isize, From 4e6cc2b81899c5f625b43d851b6c21a4a4d635ee Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Fri, 17 Feb 2023 03:43:18 +0100 Subject: [PATCH 07/11] Start account leaf layout refactoring --- .../src/circuit_tools/constraint_builder.rs | 48 +- .../src/mpt_circuit/account_leaf.rs | 452 ++++++++++-------- zkevm-circuits/src/mpt_circuit/helpers.rs | 71 +-- .../src/mpt_circuit/storage_leaf.rs | 243 ++++------ 4 files changed, 442 insertions(+), 372 deletions(-) diff --git a/zkevm-circuits/src/circuit_tools/constraint_builder.rs b/zkevm-circuits/src/circuit_tools/constraint_builder.rs index f720fdeaf7..43821c35ab 100644 --- a/zkevm-circuits/src/circuit_tools/constraint_builder.rs +++ b/zkevm-circuits/src/circuit_tools/constraint_builder.rs @@ -1,7 +1,7 @@ //! Circuit utilities use crate::{evm_circuit::util::rlc, util::Expr}; use eth_types::Field; -use gadgets::util::{and, select, sum}; +use gadgets::util::{and, select, sum, Scalar}; use halo2_proofs::plonk::{ConstraintSystem, Expression}; use itertools::Itertools; @@ -648,6 +648,52 @@ impl RLCChainable for (Expression, Expression) { } } +pub(crate) fn rlc_acc( + values: &[u8], + rlc: F, + mult: F, + r: F, +) -> (F, F) { + let mut rlc = rlc; + let mut mult = mult; + for &value in values.iter() { + rlc = rlc + F::from(value as u64) * mult; + mult *= r; + } + (rlc, mult) +} + + +/// Trait around RLC +pub trait RLCableValue { + /// Returns the RLC of itself + fn rlc_value(&self, r: F) -> F; +} + +impl RLCableValue for Vec { + fn rlc_value(&self, r: F) -> F { + rlc::value(self, r) + } +} + +impl RLCableValue for [u8] { + fn rlc_value(&self, r: F) -> F { + rlc::value(self, r) + } +} + +/// Trait around RLC +pub trait RLCChainableValue { + /// Returns the RLC of itself with a starting rlc/multiplier + fn rlc_chain_value(&self, values: &[u8], r: F) -> (F, F); +} + +impl RLCChainableValue for (F, F) { + fn rlc_chain_value(&self, values: &[u8], r: F) -> (F, F) { + rlc_acc(values, self.0, self.1, r) + } +} + /// require_parser #[macro_export] macro_rules! require_parser { diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index 7ba1898dde..3929300b67 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -1,4 +1,5 @@ use eth_types::Field; +use gadgets::util::Scalar; use halo2_proofs::plonk::{Advice, Column, ConstraintSystem, Expression}; use halo2_proofs::{ circuit::{Region, Value}, @@ -7,7 +8,11 @@ use halo2_proofs::{ }; use std::marker::PhantomData; +use crate::circuit_tools::gadgets::RequireNotZeroGadget; +use crate::mpt_circuit::helpers::Indexable; +use crate::table::ProofType; use crate::{ + assign, circuit, circuit_tools::cell_manager::{Cell, DataTransition}, circuit_tools::constraint_builder::{ConstraintBuilder, RLCable}, @@ -30,6 +35,7 @@ use crate::{ }, }; +use super::helpers::{LeafKeyGadget, RLPValueGadget}; use super::{ helpers::bytes_into_rlc, param::{ @@ -105,15 +111,19 @@ pub(crate) struct AccountLeaf { pub(crate) is_in_added_branch: bool, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub(crate) struct AccountLeafConfig { - key_data_s: KeyData, - key_data_c: KeyData, + key_data: [KeyData; 2], key_data_w: KeyData, key_data_d: KeyData, - parent_data_s: ParentData, - parent_data_c: ParentData, - diff_inv: Cell, + parent_data: [ParentData; 2], + check_is_wrong_leaf: RequireNotZeroGadget, + rlp_key: [LeafKeyGadget; 2], + mult: [Cell; 2], + wrong_rlp_key: LeafKeyGadget, + is_wrong_leaf: Cell, + rlp_nonce: [RLPValueGadget; 2], + rlp_balance: [RLPValueGadget; 2], } impl AccountLeafConfig { @@ -124,8 +134,6 @@ impl AccountLeafConfig { ) -> Self { let proof_type = ctx.proof_type; let not_first_level = ctx.position_cols.not_first_level; - let s_main = ctx.s_main; - let accs = ctx.accumulators; let address_rlc = ctx.address_rlc; let s_main = ctx.s_main; let c_main = ctx.c_main; @@ -142,48 +150,58 @@ impl AccountLeafConfig { let rot_branch_init = rot_first_child - 1; cb.base.cell_manager.as_mut().unwrap().reset(); - let mut ctx_key_data_s: Option> = None; - let mut ctx_key_data_c: Option> = None; - let mut ctx_key_data_w: Option> = None; - let mut ctx_key_data_d: Option> = None; - let mut ctx_parent_data_s: Option> = None; - let mut ctx_parent_data_c: Option> = None; - let ctx_diff_inv: Cell; + let mut config = AccountLeafConfig::default(); circuit!([meta, cb.base], { + let key_bytes = [ctx.expr(meta, -1), ctx.expr(meta, 0)]; + let wrong_bytes = ctx.expr(meta, 1); + let nonce_bytes = [ctx.expr(meta, 2)[..34].to_owned(), ctx.expr(meta, 3)[..34].to_owned()]; + let balance_bytes = [ctx.expr(meta, 2)[34..].to_owned(), ctx.expr(meta, 3)[..34].to_owned()]; + //let value_bytes = [ctx.expr(meta, 1), ctx.expr(meta, 3)]; + //let drifted_bytes = ctx.expr(meta, 4); + // + //let lookup_offset = 3; + let wrong_offset = 1; + + let mut key_rlc = vec![0.expr(); 2]; for is_s in [true, false] { - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let account = AccountLeafInfo::new(meta, ctx.clone(), offset); - // Account leaf always starts with RLP_LIST_LONG + 1 because its length is // always longer than 55 bytes due to containing two hashes - // storage root and codehash. - require!(a!(s_main.rlp1, offset) => RLP_LIST_LONG + 1); + require!(key_bytes[is_s.idx()][0] => RLP_LIST_LONG + 1); // Calculate and store the leaf data RLC - require!(a!(accs.acc_s.rlc, offset) => ctx.rlc(meta, 0..36, offset)); + require!(a!(accs.acc_s.rlc, offset) => key_bytes[is_s.idx()][0..36].rlc(&r)); - let is_branch_placeholder = ifx! {f!(ctx.position_cols.q_not_first), a!(not_first_level) => { branch.is_placeholder() }}; + // Key data + let key_data = &mut config.key_data[is_s.idx()]; + *key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], 0.expr()); - // Load the last key values - let key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], 0.expr()); + // Parent data + let parent_data = &mut config.parent_data[is_s.idx()]; + *parent_data = ParentData::load( + "account load", + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + 0.expr(), + ); // Calculate the key RLC - let key_rlc = key_data.rlc.expr() - + account.key_rlc( - meta, + let rlp_key = &mut config.rlp_key[is_s.idx()]; + *rlp_key = LeafKeyGadget::construct(&mut cb.base, &key_bytes[is_s.idx()]); + key_rlc[is_s.idx()] = key_data.rlc.expr() + + rlp_key.key_rlc( &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), - 0, + true, + &r, ); - require!(a!(accs.key.rlc, offset) => key_rlc); // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES. - let key_len = account.key_len(meta); - let num_nibbles = get_num_nibbles(key_len.expr(), key_data.is_odd.expr()); - require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); + let num_nibbles = rlp_key.num_key_nibbles(key_data.is_odd.expr()); + require!(key_data.num_nibbles.expr() + num_nibbles.expr() => KEY_LEN_IN_NIBBLES); // Key done, set the starting values KeyData::store( @@ -193,9 +211,10 @@ impl AccountLeafConfig { ); // Num bytes used in RLC - let num_bytes = account.num_bytes_on_key_row(meta); + let num_bytes = rlp_key.num_bytes_on_key_row(); // Update `mult_diff` - require!((FixedTableTag::RMult, num_bytes.expr(), a!(accs.acc_s.mult, offset)) => @"fixed"); + config.mult[is_s.idx()] = cb.base.query_cell(); + require!((FixedTableTag::RMult, num_bytes.expr(), config.mult[is_s.idx()].expr()) => @"fixed"); // RLC bytes zero check //cb.set_length(num_bytes.expr()); @@ -204,8 +223,8 @@ impl AccountLeafConfig { // in cases when there is a placeholder branch we have `key_rlc - // address_rlc != 0` because `key_rlc` is computed for the branch // that is parallel to the placeholder branch. - ifx! {not!(is_branch_placeholder), not!(a!(proof_type.is_non_existing_account_proof, offset)) => { - require!(a!(address_rlc, offset) => a!(accs.key.rlc, offset)); + ifx! {not!(parent_data.is_placeholder), not!(a!(proof_type.is_non_existing_account_proof, offset)) => { + require!(key_rlc[is_s.idx()] => a!(address_rlc, offset)); }} // Account delete @@ -224,61 +243,72 @@ impl AccountLeafConfig { // branch). if !is_s { // Note: this constraint suffices because the proper transition from branch to a - // leaf (2. case) is checked by constraints in account_leaf_key_in_added_branch. + // leaf (2. case) are checked as well. ifx! {a!(proof_type.is_account_delete_mod, offset) => { - require!(or::expr([branch.contains_placeholder_leaf(meta, is_s), branch.is_placeholder()]) => true); + let branch_contains_placeholder_leaf = if is_s { key_data.is_placeholder_leaf_s.expr() } else { key_data.is_placeholder_leaf_c.expr() }; + require!(or::expr([branch_contains_placeholder_leaf.expr(), parent_data.is_placeholder.expr()]) => true); }} } - if is_s { - ctx_key_data_s = Some(key_data); - } else { - ctx_key_data_c = Some(key_data); - } + config.rlp_nonce[is_s.idx()] = RLPValueGadget::construct(&mut cb.base, &nonce_bytes[is_s.idx()][2..]); + config.rlp_balance[is_s.idx()] = RLPValueGadget::construct(&mut cb.base, &balance_bytes[is_s.idx()][2..]); offset += 1; } - let rot_key_s = offset - 2; - let rot_key_c = rot_key_s + 1; - let rot_nonce_s = rot_key_c + 2; - let rot_nonce_c = rot_nonce_s + 1; - let rot_storage_s = rot_nonce_c + 1; - let rot_storage_c = rot_storage_s + 1; - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key_s); + + // Wrong leaf + config.is_wrong_leaf = cb.base.query_cell(); // Make sure is_wrong_leaf is boolean - require!(account.is_wrong_leaf(meta, true) => bool); - - ifx! {a!(proof_type.is_non_existing_account_proof, offset) => { - let key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 1.expr()); - ifx! {account.is_wrong_leaf(meta, true) => { - // Calculate the key and check it's the address as requested in the lookup - let key_rlc_wrong = key_data.rlc.expr() + account.key_rlc(meta, &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), offset - rot_key_s); - require!(a!(address_rlc, offset) => key_rlc_wrong); + require!(config.is_wrong_leaf => bool); + ifx! {a!(ctx.proof_type.is_non_existing_account_proof, wrong_offset) => { + // Get the previous key data + config.key_data_w = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 1.expr()); + ifx! {config.is_wrong_leaf => { + // Calculate the key + config.wrong_rlp_key = LeafKeyGadget::construct(&mut cb.base, &wrong_bytes); + let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.key_rlc( + &mut cb.base, + config.key_data_w.mult.expr(), + config.key_data_w.is_odd.expr(), + 1.expr(), + false, + &ctx.r, + ); + + // Check that it's the key as requested in the lookup + let key_rlc_lookup = a!(ctx.mpt_table.address_rlc, wrong_offset); + require!(key_rlc_lookup => key_rlc_wrong); + // Now make sure this address is different than the one of the leaf - let diff_inv = cb.base.query_cell(); - require!((a!(address_rlc, offset) - a!(accs.key.rlc, rot_key_s)) * diff_inv.expr() => 1); + config.check_is_wrong_leaf = RequireNotZeroGadget::construct(&mut cb.base, key_rlc_lookup - key_rlc[true.idx()].expr()); // Make sure the lengths of the keys are the same - let account_wrong = AccountLeafInfo::new(meta, ctx.clone(), offset); - require!(account_wrong.key_len(meta) => account.key_len(meta)); + require!(config.wrong_rlp_key.key_len() => config.rlp_key[true.idx()].key_len()); // RLC bytes zero check - let leaf = AccountLeafInfo::new(meta, ctx.clone(), offset); - let num_bytes = leaf.num_bytes_on_key_row(meta); + let num_bytes = config.wrong_rlp_key.num_bytes_on_key_row(); //cb.set_length(num_bytes); - ctx_diff_inv = diff_inv; } elsex { // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. - require!(key_data.is_placeholder_leaf_s => true); + require!(config.key_data_w.is_placeholder_leaf_s => true); }} - ctx_key_data_w = Some(key_data); } elsex { // is_wrong_leaf needs to be false when not in non_existing_account proof - require!(account.is_wrong_leaf(meta, true) => false); - }}; + require!(config.is_wrong_leaf => false); + }} + + let rot_key_s = offset - 2; + let rot_key_c = rot_key_s + 1; + let rot_nonce_s = rot_key_c + 2; + let rot_nonce_c = rot_nonce_s + 1; + let rot_storage_s = rot_nonce_c + 1; + let rot_storage_c = rot_storage_s + 1; offset += 1; ifx! {f!(ctx.position_cols.q_not_first) => { + // Nonce/balance + let mut nonce_rlc = vec![0.expr(); 2]; + let mut balance_rlc = vec![0.expr(); 2]; for is_s in [true, false] { let rot_key = offset - 3; let rot_s = if is_s { offset } else { offset - 1 }; @@ -318,14 +348,19 @@ impl AccountLeafConfig { let rlc = account.to_data_rlc(meta, ctx.main(is_s), value_rlc, is_long, offset); (rlc, num_bytes) }; - let (nonce_rlc, nonce_num_bytes) = calc_rlc( + //config.rlp_nonce[is_s.idx()] = RLPValueGadget::construct(&mut cb.base, &nonce_bytes[is_s.idx()][2..]); + //config.rlp_balance[is_s.idx()] = RLPValueGadget::construct(&mut cb.base, &balance_bytes[is_s.idx()][2..]); + + let nonce_num_bytes; + (nonce_rlc[is_s.idx()], nonce_num_bytes) = calc_rlc( nonce.expr(), account.is_nonce_long(), mult_diff_nonce.expr(), 4, true, ); - let (balance_rlc, balance_num_bytes) = calc_rlc( + let balance_num_bytes; + (balance_rlc[is_s.idx()], balance_num_bytes) = calc_rlc( balance.expr(), account.is_balance_long(), mult_diff_balance.expr(), @@ -333,6 +368,17 @@ impl AccountLeafConfig { false, ); + /*require!(config.rlp_nonce[is_s.idx()].is_long() => account.is_nonce_long()); + require!(config.rlp_balance[is_s.idx()].is_long() => account.is_balance_long()); + + let (nonce_value_rlc, nonce_leaf_rlc_value) = config.rlp_nonce[is_s.idx()].rlc(&r); + let (balance_value_rlc, balance_leaf_rlc_value) = config.rlp_balance[is_s.idx()].rlc(&r);*/ + + /*require!(nonce_value_rlc => nonce_rlc[is_s.idx()]); + require!(config.rlp_nonce[is_s.idx()].num_bytes() => nonce_num_bytes); + require!(balance_value_rlc => balance_rlc[is_s.idx()]); + require!(config.rlp_balance[is_s.idx()].num_bytes() => balance_num_bytes);*/ + // Calculate and store the combined nonce + balance multipliers let account_rlc = DataTransition::new_with_rot(meta, accs.acc_s.rlc, rot_key, offset); let mult_prev = a!(accs.acc_s.mult, rot_key); @@ -346,8 +392,8 @@ impl AccountLeafConfig { let rlc = account_rlc.prev() + account.nonce_balance_rlc( meta, - nonce_rlc.expr(), - balance_rlc.expr(), + nonce_rlc[is_s.idx()].expr(), + balance_rlc[is_s.idx()].expr(), mult_prev.expr(), mult_diff_nonce.expr(), offset, @@ -441,9 +487,10 @@ impl AccountLeafConfig { let rlc = account_rlc.prev() + account.storage_codehash_rlc(meta, storage_root.expr(), codehash.expr(), mult_prev.expr(), offset); require!(account_rlc => rlc); + // Parent data + let parent_data = &mut config.parent_data[is_s.idx()]; // Check if the account is in its parent. let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - let parent_data = ParentData::load("storage load", &mut cb.base, &ctx.memory[parent_memory(is_s)], 0.expr()); // Check is skipped for placeholder leafs which are dummy leafs ifx!{not!(and::expr(&[a!(ctx.position_cols.not_first_level, offset), not!(branch.is_placeholder()), branch.contains_placeholder_leaf(meta, is_s)])) => { let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); @@ -451,11 +498,6 @@ impl AccountLeafConfig { }} // Store the new parent ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [storage_root.expr(), true.expr(), false.expr(), storage_root.expr()]); - if is_s { - ctx_parent_data_s = Some(parent_data); - } else { - ctx_parent_data_c = Some(parent_data); - } if !is_s { // To enable lookups we need to have the previous/current storage root/code hash on the same row. @@ -501,12 +543,12 @@ impl AccountLeafConfig { let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); // Load the last key values - let key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 2.expr()); + config.key_data_d = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 2.expr()); // TODO(Brecht): make this work with loaded key data when extension node is separate ifx! {not!(branch.is_extension()) => { - require!(key_data.rlc => key_rlc_prev); - require!(key_data.mult => key_mult_prev); + require!(config.key_data_d.rlc => key_rlc_prev); + require!(config.key_data_d.mult => key_mult_prev); }} // Calculate the drifted key RLC @@ -546,7 +588,7 @@ impl AccountLeafConfig { let mult_prev = mult.expr() * mult_nonce.expr() * mult_balance.expr(); let rlc = rlc + account.storage_codehash_rlc(meta, storage_rlc.expr(), codehash_rlc.expr(), mult_prev.expr(), rot_storage); - (true.expr(), a!(accs.key.rlc, rot_key), rlc, a!(accs.mod_node_rlc(is_s), rot_first_child)) + (true.expr(), key_rlc[is_s.idx()].expr(), rlc, a!(accs.mod_node_rlc(is_s), rot_first_child)) }) }; let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { @@ -576,27 +618,18 @@ impl AccountLeafConfig { // The drifted leaf needs to be stored in the branch at `drifted_index`. require!((1, drifted_rlc, drifted_account.num_bytes(meta), mod_hash) => @"keccak"); }} - ctx_key_data_d = Some(key_data); }} }} }} }); - AccountLeafConfig { - key_data_s: ctx_key_data_s.unwrap(), - key_data_c: ctx_key_data_c.unwrap(), - key_data_w: ctx_key_data_w.unwrap(), - key_data_d: ctx_key_data_d.unwrap(), - parent_data_s: ctx_parent_data_s.unwrap(), - parent_data_c: ctx_parent_data_c.unwrap(), - diff_inv: ctx_diff_inv, - } + config } pub fn assign( &self, region: &mut Region<'_, F>, - mpt_config: &MPTConfig, + ctx: &MPTConfig, witness: &[MptWitnessRow], pv: &mut ProofValues, offset: usize, @@ -604,47 +637,50 @@ impl AccountLeafConfig { let base_offset = offset; let mut offset = offset - 1; - /* KEY */ - + let key_bytes = [&witness[base_offset - 1], &witness[base_offset + 0]]; + let wrong_bytes = &witness[base_offset + 1]; + let nonce_bytes = [&witness[base_offset + 2].bytes[..34].to_owned(), &witness[base_offset + 3].bytes[..34].to_owned()]; + let balance_bytes = [&witness[base_offset + 2].bytes[34..].to_owned(), &witness[base_offset + 3].bytes[34..].to_owned()]; + //let value_bytes = [&witness[offset + 1], &witness[offset + 3]]; + //let drifted_bytes = &witness[offset + 4]; + //let lookup_offset = offset + 3; + let wrong_offset = base_offset + 1; + + // Key + let mut key_rlc = vec![0.scalar(); 2]; for is_s in [true, false] { - let row = &witness[offset]; + let key_row = key_bytes[is_s.idx()]; + + //let key_row = &key_bytes[is_s.idx()]; + + let rlp_key_witness = self.rlp_key[is_s.idx()] + .assign(region, base_offset, &key_row.bytes) + .ok() + .unwrap(); // account leaf key S & C let mut acc = F::zero(); let mut acc_mult = F::one(); // 35 = 2 (leaf rlp) + 1 (key rlp) + key_len - let key_len = (row.get_byte(2) - 128) as usize; - for b in row.bytes.iter().take(3 + key_len) { + let key_len = (key_row.get_byte(2) - 128) as usize; + for b in key_row.bytes.iter().take(3 + key_len) { acc += F::from(*b as u64) * acc_mult; - acc_mult *= mpt_config.randomness; + acc_mult *= ctx.randomness; } - if row.get_type() == MptWitnessRowType::AccountLeafKeyS { + if key_row.get_type() == MptWitnessRowType::AccountLeafKeyS { pv.acc_account_s = acc; pv.acc_mult_account_s = acc_mult; - - if row.get_byte_rev(IS_ACCOUNT_DELETE_MOD_POS) == 1 { - region.assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(5_u64)), /* account delete mod lookup enabled in - * this row if it is is_account_delete - * proof */ - )?; + if key_row.get_byte_rev(IS_ACCOUNT_DELETE_MOD_POS) == 1 { + assign!(region, (ctx.proof_type.proof_type, offset) => ProofType::AccountDoesNotExist.scalar()).ok(); } } else { pv.acc_account_c = acc; pv.acc_mult_account_c = acc_mult; } - let key_data = if is_s { - &self.key_data_s - } else { - &self.key_data_c - }; - key_data.witness_load(region, base_offset, &mut pv.memory[key_memory(is_s)], 0)?; - key_data.witness_store( + self.key_data[is_s.idx()].witness_load(region, base_offset, &mut pv.memory[key_memory(is_s)], 0)?; + self.key_data[is_s.idx()].witness_store( region, base_offset, &mut pv.memory[key_memory(is_s)], @@ -662,16 +698,16 @@ impl AccountLeafConfig { // For leaf S and leaf C we need to start with the same rlc. let mut key_rlc_new = pv.key_rlc; let mut key_rlc_mult_new = pv.key_rlc_mult; - if (pv.is_branch_s_placeholder && row.get_type() == MptWitnessRowType::AccountLeafKeyS) + if (pv.is_branch_s_placeholder && key_row.get_type() == MptWitnessRowType::AccountLeafKeyS) || (pv.is_branch_c_placeholder - && row.get_type() == MptWitnessRowType::AccountLeafKeyC) + && key_row.get_type() == MptWitnessRowType::AccountLeafKeyC) { key_rlc_new = pv.key_rlc_prev; key_rlc_mult_new = pv.key_rlc_mult_prev; } - mpt_config.compute_key_rlc( - &row.bytes, + ctx.compute_key_rlc( + &key_row.bytes, &mut key_rlc_new, &mut key_rlc_mult_new, S_START, @@ -679,44 +715,53 @@ impl AccountLeafConfig { pv.account_key_rlc = key_rlc_new; region.assign_advice( || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, + ctx.accumulators.key.rlc, offset, || Value::known(key_rlc_new), )?; - mpt_config + ctx .assign_acc(region, acc, acc_mult, F::zero(), F::zero(), offset) .ok(); + self.mult[is_s.idx()] + .assign(region, base_offset, acc_mult) + .ok(); + + key_rlc[is_s.idx()] = key_rlc_new; offset += 1; } - /* NON_EXISTING */ + // Non-existing { + let row = wrong_bytes; + self.key_data_w .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) .ok(); - let row = &witness[offset]; - let address_rlc = bytes_into_rlc(row.address_bytes(), mpt_config.randomness); - let diff_inv = (address_rlc - pv.account_key_rlc) - .invert() - .unwrap_or(F::zero()); - self.diff_inv.assign(region, base_offset, diff_inv).ok(); + // TODO(Brecht): Change how the witness is generated + let is_wrong = row.bytes[0] != 0; + self.is_wrong_leaf + .assign(region, base_offset, F::from(is_wrong)) + .ok(); - if row.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, - offset, - || Value::known(F::from(4_u64)), /* non existing account lookup enabled - * in - * this row if it is - * non_existing_account - * proof */ - ) + let mut row_bytes = row.bytes.clone(); + row_bytes[0] = key_bytes[true.idx()].bytes[0]; + + let wrong_witness = self + .wrong_rlp_key + .assign(region, base_offset, &row_bytes) + .ok() + .unwrap(); + + let address_rlc = bytes_into_rlc(row.address_bytes(), ctx.randomness); + self.check_is_wrong_leaf + .assign(region, base_offset, address_rlc - key_rlc[true.idx()]) .ok(); + + if row.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1 { + assign!(region, (ctx.proof_type.proof_type, offset) => ProofType::AccountDestructed.scalar()).ok(); } } @@ -725,17 +770,27 @@ impl AccountLeafConfig { /* NONCE/BALANCE */ for is_s in [true, false] { - let row = &witness[offset]; + let value_row = &witness[offset]; + + let nonce_witness = self.rlp_nonce[is_s.idx()] + .assign(region, base_offset, &nonce_bytes[is_s.idx()][2..]) + .ok() + .unwrap(); + + let balance_witness = self.rlp_balance[is_s.idx()] + .assign(region, base_offset, &balance_bytes[is_s.idx()][2..]) + .ok() + .unwrap(); let mut nonce_len: usize = 1; // Note: when nonce or balance is 0, the actual value stored in RLP encoding is // 128. - if row.get_byte(S_START) > 128 { - nonce_len = row.get_byte(S_START) as usize - 128 + 1; // +1 for byte with length info + if value_row.get_byte(S_START) > 128 { + nonce_len = value_row.get_byte(S_START) as usize - 128 + 1; // +1 for byte with length info region .assign_advice( || "assign sel1".to_string(), - mpt_config.denoter.sel1, + ctx.denoter.sel1, offset - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, || Value::known(F::one()), @@ -745,7 +800,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign sel1".to_string(), - mpt_config.denoter.sel1, + ctx.denoter.sel1, offset - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, || Value::known(F::zero()), @@ -754,12 +809,12 @@ impl AccountLeafConfig { } let mut balance_len: usize = 1; - if row.get_byte(C_START) > 128 { - balance_len = row.get_byte(C_START) as usize - 128 + 1; // +1 for byte with length info + if value_row.get_byte(C_START) > 128 { + balance_len = value_row.get_byte(C_START) as usize - 128 + 1; // +1 for byte with length info region .assign_advice( || "assign sel2".to_string(), - mpt_config.denoter.sel2, + ctx.denoter.sel2, offset - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, || Value::known(F::one()), @@ -769,7 +824,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign sel2".to_string(), - mpt_config.denoter.sel2, + ctx.denoter.sel2, offset - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, || Value::known(F::zero()), @@ -784,10 +839,10 @@ impl AccountLeafConfig { // without RLP specific byte (there is a RLP specific byte when // nonce/balance RLP length > 1). if nonce_len == 1 && balance_len == 1 { - mpt_config + ctx .compute_rlc_and_assign( region, - &row.bytes, + &value_row.bytes, pv, offset, (S_START, HASH_WIDTH), @@ -795,10 +850,10 @@ impl AccountLeafConfig { ) .ok(); } else if nonce_len > 1 && balance_len == 1 { - mpt_config + ctx .compute_rlc_and_assign( region, - &row.bytes, + &value_row.bytes, pv, offset, (S_START + 1, HASH_WIDTH - 1), @@ -806,10 +861,10 @@ impl AccountLeafConfig { ) .ok(); } else if nonce_len == 1 && balance_len > 1 { - mpt_config + ctx .compute_rlc_and_assign( region, - &row.bytes, + &value_row.bytes, pv, offset, (S_START, HASH_WIDTH), @@ -817,10 +872,10 @@ impl AccountLeafConfig { ) .ok(); } else if nonce_len > 1 && balance_len > 1 { - mpt_config + ctx .compute_rlc_and_assign( region, - &row.bytes, + &value_row.bytes, pv, offset, (S_START + 1, HASH_WIDTH - 1), @@ -831,18 +886,18 @@ impl AccountLeafConfig { let mut acc_account; let mut acc_mult_account; - if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { + if value_row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { pv.nonce_value_s = pv.rlc1; pv.balance_value_s = pv.rlc2; acc_account = pv.acc_account_s; acc_mult_account = pv.acc_mult_account_s; - if row.get_byte_rev(IS_NONCE_MOD_POS) == 1 { + if value_row.get_byte_rev(IS_NONCE_MOD_POS) == 1 { region .assign_advice( || "assign which lookup type enabled".to_string(), - mpt_config.proof_type.proof_type, + ctx.proof_type.proof_type, offset, || Value::known(F::from(1_u64)), ) @@ -855,11 +910,11 @@ impl AccountLeafConfig { let nonce_value_c = pv.rlc1; let balance_value_c = pv.rlc2; - if row.get_byte_rev(IS_BALANCE_MOD_POS) == 1 { + if value_row.get_byte_rev(IS_BALANCE_MOD_POS) == 1 { region .assign_advice( || "assign which lookup type enabled".to_string(), - mpt_config.proof_type.proof_type, + ctx.proof_type.proof_type, offset, || Value::known(F::from(2_u64)), ) @@ -874,7 +929,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign nonce S".to_string(), - mpt_config.value_prev, + ctx.value_prev, offset_s, || Value::known(pv.nonce_value_s), ) @@ -884,7 +939,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign nonce C".to_string(), - mpt_config.value, + ctx.value, offset_s, || Value::known(nonce_value_c), ) @@ -894,7 +949,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign value_prev".to_string(), - mpt_config.value_prev, + ctx.value_prev, offset, || Value::known(pv.balance_value_s), ) @@ -904,7 +959,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign balance C".to_string(), - mpt_config.value, + ctx.value, offset, || Value::known(balance_value_c), ) @@ -912,16 +967,16 @@ impl AccountLeafConfig { } // s_rlp1, s_rlp2 - mpt_config.compute_acc_and_mult( - &row.bytes, + ctx.compute_acc_and_mult( + &value_row.bytes, &mut acc_account, &mut acc_mult_account, S_START - 2, 2, ); // c_rlp1, c_rlp2 - mpt_config.compute_acc_and_mult( - &row.bytes, + ctx.compute_acc_and_mult( + &value_row.bytes, &mut acc_account, &mut acc_mult_account, C_START - 2, @@ -944,8 +999,8 @@ impl AccountLeafConfig { - sel1/sel2: 1/1 (how to check: sel1*sel2) */ - mpt_config.compute_acc_and_mult( - &row.bytes, + ctx.compute_acc_and_mult( + &value_row.bytes, &mut acc_account, &mut acc_mult_account, S_START, @@ -955,7 +1010,7 @@ impl AccountLeafConfig { let mut mult_diff_s = F::one(); for _ in 0..nonce_len + 4 { // + 4 because of s_rlp1, s_rlp2, c_rlp1, c_rlp2 - mult_diff_s *= mpt_config.randomness; + mult_diff_s *= ctx.randomness; } // It's easier to constrain (in account_leaf_nonce_balance.rs) @@ -964,8 +1019,8 @@ impl AccountLeafConfig { let acc_mult_tmp = acc_mult_account; // balance contribution to leaf RLC - mpt_config.compute_acc_and_mult( - &row.bytes, + ctx.compute_acc_and_mult( + &value_row.bytes, &mut acc_account, &mut acc_mult_account, C_START, @@ -974,10 +1029,10 @@ impl AccountLeafConfig { let mut mult_diff_c = F::one(); for _ in 0..balance_len { - mult_diff_c *= mpt_config.randomness; + mult_diff_c *= ctx.randomness; } - mpt_config + ctx .assign_acc( region, acc_account, @@ -991,7 +1046,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign mult diff".to_string(), - mpt_config.accumulators.acc_c.rlc, /* assigning key_rlc leads into + ctx.accumulators.acc_c.rlc, /* assigning key_rlc leads into * PoisonedConstraint */ offset, || Value::known(mult_diff_s), @@ -1000,12 +1055,12 @@ impl AccountLeafConfig { region .assign_advice( || "assign mult diff".to_string(), - mpt_config.accumulators.key.mult, + ctx.accumulators.key.mult, offset, || Value::known(mult_diff_c), ) .ok(); - if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { + if value_row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { pv.acc_nonce_balance_s = acc_account; pv.acc_mult_nonce_balance_s = acc_mult_account; } else { @@ -1028,7 +1083,7 @@ impl AccountLeafConfig { // storage root RLC and code hash RLC pv.rlc1 = F::zero(); pv.rlc2 = F::zero(); - mpt_config + ctx .compute_rlc_and_assign( region, &row.bytes, @@ -1047,7 +1102,7 @@ impl AccountLeafConfig { // assign storage root RLC and code hash RLC for this row pv.rlc1 = F::zero(); pv.rlc2 = F::zero(); - mpt_config + ctx .compute_rlc_and_assign( region, &row.bytes, @@ -1067,7 +1122,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign lookup enabled".to_string(), - mpt_config.proof_type.proof_type, + ctx.proof_type.proof_type, offset, || Value::known(F::from(3_u64)), /* codehash mod lookup enabled in * this row if it is @@ -1084,7 +1139,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign storage root S".to_string(), - mpt_config.value_prev, + ctx.value_prev, offset_s, || Value::known(pv.storage_root_value_s), ) @@ -1094,7 +1149,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign code hash C".to_string(), - mpt_config.value, + ctx.value, offset_s, || Value::known(storage_root_value_c), ) @@ -1104,7 +1159,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign code hash S".to_string(), - mpt_config.value_prev, + ctx.value_prev, offset, || Value::known(pv.codehash_value_s), ) @@ -1114,7 +1169,7 @@ impl AccountLeafConfig { region .assign_advice( || "assign code hash C".to_string(), - mpt_config.value, + ctx.value, offset, || Value::known(codehash_value_c), ) @@ -1126,15 +1181,10 @@ impl AccountLeafConfig { } else { pv.storage_root_value_c }; - let parent_data = if is_s { - &self.parent_data_s - } else { - &self.parent_data_c - }; - parent_data + self.parent_data[is_s.idx()] .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) .ok(); - parent_data + self.parent_data[is_s.idx()] .witness_store( region, base_offset, @@ -1147,7 +1197,7 @@ impl AccountLeafConfig { .ok(); // storage - mpt_config.compute_acc_and_mult( + ctx.compute_acc_and_mult( &row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, @@ -1155,14 +1205,14 @@ impl AccountLeafConfig { HASH_WIDTH + 1, ); // code hash - mpt_config.compute_acc_and_mult( + ctx.compute_acc_and_mult( &row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, C_START - 1, HASH_WIDTH + 1, ); - mpt_config + ctx .assign_acc( region, pv.acc_s, @@ -1183,13 +1233,13 @@ impl AccountLeafConfig { pv.acc_s = F::zero(); pv.acc_mult_s = F::one(); let len = (row.bytes[2] - 128) as usize + 3; - mpt_config.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); + ctx.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); self.key_data_d .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 2) .ok(); - mpt_config + ctx .assign_acc( region, pv.acc_s, diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index 2f9be82439..6fe81cd1b9 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -4,7 +4,7 @@ use crate::{ _cb, circuit, circuit_tools::{ cell_manager::{Cell, CellManager, DataTransition, Trackable}, - constraint_builder::{Conditionable, ConstraintBuilder, RLCChainable, RLCable}, + constraint_builder::{Conditionable, ConstraintBuilder, RLCChainable, RLCable, RLCableValue, RLCChainableValue}, gadgets::IsEqualGadget, memory::MemoryBank, }, @@ -21,7 +21,7 @@ use gadgets::util::{and, not, Scalar}; use halo2_proofs::{ circuit::Region, plonk::{Error, Expression, VirtualCells}, - poly::Rotation, + poly::Rotation, halo2curves::FieldExt, }; use super::{ @@ -343,6 +343,14 @@ impl RLPValueGadget { } }) } + + pub(crate) fn rlc_rlp(&self, r: &[Expression]) -> Expression { + self.rlc(r).0 + } + + pub(crate) fn rlc_value(&self, r: &[Expression]) -> Expression { + self.rlc(r).1 + } } impl RLPValueWitness { @@ -392,6 +400,31 @@ impl RLPValueWitness { }, } } + + /// RLC data + pub(crate) fn rlc(&self, r: F) -> (F, F) { + matchr! { + self.is_short() => { + let value_rlc = self.bytes[0].scalar(); + (value_rlc, value_rlc) + }, + self.is_long() => { + let value_rlc = self.bytes[1..].rlc_value(r); + (value_rlc, self.bytes.rlc_value(r)) + }, + self.is_very_long() => { + unreachable!(); + }, + } + } + + pub(crate) fn rlc_rlp(&self, r: F) -> F { + self.rlc(r).0 + } + + pub(crate) fn rlc_value(&self, r: F) -> F { + self.rlc(r).1 + } } #[derive(Clone, Debug, Default)] @@ -620,6 +653,14 @@ impl LeafKeyWitness { unreachable!(); } } + + /// Number of bytes of RLP (including list RLP bytes) and key + pub(crate) fn rlc_leaf(&self, r: F) -> (F, F) { + (0.scalar(), 1.scalar()).rlc_chain_value( + &self.bytes[0..(self.num_bytes_on_key_row() as usize)], + r + ) + } } #[derive(Clone, Debug, Default)] @@ -1466,32 +1507,6 @@ impl BranchChildInfo { } } -#[derive(Clone)] -pub(crate) struct StorageLeafInfo { - pub(crate) is_s: bool, - pub(crate) ctx: MPTContext, - pub(crate) rot_key: i32, -} - -impl StorageLeafInfo { - pub(crate) fn new(ctx: MPTContext, is_s: bool, rot_key: i32) -> Self { - StorageLeafInfo { - is_s, - ctx: ctx.clone(), - rot_key, - } - } - - pub(crate) fn set_is_s(&mut self, is_s: bool) { - self.is_s = is_s; - } - - pub(crate) fn is_below_account(&self, meta: &mut VirtualCells) -> Expression { - let rot_parent = if self.is_s { -1 } else { -3 }; - self.ctx.is_account(meta, self.rot_key + rot_parent) - } -} - #[derive(Clone)] pub(crate) struct AccountLeafInfo { rot_key: i32, diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index 2d45eeb3e7..54c8e60550 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -9,21 +9,20 @@ use halo2_proofs::{ use std::marker::PhantomData; use crate::circuit_tools::cell_manager::Cell; -use crate::circuit_tools::constraint_builder::{ConstraintBuilder, RLCChainable, RLCable}; +use crate::circuit_tools::constraint_builder::{RLCChainable, RLCable, RLCChainableValue, RLCableValue}; use crate::circuit_tools::gadgets::{IsEqualGadget, LtGadget, RequireNotZeroGadget}; use crate::mpt_circuit::helpers::drifted_nibble_rlc; use crate::table::ProofType; use crate::{ assign, circuit, - mpt_circuit::{helpers::BranchNodeInfo, param::BRANCH_ROWS_NUM}, mpt_circuit::{ helpers::{ - get_parent_rlc_state, key_memory, parent_memory, KeyData, MPTConstraintBuilder, - ParentData, StorageLeafInfo, + key_memory, parent_memory, KeyData, MPTConstraintBuilder, + ParentData, }, param::{ EMPTY_TRIE_HASH, HASH_WIDTH, IS_NON_EXISTING_STORAGE_POS, IS_STORAGE_MOD_POS, - KEY_LEN_IN_NIBBLES, LEAF_KEY_C_IND, LEAF_NON_EXISTING_IND, + KEY_LEN_IN_NIBBLES, }, FixedTableTag, }, @@ -160,7 +159,7 @@ impl StorageLeafConfig { ); config.is_in_empty_branch[is_s.idx()] = IsEqualGadget::construct(&mut cb.base, parent_data.rlc.expr(), 128.expr()); - let is_placeholder = or::expr(&[ + let is_placeholder_leaf = or::expr(&[ config.is_in_empty_trie[is_s.idx()].expr(), config.is_in_empty_branch[is_s.idx()].expr(), ]); @@ -184,7 +183,7 @@ impl StorageLeafConfig { // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES (except in a // placeholder leaf). // TODO(Brecht): why not in placeholder leaf? - ifx! {not!(is_placeholder) => { + ifx! {not!(is_placeholder_leaf) => { let num_nibbles = rlp_key.num_key_nibbles(key_data.is_odd.expr()); require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); }} @@ -216,7 +215,7 @@ impl StorageLeafConfig { // ensure that the value is set to 0 in the placeholder leaf. For // example when adding a new storage leaf to the trie, we have an empty child in // `S` proof and non-empty in `C` proof. - ifx! {is_placeholder => { + ifx! {is_placeholder_leaf => { require!(value_rlc[is_s.idx()] => 0); }} @@ -229,14 +228,14 @@ impl StorageLeafConfig { // storage = [key, value] // TODO(Brecht): modify the witness for empty placeholder leafs to have valid // RLP encoding - ifx! {not!(is_placeholder) => { + ifx! {not!(is_placeholder_leaf) => { let key_num_bytes = rlp_key.num_bytes_on_key_row(); require!(num_bytes => key_num_bytes.expr() + value_num_bytes.expr()); }}; // Check if the account is in its parent. // Check is skipped for placeholder leafs which are dummy leafs - ifx! {not!(is_placeholder) => { + ifx! {not!(is_placeholder_leaf) => { config.is_not_hashed[is_s.idx()] = LtGadget::construct(&mut cb.base, num_bytes.expr(), 32.expr()); ifx!{or::expr(&[parent_data.is_root.expr(), not!(config.is_not_hashed[is_s.idx()])]) => { // Hashed branch hash in parent branch @@ -387,140 +386,108 @@ impl StorageLeafConfig { let mut value_rlc = vec![0.scalar(); 2]; for is_s in [true, false] { // Key - { - let key_row = &key_bytes[is_s.idx()]; + let key_row = &key_bytes[is_s.idx()]; - let rlp_key_witness = self.rlp_key[is_s.idx()] - .assign(region, base_offset, &key_row.bytes) - .ok() - .unwrap(); - - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - ctx.compute_acc_and_mult( - &key_row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - 0, - rlp_key_witness.num_bytes_on_key_row() as usize, - ); - - self.mult[is_s.idx()] - .assign(region, base_offset, pv.acc_mult_s) - .ok(); + let rlp_key_witness = self.rlp_key[is_s.idx()] + .assign(region, base_offset, &key_row.bytes) + .ok() + .unwrap(); - self.is_not_hashed[is_s.idx()] - .assign( - region, - base_offset, - F::from(rlp_key_witness.num_bytes()), - F::from(32), - ) - .ok(); + let (_, leaf_mult) = rlp_key_witness.rlc_leaf(ctx.randomness); + self.mult[is_s.idx()] + .assign(region, base_offset, leaf_mult) + .ok(); - self.key_data[is_s.idx()].witness_load( + self.is_not_hashed[is_s.idx()] + .assign( region, base_offset, - &mut pv.memory[key_memory(is_s)], - 0, - )?; - self.key_data[is_s.idx()].witness_store( - region, - base_offset, - &mut pv.memory[key_memory(is_s)], - F::zero(), - F::one(), - 0, - false, - false, - 0, - false, - F::zero(), - F::one(), - )?; + F::from(rlp_key_witness.num_bytes()), + F::from(32), + ) + .ok(); - // For leaf S and leaf C we need to start with the same rlc. - let mut key_rlc_new = pv.key_rlc; - let mut key_rlc_mult_new = pv.key_rlc_mult; - if (pv.is_branch_s_placeholder - && key_row.get_type() == MptWitnessRowType::StorageLeafSKey) - || (pv.is_branch_c_placeholder - && key_row.get_type() == MptWitnessRowType::StorageLeafCKey) - { - key_rlc_new = pv.key_rlc_prev; - key_rlc_mult_new = pv.key_rlc_mult_prev; - } - if rlp_key_witness.num_bytes_on_key_row() != 2 { - // If in last level or having only one nibble, - // the key RLC is already computed using the first two bytes above. - ctx.compute_key_rlc( - &key_row.bytes, - &mut key_rlc_new, - &mut key_rlc_mult_new, - rlp_key_witness.num_rlp_bytes_list() as usize, - ); - } - key_rlc[is_s.idx()] = key_rlc_new; + self.key_data[is_s.idx()].witness_load( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + 0, + )?; + self.key_data[is_s.idx()].witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + F::zero(), + F::one(), + 0, + false, + false, + 0, + false, + F::zero(), + F::one(), + )?; + + // For leaf S and leaf C we need to start with the same rlc. + let mut key_rlc_new = pv.key_rlc; + let mut key_rlc_mult_new = pv.key_rlc_mult; + if (pv.is_branch_s_placeholder + && key_row.get_type() == MptWitnessRowType::StorageLeafSKey) + || (pv.is_branch_c_placeholder + && key_row.get_type() == MptWitnessRowType::StorageLeafCKey) + { + key_rlc_new = pv.key_rlc_prev; + key_rlc_mult_new = pv.key_rlc_mult_prev; + } + if rlp_key_witness.num_bytes_on_key_row() != 2 { + // If in last level or having only one nibble, + // the key RLC is already computed using the first two bytes above. + ctx.compute_key_rlc( + &key_row.bytes, + &mut key_rlc_new, + &mut key_rlc_mult_new, + rlp_key_witness.num_rlp_bytes_list() as usize, + ); } + key_rlc[is_s.idx()] = key_rlc_new; // Value - { - let value_row = &value_bytes[is_s.idx()]; - - let value_witness = self.rlp_value[is_s.idx()] - .assign(region, base_offset, &value_row.bytes) - .ok() - .unwrap(); + let value_row = &value_bytes[is_s.idx()]; - // Leaf RLC - ctx.compute_acc_and_mult( - &value_row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - 0, - HASH_WIDTH + 2, - ); - - pv.acc_c = F::zero(); - pv.acc_mult_c = F::one(); - ctx.compute_acc_and_mult( - &value_row.bytes, - &mut pv.acc_c, - &mut pv.acc_mult_c, - value_witness.num_rlp_bytes() as usize, - HASH_WIDTH + 2, - ); + let value_witness = self.rlp_value[is_s.idx()] + .assign(region, base_offset, &value_row.bytes) + .ok() + .unwrap(); - value_rlc[is_s.idx()] = pv.acc_c; + value_rlc[is_s.idx()] = value_row.bytes[value_witness.num_rlp_bytes() as usize..HASH_WIDTH + 2].rlc_value(ctx.randomness); - let parent_values = self.parent_data[is_s.idx()] - .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) - .ok() - .unwrap(); - self.parent_data[is_s.idx()] - .witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(is_s)], - F::zero(), - true, - false, - F::zero(), - ) - .ok(); + let parent_values = self.parent_data[is_s.idx()] + .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) + .ok() + .unwrap(); + self.parent_data[is_s.idx()] + .witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + F::zero(), + true, + false, + F::zero(), + ) + .ok(); - self.is_in_empty_trie[is_s.idx()] - .assign( - region, - base_offset, - parent_values[0], - bytes_into_rlc(&EMPTY_TRIE_HASH, ctx.randomness), - ) - .ok(); - self.is_in_empty_branch[is_s.idx()] - .assign(region, base_offset, parent_values[0], 128.scalar()) - .ok(); - } + self.is_in_empty_trie[is_s.idx()] + .assign( + region, + base_offset, + parent_values[0], + bytes_into_rlc(&EMPTY_TRIE_HASH, ctx.randomness), + ) + .ok(); + self.is_in_empty_branch[is_s.idx()] + .assign(region, base_offset, parent_values[0], 128.scalar()) + .ok(); } // Put the data in the lookup table @@ -541,22 +508,14 @@ impl StorageLeafConfig { .ok() .unwrap(); - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - ctx.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - 0, - drifted_key_witness.num_bytes_on_key_row() as usize, - ); + let (_, leaf_mult) = drifted_key_witness.rlc_leaf(ctx.randomness); self.drifted_mult - .assign(region, base_offset, pv.acc_mult_s) + .assign(region, base_offset, leaf_mult) .ok(); } - // Wrong leaf handling + // Non-existing { let row = &wrong_bytes; if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { From 7896566a0525003c1f186268eb87b757d0b9358a Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Mon, 20 Feb 2023 02:55:10 +0100 Subject: [PATCH 08/11] Account leaf refactor --- .../src/circuit_tools/constraint_builder.rs | 8 +- zkevm-circuits/src/mpt_circuit.rs | 33 +- .../src/mpt_circuit/account_leaf.rs | 1486 ++++++----------- zkevm-circuits/src/mpt_circuit/branch.rs | 1 + zkevm-circuits/src/mpt_circuit/helpers.rs | 395 ++--- .../src/mpt_circuit/storage_leaf.rs | 362 ++-- zkevm-circuits/src/mpt_circuit/witness_row.rs | 1 + 7 files changed, 767 insertions(+), 1519 deletions(-) diff --git a/zkevm-circuits/src/circuit_tools/constraint_builder.rs b/zkevm-circuits/src/circuit_tools/constraint_builder.rs index 43821c35ab..685a157b55 100644 --- a/zkevm-circuits/src/circuit_tools/constraint_builder.rs +++ b/zkevm-circuits/src/circuit_tools/constraint_builder.rs @@ -648,12 +648,7 @@ impl RLCChainable for (Expression, Expression) { } } -pub(crate) fn rlc_acc( - values: &[u8], - rlc: F, - mult: F, - r: F, -) -> (F, F) { +pub(crate) fn rlc_acc(values: &[u8], rlc: F, mult: F, r: F) -> (F, F) { let mut rlc = rlc; let mut mult = mult; for &value in values.iter() { @@ -663,7 +658,6 @@ pub(crate) fn rlc_acc( (rlc, mult) } - /// Trait around RLC pub trait RLCableValue { /// Returns the RLC of itself diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index f3533b788f..23975f1d18 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -262,16 +262,12 @@ pub(crate) struct ProofValues { pub(crate) is_long: bool, pub(crate) rlc1: F, pub(crate) rlc2: F, - pub(crate) nonce_value_s: F, - pub(crate) balance_value_s: F, pub(crate) storage_root_value_s: F, pub(crate) storage_root_value_c: F, pub(crate) codehash_value_s: F, pub(crate) before_account_leaf: bool, pub(crate) nibbles_num: usize, - pub(crate) account_key_rlc: F, - pub(crate) is_hashed_s: bool, pub(crate) is_hashed_c: bool, @@ -775,8 +771,8 @@ impl MPTConfig { /// Make the assignments to the MPTCircuit pub fn assign( &mut self, - mut layouter: impl Layouter, - witness: &[MptWitnessRow], + layouter: &mut impl Layouter, + witness: &mut [MptWitnessRow], randomness: F, ) { self.randomness = randomness; @@ -808,7 +804,8 @@ impl MPTConfig { ]); } - for (idx, row) in witness + let working_witness = witness.to_owned().clone(); + for (idx, row) in working_witness .iter() .filter(|r| r.get_type() != MptWitnessRowType::HashToBeComputed) .enumerate() @@ -816,7 +813,7 @@ impl MPTConfig { //println!("offset: {}", offset); let mut new_proof = offset == 0; if offset > 0 { - let row_prev = &witness[offset - 1]; + let row_prev = working_witness[offset - 1].clone(); let not_first_level_prev = row_prev.not_first_level(); let not_first_level_cur = row.not_first_level(); if not_first_level_cur == 0 && not_first_level_prev == 1 { @@ -881,9 +878,9 @@ impl MPTConfig { row.assign_lookup_columns(&mut region, self, &pv, offset)?; let prev_row = if offset > 0 { - &witness[offset - 1] + working_witness[offset - 1].clone() } else { - row + row.clone() }; // leaf s or leaf c or leaf key s or leaf key c @@ -949,7 +946,7 @@ impl MPTConfig { if !(row.get_type() == MptWitnessRowType::InitBranch || row.get_type() == MptWitnessRowType::BranchChild) { - row.assign( + witness[idx].assign( &mut region, self, account_leaf, @@ -960,12 +957,12 @@ impl MPTConfig { } if offset > 0 && prev_row.get_type() == MptWitnessRowType::InitBranch { - println!("{}: branch", offset); + //println!("{}: branch", offset); self.branch_config .assign(&mut region, witness, self, &mut pv, offset) .ok(); } else if row.get_type() == MptWitnessRowType::StorageLeafSKey { - println!("{}: storage", offset); + //println!("{}: storage", offset); self.storage_config.assign( &mut region, self, @@ -974,7 +971,7 @@ impl MPTConfig { offset, )?; } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { - println!("{}: account", offset); + //println!("{}: account", offset); self.account_config.assign( &mut region, self, @@ -994,7 +991,7 @@ impl MPTConfig { ) .ok(); - memory.assign(&mut layouter, height).ok(); + memory.assign(layouter, height).ok(); } fn load_fixed_table( @@ -1161,15 +1158,15 @@ impl Circuit for MPTCircuit { } } + config.load_fixed_table(&mut layouter, self.randomness).ok(); + config.assign(&mut layouter, &mut witness_rows, self.randomness); + let challenges = Challenges::mock(Value::known(self.randomness)); config .keccak_table .dev_load(&mut layouter, &to_be_hashed, &challenges, false) .ok(); - config.load_fixed_table(&mut layouter, self.randomness).ok(); - config.assign(layouter, &witness_rows, self.randomness); - Ok(()) } } diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index 3929300b67..391bf27aba 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -1,6 +1,6 @@ use eth_types::Field; use gadgets::util::Scalar; -use halo2_proofs::plonk::{Advice, Column, ConstraintSystem, Expression}; +use halo2_proofs::plonk::{Advice, Column, ConstraintSystem}; use halo2_proofs::{ circuit::{Region, Value}, plonk::{Error, VirtualCells}, @@ -8,41 +8,29 @@ use halo2_proofs::{ }; use std::marker::PhantomData; +use crate::circuit_tools::constraint_builder::RLCChainable; use crate::circuit_tools::gadgets::RequireNotZeroGadget; -use crate::mpt_circuit::helpers::Indexable; +use crate::mpt_circuit::helpers::{drifted_nibble_rlc, Indexable, IsEmptyTreeGadget}; use crate::table::ProofType; use crate::{ - assign, - circuit, - circuit_tools::cell_manager::{Cell, DataTransition}, - circuit_tools::constraint_builder::{ConstraintBuilder, RLCable}, + assign, circuit, + circuit_tools::cell_manager::Cell, + circuit_tools::constraint_builder::RLCable, mpt_circuit::{ - helpers::{get_num_bytes_short, BranchNodeInfo}, - param::{BRANCH_ROWS_NUM, S_START}, - }, - mpt_circuit::{ - helpers::{ - get_num_nibbles, get_parent_rlc_state, key_memory, parent_memory, AccountLeafInfo, - KeyData, MPTConstraintBuilder, ParentData, - }, - param::{KEY_LEN_IN_NIBBLES, RLP_HASH_VALUE, RLP_LIST_LONG, RLP_LONG}, + helpers::{key_memory, parent_memory, KeyData, MPTConstraintBuilder, ParentData}, + param::{KEY_LEN_IN_NIBBLES, RLP_LIST_LONG, RLP_LONG}, FixedTableTag, }, mpt_circuit::{param::IS_ACCOUNT_DELETE_MOD_POS, MPTConfig, ProofValues}, - mpt_circuit::{ - witness_row::{MptWitnessRow, MptWitnessRowType}, - MPTContext, - }, + mpt_circuit::{witness_row::MptWitnessRow, MPTContext}, }; use super::helpers::{LeafKeyGadget, RLPValueGadget}; use super::{ helpers::bytes_into_rlc, param::{ - ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_NONCE_BALANCE_C_IND, - ACCOUNT_LEAF_NONCE_BALANCE_S_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND, - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, C_START, HASH_WIDTH, IS_BALANCE_MOD_POS, - IS_CODEHASH_MOD_POS, IS_NONCE_MOD_POS, IS_NON_EXISTING_ACCOUNT_POS, + HASH_WIDTH, IS_BALANCE_MOD_POS, IS_CODEHASH_MOD_POS, IS_NONCE_MOD_POS, + IS_NON_EXISTING_ACCOUNT_POS, }, }; @@ -73,30 +61,6 @@ impl AccountLeafCols { _marker: PhantomData, } } - - pub(crate) fn is_key(&self, is_s: bool) -> Column { - if is_s { - self.is_key_s - } else { - self.is_key_c - } - } - - pub(crate) fn is_nonce_balance(&self, is_s: bool) -> Column { - if is_s { - self.is_nonce_balance_s - } else { - self.is_nonce_balance_c - } - } - - pub(crate) fn is_storage_codehash(&self, is_s: bool) -> Column { - if is_s { - self.is_storage_codehash_s - } else { - self.is_storage_codehash_c - } - } } #[derive(Default, Debug)] @@ -115,15 +79,21 @@ pub(crate) struct AccountLeaf { pub(crate) struct AccountLeafConfig { key_data: [KeyData; 2], key_data_w: KeyData, - key_data_d: KeyData, parent_data: [ParentData; 2], check_is_wrong_leaf: RequireNotZeroGadget, rlp_key: [LeafKeyGadget; 2], - mult: [Cell; 2], + key_mult: [Cell; 2], wrong_rlp_key: LeafKeyGadget, is_wrong_leaf: Cell, rlp_nonce: [RLPValueGadget; 2], rlp_balance: [RLPValueGadget; 2], + rlp_storage: [RLPValueGadget; 2], + rlp_codehash: [RLPValueGadget; 2], + nonce_mult: [Cell; 2], + balance_mult: [Cell; 2], + drifted_rlp_key: LeafKeyGadget, + drifted_mult: Cell, + is_empty_trie: [IsEmptyTreeGadget; 2], } impl AccountLeafConfig { @@ -133,46 +103,66 @@ impl AccountLeafConfig { ctx: MPTContext, ) -> Self { let proof_type = ctx.proof_type; - let not_first_level = ctx.position_cols.not_first_level; - let address_rlc = ctx.address_rlc; - let s_main = ctx.s_main; - let c_main = ctx.c_main; - let accs = ctx.accumulators; - let value_prev = ctx.value_prev; - let value = ctx.value; let r = ctx.r.clone(); - let mut offset = -1; - - // key rlc is in the first branch node - let rot_parent = offset - 1; - let rot_first_child = offset - BRANCH_ROWS_NUM + 1; - let rot_branch_init = rot_first_child - 1; - cb.base.cell_manager.as_mut().unwrap().reset(); let mut config = AccountLeafConfig::default(); circuit!([meta, cb.base], { - let key_bytes = [ctx.expr(meta, -1), ctx.expr(meta, 0)]; - let wrong_bytes = ctx.expr(meta, 1); - let nonce_bytes = [ctx.expr(meta, 2)[..34].to_owned(), ctx.expr(meta, 3)[..34].to_owned()]; - let balance_bytes = [ctx.expr(meta, 2)[34..].to_owned(), ctx.expr(meta, 3)[..34].to_owned()]; - //let value_bytes = [ctx.expr(meta, 1), ctx.expr(meta, 3)]; - //let drifted_bytes = ctx.expr(meta, 4); - // - //let lookup_offset = 3; + let key_bytes = [ + ctx.expr(meta, -1)[..36].to_owned(), + ctx.expr(meta, 0)[..36].to_owned(), + ]; + let wrong_bytes = ctx.expr(meta, 1)[..36].to_owned(); + let value_rlp_bytes = [ + [ + ctx.expr(meta, 2)[..2].to_owned(), + ctx.expr(meta, 2)[34..36].to_owned(), + ] + .concat(), + [ + ctx.expr(meta, 3)[..2].to_owned(), + ctx.expr(meta, 3)[34..36].to_owned(), + ] + .concat(), + ]; + let nonce_bytes = [ + ctx.expr(meta, 2)[..34].to_owned(), + ctx.expr(meta, 3)[..34].to_owned(), + ]; + let balance_bytes = [ + ctx.expr(meta, 2)[34..].to_owned(), + ctx.expr(meta, 3)[34..].to_owned(), + ]; + let storage_bytes = [ + ctx.expr(meta, 4)[..34].to_owned(), + ctx.expr(meta, 5)[..34].to_owned(), + ]; + let codehash_bytes = [ + ctx.expr(meta, 4)[34..].to_owned(), + ctx.expr(meta, 5)[34..].to_owned(), + ]; + let drifted_bytes = ctx.expr(meta, 6)[..36].to_owned(); + + let nonce_lookup_offset = 2; + let balance_lookup_offset = 3; + let storage_lookup_offset = 4; + let codehash_lookup_offset = 5; let wrong_offset = 1; - let mut key_rlc = vec![0.expr(); 2]; - for is_s in [true, false] { - // Account leaf always starts with RLP_LIST_LONG + 1 because its length is - // always longer than 55 bytes due to containing two hashes - - // storage root and codehash. - require!(key_bytes[is_s.idx()][0] => RLP_LIST_LONG + 1); + // The two string RLP bytes stored in the s RLP bytes. + // The two list RLP bytes are stored in the c RLP bytes. + // The RLP bytes of nonce/balance are stored bytes[0]. - // Calculate and store the leaf data RLC - require!(a!(accs.acc_s.rlc, offset) => key_bytes[is_s.idx()][0..36].rlc(&r)); + config.is_wrong_leaf = cb.base.query_cell(); + let mut key_rlc = vec![0.expr(); 2]; + let mut nonce_rlc = vec![0.expr(); 2]; + let mut balance_rlc = vec![0.expr(); 2]; + let mut storage_rlc = vec![0.expr(); 2]; + let mut codehash_rlc = vec![0.expr(); 2]; + let mut leaf_no_key_rlc = vec![0.expr(); 2]; + for is_s in [true, false] { // Key data let key_data = &mut config.key_data[is_s.idx()]; *key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], 0.expr()); @@ -186,9 +176,67 @@ impl AccountLeafConfig { 0.expr(), ); + // Placeholder leaf checks + config.is_empty_trie[is_s.idx()] = + IsEmptyTreeGadget::construct(&mut cb.base, parent_data.rlc.expr(), &r); + // Calculate the key RLC let rlp_key = &mut config.rlp_key[is_s.idx()]; *rlp_key = LeafKeyGadget::construct(&mut cb.base, &key_bytes[is_s.idx()]); + config.rlp_nonce[is_s.idx()] = + RLPValueGadget::construct(&mut cb.base, &nonce_bytes[is_s.idx()][2..]); + config.rlp_balance[is_s.idx()] = + RLPValueGadget::construct(&mut cb.base, &balance_bytes[is_s.idx()][2..]); + config.rlp_storage[is_s.idx()] = + RLPValueGadget::construct(&mut cb.base, &storage_bytes[is_s.idx()][1..]); + config.rlp_codehash[is_s.idx()] = + RLPValueGadget::construct(&mut cb.base, &codehash_bytes[is_s.idx()][1..]); + + ifx! {not!(and::expr(&[a!(ctx.proof_type.is_non_existing_account_proof), not!(config.is_wrong_leaf)])) => { + // Storage root and codehash are always 32-byte hashes. + require!(config.rlp_storage[is_s.idx()].len() => HASH_WIDTH); + require!(config.rlp_codehash[is_s.idx()].len() => HASH_WIDTH); + }} + + config.key_mult[is_s.idx()] = cb.base.query_cell(); + config.nonce_mult[is_s.idx()] = cb.base.query_cell(); + config.balance_mult[is_s.idx()] = cb.base.query_cell(); + require!((FixedTableTag::RMult, rlp_key.num_bytes_on_key_row(), config.key_mult[is_s.idx()].expr()) => @"fixed"); + require!((FixedTableTag::RMult, config.rlp_nonce[is_s.idx()].num_bytes() + 4.expr(), config.nonce_mult[is_s.idx()].expr()) => @format!("fixed")); + require!((FixedTableTag::RMult, config.rlp_balance[is_s.idx()].num_bytes(), config.balance_mult[is_s.idx()].expr()) => @format!("fixed")); + + // RLC bytes zero check + // TODO(Brecht): add all these checks back + cb.set_length(rlp_key.num_bytes_on_key_row()); + + let nonce_rlp_rlc; + let balance_rlp_rlc; + let storage_rlp_rlc; + let codehash_rlp_rlc; + (nonce_rlc[is_s.idx()], nonce_rlp_rlc) = config.rlp_nonce[is_s.idx()].rlc(&r); + (balance_rlc[is_s.idx()], balance_rlp_rlc) = config.rlp_balance[is_s.idx()].rlc(&r); + (storage_rlc[is_s.idx()], storage_rlp_rlc) = config.rlp_storage[is_s.idx()].rlc(&r); + (codehash_rlc[is_s.idx()], codehash_rlp_rlc) = + config.rlp_codehash[is_s.idx()].rlc(&r); + + // Calculate the leaf RLC + leaf_no_key_rlc[is_s.idx()] = (0.expr(), 1.expr()).rlc_chain( + ( + [value_rlp_bytes[is_s.idx()].clone(), vec![nonce_rlp_rlc]] + .concat() + .rlc(&r), + config.nonce_mult[is_s.idx()].expr(), + ) + .rlc_chain( + (balance_rlp_rlc, config.balance_mult[is_s.idx()].expr()).rlc_chain( + (storage_rlp_rlc, r[32].expr()).rlc_chain(codehash_rlp_rlc), + ), + ), + ); + let leaf_rlc = (rlp_key.rlc(&r), config.key_mult[is_s.idx()].expr()) + .rlc_chain(leaf_no_key_rlc[is_s.idx()].expr()); + + // Key key_rlc[is_s.idx()] = key_data.rlc.expr() + rlp_key.key_rlc( &mut cb.base, @@ -198,67 +246,117 @@ impl AccountLeafConfig { true, &r, ); - // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES. let num_nibbles = rlp_key.num_key_nibbles(key_data.is_odd.expr()); require!(key_data.num_nibbles.expr() + num_nibbles.expr() => KEY_LEN_IN_NIBBLES); + // Check if the account is in its parent. + // Check is skipped for placeholder leafs which are dummy leafs + ifx! {not!(and::expr(&[not!(config.parent_data[is_s.idx()].is_placeholder), config.is_empty_trie[is_s.idx()].expr()])) => { + require!((1, leaf_rlc, config.rlp_key[is_s.idx()].num_bytes(), config.parent_data[is_s.idx()].rlc) => @"keccak"); + }} + + // Check the RLP encoding consistency. + // RlP encoding: account = [key, [nonce, balance, storage, codehash]] + ifx! {not!(and::expr(&[a!(ctx.proof_type.is_non_existing_account_proof), not!(config.is_wrong_leaf)])) => { + // We always store between 55 and 256 bytes of data in the values list. + require!(value_rlp_bytes[is_s.idx()][0] => RLP_LONG + 1); + // The RLP encoded list always has 2 RLP bytes (the c RLP bytes). + require!(value_rlp_bytes[is_s.idx()][1] => value_rlp_bytes[is_s.idx()][3].expr() + 2.expr()); + // `c_main.rlp1` always needs to be RLP_LIST_LONG + 1. + require!(value_rlp_bytes[is_s.idx()][2] => RLP_LIST_LONG + 1); + // The length of the list is `#(nonce bytes) + #(balance bytes) + 2 * (1 + #(hash))`. + require!(value_rlp_bytes[is_s.idx()][3] => config.rlp_nonce[is_s.idx()].num_bytes() + config.rlp_balance[is_s.idx()].num_bytes() + (2 * (1 + 32)).expr()); + // Now check that the the key and value list length matches the account length. + // The RLP encoded string always has 2 RLP bytes (the s RLP bytes). + let value_list_num_bytes = value_rlp_bytes[is_s.idx()][1].expr() + 2.expr(); + // Account length needs to equal all key bytes and all values list bytes. + require!(config.rlp_key[is_s.idx()].num_bytes() => config.rlp_key[is_s.idx()].num_bytes_on_key_row() + value_list_num_bytes); + }} + // Key done, set the starting values KeyData::store( &mut cb.base, &ctx.memory[key_memory(is_s)], KeyData::default_values(), ); + // Store the new parent + ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [ + storage_rlc[is_s.idx()].expr(), + true.expr(), + false.expr(), + storage_rlc[is_s.idx()].expr(), + ], + ); + } - // Num bytes used in RLC - let num_bytes = rlp_key.num_bytes_on_key_row(); - // Update `mult_diff` - config.mult[is_s.idx()] = cb.base.query_cell(); - require!((FixedTableTag::RMult, num_bytes.expr(), config.mult[is_s.idx()].expr()) => @"fixed"); - // RLC bytes zero check - //cb.set_length(num_bytes.expr()); - - // The computed key RLC needs to be the same as the value in `address_rlc` - // column. Note that `key_rlc` is used in `account_leaf_key_in_added_branch` and - // in cases when there is a placeholder branch we have `key_rlc - - // address_rlc != 0` because `key_rlc` is computed for the branch - // that is parallel to the placeholder branch. - ifx! {not!(parent_data.is_placeholder), not!(a!(proof_type.is_non_existing_account_proof, offset)) => { - require!(key_rlc[is_s.idx()] => a!(address_rlc, offset)); - }} + // A drifted leaf appears only when there is a placeholder branch + ifx! {config.parent_data[true.idx()].is_placeholder.expr() + config.parent_data[false.idx()].is_placeholder.expr() => { + config.drifted_rlp_key = LeafKeyGadget::construct(&mut cb.base, &drifted_bytes); + + // TODO(Brecht): seems like we have to verify the RLP encoding because the key length can change + + // The key RLC of the drifted leaf needs to be the same as the key RLC of the leaf before + // the drift - the nibbles are the same in both cases, the difference is that before the + // drift some nibbles are stored in the leaf key, while after the drift these nibbles are used as + // position in a branch or/and nibbles of the extension node. + // We need the intermediate key RLC right before `drifted_index` is added to it. + let (key_rlc_prev, key_mult_prev, placeholder_nibble, placeholder_is_odd) = ifx!{config.parent_data[true.idx()].is_placeholder.expr() => { + ( + config.key_data[true.idx()].parent_rlc.expr(), + config.key_data[true.idx()].parent_mult.expr(), + config.key_data[true.idx()].placeholder_nibble.expr(), + config.key_data[true.idx()].placeholder_is_odd.expr(), + ) + } elsex { + ( + config.key_data[false.idx()].parent_rlc.expr(), + config.key_data[false.idx()].parent_mult.expr(), + config.key_data[false.idx()].placeholder_nibble.expr(), + config.key_data[false.idx()].placeholder_is_odd.expr(), + ) + }}; - // Account delete - // We need to make sure there is no leaf when account is deleted. Two possible - // cases: - // - 1. Account leaf is deleted and there is a nil object in - // branch. In this case we have a placeholder leaf. - // - 2. Account leaf is deleted from a branch with two leaves, the remaining - // leaf moves one level up and replaces the branch. In this case we - // have a branch placeholder. So we need to check there is a - // placeholder branch when we have the second case. Note: we do not - // need to cover the case when the (only) branch dissapears and only one - // leaf remains in the trie because there will always be at least two leaves - // (the genesis account) when account will be deleted, - // so there will always be a branch / extension node (and thus placeholder - // branch). - if !is_s { - // Note: this constraint suffices because the proper transition from branch to a - // leaf (2. case) are checked as well. - ifx! {a!(proof_type.is_account_delete_mod, offset) => { - let branch_contains_placeholder_leaf = if is_s { key_data.is_placeholder_leaf_s.expr() } else { key_data.is_placeholder_leaf_c.expr() }; - require!(or::expr([branch_contains_placeholder_leaf.expr(), parent_data.is_placeholder.expr()]) => true); - }} - } - - config.rlp_nonce[is_s.idx()] = RLPValueGadget::construct(&mut cb.base, &nonce_bytes[is_s.idx()][2..]); - config.rlp_balance[is_s.idx()] = RLPValueGadget::construct(&mut cb.base, &balance_bytes[is_s.idx()][2..]); - - offset += 1; - } + // Calculate the drifted key RLC + let drifted_key_rlc = key_rlc_prev + + drifted_nibble_rlc(&mut cb.base, placeholder_nibble.expr(), key_mult_prev.expr(), placeholder_is_odd.expr()) + + config.drifted_rlp_key.key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), false, &r); + // RLC bytes zero check + cb.set_length(config.drifted_rlp_key.num_bytes_on_key_row()); + config.drifted_mult = cb.base.query_cell(); + require!((FixedTableTag::RMult, config.drifted_rlp_key.num_bytes_on_key_row(), config.drifted_mult.expr()) => @"mult"); + + // Check that the drifted leaf is unchanged and is stored at `drifted_index`. + let calc_rlc = |is_s: bool| { + // Calculate the drifted leaf rlc + let rlc = (config.drifted_rlp_key.rlc(&r), config.drifted_mult.expr()).rlc_chain(leaf_no_key_rlc[is_s.idx()].expr()); + (true.expr(), key_rlc[is_s.idx()].expr(), rlc, config.parent_data[is_s.idx()].placeholder_rlc.expr()) + }; + let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { + config.parent_data[true.idx()].is_placeholder => { + // Neighbour leaf in the added branch + calc_rlc(true) + }, + config.parent_data[false.idx()].is_placeholder => { + // Neighbour leaf in the deleted branch + calc_rlc(false) + }, + _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), + }; + ifx! {do_checks => { + // The key of the drifted leaf needs to match the key of the leaf + require!(key_rlc => drifted_key_rlc); + // The drifted leaf needs to be stored in the branch at `drifted_index`. + // TODO(Brecht): re-enable after witness change + //require!((1, drifted_rlc, config.drifted_rlp_key.num_bytes(), mod_hash) => @"keccak"); + }} + }} // Wrong leaf - config.is_wrong_leaf = cb.base.query_cell(); // Make sure is_wrong_leaf is boolean require!(config.is_wrong_leaf => bool); ifx! {a!(ctx.proof_type.is_non_existing_account_proof, wrong_offset) => { @@ -285,8 +383,7 @@ impl AccountLeafConfig { // Make sure the lengths of the keys are the same require!(config.wrong_rlp_key.key_len() => config.rlp_key[true.idx()].key_len()); // RLC bytes zero check - let num_bytes = config.wrong_rlp_key.num_bytes_on_key_row(); - //cb.set_length(num_bytes); + cb.set_length(config.wrong_rlp_key.num_bytes_on_key_row()); } elsex { // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. require!(config.key_data_w.is_placeholder_leaf_s => true); @@ -296,331 +393,71 @@ impl AccountLeafConfig { require!(config.is_wrong_leaf => false); }} - let rot_key_s = offset - 2; - let rot_key_c = rot_key_s + 1; - let rot_nonce_s = rot_key_c + 2; - let rot_nonce_c = rot_nonce_s + 1; - let rot_storage_s = rot_nonce_c + 1; - let rot_storage_c = rot_storage_s + 1; - - offset += 1; - - ifx! {f!(ctx.position_cols.q_not_first) => { - // Nonce/balance - let mut nonce_rlc = vec![0.expr(); 2]; - let mut balance_rlc = vec![0.expr(); 2]; - for is_s in [true, false] { - let rot_key = offset - 3; - let rot_s = if is_s { offset } else { offset - 1 }; - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - - // The two string RLP bytes stored in the s RLP bytes. - // The two list RLP bytes are stored in the c RLP bytes. - // The RLP bytes of nonce/balance are stored bytes[0]. - - // RLC calculation for nonce/balance - let nonce = DataTransition::new_with_rot(meta, accs.s_mod_node_rlc, offset - 1, offset); - let balance = DataTransition::new_with_rot(meta, accs.c_mod_node_rlc, offset - 1, offset); - let mult_diff_nonce = a!(accs.acc_c.rlc, offset); - let mult_diff_balance = a!(accs.key.mult, offset); - let mut calc_rlc = |data: Expression, - is_long: Expression, - mult_diff: Expression, - mult_offset: u64, - is_s: bool| { - // The is_long selector needs to be boolean - require!(is_long => bool); - // Calculate the RLC - let (num_bytes, value_rlc) = ifx! {is_long => { - let num_bytes = get_num_bytes_short::expr(a!(ctx.main(is_s).bytes[0], offset)); - let value_rlc = ctx.main(is_s).bytes(meta, offset)[1..].to_vec().rlc(&r); - (num_bytes, value_rlc) - } elsex { - (1.expr(), a!(ctx.main(is_s).bytes[0], offset)) - }}; - require!(data => value_rlc); - // RLC bytes zero check (+2 because data starts at bytes[0]) - //cb.set_length_sc(is_s, 2.expr() + num_bytes.expr()); - // Get the correct multiplier for the length - require!((FixedTableTag::RMult, num_bytes.expr() + mult_offset.expr(), mult_diff) => @format!("fixed")); - - // Go from the value rlc to the data rlc - let rlc = account.to_data_rlc(meta, ctx.main(is_s), value_rlc, is_long, offset); - (rlc, num_bytes) - }; - //config.rlp_nonce[is_s.idx()] = RLPValueGadget::construct(&mut cb.base, &nonce_bytes[is_s.idx()][2..]); - //config.rlp_balance[is_s.idx()] = RLPValueGadget::construct(&mut cb.base, &balance_bytes[is_s.idx()][2..]); - - let nonce_num_bytes; - (nonce_rlc[is_s.idx()], nonce_num_bytes) = calc_rlc( - nonce.expr(), - account.is_nonce_long(), - mult_diff_nonce.expr(), - 4, - true, - ); - let balance_num_bytes; - (balance_rlc[is_s.idx()], balance_num_bytes) = calc_rlc( - balance.expr(), - account.is_balance_long(), - mult_diff_balance.expr(), - 0, - false, - ); + // Account delete + // We need to make sure there is no leaf when account is deleted. Two possible + // cases: + // - 1. Account leaf is deleted and there is a nil object in + // branch. In this case we have a placeholder leaf. + // - 2. Account leaf is deleted from a branch with two leaves, the remaining + // leaf moves one level up and replaces the branch. In this case we + // have a branch placeholder. So we need to check there is a + // placeholder branch when we have the second case. Note: we do not + // need to cover the case when the (only) branch dissapears and only one + // leaf remains in the trie because there will always be at least two leaves + // (the genesis account) when account will be deleted, + // so there will always be a branch / extension node (and thus placeholder + // branch). + // Note: this constraint suffices because the proper transition from branch to a + // leaf (2. case) are checked as well. + ifx! {a!(ctx.proof_type.is_account_delete_mod) => { + require!(or::expr([ + config.key_data[false.idx()].is_placeholder_leaf_c.expr(), + config.parent_data[false.idx()].is_placeholder.expr() + ]) => true); + }} - /*require!(config.rlp_nonce[is_s.idx()].is_long() => account.is_nonce_long()); - require!(config.rlp_balance[is_s.idx()].is_long() => account.is_balance_long()); - - let (nonce_value_rlc, nonce_leaf_rlc_value) = config.rlp_nonce[is_s.idx()].rlc(&r); - let (balance_value_rlc, balance_leaf_rlc_value) = config.rlp_balance[is_s.idx()].rlc(&r);*/ - - /*require!(nonce_value_rlc => nonce_rlc[is_s.idx()]); - require!(config.rlp_nonce[is_s.idx()].num_bytes() => nonce_num_bytes); - require!(balance_value_rlc => balance_rlc[is_s.idx()]); - require!(config.rlp_balance[is_s.idx()].num_bytes() => balance_num_bytes);*/ - - // Calculate and store the combined nonce + balance multipliers - let account_rlc = DataTransition::new_with_rot(meta, accs.acc_s.rlc, rot_key, offset); - let mult_prev = a!(accs.acc_s.mult, rot_key); - // Multipliers - let mult_after_nonce = a!(accs.acc_c.mult, offset); - let mult_diff_balance = a!(accs.key.mult, offset); - let acc_mult_final = a!(accs.acc_s.mult, offset); - require!(mult_after_nonce => mult_prev.expr() * mult_diff_nonce.expr()); - require!(acc_mult_final => mult_after_nonce.expr() * mult_diff_balance.expr()); - // Store the RLP bytes + nonce + balance RLC. - let rlc = account_rlc.prev() - + account.nonce_balance_rlc( - meta, - nonce_rlc[is_s.idx()].expr(), - balance_rlc[is_s.idx()].expr(), - mult_prev.expr(), - mult_diff_nonce.expr(), - offset, - ); - require!(account_rlc => rlc); - - // Check the RLP encoding consistency. - // RlP encoding: account = [key, [nonce, balance, storage, codehash]] - // The only exception is when `is_non_existing_account_proof = 1` & - // `is_wrong_leaf = 0`. In this case the value does not matter as - // the account leaf is only a placeholder and does not use - // `s_main.rlp1` and `s_main.rlp2`. - // TODO(Brecht): Can we remove this if by just making this pass in this special - // case? - ifx! {not!(and::expr(&[a!(proof_type.is_non_existing_account_proof, offset), not!(account.is_wrong_leaf(meta, is_s))])) => { - // We always store between 55 and 256 bytes of data in the values list. - require!(a!(s_main.rlp1, offset) => RLP_LONG + 1); - // The RLP encoded list always has 2 RLP bytes (the c RLP bytes). - require!(a!(s_main.rlp2, offset) => a!(c_main.rlp2, offset) + 2.expr()); - // `c_main.rlp1` always needs to be RLP_LIST_LONG + 1. - require!(a!(c_main.rlp1, offset) => RLP_LIST_LONG + 1); - // The length of the list is `#(nonce bytes) + #(balance bytes) + 2 * (1 + #(hash))`. - require!(a!(c_main.rlp2, offset) => nonce_num_bytes.expr() + balance_num_bytes.expr() + (2 * (1 + 32)).expr()); - // Now check that the the key and value list length matches the account length. - let len = account.num_bytes(meta); - let key_num_bytes = account.num_bytes_on_key_row(meta); - // The RLP encoded string always has 2 RLP bytes (the s RLP bytes). - let value_list_num_bytes = a!(s_main.rlp2, offset) + 2.expr(); - // Account length needs to equal all key bytes and all values list bytes. - require!(len => key_num_bytes + value_list_num_bytes); - }} - - // To enable lookups we need to have the previous/current nonce/balance on the - // same row - if !is_s { - require!(a!(value_prev, rot_s) => nonce.prev()); - require!(a!(value, rot_s) => nonce); - require!(a!(value_prev, offset) => balance.prev()); - require!(a!(value, offset) => balance); - } - - // Check that there is only one modification. - if !is_s { - // Note: For `is_non_existing_account_proof` we do not need this constraint, - // `S` and `C` proofs are the same and we need to do a lookup into only one - // (the other one could really be whatever). - ifx! {not!(a!(proof_type.is_account_delete_mod, offset)) => { - // Nonce needs to remain the same when not modifying the nonce - ifx!{not!(a!(proof_type.is_nonce_mod, offset)) => { - require!(nonce => nonce.prev()); - }} - // Balance needs to remain the same when not modifying the balance - ifx!{not!(a!(proof_type.is_balance_mod, offset)) => { - require!(balance => balance.prev()); - }} - }} - } - - offset += 1; - } - - for is_s in [true, false] { - let rot_key = offset - 5; - let rot_nonce_balance = offset - 2; - let rot_s = if is_s { offset } else { offset - 1 }; - // rlp1 is not used, rlp2 is used to store the first RLP byte. - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - - // When non_existing_account_proof and not wrong leaf there is only a placeholder account leaf - // and the constraints in this gate are not triggered. In that case it is checked - // that there is nil in the parent branch at the proper position (see `account_non_existing.rs`), note - // that we need (placeholder) account leaf for lookups and to know when to check that parent branch - // has a nil. - // TODO(Brecht): Can we remove this if by just making this pass in this special case? - ifx! {not!(and::expr(&[a!(proof_type.is_non_existing_account_proof, offset), not!(account.is_wrong_leaf(meta, is_s))])) => { - // Storage root and codehash are always 32-byte hashes. - require!(a!(s_main.rlp2, offset) => RLP_HASH_VALUE); - require!(a!(c_main.rlp2, offset) => RLP_HASH_VALUE); - }} - - // RLC calculation - let account_rlc = DataTransition::new_with_rot(meta, accs.acc_s.rlc, rot_nonce_balance, offset); - let mult_prev = a!(accs.acc_s.mult, rot_nonce_balance); - // - Storage root - let storage_root = DataTransition::new_with_rot(meta, accs.s_mod_node_rlc, offset - 1, offset); - require!(storage_root => s_main.bytes(meta, offset).rlc(&r)); - // - Codehash - let codehash = DataTransition::new_with_rot(meta, accs.c_mod_node_rlc, offset - 1, offset); - require!(codehash => c_main.bytes(meta, offset).rlc(&r)); - // The full account leaf RLC - let rlc = account_rlc.prev() + account.storage_codehash_rlc(meta, storage_root.expr(), codehash.expr(), mult_prev.expr(), offset); - require!(account_rlc => rlc); - - // Parent data - let parent_data = &mut config.parent_data[is_s.idx()]; - // Check if the account is in its parent. - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - // Check is skipped for placeholder leafs which are dummy leafs - ifx!{not!(and::expr(&[a!(ctx.position_cols.not_first_level, offset), not!(branch.is_placeholder()), branch.contains_placeholder_leaf(meta, is_s)])) => { - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - require!((1, account_rlc, account.num_bytes(meta), parent_data.rlc) => @"keccak"); - }} - // Store the new parent - ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [storage_root.expr(), true.expr(), false.expr(), storage_root.expr()]); - - if !is_s { - // To enable lookups we need to have the previous/current storage root/code hash on the same row. - require!(a!(value_prev, rot_s) => storage_root.prev()); - require!(a!(value, rot_s) => storage_root); - require!(a!(value_prev, offset) => codehash.prev()); - require!(a!(value, offset) => codehash); - - // Check that there is only one modification (except when the account is being deleted). - ifx!{not!(a!(proof_type.is_account_delete_mod, offset)) => { - // Storage root needs to remain the same when not modifying the storage root - ifx!{not!(a!(proof_type.is_storage_mod, offset)) => { - require!(storage_root => storage_root.prev()); - }} - // Codehash root needs to remain the same when not modifying the codehash - ifx!{not!(a!(proof_type.is_codehash_mod, offset)) => { - require!(codehash => codehash.prev()); - }} - }} - } - - offset += 1; - } - - ifx! {a!(ctx.position_cols.not_first_level) => { - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - let drifted_account = AccountLeafInfo::new(meta, ctx.clone(), offset); - - // A drifted leaf appears only when there is a placeholder branch - ifx! {branch.is_placeholder_s_or_c() => { - // Calculate and store the leaf RLC (RLP + key) - let drifted_rlc = a!(accs.acc_s.rlc, offset); - require!(drifted_rlc => ctx.rlc(meta, 0..36, offset)); - - // `s_rlp1` is always RLP_LIST_LONG + 1 because the account leaf is always > 55 bytes (and < 256) - require!(a!(s_main.rlp1, offset) => RLP_LIST_LONG + 1); - - // The key RLC of the drifted leaf needs to be the same as the key RLC of the leaf before - // the drift - the nibbles are the same in both cases, the difference is that before the - // drift some nibbles are stored in the leaf key, while after the drift these nibbles are used as - // position in a branch or/and nibbles of the extension node. - let is_branch_in_first_level = not!(a!(not_first_level, rot_branch_init)); - let (key_rlc_prev, key_mult_prev) = get_parent_rlc_state(meta, ctx.clone(), is_branch_in_first_level, rot_parent); - - // Load the last key values - config.key_data_d = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 2.expr()); - - // TODO(Brecht): make this work with loaded key data when extension node is separate - ifx! {not!(branch.is_extension()) => { - require!(config.key_data_d.rlc => key_rlc_prev); - require!(config.key_data_d.mult => key_mult_prev); - }} - - // Calculate the drifted key RLC - let drifted_key_rlc = key_rlc_prev + - branch.drifted_nibble_rlc(meta, &mut cb.base, key_mult_prev.expr()) + - drifted_account.key_rlc(meta, &mut cb.base, key_mult_prev.expr(), branch.is_key_odd(), r[0].expr(), 0); - - // RLC bytes zero check - let num_bytes = drifted_account.num_bytes_on_key_row(meta); - cb.set_length(num_bytes.expr()); - // Update `mult_diff` - let mult = a!(accs.acc_s.mult, offset); - require!((FixedTableTag::RMult, num_bytes.expr(), mult) => @"mult"); - - // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let calc_rlc = |is_s, meta: &mut VirtualCells<'_, F>, cb: &mut ConstraintBuilder| { - circuit!([meta, cb], { - let rot_key = if is_s { rot_key_s } else { rot_key_c }; - let rot_nonce = if is_s { rot_nonce_s } else { rot_nonce_c }; - let rot_storage = if is_s { rot_storage_s } else { rot_storage_c }; - - let account = AccountLeafInfo::new(meta, ctx.clone(), rot_key); - - // Calculate the drifted leaf rlc - // Nonce data rlc - let nonce_stored = a!(accs.s_mod_node_rlc, rot_nonce); - let nonce_rlc = account.to_data_rlc(meta, ctx.s_main, nonce_stored, account.is_nonce_long(), rot_nonce); - // Balance data rlc - let balance_stored = a!(accs.c_mod_node_rlc, rot_nonce); - let balance_rlc = account.to_data_rlc(meta, ctx.c_main, balance_stored, account.is_balance_long(), rot_nonce); - let mult_nonce = a!(accs.acc_c.rlc, rot_nonce); - let mult_balance = a!(accs.key.mult, rot_nonce); - let rlc = drifted_rlc.expr() + account.nonce_balance_rlc(meta, nonce_rlc.expr(), balance_rlc.expr(), mult.expr(), mult_nonce.expr(), rot_nonce); - // Add storage/codehash rlc - let storage_rlc = a!(accs.s_mod_node_rlc, rot_storage); - let codehash_rlc = a!(accs.c_mod_node_rlc, rot_storage); - let mult_prev = mult.expr() * mult_nonce.expr() * mult_balance.expr(); - let rlc = rlc + account.storage_codehash_rlc(meta, storage_rlc.expr(), codehash_rlc.expr(), mult_prev.expr(), rot_storage); - - (true.expr(), key_rlc[is_s.idx()].expr(), rlc, a!(accs.mod_node_rlc(is_s), rot_first_child)) - }) - }; - let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { - branch.is_placeholder_s() => { - // Neighbour leaf in the added branch - // - `leaf_key_s_rlc` is the key RLC of the leaf before it drifted down - // in a new branch. - // - `s_mod_node_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `c_mod_node_rlc` in the added branch stores the hash of - // `modified_index` (the leaf that has been added). - calc_rlc(true, meta, &mut cb.base) - }, - branch.is_placeholder_c() => { - // Neighbour leaf in the deleted branch - // -`leaf_key_c_rlc` is the key RLC of the leaf after its neighbour leaf - // has been deleted (and there were only two leaves, so the branch was deleted). - // - `c_mod_node_hash_rlc` in the placeholder branch stores the hash of a neighbour leaf. - // This is because `s_mod_node_rlc` in the deleted branch stores the hash of - // `modified_index` (the leaf that is to be deleted). - calc_rlc(false, meta, &mut cb.base) - }, - _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), - }; - ifx! {do_checks => { - // The key of the drifted leaf needs to match the key of the leaf - require!(key_rlc => drifted_key_rlc); - // The drifted leaf needs to be stored in the branch at `drifted_index`. - require!((1, drifted_rlc, drifted_account.num_bytes(meta), mod_hash) => @"keccak"); - }} - }} + // Check that there is only one modification (except when the account is being + // deleted). + ifx! {not!(a!(ctx.proof_type.is_account_delete_mod)) => { + // Nonce needs to remain the same when not modifying the nonce + ifx!{not!(a!(proof_type.is_nonce_mod, nonce_lookup_offset)) => { + require!(nonce_rlc[false.idx()] => nonce_rlc[true.idx()]); + }} + // Balance needs to remain the same when not modifying the balance + ifx!{not!(a!(proof_type.is_balance_mod, balance_lookup_offset)) => { + require!(balance_rlc[false.idx()] => balance_rlc[true.idx()]); + }} + // Storage root needs to remain the same when not modifying the storage root + ifx!{not!(a!(proof_type.is_storage_mod, storage_lookup_offset)) => { + require!(storage_rlc[false.idx()] => storage_rlc[true.idx()]); + }} + // Codehash root needs to remain the same when not modifying the codehash + ifx!{not!(a!(proof_type.is_codehash_mod, codehash_lookup_offset)) => { + require!(codehash_rlc[false.idx()] => codehash_rlc[true.idx()]); }} }} + + for is_s in [true, false] { + // The computed key RLC needs to be the same as the value in `address_rlc` + // column. Note that `key_rlc` is used in `account_leaf_key_in_added_branch` and + // in cases when there is a placeholder branch we have `key_rlc - + // address_rlc != 0` because `key_rlc` is computed for the branch + // that is parallel to the placeholder branch. + ifx! {not!(config.parent_data[is_s.idx()].is_placeholder), not!(a!(ctx.proof_type.is_non_existing_account_proof)) => { + require!(a!(ctx.mpt_table.address_rlc) => key_rlc[is_s.idx()]); + }} + } + + // Lookup data + // TODO(Brecht): check key_rlc? + require!(a!(ctx.mpt_table.value_prev, nonce_lookup_offset) => nonce_rlc[true.idx()]); + require!(a!(ctx.mpt_table.value, nonce_lookup_offset) => nonce_rlc[false.idx()]); + require!(a!(ctx.mpt_table.value_prev, balance_lookup_offset) => balance_rlc[true.idx()]); + require!(a!(ctx.mpt_table.value, balance_lookup_offset) => balance_rlc[false.idx()]); + require!(a!(ctx.mpt_table.value_prev, storage_lookup_offset) => storage_rlc[true.idx()]); + require!(a!(ctx.mpt_table.value, storage_lookup_offset) => storage_rlc[false.idx()]); + require!(a!(ctx.mpt_table.value_prev, codehash_lookup_offset) => codehash_rlc[true.idx()]); + require!(a!(ctx.mpt_table.value, codehash_lookup_offset) => codehash_rlc[false.idx()]); }); config @@ -630,56 +467,138 @@ impl AccountLeafConfig { &self, region: &mut Region<'_, F>, ctx: &MPTConfig, - witness: &[MptWitnessRow], + witness: &mut [MptWitnessRow], pv: &mut ProofValues, offset: usize, ) -> Result<(), Error> { let base_offset = offset; - let mut offset = offset - 1; - - let key_bytes = [&witness[base_offset - 1], &witness[base_offset + 0]]; - let wrong_bytes = &witness[base_offset + 1]; - let nonce_bytes = [&witness[base_offset + 2].bytes[..34].to_owned(), &witness[base_offset + 3].bytes[..34].to_owned()]; - let balance_bytes = [&witness[base_offset + 2].bytes[34..].to_owned(), &witness[base_offset + 3].bytes[34..].to_owned()]; - //let value_bytes = [&witness[offset + 1], &witness[offset + 3]]; - //let drifted_bytes = &witness[offset + 4]; - //let lookup_offset = offset + 3; + + let key_s = witness[base_offset - 1].to_owned(); + let key_c = witness[base_offset].to_owned(); + let nonce_balance_s = witness[base_offset + 2].to_owned(); + let nonce_balance_c = witness[base_offset + 3].to_owned(); + let storage_codehash_s = witness[base_offset + 4].to_owned(); + let storage_codehash_c = witness[base_offset + 5].to_owned(); + + let key_bytes = [key_s.to_owned(), key_c.to_owned()]; + let wrong_bytes = witness[base_offset + 1].to_owned(); + let nonce_bytes = [ + nonce_balance_s.bytes[..34].to_owned(), + nonce_balance_c.bytes[..34].to_owned(), + ]; + let balance_bytes = [ + nonce_balance_s.bytes[34..68].to_owned(), + nonce_balance_c.bytes[34..68].to_owned(), + ]; + let storage_bytes = [ + storage_codehash_s.bytes[..34].to_owned(), + storage_codehash_c.bytes[..34].to_owned(), + ]; + let codehash_bytes = [ + storage_codehash_s.bytes[34..68].to_owned(), + storage_codehash_c.bytes[34..68].to_owned(), + ]; + //let drifted_bytes = witness[base_offset + 6].to_owned(); + + let key_s_lookup_offset = base_offset - 1; + let nonce_lookup_offset = base_offset + 2; + let balance_lookup_offset = base_offset + 3; + let storage_lookup_offset = base_offset + 4; + let codehash_lookup_offset = base_offset + 5; let wrong_offset = base_offset + 1; // Key let mut key_rlc = vec![0.scalar(); 2]; + let mut nonce_value_rlc = vec![0.scalar(); 2]; + let mut balance_value_rlc = vec![0.scalar(); 2]; + let mut storage_value_rlc = vec![0.scalar(); 2]; + let mut codehash_value_rlc = vec![0.scalar(); 2]; for is_s in [true, false] { - let key_row = key_bytes[is_s.idx()]; - - //let key_row = &key_bytes[is_s.idx()]; - - let rlp_key_witness = self.rlp_key[is_s.idx()] - .assign(region, base_offset, &key_row.bytes) - .ok() - .unwrap(); - - // account leaf key S & C - let mut acc = F::zero(); - let mut acc_mult = F::one(); - // 35 = 2 (leaf rlp) + 1 (key rlp) + key_len - let key_len = (key_row.get_byte(2) - 128) as usize; - for b in key_row.bytes.iter().take(3 + key_len) { - acc += F::from(*b as u64) * acc_mult; - acc_mult *= ctx.randomness; + let key_row = &key_bytes[is_s.idx()]; + + self.key_data[is_s.idx()].witness_load( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + 0, + )?; + + let parent_values = self.parent_data[is_s.idx()].witness_load( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + 0, + )?; + + self.is_empty_trie[is_s.idx()].assign( + region, + base_offset, + parent_values[0], + ctx.randomness, + )?; + + let rlp_key_witness = + self.rlp_key[is_s.idx()].assign(region, base_offset, &key_row.bytes)?; + let nonce_witness = self.rlp_nonce[is_s.idx()].assign( + region, + base_offset, + &nonce_bytes[is_s.idx()][2..], + )?; + let balance_witness = self.rlp_balance[is_s.idx()].assign( + region, + base_offset, + &balance_bytes[is_s.idx()][2..], + )?; + let storage_witness = self.rlp_storage[is_s.idx()].assign( + region, + base_offset, + &storage_bytes[is_s.idx()][1..], + )?; + let codehash_witness = self.rlp_codehash[is_s.idx()].assign( + region, + base_offset, + &codehash_bytes[is_s.idx()][1..], + )?; + + nonce_value_rlc[is_s.idx()] = nonce_witness.rlc_value(ctx.randomness); + balance_value_rlc[is_s.idx()] = balance_witness.rlc_value(ctx.randomness); + storage_value_rlc[is_s.idx()] = storage_witness.rlc_value(ctx.randomness); + codehash_value_rlc[is_s.idx()] = codehash_witness.rlc_value(ctx.randomness); + + // + 4 because of s_rlp1, s_rlp2, c_rlp1, c_rlp2 + let mut mult_nonce = F::one(); + for _ in 0..nonce_witness.num_bytes() + 4 { + mult_nonce *= ctx.randomness; } + let mut mult_balance = F::one(); + for _ in 0..balance_witness.num_bytes() { + mult_balance *= ctx.randomness; + } + self.nonce_mult[is_s.idx()].assign(region, base_offset, mult_nonce)?; + self.balance_mult[is_s.idx()].assign(region, base_offset, mult_balance)?; - if key_row.get_type() == MptWitnessRowType::AccountLeafKeyS { - pv.acc_account_s = acc; - pv.acc_mult_account_s = acc_mult; - if key_row.get_byte_rev(IS_ACCOUNT_DELETE_MOD_POS) == 1 { - assign!(region, (ctx.proof_type.proof_type, offset) => ProofType::AccountDoesNotExist.scalar()).ok(); - } + // Key + // For leaf S and leaf C we need to start with the same rlc. + let is_branch_placeholder = if is_s { + pv.is_branch_s_placeholder } else { - pv.acc_account_c = acc; - pv.acc_mult_account_c = acc_mult; + pv.is_branch_c_placeholder + }; + let (key_rlc_new, key_rlc_mult) = if is_branch_placeholder { + (pv.key_rlc_prev, pv.key_rlc_mult_prev) + } else { + (pv.key_rlc, pv.key_rlc_mult) + }; + (key_rlc[is_s.idx()], _) = + rlp_key_witness.key_rlc(key_rlc_new, key_rlc_mult, ctx.randomness); + + let mut key_mult = F::one(); + for _ in 0..rlp_key_witness.num_bytes_on_key_row() { + key_mult *= ctx.randomness; } + self.key_mult[is_s.idx()].assign(region, base_offset, key_mult)?; - self.key_data[is_s.idx()].witness_load(region, base_offset, &mut pv.memory[key_memory(is_s)], 0)?; + // Update key and parent state self.key_data[is_s.idx()].witness_store( region, base_offset, @@ -694,562 +613,99 @@ impl AccountLeafConfig { F::zero(), F::one(), )?; - - // For leaf S and leaf C we need to start with the same rlc. - let mut key_rlc_new = pv.key_rlc; - let mut key_rlc_mult_new = pv.key_rlc_mult; - if (pv.is_branch_s_placeholder && key_row.get_type() == MptWitnessRowType::AccountLeafKeyS) - || (pv.is_branch_c_placeholder - && key_row.get_type() == MptWitnessRowType::AccountLeafKeyC) - { - key_rlc_new = pv.key_rlc_prev; - key_rlc_mult_new = pv.key_rlc_mult_prev; - } - - ctx.compute_key_rlc( - &key_row.bytes, - &mut key_rlc_new, - &mut key_rlc_mult_new, - S_START, - ); - pv.account_key_rlc = key_rlc_new; - region.assign_advice( - || "assign key_rlc".to_string(), - ctx.accumulators.key.rlc, - offset, - || Value::known(key_rlc_new), + self.parent_data[is_s.idx()].witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + storage_value_rlc[is_s.idx()], + true, + false, + storage_value_rlc[is_s.idx()], )?; + } - ctx - .assign_acc(region, acc, acc_mult, F::zero(), F::zero(), offset) - .ok(); + // Drifted leaf handling + if pv.is_branch_s_placeholder || pv.is_branch_c_placeholder { + // TODO(Brecht): Change how the witness is generated + let drifted_bytes = &mut witness[base_offset + 6].bytes; + let key_bytes = if pv.is_branch_s_placeholder { + &key_bytes[true.idx()] + } else { + &key_bytes[false.idx()] + }; + drifted_bytes[0] = key_bytes.bytes[0]; + drifted_bytes[1] = key_bytes.bytes[1]; + drifted_bytes[2] = key_bytes.bytes[2]; - self.mult[is_s.idx()] - .assign(region, base_offset, acc_mult) - .ok(); + let drifted_key_witness = + self.drifted_rlp_key + .assign(region, base_offset, &drifted_bytes)?; - key_rlc[is_s.idx()] = key_rlc_new; - offset += 1; + let (_, leaf_mult) = drifted_key_witness.rlc_leaf(ctx.randomness); + + self.drifted_mult.assign(region, base_offset, leaf_mult)?; } // Non-existing - { - let row = wrong_bytes; - - self.key_data_w - .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) - .ok(); + let row = wrong_bytes; + if row.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1 { + self.key_data_w.witness_load( + region, + base_offset, + &mut pv.memory[key_memory(true)], + 1, + )?; // TODO(Brecht): Change how the witness is generated let is_wrong = row.bytes[0] != 0; self.is_wrong_leaf - .assign(region, base_offset, F::from(is_wrong)) - .ok(); + .assign(region, base_offset, F::from(is_wrong))?; let mut row_bytes = row.bytes.clone(); row_bytes[0] = key_bytes[true.idx()].bytes[0]; - let wrong_witness = self - .wrong_rlp_key - .assign(region, base_offset, &row_bytes) - .ok() - .unwrap(); + let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes)?; + let (key_rlc_wrong, _) = + wrong_witness.key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.randomness); let address_rlc = bytes_into_rlc(row.address_bytes(), ctx.randomness); - self.check_is_wrong_leaf - .assign(region, base_offset, address_rlc - key_rlc[true.idx()]) - .ok(); + self.check_is_wrong_leaf.assign( + region, + base_offset, + address_rlc - key_rlc[true.idx()], + )?; - if row.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1 { - assign!(region, (ctx.proof_type.proof_type, offset) => ProofType::AccountDestructed.scalar()).ok(); - } + assign!(region, (ctx.mpt_table.key_rlc, wrong_offset) => key_rlc_wrong)?; + assign!(region, (ctx.proof_type.proof_type, wrong_offset) => ProofType::AccountDestructed.scalar())?; } - offset += 1; - - /* NONCE/BALANCE */ - - for is_s in [true, false] { - let value_row = &witness[offset]; - - let nonce_witness = self.rlp_nonce[is_s.idx()] - .assign(region, base_offset, &nonce_bytes[is_s.idx()][2..]) - .ok() - .unwrap(); - - let balance_witness = self.rlp_balance[is_s.idx()] - .assign(region, base_offset, &balance_bytes[is_s.idx()][2..]) - .ok() - .unwrap(); - - let mut nonce_len: usize = 1; - // Note: when nonce or balance is 0, the actual value stored in RLP encoding is - // 128. - if value_row.get_byte(S_START) > 128 { - nonce_len = value_row.get_byte(S_START) as usize - 128 + 1; // +1 for byte with length info - region - .assign_advice( - || "assign sel1".to_string(), - ctx.denoter.sel1, - offset - - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, - || Value::known(F::one()), - ) - .ok(); - } else { - region - .assign_advice( - || "assign sel1".to_string(), - ctx.denoter.sel1, - offset - - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, - || Value::known(F::zero()), - ) - .ok(); - } - - let mut balance_len: usize = 1; - if value_row.get_byte(C_START) > 128 { - balance_len = value_row.get_byte(C_START) as usize - 128 + 1; // +1 for byte with length info - region - .assign_advice( - || "assign sel2".to_string(), - ctx.denoter.sel2, - offset - - (ACCOUNT_LEAF_NONCE_BALANCE_S_IND - ACCOUNT_LEAF_KEY_S_IND) as usize, - || Value::known(F::one()), - ) - .ok(); - } else { - region - .assign_advice( - || "assign sel2".to_string(), - ctx.denoter.sel2, - offset - - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_KEY_C_IND) as usize, - || Value::known(F::zero()), - ) - .ok(); - } - - // nonce value RLC and balance value RLC: - pv.rlc1 = F::zero(); - pv.rlc2 = F::zero(); - // Note: Below, it first computes and assigns the nonce RLC and balance RLC - // without RLP specific byte (there is a RLP specific byte when - // nonce/balance RLP length > 1). - if nonce_len == 1 && balance_len == 1 { - ctx - .compute_rlc_and_assign( - region, - &value_row.bytes, - pv, - offset, - (S_START, HASH_WIDTH), - (C_START, HASH_WIDTH), - ) - .ok(); - } else if nonce_len > 1 && balance_len == 1 { - ctx - .compute_rlc_and_assign( - region, - &value_row.bytes, - pv, - offset, - (S_START + 1, HASH_WIDTH - 1), - (C_START, HASH_WIDTH), - ) - .ok(); - } else if nonce_len == 1 && balance_len > 1 { - ctx - .compute_rlc_and_assign( - region, - &value_row.bytes, - pv, - offset, - (S_START, HASH_WIDTH), - (C_START + 1, HASH_WIDTH - 1), - ) - .ok(); - } else if nonce_len > 1 && balance_len > 1 { - ctx - .compute_rlc_and_assign( - region, - &value_row.bytes, - pv, - offset, - (S_START + 1, HASH_WIDTH - 1), - (C_START + 1, HASH_WIDTH - 1), - ) - .ok(); - } - - let mut acc_account; - let mut acc_mult_account; - if value_row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { - pv.nonce_value_s = pv.rlc1; - pv.balance_value_s = pv.rlc2; - - acc_account = pv.acc_account_s; - acc_mult_account = pv.acc_mult_account_s; - - if value_row.get_byte_rev(IS_NONCE_MOD_POS) == 1 { - region - .assign_advice( - || "assign which lookup type enabled".to_string(), - ctx.proof_type.proof_type, - offset, - || Value::known(F::from(1_u64)), - ) - .ok(); - } - } else { - acc_account = pv.acc_account_c; - acc_mult_account = pv.acc_mult_account_c; - - let nonce_value_c = pv.rlc1; - let balance_value_c = pv.rlc2; - - if value_row.get_byte_rev(IS_BALANCE_MOD_POS) == 1 { - region - .assign_advice( - || "assign which lookup type enabled".to_string(), - ctx.proof_type.proof_type, - offset, - || Value::known(F::from(2_u64)), - ) - .ok(); - } - - let offset_s = offset - - (ACCOUNT_LEAF_NONCE_BALANCE_C_IND - ACCOUNT_LEAF_NONCE_BALANCE_S_IND) - as usize; - - // assign nonce S RLC in ACCOUNT_LEAF_NONCE_BALANCE_S row. - region - .assign_advice( - || "assign nonce S".to_string(), - ctx.value_prev, - offset_s, - || Value::known(pv.nonce_value_s), - ) - .ok(); - - // Assign nonce C RLC in ACCOUNT_LEAF_NONCE_BALANCE_S row. - region - .assign_advice( - || "assign nonce C".to_string(), - ctx.value, - offset_s, - || Value::known(nonce_value_c), - ) - .ok(); - - // assign balance S RLC in ACCOUNT_LEAF_NONCE_BALANCE_C row. - region - .assign_advice( - || "assign value_prev".to_string(), - ctx.value_prev, - offset, - || Value::known(pv.balance_value_s), - ) - .ok(); - - // Assign balance C RLC in ACCOUNT_LEAF_NONCE_BALANCE_C row. - region - .assign_advice( - || "assign balance C".to_string(), - ctx.value, - offset, - || Value::known(balance_value_c), - ) - .ok(); - } - - // s_rlp1, s_rlp2 - ctx.compute_acc_and_mult( - &value_row.bytes, - &mut acc_account, - &mut acc_mult_account, - S_START - 2, - 2, - ); - // c_rlp1, c_rlp2 - ctx.compute_acc_and_mult( - &value_row.bytes, - &mut acc_account, - &mut acc_mult_account, - C_START - 2, - 2, - ); - // nonce contribution to leaf RLC: - /* - If nonce stream length is 1, it doesn't have - the first byte with length info. Same for balance. - There are four possibilities: - - nonce is short (length 1), balance is short (length 1) - - nonce is short, balance is long - - nonce is long, balance is short - - nonce is long, balance is long - We put this info in sel1/sel2 in the key row (sel1/sel2 are - already used for other purposes in nonce balance row): - - sel1/sel2: 0/0 (how to check: (1-sel1)*(1-sel2)) - - sel1/sel2: 0/1 (how to check: (1-sel1)*sel2) - - sel1/sel2: 1/0 (how to check: sel1*(1-sel2)) - - sel1/sel2: 1/1 (how to check: sel1*sel2) - */ - - ctx.compute_acc_and_mult( - &value_row.bytes, - &mut acc_account, - &mut acc_mult_account, - S_START, - nonce_len, - ); - - let mut mult_diff_s = F::one(); - for _ in 0..nonce_len + 4 { - // + 4 because of s_rlp1, s_rlp2, c_rlp1, c_rlp2 - mult_diff_s *= ctx.randomness; - } - - // It's easier to constrain (in account_leaf_nonce_balance.rs) - // the multiplier if we store acc_mult both after nonce and after - // balance. - let acc_mult_tmp = acc_mult_account; - - // balance contribution to leaf RLC - ctx.compute_acc_and_mult( - &value_row.bytes, - &mut acc_account, - &mut acc_mult_account, - C_START, - balance_len, - ); - - let mut mult_diff_c = F::one(); - for _ in 0..balance_len { - mult_diff_c *= ctx.randomness; - } - - ctx - .assign_acc( - region, - acc_account, - acc_mult_account, - F::zero(), - acc_mult_tmp, - offset, - ) - .ok(); - - region - .assign_advice( - || "assign mult diff".to_string(), - ctx.accumulators.acc_c.rlc, /* assigning key_rlc leads into - * PoisonedConstraint */ - offset, - || Value::known(mult_diff_s), - ) - .ok(); - region - .assign_advice( - || "assign mult diff".to_string(), - ctx.accumulators.key.mult, - offset, - || Value::known(mult_diff_c), - ) - .ok(); - if value_row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { - pv.acc_nonce_balance_s = acc_account; - pv.acc_mult_nonce_balance_s = acc_mult_account; - } else { - pv.acc_nonce_balance_c = acc_account; - pv.acc_mult_nonce_balance_c = acc_mult_account; - } - - offset += 1; + // Lookup data + if key_s.get_byte_rev(IS_ACCOUNT_DELETE_MOD_POS) == 1 { + assign!(region, (ctx.proof_type.proof_type, key_s_lookup_offset) => ProofType::AccountDoesNotExist.scalar())?; } - /* STORAGE/CODEHASH */ - - for is_s in [true, false] { - let row = &witness[offset]; - - if is_s { - pv.acc_s = pv.acc_nonce_balance_s; - pv.acc_mult_s = pv.acc_mult_nonce_balance_s; - - // storage root RLC and code hash RLC - pv.rlc1 = F::zero(); - pv.rlc2 = F::zero(); - ctx - .compute_rlc_and_assign( - region, - &row.bytes, - pv, - offset, - (S_START, HASH_WIDTH), - (C_START, HASH_WIDTH), - ) - .ok(); - pv.storage_root_value_s = pv.rlc1; - pv.codehash_value_s = pv.rlc2; - } else { - pv.acc_s = pv.acc_nonce_balance_c; - pv.acc_mult_s = pv.acc_mult_nonce_balance_c; - - // assign storage root RLC and code hash RLC for this row - pv.rlc1 = F::zero(); - pv.rlc2 = F::zero(); - ctx - .compute_rlc_and_assign( - region, - &row.bytes, - pv, - offset, - (S_START, HASH_WIDTH), - (C_START, HASH_WIDTH), - ) - .ok(); - - let storage_root_value_c = pv.rlc1; - let codehash_value_c = pv.rlc2; - - pv.storage_root_value_c = storage_root_value_c; - - if row.get_byte_rev(IS_CODEHASH_MOD_POS) == 1 { - region - .assign_advice( - || "assign lookup enabled".to_string(), - ctx.proof_type.proof_type, - offset, - || Value::known(F::from(3_u64)), /* codehash mod lookup enabled in - * this row if it is - * is_codehash_mod proof */ - ) - .ok(); - } - - let offset_s = offset - - (ACCOUNT_LEAF_STORAGE_CODEHASH_C_IND - ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND) - as usize; - - // Assign storage root S - region - .assign_advice( - || "assign storage root S".to_string(), - ctx.value_prev, - offset_s, - || Value::known(pv.storage_root_value_s), - ) - .ok(); - - // Assign storage root C - region - .assign_advice( - || "assign code hash C".to_string(), - ctx.value, - offset_s, - || Value::known(storage_root_value_c), - ) - .ok(); - - // Assign code hash S - region - .assign_advice( - || "assign code hash S".to_string(), - ctx.value_prev, - offset, - || Value::known(pv.codehash_value_s), - ) - .ok(); - - // Assign code hash C - region - .assign_advice( - || "assign code hash C".to_string(), - ctx.value, - offset, - || Value::known(codehash_value_c), - ) - .ok(); - } + if nonce_balance_s.get_byte_rev(IS_NONCE_MOD_POS) == 1 { + assign!(region, (ctx.proof_type.proof_type, nonce_lookup_offset) => ProofType::NonceChanged.scalar())?; + } + //assign!(region, (ctx.mpt_table.key_rlc, nonce_lookup_offset) => + // key_rlc[false.idx()])?; + assign!(region, (ctx.mpt_table.value_prev, nonce_lookup_offset) => nonce_value_rlc[true.idx()])?; + assign!(region, (ctx.mpt_table.value, nonce_lookup_offset) => nonce_value_rlc[false.idx()])?; - let storage_root = if is_s { - pv.storage_root_value_s - } else { - pv.storage_root_value_c - }; - self.parent_data[is_s.idx()] - .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) - .ok(); - self.parent_data[is_s.idx()] - .witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(is_s)], - storage_root, - true, - false, - storage_root, - ) - .ok(); - - // storage - ctx.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - S_START - 1, - HASH_WIDTH + 1, - ); - // code hash - ctx.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - C_START - 1, - HASH_WIDTH + 1, - ); - ctx - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) - .ok(); - - offset += 1; + if nonce_balance_c.get_byte_rev(IS_BALANCE_MOD_POS) == 1 { + assign!(region, (ctx.proof_type.proof_type, balance_lookup_offset) => ProofType::BalanceChanged.scalar())?; } + assign!(region, (ctx.mpt_table.value_prev, balance_lookup_offset) => balance_value_rlc[true.idx()])?; + assign!(region, (ctx.mpt_table.value, balance_lookup_offset) => balance_value_rlc[false.idx()])?; + + assign!(region, (ctx.mpt_table.value_prev, storage_lookup_offset) => storage_value_rlc[true.idx()])?; + assign!(region, (ctx.mpt_table.value, storage_lookup_offset) => storage_value_rlc[false.idx()])?; - /* DRIFTED */ - - let row = &witness[offset]; - if row.get_byte(1) != 0 { - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - let len = (row.bytes[2] - 128) as usize + 3; - ctx.compute_acc_and_mult(&row.bytes, &mut pv.acc_s, &mut pv.acc_mult_s, 0, len); - - self.key_data_d - .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 2) - .ok(); - - ctx - .assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - F::zero(), - F::zero(), - offset, - ) - .ok(); + if storage_codehash_c.get_byte_rev(IS_CODEHASH_MOD_POS) == 1 { + assign!(region, (ctx.proof_type.proof_type, codehash_lookup_offset) => ProofType::CodeHashExists.scalar())?; } + assign!(region, (ctx.mpt_table.value_prev, codehash_lookup_offset) => codehash_value_rlc[true.idx()])?; + assign!(region, (ctx.mpt_table.value, codehash_lookup_offset) => codehash_value_rlc[false.idx()])?; Ok(()) } diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index 7ae3111560..7664d25481 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -600,6 +600,7 @@ impl BranchConfig { require!(branch.is_key_odd() => not!(config.key_data.is_odd)); }} + // TODO(Brecht): Add checks that when placeholder another branch cannot follow for is_s in [true, false] { branch.set_is_s(is_s); ifx! {not!(branch.is_placeholder()) => { diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index 6fe81cd1b9..57eb792b35 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -1,39 +1,38 @@ -use std::{any::Any, marker::PhantomData, ops::Range}; +use std::any::Any; use crate::{ _cb, circuit, circuit_tools::{ cell_manager::{Cell, CellManager, DataTransition, Trackable}, - constraint_builder::{Conditionable, ConstraintBuilder, RLCChainable, RLCable, RLCableValue, RLCChainableValue}, + constraint_builder::{ + Conditionable, ConstraintBuilder, RLCChainable, RLCChainableValue, RLCable, + RLCableValue, + }, gadgets::IsEqualGadget, memory::MemoryBank, }, - evm_circuit::util::rlc, matchr, matchw, mpt_circuit::param::{ - KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN, RLP_HASH_VALUE, RLP_LIST_LONG, RLP_LIST_SHORT, - RLP_NIL, RLP_SHORT, + EMPTY_TRIE_HASH, KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN, RLP_HASH_VALUE, RLP_LIST_LONG, + RLP_LIST_SHORT, RLP_NIL, RLP_SHORT, }, util::Expr, }; use eth_types::Field; -use gadgets::util::{and, not, Scalar}; +use gadgets::util::{and, not, or, Scalar}; use halo2_proofs::{ circuit::Region, plonk::{Error, Expression, VirtualCells}, - poly::Rotation, halo2curves::FieldExt, + poly::Rotation, }; use super::{ - columns::MainCols, param::{ - ACCOUNT_LEAF_KEY_C_IND, ACCOUNT_LEAF_KEY_S_IND, ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND, - ACCOUNT_NON_EXISTING_IND, ARITY, BRANCH_0_C_START, BRANCH_0_S_START, BRANCH_ROWS_NUM, - IS_BRANCH_C16_POS, IS_BRANCH_C1_POS, IS_BRANCH_C_PLACEHOLDER_POS, - IS_BRANCH_S_PLACEHOLDER_POS, IS_C_BRANCH_NON_HASHED_POS, IS_C_EXT_LONGER_THAN_55_POS, - IS_C_EXT_NODE_NON_HASHED_POS, IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_LONGER_THAN_55_POS, - IS_S_EXT_NODE_NON_HASHED_POS, KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, NIBBLES_COUNTER_POS, - RLP_LONG, + ARITY, BRANCH_0_C_START, BRANCH_0_S_START, BRANCH_ROWS_NUM, IS_BRANCH_C16_POS, + IS_BRANCH_C1_POS, IS_BRANCH_C_PLACEHOLDER_POS, IS_BRANCH_S_PLACEHOLDER_POS, + IS_C_BRANCH_NON_HASHED_POS, IS_C_EXT_LONGER_THAN_55_POS, IS_C_EXT_NODE_NON_HASHED_POS, + IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_LONGER_THAN_55_POS, IS_S_EXT_NODE_NON_HASHED_POS, + KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, NIBBLES_COUNTER_POS, RLP_LONG, }, witness_row::MptWitnessRow, FixedTableTag, MPTConfig, MPTContext, ProofValues, @@ -43,7 +42,7 @@ use crate::mpt_circuit::param::{ IS_EXT_LONG_ODD_C1_POS, IS_EXT_SHORT_C16_POS, IS_EXT_SHORT_C1_POS, RLP_NUM, }; -/// Indexale object +/// Indexable object pub trait Indexable { /// Convert to index fn idx(&self) -> usize; @@ -185,7 +184,7 @@ impl RLPListWitness { } /// Number of RLP bytes - pub(crate) fn num_rlp_bytes(&self) -> u64 { + pub(crate) fn num_rlp_bytes(&self) -> usize { matchr! { self.is_short() => 1, self.is_long() => 2, @@ -193,18 +192,18 @@ impl RLPListWitness { } /// Returns the total length of the list (including RLP bytes) - pub(crate) fn num_bytes(&self) -> u64 { + pub(crate) fn num_bytes(&self) -> usize { matchr! { self.is_short() => get_num_bytes_list_short::value(self.bytes[0]), - self.is_long() => 2 + (self.bytes[1] as u64), + self.is_long() => 2 + (self.bytes[1] as usize), } } /// Returns the length of the list (excluding RLP bytes) - pub(crate) fn len(&self) -> u64 { + pub(crate) fn len(&self) -> usize { matchr! { self.is_short() => get_len_list_short::value(self.bytes[0]), - self.is_long() => self.bytes[1] as u64, + self.is_long() => self.bytes[1] as usize, } } } @@ -242,7 +241,8 @@ impl RLPValueGadget { offset: usize, bytes: &[u8], ) -> Result { - const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT - 1; + // TODO(Brecht): What's the correct way to encode NIL? + /*const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT - 1; const RLP_LONG_INCLUSIVE: u8 = RLP_LONG - 1; const RLP_VALUE_MAX: u8 = RLP_LIST_SHORT - 1; @@ -254,6 +254,19 @@ impl RLPValueGadget { RLP_SHORT..=RLP_LONG_INCLUSIVE => is_long = true, RLP_LONG..=RLP_VALUE_MAX => is_very_long = true, _ => unreachable!(), + }*/ + const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT + 1; + const RLP_LONG_INCLUSIVE: u8 = RLP_LONG - 1; + const RLP_VALUE_MAX: u8 = RLP_LIST_SHORT - 1; + + let mut is_short = false; + let mut is_long = false; + let mut is_very_long = false; + match bytes[0] { + 0..=RLP_SHORT => is_short = true, + RLP_SHORT_INCLUSIVE..=RLP_LONG_INCLUSIVE => is_long = true, + RLP_LONG..=RLP_VALUE_MAX => is_very_long = true, + _ => unreachable!(), } self.is_short.assign(region, offset, F::from(is_short))?; @@ -345,11 +358,11 @@ impl RLPValueGadget { } pub(crate) fn rlc_rlp(&self, r: &[Expression]) -> Expression { - self.rlc(r).0 + self.rlc(r).1 } pub(crate) fn rlc_value(&self, r: &[Expression]) -> Expression { - self.rlc(r).1 + self.rlc(r).0 } } @@ -371,7 +384,7 @@ impl RLPValueWitness { } /// Number of RLP bytes - pub(crate) fn num_rlp_bytes(&self) -> u64 { + pub(crate) fn num_rlp_bytes(&self) -> usize { matchr! { self.is_short() => 0, self.is_long() => 1, @@ -380,7 +393,7 @@ impl RLPValueWitness { } /// Number of bytes in total (including RLP bytes) - pub(crate) fn num_bytes(&self) -> u64 { + pub(crate) fn num_bytes(&self) -> usize { matchr! { self.is_short() => 1, self.is_long() => get_num_bytes_short::value(self.bytes[0]), @@ -391,7 +404,7 @@ impl RLPValueWitness { } /// Length of the value (excluding RLP bytes) - pub(crate) fn len(&self) -> u64 { + pub(crate) fn len(&self) -> usize { matchr! { self.is_short() => 1, self.is_long() => get_len_short::value(self.bytes[0]), @@ -419,11 +432,11 @@ impl RLPValueWitness { } pub(crate) fn rlc_rlp(&self, r: F) -> F { - self.rlc(r).0 + self.rlc(r).1 } pub(crate) fn rlc_value(&self, r: F) -> F { - self.rlc(r).1 + self.rlc(r).0 } } @@ -494,6 +507,10 @@ impl LeafKeyGadget { }) } + pub(crate) fn rlc(&self, r: &[Expression]) -> Expression { + self.bytes.rlc(r) + } + pub(crate) fn key_rlc( &self, cb: &mut ConstraintBuilder, @@ -607,19 +624,33 @@ impl LeafKeyGadget { } } +pub(crate) fn compute_acc_and_mult( + row: &[u8], + acc: &mut F, + mult: &mut F, + start: usize, + len: usize, + r: F, +) { + for i in 0..len { + *acc += F::from(row[start + i] as u64) * *mult; + *mult *= r; + } +} + impl LeafKeyWitness { /// Returns the total length of the leaf (including RLP bytes) - pub(crate) fn num_bytes(&self) -> u64 { + pub(crate) fn num_bytes(&self) -> usize { self.rlp_list.num_bytes() } /// Number of RLP bytes for leaf and key - pub(crate) fn num_rlp_bytes_list(&self) -> u64 { + pub(crate) fn num_rlp_bytes_list(&self) -> usize { self.rlp_list.num_rlp_bytes() } /// Number of RLP bytes for leaf and key - pub(crate) fn num_rlp_bytes(&self) -> u64 { + pub(crate) fn num_rlp_bytes(&self) -> usize { self.rlp_list.num_rlp_bytes() + if self.rlp_list.is_short() { self.short_list_value.num_rlp_bytes() @@ -631,7 +662,7 @@ impl LeafKeyWitness { } /// Length of the key (excluding RLP bytes) - pub(crate) fn key_len(&self) -> u64 { + pub(crate) fn key_len(&self) -> usize { matchr! { self.rlp_list.is_short() => { self.short_list_value.len() @@ -643,7 +674,7 @@ impl LeafKeyWitness { } /// Number of bytes of RLP (including list RLP bytes) and key - pub(crate) fn num_bytes_on_key_row(&self) -> u64 { + pub(crate) fn num_bytes_on_key_row(&self) -> usize { self.rlp_list.num_rlp_bytes() + if self.rlp_list.is_short() { self.short_list_value.num_bytes() @@ -656,10 +687,27 @@ impl LeafKeyWitness { /// Number of bytes of RLP (including list RLP bytes) and key pub(crate) fn rlc_leaf(&self, r: F) -> (F, F) { - (0.scalar(), 1.scalar()).rlc_chain_value( - &self.bytes[0..(self.num_bytes_on_key_row() as usize)], - r - ) + (0.scalar(), 1.scalar()) + .rlc_chain_value(&self.bytes[0..(self.num_bytes_on_key_row() as usize)], r) + } + + pub(crate) fn key_rlc(&self, key_rlc: F, key_mult: F, r: F) -> (F, F) { + if self.key_len() <= 1 { + return (key_rlc, key_mult); + } + + let start = self.num_rlp_bytes_list() as usize; + let len = self.bytes[start] as usize - 128; + let even_num_of_nibbles = self.bytes[start + 1] == 32; + + let mut key_rlc = key_rlc; + let mut key_mult = key_mult; + if !even_num_of_nibbles { + // If odd number of nibbles, we have nibble+48 in s_advices[0]. + key_rlc += F::from((self.bytes[start + 1] - 48) as u64) * key_mult; + key_mult *= r; + } + (key_rlc, key_mult).rlc_chain_value(&self.bytes[start + 2..start + 2 + len - 1], r) } } @@ -1507,182 +1555,6 @@ impl BranchChildInfo { } } -#[derive(Clone)] -pub(crate) struct AccountLeafInfo { - rot_key: i32, - ctx: MPTContext, - _marker: PhantomData, - is_nonce_long: Expression, - is_balance_long: Expression, -} - -impl AccountLeafInfo { - pub(crate) fn new(meta: &mut VirtualCells, ctx: MPTContext, rot_key: i32) -> Self { - let rot = Rotation(rot_key); - let is_nonce_long = meta.query_advice(ctx.denoter.sel1, rot); - let is_balance_long = meta.query_advice(ctx.denoter.sel2, rot); - AccountLeafInfo { - rot_key, - ctx: ctx.clone(), - is_nonce_long, - is_balance_long, - _marker: PhantomData, - } - } - - pub(crate) fn is_wrong_leaf(&self, meta: &mut VirtualCells, is_s: bool) -> Expression { - let rot_non_existing = ACCOUNT_NON_EXISTING_IND - - if is_s { - ACCOUNT_LEAF_KEY_S_IND - } else { - ACCOUNT_LEAF_KEY_C_IND - }; - meta.query_advice( - self.ctx.s_main.rlp1, - Rotation(self.rot_key + rot_non_existing), - ) - } - - pub(crate) fn is_nonce_long(&self) -> Expression { - self.is_nonce_long.expr() - } - - pub(crate) fn is_balance_long(&self) -> Expression { - self.is_balance_long.expr() - } - - pub(crate) fn nonce_len(&self, meta: &mut VirtualCells) -> Expression { - circuit!([meta, _cb!()], { - 2.expr() + a!(self.ctx.s_main.rlp2, self.rot_key) - }) - } - - /// Returns the total length of the leaf (including RLP bytes) - pub(crate) fn num_bytes(&self, meta: &mut VirtualCells) -> Expression { - circuit!([meta, _cb!()], { - 2.expr() + a!(self.ctx.s_main.rlp2, self.rot_key) - }) - } - - /// Returns the length of the key - pub(crate) fn key_len(&self, _meta: &mut VirtualCells) -> Expression { - circuit!([_meta, _cb!()], { - get_len_short::expr(a!(self.ctx.s_main.bytes[0], self.rot_key)) - }) - } - - /// Number of bytes of RLP (including list RLP bytes) and key - pub(crate) fn num_bytes_on_key_row(&self, meta: &mut VirtualCells) -> Expression { - self.num_rlp_bytes(meta) + self.key_len(meta) - } - - /// Number of RLP bytes for leaf and key - pub(crate) fn num_rlp_bytes(&self, _meta: &mut VirtualCells) -> Expression { - // 2 RLP bytes + 1 byte that contains the key length. - 3.expr() - } - - pub(crate) fn nonce_balance_rlc( - &self, - meta: &mut VirtualCells, - nonce_rlc: Expression, - balance_rlc: Expression, - mult_prev: Expression, - mult_nonce: Expression, - rot_nonce: i32, - ) -> Expression { - circuit!([meta, _cb!()], { - rlc::expr( - &[ - a!(self.ctx.s_main.rlp1, rot_nonce), - a!(self.ctx.s_main.rlp2, rot_nonce), - a!(self.ctx.c_main.rlp1, rot_nonce), - a!(self.ctx.c_main.rlp2, rot_nonce), - nonce_rlc, - ] - .into_iter() - .map(|value| value * mult_prev.expr()) - .collect::>(), - &self.ctx.r, - ) + balance_rlc * mult_prev.expr() * mult_nonce.expr() - }) - } - - pub(crate) fn storage_codehash_rlc( - &self, - meta: &mut VirtualCells, - storage_rlc: Expression, - codehash_rlc: Expression, - mult_prev: Expression, - rot_storage: i32, - ) -> Expression { - circuit!([meta, _cb!()], { - rlc::expr( - &[ - a!(self.ctx.s_main.rlp2, rot_storage), - storage_rlc, - a!(self.ctx.c_main.rlp2, rot_storage), - codehash_rlc, - ] - .map(|v| v * mult_prev.expr()), - &[ - self.ctx.r[0].expr(), - self.ctx.r[32].expr(), - self.ctx.r[33].expr(), - ], - ) - }) - } - - // Can be used for nonce/balance to from a value rlc to a data rlc (which - // included the RLP bytes) - pub(crate) fn to_data_rlc( - &self, - meta: &mut VirtualCells, - main: MainCols, - value_rlc: Expression, - is_long: Expression, - rot_nonce: i32, - ) -> Expression { - circuit!([meta, _cb!()], { - ifx! {is_long => { - a!(main.bytes[0], rot_nonce) + value_rlc.expr() * self.ctx.r[0].expr() - } elsex { - value_rlc - }} - }) - } - - pub(crate) fn storage_root_rlc(&self, meta: &mut VirtualCells) -> Expression { - let storage_offset = ACCOUNT_LEAF_STORAGE_CODEHASH_S_IND - ACCOUNT_LEAF_KEY_S_IND; - let rot_storage_root = self.rot_key + storage_offset; - // Note: storage root is always in s_main.bytes. - self.ctx - .s_main - .bytes(meta, rot_storage_root) - .rlc(&self.ctx.r) - } - - pub(crate) fn key_rlc( - &self, - meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - key_mult_prev: Expression, - is_key_odd: Expression, - key_mult_first_even: Expression, - rot: i32, - ) -> Expression { - leaf_key_rlc( - cb, - &self.ctx.expr(meta, self.rot_key + rot)[3..36], - key_mult_prev.expr(), - is_key_odd, - key_mult_first_even, - &self.ctx.r, - ) - } -} - pub(crate) fn contains_placeholder_leaf( meta: &mut VirtualCells, ctx: MPTContext, @@ -1755,8 +1627,8 @@ pub(crate) mod get_len_short { pub(crate) fn expr(byte: Expression) -> Expression { byte - RLP_SHORT.expr() } - pub(crate) fn value(byte: u8) -> u64 { - (byte - RLP_SHORT) as u64 + pub(crate) fn value(byte: u8) -> usize { + (byte - RLP_SHORT) as usize } } @@ -1770,7 +1642,7 @@ pub(crate) mod get_num_bytes_short { pub(crate) fn expr(byte: Expression) -> Expression { 1.expr() + get_len_short::expr(byte) } - pub(crate) fn value(byte: u8) -> u64 { + pub(crate) fn value(byte: u8) -> usize { 1 + get_len_short::value(byte) } } @@ -1784,8 +1656,8 @@ pub(crate) mod get_len_list_short { pub(crate) fn expr(byte: Expression) -> Expression { byte - RLP_LIST_SHORT.expr() } - pub(crate) fn value(byte: u8) -> u64 { - (byte - RLP_LIST_SHORT) as u64 + pub(crate) fn value(byte: u8) -> usize { + (byte - RLP_LIST_SHORT) as usize } } @@ -1799,7 +1671,7 @@ pub(crate) mod get_num_bytes_list_short { pub(crate) fn expr(byte: Expression) -> Expression { 1.expr() + get_len_list_short::expr(byte) } - pub(crate) fn value(byte: u8) -> u64 { + pub(crate) fn value(byte: u8) -> usize { 1 + get_len_list_short::value(byte) } } @@ -1817,36 +1689,6 @@ pub(crate) fn get_num_nibbles( }) } -// Returns the RLC values stored in the parent of the current node. -pub(crate) fn get_parent_rlc_state( - meta: &mut VirtualCells, - ctx: MPTContext, - is_first_level: Expression, - rot_parent: i32, -) -> (Expression, Expression) { - let accs = ctx.accumulators; - let rot_branch_init = rot_parent + 1 - BRANCH_ROWS_NUM; - let rot_first_child = rot_branch_init + 1; - let rot_first_child_prev = rot_first_child - BRANCH_ROWS_NUM; - circuit!([meta, _cb!()], { - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - ifx! {branch.is_extension() => { - let key_mult_prev = ifx!{is_first_level => { - 1.expr() - } elsex { - a!(accs.key.mult, rot_first_child_prev) - }}; - (a!(accs.key.rlc, rot_parent), key_mult_prev * a!(accs.mult_diff, rot_first_child)) - } elsex { - ifx!{is_first_level => { - (0.expr(), 1.expr()) - } elsex { - (a!(accs.key.rlc, rot_first_child_prev), a!(accs.key.mult, rot_first_child_prev)) - }} - }} - }) -} - pub(crate) fn extend_rand(r: &[Expression]) -> Vec> { [ r.to_vec(), @@ -1951,3 +1793,56 @@ impl MPTConstraintBuilder { Self::DEFAULT_RANGE.expr() - self.range_s.apply_conditions() } } + +/// Returns `1` when `value == 0`, and returns `0` otherwise. +#[derive(Clone, Debug, Default)] +pub struct IsEmptyTreeGadget { + is_in_empty_trie: IsEqualGadget, + is_in_empty_branch: IsEqualGadget, +} + +impl IsEmptyTreeGadget { + pub(crate) fn construct( + cb: &mut ConstraintBuilder, + parent_rlc: Expression, + r: &[Expression], + ) -> Self { + circuit!([meta, cb], { + let empty_root_rlc = EMPTY_TRIE_HASH + .iter() + .map(|v| v.expr()) + .collect::>() + .rlc(&r); + let is_in_empty_trie = + IsEqualGadget::construct(cb, parent_rlc.expr(), empty_root_rlc.expr()); + let is_in_empty_branch = IsEqualGadget::construct(cb, parent_rlc.expr(), 128.expr()); + + Self { + is_in_empty_trie, + is_in_empty_branch, + } + }) + } + + pub(crate) fn expr(&self) -> Expression { + or::expr(&[self.is_in_empty_trie.expr(), self.is_in_empty_branch.expr()]) + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + parent_rlc: F, + r: F, + ) -> Result<(), Error> { + self.is_in_empty_trie.assign( + region, + offset, + parent_rlc, + bytes_into_rlc(&EMPTY_TRIE_HASH, r), + )?; + self.is_in_empty_branch + .assign(region, offset, parent_rlc, 128.scalar())?; + Ok(()) + } +} diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index 54c8e60550..622b1b86a5 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -9,21 +9,15 @@ use halo2_proofs::{ use std::marker::PhantomData; use crate::circuit_tools::cell_manager::Cell; -use crate::circuit_tools::constraint_builder::{RLCChainable, RLCable, RLCChainableValue, RLCableValue}; -use crate::circuit_tools::gadgets::{IsEqualGadget, LtGadget, RequireNotZeroGadget}; -use crate::mpt_circuit::helpers::drifted_nibble_rlc; +use crate::circuit_tools::constraint_builder::{RLCChainable, RLCableValue}; +use crate::circuit_tools::gadgets::{LtGadget, RequireNotZeroGadget}; +use crate::mpt_circuit::helpers::{drifted_nibble_rlc, IsEmptyTreeGadget}; use crate::table::ProofType; use crate::{ assign, circuit, mpt_circuit::{ - helpers::{ - key_memory, parent_memory, KeyData, MPTConstraintBuilder, - ParentData, - }, - param::{ - EMPTY_TRIE_HASH, HASH_WIDTH, IS_NON_EXISTING_STORAGE_POS, IS_STORAGE_MOD_POS, - KEY_LEN_IN_NIBBLES, - }, + helpers::{key_memory, parent_memory, KeyData, MPTConstraintBuilder, ParentData}, + param::{HASH_WIDTH, IS_NON_EXISTING_STORAGE_POS, IS_STORAGE_MOD_POS, KEY_LEN_IN_NIBBLES}, FixedTableTag, }, mpt_circuit::{ @@ -33,7 +27,7 @@ use crate::{ mpt_circuit::{MPTConfig, ProofValues}, }; -use super::helpers::{bytes_into_rlc, Indexable, LeafKeyGadget, RLPValueGadget}; +use super::helpers::{Indexable, LeafKeyGadget, RLPValueGadget}; #[derive(Clone, Debug)] pub(crate) struct StorageLeafCols { @@ -41,12 +35,6 @@ pub(crate) struct StorageLeafCols { pub(crate) is_s_value: Column, pub(crate) is_c_key: Column, pub(crate) is_c_value: Column, - /** it is at drifted_pos position in added branch, - * note that this row could be omitted when there - * is no added branch but then it would open a - * vulnerability because the attacker could omit - * these row in cases when it is needed too (and - * constraints happen in this row) */ pub(crate) is_in_added_branch: Column, pub(crate) is_non_existing: Column, _marker: PhantomData, @@ -64,22 +52,6 @@ impl StorageLeafCols { _marker: PhantomData, } } - - pub(crate) fn is_key(&self, is_s: bool) -> Column { - if is_s { - self.is_s_key - } else { - self.is_c_key - } - } - - pub(crate) fn is_value(&self, is_s: bool) -> Column { - if is_s { - self.is_s_value - } else { - self.is_c_value - } - } } #[derive(Default, Debug)] @@ -97,7 +69,7 @@ pub(crate) struct StorageLeafConfig { key_data: [KeyData; 2], key_data_w: KeyData, parent_data: [ParentData; 2], - mult: [Cell; 2], + key_mult: [Cell; 2], drifted_mult: Cell, rlp_key: [LeafKeyGadget; 2], rlp_value: [RLPValueGadget; 2], @@ -106,8 +78,7 @@ pub(crate) struct StorageLeafConfig { is_wrong_leaf: Cell, check_is_wrong_leaf: RequireNotZeroGadget, is_not_hashed: [LtGadget; 2], - is_in_empty_trie: [IsEqualGadget; 2], - is_in_empty_branch: [IsEqualGadget; 2], + is_empty_trie: [IsEmptyTreeGadget; 2], } impl StorageLeafConfig { @@ -122,16 +93,19 @@ impl StorageLeafConfig { let mut config = StorageLeafConfig::default(); circuit!([meta, cb.base], { - let key_bytes = [ctx.expr(meta, 0), ctx.expr(meta, 2)]; + let key_bytes = [ + ctx.expr(meta, 0)[..36].to_owned(), + ctx.expr(meta, 2)[..36].to_owned(), + ]; let value_bytes = [ctx.expr(meta, 1), ctx.expr(meta, 3)]; - let drifted_bytes = ctx.expr(meta, 4); - let wrong_bytes = ctx.expr(meta, 5); + let drifted_bytes = ctx.expr(meta, 4)[..36].to_owned(); + let wrong_bytes = ctx.expr(meta, 5)[..36].to_owned(); let lookup_offset = 3; let wrong_offset = 5; let mut key_rlc = vec![0.expr(); 2]; let mut value_rlc = vec![0.expr(); 2]; - let mut leaf_rlc_value = vec![0.expr(); 2]; + let mut value_rlp_rlc = vec![0.expr(); 2]; for is_s in [true, false] { // Parent data let parent_data = &mut config.parent_data[is_s.idx()]; @@ -141,35 +115,34 @@ impl StorageLeafConfig { &ctx.memory[parent_memory(is_s)], 0.expr(), ); - // Key data let key_data = &mut config.key_data[is_s.idx()]; *key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(is_s)], 0.expr()); // Placeholder leaf checks - let empty_root_rlc = EMPTY_TRIE_HASH - .iter() - .map(|v| v.expr()) - .collect::>() - .rlc(&r); - config.is_in_empty_trie[is_s.idx()] = IsEqualGadget::construct( - &mut cb.base, - parent_data.rlc.expr(), - empty_root_rlc.expr(), - ); - config.is_in_empty_branch[is_s.idx()] = - IsEqualGadget::construct(&mut cb.base, parent_data.rlc.expr(), 128.expr()); - let is_placeholder_leaf = or::expr(&[ - config.is_in_empty_trie[is_s.idx()].expr(), - config.is_in_empty_branch[is_s.idx()].expr(), - ]); + config.is_empty_trie[is_s.idx()] = + IsEmptyTreeGadget::construct(&mut cb.base, parent_data.rlc.expr(), &r); + let is_placeholder_leaf = config.is_empty_trie[is_s.idx()].expr(); - // Calculate and store the leaf data RLC - let leaf_rlc_key = key_bytes[is_s.idx()][0..36].rlc(&r); - - // Calculate the key let rlp_key = &mut config.rlp_key[is_s.idx()]; *rlp_key = LeafKeyGadget::construct(&mut cb.base, &key_bytes[is_s.idx()]); + config.rlp_value[is_s.idx()] = + RLPValueGadget::construct(&mut cb.base, &value_bytes[is_s.idx()][0..36]); + + config.key_mult[is_s.idx()] = cb.base.query_cell(); + require!((FixedTableTag::RMult, rlp_key.num_bytes_on_key_row(), config.key_mult[is_s.idx()].expr()) => @"fixed"); + + // RLC bytes zero check + //cb.set_length(rlp_key.num_bytes_on_key_row()); + //cb.set_length_s(config.rlp_value[is_s.idx()].num_bytes()); + + (value_rlc[is_s.idx()], value_rlp_rlc[is_s.idx()]) = + config.rlp_value[is_s.idx()].rlc(&r); + + let leaf_rlc = (rlp_key.rlc(&r), config.key_mult[is_s.idx()].expr()) + .rlc_chain(value_rlp_rlc[is_s.idx()].expr()); + + // Key key_rlc[is_s.idx()] = key_data.rlc.expr() + rlp_key.key_rlc( &mut cb.base, @@ -179,7 +152,6 @@ impl StorageLeafConfig { true, &r, ); - // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES (except in a // placeholder leaf). // TODO(Brecht): why not in placeholder leaf? @@ -188,29 +160,6 @@ impl StorageLeafConfig { require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); }} - // Num bytes used in RLC - let num_bytes = rlp_key.num_bytes_on_key_row(); - // Multiplier is number of bytes - config.mult[is_s.idx()] = cb.base.query_cell(); - require!((FixedTableTag::RMult, num_bytes.expr(), config.mult[is_s.idx()].expr()) => @"fixed"); - // RLC bytes zero check - //cb.set_length(num_bytes.expr()); - - // Key done, set the default values - KeyData::store( - &mut cb.base, - &ctx.memory[key_memory(is_s)], - KeyData::default_values(), - ); - - // Decode the storage value - let rlp_value = &mut config.rlp_value[is_s.idx()]; - *rlp_value = - RLPValueGadget::construct(&mut cb.base, &value_bytes[is_s.idx()][0..36]); - (value_rlc[is_s.idx()], leaf_rlc_value[is_s.idx()]) = rlp_value.rlc(&r); - let leaf_rlc = (leaf_rlc_key, config.mult[is_s.idx()].expr()) - .rlc_chain(leaf_rlc_value[is_s.idx()].expr()); - // If `is_modified_node_empty = 1`, which means an empty child, we need to // ensure that the value is set to 0 in the placeholder leaf. For // example when adding a new storage leaf to the trie, we have an empty child in @@ -219,55 +168,44 @@ impl StorageLeafConfig { require!(value_rlc[is_s.idx()] => 0); }} - // Number of bytes used by the leaf in total - let num_bytes = rlp_key.num_bytes(); - // Get the number of bytes used by the value - let value_num_bytes = rlp_value.num_bytes(); - // Make sure the RLP encoding is correct. // storage = [key, value] - // TODO(Brecht): modify the witness for empty placeholder leafs to have valid - // RLP encoding ifx! {not!(is_placeholder_leaf) => { let key_num_bytes = rlp_key.num_bytes_on_key_row(); - require!(num_bytes => key_num_bytes.expr() + value_num_bytes.expr()); + require!(rlp_key.num_bytes() => key_num_bytes.expr() + config.rlp_value[is_s.idx()].num_bytes()); }}; // Check if the account is in its parent. // Check is skipped for placeholder leafs which are dummy leafs ifx! {not!(is_placeholder_leaf) => { - config.is_not_hashed[is_s.idx()] = LtGadget::construct(&mut cb.base, num_bytes.expr(), 32.expr()); + config.is_not_hashed[is_s.idx()] = LtGadget::construct(&mut cb.base, rlp_key.num_bytes(), 32.expr()); ifx!{or::expr(&[parent_data.is_root.expr(), not!(config.is_not_hashed[is_s.idx()])]) => { // Hashed branch hash in parent branch - require!((1, leaf_rlc, num_bytes, parent_data.rlc) => @"keccak"); + require!((1, leaf_rlc, rlp_key.num_bytes(), parent_data.rlc) => @"keccak"); } elsex { // Non-hashed branch hash in parent branch require!(leaf_rlc => parent_data.rlc); }} }} + + // Key done, set the default values + KeyData::store( + &mut cb.base, + &ctx.memory[key_memory(is_s)], + KeyData::default_values(), + ); // Store the new parent ParentData::store( &mut cb.base, &ctx.memory[parent_memory(is_s)], [0.expr(), true.expr(), false.expr(), 0.expr()], ); - - // Set the number of bytes used - //cb.set_length_s(value_num_bytes); } - // Put the data in the lookup table - require!(a!(ctx.mpt_table.key_rlc, lookup_offset) => key_rlc[false.idx()]); - require!(a!(ctx.mpt_table.value_prev, lookup_offset) => value_rlc[true.idx()]); - require!(a!(ctx.mpt_table.value, lookup_offset) => value_rlc[false.idx()]); - // Drifted leaf ifx! {config.parent_data[true.idx()].is_placeholder.expr() + config.parent_data[false.idx()].is_placeholder.expr() => { config.drifted_rlp_key = LeafKeyGadget::construct(&mut cb.base, &drifted_bytes); - // Calculate and store the leaf RLC (RLP + key) - let drifted_rlc_key = drifted_bytes[0..36].rlc(&r); - // We need the intermediate key RLC right before `drifted_index` is added to it. let (key_rlc_prev, key_mult_prev, placeholder_nibble, placeholder_is_odd) = ifx!{config.parent_data[true.idx()].is_placeholder.expr() => { ( @@ -290,20 +228,15 @@ impl StorageLeafConfig { drifted_nibble_rlc(&mut cb.base, placeholder_nibble.expr(), key_mult_prev.expr(), placeholder_is_odd.expr()) + config.drifted_rlp_key.key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), true, &r); - // Check zero bytes and mult_diff config.drifted_mult = cb.base.query_cell(); - // Num bytes used in RLC - let num_bytes = config.drifted_rlp_key.num_bytes_on_key_row(); - // Multiplier is number of bytes - require!((FixedTableTag::RMult, num_bytes.expr(), config.drifted_mult.expr()) => @"fixed"); - // RLC bytes zero check - //cb.set_length(num_bytes.expr()); + require!((FixedTableTag::RMult, config.drifted_rlp_key.num_bytes_on_key_row(), config.drifted_mult.expr()) => @"fixed"); + cb.set_length(config.drifted_rlp_key.num_bytes_on_key_row()); // Check that the drifted leaf is unchanged and is stored at `drifted_index`. let calc_rlc = |is_s: bool| { // Complete the drifted leaf rlc by adding the bytes on the value row - let drifted_rlc = (drifted_rlc_key.expr(), config.drifted_mult.expr()).rlc_chain(leaf_rlc_value[is_s.idx()].expr()); + let drifted_rlc = (config.drifted_rlp_key.rlc(&r), config.drifted_mult.expr()).rlc_chain(value_rlp_rlc[is_s.idx()].expr()); (key_rlc[is_s.idx()].expr(), drifted_rlc, config.parent_data[is_s.idx()].placeholder_rlc.expr()) }; let (key_rlc, drifted_rlc, mod_hash) = matchx! { @@ -350,8 +283,7 @@ impl StorageLeafConfig { // Make sure the lengths of the keys are the same require!(config.wrong_rlp_key.key_len() => config.rlp_key[false.idx()].key_len()); // RLC bytes zero check - let num_bytes = config.wrong_rlp_key.num_bytes_on_key_row(); - //cb.set_length(num_bytes); + cb.set_length(config.wrong_rlp_key.num_bytes_on_key_row()); } elsex { // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. require!(config.key_data_w.is_placeholder_leaf_c => true); @@ -360,6 +292,11 @@ impl StorageLeafConfig { // is_wrong_leaf needs to be false when not in non_existing_account proof require!(config.is_wrong_leaf => false); }} + + // Put the data in the lookup table + require!(a!(ctx.mpt_table.key_rlc, lookup_offset) => key_rlc[false.idx()]); + require!(a!(ctx.mpt_table.value_prev, lookup_offset) => value_rlc[true.idx()]); + require!(a!(ctx.mpt_table.value, lookup_offset) => value_rlc[false.idx()]); }); config @@ -388,24 +325,18 @@ impl StorageLeafConfig { // Key let key_row = &key_bytes[is_s.idx()]; - let rlp_key_witness = self.rlp_key[is_s.idx()] - .assign(region, base_offset, &key_row.bytes) - .ok() - .unwrap(); + let rlp_key_witness = + self.rlp_key[is_s.idx()].assign(region, base_offset, &key_row.bytes)?; let (_, leaf_mult) = rlp_key_witness.rlc_leaf(ctx.randomness); - self.mult[is_s.idx()] - .assign(region, base_offset, leaf_mult) - .ok(); - - self.is_not_hashed[is_s.idx()] - .assign( - region, - base_offset, - F::from(rlp_key_witness.num_bytes()), - F::from(32), - ) - .ok(); + self.key_mult[is_s.idx()].assign(region, base_offset, leaf_mult)?; + + self.is_not_hashed[is_s.idx()].assign( + region, + base_offset, + rlp_key_witness.num_bytes().scalar(), + 32.scalar(), + )?; self.key_data[is_s.idx()].witness_load( region, @@ -439,122 +370,95 @@ impl StorageLeafConfig { key_rlc_new = pv.key_rlc_prev; key_rlc_mult_new = pv.key_rlc_mult_prev; } - if rlp_key_witness.num_bytes_on_key_row() != 2 { - // If in last level or having only one nibble, - // the key RLC is already computed using the first two bytes above. - ctx.compute_key_rlc( - &key_row.bytes, - &mut key_rlc_new, - &mut key_rlc_mult_new, - rlp_key_witness.num_rlp_bytes_list() as usize, - ); - } - key_rlc[is_s.idx()] = key_rlc_new; + (key_rlc[is_s.idx()], _) = + rlp_key_witness.key_rlc(key_rlc_new, key_rlc_mult_new, ctx.randomness); // Value let value_row = &value_bytes[is_s.idx()]; - let value_witness = self.rlp_value[is_s.idx()] - .assign(region, base_offset, &value_row.bytes) - .ok() - .unwrap(); - - value_rlc[is_s.idx()] = value_row.bytes[value_witness.num_rlp_bytes() as usize..HASH_WIDTH + 2].rlc_value(ctx.randomness); - - let parent_values = self.parent_data[is_s.idx()] - .witness_load(region, base_offset, &mut pv.memory[parent_memory(is_s)], 0) - .ok() - .unwrap(); - self.parent_data[is_s.idx()] - .witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(is_s)], - F::zero(), - true, - false, - F::zero(), - ) - .ok(); - - self.is_in_empty_trie[is_s.idx()] - .assign( - region, - base_offset, - parent_values[0], - bytes_into_rlc(&EMPTY_TRIE_HASH, ctx.randomness), - ) - .ok(); - self.is_in_empty_branch[is_s.idx()] - .assign(region, base_offset, parent_values[0], 128.scalar()) - .ok(); - } + let value_witness = + self.rlp_value[is_s.idx()].assign(region, base_offset, &value_row.bytes)?; - // Put the data in the lookup table - if value_bytes[false.idx()].get_byte_rev(IS_STORAGE_MOD_POS) == 1 { - assign!(region, (ctx.proof_type.proof_type, lookup_offset) => ProofType::StorageChanged.scalar()).ok(); + value_rlc[is_s.idx()] = value_row.bytes + [value_witness.num_rlp_bytes() as usize..HASH_WIDTH + 2] + .rlc_value(ctx.randomness); + + let parent_values = self.parent_data[is_s.idx()].witness_load( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + 0, + )?; + self.parent_data[is_s.idx()].witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + F::zero(), + true, + false, + F::zero(), + )?; + + self.is_empty_trie[is_s.idx()].assign( + region, + base_offset, + parent_values[0], + ctx.randomness, + )?; } - assign!(region, (ctx.mpt_table.key_rlc, lookup_offset) => key_rlc[false.idx()]).ok(); - assign!(region, (ctx.mpt_table.value_prev, lookup_offset) => value_rlc[true.idx()]).ok(); - assign!(region, (ctx.mpt_table.value, lookup_offset) => value_rlc[false.idx()]).ok(); // Drifted leaf handling if pv.is_branch_s_placeholder || pv.is_branch_c_placeholder { let row = &drifted_bytes; - let drifted_key_witness = self - .drifted_rlp_key - .assign(region, base_offset, &row.bytes) - .ok() - .unwrap(); + let drifted_key_witness = + self.drifted_rlp_key + .assign(region, base_offset, &row.bytes)?; let (_, leaf_mult) = drifted_key_witness.rlc_leaf(ctx.randomness); - self.drifted_mult - .assign(region, base_offset, leaf_mult) - .ok(); + self.drifted_mult.assign(region, base_offset, leaf_mult)?; } // Non-existing - { - let row = &wrong_bytes; - if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { - self.key_data_w - .witness_load(region, base_offset, &mut pv.memory[key_memory(true)], 1) - .ok(); - - // TODO(Brecht): Change how the witness is generated - let is_wrong = row.bytes[0] != 0; - self.is_wrong_leaf - .assign(region, base_offset, F::from(is_wrong)) - .ok(); - - let mut row_bytes = row.bytes.clone(); - row_bytes[0] = key_bytes[false.idx()].bytes[0]; - - let wrong_witness = self - .wrong_rlp_key - .assign(region, base_offset, &row_bytes) - .ok() - .unwrap(); - - let mut key_rlc_new = pv.key_rlc; - let mut key_rlc_mult_new = pv.key_rlc_mult; - ctx.compute_key_rlc( - &row.bytes, - &mut key_rlc_new, - &mut key_rlc_mult_new, - wrong_witness.num_rlp_bytes_list() as usize, - ); - assign!(region, (ctx.mpt_table.key_rlc, wrong_offset) => key_rlc_new).ok(); + let row = &wrong_bytes; + if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { + self.key_data_w.witness_load( + region, + base_offset, + &mut pv.memory[key_memory(true)], + 1, + )?; - self.check_is_wrong_leaf - .assign(region, base_offset, key_rlc_new - key_rlc[false.idx()]) - .ok(); + // TODO(Brecht): Change how the witness is generated + let is_wrong = row.bytes[0] != 0; + self.is_wrong_leaf + .assign(region, base_offset, F::from(is_wrong))?; - assign!(region, (ctx.proof_type.proof_type, wrong_offset) => ProofType::StorageDoesNotExist.scalar()).ok(); - } + let mut row_bytes = row.bytes.clone(); + row_bytes[0] = key_bytes[false.idx()].bytes[0]; + + let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes)?; + let (key_rlc_wrong, _) = + wrong_witness.key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.randomness); + + self.check_is_wrong_leaf.assign( + region, + base_offset, + key_rlc_wrong - key_rlc[false.idx()], + )?; + + assign!(region, (ctx.mpt_table.key_rlc, wrong_offset) => key_rlc_wrong)?; + assign!(region, (ctx.proof_type.proof_type, wrong_offset) => ProofType::StorageDoesNotExist.scalar())?; + } + + // Put the data in the lookup table + if value_bytes[false.idx()].get_byte_rev(IS_STORAGE_MOD_POS) == 1 { + assign!(region, (ctx.proof_type.proof_type, lookup_offset) => ProofType::StorageChanged.scalar())?; } + assign!(region, (ctx.mpt_table.key_rlc, lookup_offset) => key_rlc[false.idx()])?; + assign!(region, (ctx.mpt_table.value_prev, lookup_offset) => value_rlc[true.idx()])?; + assign!(region, (ctx.mpt_table.value, lookup_offset) => value_rlc[false.idx()])?; Ok(()) } diff --git a/zkevm-circuits/src/mpt_circuit/witness_row.rs b/zkevm-circuits/src/mpt_circuit/witness_row.rs index 455c203c8d..1715bb8a25 100644 --- a/zkevm-circuits/src/mpt_circuit/witness_row.rs +++ b/zkevm-circuits/src/mpt_circuit/witness_row.rs @@ -44,6 +44,7 @@ pub(crate) enum MptWitnessRowType { StorageNonExisting = 19, } +#[derive(Clone, Debug)] pub struct MptWitnessRow { pub(crate) bytes: Vec, _marker: PhantomData, From 1108e1eae40bfb5e19b39bdaba75ac7eccd3009d Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Mon, 27 Feb 2023 04:22:47 +0100 Subject: [PATCH 09/11] branch refactor --- .../src/circuit_tools/constraint_builder.rs | 75 +- zkevm-circuits/src/mpt_circuit.rs | 470 +---- .../src/mpt_circuit/account_leaf.rs | 55 +- zkevm-circuits/src/mpt_circuit/branch.rs | 1839 ++++++----------- zkevm-circuits/src/mpt_circuit/columns.rs | 136 -- zkevm-circuits/src/mpt_circuit/helpers.rs | 1345 ++++++------ zkevm-circuits/src/mpt_circuit/proof_chain.rs | 9 +- zkevm-circuits/src/mpt_circuit/selectors.rs | 69 +- .../src/mpt_circuit/storage_leaf.rs | 50 +- zkevm-circuits/src/mpt_circuit/witness_row.rs | 290 +-- 10 files changed, 1384 insertions(+), 2954 deletions(-) diff --git a/zkevm-circuits/src/circuit_tools/constraint_builder.rs b/zkevm-circuits/src/circuit_tools/constraint_builder.rs index 685a157b55..070f2727ff 100644 --- a/zkevm-circuits/src/circuit_tools/constraint_builder.rs +++ b/zkevm-circuits/src/circuit_tools/constraint_builder.rs @@ -589,6 +589,66 @@ impl_selectable!( Expression )| { vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr(), t.4.expr()] } ); +impl_selectable!( + ( + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + ), + |t: &( + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + )| { vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr(), t.4.expr(), t.5.expr()] } +); +impl_selectable!( + ( + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + ), + |t: &( + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + )| { vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr(), t.4.expr(), t.5.expr(), t.6.expr()] } +); +impl_selectable!( + ( + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + ), + |t: &( + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + Expression, + )| { vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr(), t.4.expr(), t.5.expr(), t.6.expr(), t.7.expr()] } +); /// Trait that conditionally combines multiple types pub trait Conditionable { @@ -648,11 +708,11 @@ impl RLCChainable for (Expression, Expression) { } } -pub(crate) fn rlc_acc(values: &[u8], rlc: F, mult: F, r: F) -> (F, F) { +pub(crate) fn rlc_acc(values: &[F], rlc: F, mult: F, r: F) -> (F, F) { let mut rlc = rlc; let mut mult = mult; for &value in values.iter() { - rlc = rlc + F::from(value as u64) * mult; + rlc = rlc + value * mult; mult *= r; } (rlc, mult) @@ -680,10 +740,18 @@ impl RLCableValue for [u8] { pub trait RLCChainableValue { /// Returns the RLC of itself with a starting rlc/multiplier fn rlc_chain_value(&self, values: &[u8], r: F) -> (F, F); + + /// Returns the RLC of itself with a starting rlc/multiplier + fn rlc_chain_value_f(&self, values: &[F], r: F) -> (F, F); } impl RLCChainableValue for (F, F) { fn rlc_chain_value(&self, values: &[u8], r: F) -> (F, F) { + let values = values.iter().map(|byte| byte.scalar()).collect::>(); + rlc_acc(&values, self.0, self.1, r) + } + + fn rlc_chain_value_f(&self, values: &[F], r: F) -> (F, F) { rlc_acc(values, self.0, self.1, r) } } @@ -1099,6 +1167,9 @@ macro_rules! circuit { ($condition_a:expr, $condition_b:expr, $condition_c:expr, $condition_d:expr => $when_true:block elsex $when_false:block) => {{ _ifx!($cb, $condition_a, $condition_b, $condition_c, $condition_d => $when_true elsex $when_false) }}; + ($condition_a:expr, $condition_b:expr, $condition_c:expr, $condition_d:expr, $condition_e:expr, $condition_f:expr, $condition_g:expr => $when_true:block elsex $when_false:block) => {{ + _ifx!($cb, $condition_a, $condition_b, $condition_c, $condition_d, $condition_e, $condition_f, $condition_g => $when_true elsex $when_false) + }}; ($condition:expr => $when_true:block) => {{ _ifx!($cb, $condition => $when_true) diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index 23975f1d18..d99d6f018b 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -19,17 +19,16 @@ mod selectors; mod storage_leaf; mod witness_row; -use account_leaf::{AccountLeaf, AccountLeafCols}; -use branch::{Branch, BranchCols, BranchConfig}; -use columns::{AccumulatorCols, DenoteCols, MainCols, PositionCols, ProofTypeCols}; +use branch::{BranchConfig}; +use columns::{MainCols, PositionCols, ProofTypeCols}; use proof_chain::ProofChainConfig; -use storage_leaf::{StorageLeaf, StorageLeafCols}; use witness_row::{MptWitnessRow, MptWitnessRowType}; use param::HASH_WIDTH; use selectors::SelectorsConfig; use crate::{ + assign, circuit, circuit_tools::{ cell_manager::CellManager, @@ -46,33 +45,6 @@ use crate::{ use self::{account_leaf::AccountLeafConfig, columns::MPTTable, helpers::key_memory}; -/* - MPT circuit contains S and C columns (other columns are mostly selectors). - - With S columns the prover proves the knowledge of key1/val1 that is in the - trie with rootS. - - With C columns the prover proves the knowledge of key1/val2 that is in the - trie with rootC. Note that key is the same for both S and C, whereas value - is different. The prover thus proves the knowledge how to change value at key - key1 from val1 to val2 that results the root being changed from rootS to rootC. - - The branch contains 16 nodes which are stored in 16 rows. - A row looks like: - [0, 160, 123, ..., 148, 0, 160, 232, ..., 92 ] - [rlp1 (S), rlp2 (S), b0 (S), ..., b31 (S), rlp1 (C), rlp2 C, b0 (C), ..., b31 (C)] - - Values bi (S) and bi(C) present hash of a node. Thus, the first half of a row - is a S node: - [rlp1, rlp2, b0, ..., b31] - - The second half of the row is a C node (same structure): - [rlp1, rlp2, b0, ..., b31] - - We start with top level branch and then we follow branches (could be also extension - nodes) down to the leaf. -*/ - /// Merkle Patricia Trie config. pub struct RowConfig { branch_config: BranchConfig, @@ -90,13 +62,8 @@ pub struct MPTContext { pub(crate) inter_final_root: Column, pub(crate) value_prev: Column, pub(crate) value: Column, - pub(crate) accumulators: AccumulatorCols, - pub(crate) branch: BranchCols, pub(crate) s_main: MainCols, pub(crate) c_main: MainCols, - pub(crate) account_leaf: AccountLeafCols, - pub(crate) storage_leaf: StorageLeafCols, - pub(crate) denoter: DenoteCols, pub(crate) address_rlc: Column, pub(crate) managed_columns: Vec>, pub(crate) r: Vec>, @@ -141,10 +108,6 @@ impl MPTContext { ) -> Expression { self.expr(meta, rot)[range].rlc(&self.r) } - - pub(crate) fn is_account(&self, meta: &mut VirtualCells, rot_above: i32) -> Expression { - meta.query_advice(self.account_leaf.is_in_added_branch, Rotation(rot_above)) - } } /// Merkle Patricia Trie config. @@ -156,13 +119,8 @@ pub struct MPTConfig { pub(crate) inter_final_root: Column, pub(crate) value_prev: Column, pub(crate) value: Column, - pub(crate) accumulators: AccumulatorCols, - pub(crate) branch: BranchCols, pub(crate) s_main: MainCols, pub(crate) c_main: MainCols, - pub(crate) account_leaf: AccountLeafCols, - pub(crate) storage_leaf: StorageLeafCols, - pub(crate) denoter: DenoteCols, pub(crate) managed_columns: Vec>, pub(crate) memory: Memory, keccak_table: KeccakTable, @@ -177,6 +135,9 @@ pub struct MPTConfig { branch_config: BranchConfig, storage_config: StorageLeafConfig, account_config: AccountLeafConfig, + pub(crate) is_branch: Column, + pub(crate) is_account: Column, + pub(crate) is_storage: Column, pub(crate) randomness: F, pub(crate) mpt_table: MPTTable, cb: MPTConstraintBuilder, @@ -212,77 +173,26 @@ Also, for example, `modified_node` is given in branch init but needed to be set pub(crate) struct ProofValues { pub(crate) modified_node: u8, /* branch child that is being changed, it is the same in all * branch children rows */ - pub(crate) s_mod_node_hash_rlc: F, /* hash rlc of the modified_node for S proof, it is the - * same in all branch children rows */ - pub(crate) c_mod_node_hash_rlc: F, /* hash rlc of the modified_node for C proof, it is the - * same in all branch children rows */ - pub(crate) node_index: u8, // branch child index - pub(crate) acc_s: F, /* RLC accumulator for the whole node (taking into account all - * RLP bytes of the node) */ - pub(crate) acc_mult_s: F, // multiplier for acc_s - pub(crate) acc_account_s: F, - pub(crate) acc_mult_account_s: F, - pub(crate) acc_account_c: F, - pub(crate) acc_mult_account_c: F, - pub(crate) acc_nonce_balance_s: F, - pub(crate) acc_mult_nonce_balance_s: F, - pub(crate) acc_nonce_balance_c: F, - pub(crate) acc_mult_nonce_balance_c: F, pub(crate) acc_c: F, /* RLC accumulator for the whole node (taking into account all RLP * bytes of the node) */ pub(crate) acc_mult_c: F, // multiplier for acc_c pub(crate) key_rlc: F, /* used first for account address, then for storage key */ pub(crate) key_rlc_mult: F, // multiplier for key_rlc - pub(crate) extension_node_rlc: F, // RLC accumulator for extension node - pub(crate) extension_node_mult: F, // RLC multiplier for extension node pub(crate) key_rlc_prev: F, /* for leaf after placeholder extension/branch, we need * to go one level * back * to get previous key_rlc */ pub(crate) key_rlc_mult_prev: F, - pub(crate) nibbles_num_prev: usize, - pub(crate) mult_diff: F, /* power of randomness r: multiplier_curr = multiplier_prev * - * mult_diff */ - pub(crate) key_rlc_sel: bool, /* If true, nibble is multiplied by 16, otherwise by 1. */ pub(crate) is_branch_s_placeholder: bool, // whether S branch is just a placeholder pub(crate) is_branch_c_placeholder: bool, // whether C branch is just a placeholder pub(crate) drifted_pos: u8, /* needed when leaf turned into branch and leaf moves into a * branch where * it's at drifted_pos position */ - pub(crate) rlp_len_rem_s: i32, /* branch RLP length remainder, in each branch children row - * this value - * is subtracted by the number of RLP bytes in - * this row (1 or 33) */ - pub(crate) rlp_len_rem_c: i32, - pub(crate) is_extension_node: bool, pub(crate) is_even: bool, pub(crate) is_odd: bool, - pub(crate) is_short: bool, - pub(crate) is_short_c1: bool, - pub(crate) is_long: bool, - pub(crate) rlc1: F, - pub(crate) rlc2: F, - pub(crate) storage_root_value_s: F, - pub(crate) storage_root_value_c: F, - pub(crate) codehash_value_s: F, pub(crate) before_account_leaf: bool, pub(crate) nibbles_num: usize, - pub(crate) is_hashed_s: bool, - pub(crate) is_hashed_c: bool, - - pub(crate) ext_is_hashed_s: bool, - pub(crate) ext_is_hashed_c: bool, - - pub(crate) parent_rlc_s: F, - pub(crate) parent_is_hashed_s: bool, - - pub(crate) parent_rlc_c: F, - pub(crate) parent_is_hashed_c: bool, - - pub(crate) is_placeholder_leaf_s: bool, - pub(crate) is_placeholder_leaf_c: bool, - pub(crate) memory: Memory, } @@ -292,10 +202,7 @@ impl ProofValues { memory: memory.clone(), key_rlc_mult: F::one(), key_rlc_mult_prev: F::one(), - mult_diff: F::one(), - key_rlc_sel: true, before_account_leaf: true, - extension_node_mult: F::one(), ..Default::default() } } @@ -323,12 +230,13 @@ impl MPTConfig { let value_prev = meta.advice_column(); let value = meta.advice_column(); + let is_branch = meta.advice_column(); + let is_account = meta.advice_column(); + let is_storage = meta.advice_column(); + let position_cols = PositionCols::new(meta); let proof_type = ProofTypeCols::new(meta); - let account_leaf = AccountLeafCols::new(meta); - let storage_leaf = StorageLeafCols::new(meta); - let branch = BranchCols::new(meta); let s_main = MainCols::new(meta); let c_main = MainCols::new(meta); @@ -349,42 +257,13 @@ impl MPTConfig { memory.allocate(meta, parent_memory(false)); memory.allocate(meta, parent_memory(true)); - /* - Note: `key_rlc_mult` would not be needed if we would have - big endian instead of little endian. However, then it would be much more - difficult to handle the accumulator when we iterate over the key. - At some point (but we do not know this point at compile time), the key ends - and from there on the values in the row need to be 0s. - However, if we are computing the RLC using little endian: - `rlc = rlc + row[i] * r`, - `rlc` will stay the same once r[i] = 0. - If big endian would be used: - `rlc = rlc * r + row[i]`, - `rlc` would be multiplied by `r` when `row[i] = 0`. - - However, we need to ensure there are truly 0s after the RLP stream ends, this is done - by `key_len_lookup` calls. - */ - - let accumulators = AccumulatorCols::new(meta); - - /* - Note: `acc_s.mult` and `acc_c.mult` would not be needed if we would have - big endian instead of little endian. However, then it would be much more - difficult to handle the accumulator when we iterate over the row. - For example, big endian would mean to compute `acc = acc * mult_r + row[i]`, - but we do not want `acc` to be multiplied by `mult_r` when `row[i] = 0` where - the stream already ended and 0s are only to fulfill the row. - */ - - let denoter = DenoteCols::new(meta); - let address_rlc = meta.advice_column(); + let key_rlc = meta.advice_column(); let mpt_table = MPTTable { address_rlc, proof_type: proof_type.proof_type, - key_rlc: accumulators.key.mult, + key_rlc, value_prev, value, root_prev: inter_start_root, @@ -399,13 +278,8 @@ impl MPTConfig { inter_final_root: inter_final_root.clone(), value_prev: value_prev.clone(), value: value.clone(), - branch: branch.clone(), s_main: s_main.clone(), c_main: c_main.clone(), - account_leaf: account_leaf.clone(), - storage_leaf: storage_leaf.clone(), - accumulators: accumulators.clone(), - denoter: denoter.clone(), address_rlc: address_rlc.clone(), managed_columns: managed_columns.clone(), r: extend_rand(&power_of_randomness), @@ -414,7 +288,7 @@ impl MPTConfig { let mut row_config: Option> = None; - let mut cb = MPTConstraintBuilder::new(17, None); + let mut cb = MPTConstraintBuilder::new(33, None); meta.create_gate("MPT", |meta| { let cell_manager = CellManager::new(meta, &ctx.managed_columns); cb.base.set_cell_manager(cell_manager); @@ -431,8 +305,7 @@ impl MPTConfig { KeyData::store_initial_values(&mut cb.base, &ctx.memory[key_memory(false)]); }} // Initial parent values - ifx!{f!(position_cols.q_enable), not!(a!(ctx.position_cols.not_first_level)), - a!(branch.is_init) + a!(storage_leaf.is_s_key) + a!(account_leaf.is_key_s) => { + ifx!{f!(position_cols.q_enable), not!(a!(ctx.position_cols.not_first_level)), a!(is_branch, 1) + a!(is_storage) + a!(is_account, 1) => { for is_s in [true, false] { let root = a!(ctx.inter_root(is_s)); ParentData::store(&mut cb.base, &ctx.memory[parent_memory(is_s)], [root.expr(), true.expr(), false.expr(), root.expr()]); @@ -445,16 +318,14 @@ impl MPTConfig { let account_config; ifx!{f!(position_cols.q_enable) => { matchx! { - and::expr(&[a!(branch.is_init, -1), f!(position_cols.q_not_first)]) => { + a!(is_branch) => { branch_config = BranchConfig::configure(meta, &mut cb, ctx.clone()); }, - a!(account_leaf.is_key_c) => { + a!(is_account) => { account_config = AccountLeafConfig::configure(meta, &mut cb, ctx.clone()); }, - a!(storage_leaf.is_s_key) => { - ifx!{f!(position_cols.q_not_first), a!(position_cols.not_first_level) => { - storage_config = StorageLeafConfig::configure(meta, &mut cb, ctx.clone()); - }}; + a!(is_storage) => { + storage_config = StorageLeafConfig::configure(meta, &mut cb, ctx.clone()); }, _ => (), } @@ -568,19 +439,17 @@ impl MPTConfig { let row_config = row_config.unwrap(); let randomness = F::zero(); MPTConfig { + is_branch, + is_account, + is_storage, proof_type, position_cols, inter_start_root, inter_final_root, value_prev, value, - branch, s_main, c_main, - account_leaf, - storage_leaf, - accumulators, - denoter, managed_columns, memory, keccak_table, @@ -595,179 +464,6 @@ impl MPTConfig { } } - pub(crate) fn compute_key_rlc( - &self, - row: &[u8], - key_rlc: &mut F, - key_rlc_mult: &mut F, - start: usize, - ) { - let even_num_of_nibbles = row[start + 1] == 32; - // If odd number of nibbles, we have nibble+48 in s_advices[0]. - if !even_num_of_nibbles { - *key_rlc += F::from((row[start + 1] - 48) as u64) * *key_rlc_mult; - *key_rlc_mult *= self.randomness; - - let len = row[start] as usize - 128; - self.compute_acc_and_mult( - row, - key_rlc, - key_rlc_mult, - start + 2, - len - 1, // -1 because one byte was already considered - ); - } else { - let len = row[start] as usize - 128; - self.compute_acc_and_mult( - row, - key_rlc, - key_rlc_mult, - start + 2, - len - 1, /* -1 because the first byte doesn't - * contain any key byte (it's just 32) */ - ); - } - } - - pub(crate) fn compute_acc_and_mult( - &self, - row: &[u8], - acc: &mut F, - mult: &mut F, - start: usize, - len: usize, - ) { - for i in 0..len { - *acc += F::from(row[start + i] as u64) * *mult; - *mult *= self.randomness; - } - } - - pub(crate) fn compute_rlc_and_assign( - &self, - region: &mut Region<'_, F>, - row: &[u8], - pv: &mut ProofValues, - offset: usize, - s_start_len: (usize, usize), - c_start_len: (usize, usize), - ) -> Result<(), Error> { - self.compute_acc_and_mult( - row, - &mut pv.rlc1, - &mut F::one(), - s_start_len.0, - s_start_len.1, - ); - region.assign_advice( - || "assign s_mod_node_hash_rlc".to_string(), - self.accumulators.s_mod_node_rlc, - offset, - || Value::known(pv.rlc1), - )?; - - self.compute_acc_and_mult( - row, - &mut pv.rlc2, - &mut F::one(), - c_start_len.0, - c_start_len.1, - ); - region.assign_advice( - || "assign c_mod_node_hash_rlc".to_string(), - self.accumulators.c_mod_node_rlc, - offset, - || Value::known(pv.rlc2), - )?; - - Ok(()) - } - - pub(crate) fn assign_acc( - &self, - region: &mut Region<'_, F>, - acc_s: F, - acc_mult_s: F, - acc_c: F, - acc_mult_c: F, - offset: usize, - ) -> Result<(), Error> { - region.assign_advice( - || "assign acc_s".to_string(), - self.accumulators.acc_s.rlc, - offset, - || Value::known(acc_s), - )?; - - region.assign_advice( - || "assign acc_mult_s".to_string(), - self.accumulators.acc_s.mult, - offset, - || Value::known(acc_mult_s), - )?; - - region.assign_advice( - || "assign acc_c".to_string(), - self.accumulators.acc_c.rlc, - offset, - || Value::known(acc_c), - )?; - - region.assign_advice( - || "assign acc_mult_c".to_string(), - self.accumulators.acc_c.mult, - offset, - || Value::known(acc_mult_c), - )?; - - Ok(()) - } - - /* - assign_long_short is used for setting flags for storage leaf and storage value. - For storage leaf, it sets whether it is short (one RLP byte) or long (two RLP bytes) - or last level (no nibbles in leaf, all nibbles in the path above the leaf) or one nibble. - Note that last_level and one_nibble imply having only one RLP byte. - - For storage value, it sets whether it is short or long (value having more than one byte). - */ - pub(crate) fn assign_long_short( - &self, - region: &mut Region<'_, F>, - typ: &str, - offset: usize, - ) -> Result<(), Error> { - let mut flag1 = false; - let mut flag2 = false; - // for one_nibble, it is both 0 - if typ == "long" { - flag1 = true; - } else if typ == "short" { - flag2 = true; - } else if typ == "last_level" { - flag1 = true; - flag2 = true; - } - region - .assign_advice( - || "assign s_modified_node_rlc".to_string(), - self.accumulators.s_mod_node_rlc, - offset, - || Value::known(F::from(flag1 as u64)), - ) - .ok(); - region - .assign_advice( - || "assign c_modified_node_rlc".to_string(), - self.accumulators.c_mod_node_rlc, - offset, - || Value::known(F::from(flag2 as u64)), - ) - .ok(); - - Ok(()) - } - /// Make the assignments to the MPTCircuit pub fn assign( &mut self, @@ -778,7 +474,54 @@ impl MPTConfig { self.randomness = randomness; let mut height = 0; + // TODO(Brecht): change this on the witness generation side let mut memory = self.memory.clone(); + for (_, row) in witness + .iter_mut() + .filter(|r| r.get_type() != MptWitnessRowType::HashToBeComputed) + .enumerate() + { + if row.get_type() == MptWitnessRowType::BranchChild { + //println!("- {:?}", row.bytes); + let mut child_s_bytes = row.bytes[0..34].to_owned(); + if child_s_bytes[1] == 160 { + child_s_bytes[0] = 0; + child_s_bytes.rotate_left(1); + } else { + child_s_bytes[0] = 0; + child_s_bytes[1] = 0; + child_s_bytes.rotate_left(2); + }; + + let mut child_c_bytes = row.bytes[34..68].to_owned(); + if child_c_bytes[1] == 160 { + child_c_bytes[0] = 0; + child_c_bytes.rotate_left(1); + } else { + child_c_bytes[0] = 0; + child_c_bytes[1] = 0; + child_c_bytes.rotate_left(2); + }; + + row.bytes = [child_s_bytes.clone(), child_c_bytes.clone(), row.bytes[68..].to_owned()].concat(); + //println!("+ {:?}", row.bytes); + } + + if row.get_type() == MptWitnessRowType::ExtensionNodeS || row.get_type() == MptWitnessRowType::ExtensionNodeC { + //println!("- {:?}", row.bytes); + let mut value_bytes = row.bytes[34..68].to_owned(); + if value_bytes[1] == 160 { + value_bytes[0] = 0; + value_bytes.rotate_left(1); + } else { + value_bytes[0] = 0; + value_bytes[1] = 0; + value_bytes.rotate_left(2); + }; + row.bytes = [row.bytes[0..34].to_owned(), value_bytes.clone(), row.bytes[68..].to_owned()].concat(); + //println!("+ {:?}", row.bytes); + } + } layouter .assign_region( @@ -883,85 +626,22 @@ impl MPTConfig { row.clone() }; - // leaf s or leaf c or leaf key s or leaf key c - let mut account_leaf = AccountLeaf::default(); - let mut storage_leaf = StorageLeaf::default(); - let mut branch = Branch::default(); - - if row.get_type() == MptWitnessRowType::StorageLeafSKey { - storage_leaf.is_s_key = true; - } else if row.get_type() == MptWitnessRowType::StorageLeafCKey { - storage_leaf.is_c_key = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafKeyS { - account_leaf.is_key_s = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { - account_leaf.is_key_c = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceS { - account_leaf.is_nonce_balance_s = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafNonceBalanceC { - account_leaf.is_nonce_balance_c = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafRootCodehashS { - account_leaf.is_storage_codehash_s = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafRootCodehashC { - account_leaf.is_storage_codehash_c = true; - } else if row.get_type() == MptWitnessRowType::AccountLeafNeighbouringLeaf { - account_leaf.is_in_added_branch = true; + if row.get_type() == MptWitnessRowType::AccountLeafNeighbouringLeaf { pv.key_rlc = F::zero(); // account address until here, storage key from here on pv.key_rlc_mult = F::one(); pv.key_rlc_prev = F::zero(); pv.key_rlc_mult_prev = F::one(); - pv.nibbles_num_prev = 0; - pv.key_rlc_sel = true; pv.nibbles_num = 0; - } else if row.get_type() == MptWitnessRowType::StorageLeafSValue { - storage_leaf.is_s_value = true; - } else if row.get_type() == MptWitnessRowType::StorageLeafCValue { - storage_leaf.is_c_value = true; - } else if row.get_type() == MptWitnessRowType::NeighbouringStorageLeaf { - storage_leaf.is_in_added_branch = true; - } else if row.get_type() == MptWitnessRowType::StorageNonExisting { - storage_leaf.is_non_existing = true; - } else if row.get_type() == MptWitnessRowType::ExtensionNodeS { - branch.is_extension_node_s = true; - } else if row.get_type() == MptWitnessRowType::ExtensionNodeC { - branch.is_extension_node_c = true; - } else if row.get_type() == MptWitnessRowType::AccountNonExisting { - account_leaf.is_non_existing_account_row = true; - } - - /*if row.not_first_level() == 0 && (row.get_type() == MptWitnessRowType::InitBranch || - row.get_type() == MptWitnessRowType::StorageLeafSKey || - row.get_type() == MptWitnessRowType::AccountLeafKeyC) { - pv.memory[parent_memory(true)].witness_store( - offset, - &[row.s_root_bytes_rlc(self.randomness), true.scalar(), false.scalar()], - ); - pv.memory[parent_memory(false)].witness_store( - offset, - &[row.c_root_bytes_rlc(self.randomness), true.scalar(), false.scalar()], - ); - println!("set new parent: {}", offset); - }*/ - - if !(row.get_type() == MptWitnessRowType::InitBranch - || row.get_type() == MptWitnessRowType::BranchChild) - { - witness[idx].assign( - &mut region, - self, - account_leaf, - storage_leaf, - branch, - offset, - )?; } if offset > 0 && prev_row.get_type() == MptWitnessRowType::InitBranch { //println!("{}: branch", offset); + assign!(region, (self.is_branch, offset) => 1.scalar()).ok(); self.branch_config .assign(&mut region, witness, self, &mut pv, offset) .ok(); } else if row.get_type() == MptWitnessRowType::StorageLeafSKey { + assign!(region, (self.is_storage, offset) => 1.scalar()).ok(); //println!("{}: storage", offset); self.storage_config.assign( &mut region, @@ -971,6 +651,7 @@ impl MPTConfig { offset, )?; } else if row.get_type() == MptWitnessRowType::AccountLeafKeyC { + assign!(region, (self.is_account, offset) => 1.scalar()).ok(); //println!("{}: account", offset); self.account_config.assign( &mut region, @@ -981,6 +662,13 @@ impl MPTConfig { )?; } + // assign bytes + witness[idx].assign( + &mut region, + self, + offset, + )?; + offset += 1; } diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index 391bf27aba..ed67cdde06 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -1,12 +1,10 @@ use eth_types::Field; use gadgets::util::Scalar; -use halo2_proofs::plonk::{Advice, Column, ConstraintSystem}; use halo2_proofs::{ circuit::{Region, Value}, plonk::{Error, VirtualCells}, poly::Rotation, }; -use std::marker::PhantomData; use crate::circuit_tools::constraint_builder::RLCChainable; use crate::circuit_tools::gadgets::RequireNotZeroGadget; @@ -34,47 +32,6 @@ use super::{ }, }; -#[derive(Clone, Debug)] -pub(crate) struct AccountLeafCols { - pub(crate) is_key_s: Column, - pub(crate) is_key_c: Column, - pub(crate) is_non_existing: Column, - pub(crate) is_nonce_balance_s: Column, - pub(crate) is_nonce_balance_c: Column, - pub(crate) is_storage_codehash_s: Column, - pub(crate) is_storage_codehash_c: Column, - pub(crate) is_in_added_branch: Column, - _marker: PhantomData, -} - -impl AccountLeafCols { - pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { - Self { - is_key_s: meta.advice_column(), - is_key_c: meta.advice_column(), - is_non_existing: meta.advice_column(), - is_nonce_balance_s: meta.advice_column(), - is_nonce_balance_c: meta.advice_column(), - is_storage_codehash_s: meta.advice_column(), - is_storage_codehash_c: meta.advice_column(), - is_in_added_branch: meta.advice_column(), - _marker: PhantomData, - } - } -} - -#[derive(Default, Debug)] -pub(crate) struct AccountLeaf { - pub(crate) is_key_s: bool, - pub(crate) is_key_c: bool, - pub(crate) is_non_existing_account_row: bool, - pub(crate) is_nonce_balance_s: bool, - pub(crate) is_nonce_balance_c: bool, - pub(crate) is_storage_codehash_s: bool, - pub(crate) is_storage_codehash_c: bool, - pub(crate) is_in_added_branch: bool, -} - #[derive(Clone, Debug, Default)] pub(crate) struct AccountLeafConfig { key_data: [KeyData; 2], @@ -238,7 +195,7 @@ impl AccountLeafConfig { // Key key_rlc[is_s.idx()] = key_data.rlc.expr() - + rlp_key.key_rlc( + + rlp_key.leaf_key_rlc( &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), @@ -323,7 +280,7 @@ impl AccountLeafConfig { // Calculate the drifted key RLC let drifted_key_rlc = key_rlc_prev + drifted_nibble_rlc(&mut cb.base, placeholder_nibble.expr(), key_mult_prev.expr(), placeholder_is_odd.expr()) + - config.drifted_rlp_key.key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), false, &r); + config.drifted_rlp_key.leaf_key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), false, &r); // RLC bytes zero check cb.set_length(config.drifted_rlp_key.num_bytes_on_key_row()); @@ -351,7 +308,7 @@ impl AccountLeafConfig { // The key of the drifted leaf needs to match the key of the leaf require!(key_rlc => drifted_key_rlc); // The drifted leaf needs to be stored in the branch at `drifted_index`. - // TODO(Brecht): re-enable after witness change + // TODO(Brecht): 53 "src/mpt_circuit/tests/AccountAddPlaceholderExtension.json" //require!((1, drifted_rlc, config.drifted_rlp_key.num_bytes(), mod_hash) => @"keccak"); }} }} @@ -365,7 +322,7 @@ impl AccountLeafConfig { ifx! {config.is_wrong_leaf => { // Calculate the key config.wrong_rlp_key = LeafKeyGadget::construct(&mut cb.base, &wrong_bytes); - let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.key_rlc( + let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.leaf_key_rlc( &mut cb.base, config.key_data_w.mult.expr(), config.key_data_w.is_odd.expr(), @@ -590,7 +547,7 @@ impl AccountLeafConfig { (pv.key_rlc, pv.key_rlc_mult) }; (key_rlc[is_s.idx()], _) = - rlp_key_witness.key_rlc(key_rlc_new, key_rlc_mult, ctx.randomness); + rlp_key_witness.leaf_key_rlc(key_rlc_new, key_rlc_mult, ctx.randomness); let mut key_mult = F::one(); for _ in 0..rlp_key_witness.num_bytes_on_key_row() { @@ -666,7 +623,7 @@ impl AccountLeafConfig { let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes)?; let (key_rlc_wrong, _) = - wrong_witness.key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.randomness); + wrong_witness.leaf_key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.randomness); let address_rlc = bytes_into_rlc(row.address_bytes(), ctx.randomness); self.check_is_wrong_leaf.assign( diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index 7664d25481..2b84a7bd24 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -1,105 +1,73 @@ use eth_types::Field; +use gadgets::util::Scalar; use halo2_proofs::{ - circuit::{Region, Value}, - plonk::{Advice, Column, ConstraintSystem, Error, VirtualCells}, - poly::Rotation, + circuit::{Region}, + plonk::{Error, VirtualCells, Expression}, }; -use std::marker::PhantomData; use super::{ - helpers::MPTConstraintBuilder, + helpers::{MPTConstraintBuilder, RLPListGadget, RLPItemGadget, LeafKeyGadget, RLPItemWitness}, param::{ - ARITY, IS_C_BRANCH_NON_HASHED_POS, IS_C_EXT_NODE_NON_HASHED_POS, - IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_NODE_NON_HASHED_POS, + ARITY, IS_BRANCH_C_PLACEHOLDER_POS, }, MPTContext, }; use crate::{ circuit, circuit_tools::{ - cell_manager::{CellManager, DataTransition}, - constraint_builder::{RLCChainable, RLCable}, + cell_manager::{Cell}, + constraint_builder::{RLCChainable}, gadgets::{IsEqualGadget, LtGadget, IsZeroGadget}, }, - mpt_circuit::account_leaf::AccountLeaf, - mpt_circuit::helpers::bytes_into_rlc, mpt_circuit::{ helpers::{ - contains_placeholder_leaf, get_num_nibbles, key_memory, parent_memory, Indexable, + get_num_nibbles, key_memory, parent_memory, Indexable, KeyData, ParentData, }, - param::{RLP_LIST_LONG, RLP_NIL}, - storage_leaf::StorageLeaf, + param::{RLP_NIL}, FixedTableTag, }, mpt_circuit::{ - helpers::{BranchChildInfo, BranchNodeInfo}, param::{ - BRANCH_0_C_START, BRANCH_0_KEY_POS, BRANCH_0_S_START, BRANCH_ROWS_NUM, C_RLP_START, - C_START, DRIFTED_POS, HASH_WIDTH, IS_BRANCH_C_PLACEHOLDER_POS, + BRANCH_0_KEY_POS, + DRIFTED_POS, HASH_WIDTH, IS_BRANCH_S_PLACEHOLDER_POS, IS_EXT_LONG_EVEN_C16_POS, IS_EXT_LONG_EVEN_C1_POS, IS_EXT_LONG_ODD_C16_POS, IS_EXT_LONG_ODD_C1_POS, IS_EXT_SHORT_C16_POS, - IS_EXT_SHORT_C1_POS, NIBBLES_COUNTER_POS, RLP_NUM, S_RLP_START, S_START, + IS_EXT_SHORT_C1_POS, }, }, - mpt_circuit::{param::RLP_HASH_VALUE, witness_row::MptWitnessRow}, + mpt_circuit::{witness_row::MptWitnessRow}, mpt_circuit::{MPTConfig, ProofValues}, }; -#[derive(Default, Debug)] -pub(crate) struct Branch { - pub(crate) is_branch_init: bool, - pub(crate) is_branch_child: bool, - pub(crate) is_last_branch_child: bool, - pub(crate) node_index: u8, - pub(crate) modified_index: u8, - pub(crate) drifted_index: u8, - pub(crate) is_extension_node_s: bool, - pub(crate) is_extension_node_c: bool, -} - -#[derive(Clone, Copy, Debug)] -pub(crate) struct BranchCols { - pub(crate) is_init: Column, - pub(crate) is_child: Column, - pub(crate) is_last_child: Column, - pub(crate) node_index: Column, - pub(crate) is_modified: Column, // whether this branch node is modified - pub(crate) modified_index: Column, // index of the modified node - pub(crate) is_drifted: Column, // needed when leaf is turned into branch - pub(crate) drifted_index: Column, /* needed when leaf is turned into branch - first - * nibble of - * the key stored in a leaf (because the existing - * leaf will - * jump to this position in added branch) */ - pub(crate) is_extension_node_s: Column, /* contains extension node key (s_advices) - * and hash of - * the branch (c_advices) */ - pub(crate) is_extension_node_c: Column, - _marker: PhantomData, -} - -impl BranchCols { - pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { - Self { - is_init: meta.advice_column(), - is_child: meta.advice_column(), - is_last_child: meta.advice_column(), - node_index: meta.advice_column(), - is_modified: meta.advice_column(), - modified_index: meta.advice_column(), - is_drifted: meta.advice_column(), - drifted_index: meta.advice_column(), - is_extension_node_s: meta.advice_column(), - is_extension_node_c: meta.advice_column(), - _marker: PhantomData, - } - } +#[derive(Clone, Debug, Default)] +pub(crate) struct BranchChildConfig { + rlp: RLPItemGadget, + mult: Cell, + rlc_branch: Cell, + is_hashed: IsEqualGadget, } #[derive(Clone, Debug, Default)] pub(crate) struct BranchConfig { key_data: KeyData, parent_data: [ParentData; 2], + rlp_list: [RLPListGadget; 2], + branches: [[BranchChildConfig; ARITY]; 2], + is_modified: [Cell; ARITY], + is_drifted: [Cell; ARITY], + mod_branch_rlc: [Cell; 2], + mod_branch_is_hashed: [Cell; 2], + mod_branch_is_empty: [IsZeroGadget; 2], + is_not_hashed: [LtGadget; 2], + is_placeholder: [Cell; 2], + + is_extension: Cell, + ext_rlp_key: LeafKeyGadget, + ext_rlp_value: [RLPItemGadget; 2], + ext_mult_key: Cell, + ext_is_not_hashed: LtGadget, + ext_is_key_part_odd: Cell, + ext_mult_key_len: Cell, } impl BranchConfig { @@ -108,265 +76,244 @@ impl BranchConfig { cb: &mut MPTConstraintBuilder, ctx: MPTContext, ) -> Self { - let position_cols = ctx.position_cols; - let s_main = ctx.s_main; - let c_main = ctx.c_main; - let accs = ctx.accumulators; let r = ctx.r.clone(); cb.base.cell_manager.as_mut().unwrap().reset(); let mut config = BranchConfig::default(); circuit!([meta, cb.base], { - let mut offset = -1; - let rot_branch_init = offset; - + let offset = -1; + + // Data + let rlp_bytes = [ctx.expr(meta, -1)[4..7].to_owned(), ctx.expr(meta, -1)[7..10].to_owned()]; + let branch_bytes: [[Vec>; ARITY]; 2] = [ + array_init::array_init(|i| ctx.expr(meta, i as i32)[0..34].to_owned()), + array_init::array_init(|i| ctx.expr(meta, i as i32)[34..68].to_owned()), + ]; + let ext_key_bytes: [Vec>; 2] = [ + ctx.expr(meta, offset + 17)[0..34].to_owned(), + ctx.expr(meta, offset + 18)[0..34].to_owned(), + ]; + let ext_value_bytes: [Vec>; 2] = [ + ctx.expr(meta, offset + 17)[34..68].to_owned(), + ctx.expr(meta, offset + 18)[34..68].to_owned(), + ]; + + // General inputs + config.is_extension = cb.base.query_cell(); for is_s in [true, false] { - let branch = BranchNodeInfo::new(meta, ctx.clone(), is_s, offset); - // Selector constraints - branch.init_selector_checks(meta, &mut cb.base); - // Check that stored rlc/mult values are correct. - let rlp = branch.rlp_bytes(meta); - let (rlc, mult) = matchx! { - branch.is_branch_short(meta) => (rlp[..1].rlc(&r), r[0].expr()), - branch.is_branch_long(meta) => (rlp[..2].rlc(&r), r[1].expr()), - branch.is_branch_very_long(meta) => (rlp[..3].rlc(&r), r[2].expr()), - }; - require!(a!(accs.acc(is_s).rlc, offset) => rlc); - require!(a!(accs.acc(is_s).mult, offset) => mult); + config.is_placeholder[is_s.idx()] = cb.base.query_cell(); + require!(config.is_placeholder[is_s.idx()] => bool); } - // These selectors are only stored in branch init rows - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, offset); - // Boolean checks - for selector in [ - branch.is_placeholder_s(), - branch.is_placeholder_c(), - branch.is_not_hashed_s(), - branch.is_not_hashed_c(), - ] { - require!(selector => bool); + // Load the last key values + config.key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 0.expr()); + // Load the parent values + for is_s in [true, false] { + config.parent_data[is_s.idx()] = ParentData::load( + "branch load", + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + 0.expr(), + ); } - // Update the nibble counter - ifx! {not!(branch.is_extension()) => { - let nibbles_counter_prev = ifx!{not!(branch.is_at_tree_top(meta)) => { - branch.nibbles_counter().prev() - }}; - require!(branch.nibbles_counter() => nibbles_counter_prev + 1.expr()); - }} - offset += 1; - - for node_index in 0..ARITY { - // Keep track of how many branch bytes we've processed. + /* Extension */ + + let ( + num_nibbles, + is_key_odd, + key_rlc_post_ext, + key_mult_post_ext, + is_root_s, + is_root_c, + parent_rlc_s, + parent_rlc_c, + ) = ifx! {config.is_extension => { + config.ext_rlp_key = LeafKeyGadget::construct(&mut cb.base, &ext_key_bytes[0]); + config.ext_is_key_part_odd = cb.base.query_cell(); + + // We need to check that the nibbles we stored in s are between 0 and 15. + cb.set_range_s(FixedTableTag::RangeKeyLen16.expr()); + + let mut ext_branch_rlp_rlc = vec![0.expr(); 2]; for is_s in [true, false] { - let child = BranchChildInfo::new(meta, ctx.clone(), is_s, offset); - // Get the number of bytes used by the current branch. - let num_bytes = child.num_bytes(meta); - // Fetch the number of bytes left from the previous row. - // TODO(Brecht): just store it in branch init in its own column. - let num_bytes_left = if node_index == 0 { - // Length of full branch - BranchNodeInfo::new(meta, ctx.clone(), is_s, offset - 1).len(meta) - } else { - // Simply stored in rlp1 otherwise - a!(ctx.main(is_s).rlp1, offset - 1) - }; - // Update number of bytes left - require!(a!(ctx.main(is_s).rlp1, offset) => num_bytes_left - num_bytes.expr()); - // In the final branch child `rlp1` needs to be 1 (because RLP length - // specifies also ValueNode which occupies 1 byte). - // TODO: ValueNode - if node_index == ARITY - 1 { - require!(a!(ctx.main(is_s).rlp1, offset) => 1); + config.ext_rlp_value[is_s.idx()] = RLPItemGadget::construct(&mut cb.base, &ext_value_bytes[is_s.idx()]); + + // In C we have nibbles, we check below only for S. + if is_s { + // RLP encoding checks: [key, branch] + // Verify that the lenghts are consistent. + require!(config.ext_rlp_key.len() => config.ext_rlp_key.key_num_bytes() + config.ext_rlp_value[is_s.idx()].num_bytes()); + + // Update the multiplier with the number of bytes on the first row + config.ext_mult_key = cb.base.query_cell(); + require!((FixedTableTag::RMult, config.ext_rlp_key.num_bytes_on_key_row(), config.ext_mult_key.expr()) => @"fixed"); } - // RLC - { - let main = ctx.main(is_s); - let branch = ctx.accumulators.acc(is_s); - let mult_diff = ctx.accumulators.node_mult_diff(is_s); - - let child = BranchChildInfo::new(meta, ctx.clone(), is_s, offset); - let branch_mult = - DataTransition::new_with_rot(meta, branch.mult, offset - 1, offset); - let branch_rlc = - DataTransition::new_with_rot(meta, branch.rlc, offset - 1, offset); - // Calculate the RLC - let rlc = child.rlc(meta, &mut cb.base); - require!(branch_rlc => (branch_rlc.prev(), branch_mult.prev()).rlc_chain(rlc)); - require!(branch_mult => branch_mult.prev() * a!(mult_diff, offset)); - // RLC bytes zero check - //cb.set_length_sc(is_s, child.num_bytes_on_row(meta)); - // We need to check that the multiplier changes according to `num_bytes` and - // update it. - require!((FixedTableTag::RMult, child.num_bytes(meta), a!(mult_diff, offset)) => @format!("fixed")); - // When a value is being added (and reverse situation when deleted) to the - // trie and there is no other leaf at the position - // where it is to be added, we have empty branch - // child in `S` proof and hash of a newly added leaf - // at the parallel position in `C` proof. That means - // we have empty node in `S` proof at `modified_node`. - // When this happens, we denote this situation by having a placeholder leaf. - // In this case we need to make sure the node is seen as empty. - ifx! {a!(ctx.branch.is_modified, offset), contains_placeholder_leaf(meta, ctx.clone(), is_s, offset) => { - require!(child.is_hashed(meta) => true); - require!(a!(main.rlp2, offset) => 0); + // Extension node RLC + let ext_node_rlc = (config.ext_rlp_key.rlc(&r), config.ext_mult_key.expr()).rlc_chain( + config.ext_rlp_value[is_s.idx()].rlc_rlp(&mut cb.base, &r) + ); + // Branch value data zero check + cb.set_length_c(config.ext_rlp_value[is_s.idx()].num_bytes()); + + // The branch expected in the extension node + ext_branch_rlp_rlc[is_s.idx()] = config.ext_rlp_value[is_s.idx()].rlc_rlp(&mut cb.base, &r); + + // Check if the extension node is in its parent. + let (rlc, num_bytes, is_not_hashed) = { + if is_s { + config.ext_is_not_hashed = LtGadget::construct(&mut cb.base, config.ext_rlp_key.num_bytes(), HASH_WIDTH.expr()); + } + (ext_node_rlc.expr(), config.ext_rlp_key.num_bytes(), config.ext_is_not_hashed.expr()) + }; + // TODO(Brecht): why not if it's a placeholder? + ifx! {not!(config.is_placeholder[is_s.idx()]) => { + ifx!{or::expr(&[config.parent_data[is_s.idx()].is_root.expr(), not!(is_not_hashed)]) => { + // Hashed branch hash in parent branch + require!((1, rlc, num_bytes, config.parent_data[is_s.idx()].rlc) => @"keccak"); + } elsex { + // Non-hashed branch hash in parent branch + require!(rlc => config.parent_data[is_s.idx()].rlc); }} - } + }} } - // Check that `is_modified` is enabled for the correct branch child. - ifx! {a!(ctx.branch.is_modified, offset) => { - require!(a!(ctx.branch.node_index, offset) => a!(ctx.branch.modified_index, offset)); - }} - // Check that `is_drifted` is enabled for the correct branch child. - ifx! {a!(ctx.branch.is_drifted, offset) => { - require!(a!(ctx.branch.node_index, offset) => a!(ctx.branch.drifted_index, offset)); - }} + // Extension key zero check + cb.set_length(config.ext_rlp_key.num_bytes_on_key_row()); - // Check values that need to remain the same for all branch children. - /*ifx!{a!(branch.node_index, offset) => { - // `modified_index` needs to be the same for all branch children. - require!(modified_index => modified_index.prev()); - // `drifted_index` needs to be the same for all branch children. - require!(drifted_index => drifted_index.prev()); - for is_s in [true, false] { - // `mod_node_hash_rlc` the same for all branch children - let mod_node_hash_rlc = ctx.accumulators.mod_node_rlc(is_s); - require!(a!(mod_node_hash_rlc) => a!(mod_node_hash_rlc, -1)); - // `contains_placeholder_leaf` the same for all branch children - require!(contains_placeholder_leaf(meta, ctx.clone(), is_s, 0) - => contains_placeholder_leaf(meta, ctx.clone(), is_s, -1)); - } - }}*/ - - // If we have a branch child, we can only have branch child or branch init in - // the previous row. - /*require!(or::expr([is_branch_child.prev(), is_branch_init.prev()]) => true); - // When `node_index` != 0 - ifx!{node_index => { - // `node_index` increases by 1 for each branch child. - require!(node_index => node_index.prev() + 1.expr()); - }}*/ + // Calculate the number of bytes + let key_len = config.ext_rlp_key.key_len(); + // Calculate the number of nibbles + let num_nibbles = get_num_nibbles(key_len.expr(), config.ext_is_key_part_odd.expr()); + // Make sure the nibble counter is updated correctly + let num_nibbles = config.key_data.num_nibbles.expr() + num_nibbles.expr(); - // We need to ensure that the only change in `S` and `C` proof occurs - // at `modified_index` so that only a single change can be done. - // We check `s_main.rlp = c_main.rlp` everywhere except at `modified_index`. - // (except rlp1, rlp1 is used to keep track of number of bytes processed). - /*let not_at_modification = node_index.expr() - modified_index.expr(); - ifx!{not_at_modification => { - for (s_byte, c_byte) in s_main.rlp_bytes().iter().skip(1) - .zip(c_main.rlp_bytes().iter().skip(1)) - { - require!(a!(s_byte) => a!(c_byte)); - } - }}*/ - - // Make sure `is_branch_child`, `node_index` and `is_last_child` are set - // correctly. - /*ifx!{is_branch_init.prev() => { - // First child when previous row is a branch init row - require!(is_branch_child => true); - require!(node_index => 0); + // We need to take account the nibbles of the extension node. + // The parity alternates when there's an even number of nibbles, remains the same otherwise + let is_key_odd = ifx!{config.ext_is_key_part_odd => { + not!(config.key_data.is_odd) } elsex { - // When `is_branch_child` changes back to 0, previous `node_index` needs to be 15 - // and previous `is_last_child` needs to be 1. - ifx!{is_branch_child.delta() => { - require!(node_index.prev() => 15); - require!(is_last_child.prev() => true); - }} - }}*/ - - if node_index == ARITY - 1 { - // Rotations could be avoided but we would need additional is_branch_placeholder - // column. - let mut branch = - BranchNodeInfo::new(meta, ctx.clone(), true, offset - (ARITY as i32)); - - // `is_modified` needs to be set to 1 at exactly 1 branch child - let is_modified_values = (0..ARITY) - .map(|rot| a!(ctx.branch.is_modified, offset - (rot as i32))) - .collect::>(); - require!(sum::expr(&is_modified_values) => 1); - - ifx! {branch.is_placeholder() => { - // `is_drifted` needs to be set to 1 at exactly 1 branch child - let is_drifted_values = (0..ARITY).map(|rot| a!(ctx.branch.is_drifted, offset - (rot as i32))).collect::>(); - require!(sum::expr(&is_drifted_values) => 1); - }} + config.key_data.is_odd.expr() + }}; + + // Calculate the extension node key RLC when in an extension node + // Currently, the extension node S and extension node C both have the same key RLC - + // however, sometimes extension node can be replaced by a shorter extension node + // (in terms of nibbles), this is still to be implemented. + // TODO: extension nodes of different nibbles length + let key_rlc_post_ext = config.key_data.rlc.expr() + + config.ext_rlp_key.ext_key_rlc( + &mut cb.base, + config.key_data.mult.expr(), + config.ext_is_key_part_odd.expr(), + not!(is_key_odd), + ext_key_bytes.clone(), + &ctx.r + ); + + // Get the length of the key + // Unless both parts of the key are odd, subtract 1 from the key length. + let key_len = config.ext_rlp_key.key_len(); + let key_num_bytes_for_mult = key_len - ifx! {not!(config.key_data.is_odd.expr() * config.ext_is_key_part_odd.expr()) => { 1.expr() }}; + // Get the multiplier for this key length + config.ext_mult_key_len = cb.base.query_cell(); + require!((FixedTableTag::RMult, key_num_bytes_for_mult, config.ext_mult_key_len.expr()) => @"fixed"); + + ( + num_nibbles, + is_key_odd, + key_rlc_post_ext, + config.key_data.mult.expr() * config.ext_mult_key_len.expr(), + false.expr(), + false.expr(), + ext_branch_rlp_rlc[true.idx()].expr(), + ext_branch_rlp_rlc[false.idx()].expr(), + ) + } elsex { + ( + config.key_data.num_nibbles.expr(), + config.key_data.is_odd.expr(), + config.key_data.rlc.expr(), + config.key_data.mult.expr(), + config.parent_data[true.idx()].is_root.expr(), + config.parent_data[false.idx()].is_root.expr(), + config.parent_data[true.idx()].rlc.expr(), + config.parent_data[false.idx()].rlc.expr(), + ) + }}; + let is_root = [is_root_s, is_root_c]; + let parent_rlc = [parent_rlc_s, parent_rlc_c]; - for is_s in [true, false] { - branch.set_is_s(is_s); + /* Branch */ - // Check if the branch is in its parent. - let (rlc, num_bytes, is_not_hashed) = ifx! {branch.is_extension() => { - // Note: acc_c in both cases. - let ext_rlc = a!(branch.ctx.accumulators.acc_c.rlc, offset + if is_s {1} else {2}); - (ext_rlc, branch.ext_num_bytes(meta, offset + 1), branch.ext_is_not_hashed()) - } elsex { - let acc = branch.ctx.accumulators.acc(is_s); - // TODO: acc currently doesn't have branch ValueNode info - let branch_rlc = (a!(acc.rlc, offset), a!(acc.mult, offset)).rlc_chain(RLP_NIL.expr()); - (branch_rlc, branch.num_bytes(meta), branch.is_not_hashed()) - }}; - - config.parent_data[is_s.idx()] = ParentData::load( - "branch load", - &mut cb.base, - &ctx.memory[parent_memory(is_s)], - 0.expr(), - ); - ifx! {not!(branch.is_placeholder()) => { - ifx!{or::expr(&[config.parent_data[is_s.idx()].is_root.expr(), not!(is_not_hashed)]) => { - // Hashed branch hash in parent branch - // TODO(Brecht): fix - //require!((1, rlc, num_bytes, config.parent_data[is_s.idx()].rlc) => @"keccak"); - } elsex { - // Non-hashed branch hash in parent branch - require!(rlc => config.parent_data[is_s.idx()].rlc); - }} - }} - } + let mut num_bytes_left = vec![0.expr(); 2]; + let mut branch_node_rlc = vec![0.expr(); 2]; + let mut mult = vec![1.expr(); 2]; + for is_s in [true, false] { + // Read the list + config.rlp_list[is_s.idx()] = RLPListGadget::construct(&mut cb.base, &rlp_bytes[is_s.idx()]); + // Start the RLC encoding of the branch + (branch_node_rlc[is_s.idx()], mult[is_s.idx()]) = config.rlp_list[is_s.idx()].rlc_rlp(&r); - // - For a branch placeholder we do not have any constraints. However, in the - // parallel - // (regular) branch we have an additional constraint (besides `is_modified` row - // corresponding to `mod_nod_hash_rlc`) in this case: `is_drifted` `main.bytes` - // RLC is stored in the placeholder `mod_node_hash_rlc`. For - // example, if there is a placeholder branch in `S` proof, - // we have: - // - c_mod_node_hash_rlc := `is_modified` `c_main.bytes RLC` - // - s_mod_node_hash_rlc := `is_drifted` `c_main.bytes RLC` - // - When `S` branch is NOT a placeholder: - // - s_mod_node_rlc := `is_modified` `s_main.bytes RLC` - // Run over all branch children - for rot in -(ARITY as i32) + 1..=0 { - for is_s in [true, false] { - branch.set_is_s(is_s); - ifx! {branch.is_placeholder() => { - ifx!{a!(ctx.branch.is_drifted, offset + rot) => { - let branch_rlc = ctx.main(!is_s).bytes(meta, offset + rot).rlc(&r); - require!(a!(accs.mod_node_rlc(is_s), offset + rot) => branch_rlc); - ParentData::store( - &mut cb.base, - &ctx.memory[parent_memory(is_s)], - [config.parent_data[is_s.idx()].rlc.expr(), config.parent_data[is_s.idx()].is_root.expr(), true.expr(), branch_rlc] - ); - }} - } elsex { - ifx!{a!(ctx.branch.is_modified, offset + rot) => { - let branch_rlc = ctx.main(is_s).bytes(meta, offset + rot).rlc(&r); - require!(a!(accs.mod_node_rlc(is_s), offset + rot) => branch_rlc); - ParentData::store( - &mut cb.base, - &ctx.memory[parent_memory(is_s)], - [branch_rlc.expr(), false.expr(), false.expr(), branch_rlc.expr()] - ); - }} - }} - } - } + // Keep track of how many bytes the branch contains to make sure it's correct. + num_bytes_left[is_s.idx()] = config.rlp_list[is_s.idx()].len(); + + config.mod_branch_rlc[is_s.idx()] = cb.base.query_cell(); + config.mod_branch_is_hashed[is_s.idx()] = cb.base.query_cell(); + + // Check if the branch is hashed or not + config.is_not_hashed[is_s.idx()] = LtGadget::construct(&mut cb.base, config.rlp_list[is_s.idx()].num_bytes(), HASH_WIDTH.expr()); + } + + // Process the branch children + let mut mod_branch_len = vec![0.expr(); 2]; + let mut modified_index = 0.expr(); + let mut drifted_index = 0.expr(); + for node_index in 0..ARITY { + config.is_modified[node_index] = cb.base.query_cell(); + config.is_drifted[node_index] = cb.base.query_cell(); + require!(config.is_modified[node_index] => bool); + require!(config.is_drifted[node_index] => bool); + + // Calculate the modified and drifted index from `is_modified`/`is_drifted` + modified_index = modified_index.expr() + config.is_modified[node_index].expr() * node_index.expr(); + drifted_index = drifted_index.expr() + config.is_drifted[node_index].expr() * node_index.expr(); + + for is_s in [true, false] { + let branch = &mut config.branches[is_s.idx()][node_index]; + // Read the branch + branch.rlp = RLPItemGadget::construct(&mut cb.base, &branch_bytes[is_s.idx()][node_index]); + let num_bytes = branch.rlp.num_bytes(); + // Bookkeeping for RLC + branch.mult = cb.base.query_cell(); + let mult_diff = branch.mult.expr(); + require!((FixedTableTag::RMult, num_bytes.expr(), mult_diff) => @format!("fixed")); + // RLC bytes zero check + cb.set_length_sc(is_s, num_bytes.expr()); + + // Keep track of how many bytes of the list we've processed + num_bytes_left[is_s.idx()] = num_bytes_left[is_s.idx()].expr() - num_bytes.expr(); + + // Update the full branch node RLC with the data of this branch + branch_node_rlc[is_s.idx()] = (branch_node_rlc[is_s.idx()].expr(), mult[is_s.idx()].expr()).rlc_chain( + branch.rlp.rlc_rlp(&mut cb.base, &r) + ); + + // Store the rlc of the branch + // TODO(Brecht): useless now, but useful when this work is spread over multiple rows + branch.rlc_branch = cb.base.query_cell(); + require!(branch.rlc_branch => branch.rlp.rlc_branch(&r)); + + // Store if this branch is hashed + branch.is_hashed = IsEqualGadget::construct(&mut cb.base, branch.rlp.len(), 32.expr()); + + // Update the branch node multiplier + mult[is_s.idx()] = mult[is_s.idx()].expr() * mult_diff; + + // Calculate the length of the modified branch + mod_branch_len[is_s.idx()] = mod_branch_len[is_s.idx()].expr() + branch.rlp.len() * config.is_modified[node_index].expr(); // When in a placeholder branch, both branches are the same - the placeholder // branch and its parallel counterpart, which is not a @@ -380,252 +327,132 @@ impl BranchConfig { // new leaves at the same time). The non-nil nodes need to be at // `is_modified` and `is_drifted`, elsewhere there have // to be zeros. - for is_s in [true, false] { - // So many rotation is not optimal, but most of these rotations are used - // elsewhere, so it should not be much of an overhead. - // Alternative approach would be to have a column specifying - // whether there is a placeholder branch or not (we currently have this info - // only in branch init). Another alternative would be to have a column where - // we add `rlp2` value from the current row in each - // of the 16 rows. Both alternative would require - // additional column. - let branch = - BranchNodeInfo::new(meta, ctx.clone(), is_s, offset - (ARITY as i32)); - ifx! {branch.is_placeholder() => { - let sum_rlp2 = (0..ARITY).into_iter().fold(0.expr(), |acc, idx| { - acc + a!(ctx.main(is_s).rlp2, offset - (idx as i32)) - }); - // There are constraints which ensure there is only 0 or 160 at rlp2 for - // branch children. - require!(sum_rlp2 => (RLP_HASH_VALUE as u64) * 2); - }} - } - } - offset += 1; - } - - for is_s in [true, false] { - let rot_s = offset - if is_s { 0 } else { 1 }; - let rot_last_child = rot_s - 1; - - let not_first_level = a!(position_cols.not_first_level, offset); - let ext = BranchNodeInfo::new(meta, ctx.clone(), is_s, rot_branch_init); - - ifx! {ext.is_extension() => { - let ext_rlc = DataTransition::from(a!(accs.acc_s.rlc, rot_s), a!(accs.acc_c.rlc, offset)); - - // There are two cases: - // - hashed branch has RLP_HASH_VALUE at c_rlp2 and hash in c_advices, - // - non-hashed branch has 0 at c_rlp2 and all the bytes in c_advices - // TODO(Brecht): why different layout for hashed values? If for hash detection - // just do == 32? - require!(a!(c_main.rlp2, offset) => [0, RLP_HASH_VALUE]); - - // `short` means there is only one nibble in the extension node, `long` means - // there are at least two. `even` means the number of nibbles is - // even, `odd` means the number of nibbles is odd. `c16` means that - // above the branch there are even number of nibbles, `c1` means that above - // the branch there are odd number of nibbles. - let type_selectors_c1 = [ - ext.is_short_c1.expr(), - ext.is_long_even_c1.expr(), - ext.is_long_odd_c1.expr(), - ]; - let type_selectors_c16 = [ - ext.is_short_c16.expr(), - ext.is_long_even_c16.expr(), - ext.is_long_odd_c16.expr(), - ]; - let type_selectors = [type_selectors_c1.clone(), type_selectors_c16.clone()].concat(); - let misc_selectors = [ - ext.is_longer_than_55_s.expr(), - ext.is_ext_not_hashed_s.expr(), - ]; - - // Check that the selectors are boolean - for selector in type_selectors.iter().chain(misc_selectors.iter()) { - require!(selector => bool); - } - // For extension nodes exactly 1 type selector needs to be enabled. - require!(sum::expr(&type_selectors) => 1); - // `is_key_odd` is set using the extension node type selector data. - // (while in case of a regular branch the extension node selectors do not hold this information). - require!(ext.is_key_odd() => not!(sum::expr(&type_selectors_c1))); - require!(ext.is_key_odd() => sum::expr(&type_selectors_c16)); - - // RLP encoding checks: [key, branch] - // In C we have nibbles, we check below only for S. - if is_s { - ifx! {ext.is_longer_than_55_s => { - require!(a!(s_main.rlp1, offset) => RLP_LIST_LONG + 1); + // TODO(Brecht): still need to check that `modified_index != drifted_index`? + ifx! {config.is_placeholder[is_s.idx()] => { + ifx! {or::expr(&[config.is_modified[node_index].expr(), config.is_drifted[node_index].expr()]) => { + require!(branch.rlp.len() => HASH_WIDTH); + } elsex { + require!(branch.rlp.len() => 0); }} - // Verify that the lenghts are consistent. - require!(ext.ext_len(meta, offset) => ext.ext_key_num_bytes(meta, offset) + ext.ext_branch_num_bytes(meta, offset)); - } - - // Calculate the extension node RLC. - // The intermediate RLC after `s_main` bytes needs to be properly computed. - // s_rlp1, s_rlp2, s_bytes need to be the same in both extension rows. - // However, to make space for nibble witnesses, we put nibbles in - // extension row C s_bytes. So we use s_bytes from S row. - // TODO(Brecht): Do we need to store the RLC here? we can just use `rlc` - // directly below... - require!(ext_rlc.prev() => s_main.expr(meta, rot_s).rlc(&r)); - // Update the multiplier with the number of bytes on the first row - let mult = a!(accs.acc_s.mult, offset); - require!((FixedTableTag::RMult, ext.ext_num_bytes_on_key_row(meta, rot_s), mult) => @"fixed"); - - let rlc = ifx! {ext.contains_hashed_branch(meta, offset) => { - c_main.expr(meta, offset)[1..].rlc(&r) - } elsex { - // RLC bytes zero check (+2 because data starts at bytes[0]) - //cb.set_length_c(2.expr() + ext.ext_branch_num_bytes(meta)); - - c_main.expr(meta, offset)[2..].rlc(&r) - }}; - require!(ext_rlc => (ext_rlc.prev(), mult.expr()).rlc_chain(rlc)); - - // We check that the branch hash RLC corresponds to the extension node RLC - // stored in the extension node row. TODO: acc currently doesn't - // have branch ValueNode info (which 128 if nil) - let branch_rlc = ( - a!(accs.acc(is_s).rlc, rot_last_child), - a!(accs.acc(is_s).mult, rot_last_child), - ) - .rlc_chain(RLP_NIL.expr()); - let branch_rlc_in_ext = c_main.bytes(meta, offset).rlc(&r); - ifx! {ext.contains_hashed_branch(meta, offset) => { - // Check that `(branch_rlc, extension_node_hash_rlc`) is in the keccak table. - require!((1, branch_rlc, ext.num_bytes(meta), branch_rlc_in_ext) => @"keccak"); - } elsex { - // Check if the RLC matches - require!(branch_rlc => branch_rlc_in_ext); }} + } - // Update the number of nibbles processed up to this point. - if is_s { - // Calculate the number of bytes - let key_len = ext.ext_key_len(meta, offset); - // Calculate the number of nibbles - let num_nibbles = - get_num_nibbles(key_len.expr(), ext.is_key_part_in_ext_odd()); - // Make sure the nibble counter is updated correctly - let nibbles_count_prev = ifx! {f!(ctx.position_cols.q_not_first), not!(ext.is_below_account(meta)), not_first_level.expr() => { - ext.nibbles_counter().prev() - }}; - require!(ext.nibbles_counter() => nibbles_count_prev.expr() + num_nibbles.expr() + 1.expr()); - } + // We need to ensure that the only change in `S` and `C` proof occurs + // at `modified_index` so that only a single change can be done. + // TODO(Brecht): optimize, only insert the modified branch in the circuit + ifx!{not!(config.is_modified[node_index]) => { + let branch_s = config.branches[true.idx()][node_index].rlp.rlc_rlp(&mut cb.base, &r); + let branch_c = config.branches[false.idx()][node_index].rlp.rlc_rlp(&mut cb.base, &r); + require!(branch_s => branch_c); }} + } + for is_s in [true, false] { + // Number of bytes left needs to be 1 because ValueNode which occupies 1 byte + require!(num_bytes_left[is_s.idx()] => 1); + // TODO: acc currently doesn'thave branch ValueNode info (which 128 if nil) + branch_node_rlc[is_s.idx()] = (branch_node_rlc[is_s.idx()].expr(), mult[is_s.idx()].expr()).rlc_chain(RLP_NIL.expr()); - offset += 1; + // Check if the modified branch is empty, and so a placeholder leaf will follow + config.mod_branch_is_empty[is_s.idx()] = IsZeroGadget::construct(&mut cb.base, mod_branch_len[is_s.idx()].expr()); } - offset -= 2; + // `is_modified` needs to be set to 1 at exactly 1 branch child + let is_modified_values = (0..ARITY) + .map(|rot| config.is_modified[rot].expr()) + .collect::>(); + require!(sum::expr(&is_modified_values) => 1); - let branch = BranchNodeInfo::new(meta, ctx.clone(), true, rot_branch_init); - ifx! {branch.is_extension() => { - // RLC bytes zero check - // TODO(Brecht): fix - //cb.set_length(1.expr() + branch.ext_num_bytes_on_key_row(meta, 0)); + // When there's a placeholder, `is_drifted` needs to be set to 1 at exactly 1 branch child + ifx! {or::expr(&[config.is_placeholder[true.idx()].expr(), config.is_placeholder[false.idx()].expr()]) => { + let is_drifted_values = (0..ARITY).map(|rot| config.is_drifted[rot].expr()).collect::>(); + require!(sum::expr(&is_drifted_values) => 1); }} - offset += 1; - - let key = ctx.accumulators.key; - let mult_diff = ctx.accumulators.mult_diff; - - let rot_first_child = rot_branch_init + 1; - - let mut branch = BranchNodeInfo::new(meta, ctx.clone(), false, rot_branch_init); - let modified_index = a!(ctx.branch.modified_index, rot_first_child); - let key_rlc = a!(key.rlc, rot_first_child); - let key_mult = a!(key.mult, rot_first_child); + // Check if the branch is in its parent + for is_s in [true, false] { + let (rlc, num_bytes, is_not_hashed) = { + (branch_node_rlc[is_s.idx()].expr(), config.rlp_list[is_s.idx()].num_bytes(), config.is_not_hashed[is_s.idx()].expr()) + }; - // `is_key_odd` needs to be boolean - require!(branch.is_key_odd() => bool); + // TODO(Brecht): should not need is_extension check + ifx! {not!(config.is_extension) => { + ifx! {not!(config.is_placeholder[is_s.idx()]) => { + ifx!{or::expr(&[is_root[is_s.idx()].expr(), not!(is_not_hashed)]) => { + // Hashed branch hash in parent branch + require!((1, rlc, num_bytes, parent_rlc[is_s.idx()].expr()) => @"keccak"); + } elsex { + // Non-hashed branch hash in parent branch + require!(rlc => parent_rlc[is_s.idx()].expr()); + }} + }} + }} + } - // Load the last key values - config.key_data = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 0.expr()); + // Set the branch we'll take + for node_index in 0..ARITY { + for is_s in [true, false] { + ifx! {config.is_placeholder[is_s.idx()] => { + ifx!{config.is_drifted[node_index].expr() => { + // TODO(Brecht): should we actually do !is_s + let child_rlc = config.branches[(!is_s).idx()][node_index].rlp.rlc_branch(&r); + require!(config.mod_branch_rlc[is_s.idx()] => child_rlc); + ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [config.parent_data[is_s.idx()].rlc.expr(), config.parent_data[is_s.idx()].is_root.expr(), true.expr(), child_rlc] + ); + }} + } elsex { + ifx!{config.is_modified[node_index].expr() => { + let child_rlc = config.branches[is_s.idx()][node_index].rlp.rlc_branch(&r); + require!(config.mod_branch_rlc[is_s.idx()] => child_rlc); + ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [child_rlc.expr(), false.expr(), false.expr(), child_rlc] + ); + }} + }} + } + } - // Calculate the extension node key RLC when in an extension node - let key_rlc_post_ext = ifx! {branch.is_extension() => { - let key_rlc_ext = DataTransition::new_with_rot(meta, key.rlc, offset - 1, offset); - // Extension key rlc - let ext_key_rlc = config.key_data.rlc.expr() + branch.ext_key_rlc(meta, &mut cb.base, config.key_data.mult.expr(), offset); - // Currently, the extension node S and extension node C both have the same key RLC - - // however, sometimes extension node can be replaced by a shorter extension node - // (in terms of nibbles), this is still to be implemented. - // TODO: extension nodes of different nibbles length - require!(key_rlc_ext => key_rlc_ext.prev()); - // Store it - require!(key_rlc_ext => ext_key_rlc); - ext_key_rlc.expr() - } elsex { - config.key_data.rlc.expr() - }}; + // Update the nibble counter + let num_nibbles = num_nibbles + 1.expr(); - // Get the length of the key - let key_num_bytes_for_mult = ifx! {branch.is_extension() => { - // Unless both parts of the key are odd, subtract 1 from the key length. - let key_len = branch.ext_key_len(meta, offset - 1); - key_len - ifx! {not!(config.key_data.is_odd.expr() * branch.is_key_part_in_ext_odd()) => { 1.expr() }} - }}; - // Get the multiplier for this key length - let mult_diff = a!(mult_diff, rot_first_child); - require!((FixedTableTag::RMult, key_num_bytes_for_mult, mult_diff) => @"fixed"); + // Update key parity + let is_key_odd = not!(is_key_odd); - // Now update the key RLC and multiplier for the branch nibble. - let mult = config.key_data.mult.expr() * mult_diff.expr(); - let (nibble_mult, mult_mult) = ifx! {branch.is_key_odd() => { + // Update the key RLC and multiplier for the branch nibble. + let (nibble_mult, mult) = ifx! {is_key_odd.expr() => { // The nibble will be added as the most significant nibble using the same multiplier (16.expr(), 1.expr()) } elsex { // The nibble will be added as the least significant nibble, the multiplier needs to advance (1.expr(), r[0].expr()) }}; - require!(key_rlc => key_rlc_post_ext.expr() + modified_index.expr() * nibble_mult.expr() * mult.expr()); - require!(key_mult => mult.expr() * mult_mult.expr()); + let key_rlc_post_branch = key_rlc_post_ext.expr() + modified_index.expr() * nibble_mult.expr() * key_mult_post_ext.expr(); + let key_mult_post_branch = key_mult_post_ext.expr() * mult.expr(); - // Update key parity - ifx! {branch.is_extension() => { - // We need to take account the nibbles of the extension node. - // The parity alternates when there's an even number of nibbles, remains the same otherwise - ifx!{branch.is_key_part_in_ext_even() => { - require!(branch.is_key_odd() => not!(config.key_data.is_odd)); - } elsex { - require!(branch.is_key_odd() => config.key_data.is_odd); - }} - } elsex { - // The parity simply alternates for regular branches. - require!(branch.is_key_odd() => not!(config.key_data.is_odd)); - }} - - // TODO(Brecht): Add checks that when placeholder another branch cannot follow + // TODO(Brecht): Probably best to add checks that when placeholder another branch cannot follow etc.. for is_s in [true, false] { - branch.set_is_s(is_s); - ifx! {not!(branch.is_placeholder()) => { + ifx! {not!(config.is_placeholder[is_s.idx()].expr()) => { KeyData::store( &mut cb.base, &ctx.memory[key_memory(is_s)], [ - key_rlc.expr(), - key_mult.expr(), - branch.nibbles_counter().expr(), - branch.is_key_odd(), - branch.contains_placeholder_leaf(meta, true), - branch.contains_placeholder_leaf(meta, false), + key_rlc_post_branch.expr(), + key_mult_post_branch.expr(), + num_nibbles.expr(), + is_key_odd.expr(), + config.mod_branch_is_empty[true.idx()].expr(), + config.mod_branch_is_empty[false.idx()].expr(), 0.expr(), - branch.is_key_odd(), - key_rlc.expr(), - key_mult.expr(), + is_key_odd.expr(), + key_rlc_post_branch.expr(), + key_mult_post_branch.expr(), ], ); } elsex { - let (parent_rlc, parent_mult) = ifx! {branch.is_extension() => { - (key_rlc_post_ext.expr(), mult.expr()) - } elsex { - (config.key_data.rlc.expr(), config.key_data.mult.expr()) - }}; KeyData::store( &mut cb.base, &ctx.memory[key_memory(is_s)], @@ -634,20 +461,16 @@ impl BranchConfig { config.key_data.mult.expr(), config.key_data.num_nibbles.expr(), config.key_data.is_odd.expr(), - branch.contains_placeholder_leaf(meta, true), - branch.contains_placeholder_leaf(meta, false), - a!(ctx.branch.drifted_index, rot_first_child), - branch.is_key_odd(), - parent_rlc, - parent_mult, + config.mod_branch_is_empty[true.idx()].expr(), + config.mod_branch_is_empty[false.idx()].expr(), + drifted_index.expr(), + is_key_odd.expr(), + key_rlc_post_ext.expr(), + key_mult_post_ext.expr(), ], ); }} } - - // We need to check that the nibbles we stored in s are between 0 - // and 15. cb.set_range_s(FixedTableTag::RangeKeyLen16. - // expr()); }); config @@ -656,798 +479,286 @@ impl BranchConfig { pub(crate) fn assign( &self, region: &mut Region<'_, F>, - witness: &[MptWitnessRow], + witness: &mut [MptWitnessRow], mpt_config: &MPTConfig, pv: &mut ProofValues, offset: usize, ) -> Result<(), Error> { let base_offset = offset; - let mut offset = offset - 1; - - /* INIT */ - let row = &witness[offset]; - - pv.nibbles_num_prev = pv.nibbles_num; - - pv.modified_node = row.get_byte(BRANCH_0_KEY_POS); - pv.node_index = 0; - pv.drifted_pos = row.get_byte(DRIFTED_POS); - - // Get the child that is being changed and convert it to words to enable - // lookups: - let mut s_hash = witness[offset + 1 + pv.modified_node as usize] - .s_hash_bytes() - .to_vec(); - let mut c_hash = witness[offset + 1 + pv.modified_node as usize] - .c_hash_bytes() - .to_vec(); - pv.s_mod_node_hash_rlc = bytes_into_rlc(&s_hash, mpt_config.randomness); - pv.c_mod_node_hash_rlc = bytes_into_rlc(&c_hash, mpt_config.randomness); - - if row.get_byte(IS_BRANCH_S_PLACEHOLDER_POS) == 1 { - println!("{}: s_placeholder", offset); - // We put hash of a node that moved down to the added branch. - // This is needed to check the hash of leaf_in_added_branch. - s_hash = witness[offset + 1 + pv.drifted_pos as usize] - .s_hash_bytes() - .to_vec(); - pv.s_mod_node_hash_rlc = bytes_into_rlc(&s_hash, mpt_config.randomness); - pv.is_branch_s_placeholder = true - } else { - pv.is_branch_s_placeholder = false - } - if row.get_byte(IS_BRANCH_C_PLACEHOLDER_POS) == 1 { - println!("{}: c_placeholder", offset); - c_hash = witness[offset + 1 + pv.drifted_pos as usize] - .c_hash_bytes() - .to_vec(); - pv.c_mod_node_hash_rlc = bytes_into_rlc(&c_hash, mpt_config.randomness); - pv.is_branch_c_placeholder = true - } else { - pv.is_branch_c_placeholder = false - } - /* - If no placeholder branch, we set `drifted_pos = modified_node`. This - is needed just to make some other constraints (`s_mod_node_hash_rlc` - and `c_mod_node_hash_rlc` correspond to the proper node) easier to write. - */ - if row.get_byte(IS_BRANCH_S_PLACEHOLDER_POS) == 0 - && row.get_byte(IS_BRANCH_C_PLACEHOLDER_POS) == 0 - { - pv.drifted_pos = pv.modified_node - } + let offset = offset - 1; + + let row_init = witness[offset].to_owned(); + //let row_branches: [MptWitnessRow; ARITY] = array_init::array_init(|i| witness[offset + 1 + i].to_owned()); + let row_ext_s = witness[offset + 1 + ARITY].to_owned(); + + let rlp_bytes = [ + row_init.bytes[4..7].to_owned(), + row_init.bytes[7..10].to_owned(), + ]; + let branch_bytes: [[Vec; ARITY]; 2] = [ + array_init::array_init(|i| witness[base_offset + i].bytes[0..34].to_owned()), + array_init::array_init(|i| witness[base_offset + i].bytes[34..68].to_owned()), + ]; + let ext_key_bytes: [Vec; 2] = [ + witness[offset + 17].bytes[0..34].to_owned(), + witness[offset + 18].bytes[0..34].to_owned(), + ]; + let ext_value_bytes: [Vec; 2] = [ + witness[offset + 17].bytes[34..68].to_owned(), + witness[offset + 18].bytes[34..68].to_owned(), + ]; + + pv.modified_node = row_init.get_byte(BRANCH_0_KEY_POS); + pv.drifted_pos = row_init.get_byte(DRIFTED_POS); - let account_leaf = AccountLeaf::default(); - let storage_leaf = StorageLeaf::default(); - let branch = Branch { - is_branch_init: true, - ..Default::default() - }; + pv.is_even = + row_init.get_byte(IS_EXT_LONG_EVEN_C16_POS) + row_init.get_byte(IS_EXT_LONG_EVEN_C1_POS) == 1; + pv.is_odd = row_init.get_byte(IS_EXT_LONG_ODD_C16_POS) + + row_init.get_byte(IS_EXT_LONG_ODD_C1_POS) + + row_init.get_byte(IS_EXT_SHORT_C16_POS) + + row_init.get_byte(IS_EXT_SHORT_C1_POS) + == 1; + let is_extension_node = pv.is_even || pv.is_odd; - row.assign( - region, - mpt_config, - account_leaf, - storage_leaf, - branch, - offset, - )?; + pv.is_branch_s_placeholder = row_init.get_byte(IS_BRANCH_S_PLACEHOLDER_POS) == 1; + pv.is_branch_c_placeholder = row_init.get_byte(IS_BRANCH_C_PLACEHOLDER_POS) == 1; - // reassign (it was assigned to 0 in assign_row) branch_acc and - // branch_mult to proper values + let is_placeholder = [ + pv.is_branch_s_placeholder, + pv.is_branch_c_placeholder, + ]; - // Branch (length 83) with two bytes of RLP meta data - // [248,81,128,128,... + // If no placeholder branch, we set `drifted_pos = modified_node`. This + // is needed just to make some other constraints (`s_mod_node_hash_rlc` + // and `c_mod_node_hash_rlc` correspond to the proper node) easier to write. + if !is_placeholder[true.idx()] && !is_placeholder[false.idx()] { + pv.drifted_pos = pv.modified_node; + } - // Branch (length 340) with three bytes of RLP meta data - // [249,1,81,128,16,... + let modified_index = pv.modified_node as usize; + let drifted_index = pv.drifted_pos as usize; - let s_len = [0, 1, 2].map(|i| row.get_byte(BRANCH_0_S_START + i) as u64); - pv.acc_s = F::from(s_len[0]); - pv.acc_mult_s = mpt_config.randomness; + self.is_extension.assign(region, base_offset, is_extension_node.scalar())?; - if s_len[0] == 249 { - pv.acc_s += F::from(s_len[1]) * pv.acc_mult_s; - pv.acc_mult_s *= mpt_config.randomness; - pv.acc_s += F::from(s_len[2]) * pv.acc_mult_s; - pv.acc_mult_s *= mpt_config.randomness; + let key_values = self.key_data.witness_load( + region, + base_offset, + &pv.memory[key_memory(true)], + 0, + )?; - pv.rlp_len_rem_s = s_len[1] as i32 * 256 + s_len[2] as i32; - } else if s_len[0] == 248 { - pv.acc_s += F::from(s_len[1]) * pv.acc_mult_s; - pv.acc_mult_s *= mpt_config.randomness; + /* Extension */ - pv.rlp_len_rem_s = s_len[1] as i32; - } else { - pv.rlp_len_rem_s = s_len[0] as i32 - 192; + let ext_key_witness = self.ext_rlp_key.assign(region, base_offset, &ext_key_bytes[0])?; + let mut ext_is_key_part_odd = false; + if is_extension_node { + let first_byte_index = if ext_key_witness.rlp_list.is_short() { + if ext_key_witness.short_list_value.is_short() { + 1 + } else { + 2 + } + } else { + if ext_key_witness.short_list_value.is_long() { + 2 + } else { + 3 + } + }; + ext_is_key_part_odd = ext_key_bytes[0][first_byte_index] >> 4 == 1; + self.ext_is_not_hashed.assign(region, base_offset, ext_key_witness.num_bytes().scalar(), HASH_WIDTH.scalar())?; + self.ext_is_key_part_odd.assign(region, base_offset, ext_is_key_part_odd.scalar())?; + let mut ext_mult_key= F::one(); + for _ in 0..ext_key_witness.num_bytes_on_key_row() { + ext_mult_key *= mpt_config.randomness; + } + self.ext_mult_key.assign(region, base_offset, ext_mult_key)?; + } + for is_s in [true, false] { + self.ext_rlp_value[is_s.idx()].assign(region, base_offset, &ext_value_bytes[is_s.idx()])?; } - let c_len = [0, 1, 2].map(|i| row.get_byte(BRANCH_0_C_START + i) as u64); - pv.acc_c = F::from(c_len[0]); - pv.acc_mult_c = mpt_config.randomness; + pv.key_rlc_prev = pv.key_rlc; + pv.key_rlc_mult_prev = pv.key_rlc_mult; - if c_len[0] == 249 { - pv.acc_c += F::from(c_len[1]) * pv.acc_mult_c; - pv.acc_mult_c *= mpt_config.randomness; - pv.acc_c += F::from(c_len[2]) * pv.acc_mult_c; - pv.acc_mult_c *= mpt_config.randomness; + let mut key_rlc_post_ext = pv.key_rlc; + let mut key_mult_post_ext = pv.key_rlc_mult; + let mut is_key_odd = pv.nibbles_num % 2 == 1; + if is_extension_node { + is_key_odd = if ext_is_key_part_odd { + !is_key_odd + } else { + is_key_odd + }; - pv.rlp_len_rem_c = c_len[1] as i32 * 256 + c_len[2] as i32; - } else if c_len[0] == 248 { - pv.acc_c += F::from(c_len[1]) * pv.acc_mult_c; - pv.acc_mult_c *= mpt_config.randomness; + let (key_rlc_ext, _) = ext_key_witness.ext_key_rlc( + pv.key_rlc_mult, + ext_is_key_part_odd, + !is_key_odd, + ext_key_bytes.clone(), + mpt_config.randomness, + ); + key_rlc_post_ext = pv.key_rlc + key_rlc_ext; + + let mut key_len = ext_key_witness.key_len(); + if !((key_values[3].get_lower_32() % 2 == 1) && ext_is_key_part_odd) { + key_len -= 1; + } + let mut ext_mult_key_len = 1.scalar(); + for _ in 0..key_len { + ext_mult_key_len = ext_mult_key_len * mpt_config.randomness; + } + self.ext_mult_key_len.assign(region, base_offset, ext_mult_key_len)?; - pv.rlp_len_rem_c = c_len[1] as i32; - } else { - pv.rlp_len_rem_c = c_len[0] as i32 - 192; + key_mult_post_ext = pv.key_rlc_mult * ext_mult_key_len; } - mpt_config.assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - pv.acc_c, - pv.acc_mult_c, - offset, - )?; - - pv.is_even = - row.get_byte(IS_EXT_LONG_EVEN_C16_POS) + row.get_byte(IS_EXT_LONG_EVEN_C1_POS) == 1; - pv.is_odd = row.get_byte(IS_EXT_LONG_ODD_C16_POS) - + row.get_byte(IS_EXT_LONG_ODD_C1_POS) - + row.get_byte(IS_EXT_SHORT_C16_POS) - + row.get_byte(IS_EXT_SHORT_C1_POS) - == 1; - pv.is_short = row.get_byte(IS_EXT_SHORT_C16_POS) + row.get_byte(IS_EXT_SHORT_C1_POS) == 1; - pv.is_short_c1 = row.get_byte(IS_EXT_SHORT_C1_POS) == 1; - pv.is_long = row.get_byte(IS_EXT_LONG_EVEN_C16_POS) - + row.get_byte(IS_EXT_LONG_EVEN_C1_POS) - + row.get_byte(IS_EXT_LONG_ODD_C16_POS) - + row.get_byte(IS_EXT_LONG_ODD_C1_POS) - == 1; - pv.is_extension_node = pv.is_even || pv.is_odd; - - // Assign how many nibbles have been used in the previous extension node + - // branch. - pv.nibbles_num += 1; // one nibble is used for position in branch - if pv.is_extension_node { - // Get into extension node S - let row_ext = &witness[offset + BRANCH_ROWS_NUM as usize - 2]; + if is_extension_node { let ext_nibbles: usize; - if row_ext.get_byte(1) <= 32 { + if row_ext_s.get_byte(1) <= 32 { ext_nibbles = 1 - } else if row_ext.get_byte(0) < 248 { - if row_ext.get_byte(2) == 0 { + } else if row_ext_s.get_byte(0) < 248 { + if row_ext_s.get_byte(2) == 0 { // even number of nibbles - ext_nibbles = ((row_ext.get_byte(1) - 128) as usize - 1) * 2; + ext_nibbles = ((row_ext_s.get_byte(1) - 128) as usize - 1) * 2; } else { - ext_nibbles = (row_ext.get_byte(1) - 128) as usize * 2 - 1; + ext_nibbles = (row_ext_s.get_byte(1) - 128) as usize * 2 - 1; } - } else if row_ext.get_byte(3) == 0 { + } else if row_ext_s.get_byte(3) == 0 { // even number of nibbles - ext_nibbles = ((row_ext.get_byte(2) - 128) as usize - 1) * 2; + ext_nibbles = ((row_ext_s.get_byte(2) - 128) as usize - 1) * 2; } else { - ext_nibbles = (row_ext.get_byte(2) - 128) as usize * 2 - 1; + ext_nibbles = (row_ext_s.get_byte(2) - 128) as usize * 2 - 1; } pv.nibbles_num += ext_nibbles; } - region.assign_advice( - || "assign number of nibbles".to_string(), - mpt_config.s_main.bytes[NIBBLES_COUNTER_POS - RLP_NUM], - offset, - || Value::known(F::from(pv.nibbles_num as u64)), - )?; - pv.is_hashed_s = row.get_byte(IS_S_BRANCH_NON_HASHED_POS) != 1; - pv.is_hashed_c = row.get_byte(IS_C_BRANCH_NON_HASHED_POS) != 1; - pv.ext_is_hashed_s = row.get_byte(IS_S_EXT_NODE_NON_HASHED_POS) != 1; - pv.ext_is_hashed_c = row.get_byte(IS_C_EXT_NODE_NON_HASHED_POS) != 1; + /* Branch */ - offset += 1; + for is_s in [true, false] { + let rlp_list_witness = + self.rlp_list[is_s.idx()].assign(region, base_offset, &rlp_bytes[is_s.idx()])?; - /* CHILD */ + self.is_placeholder[is_s.idx()].assign(region, base_offset, is_placeholder[is_s.idx()].scalar())?; + self.is_not_hashed[is_s.idx()].assign(region, base_offset, rlp_list_witness.num_bytes().scalar(), HASH_WIDTH.scalar())?; + } + let mut mod_node_hash_rlc = [0.scalar(); 2]; + let mut branch_witnesses = vec![vec![RLPItemWitness::default(); ARITY]; 2]; for node_index in 0..ARITY { - let row = &witness[offset]; - - let mut node_mult_diff_s = F::one(); - let mut node_mult_diff_c = F::one(); - - let len = if row.get_byte(S_RLP_START + 1) == 160 { - pv.rlp_len_rem_s -= 33; - 33 - } else if row.get_byte(S_RLP_START + 1) == 0 && row.get_byte(S_START) > 192 { - let len = 1 + (row.get_byte(S_START) as i32 - 192); - pv.rlp_len_rem_s -= len; - len - } else if row.get_byte(S_RLP_START + 1) == 0 { - pv.rlp_len_rem_s -= 1; - 1 - } else { - 0 - }; - for _ in 0..len { - node_mult_diff_s *= mpt_config.randomness; - } - - let len = if row.get_byte(C_RLP_START + 1) == 160 { - pv.rlp_len_rem_c -= 33; - 33 - } else if row.get_byte(C_RLP_START + 1) == 0 && row.get_byte(C_START) > 192 { - let len = 1 + (row.get_byte(C_START) as i32 - 192); - pv.rlp_len_rem_c -= len; - len - } else if row.get_byte(C_RLP_START + 1) == 0 { - pv.rlp_len_rem_c -= 1; - 1 - } else { - 0 - }; - for _ in 0..len { - node_mult_diff_c *= mpt_config.randomness; - } - - region.assign_advice( - || "node_mult_diff_s".to_string(), - mpt_config.accumulators.node_mult_diff_s, - offset, - || Value::known(node_mult_diff_s), - )?; - region.assign_advice( - || "node_mult_diff_c".to_string(), - mpt_config.accumulators.node_mult_diff_c, - offset, - || Value::known(node_mult_diff_c), - )?; - - if pv.node_index == 0 { - // If it's not extension node, rlc and rlc_mult in extension row - // will be the same as for branch rlc. - pv.extension_node_rlc = pv.key_rlc; - - pv.key_rlc_prev = pv.key_rlc; - pv.key_rlc_mult_prev = pv.key_rlc_mult; - - // Extension node - // We need nibbles here to be able to compute key RLC - if pv.is_extension_node { - // For key RLC, we need to first take into account - // extension node key. - // witness[offset + 16] - let ext_row = &witness[offset + 16]; - let mut key_len_pos = 1; - if ext_row.get_byte(0) == 248 { - key_len_pos = 2; - } - - if pv.key_rlc_sel { - // Note: it can't be is_even = 1 && is_short = 1. - if pv.is_even && pv.is_long { - // extension node part: - let key_len = ext_row.get_byte(key_len_pos) as usize - 128 - 1; // -1 because the first byte is 0 (is_even) - mpt_config.compute_acc_and_mult( - &ext_row.bytes, - &mut pv.extension_node_rlc, - &mut pv.key_rlc_mult, - key_len_pos + 2, /* first position behind key_len_pos - * is 0 (because is_even), we start - * with the next one */ - key_len, - ); - pv.mult_diff = F::one(); - for _ in 0..key_len { - pv.mult_diff *= mpt_config.randomness; - } - pv.key_rlc = pv.extension_node_rlc; - pv.extension_node_mult = pv.key_rlc_mult; - // branch part: - pv.key_rlc += - F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; - // key_rlc_mult stays the same - pv.key_rlc_sel = !pv.key_rlc_sel; - } else if pv.is_odd && pv.is_long { - // extension node part: - pv.extension_node_rlc += - F::from((ext_row.get_byte(key_len_pos + 1) - 16) as u64) - * F::from(16) - * pv.key_rlc_mult; - - let ext_row_c = &witness[offset + 17]; - let key_len = ext_row.get_byte(key_len_pos) as usize - 128; - - pv.mult_diff = F::one(); - for k in 0..key_len - 1 { - let second_nibble = ext_row_c.get_byte(S_START + k); - let first_nibble = - (ext_row.get_byte(key_len_pos + 2 + k) - second_nibble) / 16; - assert_eq!( - first_nibble * 16 + second_nibble, - ext_row.get_byte(key_len_pos + 2 + k), - ); - pv.extension_node_rlc += - F::from(first_nibble as u64) * pv.key_rlc_mult; - - pv.key_rlc_mult *= mpt_config.randomness; - pv.mult_diff *= mpt_config.randomness; - - pv.extension_node_rlc += - F::from(second_nibble as u64) * F::from(16) * pv.key_rlc_mult; - } - - pv.key_rlc = pv.extension_node_rlc; - pv.extension_node_mult = pv.key_rlc_mult; - // branch part: - pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; - pv.key_rlc_mult *= mpt_config.randomness; - } else if pv.is_short { - pv.extension_node_rlc += F::from((ext_row.get_byte(1) - 16) as u64) - * F::from(16) - * pv.key_rlc_mult; - pv.key_rlc = pv.extension_node_rlc; - pv.extension_node_mult = pv.key_rlc_mult; - // branch part: - pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; - pv.key_rlc_mult *= mpt_config.randomness; - pv.mult_diff = if pv.is_short_c1 { - F::one() - } else { - mpt_config.randomness - }; - } - } else if pv.is_even && pv.is_long { - // extension node part: - let ext_row_c = &witness[offset + 17]; - let key_len = ext_row.get_byte(key_len_pos) as usize - 128 - 1; // -1 because the first byte is 0 (is_even) - - pv.mult_diff = F::one(); - for k in 0..key_len { - let second_nibble = ext_row_c.get_byte(S_START + k); - let first_nibble = - (ext_row.get_byte(key_len_pos + 2 + k) - second_nibble) / 16; - assert_eq!( - first_nibble * 16 + second_nibble, - ext_row.get_byte(key_len_pos + 2 + k), - ); - pv.extension_node_rlc += F::from(first_nibble as u64) * pv.key_rlc_mult; + for is_s in [true, false] { + let child_witness = self.branches[is_s.idx()][node_index].rlp.assign(region, base_offset, &branch_bytes[is_s.idx()][node_index])?; + branch_witnesses[is_s.idx()][node_index] = child_witness.clone(); - pv.key_rlc_mult *= mpt_config.randomness; - pv.mult_diff *= mpt_config.randomness; + let mut node_mult_diff = F::one(); + for _ in 0..child_witness.num_bytes() { + node_mult_diff *= mpt_config.randomness; + } - pv.extension_node_rlc += - F::from(16) * F::from(second_nibble as u64) * pv.key_rlc_mult; - } + self.branches[is_s.idx()][node_index].mult.assign(region, base_offset, node_mult_diff)?; + self.branches[is_s.idx()][node_index].rlc_branch.assign(region, base_offset, child_witness.rlc_branch(mpt_config.randomness))?; + let is_hashed = self.branches[is_s.idx()][node_index].is_hashed.assign(region, base_offset, child_witness.len().scalar(), 32.scalar())?; - pv.key_rlc = pv.extension_node_rlc; - pv.extension_node_mult = pv.key_rlc_mult; - // branch part: - pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; - pv.key_rlc_mult *= mpt_config.randomness; - pv.key_rlc_sel = !pv.key_rlc_sel; - } else if pv.is_odd && pv.is_long { - pv.extension_node_rlc += - F::from((ext_row.get_byte(key_len_pos + 1) - 16) as u64) - * pv.key_rlc_mult; - - pv.key_rlc_mult *= mpt_config.randomness; - - let key_len = ext_row.get_byte(key_len_pos) as usize - 128; - - mpt_config.compute_acc_and_mult( - &ext_row.bytes, - &mut pv.extension_node_rlc, - &mut pv.key_rlc_mult, - key_len_pos + 2, /* the first position after key_len_pos - * is single nibble which is taken into - * account above, we start - * with fourth */ - key_len - 1, // one byte is occupied by single nibble - ); - pv.mult_diff = F::one(); - for _ in 0..key_len { - pv.mult_diff *= mpt_config.randomness; - } - pv.key_rlc = pv.extension_node_rlc; - pv.extension_node_mult = pv.key_rlc_mult; - // branch part: - pv.key_rlc += - F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; - // key_rlc_mult stays the same - } else if pv.is_short { - pv.extension_node_rlc += - F::from((ext_row.get_byte(1) - 16) as u64) * pv.key_rlc_mult; - - pv.key_rlc = pv.extension_node_rlc; - - pv.key_rlc_mult *= mpt_config.randomness; - pv.extension_node_mult = pv.key_rlc_mult; - // branch part: - pv.key_rlc += - F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; - pv.mult_diff = if pv.is_short_c1 { - F::one() - } else { - mpt_config.randomness - }; - } - } else { - if pv.key_rlc_sel { - pv.key_rlc += - F::from(pv.modified_node as u64) * F::from(16) * pv.key_rlc_mult; - // key_rlc_mult stays the same - } else { - pv.key_rlc += F::from(pv.modified_node as u64) * pv.key_rlc_mult; - pv.key_rlc_mult *= mpt_config.randomness; - } - pv.key_rlc_sel = !pv.key_rlc_sel; - pv.mult_diff = F::one(); + let mod_pos = if is_placeholder[is_s.idx()] { drifted_index } else { modified_index }; + if mod_pos == node_index { + mod_node_hash_rlc[is_s.idx()] = child_witness.rlc_branch(mpt_config.randomness); + self.mod_branch_rlc[is_s.idx()].assign(region, base_offset, mod_node_hash_rlc[is_s.idx()])?; + self.mod_branch_is_hashed[is_s.idx()].assign(region, base_offset, is_hashed)?; } - row.assign_branch_row(region, mpt_config, pv, offset)?; - } else { - row.assign_branch_row(region, mpt_config, pv, offset)?; } + self.is_modified[node_index].assign(region, base_offset, (node_index == modified_index).scalar())?; + self.is_drifted[node_index].assign(region, base_offset, (node_index == drifted_index).scalar())?; + } + + let mut is_placeholder_leaf = [0.scalar(); 2]; + for is_s in [true, false] { + is_placeholder_leaf[is_s.idx()] = self.mod_branch_is_empty[is_s.idx()].assign(region, base_offset, branch_witnesses[is_s.idx()][modified_index].len().scalar())?; + } - //println!("node index: {} ({})", pv.node_index, offset); + let mut parent_values = vec![Vec::new(); 2]; + for is_s in [true, false] { + parent_values[is_s.idx()] = self.parent_data[is_s.idx()].witness_load( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + 0, + )?; - if pv.node_index == 15 { - let parent_values_s = self.parent_data[true.idx()].witness_load( + if !is_placeholder[is_s.idx()] { + self.parent_data[is_s.idx()].witness_store( region, base_offset, - &mut pv.memory[parent_memory(true)], - 0, + &mut pv.memory[parent_memory(is_s)], + mod_node_hash_rlc[is_s.idx()], + false, + false, + mod_node_hash_rlc[is_s.idx()], )?; - let parent_values_c = self.parent_data[false.idx()].witness_load( + } else { + self.parent_data[is_s.idx()].witness_store( region, base_offset, - &mut pv.memory[parent_memory(false)], - 0, + &mut pv.memory[parent_memory(is_s)], + parent_values[is_s.idx()][0], + parent_values[is_s.idx()][1] != F::zero(), + true, + mod_node_hash_rlc[is_s.idx()], )?; - - if !pv.is_branch_s_placeholder { - self.parent_data[true.idx()].witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(true)], - pv.s_mod_node_hash_rlc, - false, - false, - pv.s_mod_node_hash_rlc, - )?; - } else { - //println!("placeholder store s"); - self.parent_data[true.idx()].witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(true)], - parent_values_s[0], - parent_values_s[1] != F::zero(), - true, - pv.s_mod_node_hash_rlc, - )?; - //self.parent_data_s.witness_store(region, offset, &mut - // pv.memory[parent_memory(true)], pv.c_mod_node_hash_rlc, - // false)?; - } - if !pv.is_branch_c_placeholder { - self.parent_data[false.idx()].witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(false)], - pv.c_mod_node_hash_rlc, - false, - false, - pv.c_mod_node_hash_rlc, - )?; - } else { - //println!("placeholder store c: {:?}", parent_values_c); - self.parent_data[false.idx()].witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(false)], - parent_values_c[0], - parent_values_c[1] != F::zero(), - true, - pv.c_mod_node_hash_rlc, - )?; - - //self.parent_data_c.witness_store(region, offset, &mut - // pv.memory[parent_memory(false)], pv.s_mod_node_hash_rlc, - // false)?; - } - } - - /* - `sel1` is to distinguish whether the S node at `modified_node` position is empty. - `sel2` is to distinguish whether the C node at `modified_node` position is empty. - Note that 128 comes from the RLP byte denoting empty leaf. - Having 128 for `*_mod_node_hash_rlc` means there is no node at - this position in branch - for example, - `s_mode_node_hash_rlc = 128` and `c_words` is some other value - when new value is added to the trie - (as opposed to just updating the value). - Note that there is a potential attack if a leaf node - is found with hash `[128, 0, ..., 0]`, - but the probability is negligible. - */ - let mut sel1 = false; - let mut sel2 = false; - if pv.s_mod_node_hash_rlc == F::from(128_u64) { - sel1 = true; - } - if pv.c_mod_node_hash_rlc == F::from(128_u64) { - sel2 = true; } - pv.is_placeholder_leaf_s = sel1; - pv.is_placeholder_leaf_c = sel2; - - region.assign_advice( - || "assign sel1".to_string(), - mpt_config.denoter.sel1, - offset, - || Value::known(F::from(sel1)), - )?; - region.assign_advice( - || "assign sel2".to_string(), - mpt_config.denoter.sel2, - offset, - || Value::known(F::from(sel2)), - )?; - - // reassign (it was assigned to 0 in assign_row) branch_acc and - // branch_mult to proper values - - // We need to distinguish between empty and non-empty node: - // empty node at position 1: 0 - // non-empty node at position 1: 160 - - let c128 = F::from(128_u64); - let c160 = F::from(160_u64); - - let compute_branch_acc_and_mult = - |branch_acc: &mut F, branch_mult: &mut F, rlp_start: usize, start: usize| { - if row.get_byte(rlp_start + 1) == 0 && row.get_byte(start) == 128 { - *branch_acc += c128 * *branch_mult; - *branch_mult *= mpt_config.randomness; - } else if row.get_byte(rlp_start + 1) == 160 { - *branch_acc += c160 * *branch_mult; - *branch_mult *= mpt_config.randomness; - for i in 0..HASH_WIDTH { - *branch_acc += F::from(row.get_byte(start + i) as u64) * *branch_mult; - *branch_mult *= mpt_config.randomness; - } - } else { - *branch_acc += F::from(row.get_byte(start) as u64) * *branch_mult; - *branch_mult *= mpt_config.randomness; - let len = row.get_byte(start) as usize - 192; - for i in 0..len { - *branch_acc += - F::from(row.get_byte(start + 1 + i) as u64) * *branch_mult; - *branch_mult *= mpt_config.randomness; - } - } - }; - - // TODO: add branch ValueNode info - - compute_branch_acc_and_mult(&mut pv.acc_s, &mut pv.acc_mult_s, S_RLP_START, S_START); - compute_branch_acc_and_mult(&mut pv.acc_c, &mut pv.acc_mult_c, C_RLP_START, C_START); - mpt_config.assign_acc( - region, - pv.acc_s, - pv.acc_mult_s, - pv.acc_c, - pv.acc_mult_c, - offset, - )?; - - // This is to avoid Poisoned Constraint in extension_node_key. - region.assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(pv.key_rlc), - )?; - region.assign_advice( - || "assign key_rlc_mult".to_string(), - mpt_config.accumulators.key.mult, - offset, - || Value::known(pv.key_rlc_mult), - )?; - - pv.node_index += 1; - - offset += 1; } - /* EXTENSION */ - - if pv.is_extension_node { - for is_s in [true, false] { - let row = &witness[offset]; - if is_s { - // [228,130,0,149,160,114,253,150,133,18,192,156,19,241,162,51,210,24,1,151,16, - // 48,7,177,42,60,49,34,230,254,242,79,132,165,90,75,249] - - // One nibble: - // [226,16,160,172,105,12... - // Could also be non-hashed branch: - // [223,16,221,198,132,32,0,0,0,1,198,132,32,0,0,0,1,128,128,128,128,128,128, - // 128,128,128,128,128,128,128,128,128] - - // [247,160,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - // 213,128,194,32,1,128,194,32,1,128,128,128,128,128,128,128,128,128,128,128, - // 128,128] [248,58,159,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - // 0,0,0,0,0,0,0,0,0,0,0,0,217,128,196,130,32,0,1,128,196,130,32,0,1,128,128, - // 128,128,128,128,128,128,128,128,128,128,128] - - // Intermediate RLC value and mult (after key) - // to know which mult we need to use in c_advices. - pv.acc_s = F::zero(); - pv.acc_mult_s = F::one(); - let len: usize; - if row.get_byte(1) <= 32 { - // key length is 1 - len = 2 // [length byte, key] - } else if row.get_byte(0) < 248 { - len = (row.get_byte(1) - 128) as usize + 2; - } else { - len = (row.get_byte(2) - 128) as usize + 3; - } - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_s, - &mut pv.acc_mult_s, - 0, - len, - ); - - // Final RLC value. - pv.acc_c = pv.acc_s; - pv.acc_mult_c = pv.acc_mult_s; - let mut start = C_RLP_START + 1; - let mut len = HASH_WIDTH + 1; - if row.get_byte(C_RLP_START + 1) == 0 { - // non-hashed branch in extension node - start = C_START; - len = HASH_WIDTH; - } - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_c, - &mut pv.acc_mult_c, - start, - len, - ); - - mpt_config - .assign_acc(region, pv.acc_s, pv.acc_mult_s, pv.acc_c, F::zero(), offset) - .ok(); - } else { - let key_values = self.key_data.witness_load( - region, - base_offset, - &pv.memory[key_memory(true)], - 0, - )?; - for is_s in [true, false] { - let is_placeholder = if is_s { - pv.is_branch_s_placeholder - } else { - pv.is_branch_c_placeholder - }; - if !is_placeholder { - self.key_data.witness_store( - region, - base_offset, - &mut pv.memory[key_memory(is_s)], - pv.key_rlc, - pv.key_rlc_mult, - pv.nibbles_num, - pv.is_placeholder_leaf_s, - pv.is_placeholder_leaf_c, - 0, - pv.nibbles_num % 2 == 1, - pv.key_rlc, - pv.key_rlc_mult, - )?; - } else { - println!("ext drifted pos: {}", pv.drifted_pos); - self.key_data.witness_store( - region, - base_offset, - &mut pv.memory[key_memory(is_s)], - key_values[0], - key_values[1], - key_values[2].get_lower_32() as usize, - pv.is_placeholder_leaf_s, - pv.is_placeholder_leaf_c, - pv.drifted_pos, - pv.nibbles_num % 2 == 1, - pv.extension_node_rlc, - pv.extension_node_mult, - )?; - } - } + // one nibble is used for position in branch + pv.nibbles_num += 1; - // We use intermediate value from previous row (because - // up to acc_s it's about key and this is the same - // for both S and C). - pv.acc_c = pv.acc_s; - pv.acc_mult_c = pv.acc_mult_s; - let mut start = C_RLP_START + 1; - let mut len = HASH_WIDTH + 1; - if row.get_byte(C_RLP_START + 1) == 0 { - // non-hashed branch in extension node - start = C_START; - len = HASH_WIDTH; - } - mpt_config.compute_acc_and_mult( - &row.bytes, - &mut pv.acc_c, - &mut pv.acc_mult_c, - start, - len, - ); + // Update key parity + let is_key_odd = !is_key_odd; - mpt_config - .assign_acc(region, pv.acc_s, pv.acc_mult_s, pv.acc_c, F::zero(), offset) - .ok(); - } - region - .assign_advice( - || "assign key_rlc".to_string(), - mpt_config.accumulators.key.rlc, - offset, - || Value::known(pv.extension_node_rlc), - ) - .ok(); - - offset += 1; - } + // Update the key RLC and multiplier for the branch nibble. + let (nibble_mult, mult): (F, F) = if is_key_odd { + // The nibble will be added as the most significant nibble using the same multiplier + (16.scalar(), 1.scalar()) } else { - offset += 1; + // The nibble will be added as the least significant nibble, the multiplier needs to advance + (1.scalar(), mpt_config.randomness) + }; + let key_rlc_post_branch: F = key_rlc_post_ext + F::from(modified_index as u64) * nibble_mult * key_mult_post_ext; + let key_mult_post_branch = key_mult_post_ext * mult; - let key_values = - self.key_data - .witness_load(region, base_offset, &pv.memory[key_memory(true)], 0)?; - for is_s in [true, false] { - let is_placeholder = if is_s { - pv.is_branch_s_placeholder - } else { - pv.is_branch_c_placeholder - }; - if !is_placeholder { - self.key_data.witness_store( - region, - base_offset, - &mut pv.memory[key_memory(is_s)], - pv.key_rlc, - pv.key_rlc_mult, - pv.nibbles_num, - pv.is_placeholder_leaf_s, - pv.is_placeholder_leaf_c, - 0, - pv.nibbles_num % 2 == 1, - pv.key_rlc, - pv.key_rlc_mult, - )?; - } else { - println!("bra drifted pos: {}", pv.drifted_pos); - self.key_data.witness_store( - region, - base_offset, - &mut pv.memory[key_memory(is_s)], - key_values[0], - key_values[1], - key_values[2].get_lower_32() as usize, - pv.is_placeholder_leaf_s, - pv.is_placeholder_leaf_c, - pv.drifted_pos, - pv.nibbles_num % 2 == 1, - key_values[0], - key_values[1], - )?; - } + pv.key_rlc = key_rlc_post_branch; + pv.key_rlc_mult = key_mult_post_branch; + + for is_s in [true, false] { + if !is_placeholder[is_s.idx()] { + self.key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + pv.key_rlc, + pv.key_rlc_mult, + pv.nibbles_num, + is_placeholder_leaf[true.idx()] == 1.scalar(), + is_placeholder_leaf[false.idx()] == 1.scalar(), + 0, + pv.nibbles_num % 2 == 1, + key_rlc_post_branch, + key_mult_post_branch, + )?; + } else { + self.key_data.witness_store( + region, + base_offset, + &mut pv.memory[key_memory(is_s)], + key_values[0], + key_values[1], + key_values[2].get_lower_32() as usize, + is_placeholder_leaf[true.idx()] == 1.scalar(), + is_placeholder_leaf[false.idx()] == 1.scalar(), + pv.drifted_pos, + pv.nibbles_num % 2 == 1, + key_rlc_post_ext, + key_mult_post_ext, + )?; } } diff --git a/zkevm-circuits/src/mpt_circuit/columns.rs b/zkevm-circuits/src/mpt_circuit/columns.rs index fe7965eab4..9ef60825ce 100644 --- a/zkevm-circuits/src/mpt_circuit/columns.rs +++ b/zkevm-circuits/src/mpt_circuit/columns.rs @@ -107,142 +107,6 @@ impl MainCols { } } -#[derive(Clone, Copy, Debug)] -pub(crate) struct AccumulatorPair { - pub(crate) rlc: Column, - pub(crate) mult: Column, - _marker: PhantomData, -} - -impl AccumulatorPair { - pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { - Self { - rlc: meta.advice_column(), - mult: meta.advice_column(), - _marker: PhantomData, - } - } -} - -// Columns that store values that are being accumulated across multiple rows. -#[derive(Clone, Copy, Debug)] -pub(crate) struct AccumulatorCols { - pub(crate) acc_s: AccumulatorPair, // accumulating RLC for a node in S proof - pub(crate) acc_c: AccumulatorPair, // accumulating RLC for a node in C proof - // key.rlc & key.mult used for account address, for storage key, - // for mult_diff_nonce/mult_diff_balance in account_leaf_nonce_balance - pub(crate) key: AccumulatorPair, // accumulating RLC for address or key - pub(crate) node_mult_diff_s: Column, /* used when accumulating branch RLC for non-hashed - * nodes in a branch */ - pub(crate) node_mult_diff_c: Column, /* used when accumulating branch RLC for - * non-hashed nodes in a branch */ - pub(crate) mult_diff: Column, /* power of randomness r: multiplier_curr = - * multiplier_prev * mult_diff (used for example for - * diff due to extension node nibbles) */ - pub(crate) s_mod_node_rlc: Column, /* modified node s_advices RLC, TODO: used also - * for leaf long/short, check whether some - * DenoteCol could be used */ - pub(crate) c_mod_node_rlc: Column, /* modified node c_advices RLC, TODO: used also - * for leaf long/short, check whether some - * DenoteCol could be used */ - _marker: PhantomData, -} - -impl AccumulatorCols { - pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { - Self { - acc_s: AccumulatorPair::new(meta), - acc_c: AccumulatorPair::new(meta), - key: AccumulatorPair::new(meta), - node_mult_diff_s: meta.advice_column(), - node_mult_diff_c: meta.advice_column(), - mult_diff: meta.advice_column(), - s_mod_node_rlc: meta.advice_column(), - c_mod_node_rlc: meta.advice_column(), - _marker: PhantomData, - } - } - - pub(crate) fn acc(&self, is_s: bool) -> AccumulatorPair { - if is_s { - self.acc_s - } else { - self.acc_c - } - } - - pub(crate) fn node_mult_diff(&self, is_s: bool) -> Column { - if is_s { - self.node_mult_diff_s - } else { - self.node_mult_diff_c - } - } - - pub(crate) fn mod_node_rlc(&self, is_s: bool) -> Column { - if is_s { - self.s_mod_node_rlc - } else { - self.c_mod_node_rlc - } - } -} - -/* -Columns that denote what kind of a row it is. These columns are used in different columns for -different purposes (as opposed to for example branch.is_child - having dedicated columns simplifies -ensuring the order of rows is corrrect, like branch.is_init appears only once and is followed -by branch.is_child ... ). For example, columns sel1, sel2 are used for denoting whether -the branch child is at modified node or whether the storage leaf is in short or long RLP format. -*/ -#[derive(Clone, Copy, Debug)] -pub(crate) struct DenoteCols { - // sel1 and sel2 in branch children: denote whether there is no leaf at is_modified (when value - // is added or deleted from trie - but no branch is added or turned into leaf) - // sel1 and sel2 in storage leaf key: key_rlc_prev and key_rlc_mult_prev - // sel1 and sel2 in storage leaf value (only when leaf without branch as otherwise this info is - // in the branch above): whether leaf is just a placeholder - // sel1 and sel2 in account leaf key specifies whether nonce / balance are short / long (check - // nonce balance row: offset - 1) - pub(crate) sel1: Column, /* TODO: check LeafKeyChip where sel1 stores key_rlc_prev, - * sel2 stores key_rlc_mult_prev */ - pub(crate) sel2: Column, - pub(crate) is_not_hashed_s: Column, - pub(crate) is_not_hashed_c: Column, - _marker: PhantomData, -} - -// TODO: check whether sel1, sel2 are sometimes used for accumulated values and -// fix it. - -impl DenoteCols { - pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { - Self { - sel1: meta.advice_column(), - sel2: meta.advice_column(), - is_not_hashed_s: meta.advice_column(), - is_not_hashed_c: meta.advice_column(), - _marker: PhantomData, - } - } - - pub(crate) fn sel(&self, is_s: bool) -> Column { - if is_s { - self.sel1 - } else { - self.sel2 - } - } - - pub(crate) fn is_not_hashed(&self, is_s: bool) -> Column { - if is_s { - self.is_not_hashed_s - } else { - self.is_not_hashed_c - } - } -} - #[derive(Clone, Copy, Debug)] pub(crate) struct PositionCols { pub(crate) q_enable: Column, diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index 57eb792b35..c1728a8a0f 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -3,7 +3,7 @@ use std::any::Any; use crate::{ _cb, circuit, circuit_tools::{ - cell_manager::{Cell, CellManager, DataTransition, Trackable}, + cell_manager::{Cell, CellManager, Trackable}, constraint_builder::{ Conditionable, ConstraintBuilder, RLCChainable, RLCChainableValue, RLCable, RLCableValue, @@ -13,34 +13,25 @@ use crate::{ }, matchr, matchw, mpt_circuit::param::{ - EMPTY_TRIE_HASH, KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN, RLP_HASH_VALUE, RLP_LIST_LONG, - RLP_LIST_SHORT, RLP_NIL, RLP_SHORT, + EMPTY_TRIE_HASH, KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN, RLP_LIST_LONG, + RLP_LIST_SHORT, RLP_SHORT, }, util::Expr, }; use eth_types::Field; -use gadgets::util::{and, not, or, Scalar}; +use gadgets::util::{not, or, Scalar}; use halo2_proofs::{ circuit::Region, plonk::{Error, Expression, VirtualCells}, - poly::Rotation, }; use super::{ param::{ - ARITY, BRANCH_0_C_START, BRANCH_0_S_START, BRANCH_ROWS_NUM, IS_BRANCH_C16_POS, - IS_BRANCH_C1_POS, IS_BRANCH_C_PLACEHOLDER_POS, IS_BRANCH_S_PLACEHOLDER_POS, - IS_C_BRANCH_NON_HASHED_POS, IS_C_EXT_LONGER_THAN_55_POS, IS_C_EXT_NODE_NON_HASHED_POS, - IS_S_BRANCH_NON_HASHED_POS, IS_S_EXT_LONGER_THAN_55_POS, IS_S_EXT_NODE_NON_HASHED_POS, - KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, NIBBLES_COUNTER_POS, RLP_LONG, + KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, RLP_LONG, }, witness_row::MptWitnessRow, FixedTableTag, MPTConfig, MPTContext, ProofValues, }; -use crate::mpt_circuit::param::{ - IS_EXT_LONG_EVEN_C16_POS, IS_EXT_LONG_EVEN_C1_POS, IS_EXT_LONG_ODD_C16_POS, - IS_EXT_LONG_ODD_C1_POS, IS_EXT_SHORT_C16_POS, IS_EXT_SHORT_C1_POS, RLP_NUM, -}; /// Indexable object pub trait Indexable { @@ -81,6 +72,8 @@ pub(crate) trait Gadget { pub(crate) struct RLPListGadget { pub(crate) is_short: Cell, pub(crate) is_long: Cell, + pub(crate) is_very_long: Cell, + pub(crate) is_string: Cell, pub(crate) bytes: Vec>, } @@ -88,6 +81,8 @@ pub(crate) struct RLPListGadget { pub(crate) struct RLPListWitness { pub(crate) is_short: bool, pub(crate) is_long: bool, + pub(crate) is_very_long: bool, + pub(crate) is_string: bool, pub(crate) bytes: Vec, } @@ -97,6 +92,8 @@ impl RLPListGadget { RLPListGadget { is_short: cb.query_cell(), is_long: cb.query_cell(), + is_very_long: cb.query_cell(), + is_string: cb.query_cell(), bytes: bytes.to_vec(), } } @@ -107,58 +104,68 @@ impl RLPListGadget { offset: usize, bytes: &[u8], ) -> Result { - const RLP_LIST_LONG_INCLUSIVE: u8 = RLP_LIST_LONG - 1; - const RLP_LIST_VALUE_MAX: u8 = 255; + const RLP_LIST_LONG_1: u8 = RLP_LIST_LONG + 1; + const RLP_LIST_LONG_2: u8 = RLP_LIST_LONG + 2; let mut is_short = false; let mut is_long = false; + let mut is_very_long = false; + let mut is_string = false; match bytes[0] { - RLP_LIST_SHORT..=RLP_LIST_LONG_INCLUSIVE => is_short = true, - RLP_LIST_LONG..=RLP_LIST_VALUE_MAX => is_long = true, - _ => { - println!("bytes: {:?}", bytes); - unreachable!(); - } + RLP_LIST_SHORT..=RLP_LIST_LONG => is_short = true, + RLP_LIST_LONG_1 => is_long = true, + RLP_LIST_LONG_2 => is_very_long = true, + _ => is_string = true, } self.is_short.assign(region, offset, F::from(is_short))?; self.is_long.assign(region, offset, F::from(is_long))?; + self.is_very_long.assign(region, offset, F::from(is_very_long))?; + self.is_string.assign(region, offset, F::from(is_string))?; Ok(RLPListWitness { is_short, is_long, + is_very_long, + is_string, bytes: bytes.to_vec(), }) } + // Single RLP byte, length at most 55 bytes + pub(crate) fn is_list(&self) -> Expression { + not::expr(self.is_string.expr()) + } + // Single RLP byte, length at most 55 bytes pub(crate) fn is_short(&self) -> Expression { self.is_short.expr() } - // RLP byte followed by the number of bytes in length, followed by the length + // RLP byte followed by the length in 1 byte, followed by the length pub(crate) fn is_long(&self) -> Expression { self.is_long.expr() } + // RLP byte followed by the length in 1 byte, followed by the length + pub(crate) fn is_very_long(&self) -> Expression { + self.is_very_long.expr() + } + /// Number of RLP bytes pub(crate) fn num_rlp_bytes(&self) -> Expression { circuit!([meta, _cb!()], { matchx! { self.is_short() => 1.expr(), self.is_long() => 2.expr(), + self.is_very_long() => 3.expr(), } }) } /// Returns the total length of the list (including RLP bytes) pub(crate) fn num_bytes(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.is_short() => get_num_bytes_list_short::expr(self.bytes[0].expr()), - self.is_long() => 2.expr() + self.bytes[1].expr(), - } - }) + self.num_rlp_bytes() + self.len() } /// Returns the length of the list (excluding RLP bytes) @@ -167,12 +174,40 @@ impl RLPListGadget { matchx! { self.is_short() => get_len_list_short::expr(self.bytes[0].expr()), self.is_long() => self.bytes[1].expr(), + self.is_very_long() => self.bytes[1].expr() * 256.expr() + self.bytes[2].expr(), + } + }) + } + + pub(crate) fn rlc(&self, r: &[Expression]) -> (Expression, Expression) { + circuit!([meta, _cb!()], { + let value_rlc = + matchx! { + self.is_short() => self.bytes[1..].rlc(&r), + self.is_long() => self.bytes[2..].rlc(&r), + self.is_very_long() => self.bytes[3..].rlc(&r), + }; + (value_rlc, self.bytes.rlc(&r)) + }) + } + + /// Returns the rlc of the RLP bytes + pub(crate) fn rlc_rlp(&self, r: &[Expression]) -> (Expression, Expression) { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => (self.bytes[..1].rlc(&r), r[0].expr()), + self.is_long() => (self.bytes[..2].rlc(&r), r[1].expr()), + self.is_very_long() => (self.bytes[..3].rlc(&r), r[2].expr()), } }) } } impl RLPListWitness { + pub(crate) fn is_list(&self) -> bool { + !self.is_string + } + // Single RLP byte, length at most 55 bytes pub(crate) fn is_short(&self) -> bool { self.is_short @@ -183,19 +218,26 @@ impl RLPListWitness { self.is_long } + // RLP byte followed by the number of bytes in length, followed by the length + pub(crate) fn is_very_long(&self) -> bool { + self.is_very_long + } + /// Number of RLP bytes pub(crate) fn num_rlp_bytes(&self) -> usize { matchr! { self.is_short() => 1, self.is_long() => 2, + self.is_very_long() => 3, } } /// Returns the total length of the list (including RLP bytes) pub(crate) fn num_bytes(&self) -> usize { matchr! { - self.is_short() => get_num_bytes_list_short::value(self.bytes[0]), - self.is_long() => 2 + (self.bytes[1] as usize), + self.is_short => get_num_bytes_list_short::value(self.bytes[0]), + self.is_long => 2 + (self.bytes[1] as usize), + self.is_very_long => 3 + (self.bytes[1] as usize) * 256 + (self.bytes[2] as usize), } } @@ -206,6 +248,29 @@ impl RLPListWitness { self.is_long() => self.bytes[1] as usize, } } + + /// RLC data + pub(crate) fn rlc(&self, r: F) -> (F, F) { + matchr! { + self.is_short() => { + (self.bytes.rlc_value(r), self.bytes.rlc_value(r)) + }, + self.is_long() => { + (self.bytes[1..].rlc_value(r), self.bytes.rlc_value(r)) + }, + _ => { + unreachable!(); + }, + } + } + + pub(crate) fn rlc_rlp(&self, r: F) -> F { + self.rlc(r).1 + } + + pub(crate) fn rlc_value(&self, r: F) -> F { + self.rlc(r).0 + } } #[derive(Clone, Debug, Default)] @@ -213,6 +278,7 @@ pub(crate) struct RLPValueGadget { pub(crate) is_short: Cell, pub(crate) is_long: Cell, pub(crate) is_very_long: Cell, + pub(crate) is_list: Cell, pub(crate) bytes: Vec>, } @@ -221,6 +287,7 @@ pub(crate) struct RLPValueWitness { pub(crate) is_short: bool, pub(crate) is_long: bool, pub(crate) is_very_long: bool, + pub(crate) is_list: bool, pub(crate) bytes: Vec, } @@ -231,6 +298,7 @@ impl RLPValueGadget { is_short: cb.query_cell(), is_long: cb.query_cell(), is_very_long: cb.query_cell(), + is_list: cb.query_cell(), bytes: bytes.to_vec(), } } @@ -241,47 +309,56 @@ impl RLPValueGadget { offset: usize, bytes: &[u8], ) -> Result { - // TODO(Brecht): What's the correct way to encode NIL? - /*const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT - 1; - const RLP_LONG_INCLUSIVE: u8 = RLP_LONG - 1; + const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT - 1; + const RLP_LONG_EXCLUSIVE: u8 = RLP_LONG + 1; const RLP_VALUE_MAX: u8 = RLP_LIST_SHORT - 1; let mut is_short = false; let mut is_long = false; let mut is_very_long = false; + let mut is_list = false; match bytes[0] { 0..=RLP_SHORT_INCLUSIVE => is_short = true, - RLP_SHORT..=RLP_LONG_INCLUSIVE => is_long = true, - RLP_LONG..=RLP_VALUE_MAX => is_very_long = true, - _ => unreachable!(), - }*/ - const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT + 1; + RLP_SHORT..=RLP_LONG => is_long = true, + RLP_LONG_EXCLUSIVE..=RLP_VALUE_MAX => is_very_long = true, + _ => is_list = true, + } + /*const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT + 1; const RLP_LONG_INCLUSIVE: u8 = RLP_LONG - 1; const RLP_VALUE_MAX: u8 = RLP_LIST_SHORT - 1; let mut is_short = false; let mut is_long = false; let mut is_very_long = false; + let mut is_list = false; match bytes[0] { 0..=RLP_SHORT => is_short = true, RLP_SHORT_INCLUSIVE..=RLP_LONG_INCLUSIVE => is_long = true, RLP_LONG..=RLP_VALUE_MAX => is_very_long = true, - _ => unreachable!(), - } + _ => is_list = true, + }*/ self.is_short.assign(region, offset, F::from(is_short))?; self.is_long.assign(region, offset, F::from(is_long))?; self.is_very_long .assign(region, offset, F::from(is_very_long))?; + self.is_list + .assign(region, offset, F::from(is_list))?; Ok(RLPValueWitness { is_short, is_long, is_very_long, + is_list, bytes: bytes.to_vec(), }) } + // Returns true if this is indeed a string RLP + pub(crate) fn is_string(&self) -> Expression { + not::expr(self.is_list.expr()) + } + // Single RLP byte containing the byte value pub(crate) fn is_short(&self) -> Expression { self.is_short.expr() @@ -367,6 +444,10 @@ impl RLPValueGadget { } impl RLPValueWitness { + pub(crate) fn is_string(&self) -> bool { + !self.is_list + } + // Single RLP byte containing the byte value pub(crate) fn is_short(&self) -> bool { self.is_short @@ -397,9 +478,7 @@ impl RLPValueWitness { matchr! { self.is_short() => 1, self.is_long() => get_num_bytes_short::value(self.bytes[0]), - self.is_very_long() => { - unreachable!(); - }, + self.is_very_long() => unreachable!(), } } @@ -408,9 +487,7 @@ impl RLPValueWitness { matchr! { self.is_short() => 1, self.is_long() => get_len_short::value(self.bytes[0]), - self.is_very_long() => { - unreachable!(); - }, + self.is_very_long() => unreachable!(), } } @@ -442,9 +519,9 @@ impl RLPValueWitness { #[derive(Clone, Debug, Default)] pub(crate) struct LeafKeyGadget { - rlp_list: RLPListGadget, - short_list_value: RLPValueGadget, - long_list_value: RLPValueGadget, + pub(crate) rlp_list: RLPListGadget, + pub(crate) short_list_value: RLPValueGadget, + pub(crate) long_list_value: RLPValueGadget, short_list_has_no_nibbles: IsEqualGadget, long_list_has_no_nibbles: IsEqualGadget, bytes: Vec>, @@ -452,9 +529,9 @@ pub(crate) struct LeafKeyGadget { #[derive(Clone, Debug, Default)] pub(crate) struct LeafKeyWitness { - rlp_list: RLPListWitness, - short_list_value: RLPValueWitness, - long_list_value: RLPValueWitness, + pub(crate) rlp_list: RLPListWitness, + pub(crate) short_list_value: RLPValueWitness, + pub(crate) long_list_value: RLPValueWitness, bytes: Vec, } @@ -511,7 +588,7 @@ impl LeafKeyGadget { self.bytes.rlc(r) } - pub(crate) fn key_rlc( + pub(crate) fn leaf_key_rlc( &self, cb: &mut ConstraintBuilder, key_mult_prev: Expression, @@ -570,11 +647,80 @@ impl LeafKeyGadget { }) } + pub(crate) fn ext_key_rlc( + &self, + cb: &mut ConstraintBuilder, + key_mult_prev: Expression, + is_key_part_odd: Expression, + is_key_odd: Expression, + data: [Vec>; 2], + r: &[Expression], + ) -> Expression { + circuit!([meta, cb], { + let (is_short, is_long) = ifx! {self.rlp_list.is_short() => { + ( + self.short_list_value.is_short(), + self.short_list_value.is_long(), + ) + } elsex { + ( + self.long_list_value.is_short(), + self.long_list_value.is_long(), + ) + }}; + let mult_first_odd = ifx! {is_key_odd => { 1.expr() } elsex { 16.expr() }}; + let calc_rlc = |cb: &mut ConstraintBuilder, + bytes: &[Expression], + key_mult_first_even: Expression| { + ext_key_rlc( + cb, + bytes, + key_mult_prev.expr(), + is_key_part_odd.expr(), + mult_first_odd.expr(), + key_mult_first_even, + r, + ) + }; + // TODO(Brecht): somehow the start index doesn't dependend on the list is_short/is_long? + matchx! { + and::expr(&[is_long.expr(), not!(is_key_odd)]) => { + // Here we need to multiply nibbles over bytes with different r's so we need to rlc over separate nibbles. + // Note that there can be at max 31 key bytes because 32 same bytes would mean + // the two keys being the same - update operation, not splitting into extension node. + // So, we do not need to look further than `s_main.bytes` even if `s_main.bytes[0]` + // is not used (when even number of nibbles). + let mut key_bytes = vec![data[0][2].expr()]; + key_bytes.append(&mut data[0][2..].iter().skip(1).zip(data[1][2..].iter()).map(|(byte, nibble_hi)| { + let nibble_lo = (byte.expr() - nibble_hi.expr()) * invert!(16); + // Check that `nibble_hi` is correct. + require!(byte => nibble_lo.expr() * 16.expr() + nibble_hi.expr()); + // Collect bytes + (nibble_hi.expr() * 16.expr() * r[0].expr()) + nibble_lo.expr() + }).collect::>()); + calc_rlc(cb, &key_bytes, 1.expr()) + }, + and::expr(&[is_long.expr(), is_key_odd.expr()]) => { + let additional_mult = ifx! {is_key_part_odd => { r[0].expr() } elsex { 1.expr() }}; + calc_rlc(cb, &data[0][2..], additional_mult) + }, + is_short => { + calc_rlc(cb, &data[0][1..2], 1.expr()) + }, + } + }) + } + /// Returns the total length of the leaf (including RLP bytes) pub(crate) fn num_bytes(&self) -> Expression { self.rlp_list.num_bytes() } + /// Length + pub(crate) fn len(&self) -> Expression { + self.rlp_list.len() + } + /// Number of RLP bytes for leaf and key pub(crate) fn num_rlp_bytes(&self) -> Expression { circuit!([meta, _cb!()], { @@ -604,6 +750,20 @@ impl LeafKeyGadget { }) } + /// Number of bytes of the key (excluding RLP bytes) + pub(crate) fn key_num_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.rlp_list.is_short() => { + self.short_list_value.num_bytes() + }, + self.rlp_list.is_long() => { + self.long_list_value.num_bytes() + }, + } + }) + } + /// Number of bytes of RLP (including list RLP bytes) and key pub(crate) fn num_bytes_on_key_row(&self) -> Expression { circuit!([meta, _cb!()], { @@ -691,7 +851,7 @@ impl LeafKeyWitness { .rlc_chain_value(&self.bytes[0..(self.num_bytes_on_key_row() as usize)], r) } - pub(crate) fn key_rlc(&self, key_rlc: F, key_mult: F, r: F) -> (F, F) { + pub(crate) fn leaf_key_rlc(&self, key_rlc: F, key_mult: F, r: F) -> (F, F) { if self.key_len() <= 1 { return (key_rlc, key_mult); } @@ -709,6 +869,66 @@ impl LeafKeyWitness { } (key_rlc, key_mult).rlc_chain_value(&self.bytes[start + 2..start + 2 + len - 1], r) } + + pub(crate) fn ext_key_rlc( + &self, + key_mult_prev: F, + is_key_part_odd: bool, + is_key_odd: bool, + data: [Vec; 2], + r: F, + ) -> (F, F) { + let (is_short, is_long) = if self.rlp_list.is_short() { + ( + self.short_list_value.is_short(), + self.short_list_value.is_long(), + ) + } else { + ( + self.long_list_value.is_short(), + self.long_list_value.is_long(), + ) + }; + let mult_first_odd = if is_key_odd { 1.scalar() } else { 16.scalar() }; + let calc_rlc = | + bytes: &[F], + key_mult_first_even: F| { + ext_key_rlc_value( + bytes, + key_mult_prev, + is_key_part_odd, + mult_first_odd, + key_mult_first_even, + r, + ) + }; + // TODO(Brecht): somehow the start index doesn't dependend on the list is_short/is_long? + matchr! { + is_long && !is_key_odd => { + // Here we need to multiply nibbles over bytes with different r's so we need to rlc over separate nibbles. + // Note that there can be at max 31 key bytes because 32 same bytes would mean + // the two keys being the same - update operation, not splitting into extension node. + // So, we do not need to look further than `s_main.bytes` even if `s_main.bytes[0]` + // is not used (when even number of nibbles). + let mut key_bytes = vec![data[0][2].scalar()]; + key_bytes.append(&mut data[0][2..].iter().skip(1).zip(data[1][2..].iter()).map(|(byte, nibble_hi)| { + let nibble_lo = (byte - nibble_hi) >> 4; + // Check that `nibble_hi` is correct. + assert!(*byte == nibble_lo * 16 + nibble_hi); + // Collect bytes + (F::from(*nibble_hi as u64) * F::from(16 as u64) * r) + F::from(nibble_lo as u64) + }).collect::>()); + calc_rlc(&key_bytes, 1.scalar()) + }, + is_long && is_key_odd => { + let additional_mult = if is_key_part_odd { r } else { 1.scalar() }; + calc_rlc(&data[0][2..].iter().map(|byte| byte.scalar()).collect::>(), additional_mult) + }, + is_short => { + calc_rlc(&data[0][1..2].iter().map(|byte| byte.scalar()).collect::>(), 1.scalar()) + }, + } + } } #[derive(Clone, Debug, Default)] @@ -957,695 +1177,125 @@ impl ParentData { } } -#[derive(Clone)] -pub(crate) struct BranchNodeInfo { - pub(crate) is_s: bool, - pub(crate) ctx: MPTContext, - pub(crate) rot_branch_init: i32, - pub(crate) is_short_c16: Expression, - pub(crate) is_short_c1: Expression, - pub(crate) is_long_even_c16: Expression, - pub(crate) is_long_even_c1: Expression, - pub(crate) is_long_odd_c16: Expression, - pub(crate) is_long_odd_c1: Expression, - pub(crate) is_longer_than_55_s: Expression, - pub(crate) is_longer_than_55_c: Expression, - pub(crate) is_not_hashed_s: Expression, - pub(crate) is_not_hashed_c: Expression, - pub(crate) is_ext_not_hashed_s: Expression, - pub(crate) is_ext_not_hashed_c: Expression, - pub(crate) is_c1: Expression, - pub(crate) is_c16: Expression, - pub(crate) is_placeholder_s: Expression, - pub(crate) is_placeholder_c: Expression, - pub(crate) nibbles_counter: DataTransition, +/// Add the nibble from the drifted branch +pub(crate) fn drifted_nibble_rlc( + cb: &mut ConstraintBuilder, + difted_index: Expression, + key_mult_prev: Expression, + is_key_odd: Expression, +) -> Expression { + circuit!([meta, cb], { + // Add the nibble from the branch (drifted_index is set to the same value for + // all children) + let drifted_mult = + key_mult_prev.expr() * ifx! {is_key_odd => { 16.expr() } elsex { 1.expr() }}; + difted_index * drifted_mult + }) } -impl BranchNodeInfo { - pub(crate) fn new( - meta: &mut VirtualCells, - ctx: MPTContext, - is_s: bool, - rot_branch_init: i32, - ) -> Self { - let s_main = ctx.s_main; - let rot = Rotation(rot_branch_init); - - let mut get_value = |pos| meta.query_advice(s_main.bytes[pos - RLP_NUM], rot); - - let is_short_c16 = get_value(IS_EXT_SHORT_C16_POS); - let is_short_c1 = get_value(IS_EXT_SHORT_C1_POS); - let is_long_even_c16 = get_value(IS_EXT_LONG_EVEN_C16_POS); - let is_long_even_c1 = get_value(IS_EXT_LONG_EVEN_C1_POS); - let is_long_odd_c16 = get_value(IS_EXT_LONG_ODD_C16_POS); - let is_long_odd_c1 = get_value(IS_EXT_LONG_ODD_C1_POS); - let is_longer_than_55_s = get_value(IS_S_EXT_LONGER_THAN_55_POS); - let is_longer_than_55_c = get_value(IS_C_EXT_LONGER_THAN_55_POS); - let is_ext_not_hashed_s = get_value(IS_S_EXT_NODE_NON_HASHED_POS); - let is_ext_not_hashed_c = get_value(IS_C_EXT_NODE_NON_HASHED_POS); - let is_not_hashed_s = get_value(IS_S_BRANCH_NON_HASHED_POS); - let is_not_hashed_c = get_value(IS_C_BRANCH_NON_HASHED_POS); - let is_c1 = get_value(IS_BRANCH_C1_POS); - let is_c16 = get_value(IS_BRANCH_C16_POS); - let is_placeholder_s = get_value(IS_BRANCH_S_PLACEHOLDER_POS); - let is_placeholder_c = get_value(IS_BRANCH_C_PLACEHOLDER_POS); - - let nibbles_counter = DataTransition::new_with_rot( - meta, - s_main.bytes[NIBBLES_COUNTER_POS - RLP_NUM], - rot_branch_init - BRANCH_ROWS_NUM, - rot_branch_init, - ); - - BranchNodeInfo { - is_s, - ctx: ctx.clone(), - rot_branch_init, - is_short_c16, - is_short_c1, - is_long_even_c16, - is_long_even_c1, - is_long_odd_c16, - is_long_odd_c1, - is_longer_than_55_s, - is_longer_than_55_c, - is_not_hashed_s, - is_not_hashed_c, - is_ext_not_hashed_s, - is_ext_not_hashed_c, - is_c1, - is_c16, - is_placeholder_s, - is_placeholder_c, - nibbles_counter, - } - } - - pub(crate) fn contains_placeholder_leaf( - &self, - meta: &mut VirtualCells, - is_s: bool, - ) -> Expression { - // All children contain the same data so we just jump to the last child here - contains_placeholder_leaf( - meta, - self.ctx.clone(), - is_s, - self.rot_branch_init + (ARITY as i32) - 1, - ) - } +pub(crate) fn leaf_key_rlc( + cb: &mut ConstraintBuilder, + bytes: &[Expression], + key_mult_prev: Expression, + is_key_odd: Expression, + key_mult_first_even: Expression, + r: &[Expression], +) -> Expression { + circuit!([meta, cb], { + // Add the odd nibble first if we have one. + let (rlc, mult) = ifx! {is_key_odd => { + (get_terminal_odd_nibble(bytes[0].expr()) * key_mult_prev.expr(), r[0].expr()) + } elsex { + require!(bytes[0] => KEY_TERMINAL_PREFIX_EVEN); + (0.expr(), key_mult_first_even.expr()) + }}; + (rlc, key_mult_prev * mult).rlc_chain(bytes[1..].rlc(r)) + }) +} - /// Adds selector constraints for branch init - pub(crate) fn init_selector_checks( - &self, - meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - ) { - circuit!([meta, cb], { - // Boolean checks - let selectors = self.get_selectors(meta); - for selector in selectors.iter() { - require!(selector => bool); - } - // There should never be `rlp1, rlp2: 0, 0` - // (we only have three cases, there is no case with both being 0). - require!(or::expr(&selectors) => true); - }); - } +pub(crate) fn ext_key_rlc( + cb: &mut ConstraintBuilder, + bytes: &[Expression], + key_mult_prev: Expression, + is_odd: Expression, + rlc_mult_first_odd: Expression, + key_mult_first_odd: Expression, + r: &[Expression], +) -> Expression { + circuit!([meta, cb], { + // Add the odd nibble first if we have one. + let (rlc, mult) = ifx! {is_odd => { + (get_ext_odd_nibble(bytes[0].expr()) * key_mult_prev.expr() * rlc_mult_first_odd, key_mult_first_odd.expr()) + } elsex { + require!(bytes[0] => KEY_PREFIX_EVEN); + (0.expr(), 1.expr()) + }}; + (rlc, key_mult_prev * mult).rlc_chain(bytes[1..].rlc(r)) + }) +} - /// Returns true if this is a branch with an extension mode - pub(crate) fn is_extension(&self) -> Expression { - self.is_key_part_in_ext_even() + self.is_key_part_in_ext_odd() - } +pub(crate) fn ext_key_rlc_value( + bytes: &[F], + key_mult_prev: F, + is_odd: bool, + rlc_mult_first_odd: F, + key_mult_first_odd: F, + r: F, +) -> (F, F) { + // Add the odd nibble first if we have one. + let (rlc, mult) = if is_odd { + (get_ext_odd_nibble_value(bytes[0]) * key_mult_prev * rlc_mult_first_odd, key_mult_first_odd) + } else { + assert!(bytes[0] == KEY_PREFIX_EVEN.scalar()); + (0.scalar(), 1.scalar()) + }; + (rlc, key_mult_prev * mult).rlc_chain_value_f(&bytes[1..], r) +} - /// Returns if the part of the key in the extension node is even - pub(crate) fn is_key_part_in_ext_even(&self) -> Expression { - self.is_long_even_c16.expr() + self.is_long_even_c1.expr() - } +pub(crate) fn get_terminal_odd_nibble(byte: Expression) -> Expression { + // The odd nible is stored in the same byte as the prefix + byte - KEY_TERMINAL_PREFIX_ODD.expr() +} - /// Returns if the part of the key in the extension node is odd - pub(crate) fn is_key_part_in_ext_odd(&self) -> Expression { - self.is_long_odd() + self.is_short() - } +pub(crate) fn get_ext_odd_nibble(byte: Expression) -> Expression { + // The odd nible is stored in the same byte as the prefix + byte - KEY_PREFIX_ODD.expr() +} - // If more than 1 nibble is stored in the extension node and the key part in the - // extension node is odd - pub(crate) fn is_long_odd(&self) -> Expression { - self.is_long_odd_c16.expr() + self.is_long_odd_c1.expr() - } +pub(crate) fn get_ext_odd_nibble_value(byte: F) -> F { + // The odd nible is stored in the same byte as the prefix + byte - F::from(KEY_PREFIX_ODD as u64) +} - // If more than 1 nibble is stored in the extension node and the key part in the - // extension node is even - pub(crate) fn is_long_even(&self) -> Expression { - self.is_key_part_in_ext_even() - } +// A single RLP byte +pub(crate) mod get_len_short { + use crate::mpt_circuit::param::RLP_SHORT; + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::plonk::Expression; - // If a single nibble is stored in the extension node - pub(crate) fn is_short(&self) -> Expression { - self.is_short_c16.expr() + self.is_short_c1.expr() + pub(crate) fn expr(byte: Expression) -> Expression { + byte - RLP_SHORT.expr() } - - // If more than 1 nibble is stored in the extension node - pub(crate) fn is_long(&self) -> Expression { - self.is_long_even() + self.is_long_odd() + pub(crate) fn value(byte: u8) -> usize { + (byte - RLP_SHORT) as usize } +} - /// Returns if the key up till and including this branch is odd. - pub(crate) fn is_key_odd(&self) -> Expression { - self.is_c16.expr() - } +// A single RLP byte + the encoded length +pub(crate) mod get_num_bytes_short { + use super::get_len_short; + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::plonk::Expression; - pub(crate) fn is_placeholder_s(&self) -> Expression { - self.is_placeholder_s.expr() + pub(crate) fn expr(byte: Expression) -> Expression { + 1.expr() + get_len_short::expr(byte) } - - pub(crate) fn is_placeholder_c(&self) -> Expression { - self.is_placeholder_c.expr() + pub(crate) fn value(byte: u8) -> usize { + 1 + get_len_short::value(byte) } - - pub(crate) fn is_placeholder(&self) -> Expression { - if self.is_s { - self.is_placeholder_s() - } else { - self.is_placeholder_c() - } - } - - pub(crate) fn is_placeholder_s_or_c(&self) -> Expression { - self.is_placeholder_s() + self.is_placeholder_c() - } - - pub(crate) fn is_not_hashed_s(&self) -> Expression { - self.is_not_hashed_s.expr() - } - - pub(crate) fn is_not_hashed_c(&self) -> Expression { - self.is_not_hashed_c.expr() - } - - pub(crate) fn is_not_hashed(&self) -> Expression { - if self.is_s { - self.is_not_hashed_s() - } else { - self.is_not_hashed_c() - } - } - - pub(crate) fn is_ext_not_hashed_s(&self) -> Expression { - self.is_ext_not_hashed_s.expr() - } - - pub(crate) fn is_ext_not_hashed_c(&self) -> Expression { - self.is_ext_not_hashed_c.expr() - } - - pub(crate) fn ext_is_not_hashed(&self) -> Expression { - if self.is_s { - self.is_ext_not_hashed_s() - } else { - self.is_ext_not_hashed_c() - } - } - - /// Number of key nibbles processed up till and including the current - /// branch. - pub(crate) fn nibbles_counter(&self) -> DataTransition { - self.nibbles_counter.clone() - } - - pub(crate) fn set_is_s(&mut self, is_s: bool) { - self.is_s = is_s; - } - - pub(crate) fn is_below_account(&self, meta: &mut VirtualCells) -> Expression { - self.ctx.is_account(meta, self.rot_branch_init - 1) - } - - pub(crate) fn is_at_tree_top(&self, meta: &mut VirtualCells) -> Expression { - circuit!([meta, _cb!()], { - or::expr(&[ - not!(a!( - self.ctx.position_cols.not_first_level, - self.rot_branch_init - )), - self.is_below_account(meta), - ]) - }) - } - - pub(crate) fn get_selectors(&self, meta: &mut VirtualCells) -> [Expression; 2] { - //`s_rlp1, s_rlp2` is used for `S` and `s_main.bytes[0], s_main.bytes[1]` is - //`s_rlp1, used for `C` - let (rlp_column_1, rlp_column_2) = if self.is_s { - (self.ctx.s_main.rlp1, self.ctx.s_main.rlp2) - } else { - (self.ctx.s_main.bytes[0], self.ctx.s_main.bytes[1]) - }; - circuit!([meta, _cb!()], { - [ - a!(rlp_column_1, self.rot_branch_init), - a!(rlp_column_2, self.rot_branch_init), - ] - }) - } - - pub(crate) fn is_branch_short(&self, meta: &mut VirtualCells) -> Expression { - // rlp1, rlp2: 1, 1 means 1 RLP byte - let rlp = self.get_selectors(meta); - and::expr([rlp[0].expr(), rlp[1].expr()]) - } - - pub(crate) fn is_branch_long(&self, meta: &mut VirtualCells) -> Expression { - // rlp1, rlp2: 1, 0 means 2 RLP bytes - let rlp = self.get_selectors(meta); - and::expr([rlp[0].expr(), not::expr(rlp[1].expr())]) - } - - pub(crate) fn is_branch_very_long(&self, meta: &mut VirtualCells) -> Expression { - // rlp1, rlp2: 0, 1 means 3 RLP bytes - let rlp = self.get_selectors(meta); - and::expr([not::expr(rlp[0].expr()), rlp[1].expr()]) - } - - pub(crate) fn rlp_bytes(&self, meta: &mut VirtualCells) -> Vec> { - let offset = if self.is_s { - BRANCH_0_S_START - } else { - BRANCH_0_C_START - } - RLP_NUM; - self.ctx.s_main.bytes(meta, self.rot_branch_init)[offset..offset + 3] - .iter() - .map(|e| e.expr()) - .collect() - } - - /// Total number of bytes used by the branch - pub(crate) fn num_bytes(&self, meta: &mut VirtualCells) -> Expression { - self.num_rlp_bytes(meta) + self.len(meta) - } - - /// Number of RLP bytes for the branch - pub(crate) fn num_rlp_bytes(&self, meta: &mut VirtualCells) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.is_branch_short(meta) => 1.expr(), - self.is_branch_long(meta) => 2.expr(), - self.is_branch_very_long(meta) => 3.expr(), - } - }) - } - - /// Total length of the branch - pub(crate) fn len(&self, meta: &mut VirtualCells) -> Expression { - let rlp_bytes = self.rlp_bytes(meta); - circuit!([meta, _cb!()], { - matchx! { - self.is_branch_short(meta) => get_len_list_short::expr(rlp_bytes[0].expr()), - self.is_branch_long(meta) => rlp_bytes[1].expr(), - self.is_branch_very_long(meta) => rlp_bytes[1].expr() * 256.expr() + rlp_bytes[2].expr(), - } - }) - } - - /// Number of bytes in the extension node - pub(crate) fn ext_num_bytes(&self, meta: &mut VirtualCells, rot_c: i32) -> Expression { - self.ext_num_rlp_bytes(meta) + self.ext_len(meta, rot_c) - } - - /// Length of the extension node (excluding RLP bytes) - pub(crate) fn ext_len(&self, _meta: &mut VirtualCells, rot_c: i32) -> Expression { - circuit!([_meta, _cb!()], { - matchx! { - self.is_short() + self.is_long() => get_len_list_short::expr(a!(self.ctx.s_main.rlp1, rot_c)), - self.is_longer_than_55_s => get_len_short::expr(a!(self.ctx.s_main.bytes[0], rot_c)), - } - }) - } - - /// Number of RLP bytes for the extension row - pub(crate) fn ext_num_rlp_bytes(&self, _meta: &mut VirtualCells) -> Expression { - circuit!([_meta, _cb!()], { - matchx! { - self.is_short() + self.is_long() => 1.expr(), - self.is_longer_than_55_s => 2.expr(), - } - }) - } - - /// Length of the key (excluding RLP bytes) - /// Uses data on the current row! - pub(crate) fn ext_key_len(&self, _meta: &mut VirtualCells, rel_rot: i32) -> Expression { - circuit!([_meta, _cb!()], { - matchx! { - self.is_short() => 1.expr(), // Only a single nibble (stored in s_rlp2) - self.is_long() => get_len_short::expr(a!(self.ctx.s_main.rlp2, rel_rot)), - self.is_longer_than_55_s => get_len_short::expr(a!(self.ctx.s_main.bytes[0], rel_rot)), - } - }) - } - - /// Number of bytes of the key (including RLP bytes) - /// Uses data on the current row! - pub(crate) fn ext_key_num_bytes( - &self, - meta: &mut VirtualCells, - rel_rot: i32, - ) -> Expression { - circuit!([meta, _cb!()], { - matchx! ( - self.is_short() => 0.expr(), - self.is_long() => 1.expr(), - self.is_longer_than_55_s => 2.expr(), - ) + self.ext_key_len(meta, rel_rot) - }) - } - - /// Number of bytes of RLP (including list RLP bytes) and key - pub(crate) fn ext_num_bytes_on_key_row( - &self, - meta: &mut VirtualCells, - rel_rot: i32, - ) -> Expression { - self.ext_num_rlp_bytes(meta) + self.ext_key_num_bytes(meta, rel_rot) - } - - /// Length of the included branch (excluding RLP bytes) - /// Uses data on the current row! - pub(crate) fn ext_branch_len( - &self, - meta: &mut VirtualCells, - rot_ext_s: i32, - ) -> Expression { - circuit!([meta, _cb!()], { - ifx! {self.contains_hashed_branch(meta, rot_ext_s) => { - 32.expr() - } elsex { - get_len_list_short::expr(a!(self.ctx.c_main.bytes[0], rot_ext_s)) - }} - }) - } - - /// Length of the included branch (excluding RLP bytes) - /// Uses data on the current row! - pub(crate) fn ext_branch_num_bytes( - &self, - meta: &mut VirtualCells, - rot_ext_s: i32, - ) -> Expression { - 1.expr() + self.ext_branch_len(meta, rot_ext_s) - } - - /// Length of the key (excluding RLP bytes) - /// Uses data on the current row! - pub(crate) fn contains_hashed_branch( - &self, - meta: &mut VirtualCells, - rot_ext_s: i32, - ) -> Expression { - circuit!([meta, _cb!()], { - a!(self.ctx.c_main.rlp2, rot_ext_s) * invert!(RLP_HASH_VALUE) - }) - } - - /// Key data is read from the current row, not at rot_key! - pub(crate) fn ext_key_rlc( - &self, - meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - key_mult_prev: Expression, - rot_ext_c: i32, - ) -> Expression { - circuit!([meta, cb], { - let mult_first_odd = ifx! {self.is_key_odd() => { 1.expr() } elsex { 16.expr() }}; - let calc_rlc = |meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - bytes: &[Expression], - key_mult_first_even: Expression| { - ext_key_rlc( - meta, - cb, - self.ctx.clone(), - bytes, - key_mult_prev.expr(), - self.is_key_part_in_ext_odd(), - mult_first_odd.expr(), - key_mult_first_even, - ) - }; - matchx! { - self.is_long_odd_c1.expr() + self.is_long_even_c1.expr() => { - // Here we need to multiply nibbles over bytes with different r's so we need to rlc over separate nibbles. - // Note that there can be at max 31 key bytes because 32 same bytes would mean - // the two keys being the same - update operation, not splitting into extension node. - // So, we do not need to look further than `s_main.bytes` even if `s_main.bytes[0]` - // is not used (when even number of nibbles). - let mut key_bytes = vec![a!(self.ctx.s_main.bytes[0], rot_ext_c - 1)]; - key_bytes.append(&mut self.ctx.s_main.bytes.iter().skip(1).zip(self.ctx.s_main.bytes.iter()).map(|(byte, byte_hi)| { - let byte = a!(byte, rot_ext_c - 1); - let nibble_hi = a!(byte_hi, rot_ext_c); - let nibble_lo = (byte.expr() - nibble_hi.expr()) * invert!(16); - // Check that `nibble_hi` is correct. - require!(byte => nibble_lo.expr() * 16.expr() + nibble_hi.expr()); - // Collect bytes - (nibble_hi.expr() * 16.expr() * self.ctx.r[0].expr()) + nibble_lo.expr() - }).collect::>()); - calc_rlc(meta, cb, &key_bytes, 1.expr()) - }, - self.is_long_odd_c16.expr() + self.is_long_even_c16.expr() => { - let additional_mult = ifx! {self.is_long_odd_c16 => { self.ctx.r[0].expr() } elsex { 1.expr() }}; - let key_bytes = self.ctx.s_main.bytes(meta, rot_ext_c - 1); - calc_rlc(meta, cb, &key_bytes, additional_mult) - }, - self.is_short() => { - let key_bytes = vec![a!(self.ctx.s_main.rlp2, rot_ext_c - 1)]; - calc_rlc(meta, cb, &key_bytes, 1.expr()) - }, - } - }) - } - - /// Add the nibble from the drifted branch - pub(crate) fn drifted_nibble_rlc( - &self, - meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - key_mult_prev: Expression, - ) -> Expression { - circuit!([meta, cb], { - // Add the nibble from the branch (drifted_index is set to the same value for - // all children) - let drifted_mult = - key_mult_prev.expr() * ifx! {self.is_key_odd() => { 16.expr() } elsex { 1.expr() }}; - a!(self.ctx.branch.drifted_index, self.rot_branch_init + 1) * drifted_mult - }) - } -} - -/// Add the nibble from the drifted branch -pub(crate) fn drifted_nibble_rlc( - cb: &mut ConstraintBuilder, - difted_index: Expression, - key_mult_prev: Expression, - is_key_odd: Expression, -) -> Expression { - circuit!([meta, cb], { - // Add the nibble from the branch (drifted_index is set to the same value for - // all children) - let drifted_mult = - key_mult_prev.expr() * ifx! {is_key_odd => { 16.expr() } elsex { 1.expr() }}; - difted_index * drifted_mult - }) -} - -#[derive(Clone)] -pub(crate) struct BranchChildInfo { - pub(crate) is_s: bool, - pub(crate) ctx: MPTContext, - pub(crate) rot_branch: i32, -} - -impl BranchChildInfo { - pub(crate) fn new( - _meta: &mut VirtualCells, - ctx: MPTContext, - is_s: bool, - rot_branch: i32, - ) -> Self { - BranchChildInfo { - is_s, - ctx: ctx.clone(), - rot_branch, - } - } - - /// Returns the total length of the leaf (including RLP bytes) - pub(crate) fn num_bytes(&self, meta: &mut VirtualCells) -> Expression { - circuit!([meta, _cb!()], { - ifx! {self.is_hashed(meta) => { - // There is `s_rlp2 = 0` when there is a nil node and `s_rlp2 = 160` when - // non-nil node (1 or 33 respectively). - a!(self.ctx.main(self.is_s).rlp2, self.rot_branch) * invert!(RLP_HASH_VALUE) * 32.expr() + 1.expr() - } elsex { - get_num_bytes_list_short::expr(a!(self.ctx.main(self.is_s).bytes[0], self.rot_branch)) - }} - }) - } - - pub(crate) fn is_hashed(&self, meta: &mut VirtualCells) -> Expression { - circuit!([meta, _cb!()], { - not!(a!( - self.ctx.denoter.is_not_hashed(self.is_s), - self.rot_branch - )) - }) - } - - pub(crate) fn rlc( - &self, - meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - ) -> Expression { - let main = self.ctx.main(self.is_s); - let r = self.ctx.r.clone(); - circuit!([meta, cb], { - ifx! {not!(self.is_hashed(meta)) => { - // When a branch child is not empty and is not hashed, a list is stored in the branch and - // we have `bytes[0] - RLP_LIST_SHORT` bytes in a row. We need to add these bytes to the RLC. - // For example we have 6 bytes in the following child: `[0,0,198,132,48,0,0,0,1,...]`. - main.expr(meta, self.rot_branch)[2..34].rlc(&r) - } elsex { - ifx!{self.is_empty(meta) => { - require!(a!(main.bytes[0], self.rot_branch) => RLP_NIL); - // There's only one byte (128 at `bytes[0]`) that needs to be added to the RLC. - main.expr(meta, self.rot_branch)[2..3].rlc(&r) - } elsex { - // When a branch child is non-empty and hashed, we have 33 bytes in a row. - main.expr(meta, self.rot_branch)[1..34].rlc(&r) - }} - }} - }) - } - - /// Branch data starts at a different offset, this will return the number of - /// bytes from the start - pub(crate) fn num_bytes_on_row(&self, meta: &mut VirtualCells) -> Expression { - circuit!([meta, _cb!()], { - ifx!(self.is_hashed(meta) => { - 2.expr() - } elsex { - ifx!{self.is_empty(meta) => { - 2.expr() - } elsex { - 1.expr() - }} - }) + self.num_bytes(meta) - }) - } - - /// Only usable when the child isn't hashed! - pub(crate) fn is_empty(&self, meta: &mut VirtualCells) -> Expression { - let main = self.ctx.main(self.is_s); - circuit!([meta, _cb!()], { - // Empty nodes have 0 at `rlp2`, have `RLP_NIL` at `bytes[0]` and 0 everywhere - // else. While hashed nodes have `RLP_HASH_VALUE at `rlp2` and then - // any byte at `bytes`. - require!(a!(main.rlp2, self.rot_branch) => [0, RLP_HASH_VALUE]); - (RLP_HASH_VALUE.expr() - a!(main.rlp2, self.rot_branch)) * invert!(RLP_HASH_VALUE) - }) - } -} - -pub(crate) fn contains_placeholder_leaf( - meta: &mut VirtualCells, - ctx: MPTContext, - is_s: bool, - rot_branch_child: i32, -) -> Expression { - meta.query_advice(ctx.denoter.sel(is_s), Rotation(rot_branch_child)) -} - -pub(crate) fn leaf_key_rlc( - cb: &mut ConstraintBuilder, - bytes: &[Expression], - key_mult_prev: Expression, - is_key_odd: Expression, - key_mult_first_even: Expression, - r: &[Expression], -) -> Expression { - circuit!([meta, cb], { - // Add the odd nibble first if we have one. - let (rlc, mult) = ifx! {is_key_odd => { - (get_terminal_odd_nibble(bytes[0].expr()) * key_mult_prev.expr(), r[0].expr()) - } elsex { - require!(bytes[0] => KEY_TERMINAL_PREFIX_EVEN); - (0.expr(), key_mult_first_even.expr()) - }}; - (rlc, key_mult_prev * mult).rlc_chain(bytes[1..].rlc(r)) - }) -} - -pub(crate) fn ext_key_rlc( - _meta: &mut VirtualCells, - cb: &mut ConstraintBuilder, - ctx: MPTContext, - bytes: &[Expression], - key_mult_prev: Expression, - is_odd: Expression, - rlc_mult_first_odd: Expression, - key_mult_first_odd: Expression, -) -> Expression { - circuit!([_meta, cb], { - // Add the odd nibble first if we have one. - let first_byte = bytes[0].clone(); - let (rlc, mult) = ifx! {is_odd => { - (get_ext_odd_nibble(first_byte.expr()) * key_mult_prev.expr() * rlc_mult_first_odd, key_mult_first_odd.expr()) - } elsex { - require!(first_byte => KEY_PREFIX_EVEN); - (0.expr(), 1.expr()) - }}; - (rlc, key_mult_prev * mult).rlc_chain(bytes[1..].rlc(&ctx.r)) - }) -} - -pub(crate) fn get_terminal_odd_nibble(byte: Expression) -> Expression { - // The odd nible is stored in the same byte as the prefix - byte - KEY_TERMINAL_PREFIX_ODD.expr() -} - -pub(crate) fn get_ext_odd_nibble(byte: Expression) -> Expression { - // The odd nible is stored in the same byte as the prefix - byte - KEY_PREFIX_ODD.expr() -} - -// A single RLP byte -pub(crate) mod get_len_short { - use crate::mpt_circuit::param::RLP_SHORT; - use eth_types::Field; - use gadgets::util::Expr; - use halo2_proofs::plonk::Expression; - - pub(crate) fn expr(byte: Expression) -> Expression { - byte - RLP_SHORT.expr() - } - pub(crate) fn value(byte: u8) -> usize { - (byte - RLP_SHORT) as usize - } -} - -// A single RLP byte + the encoded length -pub(crate) mod get_num_bytes_short { - use super::get_len_short; - use eth_types::Field; - use gadgets::util::Expr; - use halo2_proofs::plonk::Expression; - - pub(crate) fn expr(byte: Expression) -> Expression { - 1.expr() + get_len_short::expr(byte) - } - pub(crate) fn value(byte: u8) -> usize { - 1 + get_len_short::value(byte) - } -} +} pub(crate) mod get_len_list_short { use crate::mpt_circuit::param::RLP_LIST_SHORT; @@ -1815,7 +1465,7 @@ impl IsEmptyTreeGadget { .rlc(&r); let is_in_empty_trie = IsEqualGadget::construct(cb, parent_rlc.expr(), empty_root_rlc.expr()); - let is_in_empty_branch = IsEqualGadget::construct(cb, parent_rlc.expr(), 128.expr()); + let is_in_empty_branch = IsEqualGadget::construct(cb, parent_rlc.expr(), 0.expr()); Self { is_in_empty_trie, @@ -1842,7 +1492,240 @@ impl IsEmptyTreeGadget { bytes_into_rlc(&EMPTY_TRIE_HASH, r), )?; self.is_in_empty_branch - .assign(region, offset, parent_rlc, 128.scalar())?; + .assign(region, offset, parent_rlc, 0.scalar())?; Ok(()) } } + + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPItemGadget { + pub(crate) value: RLPValueGadget, + pub(crate) list: RLPListGadget, +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPItemWitness { + pub(crate) value: RLPValueWitness, + pub(crate) list: RLPListWitness, + pub(crate) bytes: Vec, +} + +impl RLPItemGadget { + pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { + RLPItemGadget { + value: RLPValueGadget::construct(cb, bytes), + list: RLPListGadget::construct(cb, bytes), + } + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + bytes: &[u8], + ) -> Result { + let value_witness = self.value.assign(region, offset, bytes)?; + let list_witness = self.list.assign(region, offset, bytes)?; + + if value_witness.is_string() && list_witness.is_list() { + println!("{:?}", bytes) + } + assert!(!(value_witness.is_string() && list_witness.is_list())); + + Ok(RLPItemWitness { + value: value_witness, + list: list_witness, + bytes: bytes.to_vec(), + }) + } + + // Single RLP byte containing the byte value + pub(crate) fn is_short(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.is_short(), + self.list.is_list() => self.list.is_short(), + } + }) + } + + // Single RLP byte containing the length of the value + pub(crate) fn is_long(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.is_long(), + self.list.is_list() => self.list.is_long(), + } + }) + } + + // RLP byte containing the lenght of the length, + // followed by the length, followed by the actual data + pub(crate) fn is_very_long(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.is_very_long(), + self.list.is_list() => self.list.is_very_long(), + } + }) + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.num_rlp_bytes(), + self.list.is_list() => self.list.num_rlp_bytes(), + } + }) + } + + /// Number of bytes in total (including RLP bytes) + pub(crate) fn num_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.num_bytes(), + self.list.is_list() => self.list.num_bytes(), + } + }) + } + + /// Length of the value (excluding RLP bytes) + pub(crate) fn len(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.len(), + self.list.is_list() => self.list.len(), + } + }) + } + + /// RLC data + pub(crate) fn rlc(&self, cb: &mut ConstraintBuilder, r: &[Expression]) -> (Expression, Expression) { + circuit!([meta, cb], { + matchx! { + self.value.is_string() => self.value.rlc(r), + self.list.is_list() => self.list.rlc(r), + } + }) + } + + pub(crate) fn rlc_rlp(&self, cb: &mut ConstraintBuilder, r: &[Expression]) -> Expression { + self.rlc(cb, r).1 + } + + pub(crate) fn rlc_value(&self, cb: &mut ConstraintBuilder, r: &[Expression]) -> Expression { + self.rlc(cb, r).0 + } + + pub(crate) fn rlc_branch(&self, r: &[Expression]) -> Expression { + /*circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.rlc_value(r), + self.list.is_list() => self.list.rlc(r).1, + } + })*/ + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.rlc(r).0, + self.list.is_list() => self.list.rlc(r).1, + } + }) + } +} + +impl RLPItemWitness { + /// Number of bytes in total (including RLP bytes) + pub(crate) fn num_bytes(&self) -> usize { + matchr! { + self.value.is_string() => self.value.num_bytes(), + self.list.is_list() => self.list.num_bytes(), + } + } + + // Single RLP byte containing the byte value + /*pub(crate) fn is_short(&self) -> bool { + matchr! { + self.value.is_string() => self.value.is_very_long(), + self.list.is_list() => self.list.is_very_long(), + } + } + + // Single RLP byte containing the length of the value + pub(crate) fn is_long(&self) -> bool { + self.is_long + } + + // RLP byte containing the lenght of the length, + // followed by the length, followed by the actual data + pub(crate) fn is_very_long(&self) -> bool { + self.is_very_long + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> usize { + matchr! { + self.is_short() => 0, + self.is_long() => 1, + self.is_very_long() => 2, + } + } + + /// Number of bytes in total (including RLP bytes) + pub(crate) fn num_bytes(&self) -> usize { + matchr! { + self.is_short() => 1, + self.is_long() => get_num_bytes_short::value(self.bytes[0]), + self.is_very_long() => { + unreachable!(); + }, + } + }*/ + + /// Length of the value (excluding RLP bytes) + pub(crate) fn len(&self) -> usize { + matchr! { + self.value.is_string() => self.value.len(), + self.list.is_list() => self.list.len(), + } + } + + /// RLC data + /*pub(crate) fn rlc(&self, r: F) -> (F, F) { + matchr! { + self.is_short() => { + let value_rlc = self.bytes[0].scalar(); + (value_rlc, value_rlc) + }, + self.is_long() => { + let value_rlc = self.bytes[1..].rlc_value(r); + (value_rlc, self.bytes.rlc_value(r)) + }, + self.is_very_long() => { + unreachable!(); + }, + } + } + + pub(crate) fn rlc_rlp(&self, r: F) -> F { + self.rlc(r).1 + } + + pub(crate) fn rlc_value(&self, r: F) -> F { + self.rlc(r).0 + }*/ + + pub(crate) fn rlc_branch(&self, r: F) -> F { + /*circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.rlc_value(r), + self.list.is_list() => self.list.rlc(r).1, + } + })*/ + matchr! { + self.value.is_string() => self.value.rlc(r).0, + self.list.is_list() => self.list.rlc(r).1, + } + } +} \ No newline at end of file diff --git a/zkevm-circuits/src/mpt_circuit/proof_chain.rs b/zkevm-circuits/src/mpt_circuit/proof_chain.rs index 5a003cae18..372743e709 100644 --- a/zkevm-circuits/src/mpt_circuit/proof_chain.rs +++ b/zkevm-circuits/src/mpt_circuit/proof_chain.rs @@ -50,18 +50,13 @@ impl ProofChainConfig { let q_enable = f!(ctx.position_cols.q_enable); let q_not_first = f!(ctx.position_cols.q_not_first); let not_first_level = DataTransition::new(meta, ctx.position_cols.not_first_level); - let is_branch_init = a!(ctx.branch.is_init); - let is_account_leaf_key_s = a!(ctx.account_leaf.is_key_s); - let is_storage_leaf_key_s = a!(ctx.storage_leaf.is_s_key); - let is_storage_leaf_last_row_prev = a!(ctx.storage_leaf.is_non_existing, -1); - let is_account_leaf_last_row_prev = a!(ctx.account_leaf.is_in_added_branch, -1); let is_non_storage_mod_proof_type_prev = not!(a!(ctx.proof_type.is_storage_mod, -1)); let start_root = DataTransition::new(meta, ctx.inter_start_root); let final_root = DataTransition::new(meta, ctx.inter_final_root); let address_rlc = DataTransition::new(meta, ctx.address_rlc); - let is_branch_or_account = is_account_leaf_key_s.expr() + is_branch_init.expr(); + /*let is_branch_or_account = is_account_leaf_key_s.expr() + is_branch_init.expr(); ifx! {q_enable => { ifx!{not!(q_not_first) => { @@ -148,7 +143,7 @@ impl ProofChainConfig { }} // TODO: check public roots to match with first and last inter roots - }} + }}*/ }); ProofChainConfig { diff --git a/zkevm-circuits/src/mpt_circuit/selectors.rs b/zkevm-circuits/src/mpt_circuit/selectors.rs index db50e92eb0..41ad7e7f8c 100644 --- a/zkevm-circuits/src/mpt_circuit/selectors.rs +++ b/zkevm-circuits/src/mpt_circuit/selectors.rs @@ -17,10 +17,6 @@ impl SelectorsConfig { ) -> Self { let proof_type = ctx.proof_type; let position_cols = ctx.position_cols; - let branch = ctx.branch; - let account_leaf = ctx.account_leaf; - let storage_leaf = ctx.storage_leaf; - let denoter = ctx.denoter; // It needs to be ensured that: // - The selectors denoting the row type are boolean values. // - For sets of selectors that are mutually exclusive, it needs to be ensured @@ -30,39 +26,6 @@ impl SelectorsConfig { let q_enable = f!(position_cols.q_enable); let q_not_first = f!(position_cols.q_not_first); let not_first_level = a!(position_cols.not_first_level); - let sel1 = a!(denoter.sel1); - let sel2 = a!(denoter.sel2); - - let is_leaf_s_key = DataTransition::new(meta, storage_leaf.is_s_key); - let is_leaf_s_value = DataTransition::new(meta, storage_leaf.is_s_value); - let is_leaf_c_key = DataTransition::new(meta, storage_leaf.is_c_key); - let is_leaf_c_value = DataTransition::new(meta, storage_leaf.is_c_value); - let is_leaf_in_added_branch = - DataTransition::new(meta, storage_leaf.is_in_added_branch); - let is_leaf_non_existing = DataTransition::new(meta, storage_leaf.is_non_existing); - let is_non_existing_storage_row = - DataTransition::new(meta, storage_leaf.is_non_existing); - let is_account_leaf_key_s = DataTransition::new(meta, account_leaf.is_key_s); - let is_account_leaf_key_c = DataTransition::new(meta, account_leaf.is_key_c); - let is_account_leaf_nonce_balance_s = - DataTransition::new(meta, account_leaf.is_nonce_balance_s); - let is_account_leaf_nonce_balance_c = - DataTransition::new(meta, account_leaf.is_nonce_balance_c); - let is_account_leaf_storage_codehash_s = - DataTransition::new(meta, account_leaf.is_storage_codehash_s); - let is_account_leaf_storage_codehash_c = - DataTransition::new(meta, account_leaf.is_storage_codehash_c); - let is_account_leaf_in_added_branch = - DataTransition::new(meta, account_leaf.is_in_added_branch); - let is_non_existing_account_row = - DataTransition::new(meta, account_leaf.is_non_existing); - let is_extension_node_s = DataTransition::new(meta, branch.is_extension_node_s); - let is_extension_node_c = DataTransition::new(meta, branch.is_extension_node_c); - let is_branch_init = DataTransition::new(meta, branch.is_init); - let is_branch_child = DataTransition::new(meta, branch.is_child); - let is_last_branch_child = DataTransition::new(meta, branch.is_last_child); - let is_modified = DataTransition::new(meta, branch.is_modified); - let is_drifted = DataTransition::new(meta, branch.is_drifted); let proof_type_id = DataTransition::new(meta, proof_type.proof_type); let is_storage_mod = DataTransition::new(meta, proof_type.is_storage_mod); @@ -77,7 +40,7 @@ impl SelectorsConfig { // Row type selectors let row_type_selectors = [ - is_branch_init.expr(), + /*is_branch_init.expr(), is_branch_child.expr(), is_extension_node_s.expr(), is_extension_node_c.expr(), @@ -94,7 +57,7 @@ impl SelectorsConfig { is_account_leaf_nonce_balance_c.expr(), is_account_leaf_storage_codehash_s.expr(), is_account_leaf_storage_codehash_c.expr(), - is_account_leaf_in_added_branch.expr(), + is_account_leaf_in_added_branch.expr(),*/ ]; // Proof type selectors @@ -113,12 +76,6 @@ impl SelectorsConfig { // It needs to be ensured that all selectors are boolean. let misc_selectors = vec![ not_first_level.expr(), - is_last_branch_child.expr(), - is_branch_child.expr(), - is_modified.expr(), - is_drifted.expr(), - sel1.expr(), - sel2.expr(), ]; for selector in misc_selectors .iter() @@ -129,14 +86,14 @@ impl SelectorsConfig { // The type of the row needs to be set (if all selectors would be 0 for a row, // then all constraints would be switched off). - require!(sum::expr(row_type_selectors.iter()) => 1); + //require!(sum::expr(row_type_selectors.iter()) => 1); // The type of the proof needs to be set. require!(sum::expr(proof_type_selectors.iter()) => 1); // We need to prevent lookups into non-lookup rows and we need to prevent for // example nonce lookup into balance lookup row. - let proof_type_lookup_row_types = [ + /*let proof_type_lookup_row_types = [ is_account_leaf_nonce_balance_s.expr(), is_account_leaf_nonce_balance_c.expr(), is_account_leaf_storage_codehash_c.expr(), @@ -159,19 +116,19 @@ impl SelectorsConfig { require!(proof_type_id => 0); }} }} - } + }*/ }}; // First row - ifx! {q_enable, not!(q_not_first) => { + /*ifx! {q_enable, not!(q_not_first) => { // In the first row only account leaf key S row or branch init row can occur require!(or::expr([is_account_leaf_key_s.cur(), is_branch_init.cur()]) => true); - }}; + }};*/ // All rows except the first row ifx! {q_not_first => { // State transitions - let transitions = [ + /*let transitions = [ // Branch init can start: // - after another branch (means after extension node C) // - after account leaf (account -> storage proof) @@ -293,12 +250,12 @@ impl SelectorsConfig { vec![is_leaf_in_added_branch.prev()], is_leaf_non_existing.cur(), ), - ]; - for (name, condition, from, to) in transitions { + ];*/ + /*for (name, condition, from, to) in transitions { ifx!{condition => { require!(name, to => from); }} - } + }*/ // Data transitions // Note that these constraints do not prevent attacks like putting account leaf @@ -322,9 +279,9 @@ impl SelectorsConfig { require!(is_mod => is_mod.prev()); } elsex { // Does not change inside first level except in the first row - ifx!{not!(is_branch_init), not!(is_account_leaf_key_s) => { + /*ifx!{not!(is_branch_init), not!(is_account_leaf_key_s) => { require!(is_mod => is_mod.prev()); - }} + }}*/ }}; } }} diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index 622b1b86a5..5b0847816b 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -1,12 +1,10 @@ use eth_types::Field; use gadgets::util::Scalar; -use halo2_proofs::plonk::{Advice, Column, ConstraintSystem}; use halo2_proofs::{ circuit::{Region, Value}, plonk::{Error, VirtualCells}, poly::Rotation, }; -use std::marker::PhantomData; use crate::circuit_tools::cell_manager::Cell; use crate::circuit_tools::constraint_builder::{RLCChainable, RLCableValue}; @@ -29,41 +27,6 @@ use crate::{ use super::helpers::{Indexable, LeafKeyGadget, RLPValueGadget}; -#[derive(Clone, Debug)] -pub(crate) struct StorageLeafCols { - pub(crate) is_s_key: Column, - pub(crate) is_s_value: Column, - pub(crate) is_c_key: Column, - pub(crate) is_c_value: Column, - pub(crate) is_in_added_branch: Column, - pub(crate) is_non_existing: Column, - _marker: PhantomData, -} - -impl StorageLeafCols { - pub(crate) fn new(meta: &mut ConstraintSystem) -> Self { - Self { - is_s_key: meta.advice_column(), - is_s_value: meta.advice_column(), - is_c_key: meta.advice_column(), - is_c_value: meta.advice_column(), - is_in_added_branch: meta.advice_column(), - is_non_existing: meta.advice_column(), - _marker: PhantomData, - } - } -} - -#[derive(Default, Debug)] -pub(crate) struct StorageLeaf { - pub(crate) is_s_key: bool, - pub(crate) is_s_value: bool, - pub(crate) is_c_key: bool, - pub(crate) is_c_value: bool, - pub(crate) is_in_added_branch: bool, - pub(crate) is_non_existing: bool, -} - #[derive(Clone, Debug, Default)] pub(crate) struct StorageLeafConfig { key_data: [KeyData; 2], @@ -144,7 +107,7 @@ impl StorageLeafConfig { // Key key_rlc[is_s.idx()] = key_data.rlc.expr() - + rlp_key.key_rlc( + + rlp_key.leaf_key_rlc( &mut cb.base, key_data.mult.expr(), key_data.is_odd.expr(), @@ -171,8 +134,7 @@ impl StorageLeafConfig { // Make sure the RLP encoding is correct. // storage = [key, value] ifx! {not!(is_placeholder_leaf) => { - let key_num_bytes = rlp_key.num_bytes_on_key_row(); - require!(rlp_key.num_bytes() => key_num_bytes.expr() + config.rlp_value[is_s.idx()].num_bytes()); + require!(rlp_key.num_bytes() => rlp_key.num_bytes_on_key_row() + config.rlp_value[is_s.idx()].num_bytes()); }}; // Check if the account is in its parent. @@ -226,7 +188,7 @@ impl StorageLeafConfig { // Calculate the drifted key RLC let drifted_key_rlc = key_rlc_prev.expr() + drifted_nibble_rlc(&mut cb.base, placeholder_nibble.expr(), key_mult_prev.expr(), placeholder_is_odd.expr()) + - config.drifted_rlp_key.key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), true, &r); + config.drifted_rlp_key.leaf_key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), true, &r); // Check zero bytes and mult_diff config.drifted_mult = cb.base.query_cell(); @@ -265,7 +227,7 @@ impl StorageLeafConfig { ifx! {config.is_wrong_leaf => { // Calculate the key config.wrong_rlp_key = LeafKeyGadget::construct(&mut cb.base, &wrong_bytes); - let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.key_rlc( + let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.leaf_key_rlc( &mut cb.base, config.key_data_w.mult.expr(), config.key_data_w.is_odd.expr(), @@ -371,7 +333,7 @@ impl StorageLeafConfig { key_rlc_mult_new = pv.key_rlc_mult_prev; } (key_rlc[is_s.idx()], _) = - rlp_key_witness.key_rlc(key_rlc_new, key_rlc_mult_new, ctx.randomness); + rlp_key_witness.leaf_key_rlc(key_rlc_new, key_rlc_mult_new, ctx.randomness); // Value let value_row = &value_bytes[is_s.idx()]; @@ -440,7 +402,7 @@ impl StorageLeafConfig { let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes)?; let (key_rlc_wrong, _) = - wrong_witness.key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.randomness); + wrong_witness.leaf_key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.randomness); self.check_is_wrong_leaf.assign( region, diff --git a/zkevm-circuits/src/mpt_circuit/witness_row.rs b/zkevm-circuits/src/mpt_circuit/witness_row.rs index 1715bb8a25..80cf41792c 100644 --- a/zkevm-circuits/src/mpt_circuit/witness_row.rs +++ b/zkevm-circuits/src/mpt_circuit/witness_row.rs @@ -7,8 +7,6 @@ use num_enum::TryFromPrimitive; use std::{convert::TryFrom, marker::PhantomData}; use crate::{ - mpt_circuit::account_leaf::AccountLeaf, - mpt_circuit::branch::Branch, mpt_circuit::helpers::bytes_into_rlc, mpt_circuit::param::{ COUNTER_WITNESS_LEN, C_RLP_START, C_START, HASH_WIDTH, IS_ACCOUNT_DELETE_MOD_POS, @@ -16,10 +14,11 @@ use crate::{ IS_NON_EXISTING_STORAGE_POS, IS_STORAGE_MOD_POS, NOT_FIRST_LEVEL_POS, RLP_NUM, S_RLP_START, S_START, WITNESS_ROW_WIDTH, }, - mpt_circuit::storage_leaf::StorageLeaf, mpt_circuit::{MPTConfig, ProofValues}, }; +use super::param::RLP_LIST_SHORT; + #[derive(Debug, Eq, PartialEq, TryFromPrimitive)] #[repr(u8)] pub(crate) enum MptWitnessRowType { @@ -114,11 +113,23 @@ impl MptWitnessRow { } pub(crate) fn s_hash_bytes(&self) -> &[u8] { - &self.bytes[S_START..S_START + HASH_WIDTH] + let offset = if self.bytes[S_RLP_START] < RLP_LIST_SHORT { + 1 + } else { + 0 + }; + &self.bytes[S_RLP_START+offset..34] + //&self.bytes[S_RLP_START..S_RLP_START + 34] } pub(crate) fn c_hash_bytes(&self) -> &[u8] { - &self.bytes[C_START..C_START + HASH_WIDTH] + let offset = if self.bytes[C_RLP_START] < RLP_LIST_SHORT { + 1 + } else { + 0 + }; + &self.bytes[C_RLP_START+offset..68] + //&self.bytes[C_RLP_START..C_RLP_START + 34] } pub(crate) fn main(&self) -> &[u8] { @@ -129,174 +140,10 @@ impl MptWitnessRow { &self, region: &mut Region<'_, F>, mpt_config: &MPTConfig, - account_leaf: AccountLeaf, - storage_leaf: StorageLeaf, - branch: Branch, offset: usize, ) -> Result<(), Error> { let row = self.main(); - // println!("row: {}", offset); - // println!("{:?}", account_leaf); - // println!("{:?}", storage_leaf); - // println!("{:?}", branch); - - region.assign_advice( - || "assign is_branch_init".to_string(), - mpt_config.branch.is_init, - offset, - || Value::known(F::from(branch.is_branch_init as u64)), - )?; - - region.assign_advice( - || "assign is_branch_child".to_string(), - mpt_config.branch.is_child, - offset, - || Value::known(F::from(branch.is_branch_child as u64)), - )?; - - region.assign_advice( - || "assign is_last_branch_child".to_string(), - mpt_config.branch.is_last_child, - offset, - || Value::known(F::from(branch.is_last_branch_child as u64)), - )?; - - region.assign_advice( - || "assign node_index".to_string(), - mpt_config.branch.node_index, - offset, - || Value::known(F::from(branch.node_index as u64)), - )?; - - region.assign_advice( - || "assign modified node".to_string(), - mpt_config.branch.modified_index, - offset, - || Value::known(F::from(branch.modified_index as u64)), - )?; - - region.assign_advice( - || "assign drifted_index".to_string(), - mpt_config.branch.drifted_index, - offset, - || Value::known(F::from(branch.drifted_index as u64)), - )?; - - region.assign_advice( - || "assign is_drifted".to_string(), - mpt_config.branch.is_drifted, - offset, - || Value::known(F::from((branch.drifted_index == branch.node_index) as u64)), - )?; - - region.assign_advice( - || "assign is_modified".to_string(), - mpt_config.branch.is_modified, - offset, - || Value::known(F::from((branch.modified_index == branch.node_index) as u64)), - )?; - - region.assign_advice( - || "assign is_leaf_s".to_string(), - mpt_config.storage_leaf.is_s_key, - offset, - || Value::known(F::from(storage_leaf.is_s_key as u64)), - )?; - region.assign_advice( - || "assign is_leaf_c".to_string(), - mpt_config.storage_leaf.is_c_key, - offset, - || Value::known(F::from(storage_leaf.is_c_key as u64)), - )?; - - region.assign_advice( - || "assign is_leaf_s_value".to_string(), - mpt_config.storage_leaf.is_s_value, - offset, - || Value::known(F::from(storage_leaf.is_s_value as u64)), - )?; - region.assign_advice( - || "assign is_leaf_c_value".to_string(), - mpt_config.storage_leaf.is_c_value, - offset, - || Value::known(F::from(storage_leaf.is_c_value as u64)), - )?; - region.assign_advice( - || "assign is leaf in added branch".to_string(), - mpt_config.storage_leaf.is_in_added_branch, - offset, - || Value::known(F::from(storage_leaf.is_in_added_branch as u64)), - )?; - region.assign_advice( - || "assign is storage non existing".to_string(), - mpt_config.storage_leaf.is_non_existing, - offset, - || Value::known(F::from(storage_leaf.is_non_existing as u64)), - )?; - - region.assign_advice( - || "assign is account leaf key s".to_string(), - mpt_config.account_leaf.is_key_s, - offset, - || Value::known(F::from(account_leaf.is_key_s as u64)), - )?; - region.assign_advice( - || "assign is account leaf key c".to_string(), - mpt_config.account_leaf.is_key_c, - offset, - || Value::known(F::from(account_leaf.is_key_c as u64)), - )?; - region.assign_advice( - || "assign is non existing account row".to_string(), - mpt_config.account_leaf.is_non_existing, - offset, - || Value::known(F::from(account_leaf.is_non_existing_account_row as u64)), - )?; - region.assign_advice( - || "assign is account leaf nonce balance s".to_string(), - mpt_config.account_leaf.is_nonce_balance_s, - offset, - || Value::known(F::from(account_leaf.is_nonce_balance_s as u64)), - )?; - region.assign_advice( - || "assign is account leaf nonce balance c".to_string(), - mpt_config.account_leaf.is_nonce_balance_c, - offset, - || Value::known(F::from(account_leaf.is_nonce_balance_c as u64)), - )?; - region.assign_advice( - || "assign is account leaf storage codehash s".to_string(), - mpt_config.account_leaf.is_storage_codehash_s, - offset, - || Value::known(F::from(account_leaf.is_storage_codehash_s as u64)), - )?; - region.assign_advice( - || "assign is account leaf storage codehash c".to_string(), - mpt_config.account_leaf.is_storage_codehash_c, - offset, - || Value::known(F::from(account_leaf.is_storage_codehash_c as u64)), - )?; - region.assign_advice( - || "assign is account leaf in added branch".to_string(), - mpt_config.account_leaf.is_in_added_branch, - offset, - || Value::known(F::from(account_leaf.is_in_added_branch as u64)), - )?; - - region.assign_advice( - || "assign is extension node s".to_string(), - mpt_config.branch.is_extension_node_s, - offset, - || Value::known(F::from(branch.is_extension_node_s as u64)), - )?; - region.assign_advice( - || "assign is extension node c".to_string(), - mpt_config.branch.is_extension_node_c, - offset, - || Value::known(F::from(branch.is_extension_node_c as u64)), - )?; - region.assign_advice( || "assign s_rlp1".to_string(), mpt_config.s_main.rlp1, @@ -320,10 +167,6 @@ impl MptWitnessRow { )?; } - /*if offset == 99 { - println!("{:?}", row); - }*/ - // not all columns may be needed let get_val = |curr_ind: usize| { let val = if curr_ind >= row.len() { @@ -360,104 +203,6 @@ impl MptWitnessRow { Ok(()) } - pub(crate) fn assign_branch_row( - &self, - region: &mut Region<'_, F>, - mpt_config: &MPTConfig, - pv: &ProofValues, - offset: usize, - ) -> Result<(), Error> { - let row = self.main(); - - let account_leaf = AccountLeaf::default(); - let storage_leaf = StorageLeaf::default(); - let branch = Branch { - is_branch_child: true, - is_last_branch_child: pv.node_index == 15, - node_index: pv.node_index, - modified_index: pv.modified_node, - drifted_index: pv.drifted_pos, - ..Default::default() - }; - - self.assign( - region, - mpt_config, - account_leaf, - storage_leaf, - branch, - offset, - )?; - - region.assign_advice( - || "s_mod_node_hash_rlc", - mpt_config.accumulators.s_mod_node_rlc, - offset, - || Value::known(pv.s_mod_node_hash_rlc), - )?; - region.assign_advice( - || "c_mod_node_hash_rlc", - mpt_config.accumulators.c_mod_node_rlc, - offset, - || Value::known(pv.c_mod_node_hash_rlc), - )?; - - region.assign_advice( - || "key rlc", - mpt_config.accumulators.key.rlc, - offset, - || Value::known(pv.key_rlc), - )?; - region.assign_advice( - || "key rlc mult", - mpt_config.accumulators.key.mult, - offset, - || Value::known(pv.key_rlc_mult), - )?; - region.assign_advice( - || "mult diff", - mpt_config.accumulators.mult_diff, - offset, - || Value::known(pv.mult_diff), - )?; - - region.assign_advice( - || "s_rlp1", - mpt_config.s_main.rlp1, - offset, - || Value::known(F::from(pv.rlp_len_rem_s as u64)), - )?; - region.assign_advice( - || "c_rlp1", - mpt_config.c_main.rlp1, - offset, - || Value::known(F::from(pv.rlp_len_rem_c as u64)), - )?; - - region.assign_advice( - || "is_not_hashed_s", - mpt_config.denoter.is_not_hashed_s, - offset, - || { - Value::known(F::from( - (row[S_RLP_START + 1] == 0 && row[S_START] > 192) as u64, - )) - }, - )?; - region.assign_advice( - || "is_not_hashed_c", - mpt_config.denoter.is_not_hashed_c, - offset, - || { - Value::known(F::from( - (row[C_RLP_START + 1] == 0 && row[C_START] > 192) as u64, - )) - }, - )?; - - Ok(()) - } - /* Assignment of the columns that are used for all lookups. There are other columns used for lookups which are lookup-specific (for example requiring old and new nonce value). @@ -472,9 +217,6 @@ impl MptWitnessRow { let s_root_rlc = self.s_root_bytes_rlc(mpt_config.randomness); let c_root_rlc = self.c_root_bytes_rlc(mpt_config.randomness); - //println!("{}: {:?}", offset, s_root_rlc); - //println!("{}: {:?}", offset, c_root_rlc); - region.assign_advice( || "inter start root", mpt_config.inter_start_root, From 00d1a89000dfa7333a6b1270bb7dfd73d1f58ae2 Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Tue, 28 Feb 2023 03:21:09 +0100 Subject: [PATCH 10/11] Misc improvements --- .../src/circuit_tools/constraint_builder.rs | 11 + zkevm-circuits/src/circuit_tools/gadgets.rs | 2 +- zkevm-circuits/src/mpt_circuit.rs | 240 +++---------- .../src/mpt_circuit/account_leaf.rs | 82 ++--- zkevm-circuits/src/mpt_circuit/branch.rs | 335 ++++++++---------- zkevm-circuits/src/mpt_circuit/helpers.rs | 197 ++++------ zkevm-circuits/src/mpt_circuit/proof_chain.rs | 2 +- .../src/mpt_circuit/storage_leaf.rs | 68 ++-- .../NonExistingAccountAfterFirstLevel.json | 2 +- .../tests/NonExistingAccountNilObject.json | 2 +- ...nExistingAccountNilObjectInFirstLevel.json | 2 +- .../tests/NonExistingStorageNil.json | 2 +- zkevm-circuits/src/mpt_circuit/witness_row.rs | 12 +- 13 files changed, 360 insertions(+), 597 deletions(-) diff --git a/zkevm-circuits/src/circuit_tools/constraint_builder.rs b/zkevm-circuits/src/circuit_tools/constraint_builder.rs index 070f2727ff..e9baaef001 100644 --- a/zkevm-circuits/src/circuit_tools/constraint_builder.rs +++ b/zkevm-circuits/src/circuit_tools/constraint_builder.rs @@ -1059,6 +1059,17 @@ macro_rules! assign { }}; } +/// assign +#[macro_export] +macro_rules! assignf { + ($region:expr, ($column:expr, $offset:expr) => $value:expr) => {{ + let description = + $crate::concat_with_preamble!(stringify!($column), " => ", stringify!($value)); + let value: F = $value; + $region.assign_fixed(|| description, $column, $offset, || Value::known(value)) + }}; +} + /// Circuit builder macros /// Nested macro's can't do repetition (https://github.com/rust-lang/rust/issues/35853) /// so we expose a couple of permutations here manually. diff --git a/zkevm-circuits/src/circuit_tools/gadgets.rs b/zkevm-circuits/src/circuit_tools/gadgets.rs index 7b39319e7e..4dc129b22b 100644 --- a/zkevm-circuits/src/circuit_tools/gadgets.rs +++ b/zkevm-circuits/src/circuit_tools/gadgets.rs @@ -65,7 +65,7 @@ impl RequireNotZeroGadget { pub(crate) fn construct(cb: &mut ConstraintBuilder, value: Expression) -> Self { circuit!([meta, cb], { let inverse = cb.query_cell(); - require!(value.expr() * inverse.expr() =>1); + require!(value.expr() * inverse.expr() => 1); Self { inverse } }) } diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index d99d6f018b..695446edc9 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -2,7 +2,7 @@ use eth_types::Field; use gadgets::{impl_expr, util::Scalar}; use halo2_proofs::{ - circuit::{Layouter, Region, SimpleFloorPlanner, Value}, + circuit::{Layouter, SimpleFloorPlanner, Value}, plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells}, poly::Rotation, }; @@ -32,7 +32,7 @@ use crate::{ circuit, circuit_tools::{ cell_manager::CellManager, - constraint_builder::{merge_lookups, RLCable}, + constraint_builder::{merge_lookups}, memory::Memory, }, mpt_circuit::{ @@ -40,7 +40,7 @@ use crate::{ storage_leaf::StorageLeafConfig, }, table::{DynamicTableColumns, KeccakTable}, - util::{power_of_randomness_from_instance, Challenges}, + util::{power_of_randomness_from_instance, Challenges}, assignf, }; use self::{account_leaf::AccountLeafConfig, columns::MPTTable, helpers::key_memory}; @@ -60,25 +60,14 @@ pub struct MPTContext { pub(crate) position_cols: PositionCols, pub(crate) inter_start_root: Column, pub(crate) inter_final_root: Column, - pub(crate) value_prev: Column, - pub(crate) value: Column, pub(crate) s_main: MainCols, pub(crate) c_main: MainCols, - pub(crate) address_rlc: Column, pub(crate) managed_columns: Vec>, pub(crate) r: Vec>, pub(crate) memory: Memory, } impl MPTContext { - pub(crate) fn main(&self, is_s: bool) -> MainCols { - if is_s { - self.s_main - } else { - self.c_main - } - } - pub(crate) fn inter_root(&self, is_s: bool) -> Column { if is_s { self.inter_start_root @@ -99,15 +88,6 @@ impl MPTContext { .map(|&byte| meta.query_advice(byte, Rotation(rot))) .collect::>() } - - pub(crate) fn rlc( - &self, - meta: &mut VirtualCells, - range: Range, - rot: i32, - ) -> Expression { - self.expr(meta, rot)[range].rlc(&self.r) - } } /// Merkle Patricia Trie config. @@ -117,28 +97,20 @@ pub struct MPTConfig { pub(crate) position_cols: PositionCols, pub(crate) inter_start_root: Column, pub(crate) inter_final_root: Column, - pub(crate) value_prev: Column, - pub(crate) value: Column, pub(crate) s_main: MainCols, pub(crate) c_main: MainCols, pub(crate) managed_columns: Vec>, pub(crate) memory: Memory, keccak_table: KeccakTable, fixed_table: [Column; 3], - pub(crate) address_rlc: Column, /* The same in all rows of a modification. The same - * as - * address_rlc computed in the account leaf key row. - * Needed to - * enable lookup for storage key/value (to have - * address RLC in - * the same row as storage key/value). */ + pub(crate) address_rlc: Column, branch_config: BranchConfig, storage_config: StorageLeafConfig, account_config: AccountLeafConfig, pub(crate) is_branch: Column, pub(crate) is_account: Column, pub(crate) is_storage: Column, - pub(crate) randomness: F, + pub(crate) r: F, pub(crate) mpt_table: MPTTable, cb: MPTConstraintBuilder, } @@ -162,36 +134,15 @@ pub enum FixedTableTag { impl_expr!(FixedTableTag); -/* -Some values are accumulating through the rows (or block of rows) and we need to access the previous value -to continue the calculation, for this reason the previous values are stored in `ProofValues` struct. -Such accumulated value is for example `key_rlc` which stores the intermediate key RLC (in each branch -and extension node block a new intermediate key RLC is computed). -Also, for example, `modified_node` is given in branch init but needed to be set in every branch children row. -*/ +// TODO(Brecht): remove by refactoring to use memory values instead #[derive(Default)] pub(crate) struct ProofValues { - pub(crate) modified_node: u8, /* branch child that is being changed, it is the same in all - * branch children rows */ - pub(crate) acc_c: F, /* RLC accumulator for the whole node (taking into account all RLP - * bytes of the node) */ - pub(crate) acc_mult_c: F, // multiplier for acc_c - pub(crate) key_rlc: F, /* used first for account address, then for storage key */ - pub(crate) key_rlc_mult: F, // multiplier for key_rlc - pub(crate) key_rlc_prev: F, /* for leaf after placeholder extension/branch, we need - * to go one level - * back - * to get previous key_rlc */ + pub(crate) key_rlc: F, + pub(crate) key_rlc_mult: F, + pub(crate) key_rlc_prev: F, pub(crate) key_rlc_mult_prev: F, - pub(crate) is_branch_s_placeholder: bool, // whether S branch is just a placeholder - pub(crate) is_branch_c_placeholder: bool, // whether C branch is just a placeholder - pub(crate) drifted_pos: u8, /* needed when leaf turned into branch and leaf moves into a - * branch where - * it's at drifted_pos position */ - pub(crate) is_even: bool, - pub(crate) is_odd: bool, + pub(crate) before_account_leaf: bool, - pub(crate) nibbles_num: usize, pub(crate) memory: Memory, } @@ -215,17 +166,10 @@ impl MPTConfig { power_of_randomness: [Expression; HASH_WIDTH], keccak_table: KeccakTable, ) -> Self { - // let _pub_root = meta.instance_column(); - let inter_start_root = meta.advice_column(); // state root before modification - first level S hash needs to be the same as - // start_root (works also if only storage proof, without account proof, but if - // this is to be allowed LeafKeyChip needs to be changed - careful with q_enable - // and q_not_first; not_first_level - // constraints would need to be added there too) - let inter_final_root = meta.advice_column(); // state root after modification - first level C hash needs to be the same as - // end_root (works also if only storage proof, without account proof, but if - // this is to be allowed LeafKeyChip needs to be changed - careful with q_enable - // and q_not_first; not_first_level - // constraints would need to be added there too) + // state root before modification + let inter_start_root = meta.advice_column(); + // state root after modification + let inter_final_root = meta.advice_column(); let value_prev = meta.advice_column(); let value = meta.advice_column(); @@ -276,11 +220,8 @@ impl MPTConfig { position_cols: position_cols.clone(), inter_start_root: inter_start_root.clone(), inter_final_root: inter_final_root.clone(), - value_prev: value_prev.clone(), - value: value.clone(), s_main: s_main.clone(), c_main: c_main.clone(), - address_rlc: address_rlc.clone(), managed_columns: managed_columns.clone(), r: extend_rand(&power_of_randomness), memory: memory.clone(), @@ -333,32 +274,21 @@ impl MPTConfig { /* Range checks */ // These range checks ensure that the value in the RLP columns are all byte value. - // These lookups also enforce the value to be zero if the passed in length is < 0. - // TODO(Brecht): would be safer/cleaner if this can be enabled everywhere even for branch child rlp1 + // These lookups also enforce the byte value to be zero the byte index >= length. // TODO(Brecht): do 2 bytes/lookup when circuit height >= 2**21 /*ifx!{f!(position_cols.q_enable) => { // Sanity checks (can be removed, here for safety) require!(cb.length_s.sum_conditions() => bool); require!(cb.length_c.sum_conditions() => bool); // Range checks - ifx!{not!(a!(branch.is_child)) => { - for &byte in ctx.rlp_bytes()[0..1].into_iter() { - require!((FixedTableTag::RangeKeyLen256, a!(byte), 0.expr()) => @"fixed"); - } - }} - for &byte in ctx.rlp_bytes()[1..2].into_iter() { + for &byte in ctx.rlp_bytes()[0..2].into_iter() { require!((FixedTableTag::RangeKeyLen256, a!(byte), 0.expr()) => @"fixed"); } for (idx, &byte) in ctx.rlp_bytes()[2..34].into_iter().enumerate() { require!((cb.get_range_s(), a!(byte), cb.get_length_s() - (idx + 1).expr()) => @"fixed"); } ifx!{cb.length_sc => { - ifx!{not!(a!(branch.is_child)) => { - for (idx, &byte) in ctx.rlp_bytes()[34..35].into_iter().enumerate() { - require!((FixedTableTag::RangeKeyLen256, a!(byte), cb.get_length_s() - 32.expr() - (idx + 1).expr()) => @"fixed"); - } - }} - for (idx, &byte) in ctx.rlp_bytes()[35..36].into_iter().enumerate() { + for (idx, &byte) in ctx.rlp_bytes()[34..36].into_iter().enumerate() { require!((FixedTableTag::RangeKeyLen256, a!(byte), cb.get_length_s() - 32.expr() - (idx + 1).expr()) => @"fixed"); } }} @@ -446,8 +376,6 @@ impl MPTConfig { position_cols, inter_start_root, inter_final_root, - value_prev, - value, s_main, c_main, managed_columns, @@ -458,7 +386,7 @@ impl MPTConfig { branch_config: row_config.branch_config, storage_config: row_config.storage_config, account_config: row_config.account_config, - randomness, + r: randomness, mpt_table, cb, } @@ -469,9 +397,9 @@ impl MPTConfig { &mut self, layouter: &mut impl Layouter, witness: &mut [MptWitnessRow], - randomness: F, + r: F, ) { - self.randomness = randomness; + self.r = r; let mut height = 0; // TODO(Brecht): change this on the witness generation side @@ -570,19 +498,19 @@ impl MPTConfig { pv.memory[parent_memory(true)].witness_store( offset, &[ - row.s_root_bytes_rlc(self.randomness), + row.s_root_bytes_rlc(self.r), true.scalar(), false.scalar(), - row.s_root_bytes_rlc(self.randomness), + row.s_root_bytes_rlc(self.r), ], ); pv.memory[parent_memory(false)].witness_store( offset, &[ - row.c_root_bytes_rlc(self.randomness), + row.c_root_bytes_rlc(self.r), true.scalar(), false.scalar(), - row.c_root_bytes_rlc(self.randomness), + row.c_root_bytes_rlc(self.r), ], ); //println!("set root: {} -> {:?}", offset, @@ -590,12 +518,7 @@ impl MPTConfig { } //println!("{} -> {:?}", offset, row.get_type()); - region.assign_fixed( - || "q_enable", - self.position_cols.q_enable, - offset, - || Value::known(F::one()), - )?; + assignf!(region, (self.position_cols.q_enable, offset) => 1.scalar())?; height += 1; if row.get_type() == MptWitnessRowType::AccountLeafKeyS { @@ -604,19 +527,8 @@ impl MPTConfig { } let q_not_first = if idx == 0 { F::zero() } else { F::one() }; - region.assign_fixed( - || "not first", - self.position_cols.q_not_first, - offset, - || Value::known(q_not_first), - )?; - - region.assign_advice( - || "not first level", - self.position_cols.not_first_level, - offset, - || Value::known(F::from(row.not_first_level() as u64)), - )?; + assignf!(region, (self.position_cols.q_not_first, offset) => q_not_first)?; + assign!(region, (self.position_cols.not_first_level, offset) => row.not_first_level().scalar())?; row.assign_lookup_columns(&mut region, self, &pv, offset)?; @@ -631,7 +543,6 @@ impl MPTConfig { pv.key_rlc_mult = F::one(); pv.key_rlc_prev = F::zero(); pv.key_rlc_mult_prev = F::one(); - pv.nibbles_num = 0; } if offset > 0 && prev_row.get_type() == MptWitnessRowType::InitBranch { @@ -694,111 +605,54 @@ impl MPTConfig { // Zero lookup for fixed_table in self.fixed_table.iter() { - region.assign_fixed( - || "fixed table zero", - *fixed_table, - offset, - || Value::known(F::zero()), - )?; + assignf!(region, (*fixed_table, offset) => 0.scalar())?; } offset += 1; + // Mult table let mut mult = F::one(); for ind in 0..(2 * HASH_WIDTH + 1) { - region.assign_fixed( - || "fixed table", - self.fixed_table[0], - offset, - || Value::known(F::from(FixedTableTag::RMult as u64)), - )?; - - region.assign_fixed( - || "fixed table", - self.fixed_table[1], - offset, - || Value::known(F::from(ind as u64)), - )?; - - region.assign_fixed( - || "fixed table", - self.fixed_table[2], - offset, - || Value::known(mult), - )?; + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::RMult.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => ind.scalar())?; + assignf!(region, (self.fixed_table[2], offset) => mult)?; mult *= randomness; - offset += 1; } + // Byte range table for ind in 0..256 { - region.assign_fixed( - || "fixed table", - self.fixed_table[0], - offset, - || Value::known(F::from(FixedTableTag::Range256 as u64)), - )?; - - region.assign_fixed( - || "fixed table", - self.fixed_table[1], - offset, - || Value::known(F::from(ind as u64)), - )?; - + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::Range256.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => ind.scalar())?; offset += 1; } + // Byte range with length table + // These fixed rows enable to easily check whether there are zeros in the unused columns (the number of unused columns vary). + // The lookups ensure that when the unused columns start, the values in these columns are zeros - + // when the unused columns start, the value that is used for the lookup in the last column is negative + // and thus a zero is enforced. let max_length = 34i32 + 1; for (tag, range) in [ (FixedTableTag::RangeKeyLen256, 256), (FixedTableTag::RangeKeyLen16, 16), ] { - for n in /* -192-max_length */ -512..max_length { + for n in -512..max_length { let range = if n < 0 { 1 } else { range }; for idx in 0..range { - region.assign_fixed( - || "fixed table[0]", - self.fixed_table[0], - offset, - || Value::known(F::from(tag as u64)), - )?; - - region.assign_fixed( - || "fixed table[1]", - self.fixed_table[1], - offset, - || Value::known(F::from(idx as u64)), - )?; - let v = F::from(n.unsigned_abs() as u64) * if n.is_negative() { -F::one() } else { F::one() }; - region.assign_fixed( - || "fixed table[2]", - self.fixed_table[2], - offset, - || Value::known(v), - )?; - + assignf!(region, (self.fixed_table[0], offset) => tag.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => idx.scalar())?; + assignf!(region, (self.fixed_table[2], offset) => v)?; offset += 1; } } } + // Nibble range table for ind in 0..16 { - region.assign_fixed( - || "fixed table", - self.fixed_table[0], - offset, - || Value::known(F::from(FixedTableTag::Range16 as u64)), - )?; - - region.assign_fixed( - || "fixed table", - self.fixed_table[1], - offset, - || Value::known(F::from(ind as u64)), - )?; - + assignf!(region, (self.fixed_table[0], offset) => FixedTableTag::Range16.scalar())?; + assignf!(region, (self.fixed_table[1], offset) => ind.scalar())?; offset += 1; } diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index ed67cdde06..3569ec344c 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -23,7 +23,7 @@ use crate::{ mpt_circuit::{witness_row::MptWitnessRow, MPTContext}, }; -use super::helpers::{LeafKeyGadget, RLPValueGadget}; +use super::helpers::{LeafKeyGadget, RLPValueGadget, ParentDataWitness}; use super::{ helpers::bytes_into_rlc, param::{ @@ -149,11 +149,9 @@ impl AccountLeafConfig { config.rlp_codehash[is_s.idx()] = RLPValueGadget::construct(&mut cb.base, &codehash_bytes[is_s.idx()][1..]); - ifx! {not!(and::expr(&[a!(ctx.proof_type.is_non_existing_account_proof), not!(config.is_wrong_leaf)])) => { - // Storage root and codehash are always 32-byte hashes. - require!(config.rlp_storage[is_s.idx()].len() => HASH_WIDTH); - require!(config.rlp_codehash[is_s.idx()].len() => HASH_WIDTH); - }} + // Storage root and codehash are always 32-byte hashes. + require!(config.rlp_storage[is_s.idx()].len() => HASH_WIDTH); + require!(config.rlp_codehash[is_s.idx()].len() => HASH_WIDTH); config.key_mult[is_s.idx()] = cb.base.query_cell(); config.nonce_mult[is_s.idx()] = cb.base.query_cell(); @@ -163,7 +161,6 @@ impl AccountLeafConfig { require!((FixedTableTag::RMult, config.rlp_balance[is_s.idx()].num_bytes(), config.balance_mult[is_s.idx()].expr()) => @format!("fixed")); // RLC bytes zero check - // TODO(Brecht): add all these checks back cb.set_length(rlp_key.num_bytes_on_key_row()); let nonce_rlp_rlc; @@ -215,21 +212,19 @@ impl AccountLeafConfig { // Check the RLP encoding consistency. // RlP encoding: account = [key, [nonce, balance, storage, codehash]] - ifx! {not!(and::expr(&[a!(ctx.proof_type.is_non_existing_account_proof), not!(config.is_wrong_leaf)])) => { - // We always store between 55 and 256 bytes of data in the values list. - require!(value_rlp_bytes[is_s.idx()][0] => RLP_LONG + 1); - // The RLP encoded list always has 2 RLP bytes (the c RLP bytes). - require!(value_rlp_bytes[is_s.idx()][1] => value_rlp_bytes[is_s.idx()][3].expr() + 2.expr()); - // `c_main.rlp1` always needs to be RLP_LIST_LONG + 1. - require!(value_rlp_bytes[is_s.idx()][2] => RLP_LIST_LONG + 1); - // The length of the list is `#(nonce bytes) + #(balance bytes) + 2 * (1 + #(hash))`. - require!(value_rlp_bytes[is_s.idx()][3] => config.rlp_nonce[is_s.idx()].num_bytes() + config.rlp_balance[is_s.idx()].num_bytes() + (2 * (1 + 32)).expr()); - // Now check that the the key and value list length matches the account length. - // The RLP encoded string always has 2 RLP bytes (the s RLP bytes). - let value_list_num_bytes = value_rlp_bytes[is_s.idx()][1].expr() + 2.expr(); - // Account length needs to equal all key bytes and all values list bytes. - require!(config.rlp_key[is_s.idx()].num_bytes() => config.rlp_key[is_s.idx()].num_bytes_on_key_row() + value_list_num_bytes); - }} + // We always store between 55 and 256 bytes of data in the values list. + require!(value_rlp_bytes[is_s.idx()][0] => RLP_LONG + 1); + // The RLP encoded list always has 2 RLP bytes (the c RLP bytes). + require!(value_rlp_bytes[is_s.idx()][1] => value_rlp_bytes[is_s.idx()][3].expr() + 2.expr()); + // `c_main.rlp1` always needs to be RLP_LIST_LONG + 1. + require!(value_rlp_bytes[is_s.idx()][2] => RLP_LIST_LONG + 1); + // The length of the list is `#(nonce bytes) + #(balance bytes) + 2 * (1 + #(hash))`. + require!(value_rlp_bytes[is_s.idx()][3] => config.rlp_nonce[is_s.idx()].num_bytes() + config.rlp_balance[is_s.idx()].num_bytes() + (2 * (1 + 32)).expr()); + // Now check that the the key and value list length matches the account length. + // The RLP encoded string always has 2 RLP bytes (the s RLP bytes). + let value_list_num_bytes = value_rlp_bytes[is_s.idx()][1].expr() + 2.expr(); + // Account length needs to equal all key bytes and all values list bytes. + require!(config.rlp_key[is_s.idx()].num_bytes() => config.rlp_key[is_s.idx()].num_bytes_on_key_row() + value_list_num_bytes); // Key done, set the starting values KeyData::store( @@ -285,7 +280,7 @@ impl AccountLeafConfig { // RLC bytes zero check cb.set_length(config.drifted_rlp_key.num_bytes_on_key_row()); config.drifted_mult = cb.base.query_cell(); - require!((FixedTableTag::RMult, config.drifted_rlp_key.num_bytes_on_key_row(), config.drifted_mult.expr()) => @"mult"); + require!((FixedTableTag::RMult, config.drifted_rlp_key.num_bytes_on_key_row(), config.drifted_mult.expr()) => @"fixed"); // Check that the drifted leaf is unchanged and is stored at `drifted_index`. let calc_rlc = |is_s: bool| { @@ -470,6 +465,7 @@ impl AccountLeafConfig { let mut balance_value_rlc = vec![0.scalar(); 2]; let mut storage_value_rlc = vec![0.scalar(); 2]; let mut codehash_value_rlc = vec![0.scalar(); 2]; + let mut parent_data = vec![ParentDataWitness::default(); 2]; for is_s in [true, false] { let key_row = &key_bytes[is_s.idx()]; @@ -480,7 +476,7 @@ impl AccountLeafConfig { 0, )?; - let parent_values = self.parent_data[is_s.idx()].witness_load( + parent_data[is_s.idx()] = self.parent_data[is_s.idx()].witness_load( region, base_offset, &mut pv.memory[parent_memory(is_s)], @@ -490,8 +486,8 @@ impl AccountLeafConfig { self.is_empty_trie[is_s.idx()].assign( region, base_offset, - parent_values[0], - ctx.randomness, + parent_data[is_s.idx()].rlc, + ctx.r, )?; let rlp_key_witness = @@ -517,41 +513,35 @@ impl AccountLeafConfig { &codehash_bytes[is_s.idx()][1..], )?; - nonce_value_rlc[is_s.idx()] = nonce_witness.rlc_value(ctx.randomness); - balance_value_rlc[is_s.idx()] = balance_witness.rlc_value(ctx.randomness); - storage_value_rlc[is_s.idx()] = storage_witness.rlc_value(ctx.randomness); - codehash_value_rlc[is_s.idx()] = codehash_witness.rlc_value(ctx.randomness); + nonce_value_rlc[is_s.idx()] = nonce_witness.rlc_value(ctx.r); + balance_value_rlc[is_s.idx()] = balance_witness.rlc_value(ctx.r); + storage_value_rlc[is_s.idx()] = storage_witness.rlc_value(ctx.r); + codehash_value_rlc[is_s.idx()] = codehash_witness.rlc_value(ctx.r); // + 4 because of s_rlp1, s_rlp2, c_rlp1, c_rlp2 let mut mult_nonce = F::one(); for _ in 0..nonce_witness.num_bytes() + 4 { - mult_nonce *= ctx.randomness; + mult_nonce *= ctx.r; } let mut mult_balance = F::one(); for _ in 0..balance_witness.num_bytes() { - mult_balance *= ctx.randomness; + mult_balance *= ctx.r; } self.nonce_mult[is_s.idx()].assign(region, base_offset, mult_nonce)?; self.balance_mult[is_s.idx()].assign(region, base_offset, mult_balance)?; // Key - // For leaf S and leaf C we need to start with the same rlc. - let is_branch_placeholder = if is_s { - pv.is_branch_s_placeholder - } else { - pv.is_branch_c_placeholder - }; - let (key_rlc_new, key_rlc_mult) = if is_branch_placeholder { + let (key_rlc_new, key_rlc_mult) = if parent_data[is_s.idx()].is_placeholder { (pv.key_rlc_prev, pv.key_rlc_mult_prev) } else { (pv.key_rlc, pv.key_rlc_mult) }; (key_rlc[is_s.idx()], _) = - rlp_key_witness.leaf_key_rlc(key_rlc_new, key_rlc_mult, ctx.randomness); + rlp_key_witness.leaf_key_rlc(key_rlc_new, key_rlc_mult, ctx.r); let mut key_mult = F::one(); for _ in 0..rlp_key_witness.num_bytes_on_key_row() { - key_mult *= ctx.randomness; + key_mult *= ctx.r; } self.key_mult[is_s.idx()].assign(region, base_offset, key_mult)?; @@ -582,10 +572,10 @@ impl AccountLeafConfig { } // Drifted leaf handling - if pv.is_branch_s_placeholder || pv.is_branch_c_placeholder { + if parent_data[true.idx()].is_placeholder || parent_data[false.idx()].is_placeholder { // TODO(Brecht): Change how the witness is generated let drifted_bytes = &mut witness[base_offset + 6].bytes; - let key_bytes = if pv.is_branch_s_placeholder { + let key_bytes = if parent_data[true.idx()].is_placeholder { &key_bytes[true.idx()] } else { &key_bytes[false.idx()] @@ -598,7 +588,7 @@ impl AccountLeafConfig { self.drifted_rlp_key .assign(region, base_offset, &drifted_bytes)?; - let (_, leaf_mult) = drifted_key_witness.rlc_leaf(ctx.randomness); + let (_, leaf_mult) = drifted_key_witness.rlc_leaf(ctx.r); self.drifted_mult.assign(region, base_offset, leaf_mult)?; } @@ -623,9 +613,9 @@ impl AccountLeafConfig { let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes)?; let (key_rlc_wrong, _) = - wrong_witness.leaf_key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.randomness); + wrong_witness.leaf_key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.r); - let address_rlc = bytes_into_rlc(row.address_bytes(), ctx.randomness); + let address_rlc = bytes_into_rlc(row.address_bytes(), ctx.r); self.check_is_wrong_leaf.assign( region, base_offset, diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index 2b84a7bd24..d363d03269 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -6,7 +6,7 @@ use halo2_proofs::{ }; use super::{ - helpers::{MPTConstraintBuilder, RLPListGadget, RLPItemGadget, LeafKeyGadget, RLPItemWitness}, + helpers::{MPTConstraintBuilder, RLPListGadget, RLPItemGadget, LeafKeyGadget, RLPItemWitness, ParentDataWitness}, param::{ ARITY, IS_BRANCH_C_PLACEHOLDER_POS, }, @@ -20,7 +20,7 @@ use crate::{ }, mpt_circuit::{ helpers::{ - get_num_nibbles, key_memory, parent_memory, Indexable, + key_memory, parent_memory, Indexable, KeyData, ParentData, }, param::{RLP_NIL}, @@ -33,7 +33,7 @@ use crate::{ IS_BRANCH_S_PLACEHOLDER_POS, IS_EXT_LONG_EVEN_C16_POS, IS_EXT_LONG_EVEN_C1_POS, IS_EXT_LONG_ODD_C16_POS, IS_EXT_LONG_ODD_C1_POS, IS_EXT_SHORT_C16_POS, IS_EXT_SHORT_C1_POS, - }, + }, helpers::num_nibbles, }, mpt_circuit::{witness_row::MptWitnessRow}, mpt_circuit::{MPTConfig, ProofValues}, @@ -64,10 +64,10 @@ pub(crate) struct BranchConfig { is_extension: Cell, ext_rlp_key: LeafKeyGadget, ext_rlp_value: [RLPItemGadget; 2], - ext_mult_key: Cell, + ext_mult: Cell, ext_is_not_hashed: LtGadget, ext_is_key_part_odd: Cell, - ext_mult_key_len: Cell, + ext_mult_key: Cell, } impl BranchConfig { @@ -131,6 +131,7 @@ impl BranchConfig { parent_rlc_c, ) = ifx! {config.is_extension => { config.ext_rlp_key = LeafKeyGadget::construct(&mut cb.base, &ext_key_bytes[0]); + // TODO(Brecht): add lookup constraint config.ext_is_key_part_odd = cb.base.query_cell(); // We need to check that the nibbles we stored in s are between 0 and 15. @@ -147,12 +148,12 @@ impl BranchConfig { require!(config.ext_rlp_key.len() => config.ext_rlp_key.key_num_bytes() + config.ext_rlp_value[is_s.idx()].num_bytes()); // Update the multiplier with the number of bytes on the first row - config.ext_mult_key = cb.base.query_cell(); - require!((FixedTableTag::RMult, config.ext_rlp_key.num_bytes_on_key_row(), config.ext_mult_key.expr()) => @"fixed"); + config.ext_mult = cb.base.query_cell(); + require!((FixedTableTag::RMult, config.ext_rlp_key.num_bytes_on_key_row(), config.ext_mult.expr()) => @"fixed"); } // Extension node RLC - let ext_node_rlc = (config.ext_rlp_key.rlc(&r), config.ext_mult_key.expr()).rlc_chain( + let ext_node_rlc = (config.ext_rlp_key.rlc(&r), config.ext_mult.expr()).rlc_chain( config.ext_rlp_value[is_s.idx()].rlc_rlp(&mut cb.base, &r) ); // Branch value data zero check @@ -186,7 +187,7 @@ impl BranchConfig { // Calculate the number of bytes let key_len = config.ext_rlp_key.key_len(); // Calculate the number of nibbles - let num_nibbles = get_num_nibbles(key_len.expr(), config.ext_is_key_part_odd.expr()); + let num_nibbles = num_nibbles::expr(key_len.expr(), config.ext_is_key_part_odd.expr()); // Make sure the nibble counter is updated correctly let num_nibbles = config.key_data.num_nibbles.expr() + num_nibbles.expr(); @@ -202,7 +203,6 @@ impl BranchConfig { // Currently, the extension node S and extension node C both have the same key RLC - // however, sometimes extension node can be replaced by a shorter extension node // (in terms of nibbles), this is still to be implemented. - // TODO: extension nodes of different nibbles length let key_rlc_post_ext = config.key_data.rlc.expr() + config.ext_rlp_key.ext_key_rlc( &mut cb.base, @@ -218,14 +218,14 @@ impl BranchConfig { let key_len = config.ext_rlp_key.key_len(); let key_num_bytes_for_mult = key_len - ifx! {not!(config.key_data.is_odd.expr() * config.ext_is_key_part_odd.expr()) => { 1.expr() }}; // Get the multiplier for this key length - config.ext_mult_key_len = cb.base.query_cell(); - require!((FixedTableTag::RMult, key_num_bytes_for_mult, config.ext_mult_key_len.expr()) => @"fixed"); + config.ext_mult_key = cb.base.query_cell(); + require!((FixedTableTag::RMult, key_num_bytes_for_mult, config.ext_mult_key.expr()) => @"fixed"); ( num_nibbles, is_key_odd, key_rlc_post_ext, - config.key_data.mult.expr() * config.ext_mult_key_len.expr(), + config.key_data.mult.expr() * config.ext_mult_key.expr(), false.expr(), false.expr(), ext_branch_rlp_rlc[true.idx()].expr(), @@ -388,34 +388,6 @@ impl BranchConfig { }} } - // Set the branch we'll take - for node_index in 0..ARITY { - for is_s in [true, false] { - ifx! {config.is_placeholder[is_s.idx()] => { - ifx!{config.is_drifted[node_index].expr() => { - // TODO(Brecht): should we actually do !is_s - let child_rlc = config.branches[(!is_s).idx()][node_index].rlp.rlc_branch(&r); - require!(config.mod_branch_rlc[is_s.idx()] => child_rlc); - ParentData::store( - &mut cb.base, - &ctx.memory[parent_memory(is_s)], - [config.parent_data[is_s.idx()].rlc.expr(), config.parent_data[is_s.idx()].is_root.expr(), true.expr(), child_rlc] - ); - }} - } elsex { - ifx!{config.is_modified[node_index].expr() => { - let child_rlc = config.branches[is_s.idx()][node_index].rlp.rlc_branch(&r); - require!(config.mod_branch_rlc[is_s.idx()] => child_rlc); - ParentData::store( - &mut cb.base, - &ctx.memory[parent_memory(is_s)], - [child_rlc.expr(), false.expr(), false.expr(), child_rlc] - ); - }} - }} - } - } - // Update the nibble counter let num_nibbles = num_nibbles + 1.expr(); @@ -433,6 +405,7 @@ impl BranchConfig { let key_rlc_post_branch = key_rlc_post_ext.expr() + modified_index.expr() * nibble_mult.expr() * key_mult_post_ext.expr(); let key_mult_post_branch = key_mult_post_ext.expr() * mult.expr(); + // Set the new keys // TODO(Brecht): Probably best to add checks that when placeholder another branch cannot follow etc.. for is_s in [true, false] { ifx! {not!(config.is_placeholder[is_s.idx()].expr()) => { @@ -471,6 +444,34 @@ impl BranchConfig { ); }} } + + // Set the branch we'll take + for node_index in 0..ARITY { + for is_s in [true, false] { + ifx! {config.is_placeholder[is_s.idx()] => { + ifx!{config.is_drifted[node_index].expr() => { + // TODO(Brecht): should we actually do !is_s + let child_rlc = config.branches[(!is_s).idx()][node_index].rlp.rlc_branch(&r); + require!(config.mod_branch_rlc[is_s.idx()] => child_rlc); + ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [config.parent_data[is_s.idx()].rlc.expr(), config.parent_data[is_s.idx()].is_root.expr(), true.expr(), child_rlc] + ); + }} + } elsex { + ifx!{config.is_modified[node_index].expr() => { + let child_rlc = config.branches[is_s.idx()][node_index].rlp.rlc_branch(&r); + require!(config.mod_branch_rlc[is_s.idx()] => child_rlc); + ParentData::store( + &mut cb.base, + &ctx.memory[parent_memory(is_s)], + [child_rlc.expr(), false.expr(), false.expr(), child_rlc] + ); + }} + }} + } + } }); config @@ -488,9 +489,30 @@ impl BranchConfig { let offset = offset - 1; let row_init = witness[offset].to_owned(); - //let row_branches: [MptWitnessRow; ARITY] = array_init::array_init(|i| witness[offset + 1 + i].to_owned()); - let row_ext_s = witness[offset + 1 + ARITY].to_owned(); + let is_placeholder = [ + row_init.get_byte(IS_BRANCH_S_PLACEHOLDER_POS) == 1, + row_init.get_byte(IS_BRANCH_C_PLACEHOLDER_POS) == 1, + ]; + + let modified_index = row_init.get_byte(BRANCH_0_KEY_POS) as usize; + let mut drifted_index = row_init.get_byte(DRIFTED_POS) as usize; + // If no placeholder branch, we set `drifted_pos = modified_node`. This + // is needed just to make some other constraints (`s_mod_node_hash_rlc` + // and `c_mod_node_hash_rlc` correspond to the proper node) easier to write. + if !is_placeholder[true.idx()] && !is_placeholder[false.idx()] { + drifted_index = modified_index; + } + + let is_extension_node = row_init.get_byte(IS_EXT_LONG_ODD_C16_POS) + + row_init.get_byte(IS_EXT_LONG_ODD_C1_POS) + + row_init.get_byte(IS_EXT_SHORT_C16_POS) + + row_init.get_byte(IS_EXT_SHORT_C1_POS) + + row_init.get_byte(IS_EXT_LONG_EVEN_C16_POS) + + row_init.get_byte(IS_EXT_LONG_EVEN_C1_POS) + == 1; + + // Data let rlp_bytes = [ row_init.bytes[4..7].to_owned(), row_init.bytes[7..10].to_owned(), @@ -508,130 +530,88 @@ impl BranchConfig { witness[offset + 18].bytes[34..68].to_owned(), ]; - pv.modified_node = row_init.get_byte(BRANCH_0_KEY_POS); - pv.drifted_pos = row_init.get_byte(DRIFTED_POS); - - pv.is_even = - row_init.get_byte(IS_EXT_LONG_EVEN_C16_POS) + row_init.get_byte(IS_EXT_LONG_EVEN_C1_POS) == 1; - pv.is_odd = row_init.get_byte(IS_EXT_LONG_ODD_C16_POS) - + row_init.get_byte(IS_EXT_LONG_ODD_C1_POS) - + row_init.get_byte(IS_EXT_SHORT_C16_POS) - + row_init.get_byte(IS_EXT_SHORT_C1_POS) - == 1; - let is_extension_node = pv.is_even || pv.is_odd; - - pv.is_branch_s_placeholder = row_init.get_byte(IS_BRANCH_S_PLACEHOLDER_POS) == 1; - pv.is_branch_c_placeholder = row_init.get_byte(IS_BRANCH_C_PLACEHOLDER_POS) == 1; - - let is_placeholder = [ - pv.is_branch_s_placeholder, - pv.is_branch_c_placeholder, - ]; - - // If no placeholder branch, we set `drifted_pos = modified_node`. This - // is needed just to make some other constraints (`s_mod_node_hash_rlc` - // and `c_mod_node_hash_rlc` correspond to the proper node) easier to write. - if !is_placeholder[true.idx()] && !is_placeholder[false.idx()] { - pv.drifted_pos = pv.modified_node; - } - - let modified_index = pv.modified_node as usize; - let drifted_index = pv.drifted_pos as usize; - self.is_extension.assign(region, base_offset, is_extension_node.scalar())?; - let key_values = self.key_data.witness_load( + let key_data = self.key_data.witness_load( region, base_offset, &pv.memory[key_memory(true)], 0, )?; - - /* Extension */ - - let ext_key_witness = self.ext_rlp_key.assign(region, base_offset, &ext_key_bytes[0])?; - let mut ext_is_key_part_odd = false; - if is_extension_node { - let first_byte_index = if ext_key_witness.rlp_list.is_short() { - if ext_key_witness.short_list_value.is_short() { - 1 - } else { - 2 - } - } else { - if ext_key_witness.short_list_value.is_long() { - 2 - } else { - 3 - } - }; - ext_is_key_part_odd = ext_key_bytes[0][first_byte_index] >> 4 == 1; - self.ext_is_not_hashed.assign(region, base_offset, ext_key_witness.num_bytes().scalar(), HASH_WIDTH.scalar())?; - self.ext_is_key_part_odd.assign(region, base_offset, ext_is_key_part_odd.scalar())?; - let mut ext_mult_key= F::one(); - for _ in 0..ext_key_witness.num_bytes_on_key_row() { - ext_mult_key *= mpt_config.randomness; - } - self.ext_mult_key.assign(region, base_offset, ext_mult_key)?; - } + let mut parent_data = vec![ParentDataWitness::default(); 2]; for is_s in [true, false] { - self.ext_rlp_value[is_s.idx()].assign(region, base_offset, &ext_value_bytes[is_s.idx()])?; + parent_data[is_s.idx()] = self.parent_data[is_s.idx()].witness_load( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + 0, + )?; } pv.key_rlc_prev = pv.key_rlc; pv.key_rlc_mult_prev = pv.key_rlc_mult; + let mut num_nibbles = key_data.num_nibbles; let mut key_rlc_post_ext = pv.key_rlc; let mut key_mult_post_ext = pv.key_rlc_mult; - let mut is_key_odd = pv.nibbles_num % 2 == 1; + let mut is_key_odd = key_data.is_odd; + + /* Extension */ + + let ext_rlp_key = self.ext_rlp_key.assign(region, base_offset, &ext_key_bytes[0])?; if is_extension_node { + let mut ext_mult= F::one(); + for _ in 0..ext_rlp_key.num_bytes_on_key_row() { + ext_mult *= mpt_config.r; + } + self.ext_mult.assign(region, base_offset, ext_mult)?; + + let first_byte_index = ext_rlp_key.rlp_list.num_rlp_bytes() + + if ext_rlp_key.rlp_list.is_short() { + ext_rlp_key.short_list_value.num_rlp_bytes() + } else { + ext_rlp_key.long_list_value.num_rlp_bytes() + }; + let ext_is_key_part_odd = ext_key_bytes[0][first_byte_index] >> 4 == 1; + self.ext_is_key_part_odd.assign(region, base_offset, ext_is_key_part_odd.scalar())?; + + self.ext_is_not_hashed.assign(region, base_offset, ext_rlp_key.num_bytes().scalar(), HASH_WIDTH.scalar())?; + + let mut key_len_mult = ext_rlp_key.key_len(); + if !(is_key_odd && ext_is_key_part_odd) { + key_len_mult -= 1; + } + + // Update number of nibbles + num_nibbles += num_nibbles::value(ext_rlp_key.key_len(), ext_is_key_part_odd); + + // Update parity is_key_odd = if ext_is_key_part_odd { !is_key_odd } else { is_key_odd }; - let (key_rlc_ext, _) = ext_key_witness.ext_key_rlc( + // Key RLC + let (key_rlc_ext, _) = ext_rlp_key.ext_key_rlc( pv.key_rlc_mult, ext_is_key_part_odd, !is_key_odd, ext_key_bytes.clone(), - mpt_config.randomness, + mpt_config.r, ); key_rlc_post_ext = pv.key_rlc + key_rlc_ext; - let mut key_len = ext_key_witness.key_len(); - if !((key_values[3].get_lower_32() % 2 == 1) && ext_is_key_part_odd) { - key_len -= 1; - } - let mut ext_mult_key_len = 1.scalar(); - for _ in 0..key_len { - ext_mult_key_len = ext_mult_key_len * mpt_config.randomness; + // Key mult + let mut ext_mult_key = 1.scalar(); + for _ in 0..key_len_mult { + ext_mult_key = ext_mult_key * mpt_config.r; } - self.ext_mult_key_len.assign(region, base_offset, ext_mult_key_len)?; - - key_mult_post_ext = pv.key_rlc_mult * ext_mult_key_len; + self.ext_mult_key.assign(region, base_offset, ext_mult_key)?; + key_mult_post_ext = pv.key_rlc_mult * ext_mult_key; } - - if is_extension_node { - let ext_nibbles: usize; - if row_ext_s.get_byte(1) <= 32 { - ext_nibbles = 1 - } else if row_ext_s.get_byte(0) < 248 { - if row_ext_s.get_byte(2) == 0 { - // even number of nibbles - ext_nibbles = ((row_ext_s.get_byte(1) - 128) as usize - 1) * 2; - } else { - ext_nibbles = (row_ext_s.get_byte(1) - 128) as usize * 2 - 1; - } - } else if row_ext_s.get_byte(3) == 0 { - // even number of nibbles - ext_nibbles = ((row_ext_s.get_byte(2) - 128) as usize - 1) * 2; - } else { - ext_nibbles = (row_ext_s.get_byte(2) - 128) as usize * 2 - 1; - } - - pv.nibbles_num += ext_nibbles; + for is_s in [true, false] { + self.ext_rlp_value[is_s.idx()].assign(region, base_offset, &ext_value_bytes[is_s.idx()])?; } /* Branch */ @@ -653,16 +633,16 @@ impl BranchConfig { let mut node_mult_diff = F::one(); for _ in 0..child_witness.num_bytes() { - node_mult_diff *= mpt_config.randomness; + node_mult_diff *= mpt_config.r; } self.branches[is_s.idx()][node_index].mult.assign(region, base_offset, node_mult_diff)?; - self.branches[is_s.idx()][node_index].rlc_branch.assign(region, base_offset, child_witness.rlc_branch(mpt_config.randomness))?; + self.branches[is_s.idx()][node_index].rlc_branch.assign(region, base_offset, child_witness.rlc_branch(mpt_config.r))?; let is_hashed = self.branches[is_s.idx()][node_index].is_hashed.assign(region, base_offset, child_witness.len().scalar(), 32.scalar())?; let mod_pos = if is_placeholder[is_s.idx()] { drifted_index } else { modified_index }; if mod_pos == node_index { - mod_node_hash_rlc[is_s.idx()] = child_witness.rlc_branch(mpt_config.randomness); + mod_node_hash_rlc[is_s.idx()] = child_witness.rlc_branch(mpt_config.r); self.mod_branch_rlc[is_s.idx()].assign(region, base_offset, mod_node_hash_rlc[is_s.idx()])?; self.mod_branch_is_hashed[is_s.idx()].assign(region, base_offset, is_hashed)?; } @@ -676,40 +656,8 @@ impl BranchConfig { is_placeholder_leaf[is_s.idx()] = self.mod_branch_is_empty[is_s.idx()].assign(region, base_offset, branch_witnesses[is_s.idx()][modified_index].len().scalar())?; } - let mut parent_values = vec![Vec::new(); 2]; - for is_s in [true, false] { - parent_values[is_s.idx()] = self.parent_data[is_s.idx()].witness_load( - region, - base_offset, - &mut pv.memory[parent_memory(is_s)], - 0, - )?; - - if !is_placeholder[is_s.idx()] { - self.parent_data[is_s.idx()].witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(is_s)], - mod_node_hash_rlc[is_s.idx()], - false, - false, - mod_node_hash_rlc[is_s.idx()], - )?; - } else { - self.parent_data[is_s.idx()].witness_store( - region, - base_offset, - &mut pv.memory[parent_memory(is_s)], - parent_values[is_s.idx()][0], - parent_values[is_s.idx()][1] != F::zero(), - true, - mod_node_hash_rlc[is_s.idx()], - )?; - } - } - // one nibble is used for position in branch - pv.nibbles_num += 1; + num_nibbles += 1; // Update key parity let is_key_odd = !is_key_odd; @@ -720,14 +668,15 @@ impl BranchConfig { (16.scalar(), 1.scalar()) } else { // The nibble will be added as the least significant nibble, the multiplier needs to advance - (1.scalar(), mpt_config.randomness) + (1.scalar(), mpt_config.r) }; - let key_rlc_post_branch: F = key_rlc_post_ext + F::from(modified_index as u64) * nibble_mult * key_mult_post_ext; + let key_rlc_post_branch = key_rlc_post_ext + F::from(modified_index as u64) * nibble_mult * key_mult_post_ext; let key_mult_post_branch = key_mult_post_ext * mult; pv.key_rlc = key_rlc_post_branch; pv.key_rlc_mult = key_mult_post_branch; + // Set the new key for is_s in [true, false] { if !is_placeholder[is_s.idx()] { self.key_data.witness_store( @@ -736,11 +685,11 @@ impl BranchConfig { &mut pv.memory[key_memory(is_s)], pv.key_rlc, pv.key_rlc_mult, - pv.nibbles_num, + num_nibbles, is_placeholder_leaf[true.idx()] == 1.scalar(), is_placeholder_leaf[false.idx()] == 1.scalar(), 0, - pv.nibbles_num % 2 == 1, + is_key_odd, key_rlc_post_branch, key_mult_post_branch, )?; @@ -749,18 +698,42 @@ impl BranchConfig { region, base_offset, &mut pv.memory[key_memory(is_s)], - key_values[0], - key_values[1], - key_values[2].get_lower_32() as usize, + key_data.rlc, + key_data.mult, + key_data.num_nibbles, is_placeholder_leaf[true.idx()] == 1.scalar(), is_placeholder_leaf[false.idx()] == 1.scalar(), - pv.drifted_pos, - pv.nibbles_num % 2 == 1, + drifted_index, + is_key_odd, key_rlc_post_ext, key_mult_post_ext, )?; } } + // Set the new parents + for is_s in [true, false] { + if !is_placeholder[is_s.idx()] { + self.parent_data[is_s.idx()].witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + mod_node_hash_rlc[is_s.idx()], + false, + false, + mod_node_hash_rlc[is_s.idx()], + )?; + } else { + self.parent_data[is_s.idx()].witness_store( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + parent_data[is_s.idx()].rlc, + parent_data[is_s.idx()].is_root, + true, + mod_node_hash_rlc[is_s.idx()], + )?; + } + } Ok(()) } diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index c1728a8a0f..dd2eee07aa 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -323,20 +323,6 @@ impl RLPValueGadget { RLP_LONG_EXCLUSIVE..=RLP_VALUE_MAX => is_very_long = true, _ => is_list = true, } - /*const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT + 1; - const RLP_LONG_INCLUSIVE: u8 = RLP_LONG - 1; - const RLP_VALUE_MAX: u8 = RLP_LIST_SHORT - 1; - - let mut is_short = false; - let mut is_long = false; - let mut is_very_long = false; - let mut is_list = false; - match bytes[0] { - 0..=RLP_SHORT => is_short = true, - RLP_SHORT_INCLUSIVE..=RLP_LONG_INCLUSIVE => is_long = true, - RLP_LONG..=RLP_VALUE_MAX => is_very_long = true, - _ => is_list = true, - }*/ self.is_short.assign(region, offset, F::from(is_short))?; self.is_long.assign(region, offset, F::from(is_long))?; @@ -711,12 +697,12 @@ impl LeafKeyGadget { }) } - /// Returns the total length of the leaf (including RLP bytes) + /// Returns the number of bytes used by the list (including RLP bytes) pub(crate) fn num_bytes(&self) -> Expression { self.rlp_list.num_bytes() } - /// Length + /// Returns the total length of the list (excluding RLP bytes) pub(crate) fn len(&self) -> Expression { self.rlp_list.len() } @@ -780,7 +766,7 @@ impl LeafKeyGadget { } pub(crate) fn num_key_nibbles(&self, is_key_odd: Expression) -> Expression { - get_num_nibbles(self.key_len(), is_key_odd) + num_nibbles::expr(self.key_len(), is_key_odd) } } @@ -799,7 +785,7 @@ pub(crate) fn compute_acc_and_mult( } impl LeafKeyWitness { - /// Returns the total length of the leaf (including RLP bytes) + /// Returns the number of bytes used by the list (including RLP bytes) pub(crate) fn num_bytes(&self) -> usize { self.rlp_list.num_bytes() } @@ -945,6 +931,20 @@ pub(crate) struct KeyData { pub(crate) parent_mult: Cell, } +#[derive(Clone, Debug, Default)] +pub(crate) struct KeyDataWitness { + pub(crate) rlc: F, + pub(crate) mult: F, + pub(crate) num_nibbles: usize, + pub(crate) is_odd: bool, + pub(crate) is_placeholder_leaf_s: bool, + pub(crate) is_placeholder_leaf_c: bool, + pub(crate) placeholder_nibble: usize, + pub(crate) placeholder_is_odd: bool, + pub(crate) parent_rlc: F, + pub(crate) parent_mult: F, +} + impl Trackable for KeyData { fn as_any(&self) -> &dyn Any { self @@ -1031,16 +1031,11 @@ impl KeyData { num_nibbles: usize, is_placeholder_leaf_s: bool, is_placeholder_leaf_c: bool, - placeholder_nibble: u8, + placeholder_nibble: usize, placeholder_is_odd: bool, parent_rlc: F, parent_mult: F, ) -> Result<(), Error> { - //println!("offset: {}", offset); - //println!("key_rlc_prev: {:?}", pv.key_rlc_prev); - //println!("key_mult_prev: {:?}", pv.key_rlc_mult_prev); - //println!("nibbles_num_prev: {:?}", pv.nibbles_num_prev); - let values = [ rlc, mult, @@ -1064,14 +1059,9 @@ impl KeyData { offset: usize, memory: &MemoryBank, load_offset: usize, - ) -> Result, Error> { + ) -> Result, Error> { let values = memory.witness_load(load_offset); - //println!("offset: {}, values: {:?}", offset, values); - //println!("key_rlc_prev: {:?}", pv.key_rlc_prev); - //println!("key_mult_prev: {:?}", pv.key_rlc_mult_prev); - //println!("nibbles_num_prev: {:?}", pv.nibbles_num_prev); - self.rlc.assign(region, offset, values[0])?; self.mult.assign(region, offset, values[1])?; self.num_nibbles.assign(region, offset, values[2])?; @@ -1085,7 +1075,18 @@ impl KeyData { self.parent_rlc.assign(region, offset, values[8])?; self.parent_mult.assign(region, offset, values[9])?; - Ok(values) + Ok(KeyDataWitness { + rlc: values[0], + mult: values[1], + num_nibbles: values[2].get_lower_32() as usize, + is_odd: values[3] != F::zero(), + is_placeholder_leaf_s: values[4] != F::zero(), + is_placeholder_leaf_c: values[5] != F::zero(), + placeholder_nibble: values[6].get_lower_32() as usize, + placeholder_is_odd: values[7] != F::zero(), + parent_rlc: values[8], + parent_mult: values[9], + }) } } @@ -1097,6 +1098,14 @@ pub(crate) struct ParentData { pub(crate) placeholder_rlc: Cell, } +#[derive(Clone, Debug, Default)] +pub(crate) struct ParentDataWitness { + pub(crate) rlc: F, + pub(crate) is_root: bool, + pub(crate) is_placeholder: bool, + pub(crate) placeholder_rlc: F, +} + impl ParentData { pub(crate) fn load( description: &'static str, @@ -1144,10 +1153,6 @@ impl ParentData { is_placeholder: bool, placeholder_rlc: F, ) -> Result<(), Error> { - //println!("offset: {}", offset); - //println!("rlc: {:?}", rlc); - //println!("is_hashed: {}", is_hashed); - let values = [ rlc, force_hashed.scalar(), @@ -1165,7 +1170,7 @@ impl ParentData { offset: usize, memory: &MemoryBank, load_offset: usize, - ) -> Result, Error> { + ) -> Result, Error> { let values = memory.witness_load(load_offset); self.rlc.assign(region, offset, values[0])?; @@ -1173,7 +1178,12 @@ impl ParentData { self.is_placeholder.assign(region, offset, values[2])?; self.placeholder_rlc.assign(region, offset, values[3])?; - Ok(values) + Ok(ParentDataWitness { + rlc: values[0], + is_root: values[1] == 1.scalar(), + is_placeholder: values[2] == 1.scalar(), + placeholder_rlc: values[3], + }) } } @@ -1326,17 +1336,29 @@ pub(crate) mod get_num_bytes_list_short { } } -pub(crate) fn get_num_nibbles( - key_len: Expression, - is_key_odd: Expression, -) -> Expression { - circuit!([meta, _cb!()], { - ifx! {is_key_odd => { - key_len.expr() * 2.expr() - 1.expr() - } elsex { - (key_len.expr() - 1.expr()) * 2.expr() - }} - }) +// Returns the number of nibbles stored in a key value +pub(crate) mod num_nibbles { + use crate::{_cb, circuit}; + use crate::circuit_tools::constraint_builder::ConstraintBuilder; + use eth_types::Field; + use halo2_proofs::plonk::Expression; + + pub(crate) fn expr(key_len: Expression, is_key_odd: Expression) -> Expression { + circuit!([meta, _cb!()], { + ifx! {is_key_odd => { + key_len.expr() * 2.expr() - 1.expr() + } elsex { + (key_len.expr() - 1.expr()) * 2.expr() + }} + }) + } + pub(crate) fn value(key_len: usize, is_key_odd: bool) -> usize { + if is_key_odd { + key_len * 2 - 1 + } else { + (key_len - 1) * 2 + } + } } pub(crate) fn extend_rand(r: &[Expression]) -> Vec> { @@ -1381,6 +1403,9 @@ pub struct MPTConstraintBuilder { pub range_s: Vec<(Expression, Expression)>, } +/// Length is set in the configuration of the rows where unused columns might appear (and which need to be checked to be zeros). +/// From the vector of lengths, the expression is computed that returns the length of the used columns for each row. +/// This enables a generalised constraint (for all rows) for the values in the unused columns being zeros in mpt.rs. impl MPTConstraintBuilder { const DEFAULT_LENGTH_S: usize = 34; const DEFAULT_LENGTH_C: usize = 32; @@ -1620,12 +1645,6 @@ impl RLPItemGadget { } pub(crate) fn rlc_branch(&self, r: &[Expression]) -> Expression { - /*circuit!([meta, _cb!()], { - matchx! { - self.value.is_string() => self.value.rlc_value(r), - self.list.is_list() => self.list.rlc(r).1, - } - })*/ circuit!([meta, _cb!()], { matchx! { self.value.is_string() => self.value.rlc(r).0, @@ -1644,45 +1663,6 @@ impl RLPItemWitness { } } - // Single RLP byte containing the byte value - /*pub(crate) fn is_short(&self) -> bool { - matchr! { - self.value.is_string() => self.value.is_very_long(), - self.list.is_list() => self.list.is_very_long(), - } - } - - // Single RLP byte containing the length of the value - pub(crate) fn is_long(&self) -> bool { - self.is_long - } - - // RLP byte containing the lenght of the length, - // followed by the length, followed by the actual data - pub(crate) fn is_very_long(&self) -> bool { - self.is_very_long - } - - /// Number of RLP bytes - pub(crate) fn num_rlp_bytes(&self) -> usize { - matchr! { - self.is_short() => 0, - self.is_long() => 1, - self.is_very_long() => 2, - } - } - - /// Number of bytes in total (including RLP bytes) - pub(crate) fn num_bytes(&self) -> usize { - matchr! { - self.is_short() => 1, - self.is_long() => get_num_bytes_short::value(self.bytes[0]), - self.is_very_long() => { - unreachable!(); - }, - } - }*/ - /// Length of the value (excluding RLP bytes) pub(crate) fn len(&self) -> usize { matchr! { @@ -1691,38 +1671,7 @@ impl RLPItemWitness { } } - /// RLC data - /*pub(crate) fn rlc(&self, r: F) -> (F, F) { - matchr! { - self.is_short() => { - let value_rlc = self.bytes[0].scalar(); - (value_rlc, value_rlc) - }, - self.is_long() => { - let value_rlc = self.bytes[1..].rlc_value(r); - (value_rlc, self.bytes.rlc_value(r)) - }, - self.is_very_long() => { - unreachable!(); - }, - } - } - - pub(crate) fn rlc_rlp(&self, r: F) -> F { - self.rlc(r).1 - } - - pub(crate) fn rlc_value(&self, r: F) -> F { - self.rlc(r).0 - }*/ - pub(crate) fn rlc_branch(&self, r: F) -> F { - /*circuit!([meta, _cb!()], { - matchx! { - self.value.is_string() => self.value.rlc_value(r), - self.list.is_list() => self.list.rlc(r).1, - } - })*/ matchr! { self.value.is_string() => self.value.rlc(r).0, self.list.is_list() => self.list.rlc(r).1, diff --git a/zkevm-circuits/src/mpt_circuit/proof_chain.rs b/zkevm-circuits/src/mpt_circuit/proof_chain.rs index 372743e709..0d0173ee30 100644 --- a/zkevm-circuits/src/mpt_circuit/proof_chain.rs +++ b/zkevm-circuits/src/mpt_circuit/proof_chain.rs @@ -54,7 +54,7 @@ impl ProofChainConfig { let start_root = DataTransition::new(meta, ctx.inter_start_root); let final_root = DataTransition::new(meta, ctx.inter_final_root); - let address_rlc = DataTransition::new(meta, ctx.address_rlc); + let address_rlc = DataTransition::new(meta, ctx.mpt_table.address_rlc); /*let is_branch_or_account = is_account_leaf_key_s.expr() + is_branch_init.expr(); diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index 5b0847816b..f2e30905f9 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -6,7 +6,7 @@ use halo2_proofs::{ poly::Rotation, }; -use crate::circuit_tools::cell_manager::Cell; +use crate::{circuit_tools::cell_manager::Cell, mpt_circuit::helpers::ParentDataWitness}; use crate::circuit_tools::constraint_builder::{RLCChainable, RLCableValue}; use crate::circuit_tools::gadgets::{LtGadget, RequireNotZeroGadget}; use crate::mpt_circuit::helpers::{drifted_nibble_rlc, IsEmptyTreeGadget}; @@ -115,27 +115,18 @@ impl StorageLeafConfig { true, &r, ); - // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES (except in a - // placeholder leaf). - // TODO(Brecht): why not in placeholder leaf? - ifx! {not!(is_placeholder_leaf) => { - let num_nibbles = rlp_key.num_key_nibbles(key_data.is_odd.expr()); - require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); - }} + // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES + let num_nibbles = rlp_key.num_key_nibbles(key_data.is_odd.expr()); + require!(key_data.num_nibbles.expr() + num_nibbles => KEY_LEN_IN_NIBBLES); - // If `is_modified_node_empty = 1`, which means an empty child, we need to - // ensure that the value is set to 0 in the placeholder leaf. For - // example when adding a new storage leaf to the trie, we have an empty child in - // `S` proof and non-empty in `C` proof. + // Placeholder leaves default to value `0`. ifx! {is_placeholder_leaf => { require!(value_rlc[is_s.idx()] => 0); }} // Make sure the RLP encoding is correct. // storage = [key, value] - ifx! {not!(is_placeholder_leaf) => { - require!(rlp_key.num_bytes() => rlp_key.num_bytes_on_key_row() + config.rlp_value[is_s.idx()].num_bytes()); - }}; + require!(rlp_key.num_bytes() => rlp_key.num_bytes_on_key_row() + config.rlp_value[is_s.idx()].num_bytes()); // Check if the account is in its parent. // Check is skipped for placeholder leafs which are dummy leafs @@ -281,16 +272,24 @@ impl StorageLeafConfig { let lookup_offset = offset + 3; let wrong_offset = offset + 5; + let mut parent_data = vec![ParentDataWitness::default(); 2]; let mut key_rlc = vec![0.scalar(); 2]; let mut value_rlc = vec![0.scalar(); 2]; for is_s in [true, false] { // Key let key_row = &key_bytes[is_s.idx()]; + parent_data[is_s.idx()] = self.parent_data[is_s.idx()].witness_load( + region, + base_offset, + &mut pv.memory[parent_memory(is_s)], + 0, + )?; + let rlp_key_witness = self.rlp_key[is_s.idx()].assign(region, base_offset, &key_row.bytes)?; - let (_, leaf_mult) = rlp_key_witness.rlc_leaf(ctx.randomness); + let (_, leaf_mult) = rlp_key_witness.rlc_leaf(ctx.r); self.key_mult[is_s.idx()].assign(region, base_offset, leaf_mult)?; self.is_not_hashed[is_s.idx()].assign( @@ -321,19 +320,14 @@ impl StorageLeafConfig { F::one(), )?; - // For leaf S and leaf C we need to start with the same rlc. - let mut key_rlc_new = pv.key_rlc; - let mut key_rlc_mult_new = pv.key_rlc_mult; - if (pv.is_branch_s_placeholder - && key_row.get_type() == MptWitnessRowType::StorageLeafSKey) - || (pv.is_branch_c_placeholder - && key_row.get_type() == MptWitnessRowType::StorageLeafCKey) - { - key_rlc_new = pv.key_rlc_prev; - key_rlc_mult_new = pv.key_rlc_mult_prev; - } + // Key + let (key_rlc_new, key_rlc_mult) = if parent_data[is_s.idx()].is_placeholder { + (pv.key_rlc_prev, pv.key_rlc_mult_prev) + } else { + (pv.key_rlc, pv.key_rlc_mult) + }; (key_rlc[is_s.idx()], _) = - rlp_key_witness.leaf_key_rlc(key_rlc_new, key_rlc_mult_new, ctx.randomness); + rlp_key_witness.leaf_key_rlc(key_rlc_new, key_rlc_mult, ctx.r); // Value let value_row = &value_bytes[is_s.idx()]; @@ -343,14 +337,8 @@ impl StorageLeafConfig { value_rlc[is_s.idx()] = value_row.bytes [value_witness.num_rlp_bytes() as usize..HASH_WIDTH + 2] - .rlc_value(ctx.randomness); + .rlc_value(ctx.r); - let parent_values = self.parent_data[is_s.idx()].witness_load( - region, - base_offset, - &mut pv.memory[parent_memory(is_s)], - 0, - )?; self.parent_data[is_s.idx()].witness_store( region, base_offset, @@ -364,20 +352,20 @@ impl StorageLeafConfig { self.is_empty_trie[is_s.idx()].assign( region, base_offset, - parent_values[0], - ctx.randomness, + parent_data[is_s.idx()].rlc, + ctx.r, )?; } // Drifted leaf handling - if pv.is_branch_s_placeholder || pv.is_branch_c_placeholder { + if parent_data[true.idx()].is_placeholder || parent_data[false.idx()].is_placeholder { let row = &drifted_bytes; let drifted_key_witness = self.drifted_rlp_key .assign(region, base_offset, &row.bytes)?; - let (_, leaf_mult) = drifted_key_witness.rlc_leaf(ctx.randomness); + let (_, leaf_mult) = drifted_key_witness.rlc_leaf(ctx.r); self.drifted_mult.assign(region, base_offset, leaf_mult)?; } @@ -402,7 +390,7 @@ impl StorageLeafConfig { let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes)?; let (key_rlc_wrong, _) = - wrong_witness.leaf_key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.randomness); + wrong_witness.leaf_key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.r); self.check_is_wrong_leaf.assign( region, diff --git a/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountAfterFirstLevel.json b/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountAfterFirstLevel.json index f649a3b9d0..21d9e63d38 100644 --- a/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountAfterFirstLevel.json +++ b/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountAfterFirstLevel.json @@ -1 +1 @@ -[[0,1,0,1,249,1,49,249,1,49,14,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,0,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,0,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,0,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,194,199,153,182,10,12,214,172,212,44,16,21,81,40,114,232,108,24,107,207,25,110,133,6,30,118,132,47,59,124,248,96,0,160,194,199,153,182,10,12,214,172,212,44,16,21,81,40,114,232,108,24,107,207,25,110,133,6,30,118,132,47,59,124,248,96,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,0,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,0,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,123,92,219,73,235,134,229,100,19,175,139,32,58,144,71,107,191,38,132,61,243,212,96,190,152,153,159,211,0,24,138,140,0,160,123,92,219,73,235,134,229,100,19,175,139,32,58,144,71,107,191,38,132,61,243,212,96,190,152,153,159,211,0,24,138,140,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,0,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,0,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,17],[248,105,160,54,144,178,57,186,58,175,153,62,68,58,225,74,239,252,68,207,141,153,49,167,155,174,217,250,20,29,14,69,6,225,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,6],[248,105,160,54,144,178,57,186,58,175,153,62,68,58,225,74,239,252,68,207,141,153,49,167,155,174,217,250,20,29,14,69,6,225,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,4],[1,0,160,51,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,18],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,7],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,8],[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,9],[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,11],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,10],[249,1,49,128,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,128,128,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,160,194,199,153,182,10,12,214,172,212,44,16,21,81,40,114,232,108,24,107,207,25,110,133,6,30,118,132,47,59,124,248,96,128,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,128,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,128,160,123,92,219,73,235,134,229,100,19,175,139,32,58,144,71,107,191,38,132,61,243,212,96,190,152,153,159,211,0,24,138,140,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,128,128,5],[249,1,49,128,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,128,128,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,160,194,199,153,182,10,12,214,172,212,44,16,21,81,40,114,232,108,24,107,207,25,110,133,6,30,118,132,47,59,124,248,96,128,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,128,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,128,160,123,92,219,73,235,134,229,100,19,175,139,32,58,144,71,107,191,38,132,61,243,212,96,190,152,153,159,211,0,24,138,140,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,128,128,5],[248,105,160,54,144,178,57,186,58,175,153,62,68,58,225,74,239,252,68,207,141,153,49,167,155,174,217,250,20,29,14,69,6,225,49,184,70,248,68,128,1,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,5],[248,105,160,54,144,178,57,186,58,175,153,62,68,58,225,74,239,252,68,207,141,153,49,167,155,174,217,250,20,29,14,69,6,225,49,184,70,248,68,128,1,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,5]] \ No newline at end of file +[[0,1,0,1,249,1,17,249,1,17,14,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,0,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,0,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,0,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,232,31,94,199,101,22,45,72,175,88,225,83,40,225,68,67,200,149,65,19,130,105,242,195,115,70,197,49,209,63,178,186,0,160,232,31,94,199,101,22,45,72,175,88,225,83,40,225,68,67,200,149,65,19,130,105,242,195,115,70,197,49,209,63,178,186,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,0,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,0,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,0,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,0,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,17],[248,105,160,54,144,178,57,186,58,175,153,62,68,58,225,74,239,252,68,207,141,153,49,167,155,174,217,250,20,29,14,69,6,225,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,6],[248,105,160,54,144,178,57,186,58,175,153,62,68,58,225,74,239,252,68,207,141,153,49,167,155,174,217,250,20,29,14,69,6,225,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,4],[1,0,160,51,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,18],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,7],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,8],[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,9],[0,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,11],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,227,108,15,21,74,54,94,8,108,104,112,80,206,231,75,221,222,153,151,161,222,222,176,229,82,23,54,140,10,182,186,164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,10],[249,1,17,128,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,128,128,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,160,232,31,94,199,101,22,45,72,175,88,225,83,40,225,68,67,200,149,65,19,130,105,242,195,115,70,197,49,209,63,178,186,128,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,128,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,128,128,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,128,128,5],[249,1,17,128,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,128,128,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,160,232,31,94,199,101,22,45,72,175,88,225,83,40,225,68,67,200,149,65,19,130,105,242,195,115,70,197,49,209,63,178,186,128,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,128,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,128,128,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,128,128,5],[248,105,160,54,144,178,57,186,58,175,153,62,68,58,225,74,239,252,68,207,141,153,49,167,155,174,217,250,20,29,14,69,6,225,49,184,70,248,68,128,1,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,5],[248,105,160,54,144,178,57,186,58,175,153,62,68,58,225,74,239,252,68,207,141,153,49,167,155,174,217,250,20,29,14,69,6,225,49,184,70,248,68,128,1,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,5]] \ No newline at end of file diff --git a/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountNilObject.json b/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountNilObject.json index 4996d1a622..41a3c026e4 100644 --- a/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountNilObject.json +++ b/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountNilObject.json @@ -1 +1 @@ -[[0,1,0,1,249,2,17,249,2,17,9,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],[0,160,144,220,175,136,196,12,123,188,149,169,18,203,221,230,124,23,87,103,179,17,115,223,158,228,176,215,51,191,221,81,28,67,0,160,144,220,175,136,196,12,123,188,149,169,18,203,221,230,124,23,87,103,179,17,115,223,158,228,176,215,51,191,221,81,28,67,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,186,190,54,159,107,18,9,47,73,24,26,224,76,161,115,251,104,209,165,69,111,24,210,15,163,44,186,115,149,64,82,189,0,160,186,190,54,159,107,18,9,47,73,24,26,224,76,161,115,251,104,209,165,69,111,24,210,15,163,44,186,115,149,64,82,189,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,71,62,207,138,126,54,168,41,231,80,57,163,176,85,229,27,131,50,203,240,51,36,171,74,242,6,107,189,111,191,0,33,0,160,71,62,207,138,126,54,168,41,231,80,57,163,176,85,229,27,131,50,203,240,51,36,171,74,242,6,107,189,111,191,0,33,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,187,218,52,117,61,122,166,195,142,96,63,54,2,68,232,245,150,17,146,29,158,31,18,131,114,254,192,213,134,212,249,224,0,160,187,218,52,117,61,122,166,195,142,96,63,54,2,68,232,245,150,17,146,29,158,31,18,131,114,254,192,213,134,212,249,224,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,217,207,245,213,242,65,138,253,22,164,218,92,34,31,220,139,212,117,32,197,146,121,34,246,154,104,23,123,100,218,106,192,0,160,217,207,245,213,242,65,138,253,22,164,218,92,34,31,220,139,212,117,32,197,146,121,34,246,154,104,23,123,100,218,106,192,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,165,243,242,247,84,33,72,201,115,151,124,138,30,21,76,67,0,254,201,47,117,95,120,70,241,183,52,211,171,29,144,231,0,160,165,243,242,247,84,33,72,201,115,151,124,138,30,21,76,67,0,254,201,47,117,95,120,70,241,183,52,211,171,29,144,231,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,232,35,133,15,80,191,114,186,174,157,23,51,163,106,68,74,182,93,10,111,170,186,64,79,5,131,206,12,164,218,217,45,0,160,232,35,133,15,80,191,114,186,174,157,23,51,163,106,68,74,182,93,10,111,170,186,64,79,5,131,206,12,164,218,217,45,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,247,160,12,190,125,75,48,177,31,174,163,174,97,183,241,242,179,21,182,29,159,107,214,139,254,88,122,208,238,206,183,33,0,160,247,160,12,190,125,75,48,177,31,174,163,174,97,183,241,242,179,21,182,29,159,107,214,139,254,88,122,208,238,206,183,33,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,113,23,239,159,201,50,241,168,142,144,142,174,173,133,101,193,155,86,69,220,158,91,27,110,132,28,94,219,223,215,22,129,0,160,113,23,239,159,201,50,241,168,142,144,142,174,173,133,101,193,155,86,69,220,158,91,27,110,132,28,94,219,223,215,22,129,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,105,235,45,226,131,243,44,17,248,89,215,188,249,61,162,57,144,211,230,98,147,94,212,214,179,156,227,103,62,200,68,114,0,160,105,235,45,226,131,243,44,17,248,89,215,188,249,61,162,57,144,211,230,98,147,94,212,214,179,156,227,103,62,200,68,114,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,32,61,38,69,99,18,187,196,218,92,210,147,183,91,132,15,197,4,94,73,61,111,144,77,24,8,35,236,34,191,237,142,0,160,32,61,38,69,99,18,187,196,218,92,210,147,183,91,132,15,197,4,94,73,61,111,144,77,24,8,35,236,34,191,237,142,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,146,135,181,194,31,34,84,175,78,100,252,167,106,204,92,216,115,153,199,241,237,232,24,219,67,38,201,140,226,220,34,8,0,160,146,135,181,194,31,34,84,175,78,100,252,167,106,204,92,216,115,153,199,241,237,232,24,219,67,38,201,140,226,220,34,8,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,111,194,215,84,227,4,196,140,230,165,23,117,60,98,177,169,193,213,146,91,137,112,116,134,215,252,8,145,158,10,148,236,0,160,111,194,215,84,227,4,196,140,230,165,23,117,60,98,177,169,193,213,146,91,137,112,116,134,215,252,8,145,158,10,148,236,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,123,28,84,241,94,41,155,213,139,223,239,151,65,83,140,120,40,181,215,209,26,72,159,156,32,208,82,179,71,29,244,117,0,160,123,28,84,241,94,41,155,213,139,223,239,151,65,83,140,120,40,181,215,209,26,72,159,156,32,208,82,179,71,29,244,117,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,81,249,221,55,57,169,39,200,158,53,117,128,164,201,123,64,35,74,160,30,211,213,224,57,13,201,130,167,151,88,128,160,0,160,81,249,221,55,57,169,39,200,158,53,117,128,164,201,123,64,35,74,160,30,211,213,224,57,13,201,130,167,151,88,128,160,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,137,214,19,242,97,89,175,67,97,111,217,69,91,180,97,244,134,155,254,222,38,242,19,8,53,237,6,122,139,150,123,251,0,160,137,214,19,242,97,89,175,67,97,111,217,69,91,180,97,244,134,155,254,222,38,242,19,8,53,237,6,122,139,150,123,251,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,17],[0,1,0,1,249,2,17,249,2,17,8,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0],[0,160,194,161,194,230,101,254,160,95,77,48,211,27,39,42,140,4,122,172,243,209,160,183,193,160,238,144,110,96,160,53,201,176,0,160,194,161,194,230,101,254,160,95,77,48,211,27,39,42,140,4,122,172,243,209,160,183,193,160,238,144,110,96,160,53,201,176,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,250,10,79,191,155,218,123,133,247,187,164,39,212,171,124,199,15,61,52,217,80,166,252,43,206,177,62,170,118,143,250,130,0,160,250,10,79,191,155,218,123,133,247,187,164,39,212,171,124,199,15,61,52,217,80,166,252,43,206,177,62,170,118,143,250,130,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,108,102,161,204,241,214,151,12,80,163,235,72,19,184,65,25,37,28,43,113,212,14,119,160,157,125,65,13,140,22,81,190,0,160,108,102,161,204,241,214,151,12,80,163,235,72,19,184,65,25,37,28,43,113,212,14,119,160,157,125,65,13,140,22,81,190,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,245,247,207,229,123,97,61,242,10,237,62,241,112,223,174,20,21,134,98,167,15,69,64,87,208,137,239,130,24,225,217,69,0,160,245,247,207,229,123,97,61,242,10,237,62,241,112,223,174,20,21,134,98,167,15,69,64,87,208,137,239,130,24,225,217,69,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,30,98,56,45,136,244,48,122,241,246,213,147,38,112,85,225,114,131,195,165,25,146,5,1,23,56,98,204,84,80,107,55,0,160,30,98,56,45,136,244,48,122,241,246,213,147,38,112,85,225,114,131,195,165,25,146,5,1,23,56,98,204,84,80,107,55,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,13,130,198,244,51,130,38,64,159,240,127,232,249,153,1,46,213,170,213,218,230,166,137,75,171,46,198,189,169,81,129,186,0,160,13,130,198,244,51,130,38,64,159,240,127,232,249,153,1,46,213,170,213,218,230,166,137,75,171,46,198,189,169,81,129,186,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,229,29,41,136,113,129,3,220,51,225,243,185,32,77,145,131,244,109,144,247,2,225,2,109,44,231,85,92,179,219,46,140,0,160,229,29,41,136,113,129,3,220,51,225,243,185,32,77,145,131,244,109,144,247,2,225,2,109,44,231,85,92,179,219,46,140,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,227,50,165,83,125,101,94,90,180,34,108,124,83,107,32,6,40,120,220,212,90,176,135,180,166,38,78,212,164,7,245,229,0,160,227,50,165,83,125,101,94,90,180,34,108,124,83,107,32,6,40,120,220,212,90,176,135,180,166,38,78,212,164,7,245,229,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,153,11,242,211,42,155,107,237,88,100,219,214,126,177,12,26,208,44,151,202,156,90,102,134,114,49,56,71,180,103,83,155,0,160,153,11,242,211,42,155,107,237,88,100,219,214,126,177,12,26,208,44,151,202,156,90,102,134,114,49,56,71,180,103,83,155,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,71,164,38,186,162,94,167,107,171,137,209,18,250,139,176,186,4,118,148,176,251,124,23,138,249,89,144,1,84,248,27,55,0,160,71,164,38,186,162,94,167,107,171,137,209,18,250,139,176,186,4,118,148,176,251,124,23,138,249,89,144,1,84,248,27,55,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,52,112,5,32,127,130,195,189,56,88,183,178,155,208,74,148,123,54,232,217,185,32,49,156,71,67,15,17,2,49,204,243,0,160,52,112,5,32,127,130,195,189,56,88,183,178,155,208,74,148,123,54,232,217,185,32,49,156,71,67,15,17,2,49,204,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,170,23,213,11,235,134,180,70,232,51,146,38,58,251,66,201,29,6,217,33,53,126,153,255,165,144,117,128,91,14,16,43,0,160,170,23,213,11,235,134,180,70,232,51,146,38,58,251,66,201,29,6,217,33,53,126,153,255,165,144,117,128,91,14,16,43,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,148,51,14,129,178,95,21,66,170,110,219,0,237,74,184,241,156,135,49,91,139,227,83,112,52,218,111,108,140,199,255,219,0,160,148,51,14,129,178,95,21,66,170,110,219,0,237,74,184,241,156,135,49,91,139,227,83,112,52,218,111,108,140,199,255,219,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,222,192,22,245,232,111,105,228,68,180,87,180,31,116,42,56,93,1,147,1,207,113,217,240,248,143,123,135,213,26,66,139,0,160,222,192,22,245,232,111,105,228,68,180,87,180,31,116,42,56,93,1,147,1,207,113,217,240,248,143,123,135,213,26,66,139,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,239,77,239,217,232,159,0,139,212,31,73,0,211,56,197,222,20,67,13,26,183,202,29,28,187,243,0,57,12,134,3,140,0,160,239,77,239,217,232,159,0,139,212,31,73,0,211,56,197,222,20,67,13,26,183,202,29,28,187,243,0,57,12,134,3,140,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,174,27,143,154,179,94,7,70,236,47,69,149,186,217,141,122,66,236,237,90,80,133,141,159,145,213,6,253,155,38,62,98,0,160,174,27,143,154,179,94,7,70,236,47,69,149,186,217,141,122,66,236,237,90,80,133,141,159,145,213,6,253,155,38,62,98,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,17],[0,1,0,1,249,1,241,249,1,241,14,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0],[0,160,118,7,164,153,100,57,90,154,30,0,132,181,165,29,36,198,58,44,76,97,239,47,37,177,191,34,92,76,241,19,47,94,0,160,118,7,164,153,100,57,90,154,30,0,132,181,165,29,36,198,58,44,76,97,239,47,37,177,191,34,92,76,241,19,47,94,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,46,34,26,12,126,235,135,79,110,204,251,192,231,83,198,108,124,65,171,229,253,211,251,65,212,206,12,190,210,183,234,20,0,160,46,34,26,12,126,235,135,79,110,204,251,192,231,83,198,108,124,65,171,229,253,211,251,65,212,206,12,190,210,183,234,20,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,224,197,106,11,198,50,194,19,158,253,80,223,164,183,241,23,64,168,71,165,108,101,245,129,13,135,141,128,243,212,58,136,0,160,224,197,106,11,198,50,194,19,158,253,80,223,164,183,241,23,64,168,71,165,108,101,245,129,13,135,141,128,243,212,58,136,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,154,188,169,221,11,40,133,220,40,23,84,96,133,124,6,24,145,50,158,186,225,79,156,243,79,157,191,46,202,228,116,45,0,160,154,188,169,221,11,40,133,220,40,23,84,96,133,124,6,24,145,50,158,186,225,79,156,243,79,157,191,46,202,228,116,45,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,101,106,135,142,233,228,56,130,2,230,168,173,72,92,95,95,72,138,18,205,234,66,58,111,124,122,115,39,149,234,142,65,0,160,101,106,135,142,233,228,56,130,2,230,168,173,72,92,95,95,72,138,18,205,234,66,58,111,124,122,115,39,149,234,142,65,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,92,203,247,191,21,27,33,100,88,238,173,241,57,84,16,21,154,15,98,233,168,236,45,101,62,138,169,99,20,246,199,180,0,160,92,203,247,191,21,27,33,100,88,238,173,241,57,84,16,21,154,15,98,233,168,236,45,101,62,138,169,99,20,246,199,180,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,180,92,247,111,158,28,57,148,203,72,82,23,123,108,136,31,116,208,22,126,99,192,40,25,134,34,0,68,97,29,209,205,0,160,180,92,247,111,158,28,57,148,203,72,82,23,123,108,136,31,116,208,22,126,99,192,40,25,134,34,0,68,97,29,209,205,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,189,240,142,201,255,115,229,75,221,46,28,254,224,96,249,93,114,58,42,106,182,133,165,73,22,103,228,48,78,75,210,41,0,160,189,240,142,201,255,115,229,75,221,46,28,254,224,96,249,93,114,58,42,106,182,133,165,73,22,103,228,48,78,75,210,41,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,228,188,6,163,117,73,6,69,7,72,145,92,254,178,24,206,5,249,71,115,251,136,163,185,24,35,186,20,24,55,230,170,0,160,228,188,6,163,117,73,6,69,7,72,145,92,254,178,24,206,5,249,71,115,251,136,163,185,24,35,186,20,24,55,230,170,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,140,237,204,190,22,29,102,222,151,44,132,113,246,67,213,84,224,22,149,128,33,33,180,168,29,238,117,1,169,54,238,81,0,160,140,237,204,190,22,29,102,222,151,44,132,113,246,67,213,84,224,22,149,128,33,33,180,168,29,238,117,1,169,54,238,81,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,196,248,47,123,243,93,49,203,5,232,213,184,40,188,187,27,103,137,133,70,75,220,228,144,70,51,216,100,24,144,80,108,0,160,196,248,47,123,243,93,49,203,5,232,213,184,40,188,187,27,103,137,133,70,75,220,228,144,70,51,216,100,24,144,80,108,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,148,60,145,205,168,58,189,238,39,184,40,235,191,82,185,191,84,220,104,112,6,113,34,188,43,20,36,80,222,48,33,46,0,160,148,60,145,205,168,58,189,238,39,184,40,235,191,82,185,191,84,220,104,112,6,113,34,188,43,20,36,80,222,48,33,46,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,22,118,116,216,102,36,81,233,167,172,29,8,114,58,60,74,239,119,168,37,174,234,243,147,173,91,54,70,18,103,166,48,0,160,22,118,116,216,102,36,81,233,167,172,29,8,114,58,60,74,239,119,168,37,174,234,243,147,173,91,54,70,18,103,166,48,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,28,112,123,243,58,65,19,173,193,62,43,196,68,11,199,175,196,53,79,221,234,57,235,71,250,241,172,58,120,76,168,217,0,160,28,112,123,243,58,65,19,173,193,62,43,196,68,11,199,175,196,53,79,221,234,57,235,71,250,241,172,58,120,76,168,217,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,246,48,79,85,101,158,175,5,227,79,143,178,102,111,85,252,55,35,113,53,68,107,226,66,254,21,132,83,150,50,43,30,0,160,246,48,79,85,101,158,175,5,227,79,143,178,102,111,85,252,55,35,113,53,68,107,226,66,254,21,132,83,150,50,43,30,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,17],[1,0,1,0,248,81,0,248,81,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,31,135,73,204,174,167,159,229,36,59,217,161,39,71,252,185,59,171,62,199,226,95,101,195,206,134,71,61,127,129,37,56,0,160,31,135,73,204,174,167,159,229,36,59,217,161,39,71,252,185,59,171,62,199,226,95,101,195,206,134,71,61,127,129,37,56,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,203,196,24,180,91,92,42,155,178,224,138,157,186,202,85,129,212,160,95,196,131,76,51,38,251,230,158,133,225,177,41,135,0,160,203,196,24,180,91,92,42,155,178,224,138,157,186,202,85,129,212,160,95,196,131,76,51,38,251,230,158,133,225,177,41,135,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,17],[248,0,159,32,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,6],[248,0,159,32,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,4],[0,0,159,32,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,18],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,7],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,8],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,9],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,11],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,10],[249,2,17,160,144,220,175,136,196,12,123,188,149,169,18,203,221,230,124,23,87,103,179,17,115,223,158,228,176,215,51,191,221,81,28,67,160,186,190,54,159,107,18,9,47,73,24,26,224,76,161,115,251,104,209,165,69,111,24,210,15,163,44,186,115,149,64,82,189,160,71,62,207,138,126,54,168,41,231,80,57,163,176,85,229,27,131,50,203,240,51,36,171,74,242,6,107,189,111,191,0,33,160,187,218,52,117,61,122,166,195,142,96,63,54,2,68,232,245,150,17,146,29,158,31,18,131,114,254,192,213,134,212,249,224,160,217,207,245,213,242,65,138,253,22,164,218,92,34,31,220,139,212,117,32,197,146,121,34,246,154,104,23,123,100,218,106,192,160,165,243,242,247,84,33,72,201,115,151,124,138,30,21,76,67,0,254,201,47,117,95,120,70,241,183,52,211,171,29,144,231,160,232,35,133,15,80,191,114,186,174,157,23,51,163,106,68,74,182,93,10,111,170,186,64,79,5,131,206,12,164,218,217,45,160,247,160,12,190,125,75,48,177,31,174,163,174,97,183,241,242,179,21,182,29,159,107,214,139,254,88,122,208,238,206,183,33,160,113,23,239,159,201,50,241,168,142,144,142,174,173,133,101,193,155,86,69,220,158,91,27,110,132,28,94,219,223,215,22,129,160,105,235,45,226,131,243,44,17,248,89,215,188,249,61,162,57,144,211,230,98,147,94,212,214,179,156,227,103,62,200,68,114,160,32,61,38,69,99,18,187,196,218,92,210,147,183,91,132,15,197,4,94,73,61,111,144,77,24,8,35,236,34,191,237,142,160,146,135,181,194,31,34,84,175,78,100,252,167,106,204,92,216,115,153,199,241,237,232,24,219,67,38,201,140,226,220,34,8,160,111,194,215,84,227,4,196,140,230,165,23,117,60,98,177,169,193,213,146,91,137,112,116,134,215,252,8,145,158,10,148,236,160,123,28,84,241,94,41,155,213,139,223,239,151,65,83,140,120,40,181,215,209,26,72,159,156,32,208,82,179,71,29,244,117,160,81,249,221,55,57,169,39,200,158,53,117,128,164,201,123,64,35,74,160,30,211,213,224,57,13,201,130,167,151,88,128,160,160,137,214,19,242,97,89,175,67,97,111,217,69,91,180,97,244,134,155,254,222,38,242,19,8,53,237,6,122,139,150,123,251,128,5],[249,2,17,160,144,220,175,136,196,12,123,188,149,169,18,203,221,230,124,23,87,103,179,17,115,223,158,228,176,215,51,191,221,81,28,67,160,186,190,54,159,107,18,9,47,73,24,26,224,76,161,115,251,104,209,165,69,111,24,210,15,163,44,186,115,149,64,82,189,160,71,62,207,138,126,54,168,41,231,80,57,163,176,85,229,27,131,50,203,240,51,36,171,74,242,6,107,189,111,191,0,33,160,187,218,52,117,61,122,166,195,142,96,63,54,2,68,232,245,150,17,146,29,158,31,18,131,114,254,192,213,134,212,249,224,160,217,207,245,213,242,65,138,253,22,164,218,92,34,31,220,139,212,117,32,197,146,121,34,246,154,104,23,123,100,218,106,192,160,165,243,242,247,84,33,72,201,115,151,124,138,30,21,76,67,0,254,201,47,117,95,120,70,241,183,52,211,171,29,144,231,160,232,35,133,15,80,191,114,186,174,157,23,51,163,106,68,74,182,93,10,111,170,186,64,79,5,131,206,12,164,218,217,45,160,247,160,12,190,125,75,48,177,31,174,163,174,97,183,241,242,179,21,182,29,159,107,214,139,254,88,122,208,238,206,183,33,160,113,23,239,159,201,50,241,168,142,144,142,174,173,133,101,193,155,86,69,220,158,91,27,110,132,28,94,219,223,215,22,129,160,105,235,45,226,131,243,44,17,248,89,215,188,249,61,162,57,144,211,230,98,147,94,212,214,179,156,227,103,62,200,68,114,160,32,61,38,69,99,18,187,196,218,92,210,147,183,91,132,15,197,4,94,73,61,111,144,77,24,8,35,236,34,191,237,142,160,146,135,181,194,31,34,84,175,78,100,252,167,106,204,92,216,115,153,199,241,237,232,24,219,67,38,201,140,226,220,34,8,160,111,194,215,84,227,4,196,140,230,165,23,117,60,98,177,169,193,213,146,91,137,112,116,134,215,252,8,145,158,10,148,236,160,123,28,84,241,94,41,155,213,139,223,239,151,65,83,140,120,40,181,215,209,26,72,159,156,32,208,82,179,71,29,244,117,160,81,249,221,55,57,169,39,200,158,53,117,128,164,201,123,64,35,74,160,30,211,213,224,57,13,201,130,167,151,88,128,160,160,137,214,19,242,97,89,175,67,97,111,217,69,91,180,97,244,134,155,254,222,38,242,19,8,53,237,6,122,139,150,123,251,128,5],[249,2,17,160,194,161,194,230,101,254,160,95,77,48,211,27,39,42,140,4,122,172,243,209,160,183,193,160,238,144,110,96,160,53,201,176,160,250,10,79,191,155,218,123,133,247,187,164,39,212,171,124,199,15,61,52,217,80,166,252,43,206,177,62,170,118,143,250,130,160,108,102,161,204,241,214,151,12,80,163,235,72,19,184,65,25,37,28,43,113,212,14,119,160,157,125,65,13,140,22,81,190,160,245,247,207,229,123,97,61,242,10,237,62,241,112,223,174,20,21,134,98,167,15,69,64,87,208,137,239,130,24,225,217,69,160,30,98,56,45,136,244,48,122,241,246,213,147,38,112,85,225,114,131,195,165,25,146,5,1,23,56,98,204,84,80,107,55,160,13,130,198,244,51,130,38,64,159,240,127,232,249,153,1,46,213,170,213,218,230,166,137,75,171,46,198,189,169,81,129,186,160,229,29,41,136,113,129,3,220,51,225,243,185,32,77,145,131,244,109,144,247,2,225,2,109,44,231,85,92,179,219,46,140,160,227,50,165,83,125,101,94,90,180,34,108,124,83,107,32,6,40,120,220,212,90,176,135,180,166,38,78,212,164,7,245,229,160,153,11,242,211,42,155,107,237,88,100,219,214,126,177,12,26,208,44,151,202,156,90,102,134,114,49,56,71,180,103,83,155,160,71,164,38,186,162,94,167,107,171,137,209,18,250,139,176,186,4,118,148,176,251,124,23,138,249,89,144,1,84,248,27,55,160,52,112,5,32,127,130,195,189,56,88,183,178,155,208,74,148,123,54,232,217,185,32,49,156,71,67,15,17,2,49,204,243,160,170,23,213,11,235,134,180,70,232,51,146,38,58,251,66,201,29,6,217,33,53,126,153,255,165,144,117,128,91,14,16,43,160,148,51,14,129,178,95,21,66,170,110,219,0,237,74,184,241,156,135,49,91,139,227,83,112,52,218,111,108,140,199,255,219,160,222,192,22,245,232,111,105,228,68,180,87,180,31,116,42,56,93,1,147,1,207,113,217,240,248,143,123,135,213,26,66,139,160,239,77,239,217,232,159,0,139,212,31,73,0,211,56,197,222,20,67,13,26,183,202,29,28,187,243,0,57,12,134,3,140,160,174,27,143,154,179,94,7,70,236,47,69,149,186,217,141,122,66,236,237,90,80,133,141,159,145,213,6,253,155,38,62,98,128,5],[249,2,17,160,194,161,194,230,101,254,160,95,77,48,211,27,39,42,140,4,122,172,243,209,160,183,193,160,238,144,110,96,160,53,201,176,160,250,10,79,191,155,218,123,133,247,187,164,39,212,171,124,199,15,61,52,217,80,166,252,43,206,177,62,170,118,143,250,130,160,108,102,161,204,241,214,151,12,80,163,235,72,19,184,65,25,37,28,43,113,212,14,119,160,157,125,65,13,140,22,81,190,160,245,247,207,229,123,97,61,242,10,237,62,241,112,223,174,20,21,134,98,167,15,69,64,87,208,137,239,130,24,225,217,69,160,30,98,56,45,136,244,48,122,241,246,213,147,38,112,85,225,114,131,195,165,25,146,5,1,23,56,98,204,84,80,107,55,160,13,130,198,244,51,130,38,64,159,240,127,232,249,153,1,46,213,170,213,218,230,166,137,75,171,46,198,189,169,81,129,186,160,229,29,41,136,113,129,3,220,51,225,243,185,32,77,145,131,244,109,144,247,2,225,2,109,44,231,85,92,179,219,46,140,160,227,50,165,83,125,101,94,90,180,34,108,124,83,107,32,6,40,120,220,212,90,176,135,180,166,38,78,212,164,7,245,229,160,153,11,242,211,42,155,107,237,88,100,219,214,126,177,12,26,208,44,151,202,156,90,102,134,114,49,56,71,180,103,83,155,160,71,164,38,186,162,94,167,107,171,137,209,18,250,139,176,186,4,118,148,176,251,124,23,138,249,89,144,1,84,248,27,55,160,52,112,5,32,127,130,195,189,56,88,183,178,155,208,74,148,123,54,232,217,185,32,49,156,71,67,15,17,2,49,204,243,160,170,23,213,11,235,134,180,70,232,51,146,38,58,251,66,201,29,6,217,33,53,126,153,255,165,144,117,128,91,14,16,43,160,148,51,14,129,178,95,21,66,170,110,219,0,237,74,184,241,156,135,49,91,139,227,83,112,52,218,111,108,140,199,255,219,160,222,192,22,245,232,111,105,228,68,180,87,180,31,116,42,56,93,1,147,1,207,113,217,240,248,143,123,135,213,26,66,139,160,239,77,239,217,232,159,0,139,212,31,73,0,211,56,197,222,20,67,13,26,183,202,29,28,187,243,0,57,12,134,3,140,160,174,27,143,154,179,94,7,70,236,47,69,149,186,217,141,122,66,236,237,90,80,133,141,159,145,213,6,253,155,38,62,98,128,5],[249,1,241,160,118,7,164,153,100,57,90,154,30,0,132,181,165,29,36,198,58,44,76,97,239,47,37,177,191,34,92,76,241,19,47,94,160,46,34,26,12,126,235,135,79,110,204,251,192,231,83,198,108,124,65,171,229,253,211,251,65,212,206,12,190,210,183,234,20,160,224,197,106,11,198,50,194,19,158,253,80,223,164,183,241,23,64,168,71,165,108,101,245,129,13,135,141,128,243,212,58,136,160,154,188,169,221,11,40,133,220,40,23,84,96,133,124,6,24,145,50,158,186,225,79,156,243,79,157,191,46,202,228,116,45,160,101,106,135,142,233,228,56,130,2,230,168,173,72,92,95,95,72,138,18,205,234,66,58,111,124,122,115,39,149,234,142,65,160,92,203,247,191,21,27,33,100,88,238,173,241,57,84,16,21,154,15,98,233,168,236,45,101,62,138,169,99,20,246,199,180,160,180,92,247,111,158,28,57,148,203,72,82,23,123,108,136,31,116,208,22,126,99,192,40,25,134,34,0,68,97,29,209,205,160,189,240,142,201,255,115,229,75,221,46,28,254,224,96,249,93,114,58,42,106,182,133,165,73,22,103,228,48,78,75,210,41,128,160,228,188,6,163,117,73,6,69,7,72,145,92,254,178,24,206,5,249,71,115,251,136,163,185,24,35,186,20,24,55,230,170,160,140,237,204,190,22,29,102,222,151,44,132,113,246,67,213,84,224,22,149,128,33,33,180,168,29,238,117,1,169,54,238,81,160,196,248,47,123,243,93,49,203,5,232,213,184,40,188,187,27,103,137,133,70,75,220,228,144,70,51,216,100,24,144,80,108,160,148,60,145,205,168,58,189,238,39,184,40,235,191,82,185,191,84,220,104,112,6,113,34,188,43,20,36,80,222,48,33,46,160,22,118,116,216,102,36,81,233,167,172,29,8,114,58,60,74,239,119,168,37,174,234,243,147,173,91,54,70,18,103,166,48,160,28,112,123,243,58,65,19,173,193,62,43,196,68,11,199,175,196,53,79,221,234,57,235,71,250,241,172,58,120,76,168,217,160,246,48,79,85,101,158,175,5,227,79,143,178,102,111,85,252,55,35,113,53,68,107,226,66,254,21,132,83,150,50,43,30,128,5],[249,1,241,160,118,7,164,153,100,57,90,154,30,0,132,181,165,29,36,198,58,44,76,97,239,47,37,177,191,34,92,76,241,19,47,94,160,46,34,26,12,126,235,135,79,110,204,251,192,231,83,198,108,124,65,171,229,253,211,251,65,212,206,12,190,210,183,234,20,160,224,197,106,11,198,50,194,19,158,253,80,223,164,183,241,23,64,168,71,165,108,101,245,129,13,135,141,128,243,212,58,136,160,154,188,169,221,11,40,133,220,40,23,84,96,133,124,6,24,145,50,158,186,225,79,156,243,79,157,191,46,202,228,116,45,160,101,106,135,142,233,228,56,130,2,230,168,173,72,92,95,95,72,138,18,205,234,66,58,111,124,122,115,39,149,234,142,65,160,92,203,247,191,21,27,33,100,88,238,173,241,57,84,16,21,154,15,98,233,168,236,45,101,62,138,169,99,20,246,199,180,160,180,92,247,111,158,28,57,148,203,72,82,23,123,108,136,31,116,208,22,126,99,192,40,25,134,34,0,68,97,29,209,205,160,189,240,142,201,255,115,229,75,221,46,28,254,224,96,249,93,114,58,42,106,182,133,165,73,22,103,228,48,78,75,210,41,128,160,228,188,6,163,117,73,6,69,7,72,145,92,254,178,24,206,5,249,71,115,251,136,163,185,24,35,186,20,24,55,230,170,160,140,237,204,190,22,29,102,222,151,44,132,113,246,67,213,84,224,22,149,128,33,33,180,168,29,238,117,1,169,54,238,81,160,196,248,47,123,243,93,49,203,5,232,213,184,40,188,187,27,103,137,133,70,75,220,228,144,70,51,216,100,24,144,80,108,160,148,60,145,205,168,58,189,238,39,184,40,235,191,82,185,191,84,220,104,112,6,113,34,188,43,20,36,80,222,48,33,46,160,22,118,116,216,102,36,81,233,167,172,29,8,114,58,60,74,239,119,168,37,174,234,243,147,173,91,54,70,18,103,166,48,160,28,112,123,243,58,65,19,173,193,62,43,196,68,11,199,175,196,53,79,221,234,57,235,71,250,241,172,58,120,76,168,217,160,246,48,79,85,101,158,175,5,227,79,143,178,102,111,85,252,55,35,113,53,68,107,226,66,254,21,132,83,150,50,43,30,128,5],[248,81,128,128,128,128,128,128,128,128,128,160,31,135,73,204,174,167,159,229,36,59,217,161,39,71,252,185,59,171,62,199,226,95,101,195,206,134,71,61,127,129,37,56,128,160,203,196,24,180,91,92,42,155,178,224,138,157,186,202,85,129,212,160,95,196,131,76,51,38,251,230,158,133,225,177,41,135,128,128,128,128,128,5],[248,81,128,128,128,128,128,128,128,128,128,160,31,135,73,204,174,167,159,229,36,59,217,161,39,71,252,185,59,171,62,199,226,95,101,195,206,134,71,61,127,129,37,56,128,160,203,196,24,180,91,92,42,155,178,224,138,157,186,202,85,129,212,160,95,196,131,76,51,38,251,230,158,133,225,177,41,135,128,128,128,128,128,5]] \ No newline at end of file +[[0,1,0,1,249,2,17,249,2,17,9,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],[0,160,144,220,175,136,196,12,123,188,149,169,18,203,221,230,124,23,87,103,179,17,115,223,158,228,176,215,51,191,221,81,28,67,0,160,144,220,175,136,196,12,123,188,149,169,18,203,221,230,124,23,87,103,179,17,115,223,158,228,176,215,51,191,221,81,28,67,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,186,190,54,159,107,18,9,47,73,24,26,224,76,161,115,251,104,209,165,69,111,24,210,15,163,44,186,115,149,64,82,189,0,160,186,190,54,159,107,18,9,47,73,24,26,224,76,161,115,251,104,209,165,69,111,24,210,15,163,44,186,115,149,64,82,189,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,71,62,207,138,126,54,168,41,231,80,57,163,176,85,229,27,131,50,203,240,51,36,171,74,242,6,107,189,111,191,0,33,0,160,71,62,207,138,126,54,168,41,231,80,57,163,176,85,229,27,131,50,203,240,51,36,171,74,242,6,107,189,111,191,0,33,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,187,218,52,117,61,122,166,195,142,96,63,54,2,68,232,245,150,17,146,29,158,31,18,131,114,254,192,213,134,212,249,224,0,160,187,218,52,117,61,122,166,195,142,96,63,54,2,68,232,245,150,17,146,29,158,31,18,131,114,254,192,213,134,212,249,224,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,217,207,245,213,242,65,138,253,22,164,218,92,34,31,220,139,212,117,32,197,146,121,34,246,154,104,23,123,100,218,106,192,0,160,217,207,245,213,242,65,138,253,22,164,218,92,34,31,220,139,212,117,32,197,146,121,34,246,154,104,23,123,100,218,106,192,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,165,243,242,247,84,33,72,201,115,151,124,138,30,21,76,67,0,254,201,47,117,95,120,70,241,183,52,211,171,29,144,231,0,160,165,243,242,247,84,33,72,201,115,151,124,138,30,21,76,67,0,254,201,47,117,95,120,70,241,183,52,211,171,29,144,231,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,232,35,133,15,80,191,114,186,174,157,23,51,163,106,68,74,182,93,10,111,170,186,64,79,5,131,206,12,164,218,217,45,0,160,232,35,133,15,80,191,114,186,174,157,23,51,163,106,68,74,182,93,10,111,170,186,64,79,5,131,206,12,164,218,217,45,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,247,160,12,190,125,75,48,177,31,174,163,174,97,183,241,242,179,21,182,29,159,107,214,139,254,88,122,208,238,206,183,33,0,160,247,160,12,190,125,75,48,177,31,174,163,174,97,183,241,242,179,21,182,29,159,107,214,139,254,88,122,208,238,206,183,33,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,113,23,239,159,201,50,241,168,142,144,142,174,173,133,101,193,155,86,69,220,158,91,27,110,132,28,94,219,223,215,22,129,0,160,113,23,239,159,201,50,241,168,142,144,142,174,173,133,101,193,155,86,69,220,158,91,27,110,132,28,94,219,223,215,22,129,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,105,235,45,226,131,243,44,17,248,89,215,188,249,61,162,57,144,211,230,98,147,94,212,214,179,156,227,103,62,200,68,114,0,160,105,235,45,226,131,243,44,17,248,89,215,188,249,61,162,57,144,211,230,98,147,94,212,214,179,156,227,103,62,200,68,114,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,32,61,38,69,99,18,187,196,218,92,210,147,183,91,132,15,197,4,94,73,61,111,144,77,24,8,35,236,34,191,237,142,0,160,32,61,38,69,99,18,187,196,218,92,210,147,183,91,132,15,197,4,94,73,61,111,144,77,24,8,35,236,34,191,237,142,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,146,135,181,194,31,34,84,175,78,100,252,167,106,204,92,216,115,153,199,241,237,232,24,219,67,38,201,140,226,220,34,8,0,160,146,135,181,194,31,34,84,175,78,100,252,167,106,204,92,216,115,153,199,241,237,232,24,219,67,38,201,140,226,220,34,8,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,111,194,215,84,227,4,196,140,230,165,23,117,60,98,177,169,193,213,146,91,137,112,116,134,215,252,8,145,158,10,148,236,0,160,111,194,215,84,227,4,196,140,230,165,23,117,60,98,177,169,193,213,146,91,137,112,116,134,215,252,8,145,158,10,148,236,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,123,28,84,241,94,41,155,213,139,223,239,151,65,83,140,120,40,181,215,209,26,72,159,156,32,208,82,179,71,29,244,117,0,160,123,28,84,241,94,41,155,213,139,223,239,151,65,83,140,120,40,181,215,209,26,72,159,156,32,208,82,179,71,29,244,117,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,81,249,221,55,57,169,39,200,158,53,117,128,164,201,123,64,35,74,160,30,211,213,224,57,13,201,130,167,151,88,128,160,0,160,81,249,221,55,57,169,39,200,158,53,117,128,164,201,123,64,35,74,160,30,211,213,224,57,13,201,130,167,151,88,128,160,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,137,214,19,242,97,89,175,67,97,111,217,69,91,180,97,244,134,155,254,222,38,242,19,8,53,237,6,122,139,150,123,251,0,160,137,214,19,242,97,89,175,67,97,111,217,69,91,180,97,244,134,155,254,222,38,242,19,8,53,237,6,122,139,150,123,251,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,17],[0,1,0,1,249,2,17,249,2,17,8,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0],[0,160,194,161,194,230,101,254,160,95,77,48,211,27,39,42,140,4,122,172,243,209,160,183,193,160,238,144,110,96,160,53,201,176,0,160,194,161,194,230,101,254,160,95,77,48,211,27,39,42,140,4,122,172,243,209,160,183,193,160,238,144,110,96,160,53,201,176,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,250,10,79,191,155,218,123,133,247,187,164,39,212,171,124,199,15,61,52,217,80,166,252,43,206,177,62,170,118,143,250,130,0,160,250,10,79,191,155,218,123,133,247,187,164,39,212,171,124,199,15,61,52,217,80,166,252,43,206,177,62,170,118,143,250,130,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,108,102,161,204,241,214,151,12,80,163,235,72,19,184,65,25,37,28,43,113,212,14,119,160,157,125,65,13,140,22,81,190,0,160,108,102,161,204,241,214,151,12,80,163,235,72,19,184,65,25,37,28,43,113,212,14,119,160,157,125,65,13,140,22,81,190,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,245,247,207,229,123,97,61,242,10,237,62,241,112,223,174,20,21,134,98,167,15,69,64,87,208,137,239,130,24,225,217,69,0,160,245,247,207,229,123,97,61,242,10,237,62,241,112,223,174,20,21,134,98,167,15,69,64,87,208,137,239,130,24,225,217,69,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,30,98,56,45,136,244,48,122,241,246,213,147,38,112,85,225,114,131,195,165,25,146,5,1,23,56,98,204,84,80,107,55,0,160,30,98,56,45,136,244,48,122,241,246,213,147,38,112,85,225,114,131,195,165,25,146,5,1,23,56,98,204,84,80,107,55,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,13,130,198,244,51,130,38,64,159,240,127,232,249,153,1,46,213,170,213,218,230,166,137,75,171,46,198,189,169,81,129,186,0,160,13,130,198,244,51,130,38,64,159,240,127,232,249,153,1,46,213,170,213,218,230,166,137,75,171,46,198,189,169,81,129,186,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,229,29,41,136,113,129,3,220,51,225,243,185,32,77,145,131,244,109,144,247,2,225,2,109,44,231,85,92,179,219,46,140,0,160,229,29,41,136,113,129,3,220,51,225,243,185,32,77,145,131,244,109,144,247,2,225,2,109,44,231,85,92,179,219,46,140,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,227,50,165,83,125,101,94,90,180,34,108,124,83,107,32,6,40,120,220,212,90,176,135,180,166,38,78,212,164,7,245,229,0,160,227,50,165,83,125,101,94,90,180,34,108,124,83,107,32,6,40,120,220,212,90,176,135,180,166,38,78,212,164,7,245,229,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,153,11,242,211,42,155,107,237,88,100,219,214,126,177,12,26,208,44,151,202,156,90,102,134,114,49,56,71,180,103,83,155,0,160,153,11,242,211,42,155,107,237,88,100,219,214,126,177,12,26,208,44,151,202,156,90,102,134,114,49,56,71,180,103,83,155,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,71,164,38,186,162,94,167,107,171,137,209,18,250,139,176,186,4,118,148,176,251,124,23,138,249,89,144,1,84,248,27,55,0,160,71,164,38,186,162,94,167,107,171,137,209,18,250,139,176,186,4,118,148,176,251,124,23,138,249,89,144,1,84,248,27,55,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,52,112,5,32,127,130,195,189,56,88,183,178,155,208,74,148,123,54,232,217,185,32,49,156,71,67,15,17,2,49,204,243,0,160,52,112,5,32,127,130,195,189,56,88,183,178,155,208,74,148,123,54,232,217,185,32,49,156,71,67,15,17,2,49,204,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,170,23,213,11,235,134,180,70,232,51,146,38,58,251,66,201,29,6,217,33,53,126,153,255,165,144,117,128,91,14,16,43,0,160,170,23,213,11,235,134,180,70,232,51,146,38,58,251,66,201,29,6,217,33,53,126,153,255,165,144,117,128,91,14,16,43,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,148,51,14,129,178,95,21,66,170,110,219,0,237,74,184,241,156,135,49,91,139,227,83,112,52,218,111,108,140,199,255,219,0,160,148,51,14,129,178,95,21,66,170,110,219,0,237,74,184,241,156,135,49,91,139,227,83,112,52,218,111,108,140,199,255,219,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,222,192,22,245,232,111,105,228,68,180,87,180,31,116,42,56,93,1,147,1,207,113,217,240,248,143,123,135,213,26,66,139,0,160,222,192,22,245,232,111,105,228,68,180,87,180,31,116,42,56,93,1,147,1,207,113,217,240,248,143,123,135,213,26,66,139,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,239,77,239,217,232,159,0,139,212,31,73,0,211,56,197,222,20,67,13,26,183,202,29,28,187,243,0,57,12,134,3,140,0,160,239,77,239,217,232,159,0,139,212,31,73,0,211,56,197,222,20,67,13,26,183,202,29,28,187,243,0,57,12,134,3,140,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,174,27,143,154,179,94,7,70,236,47,69,149,186,217,141,122,66,236,237,90,80,133,141,159,145,213,6,253,155,38,62,98,0,160,174,27,143,154,179,94,7,70,236,47,69,149,186,217,141,122,66,236,237,90,80,133,141,159,145,213,6,253,155,38,62,98,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,17],[0,1,0,1,249,1,241,249,1,241,14,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0],[0,160,118,7,164,153,100,57,90,154,30,0,132,181,165,29,36,198,58,44,76,97,239,47,37,177,191,34,92,76,241,19,47,94,0,160,118,7,164,153,100,57,90,154,30,0,132,181,165,29,36,198,58,44,76,97,239,47,37,177,191,34,92,76,241,19,47,94,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,46,34,26,12,126,235,135,79,110,204,251,192,231,83,198,108,124,65,171,229,253,211,251,65,212,206,12,190,210,183,234,20,0,160,46,34,26,12,126,235,135,79,110,204,251,192,231,83,198,108,124,65,171,229,253,211,251,65,212,206,12,190,210,183,234,20,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,224,197,106,11,198,50,194,19,158,253,80,223,164,183,241,23,64,168,71,165,108,101,245,129,13,135,141,128,243,212,58,136,0,160,224,197,106,11,198,50,194,19,158,253,80,223,164,183,241,23,64,168,71,165,108,101,245,129,13,135,141,128,243,212,58,136,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,154,188,169,221,11,40,133,220,40,23,84,96,133,124,6,24,145,50,158,186,225,79,156,243,79,157,191,46,202,228,116,45,0,160,154,188,169,221,11,40,133,220,40,23,84,96,133,124,6,24,145,50,158,186,225,79,156,243,79,157,191,46,202,228,116,45,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,101,106,135,142,233,228,56,130,2,230,168,173,72,92,95,95,72,138,18,205,234,66,58,111,124,122,115,39,149,234,142,65,0,160,101,106,135,142,233,228,56,130,2,230,168,173,72,92,95,95,72,138,18,205,234,66,58,111,124,122,115,39,149,234,142,65,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,92,203,247,191,21,27,33,100,88,238,173,241,57,84,16,21,154,15,98,233,168,236,45,101,62,138,169,99,20,246,199,180,0,160,92,203,247,191,21,27,33,100,88,238,173,241,57,84,16,21,154,15,98,233,168,236,45,101,62,138,169,99,20,246,199,180,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,180,92,247,111,158,28,57,148,203,72,82,23,123,108,136,31,116,208,22,126,99,192,40,25,134,34,0,68,97,29,209,205,0,160,180,92,247,111,158,28,57,148,203,72,82,23,123,108,136,31,116,208,22,126,99,192,40,25,134,34,0,68,97,29,209,205,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,189,240,142,201,255,115,229,75,221,46,28,254,224,96,249,93,114,58,42,106,182,133,165,73,22,103,228,48,78,75,210,41,0,160,189,240,142,201,255,115,229,75,221,46,28,254,224,96,249,93,114,58,42,106,182,133,165,73,22,103,228,48,78,75,210,41,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,228,188,6,163,117,73,6,69,7,72,145,92,254,178,24,206,5,249,71,115,251,136,163,185,24,35,186,20,24,55,230,170,0,160,228,188,6,163,117,73,6,69,7,72,145,92,254,178,24,206,5,249,71,115,251,136,163,185,24,35,186,20,24,55,230,170,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,140,237,204,190,22,29,102,222,151,44,132,113,246,67,213,84,224,22,149,128,33,33,180,168,29,238,117,1,169,54,238,81,0,160,140,237,204,190,22,29,102,222,151,44,132,113,246,67,213,84,224,22,149,128,33,33,180,168,29,238,117,1,169,54,238,81,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,196,248,47,123,243,93,49,203,5,232,213,184,40,188,187,27,103,137,133,70,75,220,228,144,70,51,216,100,24,144,80,108,0,160,196,248,47,123,243,93,49,203,5,232,213,184,40,188,187,27,103,137,133,70,75,220,228,144,70,51,216,100,24,144,80,108,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,148,60,145,205,168,58,189,238,39,184,40,235,191,82,185,191,84,220,104,112,6,113,34,188,43,20,36,80,222,48,33,46,0,160,148,60,145,205,168,58,189,238,39,184,40,235,191,82,185,191,84,220,104,112,6,113,34,188,43,20,36,80,222,48,33,46,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,22,118,116,216,102,36,81,233,167,172,29,8,114,58,60,74,239,119,168,37,174,234,243,147,173,91,54,70,18,103,166,48,0,160,22,118,116,216,102,36,81,233,167,172,29,8,114,58,60,74,239,119,168,37,174,234,243,147,173,91,54,70,18,103,166,48,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,28,112,123,243,58,65,19,173,193,62,43,196,68,11,199,175,196,53,79,221,234,57,235,71,250,241,172,58,120,76,168,217,0,160,28,112,123,243,58,65,19,173,193,62,43,196,68,11,199,175,196,53,79,221,234,57,235,71,250,241,172,58,120,76,168,217,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,246,48,79,85,101,158,175,5,227,79,143,178,102,111,85,252,55,35,113,53,68,107,226,66,254,21,132,83,150,50,43,30,0,160,246,48,79,85,101,158,175,5,227,79,143,178,102,111,85,252,55,35,113,53,68,107,226,66,254,21,132,83,150,50,43,30,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,17],[1,0,1,0,248,81,0,248,81,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,31,135,73,204,174,167,159,229,36,59,217,161,39,71,252,185,59,171,62,199,226,95,101,195,206,134,71,61,127,129,37,56,0,160,31,135,73,204,174,167,159,229,36,59,217,161,39,71,252,185,59,171,62,199,226,95,101,195,206,134,71,61,127,129,37,56,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,160,203,196,24,180,91,92,42,155,178,224,138,157,186,202,85,129,212,160,95,196,131,76,51,38,251,230,158,133,225,177,41,135,0,160,203,196,24,180,91,92,42,155,178,224,138,157,186,202,85,129,212,160,95,196,131,76,51,38,251,230,158,133,225,177,41,135,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,17],[248,104,159,32,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,6],[248,104,159,32,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,4],[0,0,159,32,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,18],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,7],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,8],[0,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,9],[0,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,11],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,214,126,77,69,3,67,4,100,37,174,66,113,71,67,83,133,122,184,96,219,192,161,221,230,75,65,181,205,58,83,43,243,152,225,119,223,167,154,212,87,64,146,72,80,232,124,99,244,129,117,156,137,200,71,85,240,47,81,246,247,59,192,177,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,10],[249,2,17,160,144,220,175,136,196,12,123,188,149,169,18,203,221,230,124,23,87,103,179,17,115,223,158,228,176,215,51,191,221,81,28,67,160,186,190,54,159,107,18,9,47,73,24,26,224,76,161,115,251,104,209,165,69,111,24,210,15,163,44,186,115,149,64,82,189,160,71,62,207,138,126,54,168,41,231,80,57,163,176,85,229,27,131,50,203,240,51,36,171,74,242,6,107,189,111,191,0,33,160,187,218,52,117,61,122,166,195,142,96,63,54,2,68,232,245,150,17,146,29,158,31,18,131,114,254,192,213,134,212,249,224,160,217,207,245,213,242,65,138,253,22,164,218,92,34,31,220,139,212,117,32,197,146,121,34,246,154,104,23,123,100,218,106,192,160,165,243,242,247,84,33,72,201,115,151,124,138,30,21,76,67,0,254,201,47,117,95,120,70,241,183,52,211,171,29,144,231,160,232,35,133,15,80,191,114,186,174,157,23,51,163,106,68,74,182,93,10,111,170,186,64,79,5,131,206,12,164,218,217,45,160,247,160,12,190,125,75,48,177,31,174,163,174,97,183,241,242,179,21,182,29,159,107,214,139,254,88,122,208,238,206,183,33,160,113,23,239,159,201,50,241,168,142,144,142,174,173,133,101,193,155,86,69,220,158,91,27,110,132,28,94,219,223,215,22,129,160,105,235,45,226,131,243,44,17,248,89,215,188,249,61,162,57,144,211,230,98,147,94,212,214,179,156,227,103,62,200,68,114,160,32,61,38,69,99,18,187,196,218,92,210,147,183,91,132,15,197,4,94,73,61,111,144,77,24,8,35,236,34,191,237,142,160,146,135,181,194,31,34,84,175,78,100,252,167,106,204,92,216,115,153,199,241,237,232,24,219,67,38,201,140,226,220,34,8,160,111,194,215,84,227,4,196,140,230,165,23,117,60,98,177,169,193,213,146,91,137,112,116,134,215,252,8,145,158,10,148,236,160,123,28,84,241,94,41,155,213,139,223,239,151,65,83,140,120,40,181,215,209,26,72,159,156,32,208,82,179,71,29,244,117,160,81,249,221,55,57,169,39,200,158,53,117,128,164,201,123,64,35,74,160,30,211,213,224,57,13,201,130,167,151,88,128,160,160,137,214,19,242,97,89,175,67,97,111,217,69,91,180,97,244,134,155,254,222,38,242,19,8,53,237,6,122,139,150,123,251,128,5],[249,2,17,160,144,220,175,136,196,12,123,188,149,169,18,203,221,230,124,23,87,103,179,17,115,223,158,228,176,215,51,191,221,81,28,67,160,186,190,54,159,107,18,9,47,73,24,26,224,76,161,115,251,104,209,165,69,111,24,210,15,163,44,186,115,149,64,82,189,160,71,62,207,138,126,54,168,41,231,80,57,163,176,85,229,27,131,50,203,240,51,36,171,74,242,6,107,189,111,191,0,33,160,187,218,52,117,61,122,166,195,142,96,63,54,2,68,232,245,150,17,146,29,158,31,18,131,114,254,192,213,134,212,249,224,160,217,207,245,213,242,65,138,253,22,164,218,92,34,31,220,139,212,117,32,197,146,121,34,246,154,104,23,123,100,218,106,192,160,165,243,242,247,84,33,72,201,115,151,124,138,30,21,76,67,0,254,201,47,117,95,120,70,241,183,52,211,171,29,144,231,160,232,35,133,15,80,191,114,186,174,157,23,51,163,106,68,74,182,93,10,111,170,186,64,79,5,131,206,12,164,218,217,45,160,247,160,12,190,125,75,48,177,31,174,163,174,97,183,241,242,179,21,182,29,159,107,214,139,254,88,122,208,238,206,183,33,160,113,23,239,159,201,50,241,168,142,144,142,174,173,133,101,193,155,86,69,220,158,91,27,110,132,28,94,219,223,215,22,129,160,105,235,45,226,131,243,44,17,248,89,215,188,249,61,162,57,144,211,230,98,147,94,212,214,179,156,227,103,62,200,68,114,160,32,61,38,69,99,18,187,196,218,92,210,147,183,91,132,15,197,4,94,73,61,111,144,77,24,8,35,236,34,191,237,142,160,146,135,181,194,31,34,84,175,78,100,252,167,106,204,92,216,115,153,199,241,237,232,24,219,67,38,201,140,226,220,34,8,160,111,194,215,84,227,4,196,140,230,165,23,117,60,98,177,169,193,213,146,91,137,112,116,134,215,252,8,145,158,10,148,236,160,123,28,84,241,94,41,155,213,139,223,239,151,65,83,140,120,40,181,215,209,26,72,159,156,32,208,82,179,71,29,244,117,160,81,249,221,55,57,169,39,200,158,53,117,128,164,201,123,64,35,74,160,30,211,213,224,57,13,201,130,167,151,88,128,160,160,137,214,19,242,97,89,175,67,97,111,217,69,91,180,97,244,134,155,254,222,38,242,19,8,53,237,6,122,139,150,123,251,128,5],[249,2,17,160,194,161,194,230,101,254,160,95,77,48,211,27,39,42,140,4,122,172,243,209,160,183,193,160,238,144,110,96,160,53,201,176,160,250,10,79,191,155,218,123,133,247,187,164,39,212,171,124,199,15,61,52,217,80,166,252,43,206,177,62,170,118,143,250,130,160,108,102,161,204,241,214,151,12,80,163,235,72,19,184,65,25,37,28,43,113,212,14,119,160,157,125,65,13,140,22,81,190,160,245,247,207,229,123,97,61,242,10,237,62,241,112,223,174,20,21,134,98,167,15,69,64,87,208,137,239,130,24,225,217,69,160,30,98,56,45,136,244,48,122,241,246,213,147,38,112,85,225,114,131,195,165,25,146,5,1,23,56,98,204,84,80,107,55,160,13,130,198,244,51,130,38,64,159,240,127,232,249,153,1,46,213,170,213,218,230,166,137,75,171,46,198,189,169,81,129,186,160,229,29,41,136,113,129,3,220,51,225,243,185,32,77,145,131,244,109,144,247,2,225,2,109,44,231,85,92,179,219,46,140,160,227,50,165,83,125,101,94,90,180,34,108,124,83,107,32,6,40,120,220,212,90,176,135,180,166,38,78,212,164,7,245,229,160,153,11,242,211,42,155,107,237,88,100,219,214,126,177,12,26,208,44,151,202,156,90,102,134,114,49,56,71,180,103,83,155,160,71,164,38,186,162,94,167,107,171,137,209,18,250,139,176,186,4,118,148,176,251,124,23,138,249,89,144,1,84,248,27,55,160,52,112,5,32,127,130,195,189,56,88,183,178,155,208,74,148,123,54,232,217,185,32,49,156,71,67,15,17,2,49,204,243,160,170,23,213,11,235,134,180,70,232,51,146,38,58,251,66,201,29,6,217,33,53,126,153,255,165,144,117,128,91,14,16,43,160,148,51,14,129,178,95,21,66,170,110,219,0,237,74,184,241,156,135,49,91,139,227,83,112,52,218,111,108,140,199,255,219,160,222,192,22,245,232,111,105,228,68,180,87,180,31,116,42,56,93,1,147,1,207,113,217,240,248,143,123,135,213,26,66,139,160,239,77,239,217,232,159,0,139,212,31,73,0,211,56,197,222,20,67,13,26,183,202,29,28,187,243,0,57,12,134,3,140,160,174,27,143,154,179,94,7,70,236,47,69,149,186,217,141,122,66,236,237,90,80,133,141,159,145,213,6,253,155,38,62,98,128,5],[249,2,17,160,194,161,194,230,101,254,160,95,77,48,211,27,39,42,140,4,122,172,243,209,160,183,193,160,238,144,110,96,160,53,201,176,160,250,10,79,191,155,218,123,133,247,187,164,39,212,171,124,199,15,61,52,217,80,166,252,43,206,177,62,170,118,143,250,130,160,108,102,161,204,241,214,151,12,80,163,235,72,19,184,65,25,37,28,43,113,212,14,119,160,157,125,65,13,140,22,81,190,160,245,247,207,229,123,97,61,242,10,237,62,241,112,223,174,20,21,134,98,167,15,69,64,87,208,137,239,130,24,225,217,69,160,30,98,56,45,136,244,48,122,241,246,213,147,38,112,85,225,114,131,195,165,25,146,5,1,23,56,98,204,84,80,107,55,160,13,130,198,244,51,130,38,64,159,240,127,232,249,153,1,46,213,170,213,218,230,166,137,75,171,46,198,189,169,81,129,186,160,229,29,41,136,113,129,3,220,51,225,243,185,32,77,145,131,244,109,144,247,2,225,2,109,44,231,85,92,179,219,46,140,160,227,50,165,83,125,101,94,90,180,34,108,124,83,107,32,6,40,120,220,212,90,176,135,180,166,38,78,212,164,7,245,229,160,153,11,242,211,42,155,107,237,88,100,219,214,126,177,12,26,208,44,151,202,156,90,102,134,114,49,56,71,180,103,83,155,160,71,164,38,186,162,94,167,107,171,137,209,18,250,139,176,186,4,118,148,176,251,124,23,138,249,89,144,1,84,248,27,55,160,52,112,5,32,127,130,195,189,56,88,183,178,155,208,74,148,123,54,232,217,185,32,49,156,71,67,15,17,2,49,204,243,160,170,23,213,11,235,134,180,70,232,51,146,38,58,251,66,201,29,6,217,33,53,126,153,255,165,144,117,128,91,14,16,43,160,148,51,14,129,178,95,21,66,170,110,219,0,237,74,184,241,156,135,49,91,139,227,83,112,52,218,111,108,140,199,255,219,160,222,192,22,245,232,111,105,228,68,180,87,180,31,116,42,56,93,1,147,1,207,113,217,240,248,143,123,135,213,26,66,139,160,239,77,239,217,232,159,0,139,212,31,73,0,211,56,197,222,20,67,13,26,183,202,29,28,187,243,0,57,12,134,3,140,160,174,27,143,154,179,94,7,70,236,47,69,149,186,217,141,122,66,236,237,90,80,133,141,159,145,213,6,253,155,38,62,98,128,5],[249,1,241,160,118,7,164,153,100,57,90,154,30,0,132,181,165,29,36,198,58,44,76,97,239,47,37,177,191,34,92,76,241,19,47,94,160,46,34,26,12,126,235,135,79,110,204,251,192,231,83,198,108,124,65,171,229,253,211,251,65,212,206,12,190,210,183,234,20,160,224,197,106,11,198,50,194,19,158,253,80,223,164,183,241,23,64,168,71,165,108,101,245,129,13,135,141,128,243,212,58,136,160,154,188,169,221,11,40,133,220,40,23,84,96,133,124,6,24,145,50,158,186,225,79,156,243,79,157,191,46,202,228,116,45,160,101,106,135,142,233,228,56,130,2,230,168,173,72,92,95,95,72,138,18,205,234,66,58,111,124,122,115,39,149,234,142,65,160,92,203,247,191,21,27,33,100,88,238,173,241,57,84,16,21,154,15,98,233,168,236,45,101,62,138,169,99,20,246,199,180,160,180,92,247,111,158,28,57,148,203,72,82,23,123,108,136,31,116,208,22,126,99,192,40,25,134,34,0,68,97,29,209,205,160,189,240,142,201,255,115,229,75,221,46,28,254,224,96,249,93,114,58,42,106,182,133,165,73,22,103,228,48,78,75,210,41,128,160,228,188,6,163,117,73,6,69,7,72,145,92,254,178,24,206,5,249,71,115,251,136,163,185,24,35,186,20,24,55,230,170,160,140,237,204,190,22,29,102,222,151,44,132,113,246,67,213,84,224,22,149,128,33,33,180,168,29,238,117,1,169,54,238,81,160,196,248,47,123,243,93,49,203,5,232,213,184,40,188,187,27,103,137,133,70,75,220,228,144,70,51,216,100,24,144,80,108,160,148,60,145,205,168,58,189,238,39,184,40,235,191,82,185,191,84,220,104,112,6,113,34,188,43,20,36,80,222,48,33,46,160,22,118,116,216,102,36,81,233,167,172,29,8,114,58,60,74,239,119,168,37,174,234,243,147,173,91,54,70,18,103,166,48,160,28,112,123,243,58,65,19,173,193,62,43,196,68,11,199,175,196,53,79,221,234,57,235,71,250,241,172,58,120,76,168,217,160,246,48,79,85,101,158,175,5,227,79,143,178,102,111,85,252,55,35,113,53,68,107,226,66,254,21,132,83,150,50,43,30,128,5],[249,1,241,160,118,7,164,153,100,57,90,154,30,0,132,181,165,29,36,198,58,44,76,97,239,47,37,177,191,34,92,76,241,19,47,94,160,46,34,26,12,126,235,135,79,110,204,251,192,231,83,198,108,124,65,171,229,253,211,251,65,212,206,12,190,210,183,234,20,160,224,197,106,11,198,50,194,19,158,253,80,223,164,183,241,23,64,168,71,165,108,101,245,129,13,135,141,128,243,212,58,136,160,154,188,169,221,11,40,133,220,40,23,84,96,133,124,6,24,145,50,158,186,225,79,156,243,79,157,191,46,202,228,116,45,160,101,106,135,142,233,228,56,130,2,230,168,173,72,92,95,95,72,138,18,205,234,66,58,111,124,122,115,39,149,234,142,65,160,92,203,247,191,21,27,33,100,88,238,173,241,57,84,16,21,154,15,98,233,168,236,45,101,62,138,169,99,20,246,199,180,160,180,92,247,111,158,28,57,148,203,72,82,23,123,108,136,31,116,208,22,126,99,192,40,25,134,34,0,68,97,29,209,205,160,189,240,142,201,255,115,229,75,221,46,28,254,224,96,249,93,114,58,42,106,182,133,165,73,22,103,228,48,78,75,210,41,128,160,228,188,6,163,117,73,6,69,7,72,145,92,254,178,24,206,5,249,71,115,251,136,163,185,24,35,186,20,24,55,230,170,160,140,237,204,190,22,29,102,222,151,44,132,113,246,67,213,84,224,22,149,128,33,33,180,168,29,238,117,1,169,54,238,81,160,196,248,47,123,243,93,49,203,5,232,213,184,40,188,187,27,103,137,133,70,75,220,228,144,70,51,216,100,24,144,80,108,160,148,60,145,205,168,58,189,238,39,184,40,235,191,82,185,191,84,220,104,112,6,113,34,188,43,20,36,80,222,48,33,46,160,22,118,116,216,102,36,81,233,167,172,29,8,114,58,60,74,239,119,168,37,174,234,243,147,173,91,54,70,18,103,166,48,160,28,112,123,243,58,65,19,173,193,62,43,196,68,11,199,175,196,53,79,221,234,57,235,71,250,241,172,58,120,76,168,217,160,246,48,79,85,101,158,175,5,227,79,143,178,102,111,85,252,55,35,113,53,68,107,226,66,254,21,132,83,150,50,43,30,128,5],[248,81,128,128,128,128,128,128,128,128,128,160,31,135,73,204,174,167,159,229,36,59,217,161,39,71,252,185,59,171,62,199,226,95,101,195,206,134,71,61,127,129,37,56,128,160,203,196,24,180,91,92,42,155,178,224,138,157,186,202,85,129,212,160,95,196,131,76,51,38,251,230,158,133,225,177,41,135,128,128,128,128,128,5],[248,81,128,128,128,128,128,128,128,128,128,160,31,135,73,204,174,167,159,229,36,59,217,161,39,71,252,185,59,171,62,199,226,95,101,195,206,134,71,61,127,129,37,56,128,160,203,196,24,180,91,92,42,155,178,224,138,157,186,202,85,129,212,160,95,196,131,76,51,38,251,230,158,133,225,177,41,135,128,128,128,128,128,5]] \ No newline at end of file diff --git a/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountNilObjectInFirstLevel.json b/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountNilObjectInFirstLevel.json index a3f9395d02..e5d345b0cf 100644 --- a/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountNilObjectInFirstLevel.json +++ b/zkevm-circuits/src/mpt_circuit/tests/NonExistingAccountNilObjectInFirstLevel.json @@ -1 +1 @@ -[[0,1,0,1,249,1,49,249,1,49,15,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,0,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,0,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,0,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,194,199,153,182,10,12,214,172,212,44,16,21,81,40,114,232,108,24,107,207,25,110,133,6,30,118,132,47,59,124,248,96,0,160,194,199,153,182,10,12,214,172,212,44,16,21,81,40,114,232,108,24,107,207,25,110,133,6,30,118,132,47,59,124,248,96,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,0,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,0,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,123,92,219,73,235,134,229,100,19,175,139,32,58,144,71,107,191,38,132,61,243,212,96,190,152,153,159,211,0,24,138,140,0,160,123,92,219,73,235,134,229,100,19,175,139,32,58,144,71,107,191,38,132,61,243,212,96,190,152,153,159,211,0,24,138,140,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,0,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,0,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,17],[248,0,160,60,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,6],[248,0,160,60,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,4],[0,0,160,60,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,18],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,7],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,8],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,9],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,11],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,53,134,91,242,225,196,212,95,5,117,17,194,137,77,204,212,252,119,212,98,26,23,225,216,128,107,54,255,163,72,168,130,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,10],[249,1,49,128,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,128,128,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,160,194,199,153,182,10,12,214,172,212,44,16,21,81,40,114,232,108,24,107,207,25,110,133,6,30,118,132,47,59,124,248,96,128,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,128,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,128,160,123,92,219,73,235,134,229,100,19,175,139,32,58,144,71,107,191,38,132,61,243,212,96,190,152,153,159,211,0,24,138,140,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,128,128,5],[249,1,49,128,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,128,128,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,160,194,199,153,182,10,12,214,172,212,44,16,21,81,40,114,232,108,24,107,207,25,110,133,6,30,118,132,47,59,124,248,96,128,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,128,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,128,160,123,92,219,73,235,134,229,100,19,175,139,32,58,144,71,107,191,38,132,61,243,212,96,190,152,153,159,211,0,24,138,140,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,128,128,5]] \ No newline at end of file +[[0,1,0,1,249,1,17,249,1,17,15,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,0,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,0,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,0,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,232,31,94,199,101,22,45,72,175,88,225,83,40,225,68,67,200,149,65,19,130,105,242,195,115,70,197,49,209,63,178,186,0,160,232,31,94,199,101,22,45,72,175,88,225,83,40,225,68,67,200,149,65,19,130,105,242,195,115,70,197,49,209,63,178,186,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,0,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,0,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,0,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,0,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,17],[248,105,160,60,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,6],[248,105,160,60,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,4],[0,0,160,60,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,18],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,7],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,8],[0,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,9],[0,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,11],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,75,164,100,62,218,168,27,139,249,233,219,10,200,87,57,68,143,50,229,185,38,122,10,138,248,112,105,152,253,14,5,23,252,237,52,8,133,130,180,167,143,97,28,115,102,25,94,62,148,249,8,6,55,244,16,75,187,208,208,127,251,120,61,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,10],[249,1,17,128,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,128,128,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,160,232,31,94,199,101,22,45,72,175,88,225,83,40,225,68,67,200,149,65,19,130,105,242,195,115,70,197,49,209,63,178,186,128,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,128,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,128,128,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,128,128,5],[249,1,17,128,160,171,140,219,128,140,131,3,187,97,251,72,226,118,33,123,233,119,15,168,62,207,63,144,242,35,77,85,136,133,245,171,241,128,128,160,26,105,126,129,71,88,40,25,114,252,209,59,201,112,125,188,210,241,149,152,107,5,70,61,123,120,66,101,8,68,90,4,160,181,215,169,27,229,238,39,60,206,39,226,173,154,22,13,47,170,221,90,107,165,24,211,132,1,155,104,114,138,79,98,244,160,232,31,94,199,101,22,45,72,175,88,225,83,40,225,68,67,200,149,65,19,130,105,242,195,115,70,197,49,209,63,178,186,128,160,46,13,134,195,190,253,23,127,87,74,32,172,99,128,69,50,136,144,119,233,85,50,12,147,97,205,16,183,204,111,88,9,128,160,99,1,179,155,46,168,164,77,248,176,53,97,32,219,100,183,136,231,31,82,225,215,166,48,157,13,46,91,134,254,231,203,128,128,160,27,119,121,225,73,202,223,36,212,255,183,124,167,225,19,20,184,219,112,151,228,215,11,42,23,52,147,21,60,162,229,160,160,102,167,102,40,17,73,27,61,53,46,150,149,6,180,32,210,105,232,181,26,34,79,87,75,59,56,179,70,63,67,240,9,128,128,5]] \ No newline at end of file diff --git a/zkevm-circuits/src/mpt_circuit/tests/NonExistingStorageNil.json b/zkevm-circuits/src/mpt_circuit/tests/NonExistingStorageNil.json index 0c3e217dc8..a9891dc15c 100644 --- a/zkevm-circuits/src/mpt_circuit/tests/NonExistingStorageNil.json +++ b/zkevm-circuits/src/mpt_circuit/tests/NonExistingStorageNil.json @@ -1 +1 @@ -[[0,1,0,1,249,2,17,249,2,17,3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],[0,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,0,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,0,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,0,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,81,161,102,91,160,19,144,108,131,101,101,23,128,254,23,127,21,66,253,142,104,3,221,12,246,12,75,151,83,165,8,247,0,160,81,161,102,91,160,19,144,108,131,101,101,23,128,254,23,127,21,66,253,142,104,3,221,12,246,12,75,151,83,165,8,247,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,0,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,0,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,0,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,0,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,0,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,0,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,0,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,0,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,0,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,0,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,0,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,0,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,17],[0,1,0,1,249,2,17,249,2,17,7,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,32,114,50,12,62,189,106,20,134,185,146,28,23,254,217,42,238,29,2,23,26,44,204,98,23,49,136,43,60,200,131,203,0,160,32,114,50,12,62,189,106,20,134,185,146,28,23,254,217,42,238,29,2,23,26,44,204,98,23,49,136,43,60,200,131,203,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,10,122,174,89,193,94,170,119,181,105,68,128,225,99,30,47,203,11,219,63,185,212,28,135,191,38,229,164,205,251,29,178,0,160,10,122,174,89,193,94,170,119,181,105,68,128,225,99,30,47,203,11,219,63,185,212,28,135,191,38,229,164,205,251,29,178,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,196,56,120,16,50,206,164,153,42,137,240,168,48,191,84,89,147,194,236,15,27,79,106,86,147,188,114,238,224,245,134,237,0,160,196,56,120,16,50,206,164,153,42,137,240,168,48,191,84,89,147,194,236,15,27,79,106,86,147,188,114,238,224,245,134,237,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,110,98,248,22,245,45,207,250,31,51,65,156,160,157,187,161,111,44,138,199,254,61,51,142,225,57,123,216,229,126,111,230,0,160,110,98,248,22,245,45,207,250,31,51,65,156,160,157,187,161,111,44,138,199,254,61,51,142,225,57,123,216,229,126,111,230,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,43,111,2,145,226,86,104,84,88,106,96,162,207,2,192,64,233,219,19,142,115,84,245,190,9,221,204,102,175,1,218,152,0,160,43,111,2,145,226,86,104,84,88,106,96,162,207,2,192,64,233,219,19,142,115,84,245,190,9,221,204,102,175,1,218,152,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,91,124,51,211,9,235,73,230,129,79,76,57,179,252,147,61,46,222,55,49,156,35,181,181,217,140,199,194,135,126,239,251,0,160,91,124,51,211,9,235,73,230,129,79,76,57,179,252,147,61,46,222,55,49,156,35,181,181,217,140,199,194,135,126,239,251,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,198,173,47,15,24,247,123,29,143,238,210,5,76,44,0,7,148,217,241,207,46,233,29,69,86,104,40,186,220,153,45,109,0,160,198,173,47,15,24,247,123,29,143,238,210,5,76,44,0,7,148,217,241,207,46,233,29,69,86,104,40,186,220,153,45,109,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,11,161,79,203,76,0,94,197,247,21,34,15,237,251,186,101,156,155,254,196,0,173,231,220,178,64,214,23,193,146,249,233,0,160,11,161,79,203,76,0,94,197,247,21,34,15,237,251,186,101,156,155,254,196,0,173,231,220,178,64,214,23,193,146,249,233,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,94,170,238,196,129,29,127,164,98,174,87,50,178,177,9,46,2,110,163,58,47,215,198,105,189,243,131,59,129,53,180,89,0,160,94,170,238,196,129,29,127,164,98,174,87,50,178,177,9,46,2,110,163,58,47,215,198,105,189,243,131,59,129,53,180,89,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,100,67,185,240,66,4,48,205,115,127,26,88,222,95,211,125,147,9,222,53,50,52,5,236,92,121,225,7,231,129,183,118,0,160,100,67,185,240,66,4,48,205,115,127,26,88,222,95,211,125,147,9,222,53,50,52,5,236,92,121,225,7,231,129,183,118,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,98,103,206,41,116,82,141,170,215,102,145,113,216,126,189,19,11,241,144,204,193,255,163,78,123,38,167,60,204,134,150,138,0,160,98,103,206,41,116,82,141,170,215,102,145,113,216,126,189,19,11,241,144,204,193,255,163,78,123,38,167,60,204,134,150,138,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,14,57,61,55,77,138,237,254,201,136,74,118,169,27,32,212,0,81,198,68,17,205,32,97,149,86,102,107,103,216,158,108,0,160,14,57,61,55,77,138,237,254,201,136,74,118,169,27,32,212,0,81,198,68,17,205,32,97,149,86,102,107,103,216,158,108,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,151,89,46,200,117,181,97,231,220,224,98,192,154,217,203,140,50,96,138,63,225,123,181,80,33,237,168,148,72,146,50,208,0,160,151,89,46,200,117,181,97,231,220,224,98,192,154,217,203,140,50,96,138,63,225,123,181,80,33,237,168,148,72,146,50,208,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,70,252,166,157,14,188,140,228,37,115,14,85,160,172,150,194,35,108,206,222,246,77,148,119,39,187,37,14,249,50,33,252,0,160,70,252,166,157,14,188,140,228,37,115,14,85,160,172,150,194,35,108,206,222,246,77,148,119,39,187,37,14,249,50,33,252,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,162,242,182,77,88,97,208,25,129,240,64,131,25,157,85,189,101,121,176,49,54,69,9,103,38,30,211,249,183,129,23,209,0,160,162,242,182,77,88,97,208,25,129,240,64,131,25,157,85,189,101,121,176,49,54,69,9,103,38,30,211,249,183,129,23,209,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,189,254,23,52,6,11,216,25,233,79,162,217,173,14,166,14,30,113,114,183,249,21,18,130,138,13,247,166,235,118,154,23,0,160,189,254,23,52,6,11,216,25,233,79,162,217,173,14,166,14,30,113,114,183,249,21,18,130,138,13,247,166,235,118,154,23,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,8,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,80,148,255,185,38,251,16,216,144,46,115,25,219,9,156,208,216,2,63,88,215,254,38,196,107,216,121,200,104,112,41,166,0,160,80,148,255,185,38,251,16,216,144,46,115,25,219,9,156,208,216,2,63,88,215,254,38,196,107,216,121,200,104,112,41,166,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,232,64,114,15,200,106,11,109,160,11,185,172,141,121,247,148,195,206,231,233,199,129,249,71,91,217,235,116,232,212,187,23,0,160,232,64,114,15,200,106,11,109,160,11,185,172,141,121,247,148,195,206,231,233,199,129,249,71,91,217,235,116,232,212,187,23,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,22,24,113,187,195,199,19,22,220,222,38,68,10,149,249,10,83,196,145,149,30,216,79,55,240,137,14,190,167,183,11,248,0,160,22,24,113,187,195,199,19,22,220,222,38,68,10,149,249,10,83,196,145,149,30,216,79,55,240,137,14,190,167,183,11,248,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,26,80,98,123,95,183,78,86,169,116,95,134,0,242,193,10,159,55,133,145,50,232,89,49,77,88,236,254,190,119,46,179,0,160,26,80,98,123,95,183,78,86,169,116,95,134,0,242,193,10,159,55,133,145,50,232,89,49,77,88,236,254,190,119,46,179,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,219,11,189,199,146,209,207,184,241,225,225,82,254,168,36,177,54,129,136,43,174,3,69,132,76,68,238,217,185,64,76,188,0,160,219,11,189,199,146,209,207,184,241,225,225,82,254,168,36,177,54,129,136,43,174,3,69,132,76,68,238,217,185,64,76,188,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,255,255,49,52,51,148,215,160,44,11,164,35,64,77,116,244,205,109,34,105,83,191,185,98,61,152,31,107,47,93,226,182,0,160,255,255,49,52,51,148,215,160,44,11,164,35,64,77,116,244,205,109,34,105,83,191,185,98,61,152,31,107,47,93,226,182,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,141,207,26,39,186,93,5,76,248,240,96,160,123,14,221,226,176,218,191,61,55,177,128,23,185,89,251,26,120,1,137,73,0,160,141,207,26,39,186,93,5,76,248,240,96,160,123,14,221,226,176,218,191,61,55,177,128,23,185,89,251,26,120,1,137,73,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,35,20,61,139,93,25,155,182,10,41,79,55,103,14,165,89,100,101,112,251,202,56,255,204,172,35,165,18,191,59,191,42,0,160,35,20,61,139,93,25,155,182,10,41,79,55,103,14,165,89,100,101,112,251,202,56,255,204,172,35,165,18,191,59,191,42,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,143,224,89,30,184,196,153,96,132,8,72,89,237,23,38,198,197,52,213,48,160,163,90,143,21,246,48,48,243,27,57,233,0,160,143,224,89,30,184,196,153,96,132,8,72,89,237,23,38,198,197,52,213,48,160,163,90,143,21,246,48,48,243,27,57,233,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,161,117,24,172,49,150,116,109,36,187,48,213,144,170,125,36,153,110,226,55,47,140,26,254,184,244,194,140,147,47,42,231,0,160,161,117,24,172,49,150,116,109,36,187,48,213,144,170,125,36,153,110,226,55,47,140,26,254,184,244,194,140,147,47,42,231,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,80,215,25,106,21,12,101,148,138,219,184,184,188,40,58,115,84,38,142,85,198,23,126,169,205,238,223,41,50,89,224,22,0,160,80,215,25,106,21,12,101,148,138,219,184,184,188,40,58,115,84,38,142,85,198,23,126,169,205,238,223,41,50,89,224,22,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,117,137,133,54,28,123,80,12,122,22,182,143,154,153,195,240,131,11,204,239,47,187,92,198,160,194,159,23,63,110,69,23,0,160,117,137,133,54,28,123,80,12,122,22,182,143,154,153,195,240,131,11,204,239,47,187,92,198,160,194,159,23,63,110,69,23,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,192,126,139,172,39,190,85,65,175,44,222,171,235,106,94,226,10,102,215,144,5,84,241,252,249,77,74,39,235,161,155,27,0,160,192,126,139,172,39,190,85,65,175,44,222,171,235,106,94,226,10,102,215,144,5,84,241,252,249,77,74,39,235,161,155,27,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,196,6,129,141,159,153,225,109,54,205,224,250,103,31,169,248,190,191,252,11,209,179,82,134,242,212,102,162,34,226,61,112,0,160,196,6,129,141,159,153,225,109,54,205,224,250,103,31,169,248,190,191,252,11,209,179,82,134,242,212,102,162,34,226,61,112,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,194,89,55,164,148,35,149,201,62,178,116,127,182,51,153,157,6,43,147,76,67,31,130,227,50,40,178,162,17,107,171,35,0,160,194,89,55,164,148,35,149,201,62,178,116,127,182,51,153,157,6,43,147,76,67,31,130,227,50,40,178,162,17,107,171,35,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,117,214,70,75,202,75,148,198,51,170,204,17,106,206,189,79,195,252,21,147,184,128,92,162,208,14,202,231,35,190,240,162,0,160,117,214,70,75,202,75,148,198,51,170,204,17,106,206,189,79,195,252,21,147,184,128,92,162,208,14,202,231,35,190,240,162,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,14,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,50,134,227,121,222,107,41,253,160,126,236,53,159,171,4,233,12,192,130,29,187,146,42,103,75,238,149,5,228,164,51,219,0,160,50,134,227,121,222,107,41,253,160,126,236,53,159,171,4,233,12,192,130,29,187,146,42,103,75,238,149,5,228,164,51,219,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,109,223,240,132,44,244,231,89,34,238,116,54,182,126,145,33,158,218,129,84,25,117,193,93,57,54,129,207,71,158,10,239,0,160,109,223,240,132,44,244,231,89,34,238,116,54,182,126,145,33,158,218,129,84,25,117,193,93,57,54,129,207,71,158,10,239,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,137,71,32,30,231,144,195,14,161,165,205,202,106,148,96,107,179,11,204,136,166,237,106,5,140,223,195,49,2,38,252,37,0,160,137,71,32,30,231,144,195,14,161,165,205,202,106,148,96,107,179,11,204,136,166,237,106,5,140,223,195,49,2,38,252,37,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,10,16,12,178,172,155,142,38,79,250,185,38,8,229,41,242,146,125,222,231,178,85,169,113,65,235,192,3,221,253,133,121,0,160,10,16,12,178,172,155,142,38,79,250,185,38,8,229,41,242,146,125,222,231,178,85,169,113,65,235,192,3,221,253,133,121,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,118,155,214,194,160,124,204,154,165,83,205,21,77,129,218,30,159,182,4,232,144,206,128,190,236,186,178,127,98,184,35,118,0,160,118,155,214,194,160,124,204,154,165,83,205,21,77,129,218,30,159,182,4,232,144,206,128,190,236,186,178,127,98,184,35,118,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,242,87,113,63,110,51,159,220,10,125,93,196,79,30,80,58,128,111,185,193,117,25,116,202,155,203,154,233,77,106,251,95,0,160,242,87,113,63,110,51,159,220,10,125,93,196,79,30,80,58,128,111,185,193,117,25,116,202,155,203,154,233,77,106,251,95,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,179,216,217,227,32,241,45,244,75,203,37,4,51,184,112,104,40,154,140,239,221,64,49,88,53,119,11,221,100,30,115,147,0,160,179,216,217,227,32,241,45,244,75,203,37,4,51,184,112,104,40,154,140,239,221,64,49,88,53,119,11,221,100,30,115,147,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,123,86,224,58,55,134,195,209,93,93,167,112,126,144,159,207,30,2,157,97,66,237,247,243,246,61,16,108,150,69,42,216,0,160,123,86,224,58,55,134,195,209,93,93,167,112,126,144,159,207,30,2,157,97,66,237,247,243,246,61,16,108,150,69,42,216,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,198,153,173,222,150,149,89,189,206,216,72,55,211,25,7,209,20,124,201,116,255,43,245,33,132,248,22,100,146,228,180,33,0,160,198,153,173,222,150,149,89,189,206,216,72,55,211,25,7,209,20,124,201,116,255,43,245,33,132,248,22,100,146,228,180,33,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,18,207,94,155,112,54,113,255,83,129,204,156,94,155,128,87,24,190,90,35,118,51,118,49,201,101,169,161,53,195,204,212,0,160,18,207,94,155,112,54,113,255,83,129,204,156,94,155,128,87,24,190,90,35,118,51,118,49,201,101,169,161,53,195,204,212,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,38,148,237,87,162,36,238,225,7,186,236,165,131,196,134,87,58,128,154,30,76,224,193,106,231,54,167,127,2,63,242,235,0,160,38,148,237,87,162,36,238,225,7,186,236,165,131,196,134,87,58,128,154,30,76,224,193,106,231,54,167,127,2,63,242,235,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,65,15,250,185,115,180,192,8,106,46,90,186,76,63,247,99,101,120,4,178,131,76,104,150,74,77,30,88,24,180,2,165,0,160,65,15,250,185,115,180,192,8,106,46,90,186,76,63,247,99,101,120,4,178,131,76,104,150,74,77,30,88,24,180,2,165,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,27,195,248,41,48,169,202,25,179,195,80,92,28,41,117,203,45,106,247,70,163,164,155,57,204,247,48,8,150,255,69,103,0,160,27,195,248,41,48,169,202,25,179,195,80,92,28,41,117,203,45,106,247,70,163,164,155,57,204,247,48,8,150,255,69,103,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,77,29,23,199,242,162,32,107,153,219,31,93,210,56,39,34,133,30,238,106,236,197,206,47,158,52,226,240,22,66,24,152,0,160,77,29,23,199,242,162,32,107,153,219,31,93,210,56,39,34,133,30,238,106,236,197,206,47,158,52,226,240,22,66,24,152,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,128,210,64,36,232,87,25,151,157,53,5,163,236,235,238,238,244,222,96,49,29,31,13,153,104,5,231,22,7,200,223,157,0,160,128,210,64,36,232,87,25,151,157,53,5,163,236,235,238,238,244,222,96,49,29,31,13,153,104,5,231,22,7,200,223,157,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,254,142,169,167,195,251,188,33,233,78,222,45,23,253,255,129,174,132,231,175,11,153,146,70,137,247,100,109,26,106,12,199,0,160,254,142,169,167,195,251,188,33,233,78,222,45,23,253,255,129,174,132,231,175,11,153,146,70,137,247,100,109,26,106,12,199,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,51,241,12,122,223,81,152,154,37,130,73,169,73,174,190,217,162,228,6,125,211,205,215,202,77,228,212,82,225,163,237,192,0,160,51,241,12,122,223,81,152,154,37,130,73,169,73,174,190,217,162,228,6,125,211,205,215,202,77,228,212,82,225,163,237,192,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,108,57,248,46,203,51,108,5,211,233,36,199,112,197,41,226,231,139,145,164,37,226,96,51,179,184,38,179,18,214,14,227,0,160,108,57,248,46,203,51,108,5,211,233,36,199,112,197,41,226,231,139,145,164,37,226,96,51,179,184,38,179,18,214,14,227,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,216,159,123,174,245,114,217,222,163,30,130,28,130,112,42,41,60,19,247,247,77,30,167,48,212,24,142,109,140,167,139,82,0,160,216,159,123,174,245,114,217,222,163,30,130,28,130,112,42,41,60,19,247,247,77,30,167,48,212,24,142,109,140,167,139,82,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,22,24,108,63,110,11,171,135,168,27,40,62,80,124,232,38,247,70,47,131,50,237,27,177,116,224,97,0,220,105,0,207,0,160,22,24,108,63,110,11,171,135,168,27,40,62,80,124,232,38,247,70,47,131,50,237,27,177,116,224,97,0,220,105,0,207,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,27,32,153,65,20,139,14,102,94,202,123,191,220,51,10,53,15,90,91,208,231,17,74,83,74,152,198,129,106,142,107,134,0,160,27,32,153,65,20,139,14,102,94,202,123,191,220,51,10,53,15,90,91,208,231,17,74,83,74,152,198,129,106,142,107,134,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,16,34,203,96,5,245,23,207,43,83,207,130,98,43,103,126,11,36,249,214,34,87,112,151,109,81,5,82,255,10,70,82,0,160,16,34,203,96,5,245,23,207,43,83,207,130,98,43,103,126,11,36,249,214,34,87,112,151,109,81,5,82,255,10,70,82,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,132,190,217,18,224,217,151,188,25,206,221,116,137,199,19,252,252,99,167,60,24,250,47,2,99,252,223,58,210,71,103,12,0,160,132,190,217,18,224,217,151,188,25,206,221,116,137,199,19,252,252,99,167,60,24,250,47,2,99,252,223,58,210,71,103,12,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,135,48,207,246,58,141,50,138,56,71,148,180,41,114,250,70,187,44,46,24,129,201,137,5,131,252,164,150,132,206,7,211,0,160,135,48,207,246,58,141,50,138,56,71,148,180,41,114,250,70,187,44,46,24,129,201,137,5,131,252,164,150,132,206,7,211,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,7,209,151,13,253,160,217,6,204,0,47,210,144,219,252,152,90,3,87,48,29,26,178,0,169,194,214,154,68,243,197,216,0,160,7,209,151,13,253,160,217,6,204,0,47,210,144,219,252,152,90,3,87,48,29,26,178,0,169,194,214,154,68,243,197,216,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,168,128,138,221,38,113,12,138,148,57,231,108,100,18,221,11,59,37,117,212,20,18,79,176,177,24,166,101,83,116,36,59,0,160,168,128,138,221,38,113,12,138,148,57,231,108,100,18,221,11,59,37,117,212,20,18,79,176,177,24,166,101,83,116,36,59,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,144,107,197,69,239,225,195,211,211,21,4,18,41,56,121,142,55,91,224,216,214,151,57,52,247,120,231,250,1,211,193,23,0,160,144,107,197,69,239,225,195,211,211,21,4,18,41,56,121,142,55,91,224,216,214,151,57,52,247,120,231,250,1,211,193,23,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,252,108,69,245,6,88,254,119,86,9,126,110,214,65,71,203,229,188,14,60,46,204,216,105,26,210,18,15,27,254,12,175,0,160,252,108,69,245,6,88,254,119,86,9,126,110,214,65,71,203,229,188,14,60,46,204,216,105,26,210,18,15,27,254,12,175,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,56,164,46,14,139,85,27,222,5,117,226,241,232,26,221,205,195,150,196,115,106,141,181,231,173,150,150,86,230,174,230,118,0,160,56,164,46,14,139,85,27,222,5,117,226,241,232,26,221,205,195,150,196,115,106,141,181,231,173,150,150,86,230,174,230,118,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,96,9,107,203,131,222,63,178,190,68,100,198,163,179,53,14,232,10,145,138,227,125,133,153,241,162,90,61,106,174,48,209,0,160,96,9,107,203,131,222,63,178,190,68,100,198,163,179,53,14,232,10,145,138,227,125,133,153,241,162,90,61,106,174,48,209,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,162,80,140,238,232,172,104,178,189,11,3,53,206,103,224,50,105,110,53,97,36,158,83,102,72,24,88,21,28,158,125,203,0,160,162,80,140,238,232,172,104,178,189,11,3,53,206,103,224,50,105,110,53,97,36,158,83,102,72,24,88,21,28,158,125,203,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,230,193,57,145,215,135,56,63,27,141,34,161,66,40,124,150,99,218,110,125,26,203,193,93,106,20,228,191,226,53,27,240,0,160,230,193,57,145,215,135,56,63,27,141,34,161,66,40,124,150,99,218,110,125,26,203,193,93,106,20,228,191,226,53,27,240,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,11,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,33,39,1,20,248,247,235,8,83,14,6,51,208,30,213,108,102,237,221,215,232,228,70,187,27,78,176,0,8,163,95,170,0,160,33,39,1,20,248,247,235,8,83,14,6,51,208,30,213,108,102,237,221,215,232,228,70,187,27,78,176,0,8,163,95,170,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,170,99,98,103,42,49,51,254,9,177,205,247,241,15,60,230,117,203,102,101,101,117,218,172,171,136,197,129,129,130,31,135,0,160,170,99,98,103,42,49,51,254,9,177,205,247,241,15,60,230,117,203,102,101,101,117,218,172,171,136,197,129,129,130,31,135,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,117,64,244,64,112,120,157,17,156,151,58,2,245,143,63,101,157,15,87,248,32,196,84,75,122,84,59,46,48,185,191,98,0,160,117,64,244,64,112,120,157,17,156,151,58,2,245,143,63,101,157,15,87,248,32,196,84,75,122,84,59,46,48,185,191,98,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,152,57,96,242,252,200,111,209,46,155,238,44,25,164,134,150,12,61,86,57,75,184,111,192,204,68,72,77,18,170,16,245,0,160,152,57,96,242,252,200,111,209,46,155,238,44,25,164,134,150,12,61,86,57,75,184,111,192,204,68,72,77,18,170,16,245,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,122,244,234,173,129,12,158,231,23,76,102,97,134,68,156,85,77,238,116,20,225,160,149,10,98,208,198,250,39,121,27,120,0,160,122,244,234,173,129,12,158,231,23,76,102,97,134,68,156,85,77,238,116,20,225,160,149,10,98,208,198,250,39,121,27,120,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,196,241,34,116,90,96,56,131,49,177,20,26,140,119,178,238,103,214,185,234,93,9,46,201,69,146,50,75,219,126,18,104,0,160,196,241,34,116,90,96,56,131,49,177,20,26,140,119,178,238,103,214,185,234,93,9,46,201,69,146,50,75,219,126,18,104,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,47,54,175,158,157,10,125,127,125,79,46,159,240,21,120,207,129,232,177,59,69,144,48,48,133,172,168,167,82,56,85,246,0,160,47,54,175,158,157,10,125,127,125,79,46,159,240,21,120,207,129,232,177,59,69,144,48,48,133,172,168,167,82,56,85,246,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,234,182,79,195,232,90,25,45,147,29,63,169,129,218,194,0,227,65,134,220,75,104,160,206,99,71,160,250,166,59,33,254,0,160,234,182,79,195,232,90,25,45,147,29,63,169,129,218,194,0,227,65,134,220,75,104,160,206,99,71,160,250,166,59,33,254,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,30,163,206,180,138,61,188,189,238,35,29,37,221,22,221,228,190,56,109,233,40,189,149,208,125,22,132,212,243,222,162,48,0,160,30,163,206,180,138,61,188,189,238,35,29,37,221,22,221,228,190,56,109,233,40,189,149,208,125,22,132,212,243,222,162,48,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,168,86,17,145,160,253,175,87,189,242,36,138,180,171,181,57,203,52,179,52,152,169,215,250,29,11,216,22,173,124,244,48,0,160,168,86,17,145,160,253,175,87,189,242,36,138,180,171,181,57,203,52,179,52,152,169,215,250,29,11,216,22,173,124,244,48,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,160,23,89,94,237,247,112,172,230,48,73,35,139,102,199,84,73,192,236,59,221,22,192,197,215,139,186,217,1,41,82,148,0,160,160,23,89,94,237,247,112,172,230,48,73,35,139,102,199,84,73,192,236,59,221,22,192,197,215,139,186,217,1,41,82,148,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,152,114,105,120,10,10,91,38,126,46,99,128,203,158,68,32,150,137,142,142,220,103,7,68,247,231,125,68,50,69,173,31,0,160,152,114,105,120,10,10,91,38,126,46,99,128,203,158,68,32,150,137,142,142,220,103,7,68,247,231,125,68,50,69,173,31,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,232,192,193,129,55,246,219,2,21,95,185,215,91,77,57,159,231,197,191,216,110,12,90,42,102,228,47,143,187,182,239,195,0,160,232,192,193,129,55,246,219,2,21,95,185,215,91,77,57,159,231,197,191,216,110,12,90,42,102,228,47,143,187,182,239,195,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,221,159,32,235,93,231,122,178,230,101,161,192,173,79,175,184,59,126,75,86,134,254,172,15,3,234,37,200,238,16,226,190,0,160,221,159,32,235,93,231,122,178,230,101,161,192,173,79,175,184,59,126,75,86,134,254,172,15,3,234,37,200,238,16,226,190,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,38,143,194,58,172,99,153,99,15,216,34,169,236,44,42,7,158,105,155,130,175,192,127,236,79,21,193,223,173,150,50,180,0,160,38,143,194,58,172,99,153,99,15,216,34,169,236,44,42,7,158,105,155,130,175,192,127,236,79,21,193,223,173,150,50,180,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,2,127,2,197,234,36,175,155,248,175,204,19,60,74,97,151,82,20,50,241,248,141,215,153,181,193,58,87,151,184,73,254,0,160,2,127,2,197,234,36,175,155,248,175,204,19,60,74,97,151,82,20,50,241,248,141,215,153,181,193,58,87,151,184,73,254,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,1,49,249,1,49,13,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,119,73,17,92,128,20,103,104,232,32,124,19,16,87,60,164,208,90,161,44,211,37,10,22,234,211,119,99,38,103,198,198,0,160,119,73,17,92,128,20,103,104,232,32,124,19,16,87,60,164,208,90,161,44,211,37,10,22,234,211,119,99,38,103,198,198,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,197,2,59,23,137,170,248,2,213,118,95,76,155,251,48,153,90,243,215,96,187,113,77,106,134,162,144,12,225,177,150,82,0,160,197,2,59,23,137,170,248,2,213,118,95,76,155,251,48,153,90,243,215,96,187,113,77,106,134,162,144,12,225,177,150,82,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,163,49,39,187,25,224,238,70,65,179,76,107,218,25,133,29,45,119,79,102,88,247,235,233,62,172,199,17,252,137,160,132,0,160,163,49,39,187,25,224,238,70,65,179,76,107,218,25,133,29,45,119,79,102,88,247,235,233,62,172,199,17,252,137,160,132,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,228,247,244,44,169,159,121,241,37,203,87,229,189,5,235,105,253,45,60,197,77,122,58,147,64,9,131,17,17,142,20,155,0,160,228,247,244,44,169,159,121,241,37,203,87,229,189,5,235,105,253,45,60,197,77,122,58,147,64,9,131,17,17,142,20,155,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,205,29,5,65,38,9,46,153,141,104,202,181,91,192,0,13,172,218,7,199,83,1,165,46,186,0,114,232,249,237,55,86,0,160,205,29,5,65,38,9,46,153,141,104,202,181,91,192,0,13,172,218,7,199,83,1,165,46,186,0,114,232,249,237,55,86,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,95,199,183,163,77,23,5,95,41,107,232,12,194,66,48,248,191,156,189,227,198,181,71,183,94,67,71,52,31,231,186,220,0,160,95,199,183,163,77,23,5,95,41,107,232,12,194,66,48,248,191,156,189,227,198,181,71,183,94,67,71,52,31,231,186,220,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,72,154,12,74,44,172,232,136,12,112,213,212,84,199,60,155,180,189,250,131,119,235,245,179,231,69,41,210,95,2,102,69,0,160,72,154,12,74,44,172,232,136,12,112,213,212,84,199,60,155,180,189,250,131,119,235,245,179,231,69,41,210,95,2,102,69,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,185,48,236,239,154,158,161,183,121,156,86,53,176,75,170,145,108,209,199,136,127,25,169,15,172,38,79,212,229,151,21,78,0,160,185,48,236,239,154,158,161,183,121,156,86,53,176,75,170,145,108,209,199,136,127,25,169,15,172,38,79,212,229,151,21,78,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,168,42,10,43,57,84,192,82,188,77,84,115,130,173,36,32,174,129,104,109,48,102,57,116,53,12,2,1,10,219,36,135,0,160,168,42,10,43,57,84,192,82,188,77,84,115,130,173,36,32,174,129,104,109,48,102,57,116,53,12,2,1,10,219,36,135,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[248,102,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,6],[248,102,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,4],[0,0,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,18],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,7],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,8],[0,160,108,175,176,92,138,97,66,88,92,163,20,133,186,14,202,83,61,132,245,179,24,124,92,74,69,199,166,219,149,87,245,197,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,9],[0,160,108,175,176,92,138,97,66,88,92,163,20,133,186,14,202,83,61,132,245,179,24,124,92,74,69,199,166,219,149,87,245,197,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,11],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,10],[1,0,1,0,248,81,0,248,81,0,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,147,31,200,131,19,49,103,136,46,1,167,47,128,146,235,40,179,181,1,99,210,43,90,113,42,63,194,216,20,174,42,218,0,160,147,31,200,131,19,49,103,136,46,1,167,47,128,146,235,40,179,181,1,99,210,43,90,113,42,63,194,216,20,174,42,218,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,204,123,237,30,197,175,26,208,74,15,150,211,15,238,169,175,151,34,192,58,177,202,8,45,196,255,144,212,1,208,149,21,0,160,204,123,237,30,197,175,26,208,74,15,150,211,15,238,169,175,151,34,192,58,177,202,8,45,196,255,144,212,1,208,149,21,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[228,130,51,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,2],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,13],[228,130,51,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,3],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,14],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,15],[0,160,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,19],[249,2,17,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,160,81,161,102,91,160,19,144,108,131,101,101,23,128,254,23,127,21,66,253,142,104,3,221,12,246,12,75,151,83,165,8,247,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,128,5],[249,2,17,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,160,81,161,102,91,160,19,144,108,131,101,101,23,128,254,23,127,21,66,253,142,104,3,221,12,246,12,75,151,83,165,8,247,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,128,5],[249,2,17,160,32,114,50,12,62,189,106,20,134,185,146,28,23,254,217,42,238,29,2,23,26,44,204,98,23,49,136,43,60,200,131,203,160,10,122,174,89,193,94,170,119,181,105,68,128,225,99,30,47,203,11,219,63,185,212,28,135,191,38,229,164,205,251,29,178,160,196,56,120,16,50,206,164,153,42,137,240,168,48,191,84,89,147,194,236,15,27,79,106,86,147,188,114,238,224,245,134,237,160,110,98,248,22,245,45,207,250,31,51,65,156,160,157,187,161,111,44,138,199,254,61,51,142,225,57,123,216,229,126,111,230,160,43,111,2,145,226,86,104,84,88,106,96,162,207,2,192,64,233,219,19,142,115,84,245,190,9,221,204,102,175,1,218,152,160,91,124,51,211,9,235,73,230,129,79,76,57,179,252,147,61,46,222,55,49,156,35,181,181,217,140,199,194,135,126,239,251,160,198,173,47,15,24,247,123,29,143,238,210,5,76,44,0,7,148,217,241,207,46,233,29,69,86,104,40,186,220,153,45,109,160,11,161,79,203,76,0,94,197,247,21,34,15,237,251,186,101,156,155,254,196,0,173,231,220,178,64,214,23,193,146,249,233,160,94,170,238,196,129,29,127,164,98,174,87,50,178,177,9,46,2,110,163,58,47,215,198,105,189,243,131,59,129,53,180,89,160,100,67,185,240,66,4,48,205,115,127,26,88,222,95,211,125,147,9,222,53,50,52,5,236,92,121,225,7,231,129,183,118,160,98,103,206,41,116,82,141,170,215,102,145,113,216,126,189,19,11,241,144,204,193,255,163,78,123,38,167,60,204,134,150,138,160,14,57,61,55,77,138,237,254,201,136,74,118,169,27,32,212,0,81,198,68,17,205,32,97,149,86,102,107,103,216,158,108,160,151,89,46,200,117,181,97,231,220,224,98,192,154,217,203,140,50,96,138,63,225,123,181,80,33,237,168,148,72,146,50,208,160,70,252,166,157,14,188,140,228,37,115,14,85,160,172,150,194,35,108,206,222,246,77,148,119,39,187,37,14,249,50,33,252,160,162,242,182,77,88,97,208,25,129,240,64,131,25,157,85,189,101,121,176,49,54,69,9,103,38,30,211,249,183,129,23,209,160,189,254,23,52,6,11,216,25,233,79,162,217,173,14,166,14,30,113,114,183,249,21,18,130,138,13,247,166,235,118,154,23,128,5],[249,2,17,160,32,114,50,12,62,189,106,20,134,185,146,28,23,254,217,42,238,29,2,23,26,44,204,98,23,49,136,43,60,200,131,203,160,10,122,174,89,193,94,170,119,181,105,68,128,225,99,30,47,203,11,219,63,185,212,28,135,191,38,229,164,205,251,29,178,160,196,56,120,16,50,206,164,153,42,137,240,168,48,191,84,89,147,194,236,15,27,79,106,86,147,188,114,238,224,245,134,237,160,110,98,248,22,245,45,207,250,31,51,65,156,160,157,187,161,111,44,138,199,254,61,51,142,225,57,123,216,229,126,111,230,160,43,111,2,145,226,86,104,84,88,106,96,162,207,2,192,64,233,219,19,142,115,84,245,190,9,221,204,102,175,1,218,152,160,91,124,51,211,9,235,73,230,129,79,76,57,179,252,147,61,46,222,55,49,156,35,181,181,217,140,199,194,135,126,239,251,160,198,173,47,15,24,247,123,29,143,238,210,5,76,44,0,7,148,217,241,207,46,233,29,69,86,104,40,186,220,153,45,109,160,11,161,79,203,76,0,94,197,247,21,34,15,237,251,186,101,156,155,254,196,0,173,231,220,178,64,214,23,193,146,249,233,160,94,170,238,196,129,29,127,164,98,174,87,50,178,177,9,46,2,110,163,58,47,215,198,105,189,243,131,59,129,53,180,89,160,100,67,185,240,66,4,48,205,115,127,26,88,222,95,211,125,147,9,222,53,50,52,5,236,92,121,225,7,231,129,183,118,160,98,103,206,41,116,82,141,170,215,102,145,113,216,126,189,19,11,241,144,204,193,255,163,78,123,38,167,60,204,134,150,138,160,14,57,61,55,77,138,237,254,201,136,74,118,169,27,32,212,0,81,198,68,17,205,32,97,149,86,102,107,103,216,158,108,160,151,89,46,200,117,181,97,231,220,224,98,192,154,217,203,140,50,96,138,63,225,123,181,80,33,237,168,148,72,146,50,208,160,70,252,166,157,14,188,140,228,37,115,14,85,160,172,150,194,35,108,206,222,246,77,148,119,39,187,37,14,249,50,33,252,160,162,242,182,77,88,97,208,25,129,240,64,131,25,157,85,189,101,121,176,49,54,69,9,103,38,30,211,249,183,129,23,209,160,189,254,23,52,6,11,216,25,233,79,162,217,173,14,166,14,30,113,114,183,249,21,18,130,138,13,247,166,235,118,154,23,128,5],[249,2,17,160,80,148,255,185,38,251,16,216,144,46,115,25,219,9,156,208,216,2,63,88,215,254,38,196,107,216,121,200,104,112,41,166,160,232,64,114,15,200,106,11,109,160,11,185,172,141,121,247,148,195,206,231,233,199,129,249,71,91,217,235,116,232,212,187,23,160,22,24,113,187,195,199,19,22,220,222,38,68,10,149,249,10,83,196,145,149,30,216,79,55,240,137,14,190,167,183,11,248,160,26,80,98,123,95,183,78,86,169,116,95,134,0,242,193,10,159,55,133,145,50,232,89,49,77,88,236,254,190,119,46,179,160,219,11,189,199,146,209,207,184,241,225,225,82,254,168,36,177,54,129,136,43,174,3,69,132,76,68,238,217,185,64,76,188,160,255,255,49,52,51,148,215,160,44,11,164,35,64,77,116,244,205,109,34,105,83,191,185,98,61,152,31,107,47,93,226,182,160,141,207,26,39,186,93,5,76,248,240,96,160,123,14,221,226,176,218,191,61,55,177,128,23,185,89,251,26,120,1,137,73,160,35,20,61,139,93,25,155,182,10,41,79,55,103,14,165,89,100,101,112,251,202,56,255,204,172,35,165,18,191,59,191,42,160,143,224,89,30,184,196,153,96,132,8,72,89,237,23,38,198,197,52,213,48,160,163,90,143,21,246,48,48,243,27,57,233,160,161,117,24,172,49,150,116,109,36,187,48,213,144,170,125,36,153,110,226,55,47,140,26,254,184,244,194,140,147,47,42,231,160,80,215,25,106,21,12,101,148,138,219,184,184,188,40,58,115,84,38,142,85,198,23,126,169,205,238,223,41,50,89,224,22,160,117,137,133,54,28,123,80,12,122,22,182,143,154,153,195,240,131,11,204,239,47,187,92,198,160,194,159,23,63,110,69,23,160,192,126,139,172,39,190,85,65,175,44,222,171,235,106,94,226,10,102,215,144,5,84,241,252,249,77,74,39,235,161,155,27,160,196,6,129,141,159,153,225,109,54,205,224,250,103,31,169,248,190,191,252,11,209,179,82,134,242,212,102,162,34,226,61,112,160,194,89,55,164,148,35,149,201,62,178,116,127,182,51,153,157,6,43,147,76,67,31,130,227,50,40,178,162,17,107,171,35,160,117,214,70,75,202,75,148,198,51,170,204,17,106,206,189,79,195,252,21,147,184,128,92,162,208,14,202,231,35,190,240,162,128,5],[249,2,17,160,80,148,255,185,38,251,16,216,144,46,115,25,219,9,156,208,216,2,63,88,215,254,38,196,107,216,121,200,104,112,41,166,160,232,64,114,15,200,106,11,109,160,11,185,172,141,121,247,148,195,206,231,233,199,129,249,71,91,217,235,116,232,212,187,23,160,22,24,113,187,195,199,19,22,220,222,38,68,10,149,249,10,83,196,145,149,30,216,79,55,240,137,14,190,167,183,11,248,160,26,80,98,123,95,183,78,86,169,116,95,134,0,242,193,10,159,55,133,145,50,232,89,49,77,88,236,254,190,119,46,179,160,219,11,189,199,146,209,207,184,241,225,225,82,254,168,36,177,54,129,136,43,174,3,69,132,76,68,238,217,185,64,76,188,160,255,255,49,52,51,148,215,160,44,11,164,35,64,77,116,244,205,109,34,105,83,191,185,98,61,152,31,107,47,93,226,182,160,141,207,26,39,186,93,5,76,248,240,96,160,123,14,221,226,176,218,191,61,55,177,128,23,185,89,251,26,120,1,137,73,160,35,20,61,139,93,25,155,182,10,41,79,55,103,14,165,89,100,101,112,251,202,56,255,204,172,35,165,18,191,59,191,42,160,143,224,89,30,184,196,153,96,132,8,72,89,237,23,38,198,197,52,213,48,160,163,90,143,21,246,48,48,243,27,57,233,160,161,117,24,172,49,150,116,109,36,187,48,213,144,170,125,36,153,110,226,55,47,140,26,254,184,244,194,140,147,47,42,231,160,80,215,25,106,21,12,101,148,138,219,184,184,188,40,58,115,84,38,142,85,198,23,126,169,205,238,223,41,50,89,224,22,160,117,137,133,54,28,123,80,12,122,22,182,143,154,153,195,240,131,11,204,239,47,187,92,198,160,194,159,23,63,110,69,23,160,192,126,139,172,39,190,85,65,175,44,222,171,235,106,94,226,10,102,215,144,5,84,241,252,249,77,74,39,235,161,155,27,160,196,6,129,141,159,153,225,109,54,205,224,250,103,31,169,248,190,191,252,11,209,179,82,134,242,212,102,162,34,226,61,112,160,194,89,55,164,148,35,149,201,62,178,116,127,182,51,153,157,6,43,147,76,67,31,130,227,50,40,178,162,17,107,171,35,160,117,214,70,75,202,75,148,198,51,170,204,17,106,206,189,79,195,252,21,147,184,128,92,162,208,14,202,231,35,190,240,162,128,5],[249,2,17,160,50,134,227,121,222,107,41,253,160,126,236,53,159,171,4,233,12,192,130,29,187,146,42,103,75,238,149,5,228,164,51,219,160,109,223,240,132,44,244,231,89,34,238,116,54,182,126,145,33,158,218,129,84,25,117,193,93,57,54,129,207,71,158,10,239,160,137,71,32,30,231,144,195,14,161,165,205,202,106,148,96,107,179,11,204,136,166,237,106,5,140,223,195,49,2,38,252,37,160,10,16,12,178,172,155,142,38,79,250,185,38,8,229,41,242,146,125,222,231,178,85,169,113,65,235,192,3,221,253,133,121,160,118,155,214,194,160,124,204,154,165,83,205,21,77,129,218,30,159,182,4,232,144,206,128,190,236,186,178,127,98,184,35,118,160,242,87,113,63,110,51,159,220,10,125,93,196,79,30,80,58,128,111,185,193,117,25,116,202,155,203,154,233,77,106,251,95,160,179,216,217,227,32,241,45,244,75,203,37,4,51,184,112,104,40,154,140,239,221,64,49,88,53,119,11,221,100,30,115,147,160,123,86,224,58,55,134,195,209,93,93,167,112,126,144,159,207,30,2,157,97,66,237,247,243,246,61,16,108,150,69,42,216,160,198,153,173,222,150,149,89,189,206,216,72,55,211,25,7,209,20,124,201,116,255,43,245,33,132,248,22,100,146,228,180,33,160,18,207,94,155,112,54,113,255,83,129,204,156,94,155,128,87,24,190,90,35,118,51,118,49,201,101,169,161,53,195,204,212,160,38,148,237,87,162,36,238,225,7,186,236,165,131,196,134,87,58,128,154,30,76,224,193,106,231,54,167,127,2,63,242,235,160,65,15,250,185,115,180,192,8,106,46,90,186,76,63,247,99,101,120,4,178,131,76,104,150,74,77,30,88,24,180,2,165,160,27,195,248,41,48,169,202,25,179,195,80,92,28,41,117,203,45,106,247,70,163,164,155,57,204,247,48,8,150,255,69,103,160,77,29,23,199,242,162,32,107,153,219,31,93,210,56,39,34,133,30,238,106,236,197,206,47,158,52,226,240,22,66,24,152,160,128,210,64,36,232,87,25,151,157,53,5,163,236,235,238,238,244,222,96,49,29,31,13,153,104,5,231,22,7,200,223,157,160,254,142,169,167,195,251,188,33,233,78,222,45,23,253,255,129,174,132,231,175,11,153,146,70,137,247,100,109,26,106,12,199,128,5],[249,2,17,160,50,134,227,121,222,107,41,253,160,126,236,53,159,171,4,233,12,192,130,29,187,146,42,103,75,238,149,5,228,164,51,219,160,109,223,240,132,44,244,231,89,34,238,116,54,182,126,145,33,158,218,129,84,25,117,193,93,57,54,129,207,71,158,10,239,160,137,71,32,30,231,144,195,14,161,165,205,202,106,148,96,107,179,11,204,136,166,237,106,5,140,223,195,49,2,38,252,37,160,10,16,12,178,172,155,142,38,79,250,185,38,8,229,41,242,146,125,222,231,178,85,169,113,65,235,192,3,221,253,133,121,160,118,155,214,194,160,124,204,154,165,83,205,21,77,129,218,30,159,182,4,232,144,206,128,190,236,186,178,127,98,184,35,118,160,242,87,113,63,110,51,159,220,10,125,93,196,79,30,80,58,128,111,185,193,117,25,116,202,155,203,154,233,77,106,251,95,160,179,216,217,227,32,241,45,244,75,203,37,4,51,184,112,104,40,154,140,239,221,64,49,88,53,119,11,221,100,30,115,147,160,123,86,224,58,55,134,195,209,93,93,167,112,126,144,159,207,30,2,157,97,66,237,247,243,246,61,16,108,150,69,42,216,160,198,153,173,222,150,149,89,189,206,216,72,55,211,25,7,209,20,124,201,116,255,43,245,33,132,248,22,100,146,228,180,33,160,18,207,94,155,112,54,113,255,83,129,204,156,94,155,128,87,24,190,90,35,118,51,118,49,201,101,169,161,53,195,204,212,160,38,148,237,87,162,36,238,225,7,186,236,165,131,196,134,87,58,128,154,30,76,224,193,106,231,54,167,127,2,63,242,235,160,65,15,250,185,115,180,192,8,106,46,90,186,76,63,247,99,101,120,4,178,131,76,104,150,74,77,30,88,24,180,2,165,160,27,195,248,41,48,169,202,25,179,195,80,92,28,41,117,203,45,106,247,70,163,164,155,57,204,247,48,8,150,255,69,103,160,77,29,23,199,242,162,32,107,153,219,31,93,210,56,39,34,133,30,238,106,236,197,206,47,158,52,226,240,22,66,24,152,160,128,210,64,36,232,87,25,151,157,53,5,163,236,235,238,238,244,222,96,49,29,31,13,153,104,5,231,22,7,200,223,157,160,254,142,169,167,195,251,188,33,233,78,222,45,23,253,255,129,174,132,231,175,11,153,146,70,137,247,100,109,26,106,12,199,128,5],[249,2,17,160,51,241,12,122,223,81,152,154,37,130,73,169,73,174,190,217,162,228,6,125,211,205,215,202,77,228,212,82,225,163,237,192,160,108,57,248,46,203,51,108,5,211,233,36,199,112,197,41,226,231,139,145,164,37,226,96,51,179,184,38,179,18,214,14,227,160,216,159,123,174,245,114,217,222,163,30,130,28,130,112,42,41,60,19,247,247,77,30,167,48,212,24,142,109,140,167,139,82,160,22,24,108,63,110,11,171,135,168,27,40,62,80,124,232,38,247,70,47,131,50,237,27,177,116,224,97,0,220,105,0,207,160,27,32,153,65,20,139,14,102,94,202,123,191,220,51,10,53,15,90,91,208,231,17,74,83,74,152,198,129,106,142,107,134,160,16,34,203,96,5,245,23,207,43,83,207,130,98,43,103,126,11,36,249,214,34,87,112,151,109,81,5,82,255,10,70,82,160,132,190,217,18,224,217,151,188,25,206,221,116,137,199,19,252,252,99,167,60,24,250,47,2,99,252,223,58,210,71,103,12,160,135,48,207,246,58,141,50,138,56,71,148,180,41,114,250,70,187,44,46,24,129,201,137,5,131,252,164,150,132,206,7,211,160,7,209,151,13,253,160,217,6,204,0,47,210,144,219,252,152,90,3,87,48,29,26,178,0,169,194,214,154,68,243,197,216,160,168,128,138,221,38,113,12,138,148,57,231,108,100,18,221,11,59,37,117,212,20,18,79,176,177,24,166,101,83,116,36,59,160,144,107,197,69,239,225,195,211,211,21,4,18,41,56,121,142,55,91,224,216,214,151,57,52,247,120,231,250,1,211,193,23,160,252,108,69,245,6,88,254,119,86,9,126,110,214,65,71,203,229,188,14,60,46,204,216,105,26,210,18,15,27,254,12,175,160,56,164,46,14,139,85,27,222,5,117,226,241,232,26,221,205,195,150,196,115,106,141,181,231,173,150,150,86,230,174,230,118,160,96,9,107,203,131,222,63,178,190,68,100,198,163,179,53,14,232,10,145,138,227,125,133,153,241,162,90,61,106,174,48,209,160,162,80,140,238,232,172,104,178,189,11,3,53,206,103,224,50,105,110,53,97,36,158,83,102,72,24,88,21,28,158,125,203,160,230,193,57,145,215,135,56,63,27,141,34,161,66,40,124,150,99,218,110,125,26,203,193,93,106,20,228,191,226,53,27,240,128,5],[249,2,17,160,51,241,12,122,223,81,152,154,37,130,73,169,73,174,190,217,162,228,6,125,211,205,215,202,77,228,212,82,225,163,237,192,160,108,57,248,46,203,51,108,5,211,233,36,199,112,197,41,226,231,139,145,164,37,226,96,51,179,184,38,179,18,214,14,227,160,216,159,123,174,245,114,217,222,163,30,130,28,130,112,42,41,60,19,247,247,77,30,167,48,212,24,142,109,140,167,139,82,160,22,24,108,63,110,11,171,135,168,27,40,62,80,124,232,38,247,70,47,131,50,237,27,177,116,224,97,0,220,105,0,207,160,27,32,153,65,20,139,14,102,94,202,123,191,220,51,10,53,15,90,91,208,231,17,74,83,74,152,198,129,106,142,107,134,160,16,34,203,96,5,245,23,207,43,83,207,130,98,43,103,126,11,36,249,214,34,87,112,151,109,81,5,82,255,10,70,82,160,132,190,217,18,224,217,151,188,25,206,221,116,137,199,19,252,252,99,167,60,24,250,47,2,99,252,223,58,210,71,103,12,160,135,48,207,246,58,141,50,138,56,71,148,180,41,114,250,70,187,44,46,24,129,201,137,5,131,252,164,150,132,206,7,211,160,7,209,151,13,253,160,217,6,204,0,47,210,144,219,252,152,90,3,87,48,29,26,178,0,169,194,214,154,68,243,197,216,160,168,128,138,221,38,113,12,138,148,57,231,108,100,18,221,11,59,37,117,212,20,18,79,176,177,24,166,101,83,116,36,59,160,144,107,197,69,239,225,195,211,211,21,4,18,41,56,121,142,55,91,224,216,214,151,57,52,247,120,231,250,1,211,193,23,160,252,108,69,245,6,88,254,119,86,9,126,110,214,65,71,203,229,188,14,60,46,204,216,105,26,210,18,15,27,254,12,175,160,56,164,46,14,139,85,27,222,5,117,226,241,232,26,221,205,195,150,196,115,106,141,181,231,173,150,150,86,230,174,230,118,160,96,9,107,203,131,222,63,178,190,68,100,198,163,179,53,14,232,10,145,138,227,125,133,153,241,162,90,61,106,174,48,209,160,162,80,140,238,232,172,104,178,189,11,3,53,206,103,224,50,105,110,53,97,36,158,83,102,72,24,88,21,28,158,125,203,160,230,193,57,145,215,135,56,63,27,141,34,161,66,40,124,150,99,218,110,125,26,203,193,93,106,20,228,191,226,53,27,240,128,5],[249,2,17,160,33,39,1,20,248,247,235,8,83,14,6,51,208,30,213,108,102,237,221,215,232,228,70,187,27,78,176,0,8,163,95,170,160,170,99,98,103,42,49,51,254,9,177,205,247,241,15,60,230,117,203,102,101,101,117,218,172,171,136,197,129,129,130,31,135,160,117,64,244,64,112,120,157,17,156,151,58,2,245,143,63,101,157,15,87,248,32,196,84,75,122,84,59,46,48,185,191,98,160,152,57,96,242,252,200,111,209,46,155,238,44,25,164,134,150,12,61,86,57,75,184,111,192,204,68,72,77,18,170,16,245,160,122,244,234,173,129,12,158,231,23,76,102,97,134,68,156,85,77,238,116,20,225,160,149,10,98,208,198,250,39,121,27,120,160,196,241,34,116,90,96,56,131,49,177,20,26,140,119,178,238,103,214,185,234,93,9,46,201,69,146,50,75,219,126,18,104,160,47,54,175,158,157,10,125,127,125,79,46,159,240,21,120,207,129,232,177,59,69,144,48,48,133,172,168,167,82,56,85,246,160,234,182,79,195,232,90,25,45,147,29,63,169,129,218,194,0,227,65,134,220,75,104,160,206,99,71,160,250,166,59,33,254,160,30,163,206,180,138,61,188,189,238,35,29,37,221,22,221,228,190,56,109,233,40,189,149,208,125,22,132,212,243,222,162,48,160,168,86,17,145,160,253,175,87,189,242,36,138,180,171,181,57,203,52,179,52,152,169,215,250,29,11,216,22,173,124,244,48,160,160,23,89,94,237,247,112,172,230,48,73,35,139,102,199,84,73,192,236,59,221,22,192,197,215,139,186,217,1,41,82,148,160,152,114,105,120,10,10,91,38,126,46,99,128,203,158,68,32,150,137,142,142,220,103,7,68,247,231,125,68,50,69,173,31,160,232,192,193,129,55,246,219,2,21,95,185,215,91,77,57,159,231,197,191,216,110,12,90,42,102,228,47,143,187,182,239,195,160,221,159,32,235,93,231,122,178,230,101,161,192,173,79,175,184,59,126,75,86,134,254,172,15,3,234,37,200,238,16,226,190,160,38,143,194,58,172,99,153,99,15,216,34,169,236,44,42,7,158,105,155,130,175,192,127,236,79,21,193,223,173,150,50,180,160,2,127,2,197,234,36,175,155,248,175,204,19,60,74,97,151,82,20,50,241,248,141,215,153,181,193,58,87,151,184,73,254,128,5],[249,2,17,160,33,39,1,20,248,247,235,8,83,14,6,51,208,30,213,108,102,237,221,215,232,228,70,187,27,78,176,0,8,163,95,170,160,170,99,98,103,42,49,51,254,9,177,205,247,241,15,60,230,117,203,102,101,101,117,218,172,171,136,197,129,129,130,31,135,160,117,64,244,64,112,120,157,17,156,151,58,2,245,143,63,101,157,15,87,248,32,196,84,75,122,84,59,46,48,185,191,98,160,152,57,96,242,252,200,111,209,46,155,238,44,25,164,134,150,12,61,86,57,75,184,111,192,204,68,72,77,18,170,16,245,160,122,244,234,173,129,12,158,231,23,76,102,97,134,68,156,85,77,238,116,20,225,160,149,10,98,208,198,250,39,121,27,120,160,196,241,34,116,90,96,56,131,49,177,20,26,140,119,178,238,103,214,185,234,93,9,46,201,69,146,50,75,219,126,18,104,160,47,54,175,158,157,10,125,127,125,79,46,159,240,21,120,207,129,232,177,59,69,144,48,48,133,172,168,167,82,56,85,246,160,234,182,79,195,232,90,25,45,147,29,63,169,129,218,194,0,227,65,134,220,75,104,160,206,99,71,160,250,166,59,33,254,160,30,163,206,180,138,61,188,189,238,35,29,37,221,22,221,228,190,56,109,233,40,189,149,208,125,22,132,212,243,222,162,48,160,168,86,17,145,160,253,175,87,189,242,36,138,180,171,181,57,203,52,179,52,152,169,215,250,29,11,216,22,173,124,244,48,160,160,23,89,94,237,247,112,172,230,48,73,35,139,102,199,84,73,192,236,59,221,22,192,197,215,139,186,217,1,41,82,148,160,152,114,105,120,10,10,91,38,126,46,99,128,203,158,68,32,150,137,142,142,220,103,7,68,247,231,125,68,50,69,173,31,160,232,192,193,129,55,246,219,2,21,95,185,215,91,77,57,159,231,197,191,216,110,12,90,42,102,228,47,143,187,182,239,195,160,221,159,32,235,93,231,122,178,230,101,161,192,173,79,175,184,59,126,75,86,134,254,172,15,3,234,37,200,238,16,226,190,160,38,143,194,58,172,99,153,99,15,216,34,169,236,44,42,7,158,105,155,130,175,192,127,236,79,21,193,223,173,150,50,180,160,2,127,2,197,234,36,175,155,248,175,204,19,60,74,97,151,82,20,50,241,248,141,215,153,181,193,58,87,151,184,73,254,128,5],[249,1,49,160,119,73,17,92,128,20,103,104,232,32,124,19,16,87,60,164,208,90,161,44,211,37,10,22,234,211,119,99,38,103,198,198,128,128,160,197,2,59,23,137,170,248,2,213,118,95,76,155,251,48,153,90,243,215,96,187,113,77,106,134,162,144,12,225,177,150,82,128,160,163,49,39,187,25,224,238,70,65,179,76,107,218,25,133,29,45,119,79,102,88,247,235,233,62,172,199,17,252,137,160,132,160,228,247,244,44,169,159,121,241,37,203,87,229,189,5,235,105,253,45,60,197,77,122,58,147,64,9,131,17,17,142,20,155,128,128,160,205,29,5,65,38,9,46,153,141,104,202,181,91,192,0,13,172,218,7,199,83,1,165,46,186,0,114,232,249,237,55,86,160,95,199,183,163,77,23,5,95,41,107,232,12,194,66,48,248,191,156,189,227,198,181,71,183,94,67,71,52,31,231,186,220,128,160,72,154,12,74,44,172,232,136,12,112,213,212,84,199,60,155,180,189,250,131,119,235,245,179,231,69,41,210,95,2,102,69,160,185,48,236,239,154,158,161,183,121,156,86,53,176,75,170,145,108,209,199,136,127,25,169,15,172,38,79,212,229,151,21,78,128,160,168,42,10,43,57,84,192,82,188,77,84,115,130,173,36,32,174,129,104,109,48,102,57,116,53,12,2,1,10,219,36,135,128,5],[249,1,49,160,119,73,17,92,128,20,103,104,232,32,124,19,16,87,60,164,208,90,161,44,211,37,10,22,234,211,119,99,38,103,198,198,128,128,160,197,2,59,23,137,170,248,2,213,118,95,76,155,251,48,153,90,243,215,96,187,113,77,106,134,162,144,12,225,177,150,82,128,160,163,49,39,187,25,224,238,70,65,179,76,107,218,25,133,29,45,119,79,102,88,247,235,233,62,172,199,17,252,137,160,132,160,228,247,244,44,169,159,121,241,37,203,87,229,189,5,235,105,253,45,60,197,77,122,58,147,64,9,131,17,17,142,20,155,128,128,160,205,29,5,65,38,9,46,153,141,104,202,181,91,192,0,13,172,218,7,199,83,1,165,46,186,0,114,232,249,237,55,86,160,95,199,183,163,77,23,5,95,41,107,232,12,194,66,48,248,191,156,189,227,198,181,71,183,94,67,71,52,31,231,186,220,128,160,72,154,12,74,44,172,232,136,12,112,213,212,84,199,60,155,180,189,250,131,119,235,245,179,231,69,41,210,95,2,102,69,160,185,48,236,239,154,158,161,183,121,156,86,53,176,75,170,145,108,209,199,136,127,25,169,15,172,38,79,212,229,151,21,78,128,160,168,42,10,43,57,84,192,82,188,77,84,115,130,173,36,32,174,129,104,109,48,102,57,116,53,12,2,1,10,219,36,135,128,5],[248,102,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,184,70,248,68,128,128,160,108,175,176,92,138,97,66,88,92,163,20,133,186,14,202,83,61,132,245,179,24,124,92,74,69,199,166,219,149,87,245,197,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,5],[248,102,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,184,70,248,68,128,128,160,108,175,176,92,138,97,66,88,92,163,20,133,186,14,202,83,61,132,245,179,24,124,92,74,69,199,166,219,149,87,245,197,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,5],[248,81,128,128,128,160,147,31,200,131,19,49,103,136,46,1,167,47,128,146,235,40,179,181,1,99,210,43,90,113,42,63,194,216,20,174,42,218,128,128,128,128,128,128,128,160,204,123,237,30,197,175,26,208,74,15,150,211,15,238,169,175,151,34,192,58,177,202,8,45,196,255,144,212,1,208,149,21,128,128,128,128,128,5],[248,81,128,128,128,160,147,31,200,131,19,49,103,136,46,1,167,47,128,146,235,40,179,181,1,99,210,43,90,113,42,63,194,216,20,174,42,218,128,128,128,128,128,128,128,160,204,123,237,30,197,175,26,208,74,15,150,211,15,238,169,175,151,34,192,58,177,202,8,45,196,255,144,212,1,208,149,21,128,128,128,128,128,5]] \ No newline at end of file +[[0,1,0,1,249,2,17,249,2,17,3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],[0,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,0,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,0,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,0,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,81,161,102,91,160,19,144,108,131,101,101,23,128,254,23,127,21,66,253,142,104,3,221,12,246,12,75,151,83,165,8,247,0,160,81,161,102,91,160,19,144,108,131,101,101,23,128,254,23,127,21,66,253,142,104,3,221,12,246,12,75,151,83,165,8,247,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,0,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,0,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,0,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,0,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,0,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,0,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,0,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,0,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,0,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,0,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,0,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,0,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,17],[0,1,0,1,249,2,17,249,2,17,7,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,32,114,50,12,62,189,106,20,134,185,146,28,23,254,217,42,238,29,2,23,26,44,204,98,23,49,136,43,60,200,131,203,0,160,32,114,50,12,62,189,106,20,134,185,146,28,23,254,217,42,238,29,2,23,26,44,204,98,23,49,136,43,60,200,131,203,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,10,122,174,89,193,94,170,119,181,105,68,128,225,99,30,47,203,11,219,63,185,212,28,135,191,38,229,164,205,251,29,178,0,160,10,122,174,89,193,94,170,119,181,105,68,128,225,99,30,47,203,11,219,63,185,212,28,135,191,38,229,164,205,251,29,178,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,196,56,120,16,50,206,164,153,42,137,240,168,48,191,84,89,147,194,236,15,27,79,106,86,147,188,114,238,224,245,134,237,0,160,196,56,120,16,50,206,164,153,42,137,240,168,48,191,84,89,147,194,236,15,27,79,106,86,147,188,114,238,224,245,134,237,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,110,98,248,22,245,45,207,250,31,51,65,156,160,157,187,161,111,44,138,199,254,61,51,142,225,57,123,216,229,126,111,230,0,160,110,98,248,22,245,45,207,250,31,51,65,156,160,157,187,161,111,44,138,199,254,61,51,142,225,57,123,216,229,126,111,230,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,43,111,2,145,226,86,104,84,88,106,96,162,207,2,192,64,233,219,19,142,115,84,245,190,9,221,204,102,175,1,218,152,0,160,43,111,2,145,226,86,104,84,88,106,96,162,207,2,192,64,233,219,19,142,115,84,245,190,9,221,204,102,175,1,218,152,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,91,124,51,211,9,235,73,230,129,79,76,57,179,252,147,61,46,222,55,49,156,35,181,181,217,140,199,194,135,126,239,251,0,160,91,124,51,211,9,235,73,230,129,79,76,57,179,252,147,61,46,222,55,49,156,35,181,181,217,140,199,194,135,126,239,251,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,198,173,47,15,24,247,123,29,143,238,210,5,76,44,0,7,148,217,241,207,46,233,29,69,86,104,40,186,220,153,45,109,0,160,198,173,47,15,24,247,123,29,143,238,210,5,76,44,0,7,148,217,241,207,46,233,29,69,86,104,40,186,220,153,45,109,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,11,161,79,203,76,0,94,197,247,21,34,15,237,251,186,101,156,155,254,196,0,173,231,220,178,64,214,23,193,146,249,233,0,160,11,161,79,203,76,0,94,197,247,21,34,15,237,251,186,101,156,155,254,196,0,173,231,220,178,64,214,23,193,146,249,233,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,94,170,238,196,129,29,127,164,98,174,87,50,178,177,9,46,2,110,163,58,47,215,198,105,189,243,131,59,129,53,180,89,0,160,94,170,238,196,129,29,127,164,98,174,87,50,178,177,9,46,2,110,163,58,47,215,198,105,189,243,131,59,129,53,180,89,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,100,67,185,240,66,4,48,205,115,127,26,88,222,95,211,125,147,9,222,53,50,52,5,236,92,121,225,7,231,129,183,118,0,160,100,67,185,240,66,4,48,205,115,127,26,88,222,95,211,125,147,9,222,53,50,52,5,236,92,121,225,7,231,129,183,118,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,98,103,206,41,116,82,141,170,215,102,145,113,216,126,189,19,11,241,144,204,193,255,163,78,123,38,167,60,204,134,150,138,0,160,98,103,206,41,116,82,141,170,215,102,145,113,216,126,189,19,11,241,144,204,193,255,163,78,123,38,167,60,204,134,150,138,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,14,57,61,55,77,138,237,254,201,136,74,118,169,27,32,212,0,81,198,68,17,205,32,97,149,86,102,107,103,216,158,108,0,160,14,57,61,55,77,138,237,254,201,136,74,118,169,27,32,212,0,81,198,68,17,205,32,97,149,86,102,107,103,216,158,108,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,151,89,46,200,117,181,97,231,220,224,98,192,154,217,203,140,50,96,138,63,225,123,181,80,33,237,168,148,72,146,50,208,0,160,151,89,46,200,117,181,97,231,220,224,98,192,154,217,203,140,50,96,138,63,225,123,181,80,33,237,168,148,72,146,50,208,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,70,252,166,157,14,188,140,228,37,115,14,85,160,172,150,194,35,108,206,222,246,77,148,119,39,187,37,14,249,50,33,252,0,160,70,252,166,157,14,188,140,228,37,115,14,85,160,172,150,194,35,108,206,222,246,77,148,119,39,187,37,14,249,50,33,252,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,162,242,182,77,88,97,208,25,129,240,64,131,25,157,85,189,101,121,176,49,54,69,9,103,38,30,211,249,183,129,23,209,0,160,162,242,182,77,88,97,208,25,129,240,64,131,25,157,85,189,101,121,176,49,54,69,9,103,38,30,211,249,183,129,23,209,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,189,254,23,52,6,11,216,25,233,79,162,217,173,14,166,14,30,113,114,183,249,21,18,130,138,13,247,166,235,118,154,23,0,160,189,254,23,52,6,11,216,25,233,79,162,217,173,14,166,14,30,113,114,183,249,21,18,130,138,13,247,166,235,118,154,23,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,8,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,80,148,255,185,38,251,16,216,144,46,115,25,219,9,156,208,216,2,63,88,215,254,38,196,107,216,121,200,104,112,41,166,0,160,80,148,255,185,38,251,16,216,144,46,115,25,219,9,156,208,216,2,63,88,215,254,38,196,107,216,121,200,104,112,41,166,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,232,64,114,15,200,106,11,109,160,11,185,172,141,121,247,148,195,206,231,233,199,129,249,71,91,217,235,116,232,212,187,23,0,160,232,64,114,15,200,106,11,109,160,11,185,172,141,121,247,148,195,206,231,233,199,129,249,71,91,217,235,116,232,212,187,23,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,22,24,113,187,195,199,19,22,220,222,38,68,10,149,249,10,83,196,145,149,30,216,79,55,240,137,14,190,167,183,11,248,0,160,22,24,113,187,195,199,19,22,220,222,38,68,10,149,249,10,83,196,145,149,30,216,79,55,240,137,14,190,167,183,11,248,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,26,80,98,123,95,183,78,86,169,116,95,134,0,242,193,10,159,55,133,145,50,232,89,49,77,88,236,254,190,119,46,179,0,160,26,80,98,123,95,183,78,86,169,116,95,134,0,242,193,10,159,55,133,145,50,232,89,49,77,88,236,254,190,119,46,179,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,219,11,189,199,146,209,207,184,241,225,225,82,254,168,36,177,54,129,136,43,174,3,69,132,76,68,238,217,185,64,76,188,0,160,219,11,189,199,146,209,207,184,241,225,225,82,254,168,36,177,54,129,136,43,174,3,69,132,76,68,238,217,185,64,76,188,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,255,255,49,52,51,148,215,160,44,11,164,35,64,77,116,244,205,109,34,105,83,191,185,98,61,152,31,107,47,93,226,182,0,160,255,255,49,52,51,148,215,160,44,11,164,35,64,77,116,244,205,109,34,105,83,191,185,98,61,152,31,107,47,93,226,182,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,141,207,26,39,186,93,5,76,248,240,96,160,123,14,221,226,176,218,191,61,55,177,128,23,185,89,251,26,120,1,137,73,0,160,141,207,26,39,186,93,5,76,248,240,96,160,123,14,221,226,176,218,191,61,55,177,128,23,185,89,251,26,120,1,137,73,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,35,20,61,139,93,25,155,182,10,41,79,55,103,14,165,89,100,101,112,251,202,56,255,204,172,35,165,18,191,59,191,42,0,160,35,20,61,139,93,25,155,182,10,41,79,55,103,14,165,89,100,101,112,251,202,56,255,204,172,35,165,18,191,59,191,42,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,143,224,89,30,184,196,153,96,132,8,72,89,237,23,38,198,197,52,213,48,160,163,90,143,21,246,48,48,243,27,57,233,0,160,143,224,89,30,184,196,153,96,132,8,72,89,237,23,38,198,197,52,213,48,160,163,90,143,21,246,48,48,243,27,57,233,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,161,117,24,172,49,150,116,109,36,187,48,213,144,170,125,36,153,110,226,55,47,140,26,254,184,244,194,140,147,47,42,231,0,160,161,117,24,172,49,150,116,109,36,187,48,213,144,170,125,36,153,110,226,55,47,140,26,254,184,244,194,140,147,47,42,231,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,80,215,25,106,21,12,101,148,138,219,184,184,188,40,58,115,84,38,142,85,198,23,126,169,205,238,223,41,50,89,224,22,0,160,80,215,25,106,21,12,101,148,138,219,184,184,188,40,58,115,84,38,142,85,198,23,126,169,205,238,223,41,50,89,224,22,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,117,137,133,54,28,123,80,12,122,22,182,143,154,153,195,240,131,11,204,239,47,187,92,198,160,194,159,23,63,110,69,23,0,160,117,137,133,54,28,123,80,12,122,22,182,143,154,153,195,240,131,11,204,239,47,187,92,198,160,194,159,23,63,110,69,23,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,192,126,139,172,39,190,85,65,175,44,222,171,235,106,94,226,10,102,215,144,5,84,241,252,249,77,74,39,235,161,155,27,0,160,192,126,139,172,39,190,85,65,175,44,222,171,235,106,94,226,10,102,215,144,5,84,241,252,249,77,74,39,235,161,155,27,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,196,6,129,141,159,153,225,109,54,205,224,250,103,31,169,248,190,191,252,11,209,179,82,134,242,212,102,162,34,226,61,112,0,160,196,6,129,141,159,153,225,109,54,205,224,250,103,31,169,248,190,191,252,11,209,179,82,134,242,212,102,162,34,226,61,112,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,194,89,55,164,148,35,149,201,62,178,116,127,182,51,153,157,6,43,147,76,67,31,130,227,50,40,178,162,17,107,171,35,0,160,194,89,55,164,148,35,149,201,62,178,116,127,182,51,153,157,6,43,147,76,67,31,130,227,50,40,178,162,17,107,171,35,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,117,214,70,75,202,75,148,198,51,170,204,17,106,206,189,79,195,252,21,147,184,128,92,162,208,14,202,231,35,190,240,162,0,160,117,214,70,75,202,75,148,198,51,170,204,17,106,206,189,79,195,252,21,147,184,128,92,162,208,14,202,231,35,190,240,162,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,14,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,50,134,227,121,222,107,41,253,160,126,236,53,159,171,4,233,12,192,130,29,187,146,42,103,75,238,149,5,228,164,51,219,0,160,50,134,227,121,222,107,41,253,160,126,236,53,159,171,4,233,12,192,130,29,187,146,42,103,75,238,149,5,228,164,51,219,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,109,223,240,132,44,244,231,89,34,238,116,54,182,126,145,33,158,218,129,84,25,117,193,93,57,54,129,207,71,158,10,239,0,160,109,223,240,132,44,244,231,89,34,238,116,54,182,126,145,33,158,218,129,84,25,117,193,93,57,54,129,207,71,158,10,239,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,137,71,32,30,231,144,195,14,161,165,205,202,106,148,96,107,179,11,204,136,166,237,106,5,140,223,195,49,2,38,252,37,0,160,137,71,32,30,231,144,195,14,161,165,205,202,106,148,96,107,179,11,204,136,166,237,106,5,140,223,195,49,2,38,252,37,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,10,16,12,178,172,155,142,38,79,250,185,38,8,229,41,242,146,125,222,231,178,85,169,113,65,235,192,3,221,253,133,121,0,160,10,16,12,178,172,155,142,38,79,250,185,38,8,229,41,242,146,125,222,231,178,85,169,113,65,235,192,3,221,253,133,121,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,118,155,214,194,160,124,204,154,165,83,205,21,77,129,218,30,159,182,4,232,144,206,128,190,236,186,178,127,98,184,35,118,0,160,118,155,214,194,160,124,204,154,165,83,205,21,77,129,218,30,159,182,4,232,144,206,128,190,236,186,178,127,98,184,35,118,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,242,87,113,63,110,51,159,220,10,125,93,196,79,30,80,58,128,111,185,193,117,25,116,202,155,203,154,233,77,106,251,95,0,160,242,87,113,63,110,51,159,220,10,125,93,196,79,30,80,58,128,111,185,193,117,25,116,202,155,203,154,233,77,106,251,95,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,179,216,217,227,32,241,45,244,75,203,37,4,51,184,112,104,40,154,140,239,221,64,49,88,53,119,11,221,100,30,115,147,0,160,179,216,217,227,32,241,45,244,75,203,37,4,51,184,112,104,40,154,140,239,221,64,49,88,53,119,11,221,100,30,115,147,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,123,86,224,58,55,134,195,209,93,93,167,112,126,144,159,207,30,2,157,97,66,237,247,243,246,61,16,108,150,69,42,216,0,160,123,86,224,58,55,134,195,209,93,93,167,112,126,144,159,207,30,2,157,97,66,237,247,243,246,61,16,108,150,69,42,216,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,198,153,173,222,150,149,89,189,206,216,72,55,211,25,7,209,20,124,201,116,255,43,245,33,132,248,22,100,146,228,180,33,0,160,198,153,173,222,150,149,89,189,206,216,72,55,211,25,7,209,20,124,201,116,255,43,245,33,132,248,22,100,146,228,180,33,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,18,207,94,155,112,54,113,255,83,129,204,156,94,155,128,87,24,190,90,35,118,51,118,49,201,101,169,161,53,195,204,212,0,160,18,207,94,155,112,54,113,255,83,129,204,156,94,155,128,87,24,190,90,35,118,51,118,49,201,101,169,161,53,195,204,212,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,38,148,237,87,162,36,238,225,7,186,236,165,131,196,134,87,58,128,154,30,76,224,193,106,231,54,167,127,2,63,242,235,0,160,38,148,237,87,162,36,238,225,7,186,236,165,131,196,134,87,58,128,154,30,76,224,193,106,231,54,167,127,2,63,242,235,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,65,15,250,185,115,180,192,8,106,46,90,186,76,63,247,99,101,120,4,178,131,76,104,150,74,77,30,88,24,180,2,165,0,160,65,15,250,185,115,180,192,8,106,46,90,186,76,63,247,99,101,120,4,178,131,76,104,150,74,77,30,88,24,180,2,165,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,27,195,248,41,48,169,202,25,179,195,80,92,28,41,117,203,45,106,247,70,163,164,155,57,204,247,48,8,150,255,69,103,0,160,27,195,248,41,48,169,202,25,179,195,80,92,28,41,117,203,45,106,247,70,163,164,155,57,204,247,48,8,150,255,69,103,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,77,29,23,199,242,162,32,107,153,219,31,93,210,56,39,34,133,30,238,106,236,197,206,47,158,52,226,240,22,66,24,152,0,160,77,29,23,199,242,162,32,107,153,219,31,93,210,56,39,34,133,30,238,106,236,197,206,47,158,52,226,240,22,66,24,152,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,128,210,64,36,232,87,25,151,157,53,5,163,236,235,238,238,244,222,96,49,29,31,13,153,104,5,231,22,7,200,223,157,0,160,128,210,64,36,232,87,25,151,157,53,5,163,236,235,238,238,244,222,96,49,29,31,13,153,104,5,231,22,7,200,223,157,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,254,142,169,167,195,251,188,33,233,78,222,45,23,253,255,129,174,132,231,175,11,153,146,70,137,247,100,109,26,106,12,199,0,160,254,142,169,167,195,251,188,33,233,78,222,45,23,253,255,129,174,132,231,175,11,153,146,70,137,247,100,109,26,106,12,199,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,51,241,12,122,223,81,152,154,37,130,73,169,73,174,190,217,162,228,6,125,211,205,215,202,77,228,212,82,225,163,237,192,0,160,51,241,12,122,223,81,152,154,37,130,73,169,73,174,190,217,162,228,6,125,211,205,215,202,77,228,212,82,225,163,237,192,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,108,57,248,46,203,51,108,5,211,233,36,199,112,197,41,226,231,139,145,164,37,226,96,51,179,184,38,179,18,214,14,227,0,160,108,57,248,46,203,51,108,5,211,233,36,199,112,197,41,226,231,139,145,164,37,226,96,51,179,184,38,179,18,214,14,227,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,216,159,123,174,245,114,217,222,163,30,130,28,130,112,42,41,60,19,247,247,77,30,167,48,212,24,142,109,140,167,139,82,0,160,216,159,123,174,245,114,217,222,163,30,130,28,130,112,42,41,60,19,247,247,77,30,167,48,212,24,142,109,140,167,139,82,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,22,24,108,63,110,11,171,135,168,27,40,62,80,124,232,38,247,70,47,131,50,237,27,177,116,224,97,0,220,105,0,207,0,160,22,24,108,63,110,11,171,135,168,27,40,62,80,124,232,38,247,70,47,131,50,237,27,177,116,224,97,0,220,105,0,207,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,27,32,153,65,20,139,14,102,94,202,123,191,220,51,10,53,15,90,91,208,231,17,74,83,74,152,198,129,106,142,107,134,0,160,27,32,153,65,20,139,14,102,94,202,123,191,220,51,10,53,15,90,91,208,231,17,74,83,74,152,198,129,106,142,107,134,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,16,34,203,96,5,245,23,207,43,83,207,130,98,43,103,126,11,36,249,214,34,87,112,151,109,81,5,82,255,10,70,82,0,160,16,34,203,96,5,245,23,207,43,83,207,130,98,43,103,126,11,36,249,214,34,87,112,151,109,81,5,82,255,10,70,82,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,132,190,217,18,224,217,151,188,25,206,221,116,137,199,19,252,252,99,167,60,24,250,47,2,99,252,223,58,210,71,103,12,0,160,132,190,217,18,224,217,151,188,25,206,221,116,137,199,19,252,252,99,167,60,24,250,47,2,99,252,223,58,210,71,103,12,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,135,48,207,246,58,141,50,138,56,71,148,180,41,114,250,70,187,44,46,24,129,201,137,5,131,252,164,150,132,206,7,211,0,160,135,48,207,246,58,141,50,138,56,71,148,180,41,114,250,70,187,44,46,24,129,201,137,5,131,252,164,150,132,206,7,211,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,7,209,151,13,253,160,217,6,204,0,47,210,144,219,252,152,90,3,87,48,29,26,178,0,169,194,214,154,68,243,197,216,0,160,7,209,151,13,253,160,217,6,204,0,47,210,144,219,252,152,90,3,87,48,29,26,178,0,169,194,214,154,68,243,197,216,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,168,128,138,221,38,113,12,138,148,57,231,108,100,18,221,11,59,37,117,212,20,18,79,176,177,24,166,101,83,116,36,59,0,160,168,128,138,221,38,113,12,138,148,57,231,108,100,18,221,11,59,37,117,212,20,18,79,176,177,24,166,101,83,116,36,59,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,144,107,197,69,239,225,195,211,211,21,4,18,41,56,121,142,55,91,224,216,214,151,57,52,247,120,231,250,1,211,193,23,0,160,144,107,197,69,239,225,195,211,211,21,4,18,41,56,121,142,55,91,224,216,214,151,57,52,247,120,231,250,1,211,193,23,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,252,108,69,245,6,88,254,119,86,9,126,110,214,65,71,203,229,188,14,60,46,204,216,105,26,210,18,15,27,254,12,175,0,160,252,108,69,245,6,88,254,119,86,9,126,110,214,65,71,203,229,188,14,60,46,204,216,105,26,210,18,15,27,254,12,175,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,56,164,46,14,139,85,27,222,5,117,226,241,232,26,221,205,195,150,196,115,106,141,181,231,173,150,150,86,230,174,230,118,0,160,56,164,46,14,139,85,27,222,5,117,226,241,232,26,221,205,195,150,196,115,106,141,181,231,173,150,150,86,230,174,230,118,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,96,9,107,203,131,222,63,178,190,68,100,198,163,179,53,14,232,10,145,138,227,125,133,153,241,162,90,61,106,174,48,209,0,160,96,9,107,203,131,222,63,178,190,68,100,198,163,179,53,14,232,10,145,138,227,125,133,153,241,162,90,61,106,174,48,209,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,162,80,140,238,232,172,104,178,189,11,3,53,206,103,224,50,105,110,53,97,36,158,83,102,72,24,88,21,28,158,125,203,0,160,162,80,140,238,232,172,104,178,189,11,3,53,206,103,224,50,105,110,53,97,36,158,83,102,72,24,88,21,28,158,125,203,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,230,193,57,145,215,135,56,63,27,141,34,161,66,40,124,150,99,218,110,125,26,203,193,93,106,20,228,191,226,53,27,240,0,160,230,193,57,145,215,135,56,63,27,141,34,161,66,40,124,150,99,218,110,125,26,203,193,93,106,20,228,191,226,53,27,240,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,2,17,249,2,17,11,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,33,39,1,20,248,247,235,8,83,14,6,51,208,30,213,108,102,237,221,215,232,228,70,187,27,78,176,0,8,163,95,170,0,160,33,39,1,20,248,247,235,8,83,14,6,51,208,30,213,108,102,237,221,215,232,228,70,187,27,78,176,0,8,163,95,170,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,170,99,98,103,42,49,51,254,9,177,205,247,241,15,60,230,117,203,102,101,101,117,218,172,171,136,197,129,129,130,31,135,0,160,170,99,98,103,42,49,51,254,9,177,205,247,241,15,60,230,117,203,102,101,101,117,218,172,171,136,197,129,129,130,31,135,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,117,64,244,64,112,120,157,17,156,151,58,2,245,143,63,101,157,15,87,248,32,196,84,75,122,84,59,46,48,185,191,98,0,160,117,64,244,64,112,120,157,17,156,151,58,2,245,143,63,101,157,15,87,248,32,196,84,75,122,84,59,46,48,185,191,98,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,152,57,96,242,252,200,111,209,46,155,238,44,25,164,134,150,12,61,86,57,75,184,111,192,204,68,72,77,18,170,16,245,0,160,152,57,96,242,252,200,111,209,46,155,238,44,25,164,134,150,12,61,86,57,75,184,111,192,204,68,72,77,18,170,16,245,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,122,244,234,173,129,12,158,231,23,76,102,97,134,68,156,85,77,238,116,20,225,160,149,10,98,208,198,250,39,121,27,120,0,160,122,244,234,173,129,12,158,231,23,76,102,97,134,68,156,85,77,238,116,20,225,160,149,10,98,208,198,250,39,121,27,120,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,196,241,34,116,90,96,56,131,49,177,20,26,140,119,178,238,103,214,185,234,93,9,46,201,69,146,50,75,219,126,18,104,0,160,196,241,34,116,90,96,56,131,49,177,20,26,140,119,178,238,103,214,185,234,93,9,46,201,69,146,50,75,219,126,18,104,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,47,54,175,158,157,10,125,127,125,79,46,159,240,21,120,207,129,232,177,59,69,144,48,48,133,172,168,167,82,56,85,246,0,160,47,54,175,158,157,10,125,127,125,79,46,159,240,21,120,207,129,232,177,59,69,144,48,48,133,172,168,167,82,56,85,246,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,234,182,79,195,232,90,25,45,147,29,63,169,129,218,194,0,227,65,134,220,75,104,160,206,99,71,160,250,166,59,33,254,0,160,234,182,79,195,232,90,25,45,147,29,63,169,129,218,194,0,227,65,134,220,75,104,160,206,99,71,160,250,166,59,33,254,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,30,163,206,180,138,61,188,189,238,35,29,37,221,22,221,228,190,56,109,233,40,189,149,208,125,22,132,212,243,222,162,48,0,160,30,163,206,180,138,61,188,189,238,35,29,37,221,22,221,228,190,56,109,233,40,189,149,208,125,22,132,212,243,222,162,48,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,168,86,17,145,160,253,175,87,189,242,36,138,180,171,181,57,203,52,179,52,152,169,215,250,29,11,216,22,173,124,244,48,0,160,168,86,17,145,160,253,175,87,189,242,36,138,180,171,181,57,203,52,179,52,152,169,215,250,29,11,216,22,173,124,244,48,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,160,23,89,94,237,247,112,172,230,48,73,35,139,102,199,84,73,192,236,59,221,22,192,197,215,139,186,217,1,41,82,148,0,160,160,23,89,94,237,247,112,172,230,48,73,35,139,102,199,84,73,192,236,59,221,22,192,197,215,139,186,217,1,41,82,148,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,152,114,105,120,10,10,91,38,126,46,99,128,203,158,68,32,150,137,142,142,220,103,7,68,247,231,125,68,50,69,173,31,0,160,152,114,105,120,10,10,91,38,126,46,99,128,203,158,68,32,150,137,142,142,220,103,7,68,247,231,125,68,50,69,173,31,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,232,192,193,129,55,246,219,2,21,95,185,215,91,77,57,159,231,197,191,216,110,12,90,42,102,228,47,143,187,182,239,195,0,160,232,192,193,129,55,246,219,2,21,95,185,215,91,77,57,159,231,197,191,216,110,12,90,42,102,228,47,143,187,182,239,195,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,221,159,32,235,93,231,122,178,230,101,161,192,173,79,175,184,59,126,75,86,134,254,172,15,3,234,37,200,238,16,226,190,0,160,221,159,32,235,93,231,122,178,230,101,161,192,173,79,175,184,59,126,75,86,134,254,172,15,3,234,37,200,238,16,226,190,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,38,143,194,58,172,99,153,99,15,216,34,169,236,44,42,7,158,105,155,130,175,192,127,236,79,21,193,223,173,150,50,180,0,160,38,143,194,58,172,99,153,99,15,216,34,169,236,44,42,7,158,105,155,130,175,192,127,236,79,21,193,223,173,150,50,180,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,2,127,2,197,234,36,175,155,248,175,204,19,60,74,97,151,82,20,50,241,248,141,215,153,181,193,58,87,151,184,73,254,0,160,2,127,2,197,234,36,175,155,248,175,204,19,60,74,97,151,82,20,50,241,248,141,215,153,181,193,58,87,151,184,73,254,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[0,1,0,1,249,1,49,249,1,49,13,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,160,119,73,17,92,128,20,103,104,232,32,124,19,16,87,60,164,208,90,161,44,211,37,10,22,234,211,119,99,38,103,198,198,0,160,119,73,17,92,128,20,103,104,232,32,124,19,16,87,60,164,208,90,161,44,211,37,10,22,234,211,119,99,38,103,198,198,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,197,2,59,23,137,170,248,2,213,118,95,76,155,251,48,153,90,243,215,96,187,113,77,106,134,162,144,12,225,177,150,82,0,160,197,2,59,23,137,170,248,2,213,118,95,76,155,251,48,153,90,243,215,96,187,113,77,106,134,162,144,12,225,177,150,82,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,163,49,39,187,25,224,238,70,65,179,76,107,218,25,133,29,45,119,79,102,88,247,235,233,62,172,199,17,252,137,160,132,0,160,163,49,39,187,25,224,238,70,65,179,76,107,218,25,133,29,45,119,79,102,88,247,235,233,62,172,199,17,252,137,160,132,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,228,247,244,44,169,159,121,241,37,203,87,229,189,5,235,105,253,45,60,197,77,122,58,147,64,9,131,17,17,142,20,155,0,160,228,247,244,44,169,159,121,241,37,203,87,229,189,5,235,105,253,45,60,197,77,122,58,147,64,9,131,17,17,142,20,155,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,205,29,5,65,38,9,46,153,141,104,202,181,91,192,0,13,172,218,7,199,83,1,165,46,186,0,114,232,249,237,55,86,0,160,205,29,5,65,38,9,46,153,141,104,202,181,91,192,0,13,172,218,7,199,83,1,165,46,186,0,114,232,249,237,55,86,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,95,199,183,163,77,23,5,95,41,107,232,12,194,66,48,248,191,156,189,227,198,181,71,183,94,67,71,52,31,231,186,220,0,160,95,199,183,163,77,23,5,95,41,107,232,12,194,66,48,248,191,156,189,227,198,181,71,183,94,67,71,52,31,231,186,220,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,72,154,12,74,44,172,232,136,12,112,213,212,84,199,60,155,180,189,250,131,119,235,245,179,231,69,41,210,95,2,102,69,0,160,72,154,12,74,44,172,232,136,12,112,213,212,84,199,60,155,180,189,250,131,119,235,245,179,231,69,41,210,95,2,102,69,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,185,48,236,239,154,158,161,183,121,156,86,53,176,75,170,145,108,209,199,136,127,25,169,15,172,38,79,212,229,151,21,78,0,160,185,48,236,239,154,158,161,183,121,156,86,53,176,75,170,145,108,209,199,136,127,25,169,15,172,38,79,212,229,151,21,78,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,168,42,10,43,57,84,192,82,188,77,84,115,130,173,36,32,174,129,104,109,48,102,57,116,53,12,2,1,10,219,36,135,0,160,168,42,10,43,57,84,192,82,188,77,84,115,130,173,36,32,174,129,104,109,48,102,57,116,53,12,2,1,10,219,36,135,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[248,102,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,6],[248,102,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,4],[0,0,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,18],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,7],[184,70,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,68,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,8],[0,160,108,175,176,92,138,97,66,88,92,163,20,133,186,14,202,83,61,132,245,179,24,124,92,74,69,199,166,219,149,87,245,197,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,9],[0,160,108,175,176,92,138,97,66,88,92,163,20,133,186,14,202,83,61,132,245,179,24,124,92,74,69,199,166,219,149,87,245,197,0,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,11],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,10],[1,0,1,0,248,81,0,248,81,0,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,147,31,200,131,19,49,103,136,46,1,167,47,128,146,235,40,179,181,1,99,210,43,90,113,42,63,194,216,20,174,42,218,0,160,147,31,200,131,19,49,103,136,46,1,167,47,128,146,235,40,179,181,1,99,210,43,90,113,42,63,194,216,20,174,42,218,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,160,204,123,237,30,197,175,26,208,74,15,150,211,15,238,169,175,151,34,192,58,177,202,8,45,196,255,144,212,1,208,149,21,0,160,204,123,237,30,197,175,26,208,74,15,150,211,15,238,169,175,151,34,192,58,177,202,8,45,196,255,144,212,1,208,149,21,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,17],[226,160,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,2],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,13],[226,160,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,3],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,14],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,15],[0,160,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,51,249,190,25,92,195,96,144,163,223,3,204,51,198,92,180,19,6,89,244,90,113,203,1,243,202,105,41,218,208,136,76,55,142,59,217,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,19],[249,2,17,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,160,81,161,102,91,160,19,144,108,131,101,101,23,128,254,23,127,21,66,253,142,104,3,221,12,246,12,75,151,83,165,8,247,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,128,5],[249,2,17,160,215,178,43,142,72,221,147,48,230,157,99,126,109,240,144,184,54,167,1,19,157,71,126,226,97,100,220,221,118,5,202,114,160,195,19,38,251,242,179,135,46,118,82,177,213,78,156,167,171,134,95,6,233,153,168,219,176,131,34,215,213,95,252,168,165,160,242,119,75,182,209,50,158,172,168,239,218,202,172,144,155,94,44,154,149,92,253,83,150,12,4,176,33,46,25,36,170,225,160,81,161,102,91,160,19,144,108,131,101,101,23,128,254,23,127,21,66,253,142,104,3,221,12,246,12,75,151,83,165,8,247,160,100,75,99,34,122,170,85,172,143,62,172,142,154,219,40,105,162,136,113,194,41,38,129,211,105,114,94,62,145,244,97,170,160,229,94,177,9,226,34,180,156,33,249,119,163,74,194,218,172,92,90,13,44,22,231,5,100,72,203,19,192,62,46,34,34,160,15,175,179,52,244,84,197,105,112,43,252,115,186,76,237,251,88,5,62,201,157,9,7,153,100,224,202,249,250,183,125,248,160,14,229,239,45,75,116,39,109,41,89,200,43,18,94,204,133,62,175,23,200,68,93,170,95,36,226,233,183,66,98,37,184,160,6,197,49,201,57,39,248,81,26,196,11,167,230,243,100,223,97,38,20,1,226,39,180,161,172,204,67,80,173,223,89,42,160,3,131,195,206,124,22,207,14,142,91,216,135,77,202,69,1,53,115,223,85,52,95,43,227,237,82,138,95,93,70,227,232,160,98,109,64,32,201,140,205,221,164,1,209,57,84,209,249,108,87,101,70,12,37,160,114,139,27,145,104,130,62,183,150,108,160,69,221,169,92,165,83,34,53,123,93,55,127,206,167,112,175,13,233,196,118,68,137,156,246,219,49,159,137,25,37,30,157,160,39,24,29,240,236,191,237,195,74,255,251,61,19,232,218,181,111,83,69,125,70,208,135,182,81,0,125,85,38,21,25,11,160,191,249,76,252,217,172,58,95,133,138,144,243,9,87,191,253,23,150,215,186,153,214,27,17,128,10,154,202,202,43,193,173,160,238,147,22,82,116,71,41,238,84,0,62,40,0,153,205,90,194,234,61,255,205,197,55,0,41,239,197,174,219,163,6,130,160,22,99,129,222,131,163,115,40,32,94,210,97,181,141,77,173,9,184,214,164,50,44,139,113,241,255,7,213,43,8,145,41,128,5],[249,2,17,160,32,114,50,12,62,189,106,20,134,185,146,28,23,254,217,42,238,29,2,23,26,44,204,98,23,49,136,43,60,200,131,203,160,10,122,174,89,193,94,170,119,181,105,68,128,225,99,30,47,203,11,219,63,185,212,28,135,191,38,229,164,205,251,29,178,160,196,56,120,16,50,206,164,153,42,137,240,168,48,191,84,89,147,194,236,15,27,79,106,86,147,188,114,238,224,245,134,237,160,110,98,248,22,245,45,207,250,31,51,65,156,160,157,187,161,111,44,138,199,254,61,51,142,225,57,123,216,229,126,111,230,160,43,111,2,145,226,86,104,84,88,106,96,162,207,2,192,64,233,219,19,142,115,84,245,190,9,221,204,102,175,1,218,152,160,91,124,51,211,9,235,73,230,129,79,76,57,179,252,147,61,46,222,55,49,156,35,181,181,217,140,199,194,135,126,239,251,160,198,173,47,15,24,247,123,29,143,238,210,5,76,44,0,7,148,217,241,207,46,233,29,69,86,104,40,186,220,153,45,109,160,11,161,79,203,76,0,94,197,247,21,34,15,237,251,186,101,156,155,254,196,0,173,231,220,178,64,214,23,193,146,249,233,160,94,170,238,196,129,29,127,164,98,174,87,50,178,177,9,46,2,110,163,58,47,215,198,105,189,243,131,59,129,53,180,89,160,100,67,185,240,66,4,48,205,115,127,26,88,222,95,211,125,147,9,222,53,50,52,5,236,92,121,225,7,231,129,183,118,160,98,103,206,41,116,82,141,170,215,102,145,113,216,126,189,19,11,241,144,204,193,255,163,78,123,38,167,60,204,134,150,138,160,14,57,61,55,77,138,237,254,201,136,74,118,169,27,32,212,0,81,198,68,17,205,32,97,149,86,102,107,103,216,158,108,160,151,89,46,200,117,181,97,231,220,224,98,192,154,217,203,140,50,96,138,63,225,123,181,80,33,237,168,148,72,146,50,208,160,70,252,166,157,14,188,140,228,37,115,14,85,160,172,150,194,35,108,206,222,246,77,148,119,39,187,37,14,249,50,33,252,160,162,242,182,77,88,97,208,25,129,240,64,131,25,157,85,189,101,121,176,49,54,69,9,103,38,30,211,249,183,129,23,209,160,189,254,23,52,6,11,216,25,233,79,162,217,173,14,166,14,30,113,114,183,249,21,18,130,138,13,247,166,235,118,154,23,128,5],[249,2,17,160,32,114,50,12,62,189,106,20,134,185,146,28,23,254,217,42,238,29,2,23,26,44,204,98,23,49,136,43,60,200,131,203,160,10,122,174,89,193,94,170,119,181,105,68,128,225,99,30,47,203,11,219,63,185,212,28,135,191,38,229,164,205,251,29,178,160,196,56,120,16,50,206,164,153,42,137,240,168,48,191,84,89,147,194,236,15,27,79,106,86,147,188,114,238,224,245,134,237,160,110,98,248,22,245,45,207,250,31,51,65,156,160,157,187,161,111,44,138,199,254,61,51,142,225,57,123,216,229,126,111,230,160,43,111,2,145,226,86,104,84,88,106,96,162,207,2,192,64,233,219,19,142,115,84,245,190,9,221,204,102,175,1,218,152,160,91,124,51,211,9,235,73,230,129,79,76,57,179,252,147,61,46,222,55,49,156,35,181,181,217,140,199,194,135,126,239,251,160,198,173,47,15,24,247,123,29,143,238,210,5,76,44,0,7,148,217,241,207,46,233,29,69,86,104,40,186,220,153,45,109,160,11,161,79,203,76,0,94,197,247,21,34,15,237,251,186,101,156,155,254,196,0,173,231,220,178,64,214,23,193,146,249,233,160,94,170,238,196,129,29,127,164,98,174,87,50,178,177,9,46,2,110,163,58,47,215,198,105,189,243,131,59,129,53,180,89,160,100,67,185,240,66,4,48,205,115,127,26,88,222,95,211,125,147,9,222,53,50,52,5,236,92,121,225,7,231,129,183,118,160,98,103,206,41,116,82,141,170,215,102,145,113,216,126,189,19,11,241,144,204,193,255,163,78,123,38,167,60,204,134,150,138,160,14,57,61,55,77,138,237,254,201,136,74,118,169,27,32,212,0,81,198,68,17,205,32,97,149,86,102,107,103,216,158,108,160,151,89,46,200,117,181,97,231,220,224,98,192,154,217,203,140,50,96,138,63,225,123,181,80,33,237,168,148,72,146,50,208,160,70,252,166,157,14,188,140,228,37,115,14,85,160,172,150,194,35,108,206,222,246,77,148,119,39,187,37,14,249,50,33,252,160,162,242,182,77,88,97,208,25,129,240,64,131,25,157,85,189,101,121,176,49,54,69,9,103,38,30,211,249,183,129,23,209,160,189,254,23,52,6,11,216,25,233,79,162,217,173,14,166,14,30,113,114,183,249,21,18,130,138,13,247,166,235,118,154,23,128,5],[249,2,17,160,80,148,255,185,38,251,16,216,144,46,115,25,219,9,156,208,216,2,63,88,215,254,38,196,107,216,121,200,104,112,41,166,160,232,64,114,15,200,106,11,109,160,11,185,172,141,121,247,148,195,206,231,233,199,129,249,71,91,217,235,116,232,212,187,23,160,22,24,113,187,195,199,19,22,220,222,38,68,10,149,249,10,83,196,145,149,30,216,79,55,240,137,14,190,167,183,11,248,160,26,80,98,123,95,183,78,86,169,116,95,134,0,242,193,10,159,55,133,145,50,232,89,49,77,88,236,254,190,119,46,179,160,219,11,189,199,146,209,207,184,241,225,225,82,254,168,36,177,54,129,136,43,174,3,69,132,76,68,238,217,185,64,76,188,160,255,255,49,52,51,148,215,160,44,11,164,35,64,77,116,244,205,109,34,105,83,191,185,98,61,152,31,107,47,93,226,182,160,141,207,26,39,186,93,5,76,248,240,96,160,123,14,221,226,176,218,191,61,55,177,128,23,185,89,251,26,120,1,137,73,160,35,20,61,139,93,25,155,182,10,41,79,55,103,14,165,89,100,101,112,251,202,56,255,204,172,35,165,18,191,59,191,42,160,143,224,89,30,184,196,153,96,132,8,72,89,237,23,38,198,197,52,213,48,160,163,90,143,21,246,48,48,243,27,57,233,160,161,117,24,172,49,150,116,109,36,187,48,213,144,170,125,36,153,110,226,55,47,140,26,254,184,244,194,140,147,47,42,231,160,80,215,25,106,21,12,101,148,138,219,184,184,188,40,58,115,84,38,142,85,198,23,126,169,205,238,223,41,50,89,224,22,160,117,137,133,54,28,123,80,12,122,22,182,143,154,153,195,240,131,11,204,239,47,187,92,198,160,194,159,23,63,110,69,23,160,192,126,139,172,39,190,85,65,175,44,222,171,235,106,94,226,10,102,215,144,5,84,241,252,249,77,74,39,235,161,155,27,160,196,6,129,141,159,153,225,109,54,205,224,250,103,31,169,248,190,191,252,11,209,179,82,134,242,212,102,162,34,226,61,112,160,194,89,55,164,148,35,149,201,62,178,116,127,182,51,153,157,6,43,147,76,67,31,130,227,50,40,178,162,17,107,171,35,160,117,214,70,75,202,75,148,198,51,170,204,17,106,206,189,79,195,252,21,147,184,128,92,162,208,14,202,231,35,190,240,162,128,5],[249,2,17,160,80,148,255,185,38,251,16,216,144,46,115,25,219,9,156,208,216,2,63,88,215,254,38,196,107,216,121,200,104,112,41,166,160,232,64,114,15,200,106,11,109,160,11,185,172,141,121,247,148,195,206,231,233,199,129,249,71,91,217,235,116,232,212,187,23,160,22,24,113,187,195,199,19,22,220,222,38,68,10,149,249,10,83,196,145,149,30,216,79,55,240,137,14,190,167,183,11,248,160,26,80,98,123,95,183,78,86,169,116,95,134,0,242,193,10,159,55,133,145,50,232,89,49,77,88,236,254,190,119,46,179,160,219,11,189,199,146,209,207,184,241,225,225,82,254,168,36,177,54,129,136,43,174,3,69,132,76,68,238,217,185,64,76,188,160,255,255,49,52,51,148,215,160,44,11,164,35,64,77,116,244,205,109,34,105,83,191,185,98,61,152,31,107,47,93,226,182,160,141,207,26,39,186,93,5,76,248,240,96,160,123,14,221,226,176,218,191,61,55,177,128,23,185,89,251,26,120,1,137,73,160,35,20,61,139,93,25,155,182,10,41,79,55,103,14,165,89,100,101,112,251,202,56,255,204,172,35,165,18,191,59,191,42,160,143,224,89,30,184,196,153,96,132,8,72,89,237,23,38,198,197,52,213,48,160,163,90,143,21,246,48,48,243,27,57,233,160,161,117,24,172,49,150,116,109,36,187,48,213,144,170,125,36,153,110,226,55,47,140,26,254,184,244,194,140,147,47,42,231,160,80,215,25,106,21,12,101,148,138,219,184,184,188,40,58,115,84,38,142,85,198,23,126,169,205,238,223,41,50,89,224,22,160,117,137,133,54,28,123,80,12,122,22,182,143,154,153,195,240,131,11,204,239,47,187,92,198,160,194,159,23,63,110,69,23,160,192,126,139,172,39,190,85,65,175,44,222,171,235,106,94,226,10,102,215,144,5,84,241,252,249,77,74,39,235,161,155,27,160,196,6,129,141,159,153,225,109,54,205,224,250,103,31,169,248,190,191,252,11,209,179,82,134,242,212,102,162,34,226,61,112,160,194,89,55,164,148,35,149,201,62,178,116,127,182,51,153,157,6,43,147,76,67,31,130,227,50,40,178,162,17,107,171,35,160,117,214,70,75,202,75,148,198,51,170,204,17,106,206,189,79,195,252,21,147,184,128,92,162,208,14,202,231,35,190,240,162,128,5],[249,2,17,160,50,134,227,121,222,107,41,253,160,126,236,53,159,171,4,233,12,192,130,29,187,146,42,103,75,238,149,5,228,164,51,219,160,109,223,240,132,44,244,231,89,34,238,116,54,182,126,145,33,158,218,129,84,25,117,193,93,57,54,129,207,71,158,10,239,160,137,71,32,30,231,144,195,14,161,165,205,202,106,148,96,107,179,11,204,136,166,237,106,5,140,223,195,49,2,38,252,37,160,10,16,12,178,172,155,142,38,79,250,185,38,8,229,41,242,146,125,222,231,178,85,169,113,65,235,192,3,221,253,133,121,160,118,155,214,194,160,124,204,154,165,83,205,21,77,129,218,30,159,182,4,232,144,206,128,190,236,186,178,127,98,184,35,118,160,242,87,113,63,110,51,159,220,10,125,93,196,79,30,80,58,128,111,185,193,117,25,116,202,155,203,154,233,77,106,251,95,160,179,216,217,227,32,241,45,244,75,203,37,4,51,184,112,104,40,154,140,239,221,64,49,88,53,119,11,221,100,30,115,147,160,123,86,224,58,55,134,195,209,93,93,167,112,126,144,159,207,30,2,157,97,66,237,247,243,246,61,16,108,150,69,42,216,160,198,153,173,222,150,149,89,189,206,216,72,55,211,25,7,209,20,124,201,116,255,43,245,33,132,248,22,100,146,228,180,33,160,18,207,94,155,112,54,113,255,83,129,204,156,94,155,128,87,24,190,90,35,118,51,118,49,201,101,169,161,53,195,204,212,160,38,148,237,87,162,36,238,225,7,186,236,165,131,196,134,87,58,128,154,30,76,224,193,106,231,54,167,127,2,63,242,235,160,65,15,250,185,115,180,192,8,106,46,90,186,76,63,247,99,101,120,4,178,131,76,104,150,74,77,30,88,24,180,2,165,160,27,195,248,41,48,169,202,25,179,195,80,92,28,41,117,203,45,106,247,70,163,164,155,57,204,247,48,8,150,255,69,103,160,77,29,23,199,242,162,32,107,153,219,31,93,210,56,39,34,133,30,238,106,236,197,206,47,158,52,226,240,22,66,24,152,160,128,210,64,36,232,87,25,151,157,53,5,163,236,235,238,238,244,222,96,49,29,31,13,153,104,5,231,22,7,200,223,157,160,254,142,169,167,195,251,188,33,233,78,222,45,23,253,255,129,174,132,231,175,11,153,146,70,137,247,100,109,26,106,12,199,128,5],[249,2,17,160,50,134,227,121,222,107,41,253,160,126,236,53,159,171,4,233,12,192,130,29,187,146,42,103,75,238,149,5,228,164,51,219,160,109,223,240,132,44,244,231,89,34,238,116,54,182,126,145,33,158,218,129,84,25,117,193,93,57,54,129,207,71,158,10,239,160,137,71,32,30,231,144,195,14,161,165,205,202,106,148,96,107,179,11,204,136,166,237,106,5,140,223,195,49,2,38,252,37,160,10,16,12,178,172,155,142,38,79,250,185,38,8,229,41,242,146,125,222,231,178,85,169,113,65,235,192,3,221,253,133,121,160,118,155,214,194,160,124,204,154,165,83,205,21,77,129,218,30,159,182,4,232,144,206,128,190,236,186,178,127,98,184,35,118,160,242,87,113,63,110,51,159,220,10,125,93,196,79,30,80,58,128,111,185,193,117,25,116,202,155,203,154,233,77,106,251,95,160,179,216,217,227,32,241,45,244,75,203,37,4,51,184,112,104,40,154,140,239,221,64,49,88,53,119,11,221,100,30,115,147,160,123,86,224,58,55,134,195,209,93,93,167,112,126,144,159,207,30,2,157,97,66,237,247,243,246,61,16,108,150,69,42,216,160,198,153,173,222,150,149,89,189,206,216,72,55,211,25,7,209,20,124,201,116,255,43,245,33,132,248,22,100,146,228,180,33,160,18,207,94,155,112,54,113,255,83,129,204,156,94,155,128,87,24,190,90,35,118,51,118,49,201,101,169,161,53,195,204,212,160,38,148,237,87,162,36,238,225,7,186,236,165,131,196,134,87,58,128,154,30,76,224,193,106,231,54,167,127,2,63,242,235,160,65,15,250,185,115,180,192,8,106,46,90,186,76,63,247,99,101,120,4,178,131,76,104,150,74,77,30,88,24,180,2,165,160,27,195,248,41,48,169,202,25,179,195,80,92,28,41,117,203,45,106,247,70,163,164,155,57,204,247,48,8,150,255,69,103,160,77,29,23,199,242,162,32,107,153,219,31,93,210,56,39,34,133,30,238,106,236,197,206,47,158,52,226,240,22,66,24,152,160,128,210,64,36,232,87,25,151,157,53,5,163,236,235,238,238,244,222,96,49,29,31,13,153,104,5,231,22,7,200,223,157,160,254,142,169,167,195,251,188,33,233,78,222,45,23,253,255,129,174,132,231,175,11,153,146,70,137,247,100,109,26,106,12,199,128,5],[249,2,17,160,51,241,12,122,223,81,152,154,37,130,73,169,73,174,190,217,162,228,6,125,211,205,215,202,77,228,212,82,225,163,237,192,160,108,57,248,46,203,51,108,5,211,233,36,199,112,197,41,226,231,139,145,164,37,226,96,51,179,184,38,179,18,214,14,227,160,216,159,123,174,245,114,217,222,163,30,130,28,130,112,42,41,60,19,247,247,77,30,167,48,212,24,142,109,140,167,139,82,160,22,24,108,63,110,11,171,135,168,27,40,62,80,124,232,38,247,70,47,131,50,237,27,177,116,224,97,0,220,105,0,207,160,27,32,153,65,20,139,14,102,94,202,123,191,220,51,10,53,15,90,91,208,231,17,74,83,74,152,198,129,106,142,107,134,160,16,34,203,96,5,245,23,207,43,83,207,130,98,43,103,126,11,36,249,214,34,87,112,151,109,81,5,82,255,10,70,82,160,132,190,217,18,224,217,151,188,25,206,221,116,137,199,19,252,252,99,167,60,24,250,47,2,99,252,223,58,210,71,103,12,160,135,48,207,246,58,141,50,138,56,71,148,180,41,114,250,70,187,44,46,24,129,201,137,5,131,252,164,150,132,206,7,211,160,7,209,151,13,253,160,217,6,204,0,47,210,144,219,252,152,90,3,87,48,29,26,178,0,169,194,214,154,68,243,197,216,160,168,128,138,221,38,113,12,138,148,57,231,108,100,18,221,11,59,37,117,212,20,18,79,176,177,24,166,101,83,116,36,59,160,144,107,197,69,239,225,195,211,211,21,4,18,41,56,121,142,55,91,224,216,214,151,57,52,247,120,231,250,1,211,193,23,160,252,108,69,245,6,88,254,119,86,9,126,110,214,65,71,203,229,188,14,60,46,204,216,105,26,210,18,15,27,254,12,175,160,56,164,46,14,139,85,27,222,5,117,226,241,232,26,221,205,195,150,196,115,106,141,181,231,173,150,150,86,230,174,230,118,160,96,9,107,203,131,222,63,178,190,68,100,198,163,179,53,14,232,10,145,138,227,125,133,153,241,162,90,61,106,174,48,209,160,162,80,140,238,232,172,104,178,189,11,3,53,206,103,224,50,105,110,53,97,36,158,83,102,72,24,88,21,28,158,125,203,160,230,193,57,145,215,135,56,63,27,141,34,161,66,40,124,150,99,218,110,125,26,203,193,93,106,20,228,191,226,53,27,240,128,5],[249,2,17,160,51,241,12,122,223,81,152,154,37,130,73,169,73,174,190,217,162,228,6,125,211,205,215,202,77,228,212,82,225,163,237,192,160,108,57,248,46,203,51,108,5,211,233,36,199,112,197,41,226,231,139,145,164,37,226,96,51,179,184,38,179,18,214,14,227,160,216,159,123,174,245,114,217,222,163,30,130,28,130,112,42,41,60,19,247,247,77,30,167,48,212,24,142,109,140,167,139,82,160,22,24,108,63,110,11,171,135,168,27,40,62,80,124,232,38,247,70,47,131,50,237,27,177,116,224,97,0,220,105,0,207,160,27,32,153,65,20,139,14,102,94,202,123,191,220,51,10,53,15,90,91,208,231,17,74,83,74,152,198,129,106,142,107,134,160,16,34,203,96,5,245,23,207,43,83,207,130,98,43,103,126,11,36,249,214,34,87,112,151,109,81,5,82,255,10,70,82,160,132,190,217,18,224,217,151,188,25,206,221,116,137,199,19,252,252,99,167,60,24,250,47,2,99,252,223,58,210,71,103,12,160,135,48,207,246,58,141,50,138,56,71,148,180,41,114,250,70,187,44,46,24,129,201,137,5,131,252,164,150,132,206,7,211,160,7,209,151,13,253,160,217,6,204,0,47,210,144,219,252,152,90,3,87,48,29,26,178,0,169,194,214,154,68,243,197,216,160,168,128,138,221,38,113,12,138,148,57,231,108,100,18,221,11,59,37,117,212,20,18,79,176,177,24,166,101,83,116,36,59,160,144,107,197,69,239,225,195,211,211,21,4,18,41,56,121,142,55,91,224,216,214,151,57,52,247,120,231,250,1,211,193,23,160,252,108,69,245,6,88,254,119,86,9,126,110,214,65,71,203,229,188,14,60,46,204,216,105,26,210,18,15,27,254,12,175,160,56,164,46,14,139,85,27,222,5,117,226,241,232,26,221,205,195,150,196,115,106,141,181,231,173,150,150,86,230,174,230,118,160,96,9,107,203,131,222,63,178,190,68,100,198,163,179,53,14,232,10,145,138,227,125,133,153,241,162,90,61,106,174,48,209,160,162,80,140,238,232,172,104,178,189,11,3,53,206,103,224,50,105,110,53,97,36,158,83,102,72,24,88,21,28,158,125,203,160,230,193,57,145,215,135,56,63,27,141,34,161,66,40,124,150,99,218,110,125,26,203,193,93,106,20,228,191,226,53,27,240,128,5],[249,2,17,160,33,39,1,20,248,247,235,8,83,14,6,51,208,30,213,108,102,237,221,215,232,228,70,187,27,78,176,0,8,163,95,170,160,170,99,98,103,42,49,51,254,9,177,205,247,241,15,60,230,117,203,102,101,101,117,218,172,171,136,197,129,129,130,31,135,160,117,64,244,64,112,120,157,17,156,151,58,2,245,143,63,101,157,15,87,248,32,196,84,75,122,84,59,46,48,185,191,98,160,152,57,96,242,252,200,111,209,46,155,238,44,25,164,134,150,12,61,86,57,75,184,111,192,204,68,72,77,18,170,16,245,160,122,244,234,173,129,12,158,231,23,76,102,97,134,68,156,85,77,238,116,20,225,160,149,10,98,208,198,250,39,121,27,120,160,196,241,34,116,90,96,56,131,49,177,20,26,140,119,178,238,103,214,185,234,93,9,46,201,69,146,50,75,219,126,18,104,160,47,54,175,158,157,10,125,127,125,79,46,159,240,21,120,207,129,232,177,59,69,144,48,48,133,172,168,167,82,56,85,246,160,234,182,79,195,232,90,25,45,147,29,63,169,129,218,194,0,227,65,134,220,75,104,160,206,99,71,160,250,166,59,33,254,160,30,163,206,180,138,61,188,189,238,35,29,37,221,22,221,228,190,56,109,233,40,189,149,208,125,22,132,212,243,222,162,48,160,168,86,17,145,160,253,175,87,189,242,36,138,180,171,181,57,203,52,179,52,152,169,215,250,29,11,216,22,173,124,244,48,160,160,23,89,94,237,247,112,172,230,48,73,35,139,102,199,84,73,192,236,59,221,22,192,197,215,139,186,217,1,41,82,148,160,152,114,105,120,10,10,91,38,126,46,99,128,203,158,68,32,150,137,142,142,220,103,7,68,247,231,125,68,50,69,173,31,160,232,192,193,129,55,246,219,2,21,95,185,215,91,77,57,159,231,197,191,216,110,12,90,42,102,228,47,143,187,182,239,195,160,221,159,32,235,93,231,122,178,230,101,161,192,173,79,175,184,59,126,75,86,134,254,172,15,3,234,37,200,238,16,226,190,160,38,143,194,58,172,99,153,99,15,216,34,169,236,44,42,7,158,105,155,130,175,192,127,236,79,21,193,223,173,150,50,180,160,2,127,2,197,234,36,175,155,248,175,204,19,60,74,97,151,82,20,50,241,248,141,215,153,181,193,58,87,151,184,73,254,128,5],[249,2,17,160,33,39,1,20,248,247,235,8,83,14,6,51,208,30,213,108,102,237,221,215,232,228,70,187,27,78,176,0,8,163,95,170,160,170,99,98,103,42,49,51,254,9,177,205,247,241,15,60,230,117,203,102,101,101,117,218,172,171,136,197,129,129,130,31,135,160,117,64,244,64,112,120,157,17,156,151,58,2,245,143,63,101,157,15,87,248,32,196,84,75,122,84,59,46,48,185,191,98,160,152,57,96,242,252,200,111,209,46,155,238,44,25,164,134,150,12,61,86,57,75,184,111,192,204,68,72,77,18,170,16,245,160,122,244,234,173,129,12,158,231,23,76,102,97,134,68,156,85,77,238,116,20,225,160,149,10,98,208,198,250,39,121,27,120,160,196,241,34,116,90,96,56,131,49,177,20,26,140,119,178,238,103,214,185,234,93,9,46,201,69,146,50,75,219,126,18,104,160,47,54,175,158,157,10,125,127,125,79,46,159,240,21,120,207,129,232,177,59,69,144,48,48,133,172,168,167,82,56,85,246,160,234,182,79,195,232,90,25,45,147,29,63,169,129,218,194,0,227,65,134,220,75,104,160,206,99,71,160,250,166,59,33,254,160,30,163,206,180,138,61,188,189,238,35,29,37,221,22,221,228,190,56,109,233,40,189,149,208,125,22,132,212,243,222,162,48,160,168,86,17,145,160,253,175,87,189,242,36,138,180,171,181,57,203,52,179,52,152,169,215,250,29,11,216,22,173,124,244,48,160,160,23,89,94,237,247,112,172,230,48,73,35,139,102,199,84,73,192,236,59,221,22,192,197,215,139,186,217,1,41,82,148,160,152,114,105,120,10,10,91,38,126,46,99,128,203,158,68,32,150,137,142,142,220,103,7,68,247,231,125,68,50,69,173,31,160,232,192,193,129,55,246,219,2,21,95,185,215,91,77,57,159,231,197,191,216,110,12,90,42,102,228,47,143,187,182,239,195,160,221,159,32,235,93,231,122,178,230,101,161,192,173,79,175,184,59,126,75,86,134,254,172,15,3,234,37,200,238,16,226,190,160,38,143,194,58,172,99,153,99,15,216,34,169,236,44,42,7,158,105,155,130,175,192,127,236,79,21,193,223,173,150,50,180,160,2,127,2,197,234,36,175,155,248,175,204,19,60,74,97,151,82,20,50,241,248,141,215,153,181,193,58,87,151,184,73,254,128,5],[249,1,49,160,119,73,17,92,128,20,103,104,232,32,124,19,16,87,60,164,208,90,161,44,211,37,10,22,234,211,119,99,38,103,198,198,128,128,160,197,2,59,23,137,170,248,2,213,118,95,76,155,251,48,153,90,243,215,96,187,113,77,106,134,162,144,12,225,177,150,82,128,160,163,49,39,187,25,224,238,70,65,179,76,107,218,25,133,29,45,119,79,102,88,247,235,233,62,172,199,17,252,137,160,132,160,228,247,244,44,169,159,121,241,37,203,87,229,189,5,235,105,253,45,60,197,77,122,58,147,64,9,131,17,17,142,20,155,128,128,160,205,29,5,65,38,9,46,153,141,104,202,181,91,192,0,13,172,218,7,199,83,1,165,46,186,0,114,232,249,237,55,86,160,95,199,183,163,77,23,5,95,41,107,232,12,194,66,48,248,191,156,189,227,198,181,71,183,94,67,71,52,31,231,186,220,128,160,72,154,12,74,44,172,232,136,12,112,213,212,84,199,60,155,180,189,250,131,119,235,245,179,231,69,41,210,95,2,102,69,160,185,48,236,239,154,158,161,183,121,156,86,53,176,75,170,145,108,209,199,136,127,25,169,15,172,38,79,212,229,151,21,78,128,160,168,42,10,43,57,84,192,82,188,77,84,115,130,173,36,32,174,129,104,109,48,102,57,116,53,12,2,1,10,219,36,135,128,5],[249,1,49,160,119,73,17,92,128,20,103,104,232,32,124,19,16,87,60,164,208,90,161,44,211,37,10,22,234,211,119,99,38,103,198,198,128,128,160,197,2,59,23,137,170,248,2,213,118,95,76,155,251,48,153,90,243,215,96,187,113,77,106,134,162,144,12,225,177,150,82,128,160,163,49,39,187,25,224,238,70,65,179,76,107,218,25,133,29,45,119,79,102,88,247,235,233,62,172,199,17,252,137,160,132,160,228,247,244,44,169,159,121,241,37,203,87,229,189,5,235,105,253,45,60,197,77,122,58,147,64,9,131,17,17,142,20,155,128,128,160,205,29,5,65,38,9,46,153,141,104,202,181,91,192,0,13,172,218,7,199,83,1,165,46,186,0,114,232,249,237,55,86,160,95,199,183,163,77,23,5,95,41,107,232,12,194,66,48,248,191,156,189,227,198,181,71,183,94,67,71,52,31,231,186,220,128,160,72,154,12,74,44,172,232,136,12,112,213,212,84,199,60,155,180,189,250,131,119,235,245,179,231,69,41,210,95,2,102,69,160,185,48,236,239,154,158,161,183,121,156,86,53,176,75,170,145,108,209,199,136,127,25,169,15,172,38,79,212,229,151,21,78,128,160,168,42,10,43,57,84,192,82,188,77,84,115,130,173,36,32,174,129,104,109,48,102,57,116,53,12,2,1,10,219,36,135,128,5],[248,102,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,184,70,248,68,128,128,160,108,175,176,92,138,97,66,88,92,163,20,133,186,14,202,83,61,132,245,179,24,124,92,74,69,199,166,219,149,87,245,197,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,5],[248,102,157,57,47,8,36,135,220,3,79,164,170,203,106,91,189,74,36,174,197,127,223,251,73,189,128,179,24,228,185,158,184,70,248,68,128,128,160,108,175,176,92,138,97,66,88,92,163,20,133,186,14,202,83,61,132,245,179,24,124,92,74,69,199,166,219,149,87,245,197,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112,5],[248,81,128,128,128,160,147,31,200,131,19,49,103,136,46,1,167,47,128,146,235,40,179,181,1,99,210,43,90,113,42,63,194,216,20,174,42,218,128,128,128,128,128,128,128,160,204,123,237,30,197,175,26,208,74,15,150,211,15,238,169,175,151,34,192,58,177,202,8,45,196,255,144,212,1,208,149,21,128,128,128,128,128,5],[248,81,128,128,128,160,147,31,200,131,19,49,103,136,46,1,167,47,128,146,235,40,179,181,1,99,210,43,90,113,42,63,194,216,20,174,42,218,128,128,128,128,128,128,128,160,204,123,237,30,197,175,26,208,74,15,150,211,15,238,169,175,151,34,192,58,177,202,8,45,196,255,144,212,1,208,149,21,128,128,128,128,128,5]] \ No newline at end of file diff --git a/zkevm-circuits/src/mpt_circuit/witness_row.rs b/zkevm-circuits/src/mpt_circuit/witness_row.rs index 80cf41792c..c3856091c1 100644 --- a/zkevm-circuits/src/mpt_circuit/witness_row.rs +++ b/zkevm-circuits/src/mpt_circuit/witness_row.rs @@ -9,10 +9,10 @@ use std::{convert::TryFrom, marker::PhantomData}; use crate::{ mpt_circuit::helpers::bytes_into_rlc, mpt_circuit::param::{ - COUNTER_WITNESS_LEN, C_RLP_START, C_START, HASH_WIDTH, IS_ACCOUNT_DELETE_MOD_POS, + COUNTER_WITNESS_LEN, C_RLP_START, HASH_WIDTH, IS_ACCOUNT_DELETE_MOD_POS, IS_BALANCE_MOD_POS, IS_CODEHASH_MOD_POS, IS_NONCE_MOD_POS, IS_NON_EXISTING_ACCOUNT_POS, IS_NON_EXISTING_STORAGE_POS, IS_STORAGE_MOD_POS, NOT_FIRST_LEVEL_POS, RLP_NUM, S_RLP_START, - S_START, WITNESS_ROW_WIDTH, + WITNESS_ROW_WIDTH, }, mpt_circuit::{MPTConfig, ProofValues}, }; @@ -119,7 +119,6 @@ impl MptWitnessRow { 0 }; &self.bytes[S_RLP_START+offset..34] - //&self.bytes[S_RLP_START..S_RLP_START + 34] } pub(crate) fn c_hash_bytes(&self) -> &[u8] { @@ -129,7 +128,6 @@ impl MptWitnessRow { 0 }; &self.bytes[C_RLP_START+offset..68] - //&self.bytes[C_RLP_START..C_RLP_START + 34] } pub(crate) fn main(&self) -> &[u8] { @@ -214,8 +212,8 @@ impl MptWitnessRow { pv: &ProofValues, offset: usize, ) -> Result<(), Error> { - let s_root_rlc = self.s_root_bytes_rlc(mpt_config.randomness); - let c_root_rlc = self.c_root_bytes_rlc(mpt_config.randomness); + let s_root_rlc = self.s_root_bytes_rlc(mpt_config.r); + let c_root_rlc = self.c_root_bytes_rlc(mpt_config.r); region.assign_advice( || "inter start root", @@ -243,7 +241,7 @@ impl MptWitnessRow { prevent omitting account proof (and having only storage proof with the appropriate address RLC) */ - let address_rlc = bytes_into_rlc(self.address_bytes(), mpt_config.randomness); + let address_rlc = bytes_into_rlc(self.address_bytes(), mpt_config.r); region.assign_advice( || "address RLC", From fb94d83d67aaf15c08dc8c6d68538ed2ca9b2419 Mon Sep 17 00:00:00 2001 From: Brechtpd Date: Wed, 1 Mar 2023 02:22:24 +0100 Subject: [PATCH 11/11] Misc small improvements --- .../src/circuit_tools/constraint_builder.rs | 36 +- zkevm-circuits/src/mpt_circuit.rs | 47 +- .../src/mpt_circuit/account_leaf.rs | 245 ++--- zkevm-circuits/src/mpt_circuit/branch.rs | 246 +++-- zkevm-circuits/src/mpt_circuit/helpers.rs | 901 ++++-------------- zkevm-circuits/src/mpt_circuit/rlp_gadgets.rs | 722 ++++++++++++++ .../src/mpt_circuit/storage_leaf.rs | 227 ++--- zkevm-circuits/src/mpt_circuit/witness_row.rs | 4 +- 8 files changed, 1280 insertions(+), 1148 deletions(-) create mode 100644 zkevm-circuits/src/mpt_circuit/rlp_gadgets.rs diff --git a/zkevm-circuits/src/circuit_tools/constraint_builder.rs b/zkevm-circuits/src/circuit_tools/constraint_builder.rs index e9baaef001..5891ba9762 100644 --- a/zkevm-circuits/src/circuit_tools/constraint_builder.rs +++ b/zkevm-circuits/src/circuit_tools/constraint_builder.rs @@ -605,7 +605,16 @@ impl_selectable!( Expression, Expression, Expression, - )| { vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr(), t.4.expr(), t.5.expr()] } + )| { + vec![ + t.0.expr(), + t.1.expr(), + t.2.expr(), + t.3.expr(), + t.4.expr(), + t.5.expr(), + ] + } ); impl_selectable!( ( @@ -625,7 +634,17 @@ impl_selectable!( Expression, Expression, Expression, - )| { vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr(), t.4.expr(), t.5.expr(), t.6.expr()] } + )| { + vec![ + t.0.expr(), + t.1.expr(), + t.2.expr(), + t.3.expr(), + t.4.expr(), + t.5.expr(), + t.6.expr(), + ] + } ); impl_selectable!( ( @@ -647,7 +666,18 @@ impl_selectable!( Expression, Expression, Expression, - )| { vec![t.0.expr(), t.1.expr(), t.2.expr(), t.3.expr(), t.4.expr(), t.5.expr(), t.6.expr(), t.7.expr()] } + )| { + vec![ + t.0.expr(), + t.1.expr(), + t.2.expr(), + t.3.expr(), + t.4.expr(), + t.5.expr(), + t.6.expr(), + t.7.expr(), + ] + } ); /// Trait that conditionally combines multiple types diff --git a/zkevm-circuits/src/mpt_circuit.rs b/zkevm-circuits/src/mpt_circuit.rs index 695446edc9..773fd6f952 100644 --- a/zkevm-circuits/src/mpt_circuit.rs +++ b/zkevm-circuits/src/mpt_circuit.rs @@ -15,11 +15,12 @@ mod columns; mod helpers; mod param; mod proof_chain; +mod rlp_gadgets; mod selectors; mod storage_leaf; mod witness_row; -use branch::{BranchConfig}; +use branch::BranchConfig; use columns::{MainCols, PositionCols, ProofTypeCols}; use proof_chain::ProofChainConfig; use witness_row::{MptWitnessRow, MptWitnessRowType}; @@ -28,19 +29,14 @@ use param::HASH_WIDTH; use selectors::SelectorsConfig; use crate::{ - assign, - circuit, - circuit_tools::{ - cell_manager::CellManager, - constraint_builder::{merge_lookups}, - memory::Memory, - }, + assign, assignf, circuit, + circuit_tools::{cell_manager::CellManager, constraint_builder::merge_lookups, memory::Memory}, mpt_circuit::{ helpers::{extend_rand, parent_memory, KeyData, MPTConstraintBuilder, ParentData}, storage_leaf::StorageLeafConfig, }, table::{DynamicTableColumns, KeccakTable}, - util::{power_of_randomness_from_instance, Challenges}, assignf, + util::{power_of_randomness_from_instance, Challenges}, }; use self::{account_leaf::AccountLeafConfig, columns::MPTTable, helpers::key_memory}; @@ -137,13 +133,7 @@ impl_expr!(FixedTableTag); // TODO(Brecht): remove by refactoring to use memory values instead #[derive(Default)] pub(crate) struct ProofValues { - pub(crate) key_rlc: F, - pub(crate) key_rlc_mult: F, - pub(crate) key_rlc_prev: F, - pub(crate) key_rlc_mult_prev: F, - pub(crate) before_account_leaf: bool, - pub(crate) memory: Memory, } @@ -151,8 +141,6 @@ impl ProofValues { fn new(memory: &Memory) -> Self { Self { memory: memory.clone(), - key_rlc_mult: F::one(), - key_rlc_mult_prev: F::one(), before_account_leaf: true, ..Default::default() } @@ -431,11 +419,18 @@ impl MPTConfig { child_c_bytes.rotate_left(2); }; - row.bytes = [child_s_bytes.clone(), child_c_bytes.clone(), row.bytes[68..].to_owned()].concat(); + row.bytes = [ + child_s_bytes.clone(), + child_c_bytes.clone(), + row.bytes[68..].to_owned(), + ] + .concat(); //println!("+ {:?}", row.bytes); } - if row.get_type() == MptWitnessRowType::ExtensionNodeS || row.get_type() == MptWitnessRowType::ExtensionNodeC { + if row.get_type() == MptWitnessRowType::ExtensionNodeS + || row.get_type() == MptWitnessRowType::ExtensionNodeC + { //println!("- {:?}", row.bytes); let mut value_bytes = row.bytes[34..68].to_owned(); if value_bytes[1] == 160 { @@ -446,7 +441,12 @@ impl MPTConfig { value_bytes[1] = 0; value_bytes.rotate_left(2); }; - row.bytes = [row.bytes[0..34].to_owned(), value_bytes.clone(), row.bytes[68..].to_owned()].concat(); + row.bytes = [ + row.bytes[0..34].to_owned(), + value_bytes.clone(), + row.bytes[68..].to_owned(), + ] + .concat(); //println!("+ {:?}", row.bytes); } } @@ -538,13 +538,6 @@ impl MPTConfig { row.clone() }; - if row.get_type() == MptWitnessRowType::AccountLeafNeighbouringLeaf { - pv.key_rlc = F::zero(); // account address until here, storage key from here on - pv.key_rlc_mult = F::one(); - pv.key_rlc_prev = F::zero(); - pv.key_rlc_mult_prev = F::one(); - } - if offset > 0 && prev_row.get_type() == MptWitnessRowType::InitBranch { //println!("{}: branch", offset); assign!(region, (self.is_branch, offset) => 1.scalar()).ok(); diff --git a/zkevm-circuits/src/mpt_circuit/account_leaf.rs b/zkevm-circuits/src/mpt_circuit/account_leaf.rs index 3569ec344c..d3acd3a1d7 100644 --- a/zkevm-circuits/src/mpt_circuit/account_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/account_leaf.rs @@ -6,9 +6,7 @@ use halo2_proofs::{ poly::Rotation, }; -use crate::circuit_tools::constraint_builder::RLCChainable; -use crate::circuit_tools::gadgets::RequireNotZeroGadget; -use crate::mpt_circuit::helpers::{drifted_nibble_rlc, Indexable, IsEmptyTreeGadget}; +use crate::mpt_circuit::helpers::{Indexable, IsEmptyTreeGadget}; use crate::table::ProofType; use crate::{ assign, circuit, @@ -22,35 +20,33 @@ use crate::{ mpt_circuit::{param::IS_ACCOUNT_DELETE_MOD_POS, MPTConfig, ProofValues}, mpt_circuit::{witness_row::MptWitnessRow, MPTContext}, }; +use crate::{ + circuit_tools::constraint_builder::RLCChainable, + mpt_circuit::helpers::{DriftedGadget, WrongGadget}, +}; -use super::helpers::{LeafKeyGadget, RLPValueGadget, ParentDataWitness}; +use super::param::{HASH_WIDTH, IS_BALANCE_MOD_POS, IS_CODEHASH_MOD_POS, IS_NONCE_MOD_POS}; use super::{ - helpers::bytes_into_rlc, - param::{ - HASH_WIDTH, IS_BALANCE_MOD_POS, IS_CODEHASH_MOD_POS, IS_NONCE_MOD_POS, - IS_NON_EXISTING_ACCOUNT_POS, - }, + helpers::{LeafKeyGadget, ParentDataWitness}, + param::IS_NON_EXISTING_ACCOUNT_POS, + rlp_gadgets::RLPValueGadget, }; #[derive(Clone, Debug, Default)] pub(crate) struct AccountLeafConfig { key_data: [KeyData; 2], - key_data_w: KeyData, parent_data: [ParentData; 2], - check_is_wrong_leaf: RequireNotZeroGadget, rlp_key: [LeafKeyGadget; 2], key_mult: [Cell; 2], - wrong_rlp_key: LeafKeyGadget, - is_wrong_leaf: Cell, rlp_nonce: [RLPValueGadget; 2], rlp_balance: [RLPValueGadget; 2], rlp_storage: [RLPValueGadget; 2], rlp_codehash: [RLPValueGadget; 2], nonce_mult: [Cell; 2], balance_mult: [Cell; 2], - drifted_rlp_key: LeafKeyGadget, - drifted_mult: Cell, is_empty_trie: [IsEmptyTreeGadget; 2], + drifted: DriftedGadget, + wrong: WrongGadget, } impl AccountLeafConfig { @@ -111,8 +107,6 @@ impl AccountLeafConfig { // The two list RLP bytes are stored in the c RLP bytes. // The RLP bytes of nonce/balance are stored bytes[0]. - config.is_wrong_leaf = cb.base.query_cell(); - let mut key_rlc = vec![0.expr(); 2]; let mut nonce_rlc = vec![0.expr(); 2]; let mut balance_rlc = vec![0.expr(); 2]; @@ -197,7 +191,6 @@ impl AccountLeafConfig { key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), - true, &r, ); // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES. @@ -218,7 +211,8 @@ impl AccountLeafConfig { require!(value_rlp_bytes[is_s.idx()][1] => value_rlp_bytes[is_s.idx()][3].expr() + 2.expr()); // `c_main.rlp1` always needs to be RLP_LIST_LONG + 1. require!(value_rlp_bytes[is_s.idx()][2] => RLP_LIST_LONG + 1); - // The length of the list is `#(nonce bytes) + #(balance bytes) + 2 * (1 + #(hash))`. + // The length of the list is `#(nonce bytes) + #(balance bytes) + 2 * (1 + + // #(hash))`. require!(value_rlp_bytes[is_s.idx()][3] => config.rlp_nonce[is_s.idx()].num_bytes() + config.rlp_balance[is_s.idx()].num_bytes() + (2 * (1 + 32)).expr()); // Now check that the the key and value list length matches the account length. // The RLP encoded string always has 2 RLP bytes (the s RLP bytes). @@ -245,105 +239,31 @@ impl AccountLeafConfig { ); } - // A drifted leaf appears only when there is a placeholder branch - ifx! {config.parent_data[true.idx()].is_placeholder.expr() + config.parent_data[false.idx()].is_placeholder.expr() => { - config.drifted_rlp_key = LeafKeyGadget::construct(&mut cb.base, &drifted_bytes); - - // TODO(Brecht): seems like we have to verify the RLP encoding because the key length can change - - // The key RLC of the drifted leaf needs to be the same as the key RLC of the leaf before - // the drift - the nibbles are the same in both cases, the difference is that before the - // drift some nibbles are stored in the leaf key, while after the drift these nibbles are used as - // position in a branch or/and nibbles of the extension node. - // We need the intermediate key RLC right before `drifted_index` is added to it. - let (key_rlc_prev, key_mult_prev, placeholder_nibble, placeholder_is_odd) = ifx!{config.parent_data[true.idx()].is_placeholder.expr() => { - ( - config.key_data[true.idx()].parent_rlc.expr(), - config.key_data[true.idx()].parent_mult.expr(), - config.key_data[true.idx()].placeholder_nibble.expr(), - config.key_data[true.idx()].placeholder_is_odd.expr(), - ) - } elsex { - ( - config.key_data[false.idx()].parent_rlc.expr(), - config.key_data[false.idx()].parent_mult.expr(), - config.key_data[false.idx()].placeholder_nibble.expr(), - config.key_data[false.idx()].placeholder_is_odd.expr(), - ) - }}; - - // Calculate the drifted key RLC - let drifted_key_rlc = key_rlc_prev + - drifted_nibble_rlc(&mut cb.base, placeholder_nibble.expr(), key_mult_prev.expr(), placeholder_is_odd.expr()) + - config.drifted_rlp_key.leaf_key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), false, &r); - - // RLC bytes zero check - cb.set_length(config.drifted_rlp_key.num_bytes_on_key_row()); - config.drifted_mult = cb.base.query_cell(); - require!((FixedTableTag::RMult, config.drifted_rlp_key.num_bytes_on_key_row(), config.drifted_mult.expr()) => @"fixed"); - - // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let calc_rlc = |is_s: bool| { - // Calculate the drifted leaf rlc - let rlc = (config.drifted_rlp_key.rlc(&r), config.drifted_mult.expr()).rlc_chain(leaf_no_key_rlc[is_s.idx()].expr()); - (true.expr(), key_rlc[is_s.idx()].expr(), rlc, config.parent_data[is_s.idx()].placeholder_rlc.expr()) - }; - let (do_checks, key_rlc, drifted_rlc, mod_hash) = matchx! { - config.parent_data[true.idx()].is_placeholder => { - // Neighbour leaf in the added branch - calc_rlc(true) - }, - config.parent_data[false.idx()].is_placeholder => { - // Neighbour leaf in the deleted branch - calc_rlc(false) - }, - _ => (false.expr(), 0.expr(), 0.expr(), 0.expr()), - }; - ifx! {do_checks => { - // The key of the drifted leaf needs to match the key of the leaf - require!(key_rlc => drifted_key_rlc); - // The drifted leaf needs to be stored in the branch at `drifted_index`. - // TODO(Brecht): 53 "src/mpt_circuit/tests/AccountAddPlaceholderExtension.json" - //require!((1, drifted_rlc, config.drifted_rlp_key.num_bytes(), mod_hash) => @"keccak"); - }} - }} - - // Wrong leaf - // Make sure is_wrong_leaf is boolean - require!(config.is_wrong_leaf => bool); - ifx! {a!(ctx.proof_type.is_non_existing_account_proof, wrong_offset) => { - // Get the previous key data - config.key_data_w = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 1.expr()); - ifx! {config.is_wrong_leaf => { - // Calculate the key - config.wrong_rlp_key = LeafKeyGadget::construct(&mut cb.base, &wrong_bytes); - let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.leaf_key_rlc( - &mut cb.base, - config.key_data_w.mult.expr(), - config.key_data_w.is_odd.expr(), - 1.expr(), - false, - &ctx.r, - ); - - // Check that it's the key as requested in the lookup - let key_rlc_lookup = a!(ctx.mpt_table.address_rlc, wrong_offset); - require!(key_rlc_lookup => key_rlc_wrong); - - // Now make sure this address is different than the one of the leaf - config.check_is_wrong_leaf = RequireNotZeroGadget::construct(&mut cb.base, key_rlc_lookup - key_rlc[true.idx()].expr()); - // Make sure the lengths of the keys are the same - require!(config.wrong_rlp_key.key_len() => config.rlp_key[true.idx()].key_len()); - // RLC bytes zero check - cb.set_length(config.wrong_rlp_key.num_bytes_on_key_row()); - } elsex { - // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. - require!(config.key_data_w.is_placeholder_leaf_s => true); - }} - } elsex { - // is_wrong_leaf needs to be false when not in non_existing_account proof - require!(config.is_wrong_leaf => false); - }} + // Drifted leaf handling + config.drifted = DriftedGadget::construct( + cb, + &config.parent_data, + &config.key_data, + &key_rlc, + &leaf_no_key_rlc, + &drifted_bytes, + &ctx.r, + ); + + // Wrong leaf handling + let is_non_existing = a!(ctx.proof_type.is_non_existing_account_proof, wrong_offset); + config.wrong = WrongGadget::construct( + meta, + cb, + ctx.clone(), + is_non_existing, + &config.rlp_key, + &key_rlc, + &wrong_bytes, + wrong_offset, + true, + &ctx.r, + ); // Account delete // We need to make sure there is no leaf when account is deleted. Two possible @@ -431,9 +351,10 @@ impl AccountLeafConfig { let nonce_balance_c = witness[base_offset + 3].to_owned(); let storage_codehash_s = witness[base_offset + 4].to_owned(); let storage_codehash_c = witness[base_offset + 5].to_owned(); + let row_drifted = witness[base_offset + 6].to_owned(); - let key_bytes = [key_s.to_owned(), key_c.to_owned()]; - let wrong_bytes = witness[base_offset + 1].to_owned(); + let row_key = [&key_s, &key_c]; + let row_wrong = witness[base_offset + 1].to_owned(); let nonce_bytes = [ nonce_balance_s.bytes[..34].to_owned(), nonce_balance_c.bytes[..34].to_owned(), @@ -450,7 +371,6 @@ impl AccountLeafConfig { storage_codehash_s.bytes[34..68].to_owned(), storage_codehash_c.bytes[34..68].to_owned(), ]; - //let drifted_bytes = witness[base_offset + 6].to_owned(); let key_s_lookup_offset = base_offset - 1; let nonce_lookup_offset = base_offset + 2; @@ -467,9 +387,9 @@ impl AccountLeafConfig { let mut codehash_value_rlc = vec![0.scalar(); 2]; let mut parent_data = vec![ParentDataWitness::default(); 2]; for is_s in [true, false] { - let key_row = &key_bytes[is_s.idx()]; + let key_row = &row_key[is_s.idx()]; - self.key_data[is_s.idx()].witness_load( + let key_data = self.key_data[is_s.idx()].witness_load( region, base_offset, &mut pv.memory[key_memory(is_s)], @@ -531,13 +451,8 @@ impl AccountLeafConfig { self.balance_mult[is_s.idx()].assign(region, base_offset, mult_balance)?; // Key - let (key_rlc_new, key_rlc_mult) = if parent_data[is_s.idx()].is_placeholder { - (pv.key_rlc_prev, pv.key_rlc_mult_prev) - } else { - (pv.key_rlc, pv.key_rlc_mult) - }; (key_rlc[is_s.idx()], _) = - rlp_key_witness.leaf_key_rlc(key_rlc_new, key_rlc_mult, ctx.r); + rlp_key_witness.leaf_key_rlc(key_data.rlc, key_data.mult, ctx.r); let mut key_mult = F::one(); for _ in 0..rlp_key_witness.num_bytes_on_key_row() { @@ -572,59 +487,25 @@ impl AccountLeafConfig { } // Drifted leaf handling - if parent_data[true.idx()].is_placeholder || parent_data[false.idx()].is_placeholder { - // TODO(Brecht): Change how the witness is generated - let drifted_bytes = &mut witness[base_offset + 6].bytes; - let key_bytes = if parent_data[true.idx()].is_placeholder { - &key_bytes[true.idx()] - } else { - &key_bytes[false.idx()] - }; - drifted_bytes[0] = key_bytes.bytes[0]; - drifted_bytes[1] = key_bytes.bytes[1]; - drifted_bytes[2] = key_bytes.bytes[2]; - - let drifted_key_witness = - self.drifted_rlp_key - .assign(region, base_offset, &drifted_bytes)?; - - let (_, leaf_mult) = drifted_key_witness.rlc_leaf(ctx.r); - - self.drifted_mult.assign(region, base_offset, leaf_mult)?; - } - - // Non-existing - let row = wrong_bytes; - if row.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1 { - self.key_data_w.witness_load( - region, - base_offset, - &mut pv.memory[key_memory(true)], - 1, - )?; - - // TODO(Brecht): Change how the witness is generated - let is_wrong = row.bytes[0] != 0; - self.is_wrong_leaf - .assign(region, base_offset, F::from(is_wrong))?; - - let mut row_bytes = row.bytes.clone(); - row_bytes[0] = key_bytes[true.idx()].bytes[0]; - - let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes)?; - let (key_rlc_wrong, _) = - wrong_witness.leaf_key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.r); - - let address_rlc = bytes_into_rlc(row.address_bytes(), ctx.r); - self.check_is_wrong_leaf.assign( - region, - base_offset, - address_rlc - key_rlc[true.idx()], - )?; - - assign!(region, (ctx.mpt_table.key_rlc, wrong_offset) => key_rlc_wrong)?; - assign!(region, (ctx.proof_type.proof_type, wrong_offset) => ProofType::AccountDestructed.scalar())?; - } + self.drifted + .assign(region, base_offset, &parent_data, &row_drifted.bytes, ctx.r)?; + + // Wrong leaf handling + let is_non_existing = row_wrong.get_byte_rev(IS_NON_EXISTING_ACCOUNT_POS) == 1; + self.wrong.assign( + region, + base_offset, + ctx, + is_non_existing, + &mut pv.memory, + &key_rlc, + &row_wrong.bytes, + wrong_offset, + row_key, + true, + ProofType::AccountDoesNotExist, + ctx.r, + )?; // Lookup data if key_s.get_byte_rev(IS_ACCOUNT_DELETE_MOD_POS) == 1 { diff --git a/zkevm-circuits/src/mpt_circuit/branch.rs b/zkevm-circuits/src/mpt_circuit/branch.rs index d363d03269..eec339beba 100644 --- a/zkevm-circuits/src/mpt_circuit/branch.rs +++ b/zkevm-circuits/src/mpt_circuit/branch.rs @@ -1,41 +1,37 @@ use eth_types::Field; use gadgets::util::Scalar; use halo2_proofs::{ - circuit::{Region}, - plonk::{Error, VirtualCells, Expression}, + circuit::Region, + plonk::{Error, Expression, VirtualCells}, }; use super::{ - helpers::{MPTConstraintBuilder, RLPListGadget, RLPItemGadget, LeafKeyGadget, RLPItemWitness, ParentDataWitness}, - param::{ - ARITY, IS_BRANCH_C_PLACEHOLDER_POS, - }, + helpers::{LeafKeyGadget, MPTConstraintBuilder, ParentDataWitness}, + param::{ARITY, IS_BRANCH_C_PLACEHOLDER_POS}, + rlp_gadgets::{RLPItemGadget, RLPItemWitness, RLPListGadget}, MPTContext, }; use crate::{ circuit, circuit_tools::{ - cell_manager::{Cell}, - constraint_builder::{RLCChainable}, gadgets::{IsEqualGadget, LtGadget, IsZeroGadget}, + cell_manager::Cell, + constraint_builder::RLCChainable, + gadgets::{IsEqualGadget, IsZeroGadget, LtGadget}, }, + mpt_circuit::witness_row::MptWitnessRow, mpt_circuit::{ - helpers::{ - key_memory, parent_memory, Indexable, - KeyData, ParentData, + helpers::num_nibbles, + param::{ + BRANCH_0_KEY_POS, DRIFTED_POS, HASH_WIDTH, IS_BRANCH_S_PLACEHOLDER_POS, + IS_EXT_LONG_EVEN_C16_POS, IS_EXT_LONG_EVEN_C1_POS, IS_EXT_LONG_ODD_C16_POS, + IS_EXT_LONG_ODD_C1_POS, IS_EXT_SHORT_C16_POS, IS_EXT_SHORT_C1_POS, }, - param::{RLP_NIL}, - FixedTableTag, }, mpt_circuit::{ - param::{ - BRANCH_0_KEY_POS, - DRIFTED_POS, HASH_WIDTH, - IS_BRANCH_S_PLACEHOLDER_POS, IS_EXT_LONG_EVEN_C16_POS, IS_EXT_LONG_EVEN_C1_POS, - IS_EXT_LONG_ODD_C16_POS, IS_EXT_LONG_ODD_C1_POS, IS_EXT_SHORT_C16_POS, - IS_EXT_SHORT_C1_POS, - }, helpers::num_nibbles, + helpers::{key_memory, parent_memory, Indexable, KeyData, ParentData}, + param::RLP_NIL, + FixedTableTag, }, - mpt_circuit::{witness_row::MptWitnessRow}, mpt_circuit::{MPTConfig, ProofValues}, }; @@ -85,7 +81,10 @@ impl BranchConfig { let offset = -1; // Data - let rlp_bytes = [ctx.expr(meta, -1)[4..7].to_owned(), ctx.expr(meta, -1)[7..10].to_owned()]; + let rlp_bytes = [ + ctx.expr(meta, -1)[4..7].to_owned(), + ctx.expr(meta, -1)[7..10].to_owned(), + ]; let branch_bytes: [[Vec>; ARITY]; 2] = [ array_init::array_init(|i| ctx.expr(meta, i as i32)[0..34].to_owned()), array_init::array_init(|i| ctx.expr(meta, i as i32)[34..68].to_owned()), @@ -253,9 +252,11 @@ impl BranchConfig { let mut mult = vec![1.expr(); 2]; for is_s in [true, false] { // Read the list - config.rlp_list[is_s.idx()] = RLPListGadget::construct(&mut cb.base, &rlp_bytes[is_s.idx()]); + config.rlp_list[is_s.idx()] = + RLPListGadget::construct(&mut cb.base, &rlp_bytes[is_s.idx()]); // Start the RLC encoding of the branch - (branch_node_rlc[is_s.idx()], mult[is_s.idx()]) = config.rlp_list[is_s.idx()].rlc_rlp(&r); + (branch_node_rlc[is_s.idx()], mult[is_s.idx()]) = + config.rlp_list[is_s.idx()].rlc_rlp(&r); // Keep track of how many bytes the branch contains to make sure it's correct. num_bytes_left[is_s.idx()] = config.rlp_list[is_s.idx()].len(); @@ -264,7 +265,11 @@ impl BranchConfig { config.mod_branch_is_hashed[is_s.idx()] = cb.base.query_cell(); // Check if the branch is hashed or not - config.is_not_hashed[is_s.idx()] = LtGadget::construct(&mut cb.base, config.rlp_list[is_s.idx()].num_bytes(), HASH_WIDTH.expr()); + config.is_not_hashed[is_s.idx()] = LtGadget::construct( + &mut cb.base, + config.rlp_list[is_s.idx()].num_bytes(), + HASH_WIDTH.expr(), + ); } // Process the branch children @@ -278,13 +283,18 @@ impl BranchConfig { require!(config.is_drifted[node_index] => bool); // Calculate the modified and drifted index from `is_modified`/`is_drifted` - modified_index = modified_index.expr() + config.is_modified[node_index].expr() * node_index.expr(); - drifted_index = drifted_index.expr() + config.is_drifted[node_index].expr() * node_index.expr(); + modified_index = modified_index.expr() + + config.is_modified[node_index].expr() * node_index.expr(); + drifted_index = + drifted_index.expr() + config.is_drifted[node_index].expr() * node_index.expr(); for is_s in [true, false] { let branch = &mut config.branches[is_s.idx()][node_index]; // Read the branch - branch.rlp = RLPItemGadget::construct(&mut cb.base, &branch_bytes[is_s.idx()][node_index]); + branch.rlp = RLPItemGadget::construct( + &mut cb.base, + &branch_bytes[is_s.idx()][node_index], + ); let num_bytes = branch.rlp.num_bytes(); // Bookkeeping for RLC branch.mult = cb.base.query_cell(); @@ -294,26 +304,30 @@ impl BranchConfig { cb.set_length_sc(is_s, num_bytes.expr()); // Keep track of how many bytes of the list we've processed - num_bytes_left[is_s.idx()] = num_bytes_left[is_s.idx()].expr() - num_bytes.expr(); + num_bytes_left[is_s.idx()] = + num_bytes_left[is_s.idx()].expr() - num_bytes.expr(); // Update the full branch node RLC with the data of this branch - branch_node_rlc[is_s.idx()] = (branch_node_rlc[is_s.idx()].expr(), mult[is_s.idx()].expr()).rlc_chain( - branch.rlp.rlc_rlp(&mut cb.base, &r) - ); + branch_node_rlc[is_s.idx()] = + (branch_node_rlc[is_s.idx()].expr(), mult[is_s.idx()].expr()) + .rlc_chain(branch.rlp.rlc_rlp(&mut cb.base, &r)); // Store the rlc of the branch - // TODO(Brecht): useless now, but useful when this work is spread over multiple rows + // TODO(Brecht): useless now, but useful when this work is spread over multiple + // rows branch.rlc_branch = cb.base.query_cell(); require!(branch.rlc_branch => branch.rlp.rlc_branch(&r)); // Store if this branch is hashed - branch.is_hashed = IsEqualGadget::construct(&mut cb.base, branch.rlp.len(), 32.expr()); + branch.is_hashed = + IsEqualGadget::construct(&mut cb.base, branch.rlp.len(), 32.expr()); // Update the branch node multiplier mult[is_s.idx()] = mult[is_s.idx()].expr() * mult_diff; // Calculate the length of the modified branch - mod_branch_len[is_s.idx()] = mod_branch_len[is_s.idx()].expr() + branch.rlp.len() * config.is_modified[node_index].expr(); + mod_branch_len[is_s.idx()] = mod_branch_len[is_s.idx()].expr() + + branch.rlp.len() * config.is_modified[node_index].expr(); // When in a placeholder branch, both branches are the same - the placeholder // branch and its parallel counterpart, which is not a @@ -340,7 +354,7 @@ impl BranchConfig { // We need to ensure that the only change in `S` and `C` proof occurs // at `modified_index` so that only a single change can be done. // TODO(Brecht): optimize, only insert the modified branch in the circuit - ifx!{not!(config.is_modified[node_index]) => { + ifx! {not!(config.is_modified[node_index]) => { let branch_s = config.branches[true.idx()][node_index].rlp.rlc_rlp(&mut cb.base, &r); let branch_c = config.branches[false.idx()][node_index].rlp.rlc_rlp(&mut cb.base, &r); require!(branch_s => branch_c); @@ -350,10 +364,13 @@ impl BranchConfig { // Number of bytes left needs to be 1 because ValueNode which occupies 1 byte require!(num_bytes_left[is_s.idx()] => 1); // TODO: acc currently doesn'thave branch ValueNode info (which 128 if nil) - branch_node_rlc[is_s.idx()] = (branch_node_rlc[is_s.idx()].expr(), mult[is_s.idx()].expr()).rlc_chain(RLP_NIL.expr()); + branch_node_rlc[is_s.idx()] = + (branch_node_rlc[is_s.idx()].expr(), mult[is_s.idx()].expr()) + .rlc_chain(RLP_NIL.expr()); // Check if the modified branch is empty, and so a placeholder leaf will follow - config.mod_branch_is_empty[is_s.idx()] = IsZeroGadget::construct(&mut cb.base, mod_branch_len[is_s.idx()].expr()); + config.mod_branch_is_empty[is_s.idx()] = + IsZeroGadget::construct(&mut cb.base, mod_branch_len[is_s.idx()].expr()); } // `is_modified` needs to be set to 1 at exactly 1 branch child @@ -362,7 +379,8 @@ impl BranchConfig { .collect::>(); require!(sum::expr(&is_modified_values) => 1); - // When there's a placeholder, `is_drifted` needs to be set to 1 at exactly 1 branch child + // When there's a placeholder, `is_drifted` needs to be set to 1 at exactly 1 + // branch child ifx! {or::expr(&[config.is_placeholder[true.idx()].expr(), config.is_placeholder[false.idx()].expr()]) => { let is_drifted_values = (0..ARITY).map(|rot| config.is_drifted[rot].expr()).collect::>(); require!(sum::expr(&is_drifted_values) => 1); @@ -371,7 +389,11 @@ impl BranchConfig { // Check if the branch is in its parent for is_s in [true, false] { let (rlc, num_bytes, is_not_hashed) = { - (branch_node_rlc[is_s.idx()].expr(), config.rlp_list[is_s.idx()].num_bytes(), config.is_not_hashed[is_s.idx()].expr()) + ( + branch_node_rlc[is_s.idx()].expr(), + config.rlp_list[is_s.idx()].num_bytes(), + config.is_not_hashed[is_s.idx()].expr(), + ) }; // TODO(Brecht): should not need is_extension check @@ -402,11 +424,13 @@ impl BranchConfig { // The nibble will be added as the least significant nibble, the multiplier needs to advance (1.expr(), r[0].expr()) }}; - let key_rlc_post_branch = key_rlc_post_ext.expr() + modified_index.expr() * nibble_mult.expr() * key_mult_post_ext.expr(); + let key_rlc_post_branch = key_rlc_post_ext.expr() + + modified_index.expr() * nibble_mult.expr() * key_mult_post_ext.expr(); let key_mult_post_branch = key_mult_post_ext.expr() * mult.expr(); // Set the new keys - // TODO(Brecht): Probably best to add checks that when placeholder another branch cannot follow etc.. + // TODO(Brecht): Probably best to add checks that when placeholder another + // branch cannot follow etc.. for is_s in [true, false] { ifx! {not!(config.is_placeholder[is_s.idx()].expr()) => { KeyData::store( @@ -530,14 +554,12 @@ impl BranchConfig { witness[offset + 18].bytes[34..68].to_owned(), ]; - self.is_extension.assign(region, base_offset, is_extension_node.scalar())?; + self.is_extension + .assign(region, base_offset, is_extension_node.scalar())?; - let key_data = self.key_data.witness_load( - region, - base_offset, - &pv.memory[key_memory(true)], - 0, - )?; + let key_data = + self.key_data + .witness_load(region, base_offset, &pv.memory[key_memory(true)], 0)?; let mut parent_data = vec![ParentDataWitness::default(); 2]; for is_s in [true, false] { parent_data[is_s.idx()] = self.parent_data[is_s.idx()].witness_load( @@ -548,34 +570,39 @@ impl BranchConfig { )?; } - pv.key_rlc_prev = pv.key_rlc; - pv.key_rlc_mult_prev = pv.key_rlc_mult; - let mut num_nibbles = key_data.num_nibbles; - let mut key_rlc_post_ext = pv.key_rlc; - let mut key_mult_post_ext = pv.key_rlc_mult; + let mut key_rlc_post_ext = key_data.rlc; + let mut key_mult_post_ext = key_data.mult; let mut is_key_odd = key_data.is_odd; /* Extension */ - let ext_rlp_key = self.ext_rlp_key.assign(region, base_offset, &ext_key_bytes[0])?; + let ext_rlp_key = self + .ext_rlp_key + .assign(region, base_offset, &ext_key_bytes[0])?; if is_extension_node { - let mut ext_mult= F::one(); + let mut ext_mult = F::one(); for _ in 0..ext_rlp_key.num_bytes_on_key_row() { ext_mult *= mpt_config.r; } self.ext_mult.assign(region, base_offset, ext_mult)?; - let first_byte_index = ext_rlp_key.rlp_list.num_rlp_bytes() + - if ext_rlp_key.rlp_list.is_short() { + let first_byte_index = ext_rlp_key.rlp_list.num_rlp_bytes() + + if ext_rlp_key.rlp_list.is_short() { ext_rlp_key.short_list_value.num_rlp_bytes() } else { ext_rlp_key.long_list_value.num_rlp_bytes() }; let ext_is_key_part_odd = ext_key_bytes[0][first_byte_index] >> 4 == 1; - self.ext_is_key_part_odd.assign(region, base_offset, ext_is_key_part_odd.scalar())?; + self.ext_is_key_part_odd + .assign(region, base_offset, ext_is_key_part_odd.scalar())?; - self.ext_is_not_hashed.assign(region, base_offset, ext_rlp_key.num_bytes().scalar(), HASH_WIDTH.scalar())?; + self.ext_is_not_hashed.assign( + region, + base_offset, + ext_rlp_key.num_bytes().scalar(), + HASH_WIDTH.scalar(), + )?; let mut key_len_mult = ext_rlp_key.key_len(); if !(is_key_odd && ext_is_key_part_odd) { @@ -594,24 +621,29 @@ impl BranchConfig { // Key RLC let (key_rlc_ext, _) = ext_rlp_key.ext_key_rlc( - pv.key_rlc_mult, + key_data.mult, ext_is_key_part_odd, !is_key_odd, ext_key_bytes.clone(), mpt_config.r, ); - key_rlc_post_ext = pv.key_rlc + key_rlc_ext; + key_rlc_post_ext = key_data.rlc + key_rlc_ext; // Key mult let mut ext_mult_key = 1.scalar(); for _ in 0..key_len_mult { ext_mult_key = ext_mult_key * mpt_config.r; } - self.ext_mult_key.assign(region, base_offset, ext_mult_key)?; - key_mult_post_ext = pv.key_rlc_mult * ext_mult_key; + self.ext_mult_key + .assign(region, base_offset, ext_mult_key)?; + key_mult_post_ext = key_data.mult * ext_mult_key; } for is_s in [true, false] { - self.ext_rlp_value[is_s.idx()].assign(region, base_offset, &ext_value_bytes[is_s.idx()])?; + self.ext_rlp_value[is_s.idx()].assign( + region, + base_offset, + &ext_value_bytes[is_s.idx()], + )?; } /* Branch */ @@ -620,15 +652,28 @@ impl BranchConfig { let rlp_list_witness = self.rlp_list[is_s.idx()].assign(region, base_offset, &rlp_bytes[is_s.idx()])?; - self.is_placeholder[is_s.idx()].assign(region, base_offset, is_placeholder[is_s.idx()].scalar())?; - self.is_not_hashed[is_s.idx()].assign(region, base_offset, rlp_list_witness.num_bytes().scalar(), HASH_WIDTH.scalar())?; + self.is_placeholder[is_s.idx()].assign( + region, + base_offset, + is_placeholder[is_s.idx()].scalar(), + )?; + self.is_not_hashed[is_s.idx()].assign( + region, + base_offset, + rlp_list_witness.num_bytes().scalar(), + HASH_WIDTH.scalar(), + )?; } let mut mod_node_hash_rlc = [0.scalar(); 2]; let mut branch_witnesses = vec![vec![RLPItemWitness::default(); ARITY]; 2]; for node_index in 0..ARITY { for is_s in [true, false] { - let child_witness = self.branches[is_s.idx()][node_index].rlp.assign(region, base_offset, &branch_bytes[is_s.idx()][node_index])?; + let child_witness = self.branches[is_s.idx()][node_index].rlp.assign( + region, + base_offset, + &branch_bytes[is_s.idx()][node_index], + )?; branch_witnesses[is_s.idx()][node_index] = child_witness.clone(); let mut node_mult_diff = F::one(); @@ -636,24 +681,57 @@ impl BranchConfig { node_mult_diff *= mpt_config.r; } - self.branches[is_s.idx()][node_index].mult.assign(region, base_offset, node_mult_diff)?; - self.branches[is_s.idx()][node_index].rlc_branch.assign(region, base_offset, child_witness.rlc_branch(mpt_config.r))?; - let is_hashed = self.branches[is_s.idx()][node_index].is_hashed.assign(region, base_offset, child_witness.len().scalar(), 32.scalar())?; + self.branches[is_s.idx()][node_index].mult.assign( + region, + base_offset, + node_mult_diff, + )?; + self.branches[is_s.idx()][node_index].rlc_branch.assign( + region, + base_offset, + child_witness.rlc_branch(mpt_config.r), + )?; + let is_hashed = self.branches[is_s.idx()][node_index].is_hashed.assign( + region, + base_offset, + child_witness.len().scalar(), + 32.scalar(), + )?; - let mod_pos = if is_placeholder[is_s.idx()] { drifted_index } else { modified_index }; + let mod_pos = if is_placeholder[is_s.idx()] { + drifted_index + } else { + modified_index + }; if mod_pos == node_index { mod_node_hash_rlc[is_s.idx()] = child_witness.rlc_branch(mpt_config.r); - self.mod_branch_rlc[is_s.idx()].assign(region, base_offset, mod_node_hash_rlc[is_s.idx()])?; + self.mod_branch_rlc[is_s.idx()].assign( + region, + base_offset, + mod_node_hash_rlc[is_s.idx()], + )?; self.mod_branch_is_hashed[is_s.idx()].assign(region, base_offset, is_hashed)?; } } - self.is_modified[node_index].assign(region, base_offset, (node_index == modified_index).scalar())?; - self.is_drifted[node_index].assign(region, base_offset, (node_index == drifted_index).scalar())?; + self.is_modified[node_index].assign( + region, + base_offset, + (node_index == modified_index).scalar(), + )?; + self.is_drifted[node_index].assign( + region, + base_offset, + (node_index == drifted_index).scalar(), + )?; } let mut is_placeholder_leaf = [0.scalar(); 2]; for is_s in [true, false] { - is_placeholder_leaf[is_s.idx()] = self.mod_branch_is_empty[is_s.idx()].assign(region, base_offset, branch_witnesses[is_s.idx()][modified_index].len().scalar())?; + is_placeholder_leaf[is_s.idx()] = self.mod_branch_is_empty[is_s.idx()].assign( + region, + base_offset, + branch_witnesses[is_s.idx()][modified_index].len().scalar(), + )?; } // one nibble is used for position in branch @@ -664,18 +742,18 @@ impl BranchConfig { // Update the key RLC and multiplier for the branch nibble. let (nibble_mult, mult): (F, F) = if is_key_odd { - // The nibble will be added as the most significant nibble using the same multiplier + // The nibble will be added as the most significant nibble using the same + // multiplier (16.scalar(), 1.scalar()) } else { - // The nibble will be added as the least significant nibble, the multiplier needs to advance + // The nibble will be added as the least significant nibble, the multiplier + // needs to advance (1.scalar(), mpt_config.r) }; - let key_rlc_post_branch = key_rlc_post_ext + F::from(modified_index as u64) * nibble_mult * key_mult_post_ext; + let key_rlc_post_branch = + key_rlc_post_ext + F::from(modified_index as u64) * nibble_mult * key_mult_post_ext; let key_mult_post_branch = key_mult_post_ext * mult; - pv.key_rlc = key_rlc_post_branch; - pv.key_rlc_mult = key_mult_post_branch; - // Set the new key for is_s in [true, false] { if !is_placeholder[is_s.idx()] { @@ -683,8 +761,8 @@ impl BranchConfig { region, base_offset, &mut pv.memory[key_memory(is_s)], - pv.key_rlc, - pv.key_rlc_mult, + key_rlc_post_branch, + key_mult_post_branch, num_nibbles, is_placeholder_leaf[true.idx()] == 1.scalar(), is_placeholder_leaf[false.idx()] == 1.scalar(), diff --git a/zkevm-circuits/src/mpt_circuit/helpers.rs b/zkevm-circuits/src/mpt_circuit/helpers.rs index dd2eee07aa..f6d3efd4c4 100644 --- a/zkevm-circuits/src/mpt_circuit/helpers.rs +++ b/zkevm-circuits/src/mpt_circuit/helpers.rs @@ -1,33 +1,34 @@ use std::any::Any; use crate::{ - _cb, circuit, + _cb, assign, circuit, circuit_tools::{ cell_manager::{Cell, CellManager, Trackable}, constraint_builder::{ Conditionable, ConstraintBuilder, RLCChainable, RLCChainableValue, RLCable, - RLCableValue, }, - gadgets::IsEqualGadget, - memory::MemoryBank, + gadgets::{IsEqualGadget, RequireNotZeroGadget}, + memory::{Memory, MemoryBank}, }, matchr, matchw, - mpt_circuit::param::{ - EMPTY_TRIE_HASH, KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN, RLP_LIST_LONG, - RLP_LIST_SHORT, RLP_SHORT, + mpt_circuit::{ + param::{EMPTY_TRIE_HASH, KEY_PREFIX_EVEN, KEY_TERMINAL_PREFIX_EVEN}, + rlp_gadgets::{get_ext_odd_nibble, get_terminal_odd_nibble}, }, + table::ProofType, util::Expr, }; use eth_types::Field; -use gadgets::util::{not, or, Scalar}; +use gadgets::util::{or, Scalar}; use halo2_proofs::{ - circuit::Region, + circuit::{Region, Value}, plonk::{Error, Expression, VirtualCells}, + poly::Rotation, }; use super::{ - param::{ - KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, RLP_LONG, + rlp_gadgets::{ + get_ext_odd_nibble_value, RLPListGadget, RLPListWitness, RLPValueGadget, RLPValueWitness, }, witness_row::MptWitnessRow, FixedTableTag, MPTConfig, MPTContext, ProofValues, @@ -68,441 +69,6 @@ pub(crate) trait Gadget { ) -> Result<(), Error>; } -#[derive(Clone, Debug, Default)] -pub(crate) struct RLPListGadget { - pub(crate) is_short: Cell, - pub(crate) is_long: Cell, - pub(crate) is_very_long: Cell, - pub(crate) is_string: Cell, - pub(crate) bytes: Vec>, -} - -#[derive(Clone, Debug, Default)] -pub(crate) struct RLPListWitness { - pub(crate) is_short: bool, - pub(crate) is_long: bool, - pub(crate) is_very_long: bool, - pub(crate) is_string: bool, - pub(crate) bytes: Vec, -} - -impl RLPListGadget { - pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { - // TODO(Brecht): add lookup - RLPListGadget { - is_short: cb.query_cell(), - is_long: cb.query_cell(), - is_very_long: cb.query_cell(), - is_string: cb.query_cell(), - bytes: bytes.to_vec(), - } - } - - pub(crate) fn assign( - &self, - region: &mut Region<'_, F>, - offset: usize, - bytes: &[u8], - ) -> Result { - const RLP_LIST_LONG_1: u8 = RLP_LIST_LONG + 1; - const RLP_LIST_LONG_2: u8 = RLP_LIST_LONG + 2; - - let mut is_short = false; - let mut is_long = false; - let mut is_very_long = false; - let mut is_string = false; - match bytes[0] { - RLP_LIST_SHORT..=RLP_LIST_LONG => is_short = true, - RLP_LIST_LONG_1 => is_long = true, - RLP_LIST_LONG_2 => is_very_long = true, - _ => is_string = true, - } - - self.is_short.assign(region, offset, F::from(is_short))?; - self.is_long.assign(region, offset, F::from(is_long))?; - self.is_very_long.assign(region, offset, F::from(is_very_long))?; - self.is_string.assign(region, offset, F::from(is_string))?; - - Ok(RLPListWitness { - is_short, - is_long, - is_very_long, - is_string, - bytes: bytes.to_vec(), - }) - } - - // Single RLP byte, length at most 55 bytes - pub(crate) fn is_list(&self) -> Expression { - not::expr(self.is_string.expr()) - } - - // Single RLP byte, length at most 55 bytes - pub(crate) fn is_short(&self) -> Expression { - self.is_short.expr() - } - - // RLP byte followed by the length in 1 byte, followed by the length - pub(crate) fn is_long(&self) -> Expression { - self.is_long.expr() - } - - // RLP byte followed by the length in 1 byte, followed by the length - pub(crate) fn is_very_long(&self) -> Expression { - self.is_very_long.expr() - } - - /// Number of RLP bytes - pub(crate) fn num_rlp_bytes(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.is_short() => 1.expr(), - self.is_long() => 2.expr(), - self.is_very_long() => 3.expr(), - } - }) - } - - /// Returns the total length of the list (including RLP bytes) - pub(crate) fn num_bytes(&self) -> Expression { - self.num_rlp_bytes() + self.len() - } - - /// Returns the length of the list (excluding RLP bytes) - pub(crate) fn len(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.is_short() => get_len_list_short::expr(self.bytes[0].expr()), - self.is_long() => self.bytes[1].expr(), - self.is_very_long() => self.bytes[1].expr() * 256.expr() + self.bytes[2].expr(), - } - }) - } - - pub(crate) fn rlc(&self, r: &[Expression]) -> (Expression, Expression) { - circuit!([meta, _cb!()], { - let value_rlc = - matchx! { - self.is_short() => self.bytes[1..].rlc(&r), - self.is_long() => self.bytes[2..].rlc(&r), - self.is_very_long() => self.bytes[3..].rlc(&r), - }; - (value_rlc, self.bytes.rlc(&r)) - }) - } - - /// Returns the rlc of the RLP bytes - pub(crate) fn rlc_rlp(&self, r: &[Expression]) -> (Expression, Expression) { - circuit!([meta, _cb!()], { - matchx! { - self.is_short() => (self.bytes[..1].rlc(&r), r[0].expr()), - self.is_long() => (self.bytes[..2].rlc(&r), r[1].expr()), - self.is_very_long() => (self.bytes[..3].rlc(&r), r[2].expr()), - } - }) - } -} - -impl RLPListWitness { - pub(crate) fn is_list(&self) -> bool { - !self.is_string - } - - // Single RLP byte, length at most 55 bytes - pub(crate) fn is_short(&self) -> bool { - self.is_short - } - - // RLP byte followed by the number of bytes in length, followed by the length - pub(crate) fn is_long(&self) -> bool { - self.is_long - } - - // RLP byte followed by the number of bytes in length, followed by the length - pub(crate) fn is_very_long(&self) -> bool { - self.is_very_long - } - - /// Number of RLP bytes - pub(crate) fn num_rlp_bytes(&self) -> usize { - matchr! { - self.is_short() => 1, - self.is_long() => 2, - self.is_very_long() => 3, - } - } - - /// Returns the total length of the list (including RLP bytes) - pub(crate) fn num_bytes(&self) -> usize { - matchr! { - self.is_short => get_num_bytes_list_short::value(self.bytes[0]), - self.is_long => 2 + (self.bytes[1] as usize), - self.is_very_long => 3 + (self.bytes[1] as usize) * 256 + (self.bytes[2] as usize), - } - } - - /// Returns the length of the list (excluding RLP bytes) - pub(crate) fn len(&self) -> usize { - matchr! { - self.is_short() => get_len_list_short::value(self.bytes[0]), - self.is_long() => self.bytes[1] as usize, - } - } - - /// RLC data - pub(crate) fn rlc(&self, r: F) -> (F, F) { - matchr! { - self.is_short() => { - (self.bytes.rlc_value(r), self.bytes.rlc_value(r)) - }, - self.is_long() => { - (self.bytes[1..].rlc_value(r), self.bytes.rlc_value(r)) - }, - _ => { - unreachable!(); - }, - } - } - - pub(crate) fn rlc_rlp(&self, r: F) -> F { - self.rlc(r).1 - } - - pub(crate) fn rlc_value(&self, r: F) -> F { - self.rlc(r).0 - } -} - -#[derive(Clone, Debug, Default)] -pub(crate) struct RLPValueGadget { - pub(crate) is_short: Cell, - pub(crate) is_long: Cell, - pub(crate) is_very_long: Cell, - pub(crate) is_list: Cell, - pub(crate) bytes: Vec>, -} - -#[derive(Clone, Debug, Default)] -pub(crate) struct RLPValueWitness { - pub(crate) is_short: bool, - pub(crate) is_long: bool, - pub(crate) is_very_long: bool, - pub(crate) is_list: bool, - pub(crate) bytes: Vec, -} - -impl RLPValueGadget { - pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { - // TODO(Brecht): add lookup - RLPValueGadget { - is_short: cb.query_cell(), - is_long: cb.query_cell(), - is_very_long: cb.query_cell(), - is_list: cb.query_cell(), - bytes: bytes.to_vec(), - } - } - - pub(crate) fn assign( - &self, - region: &mut Region<'_, F>, - offset: usize, - bytes: &[u8], - ) -> Result { - const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT - 1; - const RLP_LONG_EXCLUSIVE: u8 = RLP_LONG + 1; - const RLP_VALUE_MAX: u8 = RLP_LIST_SHORT - 1; - - let mut is_short = false; - let mut is_long = false; - let mut is_very_long = false; - let mut is_list = false; - match bytes[0] { - 0..=RLP_SHORT_INCLUSIVE => is_short = true, - RLP_SHORT..=RLP_LONG => is_long = true, - RLP_LONG_EXCLUSIVE..=RLP_VALUE_MAX => is_very_long = true, - _ => is_list = true, - } - - self.is_short.assign(region, offset, F::from(is_short))?; - self.is_long.assign(region, offset, F::from(is_long))?; - self.is_very_long - .assign(region, offset, F::from(is_very_long))?; - self.is_list - .assign(region, offset, F::from(is_list))?; - - Ok(RLPValueWitness { - is_short, - is_long, - is_very_long, - is_list, - bytes: bytes.to_vec(), - }) - } - - // Returns true if this is indeed a string RLP - pub(crate) fn is_string(&self) -> Expression { - not::expr(self.is_list.expr()) - } - - // Single RLP byte containing the byte value - pub(crate) fn is_short(&self) -> Expression { - self.is_short.expr() - } - - // Single RLP byte containing the length of the value - pub(crate) fn is_long(&self) -> Expression { - self.is_long.expr() - } - - // RLP byte containing the lenght of the length, - // followed by the length, followed by the actual data - pub(crate) fn is_very_long(&self) -> Expression { - self.is_very_long.expr() - } - - /// Number of RLP bytes - pub(crate) fn num_rlp_bytes(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.is_short() => 0.expr(), - self.is_long() => 1.expr(), - self.is_very_long() => 2.expr(), - } - }) - } - - /// Number of bytes in total (including RLP bytes) - pub(crate) fn num_bytes(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.is_short() => 1.expr(), - self.is_long() => get_num_bytes_short::expr(self.bytes[0].expr()), - self.is_very_long() => { - unreachablex!(); - 0.expr() - }, - } - }) - } - - /// Length of the value (excluding RLP bytes) - pub(crate) fn len(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.is_short() => 1.expr(), - self.is_long() => get_len_short::expr(self.bytes[0].expr()), - self.is_very_long() => { - unreachablex!(); - 0.expr() - }, - } - }) - } - - /// RLC data - pub(crate) fn rlc(&self, r: &[Expression]) -> (Expression, Expression) { - circuit!([meta, _cb!()], { - matchx! { - self.is_short() => { - let value_rlc = self.bytes[0].expr(); - (value_rlc.expr(), value_rlc.expr()) - }, - self.is_long() => { - let value_rlc = self.bytes[1..].rlc(&r); - (value_rlc, self.bytes.rlc(&r)) - }, - self.is_very_long() => { - unreachablex!(); - (0.expr(), 0.expr()) - }, - } - }) - } - - pub(crate) fn rlc_rlp(&self, r: &[Expression]) -> Expression { - self.rlc(r).1 - } - - pub(crate) fn rlc_value(&self, r: &[Expression]) -> Expression { - self.rlc(r).0 - } -} - -impl RLPValueWitness { - pub(crate) fn is_string(&self) -> bool { - !self.is_list - } - - // Single RLP byte containing the byte value - pub(crate) fn is_short(&self) -> bool { - self.is_short - } - - // Single RLP byte containing the length of the value - pub(crate) fn is_long(&self) -> bool { - self.is_long - } - - // RLP byte containing the lenght of the length, - // followed by the length, followed by the actual data - pub(crate) fn is_very_long(&self) -> bool { - self.is_very_long - } - - /// Number of RLP bytes - pub(crate) fn num_rlp_bytes(&self) -> usize { - matchr! { - self.is_short() => 0, - self.is_long() => 1, - self.is_very_long() => 2, - } - } - - /// Number of bytes in total (including RLP bytes) - pub(crate) fn num_bytes(&self) -> usize { - matchr! { - self.is_short() => 1, - self.is_long() => get_num_bytes_short::value(self.bytes[0]), - self.is_very_long() => unreachable!(), - } - } - - /// Length of the value (excluding RLP bytes) - pub(crate) fn len(&self) -> usize { - matchr! { - self.is_short() => 1, - self.is_long() => get_len_short::value(self.bytes[0]), - self.is_very_long() => unreachable!(), - } - } - - /// RLC data - pub(crate) fn rlc(&self, r: F) -> (F, F) { - matchr! { - self.is_short() => { - let value_rlc = self.bytes[0].scalar(); - (value_rlc, value_rlc) - }, - self.is_long() => { - let value_rlc = self.bytes[1..].rlc_value(r); - (value_rlc, self.bytes.rlc_value(r)) - }, - self.is_very_long() => { - unreachable!(); - }, - } - } - - pub(crate) fn rlc_rlp(&self, r: F) -> F { - self.rlc(r).1 - } - - pub(crate) fn rlc_value(&self, r: F) -> F { - self.rlc(r).0 - } -} - #[derive(Clone, Debug, Default)] pub(crate) struct LeafKeyGadget { pub(crate) rlp_list: RLPListGadget, @@ -523,6 +89,8 @@ pub(crate) struct LeafKeyWitness { impl LeafKeyGadget { pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { + // TODO(Brecht): move list RLP bytes out so the key always starts at the same + // position LeafKeyGadget { rlp_list: RLPListGadget::construct(cb, bytes), short_list_value: RLPValueGadget::construct(cb, &bytes[1..]), @@ -580,7 +148,6 @@ impl LeafKeyGadget { key_mult_prev: Expression, is_key_odd: Expression, key_mult_first_even: Expression, - requires_longer_than_55: bool, r: &[Expression], ) -> Expression { circuit!([meta, cb], { @@ -606,7 +173,7 @@ impl LeafKeyGadget { calc_rlc(cb, &self.bytes[1..2], is_odd) }, self.short_list_value.is_long() => { - // First key byte is at `s_main.bytes[0]`. + // First key byte is at `bytes[2]`. calc_rlc(cb, &self.bytes[2..35], is_key_odd.expr()) }, } @@ -620,11 +187,7 @@ impl LeafKeyGadget { calc_rlc(cb, &self.bytes[2..3], is_odd) }, self.long_list_value.is_long() => { - if requires_longer_than_55 { - // rlp1 needs to be 248. - require!(self.bytes[0] => (RLP_LIST_LONG + 1)); - } - // First key byte is at `s_main.bytes[1]`. + // First key byte is at `bytes[3]`. calc_rlc(cb, &self.bytes[3..36], is_key_odd.expr()) }, } @@ -668,7 +231,8 @@ impl LeafKeyGadget { r, ) }; - // TODO(Brecht): somehow the start index doesn't dependend on the list is_short/is_long? + // TODO(Brecht): somehow the start index doesn't dependend on the list + // is_short/is_long? matchx! { and::expr(&[is_long.expr(), not!(is_key_odd)]) => { // Here we need to multiply nibbles over bytes with different r's so we need to rlc over separate nibbles. @@ -770,20 +334,6 @@ impl LeafKeyGadget { } } -pub(crate) fn compute_acc_and_mult( - row: &[u8], - acc: &mut F, - mult: &mut F, - start: usize, - len: usize, - r: F, -) { - for i in 0..len { - *acc += F::from(row[start + i] as u64) * *mult; - *mult *= r; - } -} - impl LeafKeyWitness { /// Returns the number of bytes used by the list (including RLP bytes) pub(crate) fn num_bytes(&self) -> usize { @@ -875,10 +425,8 @@ impl LeafKeyWitness { self.long_list_value.is_long(), ) }; - let mult_first_odd = if is_key_odd { 1.scalar() } else { 16.scalar() }; - let calc_rlc = | - bytes: &[F], - key_mult_first_even: F| { + let mult_first_odd = if is_key_odd { 1.scalar() } else { 16.scalar() }; + let calc_rlc = |bytes: &[F], key_mult_first_even: F| { ext_key_rlc_value( bytes, key_mult_prev, @@ -888,7 +436,8 @@ impl LeafKeyWitness { r, ) }; - // TODO(Brecht): somehow the start index doesn't dependend on the list is_short/is_long? + // TODO(Brecht): somehow the start index doesn't dependend on the list + // is_short/is_long? matchr! { is_long && !is_key_odd => { // Here we need to multiply nibbles over bytes with different r's so we need to rlc over separate nibbles. @@ -1082,7 +631,7 @@ impl KeyData { is_odd: values[3] != F::zero(), is_placeholder_leaf_s: values[4] != F::zero(), is_placeholder_leaf_c: values[5] != F::zero(), - placeholder_nibble: values[6].get_lower_32() as usize, + placeholder_nibble: values[6].get_lower_32() as usize, placeholder_is_odd: values[7] != F::zero(), parent_rlc: values[8], parent_mult: values[9], @@ -1254,7 +803,10 @@ pub(crate) fn ext_key_rlc_value( ) -> (F, F) { // Add the odd nibble first if we have one. let (rlc, mult) = if is_odd { - (get_ext_odd_nibble_value(bytes[0]) * key_mult_prev * rlc_mult_first_odd, key_mult_first_odd) + ( + get_ext_odd_nibble_value(bytes[0]) * key_mult_prev * rlc_mult_first_odd, + key_mult_first_odd, + ) } else { assert!(bytes[0] == KEY_PREFIX_EVEN.scalar()); (0.scalar(), 1.scalar()) @@ -1262,88 +814,17 @@ pub(crate) fn ext_key_rlc_value( (rlc, key_mult_prev * mult).rlc_chain_value_f(&bytes[1..], r) } -pub(crate) fn get_terminal_odd_nibble(byte: Expression) -> Expression { - // The odd nible is stored in the same byte as the prefix - byte - KEY_TERMINAL_PREFIX_ODD.expr() -} - -pub(crate) fn get_ext_odd_nibble(byte: Expression) -> Expression { - // The odd nible is stored in the same byte as the prefix - byte - KEY_PREFIX_ODD.expr() -} - -pub(crate) fn get_ext_odd_nibble_value(byte: F) -> F { - // The odd nible is stored in the same byte as the prefix - byte - F::from(KEY_PREFIX_ODD as u64) -} - -// A single RLP byte -pub(crate) mod get_len_short { - use crate::mpt_circuit::param::RLP_SHORT; - use eth_types::Field; - use gadgets::util::Expr; - use halo2_proofs::plonk::Expression; - - pub(crate) fn expr(byte: Expression) -> Expression { - byte - RLP_SHORT.expr() - } - pub(crate) fn value(byte: u8) -> usize { - (byte - RLP_SHORT) as usize - } -} - -// A single RLP byte + the encoded length -pub(crate) mod get_num_bytes_short { - use super::get_len_short; - use eth_types::Field; - use gadgets::util::Expr; - use halo2_proofs::plonk::Expression; - - pub(crate) fn expr(byte: Expression) -> Expression { - 1.expr() + get_len_short::expr(byte) - } - pub(crate) fn value(byte: u8) -> usize { - 1 + get_len_short::value(byte) - } -} - -pub(crate) mod get_len_list_short { - use crate::mpt_circuit::param::RLP_LIST_SHORT; - use eth_types::Field; - use gadgets::util::Expr; - use halo2_proofs::plonk::Expression; - - pub(crate) fn expr(byte: Expression) -> Expression { - byte - RLP_LIST_SHORT.expr() - } - pub(crate) fn value(byte: u8) -> usize { - (byte - RLP_LIST_SHORT) as usize - } -} - -// A single RLP byte + the encoded length -pub(crate) mod get_num_bytes_list_short { - use super::get_len_list_short; - use eth_types::Field; - use gadgets::util::Expr; - use halo2_proofs::plonk::Expression; - - pub(crate) fn expr(byte: Expression) -> Expression { - 1.expr() + get_len_list_short::expr(byte) - } - pub(crate) fn value(byte: u8) -> usize { - 1 + get_len_list_short::value(byte) - } -} - // Returns the number of nibbles stored in a key value pub(crate) mod num_nibbles { - use crate::{_cb, circuit}; use crate::circuit_tools::constraint_builder::ConstraintBuilder; + use crate::{_cb, circuit}; use eth_types::Field; use halo2_proofs::plonk::Expression; - pub(crate) fn expr(key_len: Expression, is_key_odd: Expression) -> Expression { + pub(crate) fn expr( + key_len: Expression, + is_key_odd: Expression, + ) -> Expression { circuit!([meta, _cb!()], { ifx! {is_key_odd => { key_len.expr() * 2.expr() - 1.expr() @@ -1403,9 +884,11 @@ pub struct MPTConstraintBuilder { pub range_s: Vec<(Expression, Expression)>, } -/// Length is set in the configuration of the rows where unused columns might appear (and which need to be checked to be zeros). -/// From the vector of lengths, the expression is computed that returns the length of the used columns for each row. -/// This enables a generalised constraint (for all rows) for the values in the unused columns being zeros in mpt.rs. +/// Length is set in the configuration of the rows where unused columns might +/// appear (and which need to be checked to be zeros). From the vector of +/// lengths, the expression is computed that returns the length of the used +/// columns for each row. This enables a generalised constraint (for all rows) +/// for the values in the unused columns being zeros in mpt.rs. impl MPTConstraintBuilder { const DEFAULT_LENGTH_S: usize = 34; const DEFAULT_LENGTH_C: usize = 32; @@ -1522,159 +1005,197 @@ impl IsEmptyTreeGadget { } } - +/// Handles drifted leaves #[derive(Clone, Debug, Default)] -pub(crate) struct RLPItemGadget { - pub(crate) value: RLPValueGadget, - pub(crate) list: RLPListGadget, +pub struct DriftedGadget { + drifted_rlp_key: LeafKeyGadget, + drifted_mult: Cell, } -#[derive(Clone, Debug, Default)] -pub(crate) struct RLPItemWitness { - pub(crate) value: RLPValueWitness, - pub(crate) list: RLPListWitness, - pub(crate) bytes: Vec, -} - -impl RLPItemGadget { - pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { - RLPItemGadget { - value: RLPValueGadget::construct(cb, bytes), - list: RLPListGadget::construct(cb, bytes), - } +impl DriftedGadget { + pub(crate) fn construct( + cb: &mut MPTConstraintBuilder, + parent_data: &[ParentData], + key_data: &[KeyData], + key_rlc: &[Expression], + leaf_no_key_rlc: &[Expression], + drifted_bytes: &[Expression], + r: &[Expression], + ) -> Self { + let mut config = DriftedGadget::default(); + circuit!([meta, cb.base], { + ifx! {parent_data[true.idx()].is_placeholder.expr() + parent_data[false.idx()].is_placeholder.expr() => { + config.drifted_rlp_key = LeafKeyGadget::construct(&mut cb.base, drifted_bytes); + config.drifted_mult = cb.base.query_cell(); + for is_s in [true, false] { + ifx! {parent_data[is_s.idx()].is_placeholder.expr() => { + // We need the intermediate key RLC right before `drifted_index` is added to it. + let (key_rlc_prev, key_mult_prev, placeholder_nibble, placeholder_is_odd) = ( + key_data[is_s.idx()].parent_rlc.expr(), + key_data[is_s.idx()].parent_mult.expr(), + key_data[is_s.idx()].placeholder_nibble.expr(), + key_data[is_s.idx()].placeholder_is_odd.expr(), + ); + + // TODO(Brecht): Length can change it seems so need to add RLP consistency checks? + + // Calculate the drifted key RLC + let drifted_key_rlc = key_rlc_prev.expr() + + drifted_nibble_rlc(&mut cb.base, placeholder_nibble.expr(), key_mult_prev.expr(), placeholder_is_odd.expr()) + + config.drifted_rlp_key.leaf_key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), &r); + + // Check zero bytes and mult_diff + require!((FixedTableTag::RMult, config.drifted_rlp_key.num_bytes_on_key_row(), config.drifted_mult.expr()) => @"fixed"); + cb.set_length(config.drifted_rlp_key.num_bytes_on_key_row()); + + // Check that the drifted leaf is unchanged and is stored at `drifted_index`. + // Complete the drifted leaf rlc by adding the bytes on the value row + let drifted_rlc = (config.drifted_rlp_key.rlc(&r), config.drifted_mult.expr()).rlc_chain(leaf_no_key_rlc[is_s.idx()].expr()); + // The key of the drifted leaf needs to match the key of the leaf + require!(key_rlc[is_s.idx()].expr() => drifted_key_rlc); + // The drifted leaf needs to be stored in the branch at `drifted_index`. + require!((1, drifted_rlc, config.drifted_rlp_key.num_bytes(), parent_data[is_s.idx()].placeholder_rlc.expr()) => @"keccak"); + } + }} + }} + config + }) } pub(crate) fn assign( &self, region: &mut Region<'_, F>, offset: usize, - bytes: &[u8], - ) -> Result { - let value_witness = self.value.assign(region, offset, bytes)?; - let list_witness = self.list.assign(region, offset, bytes)?; - - if value_witness.is_string() && list_witness.is_list() { - println!("{:?}", bytes) - } - assert!(!(value_witness.is_string() && list_witness.is_list())); - - Ok(RLPItemWitness { - value: value_witness, - list: list_witness, - bytes: bytes.to_vec(), - }) - } - - // Single RLP byte containing the byte value - pub(crate) fn is_short(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.value.is_string() => self.value.is_short(), - self.list.is_list() => self.list.is_short(), - } - }) - } - - // Single RLP byte containing the length of the value - pub(crate) fn is_long(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.value.is_string() => self.value.is_long(), - self.list.is_list() => self.list.is_long(), - } - }) - } - - // RLP byte containing the lenght of the length, - // followed by the length, followed by the actual data - pub(crate) fn is_very_long(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.value.is_string() => self.value.is_very_long(), - self.list.is_list() => self.list.is_very_long(), - } - }) - } + parent_data: &[ParentDataWitness], + drifted_bytes: &[u8], + r: F, + ) -> Result<(), Error> { + if parent_data[true.idx()].is_placeholder || parent_data[false.idx()].is_placeholder { + let drifted_key_witness = self.drifted_rlp_key.assign(region, offset, drifted_bytes)?; - /// Number of RLP bytes - pub(crate) fn num_rlp_bytes(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.value.is_string() => self.value.num_rlp_bytes(), - self.list.is_list() => self.list.num_rlp_bytes(), - } - }) - } + let (_, leaf_mult) = drifted_key_witness.rlc_leaf(r); - /// Number of bytes in total (including RLP bytes) - pub(crate) fn num_bytes(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.value.is_string() => self.value.num_bytes(), - self.list.is_list() => self.list.num_bytes(), - } - }) + self.drifted_mult.assign(region, offset, leaf_mult)?; + } + Ok(()) } +} - /// Length of the value (excluding RLP bytes) - pub(crate) fn len(&self) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.value.is_string() => self.value.len(), - self.list.is_list() => self.list.len(), - } - }) - } +/// Handles wrong leaves +#[derive(Clone, Debug, Default)] +pub struct WrongGadget { + key_data_w: KeyData, + wrong_rlp_key: LeafKeyGadget, + wrong_mult: Cell, + is_wrong_leaf: Cell, + check_is_wrong_leaf: RequireNotZeroGadget, +} - /// RLC data - pub(crate) fn rlc(&self, cb: &mut ConstraintBuilder, r: &[Expression]) -> (Expression, Expression) { - circuit!([meta, cb], { - matchx! { - self.value.is_string() => self.value.rlc(r), - self.list.is_list() => self.list.rlc(r), - } +impl WrongGadget { + pub(crate) fn construct( + meta: &mut VirtualCells<'_, F>, + cb: &mut MPTConstraintBuilder, + ctx: MPTContext, + is_non_existing: Expression, + rlp_key: &[LeafKeyGadget], + key_rlc: &[Expression], + wrong_bytes: &[Expression], + wrong_offset: usize, + for_placeholder_s: bool, + r: &[Expression], + ) -> Self { + // TODO(Brecht): strangely inconsistent between storage/account (see the need of + // for_placeholder_s). Something more similar to how the drifted key + // works (s and c cases separately makes more sense to me). + let mut config = WrongGadget::default(); + circuit!([meta, cb.base], { + config.is_wrong_leaf = cb.base.query_cell(); + // Make sure is_wrong_leaf is boolean + require!(config.is_wrong_leaf => bool); + ifx! {is_non_existing => { + // Get the previous key data + // TODO(Brecht): This always loads the keys from s? But some other data comes from c... + config.key_data_w = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 1.expr()); + ifx! {config.is_wrong_leaf => { + // Calculate the key + config.wrong_rlp_key = LeafKeyGadget::construct(&mut cb.base, &wrong_bytes); + let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.leaf_key_rlc( + &mut cb.base, + config.key_data_w.mult.expr(), + config.key_data_w.is_odd.expr(), + 1.expr(), + r, + ); + + // Check that it's the key as requested in the lookup + let key_rlc_lookup = a!(ctx.mpt_table.key_rlc, wrong_offset); + require!(key_rlc_lookup => key_rlc_wrong); + + // Now make sure this address is different than the one of the leaf + config.check_is_wrong_leaf = RequireNotZeroGadget::construct(&mut cb.base, key_rlc_lookup - key_rlc[for_placeholder_s.idx()].expr()); + // Make sure the lengths of the keys are the same + require!(config.wrong_rlp_key.key_len() => rlp_key[for_placeholder_s.idx()].key_len()); + // RLC bytes zero check + cb.set_length(config.wrong_rlp_key.num_bytes_on_key_row()); + } elsex { + // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. + if for_placeholder_s { + require!(config.key_data_w.is_placeholder_leaf_s => true); + } else { + require!(config.key_data_w.is_placeholder_leaf_c => true); + } + }} + } elsex { + // is_wrong_leaf needs to be false when not in non_existing_account proof + require!(config.is_wrong_leaf => false); + }} + config }) } - pub(crate) fn rlc_rlp(&self, cb: &mut ConstraintBuilder, r: &[Expression]) -> Expression { - self.rlc(cb, r).1 - } - - pub(crate) fn rlc_value(&self, cb: &mut ConstraintBuilder, r: &[Expression]) -> Expression { - self.rlc(cb, r).0 - } - - pub(crate) fn rlc_branch(&self, r: &[Expression]) -> Expression { - circuit!([meta, _cb!()], { - matchx! { - self.value.is_string() => self.value.rlc(r).0, - self.list.is_list() => self.list.rlc(r).1, + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + ctx: &MPTConfig, + is_non_existing: bool, + memory: &mut Memory, + key_rlc: &[F], + wrong_bytes: &[u8], + wrong_offset: usize, + row_key: [&MptWitnessRow; 2], + for_placeholder_s: bool, + proof_type: ProofType, + r: F, + ) -> Result<(), Error> { + if is_non_existing { + let key_data_w = + self.key_data_w + .witness_load(region, offset, &mut memory[key_memory(true)], 1)?; + + // TODO(Brecht): Change how the witness is generated + let is_wrong_leaf = wrong_bytes[0] != 0; + self.is_wrong_leaf + .assign(region, offset, F::from(is_wrong_leaf))?; + + if is_wrong_leaf { + let mut bytes = wrong_bytes.to_vec(); + bytes[0] = row_key[for_placeholder_s.idx()].bytes[0]; + + let wrong_witness = self.wrong_rlp_key.assign(region, offset, &bytes)?; + let (key_rlc_wrong, _) = + wrong_witness.leaf_key_rlc(key_data_w.rlc, key_data_w.mult, r); + + self.check_is_wrong_leaf.assign( + region, + offset, + key_rlc_wrong - key_rlc[for_placeholder_s.idx()], + )?; + + assign!(region, (ctx.mpt_table.key_rlc, wrong_offset) => key_rlc_wrong)?; } - }) - } -} - -impl RLPItemWitness { - /// Number of bytes in total (including RLP bytes) - pub(crate) fn num_bytes(&self) -> usize { - matchr! { - self.value.is_string() => self.value.num_bytes(), - self.list.is_list() => self.list.num_bytes(), - } - } - - /// Length of the value (excluding RLP bytes) - pub(crate) fn len(&self) -> usize { - matchr! { - self.value.is_string() => self.value.len(), - self.list.is_list() => self.list.len(), - } - } - - pub(crate) fn rlc_branch(&self, r: F) -> F { - matchr! { - self.value.is_string() => self.value.rlc(r).0, - self.list.is_list() => self.list.rlc(r).1, + assign!(region, (ctx.proof_type.proof_type, wrong_offset) => proof_type.scalar())?; } + Ok(()) } -} \ No newline at end of file +} diff --git a/zkevm-circuits/src/mpt_circuit/rlp_gadgets.rs b/zkevm-circuits/src/mpt_circuit/rlp_gadgets.rs new file mode 100644 index 0000000000..b19ec632c8 --- /dev/null +++ b/zkevm-circuits/src/mpt_circuit/rlp_gadgets.rs @@ -0,0 +1,722 @@ +use crate::{ + _cb, circuit, + circuit_tools::{ + cell_manager::Cell, + constraint_builder::{ConstraintBuilder, RLCable, RLCableValue}, + }, + matchr, matchw, + mpt_circuit::param::{RLP_LIST_LONG, RLP_LIST_SHORT, RLP_SHORT}, + util::Expr, +}; +use eth_types::Field; +use gadgets::util::{not, Scalar}; +use halo2_proofs::{ + circuit::Region, + plonk::{Error, Expression}, +}; + +use super::param::{KEY_PREFIX_ODD, KEY_TERMINAL_PREFIX_ODD, RLP_LONG}; + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPListGadget { + pub(crate) is_short: Cell, + pub(crate) is_long: Cell, + pub(crate) is_very_long: Cell, + pub(crate) is_string: Cell, + pub(crate) bytes: Vec>, +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPListWitness { + pub(crate) is_short: bool, + pub(crate) is_long: bool, + pub(crate) is_very_long: bool, + pub(crate) is_string: bool, + pub(crate) bytes: Vec, +} + +impl RLPListGadget { + pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { + // TODO(Brecht): add lookup + RLPListGadget { + is_short: cb.query_cell(), + is_long: cb.query_cell(), + is_very_long: cb.query_cell(), + is_string: cb.query_cell(), + bytes: bytes.to_vec(), + } + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + bytes: &[u8], + ) -> Result { + const RLP_LIST_LONG_1: u8 = RLP_LIST_LONG + 1; + const RLP_LIST_LONG_2: u8 = RLP_LIST_LONG + 2; + + let mut is_short = false; + let mut is_long = false; + let mut is_very_long = false; + let mut is_string = false; + match bytes[0] { + RLP_LIST_SHORT..=RLP_LIST_LONG => is_short = true, + RLP_LIST_LONG_1 => is_long = true, + RLP_LIST_LONG_2 => is_very_long = true, + _ => is_string = true, + } + + self.is_short.assign(region, offset, F::from(is_short))?; + self.is_long.assign(region, offset, F::from(is_long))?; + self.is_very_long + .assign(region, offset, F::from(is_very_long))?; + self.is_string.assign(region, offset, F::from(is_string))?; + + Ok(RLPListWitness { + is_short, + is_long, + is_very_long, + is_string, + bytes: bytes.to_vec(), + }) + } + + // Single RLP byte, length at most 55 bytes + pub(crate) fn is_list(&self) -> Expression { + not::expr(self.is_string.expr()) + } + + // Single RLP byte, length at most 55 bytes + pub(crate) fn is_short(&self) -> Expression { + self.is_short.expr() + } + + // RLP byte followed by the length in 1 byte, followed by the length + pub(crate) fn is_long(&self) -> Expression { + self.is_long.expr() + } + + // RLP byte followed by the length in 1 byte, followed by the length + pub(crate) fn is_very_long(&self) -> Expression { + self.is_very_long.expr() + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => 1.expr(), + self.is_long() => 2.expr(), + self.is_very_long() => 3.expr(), + } + }) + } + + /// Returns the total length of the list (including RLP bytes) + pub(crate) fn num_bytes(&self) -> Expression { + self.num_rlp_bytes() + self.len() + } + + /// Returns the length of the list (excluding RLP bytes) + pub(crate) fn len(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => get_len_list_short::expr(self.bytes[0].expr()), + self.is_long() => self.bytes[1].expr(), + self.is_very_long() => self.bytes[1].expr() * 256.expr() + self.bytes[2].expr(), + } + }) + } + + pub(crate) fn rlc(&self, r: &[Expression]) -> (Expression, Expression) { + circuit!([meta, _cb!()], { + let value_rlc = matchx! { + self.is_short() => self.bytes[1..].rlc(&r), + self.is_long() => self.bytes[2..].rlc(&r), + self.is_very_long() => self.bytes[3..].rlc(&r), + }; + (value_rlc, self.bytes.rlc(&r)) + }) + } + + /// Returns the rlc of the RLP bytes + pub(crate) fn rlc_rlp(&self, r: &[Expression]) -> (Expression, Expression) { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => (self.bytes[..1].rlc(&r), r[0].expr()), + self.is_long() => (self.bytes[..2].rlc(&r), r[1].expr()), + self.is_very_long() => (self.bytes[..3].rlc(&r), r[2].expr()), + } + }) + } +} + +impl RLPListWitness { + pub(crate) fn is_list(&self) -> bool { + !self.is_string + } + + // Single RLP byte, length at most 55 bytes + pub(crate) fn is_short(&self) -> bool { + self.is_short + } + + // RLP byte followed by the number of bytes in length, followed by the length + pub(crate) fn is_long(&self) -> bool { + self.is_long + } + + // RLP byte followed by the number of bytes in length, followed by the length + pub(crate) fn is_very_long(&self) -> bool { + self.is_very_long + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> usize { + matchr! { + self.is_short() => 1, + self.is_long() => 2, + self.is_very_long() => 3, + } + } + + /// Returns the total length of the list (including RLP bytes) + pub(crate) fn num_bytes(&self) -> usize { + matchr! { + self.is_short => get_num_bytes_list_short::value(self.bytes[0]), + self.is_long => 2 + (self.bytes[1] as usize), + self.is_very_long => 3 + (self.bytes[1] as usize) * 256 + (self.bytes[2] as usize), + } + } + + /// Returns the length of the list (excluding RLP bytes) + pub(crate) fn len(&self) -> usize { + matchr! { + self.is_short() => get_len_list_short::value(self.bytes[0]), + self.is_long() => self.bytes[1] as usize, + } + } + + /// RLC data + pub(crate) fn rlc(&self, r: F) -> (F, F) { + matchr! { + self.is_short() => { + (self.bytes.rlc_value(r), self.bytes.rlc_value(r)) + }, + self.is_long() => { + (self.bytes[1..].rlc_value(r), self.bytes.rlc_value(r)) + }, + _ => { + unreachable!(); + }, + } + } + + pub(crate) fn rlc_rlp(&self, r: F) -> F { + self.rlc(r).1 + } + + pub(crate) fn rlc_value(&self, r: F) -> F { + self.rlc(r).0 + } +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPValueGadget { + pub(crate) is_short: Cell, + pub(crate) is_long: Cell, + pub(crate) is_very_long: Cell, + pub(crate) is_list: Cell, + pub(crate) bytes: Vec>, +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPValueWitness { + pub(crate) is_short: bool, + pub(crate) is_long: bool, + pub(crate) is_very_long: bool, + pub(crate) is_list: bool, + pub(crate) bytes: Vec, +} + +impl RLPValueGadget { + pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { + // TODO(Brecht): add lookup + RLPValueGadget { + is_short: cb.query_cell(), + is_long: cb.query_cell(), + is_very_long: cb.query_cell(), + is_list: cb.query_cell(), + bytes: bytes.to_vec(), + } + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + bytes: &[u8], + ) -> Result { + const RLP_SHORT_INCLUSIVE: u8 = RLP_SHORT - 1; + const RLP_LONG_EXCLUSIVE: u8 = RLP_LONG + 1; + const RLP_VALUE_MAX: u8 = RLP_LIST_SHORT - 1; + + let mut is_short = false; + let mut is_long = false; + let mut is_very_long = false; + let mut is_list = false; + match bytes[0] { + 0..=RLP_SHORT_INCLUSIVE => is_short = true, + RLP_SHORT..=RLP_LONG => is_long = true, + RLP_LONG_EXCLUSIVE..=RLP_VALUE_MAX => is_very_long = true, + _ => is_list = true, + } + + self.is_short.assign(region, offset, F::from(is_short))?; + self.is_long.assign(region, offset, F::from(is_long))?; + self.is_very_long + .assign(region, offset, F::from(is_very_long))?; + self.is_list.assign(region, offset, F::from(is_list))?; + + Ok(RLPValueWitness { + is_short, + is_long, + is_very_long, + is_list, + bytes: bytes.to_vec(), + }) + } + + // Returns true if this is indeed a string RLP + pub(crate) fn is_string(&self) -> Expression { + not::expr(self.is_list.expr()) + } + + // Single RLP byte containing the byte value + pub(crate) fn is_short(&self) -> Expression { + self.is_short.expr() + } + + // Single RLP byte containing the length of the value + pub(crate) fn is_long(&self) -> Expression { + self.is_long.expr() + } + + // RLP byte containing the lenght of the length, + // followed by the length, followed by the actual data + pub(crate) fn is_very_long(&self) -> Expression { + self.is_very_long.expr() + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => 0.expr(), + self.is_long() => 1.expr(), + self.is_very_long() => 2.expr(), + } + }) + } + + /// Number of bytes in total (including RLP bytes) + pub(crate) fn num_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => 1.expr(), + self.is_long() => get_num_bytes_short::expr(self.bytes[0].expr()), + self.is_very_long() => { + unreachablex!(); + 0.expr() + }, + } + }) + } + + /// Length of the value (excluding RLP bytes) + pub(crate) fn len(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => 1.expr(), + self.is_long() => get_len_short::expr(self.bytes[0].expr()), + self.is_very_long() => { + unreachablex!(); + 0.expr() + }, + } + }) + } + + /// RLC data + pub(crate) fn rlc(&self, r: &[Expression]) -> (Expression, Expression) { + circuit!([meta, _cb!()], { + matchx! { + self.is_short() => { + let value_rlc = self.bytes[0].expr(); + (value_rlc.expr(), value_rlc.expr()) + }, + self.is_long() => { + let value_rlc = self.bytes[1..].rlc(&r); + (value_rlc, self.bytes.rlc(&r)) + }, + self.is_very_long() => { + unreachablex!(); + (0.expr(), 0.expr()) + }, + } + }) + } + + pub(crate) fn rlc_rlp(&self, r: &[Expression]) -> Expression { + self.rlc(r).1 + } + + pub(crate) fn rlc_value(&self, r: &[Expression]) -> Expression { + self.rlc(r).0 + } +} + +impl RLPValueWitness { + pub(crate) fn is_string(&self) -> bool { + !self.is_list + } + + // Single RLP byte containing the byte value + pub(crate) fn is_short(&self) -> bool { + self.is_short + } + + // Single RLP byte containing the length of the value + pub(crate) fn is_long(&self) -> bool { + self.is_long + } + + // RLP byte containing the lenght of the length, + // followed by the length, followed by the actual data + pub(crate) fn is_very_long(&self) -> bool { + self.is_very_long + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> usize { + matchr! { + self.is_short() => 0, + self.is_long() => 1, + self.is_very_long() => 2, + } + } + + /// Number of bytes in total (including RLP bytes) + pub(crate) fn num_bytes(&self) -> usize { + matchr! { + self.is_short() => 1, + self.is_long() => get_num_bytes_short::value(self.bytes[0]), + self.is_very_long() => unreachable!(), + } + } + + /// Length of the value (excluding RLP bytes) + pub(crate) fn len(&self) -> usize { + matchr! { + self.is_short() => 1, + self.is_long() => get_len_short::value(self.bytes[0]), + self.is_very_long() => unreachable!(), + } + } + + /// RLC data + pub(crate) fn rlc(&self, r: F) -> (F, F) { + matchr! { + self.is_short() => { + let value_rlc = self.bytes[0].scalar(); + (value_rlc, value_rlc) + }, + self.is_long() => { + let value_rlc = self.bytes[1..].rlc_value(r); + (value_rlc, self.bytes.rlc_value(r)) + }, + self.is_very_long() => { + unreachable!(); + }, + } + } + + pub(crate) fn rlc_rlp(&self, r: F) -> F { + self.rlc(r).1 + } + + pub(crate) fn rlc_value(&self, r: F) -> F { + self.rlc(r).0 + } +} + +pub(crate) fn get_terminal_odd_nibble(byte: Expression) -> Expression { + // The odd nible is stored in the same byte as the prefix + byte - KEY_TERMINAL_PREFIX_ODD.expr() +} + +pub(crate) fn get_ext_odd_nibble(byte: Expression) -> Expression { + // The odd nible is stored in the same byte as the prefix + byte - KEY_PREFIX_ODD.expr() +} + +pub(crate) fn get_ext_odd_nibble_value(byte: F) -> F { + // The odd nible is stored in the same byte as the prefix + byte - F::from(KEY_PREFIX_ODD as u64) +} + +// A single RLP byte +pub(crate) mod get_len_short { + use crate::mpt_circuit::param::RLP_SHORT; + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::plonk::Expression; + + pub(crate) fn expr(byte: Expression) -> Expression { + byte - RLP_SHORT.expr() + } + pub(crate) fn value(byte: u8) -> usize { + (byte - RLP_SHORT) as usize + } +} + +// A single RLP byte + the encoded length +pub(crate) mod get_num_bytes_short { + use super::get_len_short; + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::plonk::Expression; + + pub(crate) fn expr(byte: Expression) -> Expression { + 1.expr() + get_len_short::expr(byte) + } + pub(crate) fn value(byte: u8) -> usize { + 1 + get_len_short::value(byte) + } +} + +pub(crate) mod get_len_list_short { + use crate::mpt_circuit::param::RLP_LIST_SHORT; + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::plonk::Expression; + + pub(crate) fn expr(byte: Expression) -> Expression { + byte - RLP_LIST_SHORT.expr() + } + pub(crate) fn value(byte: u8) -> usize { + (byte - RLP_LIST_SHORT) as usize + } +} + +// A single RLP byte + the encoded length +pub(crate) mod get_num_bytes_list_short { + use super::get_len_list_short; + use eth_types::Field; + use gadgets::util::Expr; + use halo2_proofs::plonk::Expression; + + pub(crate) fn expr(byte: Expression) -> Expression { + 1.expr() + get_len_list_short::expr(byte) + } + pub(crate) fn value(byte: u8) -> usize { + 1 + get_len_list_short::value(byte) + } +} + +// Returns the number of nibbles stored in a key value +pub(crate) mod num_nibbles { + use crate::circuit_tools::constraint_builder::ConstraintBuilder; + use crate::{_cb, circuit}; + use eth_types::Field; + use halo2_proofs::plonk::Expression; + + pub(crate) fn expr( + key_len: Expression, + is_key_odd: Expression, + ) -> Expression { + circuit!([meta, _cb!()], { + ifx! {is_key_odd => { + key_len.expr() * 2.expr() - 1.expr() + } elsex { + (key_len.expr() - 1.expr()) * 2.expr() + }} + }) + } + pub(crate) fn value(key_len: usize, is_key_odd: bool) -> usize { + if is_key_odd { + key_len * 2 - 1 + } else { + (key_len - 1) * 2 + } + } +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPItemGadget { + pub(crate) value: RLPValueGadget, + pub(crate) list: RLPListGadget, +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct RLPItemWitness { + pub(crate) value: RLPValueWitness, + pub(crate) list: RLPListWitness, + pub(crate) bytes: Vec, +} + +impl RLPItemGadget { + pub(crate) fn construct(cb: &mut ConstraintBuilder, bytes: &[Expression]) -> Self { + RLPItemGadget { + value: RLPValueGadget::construct(cb, bytes), + list: RLPListGadget::construct(cb, bytes), + } + } + + pub(crate) fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + bytes: &[u8], + ) -> Result { + let value_witness = self.value.assign(region, offset, bytes)?; + let list_witness = self.list.assign(region, offset, bytes)?; + + if value_witness.is_string() && list_witness.is_list() { + println!("{:?}", bytes) + } + assert!(!(value_witness.is_string() && list_witness.is_list())); + + Ok(RLPItemWitness { + value: value_witness, + list: list_witness, + bytes: bytes.to_vec(), + }) + } + + // Single RLP byte containing the byte value + pub(crate) fn is_short(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.is_short(), + self.list.is_list() => self.list.is_short(), + } + }) + } + + // Single RLP byte containing the length of the value + pub(crate) fn is_long(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.is_long(), + self.list.is_list() => self.list.is_long(), + } + }) + } + + // RLP byte containing the lenght of the length, + // followed by the length, followed by the actual data + pub(crate) fn is_very_long(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.is_very_long(), + self.list.is_list() => self.list.is_very_long(), + } + }) + } + + /// Number of RLP bytes + pub(crate) fn num_rlp_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.num_rlp_bytes(), + self.list.is_list() => self.list.num_rlp_bytes(), + } + }) + } + + /// Number of bytes in total (including RLP bytes) + pub(crate) fn num_bytes(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.num_bytes(), + self.list.is_list() => self.list.num_bytes(), + } + }) + } + + /// Length of the value (excluding RLP bytes) + pub(crate) fn len(&self) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.len(), + self.list.is_list() => self.list.len(), + } + }) + } + + /// RLC data + pub(crate) fn rlc( + &self, + cb: &mut ConstraintBuilder, + r: &[Expression], + ) -> (Expression, Expression) { + circuit!([meta, cb], { + matchx! { + self.value.is_string() => self.value.rlc(r), + self.list.is_list() => self.list.rlc(r), + } + }) + } + + pub(crate) fn rlc_rlp( + &self, + cb: &mut ConstraintBuilder, + r: &[Expression], + ) -> Expression { + self.rlc(cb, r).1 + } + + pub(crate) fn rlc_value( + &self, + cb: &mut ConstraintBuilder, + r: &[Expression], + ) -> Expression { + self.rlc(cb, r).0 + } + + pub(crate) fn rlc_branch(&self, r: &[Expression]) -> Expression { + circuit!([meta, _cb!()], { + matchx! { + self.value.is_string() => self.value.rlc(r).0, + self.list.is_list() => self.list.rlc(r).1, + } + }) + } +} + +impl RLPItemWitness { + /// Number of bytes in total (including RLP bytes) + pub(crate) fn num_bytes(&self) -> usize { + matchr! { + self.value.is_string() => self.value.num_bytes(), + self.list.is_list() => self.list.num_bytes(), + } + } + + /// Length of the value (excluding RLP bytes) + pub(crate) fn len(&self) -> usize { + matchr! { + self.value.is_string() => self.value.len(), + self.list.is_list() => self.list.len(), + } + } + + pub(crate) fn rlc_branch(&self, r: F) -> F { + matchr! { + self.value.is_string() => self.value.rlc(r).0, + self.list.is_list() => self.list.rlc(r).1, + } + } +} diff --git a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs index f2e30905f9..dc3ef8eea4 100644 --- a/zkevm-circuits/src/mpt_circuit/storage_leaf.rs +++ b/zkevm-circuits/src/mpt_circuit/storage_leaf.rs @@ -6,42 +6,44 @@ use halo2_proofs::{ poly::Rotation, }; -use crate::{circuit_tools::cell_manager::Cell, mpt_circuit::helpers::ParentDataWitness}; use crate::circuit_tools::constraint_builder::{RLCChainable, RLCableValue}; -use crate::circuit_tools::gadgets::{LtGadget, RequireNotZeroGadget}; -use crate::mpt_circuit::helpers::{drifted_nibble_rlc, IsEmptyTreeGadget}; +use crate::circuit_tools::gadgets::LtGadget; +use crate::mpt_circuit::helpers::IsEmptyTreeGadget; use crate::table::ProofType; use crate::{ assign, circuit, mpt_circuit::{ helpers::{key_memory, parent_memory, KeyData, MPTConstraintBuilder, ParentData}, - param::{HASH_WIDTH, IS_NON_EXISTING_STORAGE_POS, IS_STORAGE_MOD_POS, KEY_LEN_IN_NIBBLES}, + param::{HASH_WIDTH, IS_STORAGE_MOD_POS, KEY_LEN_IN_NIBBLES}, FixedTableTag, }, - mpt_circuit::{ - witness_row::{MptWitnessRow, MptWitnessRowType}, - MPTContext, - }, + mpt_circuit::{witness_row::MptWitnessRow, MPTContext}, mpt_circuit::{MPTConfig, ProofValues}, }; +use crate::{ + circuit_tools::cell_manager::Cell, + mpt_circuit::helpers::{DriftedGadget, ParentDataWitness}, +}; -use super::helpers::{Indexable, LeafKeyGadget, RLPValueGadget}; +use super::{ + helpers::{Indexable, LeafKeyGadget, WrongGadget}, + param::IS_NON_EXISTING_STORAGE_POS, + rlp_gadgets::RLPValueGadget, +}; #[derive(Clone, Debug, Default)] pub(crate) struct StorageLeafConfig { key_data: [KeyData; 2], - key_data_w: KeyData, parent_data: [ParentData; 2], key_mult: [Cell; 2], - drifted_mult: Cell, rlp_key: [LeafKeyGadget; 2], rlp_value: [RLPValueGadget; 2], - drifted_rlp_key: LeafKeyGadget, wrong_rlp_key: LeafKeyGadget, is_wrong_leaf: Cell, - check_is_wrong_leaf: RequireNotZeroGadget, is_not_hashed: [LtGadget; 2], is_empty_trie: [IsEmptyTreeGadget; 2], + drifted: DriftedGadget, + wrong: WrongGadget, } impl StorageLeafConfig { @@ -96,8 +98,8 @@ impl StorageLeafConfig { require!((FixedTableTag::RMult, rlp_key.num_bytes_on_key_row(), config.key_mult[is_s.idx()].expr()) => @"fixed"); // RLC bytes zero check - //cb.set_length(rlp_key.num_bytes_on_key_row()); - //cb.set_length_s(config.rlp_value[is_s.idx()].num_bytes()); + cb.set_length(rlp_key.num_bytes_on_key_row()); + cb.set_length_s(config.rlp_value[is_s.idx()].num_bytes()); (value_rlc[is_s.idx()], value_rlp_rlc[is_s.idx()]) = config.rlp_value[is_s.idx()].rlc(&r); @@ -112,7 +114,6 @@ impl StorageLeafConfig { key_data.mult.expr(), key_data.is_odd.expr(), 1.expr(), - true, &r, ); // Total number of nibbles needs to be KEY_LEN_IN_NIBBLES @@ -155,96 +156,31 @@ impl StorageLeafConfig { ); } - // Drifted leaf - ifx! {config.parent_data[true.idx()].is_placeholder.expr() + config.parent_data[false.idx()].is_placeholder.expr() => { - config.drifted_rlp_key = LeafKeyGadget::construct(&mut cb.base, &drifted_bytes); - - // We need the intermediate key RLC right before `drifted_index` is added to it. - let (key_rlc_prev, key_mult_prev, placeholder_nibble, placeholder_is_odd) = ifx!{config.parent_data[true.idx()].is_placeholder.expr() => { - ( - config.key_data[true.idx()].parent_rlc.expr(), - config.key_data[true.idx()].parent_mult.expr(), - config.key_data[true.idx()].placeholder_nibble.expr(), - config.key_data[true.idx()].placeholder_is_odd.expr(), - ) - } elsex { - ( - config.key_data[false.idx()].parent_rlc.expr(), - config.key_data[false.idx()].parent_mult.expr(), - config.key_data[false.idx()].placeholder_nibble.expr(), - config.key_data[false.idx()].placeholder_is_odd.expr(), - ) - }}; - - // Calculate the drifted key RLC - let drifted_key_rlc = key_rlc_prev.expr() + - drifted_nibble_rlc(&mut cb.base, placeholder_nibble.expr(), key_mult_prev.expr(), placeholder_is_odd.expr()) + - config.drifted_rlp_key.leaf_key_rlc(&mut cb.base, key_mult_prev.expr(), placeholder_is_odd.expr(), r[0].expr(), true, &r); - - // Check zero bytes and mult_diff - config.drifted_mult = cb.base.query_cell(); - require!((FixedTableTag::RMult, config.drifted_rlp_key.num_bytes_on_key_row(), config.drifted_mult.expr()) => @"fixed"); - cb.set_length(config.drifted_rlp_key.num_bytes_on_key_row()); - - // Check that the drifted leaf is unchanged and is stored at `drifted_index`. - let calc_rlc = |is_s: bool| { - // Complete the drifted leaf rlc by adding the bytes on the value row - let drifted_rlc = (config.drifted_rlp_key.rlc(&r), config.drifted_mult.expr()).rlc_chain(value_rlp_rlc[is_s.idx()].expr()); - (key_rlc[is_s.idx()].expr(), drifted_rlc, config.parent_data[is_s.idx()].placeholder_rlc.expr()) - }; - let (key_rlc, drifted_rlc, mod_hash) = matchx! { - config.parent_data[true.idx()].is_placeholder => { - // Neighbour leaf in the added branch - calc_rlc(true) - }, - config.parent_data[false.idx()].is_placeholder => { - // Neighbour leaf in the deleted branch - calc_rlc(false) - }, - }; - // The key of the drifted leaf needs to match the key of the leaf - require!(key_rlc => drifted_key_rlc); - // The drifted leaf needs to be stored in the branch at `drifted_index`. - require!((1, drifted_rlc, config.drifted_rlp_key.num_bytes(), mod_hash) => @"keccak"); - }} - - // Wrong leaf - config.is_wrong_leaf = cb.base.query_cell(); - // Make sure is_wrong_leaf is boolean - require!(config.is_wrong_leaf => bool); - ifx! {a!(ctx.proof_type.is_non_existing_storage_proof, wrong_offset) => { - // Get the previous key data - config.key_data_w = KeyData::load(&mut cb.base, &ctx.memory[key_memory(true)], 1.expr()); - ifx! {config.is_wrong_leaf => { - // Calculate the key - config.wrong_rlp_key = LeafKeyGadget::construct(&mut cb.base, &wrong_bytes); - let key_rlc_wrong = config.key_data_w.rlc.expr() + config.wrong_rlp_key.leaf_key_rlc( - &mut cb.base, - config.key_data_w.mult.expr(), - config.key_data_w.is_odd.expr(), - 1.expr(), - false, - &ctx.r, - ); - - // Check that it's the key as requested in the lookup - let key_rlc_lookup = a!(ctx.mpt_table.key_rlc, wrong_offset); - require!(key_rlc_lookup => key_rlc_wrong); - - // Now make sure this address is different than the one of the leaf - config.check_is_wrong_leaf = RequireNotZeroGadget::construct(&mut cb.base, key_rlc_lookup - key_rlc[false.idx()].expr()); - // Make sure the lengths of the keys are the same - require!(config.wrong_rlp_key.key_len() => config.rlp_key[false.idx()].key_len()); - // RLC bytes zero check - cb.set_length(config.wrong_rlp_key.num_bytes_on_key_row()); - } elsex { - // In case when there is no wrong leaf, we need to check there is a nil object in the parent branch. - require!(config.key_data_w.is_placeholder_leaf_c => true); - }} - } elsex { - // is_wrong_leaf needs to be false when not in non_existing_account proof - require!(config.is_wrong_leaf => false); - }} + // Drifted leaf handling + config.drifted = DriftedGadget::construct( + cb, + &config.parent_data, + &config.key_data, + &key_rlc, + &value_rlp_rlc, + &drifted_bytes, + &ctx.r, + ); + + // Wrong leaf handling + let is_non_existing = a!(ctx.proof_type.is_non_existing_storage_proof, wrong_offset); + config.wrong = WrongGadget::construct( + meta, + cb, + ctx.clone(), + is_non_existing, + &config.rlp_key, + &key_rlc, + &wrong_bytes, + wrong_offset, + false, + &ctx.r, + ); // Put the data in the lookup table require!(a!(ctx.mpt_table.key_rlc, lookup_offset) => key_rlc[false.idx()]); @@ -265,10 +201,10 @@ impl StorageLeafConfig { ) -> Result<(), Error> { let base_offset = offset; - let key_bytes = [&witness[offset + 0], &witness[offset + 2]]; + let row_key = [&witness[offset + 0], &witness[offset + 2]]; let value_bytes = [&witness[offset + 1], &witness[offset + 3]]; - let drifted_bytes = &witness[offset + 4]; - let wrong_bytes = &witness[offset + 5]; + let row_drifted = &witness[offset + 4]; + let row_wrong = &witness[offset + 5]; let lookup_offset = offset + 3; let wrong_offset = offset + 5; @@ -277,7 +213,7 @@ impl StorageLeafConfig { let mut value_rlc = vec![0.scalar(); 2]; for is_s in [true, false] { // Key - let key_row = &key_bytes[is_s.idx()]; + let key_row = &row_key[is_s.idx()]; parent_data[is_s.idx()] = self.parent_data[is_s.idx()].witness_load( region, @@ -299,7 +235,7 @@ impl StorageLeafConfig { 32.scalar(), )?; - self.key_data[is_s.idx()].witness_load( + let key_data = self.key_data[is_s.idx()].witness_load( region, base_offset, &mut pv.memory[key_memory(is_s)], @@ -321,13 +257,8 @@ impl StorageLeafConfig { )?; // Key - let (key_rlc_new, key_rlc_mult) = if parent_data[is_s.idx()].is_placeholder { - (pv.key_rlc_prev, pv.key_rlc_mult_prev) - } else { - (pv.key_rlc, pv.key_rlc_mult) - }; (key_rlc[is_s.idx()], _) = - rlp_key_witness.leaf_key_rlc(key_rlc_new, key_rlc_mult, ctx.r); + rlp_key_witness.leaf_key_rlc(key_data.rlc, key_data.mult, ctx.r); // Value let value_row = &value_bytes[is_s.idx()]; @@ -358,49 +289,25 @@ impl StorageLeafConfig { } // Drifted leaf handling - if parent_data[true.idx()].is_placeholder || parent_data[false.idx()].is_placeholder { - let row = &drifted_bytes; - - let drifted_key_witness = - self.drifted_rlp_key - .assign(region, base_offset, &row.bytes)?; - - let (_, leaf_mult) = drifted_key_witness.rlc_leaf(ctx.r); - - self.drifted_mult.assign(region, base_offset, leaf_mult)?; - } - - // Non-existing - let row = &wrong_bytes; - if row.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1 { - self.key_data_w.witness_load( - region, - base_offset, - &mut pv.memory[key_memory(true)], - 1, - )?; - - // TODO(Brecht): Change how the witness is generated - let is_wrong = row.bytes[0] != 0; - self.is_wrong_leaf - .assign(region, base_offset, F::from(is_wrong))?; - - let mut row_bytes = row.bytes.clone(); - row_bytes[0] = key_bytes[false.idx()].bytes[0]; - - let wrong_witness = self.wrong_rlp_key.assign(region, base_offset, &row_bytes)?; - let (key_rlc_wrong, _) = - wrong_witness.leaf_key_rlc(pv.key_rlc, pv.key_rlc_mult, ctx.r); - - self.check_is_wrong_leaf.assign( - region, - base_offset, - key_rlc_wrong - key_rlc[false.idx()], - )?; - - assign!(region, (ctx.mpt_table.key_rlc, wrong_offset) => key_rlc_wrong)?; - assign!(region, (ctx.proof_type.proof_type, wrong_offset) => ProofType::StorageDoesNotExist.scalar())?; - } + self.drifted + .assign(region, base_offset, &parent_data, &row_drifted.bytes, ctx.r)?; + + // Wrong leaf handling + let is_non_existing = row_wrong.get_byte_rev(IS_NON_EXISTING_STORAGE_POS) == 1; + self.wrong.assign( + region, + base_offset, + ctx, + is_non_existing, + &mut pv.memory, + &key_rlc, + &row_wrong.bytes, + wrong_offset, + row_key, + false, + ProofType::StorageDoesNotExist, + ctx.r, + )?; // Put the data in the lookup table if value_bytes[false.idx()].get_byte_rev(IS_STORAGE_MOD_POS) == 1 { diff --git a/zkevm-circuits/src/mpt_circuit/witness_row.rs b/zkevm-circuits/src/mpt_circuit/witness_row.rs index c3856091c1..4d84544d02 100644 --- a/zkevm-circuits/src/mpt_circuit/witness_row.rs +++ b/zkevm-circuits/src/mpt_circuit/witness_row.rs @@ -118,7 +118,7 @@ impl MptWitnessRow { } else { 0 }; - &self.bytes[S_RLP_START+offset..34] + &self.bytes[S_RLP_START + offset..34] } pub(crate) fn c_hash_bytes(&self) -> &[u8] { @@ -127,7 +127,7 @@ impl MptWitnessRow { } else { 0 }; - &self.bytes[C_RLP_START+offset..68] + &self.bytes[C_RLP_START + offset..68] } pub(crate) fn main(&self) -> &[u8] {