Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

State Circuit: Refactor word_rlc into word lo/hi #1423

Merged
merged 12 commits into from
Jun 8, 2023
1 change: 0 additions & 1 deletion zkevm-circuits/src/copy_circuit/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ impl<F: Field> Circuit<F> for CopyCircuit<F> {
&mut layouter,
&self.external_data.rws.table_assignments(),
self.external_data.max_rws,
challenge_values.evm_word(),
)?;

config.0.bytecode_table.load(
Expand Down
1 change: 0 additions & 1 deletion zkevm-circuits/src/evm_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,6 @@ impl<F: Field> Circuit<F> for EvmCircuit<F> {
&mut layouter,
&block.rws.table_assignments(),
block.circuits_params.max_rws,
challenges.evm_word(),
)?;
config
.bytecode_table
Expand Down
9 changes: 3 additions & 6 deletions zkevm-circuits/src/evm_circuit/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,10 +1377,7 @@ impl<F: Field> ExecutionConfig<F> {
.rw_indices
.iter()
.map(|rw_idx| block.rws[*rw_idx])
.map(|rw| {
rw.table_assignment_aux(evm_randomness)
.rlc(lookup_randomness)
})
.map(|rw| rw.table_assignment().unwrap().rlc(lookup_randomness))
.fold(BTreeSet::<F>::new(), |mut set, value| {
set.insert(value);
set
Expand Down Expand Up @@ -1429,8 +1426,8 @@ impl<F: Field> ExecutionConfig<F> {
};
let rw_idx = step.rw_indices[idx];
let rw = block.rws[rw_idx];
let table_assignments = rw.table_assignment_aux(evm_randomness);
let rlc = table_assignments.rlc(lookup_randomness);
let table_assignments = rw.table_assignment();
let rlc = table_assignments.unwrap().rlc(lookup_randomness);
if rlc != assigned_rw_value.1 {
log::error!(
"incorrect rw witness. lookup input name: \"{}\"\nassigned={:?}\nrlc ={:?}\nrw index: {:?}, {}th rw of step {:?}, rw: {:?}",
Expand Down
277 changes: 137 additions & 140 deletions zkevm-circuits/src/state_circuit.rs

Large diffs are not rendered by default.

262 changes: 151 additions & 111 deletions zkevm-circuits/src/state_circuit/constraint_builder.rs

Large diffs are not rendered by default.

36 changes: 21 additions & 15 deletions zkevm-circuits/src/state_circuit/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ where
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
let challenges = challenges.values(&mut layouter);
config
.mpt_table
.load(&mut layouter, &self.updates, challenges.evm_word())?;
config.mpt_table.load(&mut layouter, &self.updates)?;
self.synthesize_sub(&config, &challenges, &mut layouter)
}
}
Expand All @@ -61,11 +59,14 @@ pub enum AdviceColumn {
Address,
AddressLimb0,
AddressLimb1,
StorageKey,
StorageKeyByte0,
StorageKeyByte1,
Value,
ValuePrev,
StorageKeyLo,
StorageKeyHi,
StorageKeyLimb0,
StorageKeyLimb1,
ValueLo,
ValueHi,
ValuePrevLo,
ValuePrevHi,
RwCounter,
RwCounterLimb0,
RwCounterLimb1,
Expand All @@ -79,7 +80,8 @@ pub enum AdviceColumn {
LimbIndexBit2,
LimbIndexBit3,
LimbIndexBit4, // least significant bit
InitialValue,
InitialValueLo,
InitialValueHi,
IsZero, // committed_value and value are 0
// NonEmptyWitness is the BatchedIsZero chip witness that contains the
// inverse of the non-zero value if any in [committed_value, value]
Expand All @@ -93,11 +95,14 @@ impl AdviceColumn {
Self::Address => config.rw_table.address,
Self::AddressLimb0 => config.sort_keys.address.limbs[0],
Self::AddressLimb1 => config.sort_keys.address.limbs[1],
Self::StorageKey => config.rw_table.storage_key,
Self::StorageKeyByte0 => config.sort_keys.storage_key.bytes[0],
Self::StorageKeyByte1 => config.sort_keys.storage_key.bytes[1],
Self::Value => config.rw_table.value,
Self::ValuePrev => config.rw_table.value_prev,
Self::StorageKeyLo => config.rw_table.storage_key.lo(),
Self::StorageKeyHi => config.rw_table.storage_key.hi(),
Self::StorageKeyLimb0 => config.sort_keys.storage_key.limbs[0],
Self::StorageKeyLimb1 => config.sort_keys.storage_key.limbs[1],
Self::ValueLo => config.rw_table.value.lo(),
Self::ValueHi => config.rw_table.value.hi(),
Self::ValuePrevLo => config.rw_table.value_prev.lo(),
Self::ValuePrevHi => config.rw_table.value_prev.hi(),
Self::RwCounter => config.rw_table.rw_counter,
Self::RwCounterLimb0 => config.sort_keys.rw_counter.limbs[0],
Self::RwCounterLimb1 => config.sort_keys.rw_counter.limbs[1],
Expand All @@ -111,7 +116,8 @@ impl AdviceColumn {
Self::LimbIndexBit2 => config.lexicographic_ordering.first_different_limb.bits[2],
Self::LimbIndexBit3 => config.lexicographic_ordering.first_different_limb.bits[3],
Self::LimbIndexBit4 => config.lexicographic_ordering.first_different_limb.bits[4],
Self::InitialValue => config.initial_value,
Self::InitialValueLo => config.initial_value.lo(),
Self::InitialValueHi => config.initial_value.hi(),
Self::IsZero => config.is_non_exist.is_zero,
Self::NonEmptyWitness => config.is_non_exist.nonempty_witness,
}
Expand Down
11 changes: 3 additions & 8 deletions zkevm-circuits/src/state_circuit/lexicographic_ordering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ struct Queries<F: Field> {
field_tag: Expression<F>, // 8 bits, so we can pack tag + field_tag into one limb.
id_limbs: [Expression<F>; N_LIMBS_ID],
address_limbs: [Expression<F>; N_LIMBS_ACCOUNT_ADDRESS],
storage_key_bytes: [Expression<F>; N_BYTES_WORD],
storage_key_limbs: [Expression<F>; N_LIMBS_WORD],
rw_counter_limbs: [Expression<F>; N_LIMBS_RW_COUNTER],
}

Expand All @@ -265,18 +265,13 @@ impl<F: Field> Queries<F> {
id_limbs: keys.id.limbs.map(&mut query_advice),
address_limbs: keys.address.limbs.map(&mut query_advice),
field_tag: query_advice(keys.field_tag),
storage_key_bytes: keys.storage_key.bytes.map(&mut query_advice),
storage_key_limbs: keys.storage_key.limbs.map(&mut query_advice),
rw_counter_limbs: keys.rw_counter.limbs.map(query_advice),
}
}

fn storage_key_be_limbs(&self) -> Vec<Expression<F>> {
self.storage_key_bytes
.iter()
.rev()
.tuples()
.map(|(hi, lo)| (1u64 << 8).expr() * hi.clone() + lo.clone())
.collect()
self.storage_key_limbs.iter().rev().cloned().collect()
}

fn be_limbs(&self) -> Vec<Expression<F>> {
Expand Down
103 changes: 50 additions & 53 deletions zkevm-circuits/src/state_circuit/multiple_precision_integer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{lookups, param::*};
use crate::util::Expr;
use eth_types::{Address, Field};
use eth_types::{Address, Field, ToLittleEndian, Word};
use halo2_proofs::{
circuit::{Layouter, Region, Value},
plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells},
Expand All @@ -11,22 +11,38 @@ use std::marker::PhantomData;

pub trait ToLimbs<const N: usize> {
fn to_limbs(&self) -> [u16; N];
fn annotation() -> &'static str;
}

impl ToLimbs<N_LIMBS_ACCOUNT_ADDRESS> for Address {
fn to_limbs(&self) -> [u16; 10] {
fn to_limbs(&self) -> [u16; N_LIMBS_ACCOUNT_ADDRESS] {
// address bytes are be.... maybe just have everything be later?
// you will need this in the future later because it makes the key ordering more
// obvious
let le_bytes: Vec<_> = self.0.iter().rev().cloned().collect();
le_bytes_to_limbs(&le_bytes).try_into().unwrap()
}
fn annotation() -> &'static str {
hero78119 marked this conversation as resolved.
Show resolved Hide resolved
"Address"
}
}

impl ToLimbs<N_LIMBS_RW_COUNTER> for u32 {
fn to_limbs(&self) -> [u16; 2] {
fn to_limbs(&self) -> [u16; N_LIMBS_RW_COUNTER] {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should rename N_LIMBS_RW_COUNTER to N_LIMBS_U32. But probably not in this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, why not 👍

le_bytes_to_limbs(&self.to_le_bytes()).try_into().unwrap()
}
fn annotation() -> &'static str {
"u32"
}
}

impl ToLimbs<N_LIMBS_WORD> for Word {
fn to_limbs(&self) -> [u16; N_LIMBS_WORD] {
le_bytes_to_limbs(&self.to_le_bytes()).try_into().unwrap()
}
fn annotation() -> &'static str {
"Word"
}
}

#[derive(Clone, Copy)]
Expand Down Expand Up @@ -58,47 +74,19 @@ impl<F: Field, const N: usize> Queries<F, N> {
}
}

impl Config<Address, N_LIMBS_ACCOUNT_ADDRESS> {
pub fn assign<F: Field>(
&self,
region: &mut Region<'_, F>,
offset: usize,
value: Address,
) -> Result<(), Error> {
for (i, &limb) in value.to_limbs().iter().enumerate() {
region.assign_advice(
|| format!("limb[{}] in address mpi", i),
self.limbs[i],
offset,
|| Value::known(F::from(limb as u64)),
)?;
}
Ok(())
}

/// Annotates columns of this gadget embedded within a circuit region.
pub fn annotate_columns_in_region<F: Field>(&self, region: &mut Region<F>, prefix: &str) {
let mut annotations = Vec::new();
for (i, _) in self.limbs.iter().enumerate() {
annotations.push(format!("MPI_limbs_address_{}", i));
}
self.limbs
.iter()
.zip(annotations.iter())
.for_each(|(col, ann)| region.name_column(|| format!("{}_{}", prefix, ann), *col));
}
}

impl Config<u32, N_LIMBS_RW_COUNTER> {
impl<T, const N: usize> Config<T, N>
where
T: ToLimbs<N>,
{
pub fn assign<F: Field>(
&self,
region: &mut Region<'_, F>,
offset: usize,
value: u32,
value: T,
) -> Result<(), Error> {
for (i, &limb) in value.to_limbs().iter().enumerate() {
region.assign_advice(
|| format!("limb[{}] in u32 mpi", i),
|| format!("limb[{}] in {} mpi", i, T::annotation()),
self.limbs[i],
offset,
|| Value::known(F::from(limb as u64)),
Expand All @@ -111,7 +99,7 @@ impl Config<u32, N_LIMBS_RW_COUNTER> {
pub fn annotate_columns_in_region<F: Field>(&self, region: &mut Region<F>, prefix: &str) {
let mut annotations = Vec::new();
for (i, _) in self.limbs.iter().enumerate() {
annotations.push(format!("MPI_limbs_u32_{}", i));
annotations.push(format!("MPI_limbs_{}_{}", T::annotation(), i));
}
self.limbs
.iter()
Expand All @@ -120,19 +108,19 @@ impl Config<u32, N_LIMBS_RW_COUNTER> {
}
}

pub struct Chip<F: Field, T, const N: usize>
pub struct Chip<F: Field, T, const N_LIMBS: usize, const N_VALUES: usize>
where
T: ToLimbs<N>,
T: ToLimbs<N_LIMBS>,
{
config: Config<T, N>,
config: Config<T, N_LIMBS>,
_marker: PhantomData<F>,
}

impl<F: Field, T, const N: usize> Chip<F, T, N>
impl<F: Field, T, const N_LIMBS: usize, const N_VALUES: usize> Chip<F, T, N_LIMBS, N_VALUES>
where
T: ToLimbs<N>,
T: ToLimbs<N_LIMBS>,
{
pub fn construct(config: Config<T, N>) -> Self {
pub fn construct(config: Config<T, N_LIMBS>) -> Self {
Self {
config,
_marker: PhantomData,
Expand All @@ -142,22 +130,31 @@ where
pub fn configure(
meta: &mut ConstraintSystem<F>,
selector: Column<Fixed>,
value: Column<Advice>,
values: [Column<Advice>; N_VALUES],
lookup: lookups::Config,
) -> Config<T, N> {
let limbs = [0; N].map(|_| meta.advice_column());
) -> Config<T, N_LIMBS> {
assert_eq!(N_LIMBS & N_VALUES, 0);
let limbs_per_value = N_LIMBS / N_VALUES;

let limbs = [0; N_LIMBS].map(|_| meta.advice_column());

for &limb in &limbs {
lookup.range_check_u16(meta, "mpi limb fits into u16", |meta| {
meta.query_advice(limb, Rotation::cur())
});
}
meta.create_gate("mpi value matches claimed limbs", |meta| {
let selector = meta.query_fixed(selector, Rotation::cur());
let value = meta.query_advice(value, Rotation::cur());
let limbs = limbs.map(|limb| meta.query_advice(limb, Rotation::cur()));
vec![selector * (value - value_from_limbs(&limbs))]
});

for (n, value) in values.iter().enumerate() {
meta.create_gate("mpi value matches claimed limbs", |meta| {
let selector = meta.query_fixed(selector, Rotation::cur());
let value_expr = meta.query_advice(*value, Rotation::cur());
let value_limbs = &limbs[n * limbs_per_value..(n + 1) * limbs_per_value];
let limbs_expr = value_limbs
.iter()
.map(|limb| meta.query_advice(*limb, Rotation::cur()));
vec![selector * (value_expr - value_from_limbs(&limbs_expr.collect::<Vec<_>>()))]
});
}

Config {
limbs,
Expand Down
1 change: 1 addition & 0 deletions zkevm-circuits/src/state_circuit/param.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub(super) const N_LIMBS_RW_COUNTER: usize = 2;
pub(super) const N_LIMBS_ACCOUNT_ADDRESS: usize = 10;
pub(super) const N_LIMBS_ID: usize = 2;
pub(super) const N_LIMBS_WORD: usize = 16;
Loading