Skip to content

Commit

Permalink
Constrain value_prev to be value at Rotation::prev() (privacy-scaling…
Browse files Browse the repository at this point in the history
  • Loading branch information
z2trillion and Mason Liang authored Feb 17, 2023
1 parent b5c76d1 commit f834e61
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 9 deletions.
3 changes: 1 addition & 2 deletions zkevm-circuits/src/state_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,9 +555,8 @@ fn queries<F: Field>(meta: &mut VirtualCells<'_, F>, c: &StateCircuitConfig<F>)
field_tag: meta.query_advice(c.rw_table.field_tag, Rotation::cur()),
storage_key: meta.query_advice(c.rw_table.storage_key, Rotation::cur()),
value: meta.query_advice(c.rw_table.value, Rotation::cur()),
// TODO: we should constain value.prev() <-> value_prev.cur() later
// see https://github.com/privacy-scaling-explorations/zkevm-specs/issues/202 for more details
value_prev: meta.query_advice(c.rw_table.value, Rotation::prev()),
value_prev_column: meta.query_advice(c.rw_table.value_prev, Rotation::cur()),
},
// TODO: clean this up
mpt_update_table: MptUpdateTableQueries {
Expand Down
78 changes: 76 additions & 2 deletions zkevm-circuits/src/state_circuit/constraint_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ pub struct RwTableQueries<F: Field> {
pub field_tag: Expression<F>,
pub storage_key: Expression<F>,
pub value: Expression<F>,
pub value_prev: Expression<F>,
// TODO: aux1 and aux2
pub value_prev: Expression<F>, // meta.query(value, Rotation::prev())
pub value_prev_column: Expression<F>, /*meta.query(prev_value, Rotation::cur())
* TODO: aux1 and aux2 */
}

#[derive(Clone)]
Expand Down Expand Up @@ -156,6 +157,11 @@ impl<F: Field> ConstraintBuilder<F> {
"first access reads don't change value",
q.is_read() * (q.rw_table.value.clone() - q.initial_value()),
);
cb.require_equal(
"value_prev column is initial_value for first access",
q.value_prev_column(),
q.initial_value.clone(),
);
});

// When all the keys in the current row and previous row are equal.
Expand Down Expand Up @@ -189,6 +195,7 @@ impl<F: Field> ConstraintBuilder<F> {
q.state_root_prev(),
)
});
self.require_zero("value_prev column is 0 for Start", q.value_prev_column());
}

fn build_memory_constraints(&mut self, q: &Queries<F>) {
Expand All @@ -213,6 +220,11 @@ impl<F: Field> ConstraintBuilder<F> {
q.state_root(),
q.state_root_prev(),
);
self.require_equal(
"value_prev column equals initial_value for Memory",
q.value_prev_column(),
q.initial_value(),
);
}

fn build_stack_constraints(&mut self, q: &Queries<F>) {
Expand Down Expand Up @@ -240,6 +252,11 @@ impl<F: Field> ConstraintBuilder<F> {
q.state_root(),
q.state_root_prev(),
);
self.require_equal(
"value_prev column equals initial_value for Stack",
q.value_prev_column(),
q.initial_value(),
);
}

fn build_account_storage_constraints(&mut self, q: &Queries<F>) {
Expand Down Expand Up @@ -278,6 +295,14 @@ impl<F: Field> ConstraintBuilder<F> {
],
);
});

self.condition(q.not_first_access.clone(), |cb| {
cb.require_equal(
"value column at Rotation::prev() equals value_prev at Rotation::cur()",
q.rw_table.value_prev.clone(),
q.value_prev_column(),
);
});
}

fn build_tx_access_list_account_constraints(&mut self, q: &Queries<F>) {
Expand All @@ -297,6 +322,14 @@ impl<F: Field> ConstraintBuilder<F> {
q.state_root(),
q.state_root_prev(),
);

self.condition(q.not_first_access.clone(), |cb| {
cb.require_equal(
"value column at Rotation::prev() equals value_prev at Rotation::cur()",
q.rw_table.value_prev.clone(),
q.value_prev_column(),
);
});
}

fn build_tx_access_list_account_storage_constraints(&mut self, q: &Queries<F>) {
Expand All @@ -315,6 +348,14 @@ impl<F: Field> ConstraintBuilder<F> {
q.state_root(),
q.state_root_prev(),
);

self.condition(q.not_first_access.clone(), |cb| {
cb.require_equal(
"value column at Rotation::prev() equals value_prev at Rotation::cur()",
q.rw_table.value_prev.clone(),
q.value_prev_column(),
);
});
}

fn build_tx_refund_constraints(&mut self, q: &Queries<F>) {
Expand All @@ -331,6 +372,14 @@ impl<F: Field> ConstraintBuilder<F> {
q.state_root(),
q.state_root_prev(),
);

self.condition(q.not_first_access.clone(), |cb| {
cb.require_equal(
"value column at Rotation::prev() equals value_prev at Rotation::cur()",
q.rw_table.value_prev.clone(),
q.value_prev_column(),
);
});
// 7.2. `initial value` is 0
self.require_zero("initial TxRefund value is 0", q.initial_value());
// 7.3. First access for a set of all keys are 0 if READ
Expand Down Expand Up @@ -399,6 +448,14 @@ impl<F: Field> ConstraintBuilder<F> {
],
);
});

