miden_processor/host/advice/
inputs.rs

1use alloc::vec::Vec;
2
3use miden_core::{
4    AdviceMap, Felt, Word,
5    crypto::merkle::{InnerNodeInfo, MerkleStore},
6    errors::InputError,
7    utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
8};
9
10// ADVICE INPUTS
11// ================================================================================================
12
13/// Inputs container to initialize advice provider for the execution of Miden VM programs.
14///
15/// The program may request nondeterministic advice inputs from the prover. These inputs are secret
16/// inputs. This means that the prover does not need to share them with the verifier.
17///
18/// There are three types of advice inputs:
19///
20/// 1. Single advice stack which can contain any number of elements.
21/// 2. Key-mapped element lists which can be pushed onto the advice stack.
22/// 3. Merkle store, which is used to provide nondeterministic inputs for instructions that operates
23///    with Merkle trees.
24#[derive(Clone, Debug, Default, PartialEq, Eq)]
25pub struct AdviceInputs {
26    pub stack: Vec<Felt>,
27    pub map: AdviceMap,
28    pub store: MerkleStore,
29}
30
31impl AdviceInputs {
32    // CONSTRUCTORS
33    // --------------------------------------------------------------------------------------------
34
35    /// Attempts to extend the stack values with the given sequence of integers, returning an error
36    /// if any of the numbers fails while converting to an element `[Felt]`.
37    pub fn with_stack_values<I>(mut self, iter: I) -> Result<Self, InputError>
38    where
39        I: IntoIterator<Item = u64>,
40    {
41        let stack = iter
42            .into_iter()
43            .map(|v| Felt::try_from(v).map_err(|e| InputError::NotFieldElement(v, e)))
44            .collect::<Result<Vec<_>, _>>()?;
45
46        self.stack.extend(stack.iter());
47        Ok(self)
48    }
49
50    /// Extends the stack with the given elements.
51    pub fn with_stack<I>(mut self, iter: I) -> Self
52    where
53        I: IntoIterator<Item = Felt>,
54    {
55        self.stack.extend(iter);
56        self
57    }
58
59    /// Extends the map of values with the given argument, replacing previously inserted items.
60    pub fn with_map<I>(mut self, iter: I) -> Self
61    where
62        I: IntoIterator<Item = (Word, Vec<Felt>)>,
63    {
64        self.map.extend(iter);
65        self
66    }
67
68    /// Replaces the [MerkleStore] with the provided argument.
69    pub fn with_merkle_store(mut self, store: MerkleStore) -> Self {
70        self.store = store;
71        self
72    }
73
74    // PUBLIC MUTATORS
75    // --------------------------------------------------------------------------------------------
76
77    /// Extends the stack with the given elements.
78    pub fn extend_stack<I>(&mut self, iter: I)
79    where
80        I: IntoIterator<Item = Felt>,
81    {
82        self.stack.extend(iter);
83    }
84
85    /// Extends the map of values with the given argument, replacing previously inserted items.
86    pub fn extend_map<I>(&mut self, iter: I)
87    where
88        I: IntoIterator<Item = (Word, Vec<Felt>)>,
89    {
90        self.map.extend(iter);
91    }
92
93    /// Extends the [MerkleStore] with the given nodes.
94    pub fn extend_merkle_store<I>(&mut self, iter: I)
95    where
96        I: Iterator<Item = InnerNodeInfo>,
97    {
98        self.store.extend(iter);
99    }
100
101    /// Extends the contents of this instance with the contents of the other instance.
102    pub fn extend(&mut self, other: Self) {
103        self.stack.extend(other.stack);
104        self.map.extend(other.map);
105        self.store.extend(other.store.inner_nodes());
106    }
107
108    // PUBLIC ACCESSORS
109    // --------------------------------------------------------------------------------------------
110
111    /// Returns a reference to the advice stack.
112    pub fn stack(&self) -> &[Felt] {
113        &self.stack
114    }
115
116    /// Fetch a values set mapped by the given key.
117    pub fn mapped_values(&self, key: &Word) -> Option<&[Felt]> {
118        self.map.get(key)
119    }
120
121    /// Returns the underlying [MerkleStore].
122    pub const fn merkle_store(&self) -> &MerkleStore {
123        &self.store
124    }
125
126    // DESTRUCTORS
127    // --------------------------------------------------------------------------------------------
128
129    /// Decomposes these `[Self]` into their raw components.
130    #[allow(clippy::type_complexity)]
131    pub(crate) fn into_parts(self) -> (Vec<Felt>, AdviceMap, MerkleStore) {
132        let Self { stack, map, store } = self;
133        (stack, map, store)
134    }
135}
136
137impl Serializable for AdviceInputs {
138    fn write_into<W: ByteWriter>(&self, target: &mut W) {
139        let Self { stack, map, store } = self;
140        stack.write_into(target);
141        map.write_into(target);
142        store.write_into(target);
143    }
144}
145
146impl Deserializable for AdviceInputs {
147    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
148        let stack = Vec::<Felt>::read_from(source)?;
149        let map = AdviceMap::read_from(source)?;
150        let store = MerkleStore::read_from(source)?;
151        Ok(Self { stack, map, store })
152    }
153}
154
155// TESTS
156// ================================================================================================
157
158#[cfg(test)]
159mod tests {
160    use winter_utils::{Deserializable, Serializable};
161
162    use crate::AdviceInputs;
163
164    #[test]
165    fn test_advice_inputs_eq() {
166        let advice1 = AdviceInputs::default();
167        let advice2 = AdviceInputs::default();
168
169        assert_eq!(advice1, advice2);
170
171        let advice1 = AdviceInputs::default().with_stack_values([1, 2, 3].iter().copied()).unwrap();
172        let advice2 = AdviceInputs::default().with_stack_values([1, 2, 3].iter().copied()).unwrap();
173
174        assert_eq!(advice1, advice2);
175    }
176
177    #[test]
178    fn test_advice_inputs_serialization() {
179        let advice1 = AdviceInputs::default().with_stack_values([1, 2, 3].iter().copied()).unwrap();
180        let bytes = advice1.to_bytes();
181        let advice2 = AdviceInputs::read_from_bytes(&bytes).unwrap();
182
183        assert_eq!(advice1, advice2);
184    }
185}