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

Commit 323a4f2

Browse files
DreamWuGitz2trillionz2trillionicemelon
authored
fix tag byte overlap issue #520 (#523)
* fix tag byte overlap issue * fix clippy * Update constraints and bit packing for 5 bit field tags * Update comments * minor update for comment minor update for comment Co-authored-by: Haichen Shen <shenhaichen@gmail.com> Co-authored-by: z2trillion <mason@scroll.tech> Co-authored-by: z2trillion <z2trillion@users.noreply.github.com> Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
1 parent f5c8682 commit 323a4f2

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

zkevm-circuits/src/state_circuit/lexicographic_ordering.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ use std::ops::Mul;
6060

6161
// Packing the field into 480 bits:
6262
// 4 bits for tag,
63-
// + 4 bits for field_tag // TODO: this actually needs 5 bits. Either reduce id
64-
// + 24 bits for id // to 23 bits, or add diff_3 etc.
63+
// + 5 bits for field_tag
64+
// + 23 bits for id
6565
// + 160 bits for address,
6666
// + 256 bits for storage key
6767
// + 32 bits for rw_counter
@@ -294,7 +294,7 @@ impl<F: Field> Queries<F> {
294294
}
295295

296296
fn packed_tags(&self) -> Expression<F> {
297-
(1u64 << 4).expr() * self.tag.clone() + self.field_tag.clone()
297+
(1u64 << 5).expr() * self.tag.clone() + self.field_tag.clone()
298298
}
299299

300300
fn storage_key_be_limbs(&self) -> Vec<Expression<F>> {
@@ -316,25 +316,27 @@ impl<F: Field> Queries<F> {
316316
.chain(self.rw_counter_limbs.iter().rev())
317317
.cloned()
318318
.collect();
319-
// most significant byte of id should be 0, so safe to overwrite it with packed
320-
// tags.
321-
limbs[0] = limbs[0].clone() + self.packed_tags() * (1u64 << 8).expr();
319+
// The packed tags are shifted left by 7 bits so that they occupy the most
320+
// significant 9 bits of the first 16-bit limb.
321+
limbs[0] = limbs[0].clone() + self.packed_tags() * (1u64 << 7).expr();
322322
limbs
323323
}
324324
}
325325

326326
fn rw_to_be_limbs(row: &Rw) -> Vec<u16> {
327+
let mut id = row.id().unwrap_or_default() as u32;
328+
assert_eq!(id.to_be_bytes().len(), 4);
329+
// The max value of `id` is 2^23 - 1, so the 9 most significant bits should be
330+
// 0. We use these 9 bits to hold value of `tag` and `field_tag`.
331+
assert!(id < (1 << 23));
332+
id += (((row.tag() as u32) << 5) + (row.field_tag().unwrap_or_default() as u32)) << 23;
333+
327334
let mut be_bytes = vec![];
328-
be_bytes.extend_from_slice(&(row.id().unwrap_or_default() as u32).to_be_bytes());
335+
be_bytes.extend_from_slice(&id.to_be_bytes());
329336
be_bytes.extend_from_slice(&(row.address().unwrap_or_default().0));
330337
be_bytes.extend_from_slice(&(row.storage_key().unwrap_or_default().to_be_bytes()));
331338
be_bytes.extend_from_slice(&((row.rw_counter() as u32).to_be_bytes()));
332339

333-
// check that the first byte of id is not used, and overwrites it with packed
334-
// tags.
335-
assert_eq!(be_bytes[0], 0);
336-
be_bytes[0] = row.field_tag().unwrap_or_default() as u8 + ((row.tag() as u8) << 4);
337-
338340
be_bytes
339341
.iter()
340342
.tuples()

0 commit comments

Comments
 (0)