1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
use super::{utils::IntoBytes, BTreeMap, Felt, InputError, MerkleSet, Vec};
// ADVICE INPUTS
// ================================================================================================
/// Inputs container to initialize advice provider for the execution of Miden VM programs.
///
/// The program may request nondeterministic advice inputs from the prover. These inputs are secret
/// inputs. This means that the prover does not need to share them with the verifier.
///
/// There are three types of advice inputs:
///
/// 1. Single advice tape which can contain any number of elements.
/// 2. Multiple advice tapes that can be appended to the main tape, and are mapped by 32 bytes keys.
/// 3. Merkle sets list, which are used to provide nondeterministic inputs for instructions that
/// operates with Merkle trees.
#[derive(Clone, Debug, Default)]
pub struct AdviceInputs {
tape: Vec<Felt>,
values_map: BTreeMap<[u8; 32], Vec<Felt>>,
merkle_sets: BTreeMap<[u8; 32], MerkleSet>,
}
impl AdviceInputs {
// CONSTRUCTORS
// --------------------------------------------------------------------------------------------
/// Attempts to extend the tape values with the given sequence of integers, returning an error
/// if any of the numbers fails while converting to an element `[Felt]`.
pub fn with_tape_values<I>(mut self, iter: I) -> Result<Self, InputError>
where
I: IntoIterator<Item = u64>,
{
let tape = iter
.into_iter()
.map(|v| {
Felt::try_from(v).map_err(|_| {
InputError::NotFieldElement(v, "the provided value isn't a valid field element")
})
})
.collect::<Result<Vec<_>, _>>()?;
self.tape.extend(tape);
Ok(self)
}
/// Extends the tape with the given elements.
pub fn with_tape<I>(mut self, iter: I) -> Self
where
I: IntoIterator<Item = Felt>,
{
self.tape.extend(iter);
self
}
/// Extends the map of values with the given argument, replacing previously inserted items.
pub fn with_values_map<I>(mut self, iter: I) -> Self
where
I: IntoIterator<Item = ([u8; 32], Vec<Felt>)>,
{
self.values_map.extend(iter);
self
}
/// Attempts to extend the Merkle sets with the given argument, failing if a duplicated root is
/// provided.
pub fn with_merkle_sets<I>(mut self, iter: I) -> Result<Self, InputError>
where
I: IntoIterator<Item = MerkleSet>,
{
for set in iter.into_iter() {
let key = set.root().into_bytes();
if self.merkle_sets.contains_key(&key) {
return Err(InputError::DuplicateAdviceRoot(key));
}
self.merkle_sets.insert(key, set);
}
Ok(self)
}
// PUBLIC ACCESSORS
// --------------------------------------------------------------------------------------------
/// Returns a reference to the advice tape.
pub fn tape(&self) -> &[Felt] {
&self.tape
}
/// Fetch a values set mapped by the given key.
pub fn mapped_values(&self, key: &[u8; 32]) -> Option<&[Felt]> {
self.values_map.get(key).map(Vec::as_slice)
}
/// Fetch a Merkle set mapped by the given key.
pub fn merkle_set(&self, key: &[u8; 32]) -> Option<&MerkleSet> {
self.merkle_sets.get(key)
}
// DESTRUCTORS
// --------------------------------------------------------------------------------------------
/// Decomposes these `[Self]` into their raw components.
#[allow(clippy::type_complexity)]
pub(crate) fn into_parts(
self,
) -> (Vec<Felt>, BTreeMap<[u8; 32], Vec<Felt>>, BTreeMap<[u8; 32], MerkleSet>) {
let Self {
tape,
values_map,
merkle_sets,
} = self;
(tape, values_map, merkle_sets)
}
}