1extern crate alloc;
2
3use alloc::vec::Vec;
4
5use miden_stdlib_sys::{Felt, Word, WordAligned};
6
7use super::{
8 AccountId, MAX_ATTACHMENT_WORDS, MAX_ATTACHMENTS_PER_NOTE, NoteType, RawAccountId,
9 RawAttachmentLocation, Recipient, Tag, assert_attachment_count, assert_attachment_word_count,
10};
11
12const MAX_NOTE_STORAGE_ITEMS: usize = 1024;
13
14#[allow(improper_ctypes)]
15unsafe extern "C" {
16 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
17 #[link_name = "miden::protocol::note::compute_and_store_recipient"]
18 fn extern_note_build_recipient(
19 storage_ptr: *mut Felt,
20 num_storage_items: usize,
21 serial_num_f0: Felt,
22 serial_num_f1: Felt,
23 serial_num_f2: Felt,
24 serial_num_f3: Felt,
25 script_root_f0: Felt,
26 script_root_f1: Felt,
27 script_root_f2: Felt,
28 script_root_f3: Felt,
29 ptr: *mut Recipient,
30 );
31 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
32 #[link_name = "miden::protocol::note::compute_storage_commitment"]
33 fn extern_note_compute_storage_commitment(
34 storage_ptr: *const Felt,
35 num_storage_items: usize,
36 ptr: *mut Word,
37 );
38 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
39 #[link_name = "miden::protocol::note::write_attachment_commitments_to_memory"]
40 fn extern_note_write_attachment_commitments_to_memory(
41 attachments_commitment_f0: Felt,
42 attachments_commitment_f1: Felt,
43 attachments_commitment_f2: Felt,
44 attachments_commitment_f3: Felt,
45 dest_ptr: *mut Felt,
46 ) -> usize;
47 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
48 #[link_name = "miden::protocol::note::write_attachment_to_memory"]
49 fn extern_note_write_attachment_to_memory(
50 attachment_commitment_f0: Felt,
51 attachment_commitment_f1: Felt,
52 attachment_commitment_f2: Felt,
53 attachment_commitment_f3: Felt,
54 dest_ptr: *mut Felt,
55 ) -> usize;
56 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
57 #[link_name = "miden::protocol::note::write_indexed_attachment_to_memory"]
58 fn extern_note_write_indexed_attachment_to_memory(
59 num_attachments: Felt,
60 attachment_commitments_ptr: *const Felt,
61 attachment_idx: Felt,
62 dest_ptr: *mut Felt,
63 ) -> usize;
64 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
65 #[link_name = "miden::protocol::note::compute_recipient"]
66 fn extern_note_compute_recipient(
67 serial_num_f0: Felt,
68 serial_num_f1: Felt,
69 serial_num_f2: Felt,
70 serial_num_f3: Felt,
71 script_root_f0: Felt,
72 script_root_f1: Felt,
73 script_root_f2: Felt,
74 script_root_f3: Felt,
75 storage_commitment_f0: Felt,
76 storage_commitment_f1: Felt,
77 storage_commitment_f2: Felt,
78 storage_commitment_f3: Felt,
79 ptr: *mut Recipient,
80 );
81 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
82 #[link_name = "miden::protocol::note::metadata_into_sender"]
83 fn extern_note_metadata_into_sender(
84 metadata_f0: Felt,
85 metadata_f1: Felt,
86 metadata_f2: Felt,
87 metadata_f3: Felt,
88 ptr: *mut RawAccountId,
89 );
90 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
91 #[link_name = "miden::protocol::note::metadata_into_attachment_schemes"]
92 fn extern_note_metadata_into_attachment_schemes(
93 metadata_f0: Felt,
94 metadata_f1: Felt,
95 metadata_f2: Felt,
96 metadata_f3: Felt,
97 ptr: *mut Word,
98 );
99 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
100 #[link_name = "miden::protocol::note::metadata_into_note_type"]
101 fn extern_note_metadata_into_note_type(
102 metadata_f0: Felt,
103 metadata_f1: Felt,
104 metadata_f2: Felt,
105 metadata_f3: Felt,
106 ) -> Felt;
107 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
108 #[link_name = "miden::protocol::note::metadata_into_tag"]
109 fn extern_note_metadata_into_tag(
110 metadata_f0: Felt,
111 metadata_f1: Felt,
112 metadata_f2: Felt,
113 metadata_f3: Felt,
114 ) -> Felt;
115 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
116 #[link_name = "miden::protocol::note::find_attachment_idx"]
117 fn extern_note_find_attachment_idx(
118 attachment_scheme: Felt,
119 metadata_f0: Felt,
120 metadata_f1: Felt,
121 metadata_f2: Felt,
122 metadata_f3: Felt,
123 ptr: *mut RawAttachmentLocation,
124 );
125 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
128 #[link_name = "intrinsics::note::script_root"]
129 fn extern_note_script_root(ptr: *mut Word);
130}
131
132#[doc(hidden)]
150pub fn __entrypoint_root() -> Word {
151 unsafe {
152 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
153 extern_note_script_root(ret_area.as_mut_ptr());
154 ret_area.into_inner().assume_init()
155 }
156}
157
158pub fn compute_and_store_recipient(
166 serial_num: Word,
167 script_root: Word,
168 storage: Vec<Felt>,
169) -> Recipient {
170 assert!(
171 storage.len() <= MAX_NOTE_STORAGE_ITEMS,
172 "note storage cannot contain more than {MAX_NOTE_STORAGE_ITEMS} items"
173 );
174
175 let rust_ptr = if storage.is_empty() {
176 0
177 } else {
178 storage.as_ptr().addr() as u32
179 };
180 let miden_ptr = rust_ptr / 4;
181
182 assert_eq!(miden_ptr % 4, 0, "storage pointer must be word-aligned");
184
185 unsafe {
186 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Recipient>::uninit());
187 extern_note_build_recipient(
188 miden_ptr as *mut Felt,
189 storage.len(),
190 serial_num[0],
191 serial_num[1],
192 serial_num[2],
193 serial_num[3],
194 script_root[0],
195 script_root[1],
196 script_root[2],
197 script_root[3],
198 ret_area.as_mut_ptr(),
199 );
200 ret_area.into_inner().assume_init()
201 }
202}
203
204pub fn build_recipient(serial_num: Word, script_root: Word, storage: Vec<Felt>) -> Recipient {
208 compute_and_store_recipient(serial_num, script_root, storage)
209}
210
211pub fn compute_storage_commitment(storage: &[Felt]) -> Word {
215 assert!(
216 storage.len() <= MAX_NOTE_STORAGE_ITEMS,
217 "note storage cannot contain more than {MAX_NOTE_STORAGE_ITEMS} items"
218 );
219
220 let rust_ptr = if storage.is_empty() {
221 0
222 } else {
223 storage.as_ptr().addr() as u32
224 };
225 let miden_ptr = rust_ptr / 4;
226
227 assert_eq!(miden_ptr % 4, 0, "storage pointer must be word-aligned");
228
229 unsafe {
230 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
231 extern_note_compute_storage_commitment(
232 miden_ptr as *const Felt,
233 storage.len(),
234 ret_area.as_mut_ptr(),
235 );
236 ret_area.into_inner().assume_init()
237 }
238}
239
240pub fn write_attachment_commitments_to_memory(attachments_commitment: Word) -> Vec<Word> {
244 let mut commitments: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENTS_PER_NOTE);
245 let num_attachments = unsafe {
246 let ptr = (commitments.as_mut_ptr().addr() / 4) as u32;
247 extern_note_write_attachment_commitments_to_memory(
248 attachments_commitment[0],
249 attachments_commitment[1],
250 attachments_commitment[2],
251 attachments_commitment[3],
252 ptr as *mut Felt,
253 )
254 };
255 assert_attachment_count(num_attachments);
256 unsafe {
257 commitments.set_len(num_attachments);
258 }
259 commitments
260}
261
262pub fn write_attachment_to_memory(attachment_commitment: Word) -> Vec<Word> {
266 let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
267 let num_words = unsafe {
268 let ptr = (attachment.as_mut_ptr().addr() / 4) as u32;
269 extern_note_write_attachment_to_memory(
270 attachment_commitment[0],
271 attachment_commitment[1],
272 attachment_commitment[2],
273 attachment_commitment[3],
274 ptr as *mut Felt,
275 )
276 };
277 assert_attachment_word_count(num_words);
278 unsafe {
279 attachment.set_len(num_words);
280 }
281 attachment
282}
283
284pub fn write_indexed_attachment_to_memory(
288 attachment_commitments: &[Word],
289 attachment_idx: u32,
290) -> Vec<Word> {
291 assert_attachment_count(attachment_commitments.len());
292
293 let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
294 let num_words = unsafe {
295 let commitments_ptr = if attachment_commitments.is_empty() {
296 0
297 } else {
298 (attachment_commitments.as_ptr().addr() / 4) as u32
299 };
300 let dest_ptr = (attachment.as_mut_ptr().addr() / 4) as u32;
301 extern_note_write_indexed_attachment_to_memory(
302 Felt::from_u32(attachment_commitments.len() as u32),
303 commitments_ptr as *const Felt,
304 Felt::from_u32(attachment_idx),
305 dest_ptr as *mut Felt,
306 )
307 };
308 assert_attachment_word_count(num_words);
309 unsafe {
310 attachment.set_len(num_words);
311 }
312 attachment
313}
314
315pub fn compute_recipient(
317 serial_num: Word,
318 script_root: Word,
319 storage_commitment: Word,
320) -> Recipient {
321 unsafe {
322 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Recipient>::uninit());
323 extern_note_compute_recipient(
324 serial_num[0],
325 serial_num[1],
326 serial_num[2],
327 serial_num[3],
328 script_root[0],
329 script_root[1],
330 script_root[2],
331 script_root[3],
332 storage_commitment[0],
333 storage_commitment[1],
334 storage_commitment[2],
335 storage_commitment[3],
336 ret_area.as_mut_ptr(),
337 );
338 ret_area.into_inner().assume_init()
339 }
340}
341
342pub fn metadata_into_sender(metadata: Word) -> AccountId {
344 unsafe {
345 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<RawAccountId>::uninit());
346 extern_note_metadata_into_sender(
347 metadata[0],
348 metadata[1],
349 metadata[2],
350 metadata[3],
351 ret_area.as_mut_ptr(),
352 );
353 ret_area.into_inner().assume_init().into_account_id()
354 }
355}
356
357pub fn metadata_into_attachment_schemes(metadata: Word) -> Word {
359 unsafe {
360 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
361 extern_note_metadata_into_attachment_schemes(
362 metadata[0],
363 metadata[1],
364 metadata[2],
365 metadata[3],
366 ret_area.as_mut_ptr(),
367 );
368 ret_area.into_inner().assume_init()
369 }
370}
371
372pub fn metadata_into_note_type(metadata: Word) -> NoteType {
374 unsafe {
375 NoteType::from(extern_note_metadata_into_note_type(
376 metadata[0],
377 metadata[1],
378 metadata[2],
379 metadata[3],
380 ))
381 }
382}
383
384pub fn metadata_into_tag(metadata: Word) -> Tag {
386 unsafe {
387 Tag::from(extern_note_metadata_into_tag(
388 metadata[0],
389 metadata[1],
390 metadata[2],
391 metadata[3],
392 ))
393 }
394}
395
396pub fn find_attachment_idx(attachment_scheme: Felt, metadata: Word) -> Option<u32> {
398 unsafe {
399 let mut ret_area =
400 WordAligned::new(::core::mem::MaybeUninit::<RawAttachmentLocation>::uninit());
401 extern_note_find_attachment_idx(
402 attachment_scheme,
403 metadata[0],
404 metadata[1],
405 metadata[2],
406 metadata[3],
407 ret_area.as_mut_ptr(),
408 );
409 ret_area.into_inner().assume_init().into_attachment_index()
410 }
411}