Sha256RoundFunction
Sha256RoundFunction PI
Input
pub struct PrecompileFunctionInputData<F: SmallField> {
pub initial_log_queue_state: QueueState<F, QUEUE_STATE_WIDTH>,
pub initial_memory_queue_state: QueueState<F, FULL_SPONGE_QUEUE_STATE_WIDTH>,
}Output
pub struct PrecompileFunctionOutputData<F: SmallField> {
pub final_memory_state: QueueState<F, FULL_SPONGE_QUEUE_STATE_WIDTH>,
}FSM Input and FSM Output
pub struct Sha256RoundFunctionFSMInputOutput<F: SmallField> {
pub internal_fsm: Sha256RoundFunctionFSM<F>,
pub log_queue_state: QueueState<F, QUEUE_STATE_WIDTH>,
pub memory_queue_state: QueueState<F, FULL_SPONGE_QUEUE_STATE_WIDTH>,
}
pub struct Sha256RoundFunctionFSM<F: SmallField> {
pub read_precompile_call: Boolean<F>,
pub read_words_for_round: Boolean<F>,
pub completed: Boolean<F>,
pub sha256_inner_state: [UInt32<F>; 8],
pub timestamp_to_use_for_read: UInt32<F>,
pub timestamp_to_use_for_write: UInt32<F>,
pub precompile_call_params: Sha256PrecompileCallParams<F>,
}Main circuit logic
This is a precompile for the SHA256 hash function’s round function.
We start from witness allocation:
Check if requests_queue_state_from_input is trivial ( we didn't pop elements yet) and choose between input and fsm queue state:
the same procedure we do for memory_queue:
Call inner part where is main logic:
Form the final state (depending on flag we choose between states):
Finally, we compute a commitment to PublicInput and allocate it as witness variables.
Inner part
Start for set up different flags: precompile_address, aux_byte_for_precompile, and plugs:
We can have a degenerate case when the queue is empty, but it's the first circuit in the queue, so we take default FSM state that has state.read_precompile_call = true, we can only skip the full circuit if we are not in any form of progress:
Main work cycle:
Check income data with constants(precompile addresses aux byte for precompile and must match):
Create parameters that describe the call itself:
input_page– memory page forread_queueinput_offset– page indexread_queueoutput_page– memory page forwrite_queueoutput_offset– page indexwrite_queuenum_rounds– number of rounds for hash function
Setup timestamp:
Reset buffer if needed:
Now perform a few memory queries to read content:
We need to change endianness. Memory is BE, and each of the 4-byte chunks should be interpreted as BE u32 for sha256:
get the initial state for SHA256:
finally, compute sha256 and write into memory if we completed all hash rounds. BTW SHA256 algorithm you can read here:
Update state:
Last updated