self.condition(q.not_first_access.clone(), |cb| {
cb.require_equal(
"value column at Rotation::prev() equals value_prev at Rotation::cur()",
q.rw_table.value_prev.clone(),
q.value_prev_column(),
);
});
}

fn build_call_context_constraints(&mut self, q: &Queries<F>) {
Expand All @@ -417,6 +474,10 @@ impl<F: Field> ConstraintBuilder<F> {
q.state_root(),
q.state_root_prev(),
);
self.require_zero(
"value_prev column is 0 for CallContext",
q.value_prev_column(),
);
}

fn build_tx_log_constraints(&mut self, q: &Queries<F>) {
Expand All @@ -432,6 +493,11 @@ impl<F: Field> ConstraintBuilder<F> {
q.state_root(),
q.state_root_prev(),
);
self.require_equal(
"value_prev column equals initial_value for TxLog",
q.value_prev_column(),
q.initial_value(),
);
}

fn build_tx_receipt_constraints(&mut self, q: &Queries<F>) {
Expand All @@ -443,6 +509,10 @@ impl<F: Field> ConstraintBuilder<F> {
q.state_root(),
q.state_root_prev(),
);
self.require_zero(
"value_prev_column is 0 for TxReceipt",
q.value_prev_column(),
);
}

fn require_zero(&mut self, name: &'static str, e: Expression<F>) {
Expand Down Expand Up @@ -578,6 +648,10 @@ impl<F: Field> Queries<F> {
fn state_root_prev(&self) -> Expression<F> {
self.state_root_prev.clone()
}

fn value_prev_column(&self) -> Expression<F> {
self.rw_table.value_prev_column.clone()
}
}

fn from_digits<F: Field>(digits: &[Expression<F>], base: Expression<F>) -> Expression<F> {
Expand Down
22 changes: 17 additions & 5 deletions zkevm-circuits/src/state_circuit/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub enum AdviceColumn {
StorageKeyByte0,
StorageKeyByte1,
Value,
ValuePrev,
RwCounter,
RwCounterLimb0,
RwCounterLimb1,
Expand Down Expand Up @@ -67,6 +68,7 @@ impl AdviceColumn {
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::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 Down Expand Up @@ -777,16 +779,16 @@ fn invalid_memory_address() {
fn bad_initial_memory_value() {
let rows = vec![Rw::Memory {
rw_counter: 1,
is_write: false,
is_write: true,
call_id: 1,
memory_address: 10,
byte: 0,
}];

let v = Fr::from(200);
let overrides = HashMap::from([
((AdviceColumn::IsWrite, 0), Fr::from(1)),
((AdviceColumn::Value, 0), v),
((AdviceColumn::ValuePrev, 0), v),
((AdviceColumn::IsZero, 0), Fr::zero()),
((AdviceColumn::NonEmptyWitness, 0), v.invert().unwrap()),
((AdviceColumn::InitialValue, 0), v),
Expand Down Expand Up @@ -903,7 +905,10 @@ fn bad_initial_stack_value() {
value: Word::from(10),
}];

let overrides = HashMap::from([((AdviceColumn::InitialValue, 0), Fr::from(10))]);
let overrides = HashMap::from([
((AdviceColumn::InitialValue, 0), Fr::from(10)),
((AdviceColumn::ValuePrev, 0), Fr::from(10)),
]);

assert_error_matches(
verify_with_overrides(rows, overrides),
Expand All @@ -922,7 +927,10 @@ fn bad_initial_tx_access_list_account_value() {
is_warm_prev: false,
}];

let overrides = HashMap::from([((AdviceColumn::InitialValue, 0), Fr::from(1))]);
let overrides = HashMap::from([
((AdviceColumn::InitialValue, 0), Fr::from(1)),
((AdviceColumn::ValuePrev, 0), Fr::from(1)),
]);

assert_error_matches(
verify_with_overrides(rows, overrides),
Expand All @@ -943,6 +951,7 @@ fn bad_initial_tx_refund_value() {
let overrides = HashMap::from([
((AdviceColumn::IsWrite, 0), Fr::from(1)),
((AdviceColumn::Value, 0), v),
((AdviceColumn::ValuePrev, 0), v),
((AdviceColumn::IsZero, 0), Fr::zero()),
((AdviceColumn::NonEmptyWitness, 0), v.invert().unwrap()),
((AdviceColumn::InitialValue, 0), v),
Expand All @@ -966,7 +975,10 @@ fn bad_initial_tx_log_value() {
value: U256::from(300),
}];

let overrides = HashMap::from([((AdviceColumn::InitialValue, 0), Fr::from(10))]);
let overrides = HashMap::from([
((AdviceColumn::InitialValue, 0), Fr::from(10)),
((AdviceColumn::ValuePrev, 0), Fr::from(10)),
]);

assert_error_matches(
verify_with_overrides(rows, overrides),
Expand Down

0 comments on commit f834e61

Please sign in to comment.