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

Commit 37be672

Browse files
author
Aurélien Nicolas
committed
memory_opt_pad: replace LtChip with a simple column
1 parent 7f0043f commit 37be672

File tree

2 files changed

+42
-37
lines changed

2 files changed

+42
-37
lines changed

bus-mapping/src/circuit_input_builder/execution.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,16 @@ pub enum NumberOrHash {
346346
}
347347

348348
/// Represents all bytes related in one copy event.
349+
///
350+
/// - When the source is memory, `bytes` is the memory content, including masked areas. The
351+
/// destination data is the non-masked bytes.
352+
/// - When only the destination is memory or log, `bytes` is the memory content to write, including
353+
/// masked areas. The source data is the non-masked bytes.
354+
/// - When both source and destination are memory or log, it is `aux_bytes` that holds the
355+
/// destination memory.
356+
///
357+
/// Additionally, when the destination is memory, `bytes_write_prev` holds the memory content
358+
/// *before* the write.
349359
#[derive(Clone, Debug)]
350360
pub struct CopyBytes {
351361
/// Represents the list of (bytes, is_code, mask) copied during this copy event

zkevm-circuits/src/copy_circuit.rs

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ pub struct CopyCircuitConfig<F> {
102102
pub addr_lt_addr_end: LtConfig<F, 8>,
103103
/// Whether this is the end of a word (last byte).
104104
pub is_word_end: IsEqualConfig<F>,
105-
/// non pad and non mask gadget
106-
pub non_pad_non_mask: LtConfig<F, 1>,
105+
/// non pad and non mask witness to reduce the degree of lookups.
106+
pub non_pad_non_mask: Column<Advice>,
107107
// External tables
108108
/// TxTable
109109
pub tx_table: TxTable,
@@ -199,15 +199,7 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
199199
|_meta| 31.expr(),
200200
);
201201

202-
let non_pad_non_mask = LtChip::configure(
203-
meta,
204-
|meta| meta.query_selector(q_step),
205-
|meta| {
206-
meta.query_advice(is_pad, Rotation::cur())
207-
+ meta.query_advice(mask, Rotation::cur())
208-
},
209-
|_meta| 1.expr(),
210-
);
202+
let non_pad_non_mask = meta.advice_column();
211203

212204
meta.create_gate("decode tag", |meta| {
213205
let enabled = meta.query_fixed(q_enable, Rotation::cur());
@@ -306,6 +298,14 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
306298
meta.query_selector(q_step),
307299
]),
308300
);
301+
cb.require_equal(
302+
"non_pad_non_mask = !pad AND !mask",
303+
meta.query_advice(non_pad_non_mask, Rotation::cur()),
304+
and::expr([
305+
not::expr(meta.query_advice(is_pad, Rotation::cur())),
306+
not::expr(meta.query_advice(mask, Rotation::cur())),
307+
]),
308+
);
309309

310310
// Whether this row is part of an event.
311311
let is_event = meta.query_advice(is_event, Rotation::cur());
@@ -625,6 +625,10 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
625625
},
626626
);
627627

628+
let value_or_pad_2 = meta.query_advice(value, Rotation(2))
629+
* not::expr(meta.query_advice(is_pad, Rotation(2)));
630+
631+
// TODO: check value_acc(0) = value when is_first
628632
cb.require_equal(
629633
"value_acc is same for read-write rows",
630634
meta.query_advice(value_acc, Rotation::cur()),
@@ -641,20 +645,10 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
641645
"value_acc(2) == value_acc(0) * r + value(2)",
642646
meta.query_advice(value_acc, Rotation(2)),
643647
meta.query_advice(value_acc, Rotation::cur()) * challenges.keccak_input()
644-
+ meta.query_advice(value, Rotation(2)),
648+
+ value_or_pad_2,
645649
);
646650
},
647651
);
648-
cb.condition(not::expr(meta.query_advice(mask, Rotation::cur())), |cb| {
649-
cb.require_zero(
650-
"value == 0 when is_pad == 1 for read",
651-
and::expr([
652-
meta.query_advice(is_pad, Rotation::cur()),
653-
meta.query_advice(value, Rotation::cur()),
654-
meta.query_advice(mask, Rotation::cur()),
655-
]),
656-
);
657-
});
658652

