@@ -102,8 +102,8 @@ pub struct CopyCircuitConfig<F> {
102
102
pub addr_lt_addr_end : LtConfig < F , 8 > ,
103
103
/// Whether this is the end of a word (last byte).
104
104
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 > ,
107
107
// External tables
108
108
/// TxTable
109
109
pub tx_table : TxTable ,
@@ -199,15 +199,7 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
199
199
|_meta| 31 . expr ( ) ,
200
200
) ;
201
201
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 ( ) ;
211
203
212
204
meta. create_gate ( "decode tag" , |meta| {
213
205
let enabled = meta. query_fixed ( q_enable, Rotation :: cur ( ) ) ;
@@ -306,6 +298,14 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
306
298
meta. query_selector ( q_step) ,
307
299
] ) ,
308
300
) ;
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
+ ) ;
309
309
310
310
// Whether this row is part of an event.
311
311
let is_event = meta. query_advice ( is_event, Rotation :: cur ( ) ) ;
@@ -625,6 +625,10 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
625
625
} ,
626
626
) ;
627
627
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
628
632
cb. require_equal (
629
633
"value_acc is same for read-write rows" ,
630
634
meta. query_advice ( value_acc, Rotation :: cur ( ) ) ,
@@ -641,20 +645,10 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
641
645
"value_acc(2) == value_acc(0) * r + value(2)" ,
642
646
meta. query_advice ( value_acc, Rotation ( 2 ) ) ,
643
647
meta. query_advice ( value_acc, Rotation :: cur ( ) ) * challenges. keccak_input ( )
644
- + meta . query_advice ( value , Rotation ( 2 ) ) ,
648
+ + value_or_pad_2 ,
645
649
) ;
646
650
} ,
647
651
) ;
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
- } ) ;
658
652
659
653
cb. require_equal (
660
654
"is_pad == 1 - (src_addr < src_addr_end) for read row" ,
@@ -730,7 +724,7 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
730
724
meta. lookup_any ( "Bytecode lookup" , |meta| {
731
725
let cond = meta. query_fixed ( q_enable, Rotation :: cur ( ) )
732
726
* 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 ( ) ) ;
734
728
735
729
vec ! [
736
730
1 . expr( ) ,
@@ -749,7 +743,7 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
749
743
meta. lookup_any ( "Tx calldata lookup" , |meta| {
750
744
let cond = meta. query_fixed ( q_enable, Rotation :: cur ( ) )
751
745
* 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 ( ) ) ;
753
747
754
748
vec ! [
755
749
1 . expr( ) ,
@@ -806,7 +800,6 @@ impl<F: Field> CopyCircuitConfig<F> {
806
800
tag_chip : & BinaryNumberChip < F , CopyDataType , 4 > ,
807
801
lt_chip : & LtChip < F , 8 > ,
808
802
lt_word_end_chip : & IsEqualChip < F > ,
809
- non_pad_non_mask_chip : & LtChip < F , 1 > ,
810
803
challenges : Challenges < Value < F > > ,
811
804
copy_event : & CopyEvent ,
812
805
) -> Result < ( ) , Error > {
@@ -901,13 +894,14 @@ impl<F: Field> CopyCircuitConfig<F> {
901
894
902
895
let pad = unwrap_value ( circuit_row[ 7 ] . 0 ) ;
903
896
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 ,
907
901
* offset,
908
- pad + mask, // is_pad + mask
909
- F :: from ( 1u64 ) ,
902
+ || Value :: known ( F :: from ( non_pad_non_mask) ) ,
910
903
) ?;
904
+
911
905
// if the memory copy operation is related to precompile calls.
912
906
let is_precompiled = CopyDataType :: precompile_types ( ) . contains ( tag) ;
913
907
region. assign_advice (
@@ -972,7 +966,6 @@ impl<F: Field> CopyCircuitConfig<F> {
972
966
let tag_chip = BinaryNumberChip :: construct ( self . copy_table . tag ) ;
973
967
let lt_chip = LtChip :: construct ( self . addr_lt_addr_end ) ;
974
968
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 ) ;
976
969
977
970
layouter. assign_region (
978
971
|| "assign copy table" ,
@@ -986,6 +979,7 @@ impl<F: Field> CopyCircuitConfig<F> {
986
979
region. name_column ( || "front_mask" , self . front_mask ) ;
987
980
region. name_column ( || "is_code" , self . is_code ) ;
988
981
region. name_column ( || "is_pad" , self . is_pad ) ;
982
+ region. name_column ( || "non_pad_non_mask" , self . non_pad_non_mask ) ;
989
983
region. name_column ( || "is_event" , self . is_event ) ;
990
984
991
985
let mut offset = 0 ;
@@ -1007,7 +1001,6 @@ impl<F: Field> CopyCircuitConfig<F> {
1007
1001
& tag_chip,
1008
1002
& lt_chip,
1009
1003
& lt_word_end_chip,
1010
- & non_pad_non_mask_chip,
1011
1004
challenges,
1012
1005
copy_event,
1013
1006
) ?;
@@ -1022,7 +1015,6 @@ impl<F: Field> CopyCircuitConfig<F> {
1022
1015
& tag_chip,
1023
1016
& lt_chip,
1024
1017
& lt_word_end_chip,
1025
- & non_pad_non_mask_chip,
1026
1018
) ?;
1027
1019
}
1028
1020
@@ -1033,7 +1025,6 @@ impl<F: Field> CopyCircuitConfig<F> {
1033
1025
& tag_chip,
1034
1026
& lt_chip,
1035
1027
& lt_word_end_chip,
1036
- & non_pad_non_mask_chip,
1037
1028
) ?;
1038
1029
self . assign_padding_row (
1039
1030
& mut region,
@@ -1042,7 +1033,6 @@ impl<F: Field> CopyCircuitConfig<F> {
1042
1033
& tag_chip,
1043
1034
& lt_chip,
1044
1035
& lt_word_end_chip,
1045
- & non_pad_non_mask_chip,
1046
1036
) ?;
1047
1037
1048
1038
Ok ( ( ) )
@@ -1059,7 +1049,6 @@ impl<F: Field> CopyCircuitConfig<F> {
1059
1049
tag_chip : & BinaryNumberChip < F , CopyDataType , 4 > ,
1060
1050
lt_chip : & LtChip < F , 8 > ,
1061
1051
lt_word_end_chip : & IsEqualChip < F > ,
1062
- non_pad_non_mask_chip : & LtChip < F , 1 > ,
1063
1052
) -> Result < ( ) , Error > {
1064
1053
if !is_last_two {
1065
1054
// q_enable
@@ -1227,7 +1216,13 @@ impl<F: Field> CopyCircuitConfig<F> {
1227
1216
Value :: known ( F :: zero ( ) ) ,
1228
1217
Value :: known ( F :: from ( 31u64 ) ) ,
1229
1218
) ?;
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
+
1231
1226
for column in [
1232
1227
self . is_precompiled ,
1233
1228
self . is_tx_calldata ,
0 commit comments