miden_protocol/note/
recipient.rs1use alloc::vec::Vec;
2use core::fmt::Debug;
3
4use super::{
5 ByteReader,
6 ByteWriter,
7 Deserializable,
8 DeserializationError,
9 Hasher,
10 NoteScript,
11 NoteStorage,
12 Serializable,
13 Word,
14};
15use crate::Felt;
16
17#[derive(Clone, Debug, PartialEq, Eq)]
28pub struct NoteRecipient {
29 serial_num: Word,
30 script: NoteScript,
31 storage: NoteStorage,
32 digest: Word,
33}
34
35impl NoteRecipient {
36 pub fn new(serial_num: Word, script: NoteScript, storage: NoteStorage) -> Self {
37 let (_, _, digest) = compute_recipient_chain(serial_num, &script, &storage);
38 Self { serial_num, script, storage, digest }
39 }
40
41 pub fn serial_num(&self) -> Word {
46 self.serial_num
47 }
48
49 pub fn script(&self) -> &NoteScript {
51 &self.script
52 }
53
54 pub fn storage(&self) -> &NoteStorage {
56 &self.storage
57 }
58
59 pub fn digest(&self) -> Word {
63 self.digest
64 }
65
66 pub fn to_advice_map_entries(&self) -> [(Word, Vec<Felt>); 5] {
71 let (serial_commitment, serial_script_commitment, digest) =
72 compute_recipient_chain(self.serial_num, &self.script, &self.storage);
73 let script_root = Word::from(self.script.root());
74 let script_encoded = <Vec<Felt>>::from(&self.script);
75
76 [
77 (serial_commitment, concat_words(self.serial_num, Word::empty())),
78 (serial_script_commitment, concat_words(serial_commitment, script_root)),
79 (digest, concat_words(serial_script_commitment, self.storage.commitment())),
80 (self.storage().commitment(), self.storage().to_elements()),
81 (script_root, script_encoded),
82 ]
83 }
84
85 pub fn clear_debug_info(&mut self) {
90 self.script.clear_debug_info();
91 }
92
93 pub fn into_parts(self) -> (Word, NoteScript, NoteStorage) {
95 (self.serial_num, self.script, self.storage)
96 }
97}
98
99fn compute_recipient_chain(
102 serial_num: Word,
103 script: &NoteScript,
104 storage: &NoteStorage,
105) -> (Word, Word, Word) {
106 let serial_commitment = Hasher::merge(&[serial_num, Word::empty()]);
107 let serial_script_commitment = Hasher::merge(&[serial_commitment, script.root().into()]);
108 let recipient_digest = Hasher::merge(&[serial_script_commitment, storage.commitment()]);
109
110 (serial_commitment, serial_script_commitment, recipient_digest)
111}
112
113fn concat_words(first: Word, second: Word) -> Vec<Felt> {
114 let mut elements = Vec::with_capacity(2 * Word::NUM_ELEMENTS);
115 elements.extend(first);
116 elements.extend(second);
117 elements
118}
119
120impl Serializable for NoteRecipient {
124 fn write_into<W: ByteWriter>(&self, target: &mut W) {
125 let Self {
126 script,
127 storage,
128 serial_num,
129
130 digest: _,
133 } = self;
134
135 script.write_into(target);
136 storage.write_into(target);
137 serial_num.write_into(target);
138 }
139
140 fn get_size_hint(&self) -> usize {
141 self.script.get_size_hint() + self.storage.get_size_hint() + Word::SERIALIZED_SIZE
142 }
143}
144
145impl Deserializable for NoteRecipient {
146 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
147 let script = NoteScript::read_from(source)?;
148 let storage = NoteStorage::read_from(source)?;
149 let serial_num = Word::read_from(source)?;
150
151 Ok(Self::new(serial_num, script, storage))
152 }
153}