659653
cb.require_equal(
660654
"is_pad == 1 - (src_addr < src_addr_end) for read row",
@@ -730,7 +724,7 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
730724
meta.lookup_any("Bytecode lookup", |meta| {
731725
let cond = meta.query_fixed(q_enable, Rotation::cur())
732726
* meta.query_advice(is_bytecode, Rotation::cur())
733-
* non_pad_non_mask.is_lt(meta, None);
727+
* meta.query_advice(non_pad_non_mask, Rotation::cur());
734728

735729
vec![
736730
1.expr(),
@@ -749,7 +743,7 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
749743
meta.lookup_any("Tx calldata lookup", |meta| {
750744
let cond = meta.query_fixed(q_enable, Rotation::cur())
751745
* meta.query_advice(is_tx_calldata, Rotation::cur())
752-
* non_pad_non_mask.is_lt(meta, None);
746+
* meta.query_advice(non_pad_non_mask, Rotation::cur());
753747

754748
vec![
755749
1.expr(),
@@ -806,7 +800,6 @@ impl<F: Field> CopyCircuitConfig<F> {
806800
tag_chip: &BinaryNumberChip<F, CopyDataType, 4>,
807801
lt_chip: &LtChip<F, 8>,
808802
lt_word_end_chip: &IsEqualChip<F>,
809-
non_pad_non_mask_chip: &LtChip<F, 1>,
810803
challenges: Challenges<Value<F>>,
811804
copy_event: &CopyEvent,
812805
) -> Result<(), Error> {
@@ -901,13 +894,14 @@ impl<F: Field> CopyCircuitConfig<F> {
901894

902895
let pad = unwrap_value(circuit_row[7].0);
903896
let mask = unwrap_value(circuit_row[9].0);
904-
905-
non_pad_non_mask_chip.assign(
906-
region,
897+
let non_pad_non_mask = pad.is_zero_vartime() && mask.is_zero_vartime();
898+
region.assign_advice(
899+
|| format!("non_pad_non_mask at row: {offset}"),
900+
self.non_pad_non_mask,
907901
*offset,
908-
pad + mask, // is_pad + mask
909-
F::from(1u64),
902+
|| Value::known(F::from(non_pad_non_mask)),
910903
)?;
904+
911905
// if the memory copy operation is related to precompile calls.
912906
let is_precompiled = CopyDataType::precompile_types().contains(tag);
913907
region.assign_advice(
@@ -972,7 +966,6 @@ impl<F: Field> CopyCircuitConfig<F> {
972966
let tag_chip = BinaryNumberChip::construct(self.copy_table.tag);
973967
let lt_chip = LtChip::construct(self.addr_lt_addr_end);
974968
let lt_word_end_chip = IsEqualChip::construct(self.is_word_end.clone());
975-
let non_pad_non_mask_chip: LtChip<F, 1> = LtChip::construct(self.non_pad_non_mask);
976969

977970
layouter.assign_region(
978971
|| "assign copy table",
@@ -986,6 +979,7 @@ impl<F: Field> CopyCircuitConfig<F> {
986979
region.name_column(|| "front_mask", self.front_mask);
987980
region.name_column(|| "is_code", self.is_code);
988981
region.name_column(|| "is_pad", self.is_pad);
982+
region.name_column(|| "non_pad_non_mask", self.non_pad_non_mask);
989983
region.name_column(|| "is_event", self.is_event);
990984

991985
let mut offset = 0;
@@ -1007,7 +1001,6 @@ impl<F: Field> CopyCircuitConfig<F> {
10071001
&tag_chip,
10081002
&lt_chip,
10091003
&lt_word_end_chip,
1010-
&non_pad_non_mask_chip,
10111004
challenges,
10121005
copy_event,
10131006
)?;
@@ -1022,7 +1015,6 @@ impl<F: Field> CopyCircuitConfig<F> {
10221015
&tag_chip,
10231016
&lt_chip,
10241017
&lt_word_end_chip,
1025-
&non_pad_non_mask_chip,
10261018
)?;
10271019
}
10281020

@@ -1033,7 +1025,6 @@ impl<F: Field> CopyCircuitConfig<F> {
10331025
&tag_chip,
10341026
&lt_chip,
10351027
&lt_word_end_chip,
1036-
&non_pad_non_mask_chip,
10371028
)?;
10381029
self.assign_padding_row(
10391030
&mut region,
@@ -1042,7 +1033,6 @@ impl<F: Field> CopyCircuitConfig<F> {
10421033
&tag_chip,
10431034
&lt_chip,
10441035
&lt_word_end_chip,
1045-
&non_pad_non_mask_chip,
10461036
)?;
10471037

10481038
Ok(())
@@ -1059,7 +1049,6 @@ impl<F: Field> CopyCircuitConfig<F> {
10591049
tag_chip: &BinaryNumberChip<F, CopyDataType, 4>,
10601050
lt_chip: &LtChip<F, 8>,
10611051
lt_word_end_chip: &IsEqualChip<F>,
1062-
non_pad_non_mask_chip: &LtChip<F, 1>,
10631052
) -> Result<(), Error> {
10641053
if !is_last_two {
10651054
// q_enable
@@ -1227,7 +1216,13 @@ impl<F: Field> CopyCircuitConfig<F> {
12271216
Value::known(F::zero()),
12281217
Value::known(F::from(31u64)),
12291218
)?;
1230-
non_pad_non_mask_chip.assign(region, *offset, F::one(), F::one())?;
1219+
region.assign_advice(
1220+
|| format!("non_pad_non_mask at row: {offset}"),
1221+
self.non_pad_non_mask,
1222+
*offset,
1223+
|| Value::known(F::zero()),
1224+
)?;
1225+
12311226
for column in [
12321227
self.is_precompiled,
12331228
self.is_tx_calldata,

0 commit comments

Comments
 (0)