Skip to main content

miden_test_utils/
host.rs

1use alloc::sync::Arc;
2
3use processor::{
4    AdviceProvider, AdviceSource, DefaultHost, ErrorContext, MastForest, ProcessState,
5};
6use prover::{ExecutionError, Host, MemAdviceProvider};
7use stdlib::{EVENT_FALCON_SIG_TO_STACK, falcon_sign};
8use vm_core::mast::MastNodeExt;
9
10pub struct TestHost(DefaultHost<MemAdviceProvider>);
11
12impl TestHost {
13    pub fn new(advice_provider: MemAdviceProvider) -> Self {
14        Self(DefaultHost::new(advice_provider))
15    }
16
17    pub fn load_mast_forest(&mut self, mast_forest: Arc<MastForest>) -> Result<(), ExecutionError> {
18        self.0.load_mast_forest(mast_forest)
19    }
20
21    pub fn advice_provider(&self) -> &MemAdviceProvider {
22        self.0.advice_provider()
23    }
24
25    pub fn advice_provider_mut(&mut self) -> &mut MemAdviceProvider {
26        self.0.advice_provider_mut()
27    }
28
29    pub fn into_inner(self) -> MemAdviceProvider {
30        self.0.into_inner()
31    }
32}
33
34impl Host for TestHost {
35    type AdviceProvider = MemAdviceProvider;
36
37    fn advice_provider(&self) -> &Self::AdviceProvider {
38        self.0.advice_provider()
39    }
40
41    fn advice_provider_mut(&mut self) -> &mut Self::AdviceProvider {
42        self.0.advice_provider_mut()
43    }
44
45    fn get_mast_forest(&self, node_digest: &prover::Digest) -> Option<Arc<processor::MastForest>> {
46        self.0.get_mast_forest(node_digest)
47    }
48
49    fn on_event(
50        &mut self,
51        process: ProcessState,
52        event_id: u32,
53        err_ctx: &ErrorContext<'_, impl MastNodeExt>,
54    ) -> Result<(), ExecutionError> {
55        if event_id == EVENT_FALCON_SIG_TO_STACK {
56            let advice_provider = self.advice_provider_mut();
57            push_falcon_signature(advice_provider, process, err_ctx)
58        } else {
59            Ok(())
60        }
61    }
62}
63
64/// Pushes values onto the advice stack which are required for verification of a DSA in Miden
65/// VM.
66///
67/// Inputs:
68///   Operand stack: [PK, MSG, ...]
69///   Advice stack: \[ SIGNATURE \]
70///
71/// Outputs:
72///   Operand stack: [PK, MSG, ...]
73///   Advice stack: [...]
74///
75/// Where:
76/// - PK is the digest of an expanded public.
77/// - MSG is the digest of the message to be signed.
78/// - SIGNATURE is the signature being verified.
79///
80/// The advice provider is expected to contain the private key associated to the public key PK.
81pub fn push_falcon_signature(
82    advice_provider: &mut impl AdviceProvider,
83    process: ProcessState,
84    err_ctx: &ErrorContext<'_, impl MastNodeExt>,
85) -> Result<(), ExecutionError> {
86    let pub_key = process.get_stack_word(0);
87    let msg = process.get_stack_word(1);
88
89    let pk_sk = advice_provider
90        .get_mapped_values(&pub_key.into())
91        .ok_or(ExecutionError::advice_map_key_not_found(pub_key, err_ctx))?;
92
93    let result = falcon_sign(pk_sk, msg)
94        .ok_or_else(|| ExecutionError::malformed_signature_key("RPO Falcon512", err_ctx))?;
95
96    for r in result {
97        advice_provider.push_stack(AdviceSource::Value(r), err_ctx)?;
98    }
99    Ok(())
100}