use miden_air::{
RowIndex,
trace::{chiplets::hasher::HasherState, decoder::NUM_USER_OP_HELPERS},
};
use miden_core::{
Felt, Operation, QuadFelt, Word, crypto::merkle::MerklePath, mast::MastForest,
precompile::PrecompileTranscriptState,
};
use crate::{
AdviceError, BaseHost, ContextId, ErrorContext, ExecutionError, MemoryError, ProcessState,
fast::Tracer, processor::operations::execute_sync_op,
};
mod operations;
pub trait Processor: Sized {
type System: SystemInterface;
type Stack: StackInterface;
type AdviceProvider: AdviceProviderInterface;
type Memory: MemoryInterface;
type Hasher: HasherInterface;
type HelperRegisters: OperationHelperRegisters;
fn stack(&mut self) -> &mut Self::Stack;
fn system(&mut self) -> &mut Self::System;
fn state(&mut self) -> ProcessState<'_>;
fn advice_provider(&mut self) -> &mut Self::AdviceProvider;
fn memory(&mut self) -> &mut Self::Memory;
fn hasher(&mut self) -> &mut Self::Hasher;
fn precompile_transcript_state(&self) -> PrecompileTranscriptState;
fn set_precompile_transcript_state(&mut self, state: PrecompileTranscriptState);
fn op_eval_circuit(
&mut self,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError>;
fn execute_sync_op(
&mut self,
op: &Operation,
op_idx_in_block: usize,
current_forest: &MastForest,
host: &mut impl BaseHost,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<Option<[Felt; NUM_USER_OP_HELPERS]>, ExecutionError> {
execute_sync_op(self, op, op_idx_in_block, current_forest, host, err_ctx, tracer)
}
}
pub trait SystemInterface {
fn caller_hash(&self) -> Word;
fn clk(&self) -> RowIndex;
fn ctx(&self) -> ContextId;
}
pub trait StackInterface {
fn top(&self) -> &[Felt];
fn top_mut(&mut self) -> &mut [Felt];
fn get(&self, idx: usize) -> Felt;
fn get_mut(&mut self, idx: usize) -> &mut Felt;
fn get_word(&self, start_idx: usize) -> Word;
fn depth(&self) -> u32;
fn set(&mut self, idx: usize, element: Felt);
fn set_word(&mut self, start_idx: usize, word: &Word);
fn swap(&mut self, idx1: usize, idx2: usize);
fn swapw_nth(&mut self, n: usize);
fn rotate_left(&mut self, n: usize);
fn rotate_right(&mut self, n: usize);
fn increment_size(&mut self, tracer: &mut impl Tracer) -> Result<(), ExecutionError>;
fn decrement_size(&mut self, tracer: &mut impl Tracer);
}
pub trait AdviceProviderInterface {
fn pop_stack(&mut self) -> Result<Felt, AdviceError>;
fn pop_stack_word(&mut self) -> Result<Word, AdviceError>;
fn pop_stack_dword(&mut self) -> Result<[Word; 2], AdviceError>;
fn get_merkle_path(
&self,
root: Word,
depth: Felt,
index: Felt,
) -> Result<Option<MerklePath>, AdviceError>;
fn update_merkle_node(
&mut self,
root: Word,
depth: Felt,
index: Felt,
value: Word,
) -> Result<Option<MerklePath>, AdviceError>;
}
pub trait MemoryInterface {
fn read_element(
&mut self,
ctx: ContextId,
addr: Felt,
err_ctx: &impl ErrorContext,
) -> Result<Felt, MemoryError>;
fn read_word(
&mut self,
ctx: ContextId,
addr: Felt,
clk: RowIndex,
err_ctx: &impl ErrorContext,
) -> Result<Word, MemoryError>;
fn write_element(
&mut self,
ctx: ContextId,
addr: Felt,
element: Felt,
err_ctx: &impl ErrorContext,
) -> Result<(), MemoryError>;
fn write_word(
&mut self,
ctx: ContextId,
addr: Felt,
clk: RowIndex,
word: Word,
err_ctx: &impl ErrorContext,
) -> Result<(), MemoryError>;
}
pub trait HasherInterface {
fn permute(&mut self, state: HasherState) -> (Felt, HasherState);
fn verify_merkle_root(
&mut self,
claimed_root: Word,
value: Word,
path: Option<&MerklePath>,
index: Felt,
on_err: impl FnOnce() -> ExecutionError,
) -> Result<Felt, ExecutionError>;
fn update_merkle_root(
&mut self,
claimed_old_root: Word,
old_value: Word,
new_value: Word,
path: Option<&MerklePath>,
index: Felt,
on_err: impl FnOnce() -> ExecutionError,
) -> Result<(Felt, Word), ExecutionError>;
}
pub trait OperationHelperRegisters {
fn op_eq_registers(a: Felt, b: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_u32split_registers(hi: Felt, lo: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_eqz_registers(top: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_expacc_registers(acc_update_val: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_fri_ext2fold4_registers(
ev: QuadFelt,
es: QuadFelt,
x: Felt,
x_inv: Felt,
) -> [Felt; NUM_USER_OP_HELPERS];
fn op_u32add_registers(hi: Felt, lo: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_u32add3_registers(hi: Felt, lo: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_u32sub_registers(second_new: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_u32mul_registers(hi: Felt, lo: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_u32madd_registers(hi: Felt, lo: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_u32div_registers(hi: Felt, lo: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_u32assert2_registers(first: Felt, second: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_hperm_registers(addr: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_log_precompile_registers(addr: Felt, cap_prev: Word) -> [Felt; NUM_USER_OP_HELPERS];
fn op_merkle_path_registers(addr: Felt) -> [Felt; NUM_USER_OP_HELPERS];
fn op_horner_eval_registers(
alpha: QuadFelt,
k0: Felt,
k1: Felt,
acc_tmp: QuadFelt,
) -> [Felt; NUM_USER_OP_HELPERS];
}