Skip to main content

miden_protocol/note/
inputs.rs

1use alloc::vec::Vec;
2
3use crate::errors::NoteError;
4use crate::utils::serde::{
5    ByteReader,
6    ByteWriter,
7    Deserializable,
8    DeserializationError,
9    Serializable,
10};
11use crate::{Felt, Hasher, MAX_INPUTS_PER_NOTE, Word};
12
13// NOTE INPUTS
14// ================================================================================================
15
16/// A container for note inputs.
17///
18/// A note can be associated with up to 1024 input values. Each value is represented by a single
19/// field element. Thus, note input values can contain up to ~8 KB of data.
20///
21/// All inputs associated with a note can be reduced to a single commitment which is computed as an
22/// RPO256 hash over the input elements.
23#[derive(Clone, Debug)]
24pub struct NoteInputs {
25    values: Vec<Felt>,
26    commitment: Word,
27}
28
29impl NoteInputs {
30    // CONSTRUCTOR
31    // --------------------------------------------------------------------------------------------
32
33    /// Returns [NoteInputs] instantiated from the provided values.
34    ///
35    /// # Errors
36    /// Returns an error if the number of provided inputs is greater than 1024.
37    pub fn new(values: Vec<Felt>) -> Result<Self, NoteError> {
38        if values.len() > MAX_INPUTS_PER_NOTE {
39            return Err(NoteError::TooManyInputs(values.len()));
40        }
41
42        let commitment = Hasher::hash_elements(&values);
43
44        Ok(Self { values, commitment })
45    }
46
47    // PUBLIC ACCESSORS
48    // --------------------------------------------------------------------------------------------
49
50    /// Returns a commitment to these inputs.
51    pub fn commitment(&self) -> Word {
52        self.commitment
53    }
54
55    /// Returns the number of input values.
56    ///
57    /// The returned value is guaranteed to be smaller than or equal to 1024.
58    pub fn num_values(&self) -> u16 {
59        const _: () = assert!(MAX_INPUTS_PER_NOTE <= u16::MAX as usize);
60        debug_assert!(
61            self.values.len() <= MAX_INPUTS_PER_NOTE,
62            "The constructor should have checked the number of inputs"
63        );
64        self.values.len() as u16
65    }
66
67    /// Returns a reference to the input values.
68    pub fn values(&self) -> &[Felt] {
69        &self.values
70    }
71
72    /// Returns the note's input as a vector of field elements.
73    pub fn to_elements(&self) -> Vec<Felt> {
74        self.values.to_vec()
75    }
76}
77
78impl Default for NoteInputs {
79    fn default() -> Self {
80        Self::new(vec![]).expect("empty values should be valid")
81    }
82}
83
84impl PartialEq for NoteInputs {
85    fn eq(&self, other: &Self) -> bool {
86        let NoteInputs { values: inputs, commitment: _ } = self;
87        inputs == &other.values
88    }
89}
90
91impl Eq for NoteInputs {}
92
93// CONVERSION
94// ================================================================================================
95
96impl From<NoteInputs> for Vec<Felt> {
97    fn from(value: NoteInputs) -> Self {
98        value.values
99    }
100}
101
102impl TryFrom<Vec<Felt>> for NoteInputs {
103    type Error = NoteError;
104
105    fn try_from(value: Vec<Felt>) -> Result<Self, Self::Error> {
106        NoteInputs::new(value)
107    }
108}
109
110// SERIALIZATION
111// ================================================================================================
112
113impl Serializable for NoteInputs {
114    fn write_into<W: ByteWriter>(&self, target: &mut W) {
115        let NoteInputs { values, commitment: _commitment } = self;
116        target.write_u16(values.len().try_into().expect("inputs len is not a u16 value"));
117        target.write_many(values);
118    }
119}
120
121impl Deserializable for NoteInputs {
122    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
123        let num_values = source.read_u16()? as usize;
124        let values = source.read_many::<Felt>(num_values)?;
125        Self::new(values).map_err(|v| DeserializationError::InvalidValue(format!("{v}")))
126    }
127}
128
129// TESTS
130// ================================================================================================
131
132#[cfg(test)]
133mod tests {
134    use miden_crypto::utils::Deserializable;
135
136    use super::{Felt, NoteInputs, Serializable};
137
138    #[test]
139    fn test_input_ordering() {
140        // inputs are provided in reverse stack order
141        let inputs = vec![Felt::new(1), Felt::new(2), Felt::new(3)];
142        // we expect the inputs to remain in reverse stack order.
143        let expected_ordering = vec![Felt::new(1), Felt::new(2), Felt::new(3)];
144
145        let note_inputs = NoteInputs::new(inputs).expect("note created should succeed");
146        assert_eq!(&expected_ordering, &note_inputs.values);
147    }
148
149    #[test]
150    fn test_input_serialization() {
151        let inputs = vec![Felt::new(1), Felt::new(2), Felt::new(3)];
152        let note_inputs = NoteInputs::new(inputs).unwrap();
153
154        let bytes = note_inputs.to_bytes();
155        let parsed_note_inputs = NoteInputs::read_from_bytes(&bytes).unwrap();
156        assert_eq!(note_inputs, parsed_note_inputs);
157    }
158}