Memory Circuit 是一個用來驗證存儲操作(例如,讀取和寫入操作)的零知識證明電路。
在Memory Circuit中,Prover 需要執行以下操作:
MLOAD
和 MSTORE
操作。key
對這些操作進行排序,然後通過 gc
(可能指的是全局計數器 global counter)進一步排序。key
、val
、rw
和 gc
。這些列分別代表:
key
- 我們正在操作的記憶體的關鍵(地址)。val
- 操作後的 memory[key]
的值。rw
- 存取枚舉,其值可以是:
0
- 讀取(Read)1
- 寫入(Write)還使用了一些輔助標註:
key_prev
- 上一行的 key
值。gc_prev
- 上一行的 gc
值。val_prev
- 上一行的 val
值。此外,還有一些約束條件與注意事項:
rw
必須等於 Write 且 val
必須等於 0。這是電路的第一行,並且它不查詢上一行的值。rw
必須屬於 [0, 1],確保它是一個有效的讀/寫標記。key - key_prev
必須在 [0, ?] 範圍內,保證它是非嚴格單調的。val
必須屬於 [0, 255],以確保它是一個位元組值。key
不等於 key_prev
時,rw
必須等於 Write 且 val
必須等於 0,確保新鍵值被初始化為0。key
等於 key_prev
時,gc
必須大於 gc_prev
,確保它是嚴格單調的。rw
等於 Read 時,val
必須等於 val_prev
,確保它是之前寫入的值。def check_memory(row: Row, row_prev: Row):
get_memory_address = lambda row: row.address()
# 2.0. Unused keys are 0
assert row.field_tag() == 0
assert row.storage_key() == Word(0)
assert row.value.hi == 0
assert row.initial_value.hi == 0
# 2.1. First access for a set of all keys
#
# When the set of all keys changes (first access of an address in a call)
# - If READ, value must be 0
if not all_keys_eq(row, row_prev) and row.is_write == 0:
assert row.value.value() == 0
# 2.2. mem_addr in range
assert_in_range(get_memory_address(row), 0, MAX_MEMORY_ADDRESS)
# 2.3. value is a byte
assert_in_range(row.value.value(), 0, 2**8 - 1)
# 2.4. Start initial value is 0
assert row.initial_value.value() == 0
# 2.5. state root does not change
assert row.root == row_prev.root