Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Commit 7f35654

Browse files
Simplify Zero and One Words construction and Address compression (#1746)
### Description While reviewing #1699, I noticed some room to improve the ergonomics of the words. ### Issue Link ### Type of change New feature (non-breaking change which adds functionality) ### Contents - Replaced the `address_word_to_expr` function with the `compress` method so that we can compress a word directly without finding that function to use. - introduced `zero_f` and `one_f` to create zero and one for `Word<F>`. ### Rationale I noticed that it is hard to create a `one()` and `zero()` method for both `Word<Expression<F>>` and `Word<F>`. The compiler complains about implementing duplicated methods. Since we already use `one()` and `zero()` in many places for `Word<Expression<F>>`, I named `zero_f` and `one_f` for the methods for `Word<F>`.
1 parent b303b28 commit 7f35654

File tree

10 files changed

+74
-81
lines changed

10 files changed

+74
-81
lines changed

zkevm-circuits/src/evm_circuit/util.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -449,15 +449,6 @@ pub(crate) fn is_precompiled(address: &Address) -> bool {
449449
address.0[0..19] == [0u8; 19] && (1..=9).contains(&address.0[19])
450450
}
451451

452-
const BASE_128_BYTES: [u8; 32] = [
453-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
454-
];
455-
456-
/// convert address (h160) to single expression.
457-
pub fn address_word_to_expr<F: Field>(address: Word<Expression<F>>) -> Expression<F> {
458-
address.lo() + address.hi() * Expression::Constant(F::from_repr(BASE_128_BYTES).unwrap())
459-
}
460-
461452
/// Helper struct to read rw operations from a step sequentially.
462453
pub(crate) struct StepRws<'a> {
463454
rws: &'a RwMap,

zkevm-circuits/src/evm_circuit/util/constraint_builder.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ use halo2_proofs::{
2828
};
2929

3030
use super::{
31-
address_word_to_expr, rlc, AccountAddress, CachedRegion, CellType, MemoryAddress,
32-
StoredExpression, U64Cell,
31+
rlc, AccountAddress, CachedRegion, CellType, MemoryAddress, StoredExpression, U64Cell,
3332
};
3433

3534
// Max degree allowed in all expressions passing through the ConstraintBuilder.
@@ -859,7 +858,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> {
859858
Target::TxAccessListAccount,
860859
RwValues::new(
861860
tx_id,
862-
address_word_to_expr(account_address),
861+
account_address.compress(),
863862
0.expr(),
864863
Word::zero(),
865864
Word::from_lo_unchecked(value),
@@ -882,7 +881,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> {
882881
Target::TxAccessListAccount,
883882
RwValues::new(
884883
tx_id,
885-
address_word_to_expr(account_address),
884+
account_address.compress(),
886885
0.expr(),
887886
Word::zero(),
888887
Word::from_lo_unchecked(value.clone()),
@@ -905,7 +904,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> {
905904
Target::TxAccessListAccountStorage,
906905
RwValues::new(
907906
tx_id,
908-
address_word_to_expr(account_address),
907+
account_address.compress(),
909908
0.expr(),
910909
storage_key,
911910
value,
@@ -929,7 +928,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> {
929928
Target::TxAccessListAccountStorage,
930929
RwValues::new(
931930
tx_id,
932-
address_word_to_expr(account_address),
931+
account_address.compress(),
933932
0.expr(),
934933
storage_key,
935934
value.clone(),
@@ -994,7 +993,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> {
994993
Target::Account,
995994
RwValues::new(
996995
0.expr(),
997-
address_word_to_expr(account_address),
996+
account_address.compress(),
998997
field_tag.expr(),
999998
Word::zero(),
1000999
value.clone(),
@@ -1017,7 +1016,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> {
10171016
Target::Account,
10181017
RwValues::new(
10191018
0.expr(),
1020-
address_word_to_expr(account_address),
1019+
account_address.compress(),
10211020
field_tag.expr(),
10221021
Word::zero(),
10231022
value,
@@ -1043,7 +1042,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> {
10431042
Target::Storage,
10441043
RwValues::new(
10451044
tx_id,
1046-
address_word_to_expr(account_address),
1045+
account_address.compress(),
10471046
0.expr(),
10481047
key,
10491048
value.clone(),
@@ -1069,7 +1068,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> {
10691068
Target::Storage,
10701069
RwValues::new(
10711070
tx_id,
1072-
address_word_to_expr(account_address),
1071+
account_address.compress(),
10731072
0.expr(),
10741073
key,
10751074
value,

zkevm-circuits/src/mpt_circuit/account_leaf.rs

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,10 @@ impl<F: Field> AccountLeafConfig<F> {
148148
require!(config.main_data.is_below_account => false);
149149

150150
let mut key_rlc = vec![0.expr(); 2];
151-
let mut nonce = vec![Word::<Expression<F>>::new([0.expr(), 0.expr()]); 2];
152-
let mut balance = vec![Word::<Expression<F>>::new([0.expr(), 0.expr()]); 2];
153-
let mut storage = vec![Word::<Expression<F>>::new([0.expr(), 0.expr()]); 2];
154-
let mut codehash = vec![Word::<Expression<F>>::new([0.expr(), 0.expr()]); 2];
151+
let mut nonce = vec![Word::zero(); 2];
152+
let mut balance = vec![Word::zero(); 2];
153+
let mut storage = vec![Word::zero(); 2];
154+
let mut codehash = vec![Word::zero(); 2];
155155
let mut leaf_no_key_rlc = vec![0.expr(); 2];
156156
let mut leaf_no_key_rlc_mult = vec![0.expr(); 2];
157157
let mut value_list_num_bytes = vec![0.expr(); 2];
@@ -350,8 +350,7 @@ impl<F: Field> AccountLeafConfig<F> {
350350
[
351351
config.main_data.proof_type.expr(),
352352
true.expr(),
353-
address_item.word().lo()
354-
+ address_item.word().hi() * pow::value::<F>(256.scalar(), 16),
353+
address_item.word().compress(),
355354
config.main_data.new_root.lo().expr(),
356355
config.main_data.new_root.hi().expr(),
357356
config.main_data.old_root.lo().expr(),
@@ -424,18 +423,15 @@ impl<F: Field> AccountLeafConfig<F> {
424423
require!((1.expr(), address_item.bytes_le()[1..21].rlc(&cb.keccak_r), 20.expr(), key.lo(), key.hi()) =>> @KECCAK);
425424
}
426425
}};
427-
let to_hi = Expression::<F>::Constant(pow::value::<F>(256.scalar(), 16));
428-
let lo = address_item.word().lo();
429-
let hi = address_item.word().hi() * to_hi;
430-
let address = lo + hi;
426+
let address = address_item.word().compress();
431427

432428
ifx! {not!(config.parent_data[false.idx()].is_placeholder) => {
433429
ctx.mpt_table.constrain(
434430
meta,
435431
&mut cb.base,
436432
address.clone(),
437433
proof_type.clone(),
438-
Word::<Expression<F>>::new([0.expr(), 0.expr()]),
434+
Word::zero(),
439435
config.main_data.new_root.expr(),
440436
config.main_data.old_root.expr(),
441437
Word::<Expression<F>>::new([new_value_lo, new_value_hi]),
@@ -447,10 +443,10 @@ impl<F: Field> AccountLeafConfig<F> {
447443
&mut cb.base,
448444
address,
449445
proof_type,
450-
Word::<Expression<F>>::new([0.expr(), 0.expr()]),
446+
Word::zero(),
451447
config.main_data.new_root.expr(),
452448
config.main_data.old_root.expr(),
453-
Word::<Expression<F>>::new([0.expr(), 0.expr()]),
449+
Word::zero(),
454450
Word::<Expression<F>>::new([old_value_lo, old_value_hi]),
455451
);
456452
}};
@@ -502,10 +498,10 @@ impl<F: Field> AccountLeafConfig<F> {
502498

503499
// Key
504500
let mut key_rlc = vec![0.scalar(); 2];
505-
let mut nonce = vec![Word::<F>::new([0.scalar(), 0.scalar()]); 2];
506-
let mut balance = vec![Word::<F>::new([0.scalar(), 0.scalar()]); 2];
507-
let mut storage = vec![Word::<F>::new([0.scalar(), 0.scalar()]); 2];
508-
let mut codehash = vec![Word::<F>::new([0.scalar(), 0.scalar()]); 2];
501+
let mut nonce = vec![Word::zero_f(); 2];
502+
let mut balance = vec![Word::zero_f(); 2];
503+
let mut storage = vec![Word::zero_f(); 2];
504+
let mut codehash = vec![Word::zero_f(); 2];
509505
let mut key_data = vec![KeyDataWitness::default(); 2];
510506
let mut parent_data = vec![ParentDataWitness::default(); 2];
511507
for is_s in [true, false] {
@@ -654,16 +650,13 @@ impl<F: Field> AccountLeafConfig<F> {
654650
)?;
655651

656652
// Anything following this node is below the account
657-
let lo = address_item.word::<F>().lo();
658-
let hi: F = address_item.word::<F>().hi() * pow::value::<F>(256.scalar(), 16);
659-
let address = lo + hi;
660653
MainData::witness_store(
661654
region,
662655
offset,
663656
&mut memory[main_memory()],
664657
main_data.proof_type,
665658
true,
666-
address,
659+
address_item.word().compress_f(),
667660
main_data.new_root,
668661
main_data.old_root,
669662
)?;
@@ -678,20 +671,11 @@ impl<F: Field> AccountLeafConfig<F> {
678671
} else if is_codehash_mod {
679672
(MPTProofType::CodeHashChanged, codehash)
680673
} else if is_account_delete_mod {
681-
(
682-
MPTProofType::AccountDestructed,
683-
vec![Word::<F>::new([0.scalar(), 0.scalar()]); 2],
684-
)
674+
(MPTProofType::AccountDestructed, vec![Word::zero_f(); 2])
685675
} else if is_non_existing_proof {
686-
(
687-
MPTProofType::AccountDoesNotExist,
688-
vec![Word::<F>::new([0.scalar(), 0.scalar()]); 2],
689-
)
676+
(MPTProofType::AccountDoesNotExist, vec![Word::zero_f(); 2])
690677
} else {
691-
(
692-
MPTProofType::Disabled,
693-
vec![Word::<F>::new([0.scalar(), 0.scalar()]); 2],
694-
)
678+
(MPTProofType::Disabled, vec![Word::zero_f(); 2])
695679
};
696680

697681
if account.is_mod_extension[0] || account.is_mod_extension[1] {
@@ -705,7 +689,7 @@ impl<F: Field> AccountLeafConfig<F> {
705689

706690
let mut new_value = value[false.idx()];
707691
if parent_data[false.idx()].is_placeholder {
708-
new_value = word::Word::<F>::new([0.scalar(), 0.scalar()]);
692+
new_value = word::Word::zero_f();
709693
}
710694
mpt_config.mpt_table.assign_cached(
711695
region,
@@ -714,7 +698,7 @@ impl<F: Field> AccountLeafConfig<F> {
714698
address: Value::known(from_bytes::value(
715699
&account.address.iter().cloned().rev().collect::<Vec<_>>(),
716700
)),
717-
storage_key: word::Word::<F>::new([0.scalar(), 0.scalar()]).into_value(),
701+
storage_key: word::Word::zero_f().into_value(),
718702
proof_type: Value::known(proof_type.scalar()),
719703
new_root: main_data.new_root.into_value(),
720704
old_root: main_data.old_root.into_value(),

zkevm-circuits/src/mpt_circuit/branch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ impl<F: Field> BranchGadget<F> {
351351
let key_mult_post_branch = *key_mult * mult;
352352

353353
// Set the branch we'll take
354-
let mut mod_node_hash_word = [word::Word::<F>::new([0.scalar(), 0.scalar()]); 2];
354+
let mut mod_node_hash_word = [word::Word::zero_f(); 2];
355355
let mut mod_node_hash_rlc = [0.scalar(); 2];
356356
for is_s in [true, false] {
357357
(

zkevm-circuits/src/mpt_circuit/extension.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl<F: Field> ExtensionGadget<F> {
100100
require!((FixedTableTag::ExtOddKey.expr(), first_byte, config.is_key_part_odd.expr()) =>> @FIXED);
101101

102102
let mut branch_rlp_rlc = vec![0.expr(); 2];
103-
let mut branch_rlp_word = vec![Word::<Expression<F>>::new([0.expr(), 0.expr()]); 2];
103+
let mut branch_rlp_word = vec![Word::zero(); 2];
104104
for is_s in [true, false] {
105105
// In C we have the key nibbles, we check below only for S.
106106
if is_s {

zkevm-circuits/src/mpt_circuit/extension_branch.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ impl<F: Field> ExtensionBranchConfig<F> {
158158
branch.mod_rlc[is_s.idx()].expr(),
159159
false.expr(),
160160
false.expr(),
161-
Word::<Expression<F>>::new([0.expr(), 0.expr()])
161+
Word::zero(),
162162
);
163163
} elsex {
164164
KeyData::store(
@@ -287,7 +287,7 @@ impl<F: Field> ExtensionBranchConfig<F> {
287287
mod_node_hash_rlc[is_s.idx()],
288288
false,
289289
false,
290-
Word::<F>::new([0.scalar(), 0.scalar()]),
290+
Word::zero_f(),
291291
)?;
292292
} else {
293293
KeyData::witness_store(

zkevm-circuits/src/mpt_circuit/helpers.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,11 +1081,8 @@ impl<F: Field> IsPlaceholderLeafGadget<F> {
10811081
Expression::Constant(empty_hash.hi()),
10821082
]),
10831083
);
1084-
let is_nil_in_branch_at_mod_index = IsEqualWordGadget::construct(
1085-
&mut cb.base,
1086-
&parent_word,
1087-
&Word::<Expression<F>>::new([0.expr(), 0.expr()]),
1088-
);
1084+
let is_nil_in_branch_at_mod_index =
1085+
IsEqualWordGadget::construct(&mut cb.base, &parent_word, &Word::zero());
10891086

10901087
Self {
10911088
is_empty_trie,

zkevm-circuits/src/mpt_circuit/start.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl<F: Field> StartConfig<F> {
4040

4141
config.proof_type = cb.query_cell();
4242

43-
let mut root = vec![Word::new([0.expr(), 0.expr()]); 2];
43+
let mut root = vec![Word::zero(); 2];
4444
for is_s in [true, false] {
4545
root[is_s.idx()] = root_items[is_s.idx()].word();
4646
}
@@ -96,7 +96,7 @@ impl<F: Field> StartConfig<F> {
9696
self.proof_type
9797
.assign(region, offset, start.proof_type.scalar())?;
9898

99-
let mut root = vec![Word::new([0.scalar(), 0.scalar()]); 2];
99+
let mut root = vec![Word::zero_f(); 2];
100100
for is_s in [true, false] {
101101
root[is_s.idx()] = rlp_values[is_s.idx()].word();
102102
}

zkevm-circuits/src/mpt_circuit/storage_leaf.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl<F: Field> StorageLeafConfig<F> {
104104
require!(config.main_data.is_below_account => true);
105105

106106
let mut key_rlc = vec![0.expr(); 2];
107-
let mut value_word = vec![Word::<Expression<F>>::new([0.expr(), 0.expr()]); 2];
107+
let mut value_word = vec![Word::zero(); 2];
108108
let mut value_rlp_rlc = vec![0.expr(); 2];
109109
let mut value_rlp_rlc_mult = vec![0.expr(); 2];
110110

@@ -179,7 +179,7 @@ impl<F: Field> StorageLeafConfig<F> {
179179

180180
// Placeholder leaves default to value `0`.
181181
ifx! {is_placeholder_leaf => {
182-
require!(value_word[is_s.idx()] => [0.expr(), 0.expr()]);
182+
require!(value_word[is_s.idx()] => Word::zero());
183183
}}
184184

185185
// Make sure the RLP encoding is correct.
@@ -207,11 +207,11 @@ impl<F: Field> StorageLeafConfig<F> {
207207
ParentData::store(
208208
cb,
209209
&mut ctx.memory[parent_memory(is_s)],
210-
word::Word::<Expression<F>>::new([0.expr(), 0.expr()]),
210+
word::Word::zero(),
211211
0.expr(),
212212
true.expr(),
213213
false.expr(),
214-
word::Word::<Expression<F>>::new([0.expr(), 0.expr()]),
214+
word::Word::zero(),
215215
);
216216
}
217217

@@ -332,7 +332,7 @@ impl<F: Field> StorageLeafConfig<F> {
332332
address_item.word(),
333333
config.main_data.new_root.expr(),
334334
config.main_data.old_root.expr(),
335-
Word::<Expression<F>>::new([0.expr(), 0.expr()]),
335+
Word::zero(),
336336
value_word[true.idx()].clone(),
337337
);
338338
}};
@@ -373,7 +373,7 @@ impl<F: Field> StorageLeafConfig<F> {
373373
let mut key_data = vec![KeyDataWitness::default(); 2];
374374
let mut parent_data = vec![ParentDataWitness::default(); 2];
375375
let mut key_rlc = vec![0.scalar(); 2];
376-
let mut value_word = vec![Word::<F>::new([0.scalar(), 0.scalar()]); 2];
376+
let mut value_word = vec![Word::zero_f(); 2];
377377
for is_s in [true, false] {
378378
self.is_mod_extension[is_s.idx()].assign(
379379
region,
@@ -532,7 +532,7 @@ impl<F: Field> StorageLeafConfig<F> {
532532

533533
let mut new_value = value_word[false.idx()];
534534
if parent_data[false.idx()].is_placeholder {
535-
new_value = word::Word::<F>::new([0.scalar(), 0.scalar()]);
535+
new_value = word::Word::zero_f();
536536
}
537537
mpt_config.mpt_table.assign_cached(
538538
region,

0 commit comments

Comments
 (0)