miden_processor/host/
mod.rs1use alloc::sync::Arc;
2
3use vm_core::{
4 crypto::hash::RpoDigest, mast::MastForest, sys_events::SystemEvent, DebugOptions, SignatureKind,
5};
6
7use super::{ExecutionError, ProcessState};
8use crate::{KvMap, MemAdviceProvider};
9
10pub(super) mod advice;
11use advice::AdviceProvider;
12
13#[cfg(feature = "std")]
14mod debug;
15
16mod mast_forest_store;
17pub use mast_forest_store::{MastForestStore, MemMastForestStore};
18
19mod dsa;
20
21pub trait Host {
32 type AdviceProvider: AdviceProvider;
33
34 fn advice_provider(&self) -> &Self::AdviceProvider;
39
40 fn advice_provider_mut(&mut self) -> &mut Self::AdviceProvider;
42
43 fn get_mast_forest(&self, node_digest: &RpoDigest) -> Option<Arc<MastForest>>;
46
47 fn on_event(&mut self, _process: ProcessState, _event_id: u32) -> Result<(), ExecutionError> {
52 #[cfg(feature = "std")]
53 std::println!(
54 "Event with id {} emitted at step {} in context {}",
55 _event_id,
56 _process.clk(),
57 _process.ctx()
58 );
59 Ok(())
60 }
61
62 fn on_debug(
64 &mut self,
65 _process: ProcessState,
66 _options: &DebugOptions,
67 ) -> Result<(), ExecutionError> {
68 #[cfg(feature = "std")]
69 debug::print_debug_info(_process, _options);
70 Ok(())
71 }
72
73 fn on_trace(&mut self, _process: ProcessState, _trace_id: u32) -> Result<(), ExecutionError> {
75 #[cfg(feature = "std")]
76 std::println!(
77 "Trace with id {} emitted at step {} in context {}",
78 _trace_id,
79 _process.clk(),
80 _process.ctx()
81 );
82 Ok(())
83 }
84
85 fn on_assert_failed(&mut self, process: ProcessState, err_code: u32) -> ExecutionError {
87 ExecutionError::FailedAssertion {
88 clk: process.clk(),
89 err_code,
90 err_msg: None,
91 }
92 }
93}
94
95impl<H> Host for &mut H
96where
97 H: Host,
98{
99 type AdviceProvider = H::AdviceProvider;
100
101 fn advice_provider(&self) -> &Self::AdviceProvider {
102 H::advice_provider(self)
103 }
104
105 fn advice_provider_mut(&mut self) -> &mut Self::AdviceProvider {
106 H::advice_provider_mut(self)
107 }
108
109 fn get_mast_forest(&self, node_digest: &RpoDigest) -> Option<Arc<MastForest>> {
110 H::get_mast_forest(self, node_digest)
111 }
112
113 fn on_debug(
114 &mut self,
115 process: ProcessState,
116 options: &DebugOptions,
117 ) -> Result<(), ExecutionError> {
118 H::on_debug(self, process, options)
119 }
120
121 fn on_event(&mut self, process: ProcessState, event_id: u32) -> Result<(), ExecutionError> {
122 H::on_event(self, process, event_id)
123 }
124
125 fn on_trace(&mut self, process: ProcessState, trace_id: u32) -> Result<(), ExecutionError> {
126 H::on_trace(self, process, trace_id)
127 }
128
129 fn on_assert_failed(&mut self, process: ProcessState, err_code: u32) -> ExecutionError {
130 H::on_assert_failed(self, process, err_code)
131 }
132}
133
134pub struct DefaultHost<A> {
139 adv_provider: A,
140 store: MemMastForestStore,
141}
142
143impl<A: Clone> Clone for DefaultHost<A> {
144 fn clone(&self) -> Self {
145 Self {
146 adv_provider: self.adv_provider.clone(),
147 store: self.store.clone(),
148 }
149 }
150}
151
152impl Default for DefaultHost<MemAdviceProvider> {
153 fn default() -> Self {
154 Self {
155 adv_provider: MemAdviceProvider::default(),
156 store: MemMastForestStore::default(),
157 }
158 }
159}
160
161impl<A: AdviceProvider> DefaultHost<A> {
162 pub fn new(adv_provider: A) -> Self {
163 Self {
164 adv_provider,
165 store: MemMastForestStore::default(),
166 }
167 }
168
169 pub fn load_mast_forest(&mut self, mast_forest: Arc<MastForest>) -> Result<(), ExecutionError> {
170 for (digest, values) in mast_forest.advice_map().iter() {
173 if let Some(stored_values) = self.advice_provider().get_mapped_values(digest) {
174 if stored_values != values {
175 return Err(ExecutionError::AdviceMapKeyAlreadyPresent(digest.into()));
176 }
177 } else {
178 self.advice_provider_mut().insert_into_map(digest.into(), values.clone());
179 }
180 }
181
182 self.store.insert(mast_forest);
183 Ok(())
184 }
185
186 #[cfg(any(test, feature = "testing"))]
187 pub fn advice_provider(&self) -> &A {
188 &self.adv_provider
189 }
190
191 #[cfg(any(test, feature = "testing"))]
192 pub fn advice_provider_mut(&mut self) -> &mut A {
193 &mut self.adv_provider
194 }
195
196 pub fn into_inner(self) -> A {
197 self.adv_provider
198 }
199}
200
201impl<A: AdviceProvider> Host for DefaultHost<A> {
202 type AdviceProvider = A;
203
204 fn advice_provider(&self) -> &Self::AdviceProvider {
205 &self.adv_provider
206 }
207
208 fn advice_provider_mut(&mut self) -> &mut Self::AdviceProvider {
209 &mut self.adv_provider
210 }
211
212 fn get_mast_forest(&self, node_digest: &RpoDigest) -> Option<Arc<MastForest>> {
213 self.store.get(node_digest)
214 }
215
216 fn on_event(&mut self, process: ProcessState, event_id: u32) -> Result<(), ExecutionError> {
217 if event_id == SystemEvent::FalconSigToStack.into_event_id() {
218 let advice_provider = self.advice_provider_mut();
222 push_signature(advice_provider, process, SignatureKind::RpoFalcon512)
223 } else {
224 #[cfg(feature = "std")]
225 std::println!(
226 "Event with id {} emitted at step {} in context {}",
227 event_id,
228 process.clk(),
229 process.ctx()
230 );
231 Ok(())
232 }
233 }
234}
235
236pub fn push_signature(
257 advice_provider: &mut impl AdviceProvider,
258 process: ProcessState,
259 kind: SignatureKind,
260) -> Result<(), ExecutionError> {
261 let pub_key = process.get_stack_word(0);
262 let msg = process.get_stack_word(1);
263
264 let pk_sk = advice_provider
265 .get_mapped_values(&pub_key.into())
266 .ok_or(ExecutionError::AdviceMapKeyNotFound(pub_key))?;
267
268 let result = match kind {
269 SignatureKind::RpoFalcon512 => dsa::falcon_sign(pk_sk, msg)?,
270 };
271
272 for r in result {
273 advice_provider.push_stack(crate::AdviceSource::Value(r))?;
274 }
275 Ok(())
276}