Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

Commit d63e608

Browse files
author
Aurélien Nicolas
committed
memory_opt_counters: constraints on front_mask
1 parent 69fbc92 commit d63e608

File tree

2 files changed

+38
-34
lines changed

2 files changed

+38
-34
lines changed

zkevm-circuits/src/copy_circuit.rs

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
258258
// If a row is not enabled (fixed), it is not in an event.
259259
// TODO: not currently possible due to API limitations.
260260
// (1.expr() - enabled.expr()) * is_event.expr(),
261-
261+
262262
// If a row is anything but padding (filler of the table), it is in an event.
263263
enabled.expr()
264264
* ((1.expr() - is_event.expr())
@@ -290,7 +290,6 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
290290
meta.query_advice(is_last, Rotation::cur()),
291291
);
292292
cb.require_boolean("mask is boolean", meta.query_advice(mask, Rotation::cur()));
293-
cb.require_boolean("front_mask is boolean", meta.query_advice(front_mask, Rotation::cur()));
294293
cb.require_zero(
295294
"is_first == 0 when q_step == 0",
296295
and::expr([
@@ -321,17 +320,6 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
321320

322321
// Whether this row is part of a memory or log word.
323322
let is_word = meta.query_advice(is_memory, Rotation::cur()) + meta.query_advice(is_tx_log, Rotation::cur());
324-
325-
cb.condition(
326-
is_continue.expr(),
327-
|cb| {
328-
cb.require_equal(
329-
"bytes_left == bytes_left_next + 1 for non-last step",
330-
meta.query_advice(bytes_left, Rotation::cur()),
331-
meta.query_advice(bytes_left, Rotation(2)) + 1.expr(),
332-
);
333-
},
334-
);
335323

336324
cb.condition(
337325
and::expr([
@@ -417,23 +405,43 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
417405
}
418406
);
419407

420-
// The address is incremented by 1, except in the front mask because the row address has not caught up with the address of the event yet.
421-
cb.condition(not_last_two_rows.expr(),
422-
|cb| {
408+
let front_mask_next = meta.query_advice(front_mask, Rotation(2));
409+
let front_mask = meta.query_advice(front_mask, Rotation::cur());
410+
cb.require_boolean("front_mask is boolean", front_mask.expr());
411+
412+
cb.require_zero("front_mask=1 implies mask=1",
413+
and::expr([
414+
front_mask.expr(),
415+
not::expr(meta.query_advice(mask, Rotation::cur())),
416+
]),
417+
);
418+
419+
cb.condition(not::expr(is_word_continue.is_lt(meta, None)), |cb| {
420+
// The first 31 bytes may be front_mask, but at least the 32nd byte is not masked.
421+
cb.require_zero("front_mask = 0 by the end of the first word", front_mask.expr());
422+
});
423423

424-
let addr_diff = not::expr(meta.query_advice(front_mask, Rotation::cur()));
424+
cb.condition(is_continue.expr(),
425+
|cb| {
425426

427+
cb.require_boolean("front_mask can go from 1 to 0", front_mask.expr() - front_mask_next);
428+
429+
// The address is incremented by 1, except in the front mask because the row address has not caught up with the address of the event yet.
430+
let addr_diff = not::expr(front_mask.expr());
426431
cb.require_equal(
427-
"rows[0].addr + 1 == rows[2].addr",
432+
"rows[0].addr + !front_mask == rows[2].addr",
428433
meta.query_advice(addr, Rotation::cur()) + addr_diff,
429434
meta.query_advice(addr, Rotation(2)),
430435
);
431-
},
432-
);
433436

434-
cb.condition(
435-
not_last_two_rows.expr() * is_event,
436-
|cb| {
437+
// The byte count including mask always decrements.
438+
cb.require_equal(
439+
"bytes_left == bytes_left_next + 1 for non-last step",
440+
meta.query_advice(bytes_left, Rotation::cur()),
441+
meta.query_advice(bytes_left, Rotation(2)) + 1.expr(),
442+
);
443+
444+
// Forward other fields to the next step.
437445
cb.require_equal(
438446
"rows[0].id == rows[2].id",
439447
meta.query_advice(id, Rotation::cur()),
@@ -444,7 +452,6 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
444452
tag.value(Rotation::cur())(meta),
445453
tag.value(Rotation(2))(meta),
446454
);
447-
448455
cb.require_equal(
449456
"rows[0].src_addr_end == rows[2].src_addr_end for non-last step",
450457
meta.query_advice(src_addr_end, Rotation::cur()),
@@ -789,12 +796,12 @@ impl<F: Field> CopyCircuitConfig<F> {
789796
.iter()
790797
.zip_eq(table_row)
791798
{
792-
region.assign_advice(
793-
|| format!("{label} at row: {offset}"),
794-
column,
795-
*offset,
796-
|| value,
797-
)?;
799+
region.assign_advice(
800+
|| format!("{label} at row: {offset}"),
801+
column,
802+
*offset,
803+
|| value,
804+
)?;
798805
}
799806

800807
// q_step

zkevm-circuits/src/table.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,10 +1694,7 @@ impl CopyTable {
16941694
(is_first, "is_first"),
16951695
(id, "id"),
16961696
(Value::known(addr), "addr"),
1697-
(
1698-
Value::known(F::from(addr_end)),
1699-
"src_addr_end",
1700-
),
1697+
(Value::known(F::from(addr_end)), "src_addr_end"),
17011698
(Value::known(F::from(bytes_left)), "bytes_left"),
17021699
(
17031700
Value::known(F::from(real_length_left as u64)),

0 commit comments

Comments
 (0)