miden_objects/note/
inputs.rs1use 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_SIZE, Word, ZERO};
12
13#[derive(Clone, Debug)]
25pub struct NoteInputs {
26 values: Vec<Felt>,
27 commitment: Word,
28}
29
30impl NoteInputs {
31 pub fn new(values: Vec<Felt>) -> Result<Self, NoteError> {
39 if values.len() > MAX_INPUTS_PER_NOTE {
40 return Err(NoteError::TooManyInputs(values.len()));
41 }
42
43 Ok(pad_and_build(values))
44 }
45
46 pub fn commitment(&self) -> Word {
51 self.commitment
52 }
53
54 pub fn num_values(&self) -> u8 {
58 const _: () = assert!(MAX_INPUTS_PER_NOTE <= u8::MAX as usize);
59 debug_assert!(
60 self.values.len() < MAX_INPUTS_PER_NOTE,
61 "The constructor should have checked the number of inputs"
62 );
63 self.values.len() as u8
64 }
65
66 pub fn values(&self) -> &[Felt] {
68 &self.values
69 }
70
71 pub fn format_for_advice(&self) -> Vec<Felt> {
79 pad_inputs(&self.values)
80 }
81}
82
83impl Default for NoteInputs {
84 fn default() -> Self {
85 pad_and_build(vec![])
86 }
87}
88
89impl PartialEq for NoteInputs {
90 fn eq(&self, other: &Self) -> bool {
91 let NoteInputs { values: inputs, commitment: _ } = self;
92 inputs == &other.values
93 }
94}
95
96impl Eq for NoteInputs {}
97
98impl From<NoteInputs> for Vec<Felt> {
102 fn from(value: NoteInputs) -> Self {
103 value.values
104 }
105}
106
107impl TryFrom<Vec<Felt>> for NoteInputs {
108 type Error = NoteError;
109
110 fn try_from(value: Vec<Felt>) -> Result<Self, Self::Error> {
111 NoteInputs::new(value)
112 }
113}
114
115fn pad_inputs(inputs: &[Felt]) -> Vec<Felt> {
120 const BLOCK_SIZE: usize = WORD_SIZE * 2;
121
122 let padded_len = inputs.len().next_multiple_of(BLOCK_SIZE);
123 let mut padded_inputs = Vec::with_capacity(padded_len);
124 padded_inputs.extend(inputs.iter());
125 padded_inputs.resize(padded_len, ZERO);
126
127 padded_inputs
128}
129
130fn pad_and_build(values: Vec<Felt>) -> NoteInputs {
132 let commitment = {
133 let padded_values = pad_inputs(&values);
134 Hasher::hash_elements(&padded_values)
135 };
136
137 NoteInputs { values, commitment }
138}
139
140impl Serializable for NoteInputs {
144 fn write_into<W: ByteWriter>(&self, target: &mut W) {
145 let NoteInputs { values, commitment: _commitment } = self;
146 target.write_u8(values.len().try_into().expect("inputs len is not a u8 value"));
147 target.write_many(values);
148 }
149}
150
151impl Deserializable for NoteInputs {
152 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
153 let num_values = source.read_u8()? as usize;
154 let values = source.read_many::<Felt>(num_values)?;
155 Self::new(values).map_err(|v| DeserializationError::InvalidValue(format!("{v}")))
156 }
157}
158
159#[cfg(test)]
163mod tests {
164 use miden_crypto::utils::Deserializable;
165
166 use super::{Felt, NoteInputs, Serializable};
167
168 #[test]
169 fn test_input_ordering() {
170 let inputs = vec![Felt::new(1), Felt::new(2), Felt::new(3)];
172 let expected_ordering = vec![Felt::new(1), Felt::new(2), Felt::new(3)];
174
175 let note_inputs = NoteInputs::new(inputs).expect("note created should succeed");
176 assert_eq!(&expected_ordering, ¬e_inputs.values);
177 }
178
179 #[test]
180 fn test_input_serialization() {
181 let inputs = vec![Felt::new(1), Felt::new(2), Felt::new(3)];
182 let note_inputs = NoteInputs::new(inputs).unwrap();
183
184 let bytes = note_inputs.to_bytes();
185 let parsed_note_inputs = NoteInputs::read_from_bytes(&bytes).unwrap();
186 assert_eq!(note_inputs, parsed_note_inputs);
187 }
188}