-
Notifications
You must be signed in to change notification settings - Fork 47
/
note.masm
270 lines (226 loc) · 7.42 KB
/
note.masm
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
use.miden::kernel_proc_offsets
use.std::crypto::hashes::rpo
use.std::mem
# ERRORS
# =================================================================================================
# Note data does not match the commitment
const.ERR_NOTE_DATA_DOES_NOT_MATCH_COMMITMENT=0x0002004E
# Number of note inputs exceeded the maximum limit of 128
const.ERR_PROLOGUE_NUMBER_OF_NOTE_INPUTS_EXCEEDED_LIMIT=0x0002004F
#! Writes the data currently on the advice stack into the memory at the specified location and
#! verifies that the hash of the written data is equal to the provided hash.
#!
#! Inputs: [start_ptr, end_ptr, HASH]
#! Outputs: []
#!
#! Invocation: exec
proc.write_advice_data_to_memory
# prepare the stack for reading from the advice stack
padw padw padw
# => [PAD, PAD, PAD, start_ptr, end_ptr, HASH]
# read the data from advice stack to memory
exec.mem::pipe_double_words_to_memory
# => [PERM, PERM, PERM, end_ptr, HASH]
# extract the digest
exec.rpo::squeeze_digest
# => [DIGEST, end_ptr, HASH]
# drop pointer for reading from memory
movup.4 drop
# => [DIGEST, HASH]
# assert the computed hash is equal to the expected hash
assert_eqw.err=ERR_NOTE_DATA_DOES_NOT_MATCH_COMMITMENT
# => []
end
#! Writes the assets of the currently executing note into memory starting at the specified address.
#!
#! Inputs: [dest_ptr]
#! Outputs: [num_assets, dest_ptr]
#!
#! Where:
#! - dest_ptr is the memory address to write the assets.
#! - num_assets is the number of assets in the currently executing note.
#!
#! Invocation: exec
export.get_assets
# pad the stack
padw padw padw push.0.0.0
# => [pad(15), dest_ptr]
exec.kernel_proc_offsets::get_note_assets_info_offset
# => [offset, pad(15), dest_ptr]
syscall.exec_kernel_proc
# => [ASSETS_HASH, num_assets, pad(11), dest_ptr]
# clean the stack
swapdw dropw dropw movup.7 movup.7 movup.7 drop drop drop
# => [ASSETS_HASH, num_assets, dest_ptr]
# load the asset data from the advice map to the advice stack
adv.push_mapval push.15887 drop # TODO: remove line, see miden-vm/#1122
# => [ASSETS_HASH, num_assets, dest_ptr]
# calculate number of assets rounded up to an even number
dup.4 dup is_odd add
# => [even_num_assets, ASSETS_HASH, num_assets, dest_ptr]
# calculate the start and end pointer for reading to memory
dup.6 add dup.6
# => [start_ptr, end_ptr, ASSETS_HASH, num_assets, dest_ptr]
# write the data from the advice stack into memory
exec.write_advice_data_to_memory
# => [num_assets, dest_ptr]
end
#! Loads the note's inputs to `dest_ptr`.
#!
#! Inputs:
#! Stack: [dest_ptr]
#! Advice Map: { INPUTS_HASH: [inputs_len, INPUTS] }
#! Outputs:
#! Stack: [num_inputs, dest_ptr]
#!
#! Where:
#! - dest_ptr is the memory address to write the inputs.
#! - INPUTS_HASH, sequential hash of the padded note's inputs.
#! - inputs_len, the note's input count.
#! - INPUTS, the data corresponding to the note's inputs.
#!
#! Invocation: exec
export.get_inputs
# pad the stack
padw padw padw push.0.0.0
# => [pad(15), dest_ptr]
exec.kernel_proc_offsets::get_note_inputs_hash_offset
# => [offset, pad(15), dest_ptr]
syscall.exec_kernel_proc
# => [INPUTS_HASH, pad(12), dest_ptr]
# clean the stack
swapdw dropw dropw swapw dropw
# => [INPUTS_HASH, dest_ptr]
# load the inputs from the advice map to the advice stack
adv.push_mapval push.15973 drop # TODO: remove line, see miden-vm/#1122
# => [INPUTS_HASH, dest_ptr]
adv_push.1
# => [num_inputs, INPUTS_HASH, dest_ptr]
# validate the input length
dup exec.get_max_inputs_per_note lte
assert.err=ERR_PROLOGUE_NUMBER_OF_NOTE_INPUTS_EXCEEDED_LIMIT
# => [num_inputs, INPUTS_HASH, dest_ptr]
# calculate the number of words required to store the inputs
dup movdn.5 u32divmod.4 neq.0 add
# => [num_words, INPUTS_HASH, num_inputs, dest_ptr]
# round up the number of words the next multiple of 2
dup is_odd add
# => [even_num_words, INPUTS_HASH, num_inputs, dest_ptr]
# calculate the start and end pointer for reading to memory
dup.6 add dup.6
# => [start_ptr, end_ptr, INPUTS_HASH, num_inputs, dest_ptr]
# check the input data matches the commitment, and write it to memory.
exec.write_advice_data_to_memory
# => [num_inputs, dest_ptr]
end
#! Returns the sender of the note currently being processed.
#!
#! Inputs: []
#! Outputs: [sender]
#!
#! Where:
#! - sender is the sender of the note currently being processed.
#!
#! Panics if:
#! - no note is being processed.
#!
#! Invocation: exec
export.get_sender
# pad the stack
padw padw padw push.0.0.0
# => [pad(15)]
exec.kernel_proc_offsets::get_note_sender_offset
# => [offset, pad(15)]
syscall.exec_kernel_proc
# => [sender, pad(15)]
# clean the stack
swapdw dropw dropw swapw dropw movdn.3 drop drop drop
# => [sender]
end
#! Returns the serial number of the note currently being processed.
#!
#! Inputs: []
#! Outputs: [SERIAL_NUMBER]
#!
#! Where:
#! - SERIAL_NUMBER is the serial number of the note currently being processed.
#!
#! Panics if:
#! - no note is being processed.
#!
#! Invocation: exec
export.get_serial_number
# pad the stack
padw padw padw push.0.0.0
# => [pad(15)]
exec.kernel_proc_offsets::get_note_serial_number_offset
# => [offset, pad(15)]
syscall.exec_kernel_proc
# => [SERIAL_NUMBER, pad(12)]
# clean the stack
swapdw dropw dropw swapw dropw
# => [SERIAL_NUMBER]
end
#! Computes hash of note inputs starting at the specified memory address.
#!
#! This procedure checks that the provided number of inputs is within limits and then computes the
#! hash using the procedure from the standard library. See the documentation of the
#! `std::crypto::hashes::rpo::hash_memory` for the more detailed description.
#!
#! If the number if inputs is 0, procedure returns the empty word: [0, 0, 0, 0].
#!
#! Inputs: [inputs_ptr, num_inputs]
#! Outputs: [HASH]
#!
#! Cycles:
#! - If number of elements divides by 8: 56 cycles + 3 * words
#! - Else: 189 cycles + 3 * words
#!
#! Panics if:
#! - num_inputs is greater than 128.
#!
#! Invocation: exec
export.compute_inputs_hash
# check that number of inputs is less than 128
dup.1 push.128 u32assert2 u32lte assert
# compute the hash
exec.rpo::hash_memory
# => [HASH]
end
#! Returns the script hash of the note currently being processed.
#!
#! Inputs: []
#! Outputs: [SCRIPT_HASH]
#!
#! Where:
#! - SCRIPT_HASH is the script hash of the note currently being processed.
#!
#! Panics if:
#! - no note is being processed.
#!
#! Invocation: exec
export.get_script_hash
# pad the stack
padw padw padw push.0.0.0
# => [pad(15)]
exec.kernel_proc_offsets::get_script_hash_offset
# => [offset, pad(15)]
syscall.exec_kernel_proc
# => [SCRIPT_HASH, pad(12)]
# clean the stack
swapdw dropw dropw swapw dropw
# => [SCRIPT_HASH]
end
# PROCEDURES COPIED FROM KERNEL (TODO: get rid of this duplication)
# =================================================================================================
# The maximum number of input values associated with a single note.
const.MAX_INPUTS_PER_NOTE=128
#! Returns the max allowed number of input values per note.
#!
#! Stack: []
#! Output: [max_inputs_per_note]
#!
#! - max_inputs_per_note is the max inputs per note.
export.get_max_inputs_per_note
push.MAX_INPUTS_PER_NOTE
end