tags |
---|
scroll documentation |
code: https://github.com/scroll-tech/zkevm-circuits/blob/develop/zkevm-circuits/src/pi_circuit.rs develop
branch
PublicData
contains the block header information (block contexts) as well as transactions information. It is structured as follows:
# PublicData
## ChainID (u64Word)
## transactions
- Transaction
- block_number
- id
- hash
- nonce
- gas
- gas_price
- caller_address
- callee_address
- is_create
- value
- call_data
- call_data_length
- call_data_gas_cost
- chain_id
- rlp_unsigned
- rlp_signed
- v
- r
- s
- calls
- steps
- Transaction
- ...
## block_ctxs (BTreeMap: BlockNumber(u64)->BlockContext)
- Block Context
- coinbase
- gas_limit
- number
- timestamp
- difficulty
- base_fee
- history_hashes
- chain_id
- eth_block
- Block Context
- ...
## prev_state_root (256bit hash)
## withdraw_trie_root (256bit hash)
The above PublicData
will be transformed byte by byte into pi_bytes
as the actual pi data:
pi_bytes
chain_id
(u64 Word in big-endian bytes)prev_state_root
(256-bit hash in bytes)after_state_root
(256-bit hash in bytes, obtained from the lastblock_ctx
's state root in the list ofblock_ctxs
)withdraw_trie_root
(256-bit hash in bytes)data_hash
(keccak256 ofdata_bytes
)
where data_bytes
rolls over all block_ctxs
and transactions
to produce an array with the following components
data_bytes
- roll over each
block_ctx
:number
(u64 in big-endian bytes)timestamp
(u64 in big-endian bytes)base_fee
(in big-endian bytes)gas_limit
(in big-endian bytes)num_txs
(in big-endian bytes) which is the number oftransactions
that are included in this block
- roll over each
transaction
:- tx hash (in bytes): Each
tx_hash
is of the formkeccak(rlp(tx_sign))
.
- tx hash (in bytes): Each
- roll over each
Finally pi_hash
is the Keccak256 hash of pi_bytes
.
The above pi_bytes
is assigned to the PI Circuit byte-by-byte. The PI Circuit aims to check the correctness of pi_bytes
by looking up to the Keccak table for pi_hash
and compare the pi_hash
with a given instance of the pi_hash
.
Since the Keccak table only records input RLC and output RLC, to perform the lookup, PI Circuit must record the RLC accumulation of input bytes and (hash) output bytes. This induces further checks about the correctness of these RLC accumulations. These accumulation columns are also re-used to store Keccak input rlc and output rlcs, so they induce many copy constraints. Furthermore, some of the public input data fields such as block context, tx hashes, chain_id, coinbase, difficulty are having connection with the block table and tx table, so copy constraints with them are also established.
PI Circuit is assigned in a byte-by-byte manner that corresponds to each field of the public data information. For each field, the value is decomposed into bytes and assigned in a way that each byte occupies one circuit row. At the boundaries between data fields some selectors/fixed column are turned on/off (true/false).
Also, the columns that are used to store the raw public input bytes, or RLC results, or length can be re-used to store RLC of data bytes, pi bytes, data hash, pi hash etc. This leads to copy constraints that enforce some of the specific cells in the pi circuits that must be equal. The PI circuit is written in a fashion that specific cells in a column may be extracted and then used elsewhere for copy constraint purposes.
The columns of PI circuit are explained as follows:
constant
: Fixed Column. It is dedicated to store coinbase, difficulty in bytes.rpi
: Advice Column, also calledraw_public_inputs
. It stores the RLC (usingevm_word
randomness) or LC (usingBYTE_POW_BASE=256
) of the current field of public input data represented in bytes. The choice of RLC or LC depends on the bit-length of this data field's rpi value under consideration: if this value's bit-length can be hold by a field element's capacity, we use RLC withevm_word
randomness; otherwise, we use LC withBYTE_POW_BASE
(=256) as the LC multiplication factor. This column is also used to store some data bytes, pi bytes and Keccak input RLC result as follows:- After all
data_bytes
fields are assigned, turnq_keccak=1
and record rlc of data bytes viakeccak_input
randomness - After all
pi_bytes
fields are assigned, turnq_keccak=1
and record rlc of pi bytes viakeccak_input
randomness - After all data fields are assigned, this column is used to store RLC of the high 16-byte (
Keccak_hi
) and RLC of the low 16-byte (Keccak_lo
) of thepi_hash=Keccak(pi_bytes)
usingevm_word
randomness.
- After all
rpi_bytes
: Advice Column, also calledrpi_field_bytes
. It fillspi_bytes
in a byte-by-byte manner. After all rpi data field are filled, this column is used to record the high 16 byte and the low 16 byte ofpi_hash
. So a typical assignment has the following order:data_bytes
:- for each
block_ctx
: byte by byte ofblock_number
,time_stamp
,base_fee
,gas_limit
,num_txs
. This will be padded byBlockContext::Padding(chain_id)
until number ofblock_ctx
reachesmax_inner_blocks
; - for each
transaction
: byte by byte oftx_hash
. This will be padded bydummy_tx_hash
(which corresponds to tx private key = 1.) until number oftx_hash
reachesmax_txs
;
- for each
pi_bytes
chain_id
: in big-endian formprevious_state_root
after_state_root
withdraw_trie_root
data_hash
pi_hash
- high 16 bytes
- low 16 bytes
coinbase
:N_BYTES_ACCOUNT_ADDRESS
number of bytesdifficulty
:N_BYTES_WORD
number of bytes
rpi_bytes_acc
: Advice Column, also calledrpi_field_bytes_acc
. It records the accumulation of RLC/LC ofrpi_bytes
. The choice of RLC or LC depends on the bit-length of the current pi data field's value being assigned: if this value's bit-length can be hold by a field element's capacity, we use RLC withevm_word
randomness, and at this timeis_field_rlc
is true; otherwise, we use LC withBYTE_POW_BASE
(=256) to do the LC and at this timeis_field_rlc
is false.rpi_rlc_acc
: Advice Column, cumulative RLC ofrpi_bytes
usingkeccak_input
randomness (because of the need to lookup into Keccak table). This column is also used to store the RLC of data hash and pi hash as follows:- After all
data_bytes
fields are assigned, turnq_keccak=1
and record rlc of data hash viaevm_word
randomness - After all
pi_bytes
fields are assigned, turnq_keccak=1
and record rlc of pi hash viaevm_word
randomness - After all data fields are assigned, this column is used to store cumulative RLC of the high 16-byte (
Keccak_hi
) and cumulative RLC of the low 16-byte (Keccak_lo
) of thepi_hash=Keccak(pi_bytes)
usingevm_word
randomness.
- After all
rpi_length_acc
: Advice column. It is used to record the accumulated length in bytes ofrpi_bytes
. This column is also used to store the length of data bytes and pi bytes as follows:- After all
data_bytes
fields are assigned, turnq_keccak=1
and record the length of data bytes - After all
pi_bytes
fields are assigned, turnq_keccak=1
and record the length of pi bytes - After all data fields are assigned, this column is used to store accumulation of
pi_hash
in bytes with length from 1 to 32.
- After all
is_rpi_padding
: Advice Column. It is true when the currently assigned field is not included in the data bytes. For example, this happens at the padding rows forblock_ctxs
ortransactions
insiderpi_bytes
.real_rpi
: Advice column. Ifis_rpi_padding
then assign 0, otherwise it is the same asrpi
column. This column is used for recording valid block context fields that are copied to block table.pi
: Instance Column. It is used to recordkeccak_hi
andkeccak_lo
q_field_step
: Selector Column. This selector is enabled except when the currently assigned field is running at its last byte.is_field_rlc
: Fixed Column. This is true if the bit-length of the value of currently assigned field can be hold by a field element's capacity.q_block_context
: Fixed Column. This is true when the currently assigned field is indata_bytes
and is related toblock_ctx
information.q_tx_hashes
: Fixed Column. This is true when the currently assigned field is indata_bytes
and is related totransactions
information.q_not_end
: Selector Column. It is enabled during (1)data_bytes
rows; (2)pi_bytes
rows;pi_hash_bytes
rows;is_rlc_keccak
: Fixed Column. This is true when the row is not for storing keccak hi/lo byte cells. This is because on these rows we accumulate Keccak input.q_keccak
: Selector Column. This selector is enabled at the row for computing keccak hash. This happens when therpi_bytes
column is at the row (1) after alldata_bytes
fields are assigned; (2) after allpi_bytes
fields are assigned.q_block_tag
: Fixed Column. This is to connect with the Block Table and is used to indicate that the current row is not the last row of the block table.cum_num_txs
: Advice Column. This is used to record the cumulative number of transactions;is_block_num_txs
: Fixed Column. This is true when the current row corresponds to the block table tag isNumTxs
.
-
correct accumulation of
rpi_bytes_acc
whenq_field_step==1
- when
is_field_rlc==true
:rpi_bytes_acc
accumulatesrpi_bytes
in RLC manner using evm word randomness - when
is_field_rlc==false
:rpi_bytes_acc
accumulatesrpi_bytes
in LC manner using coefficientBYTE_POW_BASE=256
- when
-
correct accumulation of
rpi_rlc_acc
whenq_not_end
is enabled:- when
is_rpi_padding
is false:rpi_rlc_acc
accumulatesrpi_bytes
in an RLC manner usingkeccak_input
randomness - when
is_rpi_padding
is true:rpi_rlc_acc
keeps the same
- when
-
correct accumulation of
rpi_length
whenq_not_end
is enabled- when
is_rpi_padding
is false:rpi_length
increases by 1 - when
is_rpi_padding
is true:rpi_length
keeps the same
- when
-
constraints for padding
- in block context:
q_block_context
is true:is_rpi_padding
is Boolean- when
q_block_context
is true at the next row andis_rpi_padding
is true at the current row, thenis_rpi_padding
is true at the next row real_rpi == not(is_rpi_padding) * rpi
- in tx_hash:
q_tx_hashes
is trueis_rpi_padding
is Boolean- when
q_tx_hashes
is true at the next row andis_rpi_padding
is true at the current row, thenis_rpi_padding
is true at the next row rpi
is RLC of dummy_tx_hash in bytes usingevm_word
randomness whenis_rpi_padding
is true.
- in block context:
-
lookup to keccak table for
keccak(rpi)
whenq_keccak==1
- lookup item
q_keccak * (1, rpi, rpi_length_acc, rpi_rlc_acc)
into keccak table for(is_final, input_rlc, input_length, output_rlc)
- lookup item
-
constraints for the block table: when
q_block_tag
is enabled- for the first row,
cum_num_txs
is 0 - when
is_block_num_txs
is true, increasecum_num_txs
at the next row bynum_txs
in the block, which is fetched from block table; else do not increase
- for the first row,
-
copy constraints:
- inside PI circuit: this is mainly to constrain certain cells are equal due to the design of PI circuit columns. This includes
- copy RLC of
data_bytes
/pi_bytes
fromrpi_rlc_acc
column torpi
column when the latter hasq_keccak==1
- copy RLC of
data_hash
fromrpi_rlc_acc
column torpi
column when the latter hasq_keccak==1
- copy RLC of
pi_hash
fromrpi_rlc_acc
column to itself - within a data field
- rpi_cells are equal
- rpi_cell equals to the last
rpi_bytes_acc
- the first
rpi_bytes_acc
equals to the first byte_cell
- copy RLC of
- copy block context fields, chain_id, coinbase, difficulty to block table
- copy tx_hashes, chain_id, coinbase, difficulty to tx table
- inside PI circuit: this is mainly to constrain certain cells are equal due to the design of PI circuit columns. This includes