Skip to content

Commit

Permalink
add state circuit to super circuit (privacy-scaling-explorations#670)
Browse files Browse the repository at this point in the history
* add state circuit to super circuit

* fix

* remove QUICK_CHECK

* clean codes

* address review comments

Co-authored-by: Rohit Narurkar <[email protected]>
  • Loading branch information
lispc and roynalnaruto authored Aug 12, 2022
1 parent 131701b commit 1c60be2
Show file tree
Hide file tree
Showing 13 changed files with 498 additions and 378 deletions.
14 changes: 13 additions & 1 deletion gadgets/src/binary_number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ where
/// - creating expressions (via the Config) that evaluate to 1 when the bits
/// match a specific value and 0 otherwise.
#[derive(Clone, Debug)]
pub struct BinaryNumberChip<F: Field, T, const N: usize> {
pub struct BinaryNumberChip<F, T, const N: usize> {
config: BinaryNumberConfig<T, N>,
_marker: PhantomData<F>,
}
Expand All @@ -122,6 +122,7 @@ where
pub fn configure(
meta: &mut ConstraintSystem<F>,
selector: Column<Fixed>,
value: Option<Column<Advice>>,
) -> BinaryNumberConfig<T, N> {
let bits = [0; N].map(|_| meta.advice_column());
bits.map(|bit| {
Expand All @@ -137,6 +138,17 @@ where
_marker: PhantomData,
};

if let Some(value) = value {
meta.create_gate("binary number value", |meta| {
let selector = meta.query_fixed(selector, Rotation::cur());
vec![
selector
* (config.value(Rotation::cur())(meta)
- meta.query_advice(value, Rotation::cur())),
]
});
}

// Disallow bit patterns (if any) that don't correspond to a variant of T.
let valid_values: BTreeSet<usize> = T::iter().map(|t| from_bits(&t.as_bits())).collect();
let mut invalid_values = (0..1 << N).filter(|i| !valid_values.contains(i)).peekable();
Expand Down
9 changes: 6 additions & 3 deletions zkevm-circuits/src/copy_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,9 +770,12 @@ mod tests {
config
.tx_table
.load(&mut layouter, &self.block.txs, self.randomness)?;
config
.rw_table
.load(&mut layouter, &self.block.rws, self.randomness)?;
config.rw_table.load(
&mut layouter,
&self.block.rws.table_assignments(),
self.block.state_circuit_pad_to,
self.randomness,
)?;
config.bytecode_table.load(
&mut layouter,
self.block.bytecodes.values(),
Expand Down
10 changes: 7 additions & 3 deletions zkevm-circuits/src/evm_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,13 @@ pub mod test {
config
.tx_table
.load(&mut layouter, &self.block.txs, self.block.randomness)?;
config
.rw_table
.load(&mut layouter, &self.block.rws, self.block.randomness)?;
self.block.rws.check_rw_counter_sanity();
config.rw_table.load(
&mut layouter,
&self.block.rws.table_assignments(),
self.block.state_circuit_pad_to,
self.block.randomness,
)?;
config.bytecode_table.load(
&mut layouter,
self.block.bytecodes.values(),
Expand Down
98 changes: 69 additions & 29 deletions zkevm-circuits/src/evm_circuit/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub struct Block<F> {
pub context: BlockContext,
/// Copy events for the EVM circuit's copy table.
pub copy_events: Vec<CopyEvent>,
/// Length to rw table rows in state circuit
pub state_circuit_pad_to: usize,
}

#[derive(Debug, Default, Clone)]
Expand Down Expand Up @@ -377,7 +379,62 @@ impl std::ops::Index<(RwTableTag, usize)> for RwMap {
&self.0.get(&tag).unwrap()[idx]
}
}

impl RwMap {
/// Check rw_counter is continuous and starting from 1
pub fn check_rw_counter_sanity(&self) {
for (idx, rw_counter) in self
.0
.values()
.flatten()
.map(|r| r.rw_counter())
.sorted()
.enumerate()
{
debug_assert_eq!(idx, rw_counter - 1);
}
}
/// Calculates the number of Rw::Start rows needed.
/// `target_len` is allowed to be 0 as an "auto" mode,
/// then only 1 Rw::Start row will be prepadded.
pub(crate) fn padding_len(rows: &[Rw], target_len: usize) -> usize {
if target_len > rows.len() {
target_len - rows.len()
} else {
if target_len != 0 {
log::error!(
"RwMap::padding_len overflow, target_len: {}, rows.len(): {}",
target_len,
rows.len()
);
}
1
}
}
/// Prepad Rw::Start rows to target length
pub fn table_assignments_prepad(rows: &[Rw], target_len: usize) -> (Vec<Rw>, usize) {
let padding_length = Self::padding_len(rows, target_len);
let padding = (1..=padding_length).map(|rw_counter| Rw::Start { rw_counter });
(
padding.chain(rows.iter().cloned()).collect(),
padding_length,
)
}
/// Build Rws for assignment
pub fn table_assignments(&self) -> Vec<Rw> {
let mut rows: Vec<Rw> = self.0.values().flatten().cloned().collect();
rows.sort_by_key(|row| {
(
row.tag() as u64,
row.id().unwrap_or_default(),
row.address().unwrap_or_default(),
row.field_tag().unwrap_or_default(),
row.storage_key().unwrap_or_default(),
row.rw_counter(),
)
});
rows
}
}
#[derive(Clone, Copy, Debug)]
pub enum Rw {
Start {
Expand Down Expand Up @@ -476,39 +533,21 @@ pub enum Rw {
value: u64,
},
}
#[derive(Default, Clone, Copy)]
pub struct RwRow<F: FieldExt> {
#[derive(Default, Clone, Copy, Debug)]
pub struct RwRow<F> {
pub rw_counter: F,
pub is_write: F,
pub tag: F,
pub key1: F,
pub key2: F,
pub key3: F,
pub key4: F,
pub id: F,
pub address: F,
pub field_tag: F,
pub storage_key: F,
pub value: F,
pub value_prev: F,
pub aux1: F,
pub aux2: F,
}

impl<F: FieldExt> From<[F; 11]> for RwRow<F> {
fn from(row: [F; 11]) -> Self {
Self {
rw_counter: row[0],
is_write: row[1],
tag: row[2],
key1: row[3],
key2: row[4],
key3: row[5],
key4: row[6],
value: row[7],
value_prev: row[8],
aux1: row[9],
aux2: row[10],
}
}
}

impl Rw {
pub fn tx_access_list_value_pair(&self) -> (bool, bool) {
match self {
Expand Down Expand Up @@ -608,10 +647,10 @@ impl Rw {
rw_counter: F::from(self.rw_counter() as u64),
is_write: F::from(self.is_write() as u64),
tag: F::from(self.tag() as u64),
key1: F::from(self.id().unwrap_or_default() as u64),
key2: self.address().unwrap_or_default().to_scalar().unwrap(),
key3: F::from(self.field_tag().unwrap_or_default() as u64),
key4: RandomLinearCombination::random_linear_combine(
id: F::from(self.id().unwrap_or_default() as u64),
address: self.address().unwrap_or_default().to_scalar().unwrap(),
field_tag: F::from(self.field_tag().unwrap_or_default() as u64),
storage_key: RandomLinearCombination::random_linear_combine(
self.storage_key().unwrap_or_default().to_le_bytes(),
randomness,
),
Expand Down Expand Up @@ -1384,5 +1423,6 @@ pub fn block_convert(
})
.collect(),
copy_events: block.copy_events.clone(),
..Default::default()
}
}
Loading

0 comments on commit 1c60be2

Please sign in to comment.