@openzeppelin/miden-multisig-client 0.16.1 → 0.17.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/README.md +192 -11
  2. package/dist/account/builder.d.ts.map +1 -1
  3. package/dist/account/builder.js +32 -25
  4. package/dist/account/builder.js.map +1 -1
  5. package/dist/account/builder.test.js +73 -21
  6. package/dist/account/builder.test.js.map +1 -1
  7. package/dist/account/layout.d.ts +31 -0
  8. package/dist/account/layout.d.ts.map +1 -0
  9. package/dist/account/layout.js +31 -0
  10. package/dist/account/layout.js.map +1 -0
  11. package/dist/account/masm/account-components/auth.d.ts +1 -4
  12. package/dist/account/masm/account-components/auth.d.ts.map +1 -1
  13. package/dist/account/masm/account-components/auth.js +36 -53
  14. package/dist/account/masm/account-components/auth.js.map +1 -1
  15. package/dist/account/masm/index.d.ts +0 -1
  16. package/dist/account/masm/index.d.ts.map +1 -1
  17. package/dist/account/masm/index.js +0 -1
  18. package/dist/account/masm/index.js.map +1 -1
  19. package/dist/account/storage.d.ts +4 -0
  20. package/dist/account/storage.d.ts.map +1 -1
  21. package/dist/account/storage.js +9 -20
  22. package/dist/account/storage.js.map +1 -1
  23. package/dist/client.d.ts +4 -0
  24. package/dist/client.d.ts.map +1 -1
  25. package/dist/client.js +10 -5
  26. package/dist/client.js.map +1 -1
  27. package/dist/client.test.js +74 -16
  28. package/dist/client.test.js.map +1 -1
  29. package/dist/index.d.ts +5 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +3 -3
  32. package/dist/index.js.map +1 -1
  33. package/dist/inspector.d.ts +59 -1
  34. package/dist/inspector.d.ts.map +1 -1
  35. package/dist/inspector.js +157 -29
  36. package/dist/inspector.js.map +1 -1
  37. package/dist/inspector.test.js +246 -37
  38. package/dist/inspector.test.js.map +1 -1
  39. package/dist/multisig.d.ts +109 -33
  40. package/dist/multisig.d.ts.map +1 -1
  41. package/dist/multisig.js +307 -104
  42. package/dist/multisig.js.map +1 -1
  43. package/dist/multisig.test.js +582 -58
  44. package/dist/multisig.test.js.map +1 -1
  45. package/dist/procedures.d.ts +6 -7
  46. package/dist/procedures.d.ts.map +1 -1
  47. package/dist/procedures.js +6 -7
  48. package/dist/procedures.js.map +1 -1
  49. package/dist/proposal/metadata.d.ts.map +1 -1
  50. package/dist/proposal/metadata.js +13 -2
  51. package/dist/proposal/metadata.js.map +1 -1
  52. package/dist/proposal/metadata.test.js +57 -0
  53. package/dist/proposal/metadata.test.js.map +1 -1
  54. package/dist/prover/errors.d.ts +5 -0
  55. package/dist/prover/errors.d.ts.map +1 -1
  56. package/dist/prover/errors.js +7 -155
  57. package/dist/prover/errors.js.map +1 -1
  58. package/dist/prover/errors.test.js +5 -0
  59. package/dist/prover/errors.test.js.map +1 -1
  60. package/dist/prover/retry.d.ts +1 -6
  61. package/dist/prover/retry.d.ts.map +1 -1
  62. package/dist/prover/retry.js +5 -28
  63. package/dist/prover/retry.js.map +1 -1
  64. package/dist/prover/retry.test.js +1 -1
  65. package/dist/prover/retry.test.js.map +1 -1
  66. package/dist/prover/workflow.d.ts +4 -3
  67. package/dist/prover/workflow.d.ts.map +1 -1
  68. package/dist/prover/workflow.js +5 -2
  69. package/dist/prover/workflow.js.map +1 -1
  70. package/dist/prover/workflow.test.js +28 -3
  71. package/dist/prover/workflow.test.js.map +1 -1
  72. package/dist/retry/classify.d.ts +16 -0
  73. package/dist/retry/classify.d.ts.map +1 -0
  74. package/dist/retry/classify.js +187 -0
  75. package/dist/retry/classify.js.map +1 -0
  76. package/dist/retry/runtime.d.ts +13 -0
  77. package/dist/retry/runtime.d.ts.map +1 -0
  78. package/dist/retry/runtime.js +33 -0
  79. package/dist/retry/runtime.js.map +1 -0
  80. package/dist/rpc/config.d.ts +11 -0
  81. package/dist/rpc/config.d.ts.map +1 -0
  82. package/dist/rpc/config.js +17 -0
  83. package/dist/rpc/config.js.map +1 -0
  84. package/dist/rpc/config.test.d.ts +2 -0
  85. package/dist/rpc/config.test.d.ts.map +1 -0
  86. package/dist/rpc/config.test.js +24 -0
  87. package/dist/rpc/config.test.js.map +1 -0
  88. package/dist/rpc/errors.d.ts +2 -0
  89. package/dist/rpc/errors.d.ts.map +1 -0
  90. package/dist/rpc/errors.js +11 -0
  91. package/dist/rpc/errors.js.map +1 -0
  92. package/dist/rpc/errors.test.d.ts +2 -0
  93. package/dist/rpc/errors.test.d.ts.map +1 -0
  94. package/dist/rpc/errors.test.js +34 -0
  95. package/dist/rpc/errors.test.js.map +1 -0
  96. package/dist/rpc/retry.d.ts +4 -0
  97. package/dist/rpc/retry.d.ts.map +1 -0
  98. package/dist/rpc/retry.js +6 -0
  99. package/dist/rpc/retry.js.map +1 -0
  100. package/dist/rpc/retry.test.d.ts +2 -0
  101. package/dist/rpc/retry.test.d.ts.map +1 -0
  102. package/dist/rpc/retry.test.js +98 -0
  103. package/dist/rpc/retry.test.js.map +1 -0
  104. package/dist/transaction/index.d.ts +1 -1
  105. package/dist/transaction/index.d.ts.map +1 -1
  106. package/dist/transaction/index.js +1 -1
  107. package/dist/transaction/index.js.map +1 -1
  108. package/dist/transaction/p2id.d.ts +17 -6
  109. package/dist/transaction/p2id.d.ts.map +1 -1
  110. package/dist/transaction/p2id.js +22 -31
  111. package/dist/transaction/p2id.js.map +1 -1
  112. package/dist/transaction/p2id.test.js +62 -24
  113. package/dist/transaction/p2id.test.js.map +1 -1
  114. package/dist/transaction/summary.d.ts +45 -2
  115. package/dist/transaction/summary.d.ts.map +1 -1
  116. package/dist/transaction/summary.js +42 -2
  117. package/dist/transaction/summary.js.map +1 -1
  118. package/dist/transaction/summary.test.d.ts +2 -0
  119. package/dist/transaction/summary.test.d.ts.map +1 -0
  120. package/dist/transaction/summary.test.js +26 -0
  121. package/dist/transaction/summary.test.js.map +1 -0
  122. package/dist/transaction/updateGuardian.d.ts.map +1 -1
  123. package/dist/transaction/updateGuardian.js +16 -18
  124. package/dist/transaction/updateGuardian.js.map +1 -1
  125. package/dist/transaction/updateProcedureThreshold.d.ts.map +1 -1
  126. package/dist/transaction/updateProcedureThreshold.js +15 -17
  127. package/dist/transaction/updateProcedureThreshold.js.map +1 -1
  128. package/dist/transaction/updateSigners.d.ts +6 -1
  129. package/dist/transaction/updateSigners.d.ts.map +1 -1
  130. package/dist/transaction/updateSigners.js +20 -17
  131. package/dist/transaction/updateSigners.js.map +1 -1
  132. package/dist/transaction.d.ts +2 -2
  133. package/dist/transaction.d.ts.map +1 -1
  134. package/dist/transaction.js +1 -1
  135. package/dist/transaction.js.map +1 -1
  136. package/dist/types/proposal.d.ts +28 -4
  137. package/dist/types/proposal.d.ts.map +1 -1
  138. package/dist/types/proposal.js +18 -0
  139. package/dist/types/proposal.js.map +1 -1
  140. package/dist/types.d.ts +0 -1
  141. package/dist/types.d.ts.map +1 -1
  142. package/dist/utils/signature.d.ts +11 -7
  143. package/dist/utils/signature.d.ts.map +1 -1
  144. package/dist/utils/signature.js +24 -58
  145. package/dist/utils/signature.js.map +1 -1
  146. package/dist/utils/word.d.ts +7 -0
  147. package/dist/utils/word.d.ts.map +1 -1
  148. package/dist/utils/word.js +15 -0
  149. package/dist/utils/word.js.map +1 -1
  150. package/masm/account_components/auth/guarded_multisig.masm +42 -0
  151. package/package.json +7 -4
  152. package/src/account/builder.test.ts +111 -45
  153. package/src/account/builder.ts +45 -33
  154. package/src/account/layout.ts +33 -0
  155. package/src/account/masm/account-components/auth.ts +36 -56
  156. package/src/account/masm/index.ts +0 -1
  157. package/src/account/storage.ts +9 -22
  158. package/src/client.test.ts +87 -16
  159. package/src/client.ts +16 -3
  160. package/src/index.ts +27 -1
  161. package/src/inspector.test.ts +330 -38
  162. package/src/inspector.ts +196 -33
  163. package/src/multisig.test.ts +680 -63
  164. package/src/multisig.ts +400 -115
  165. package/src/procedures.ts +6 -7
  166. package/src/proposal/metadata.test.ts +76 -0
  167. package/src/proposal/metadata.ts +13 -2
  168. package/src/prover/errors.test.ts +8 -0
  169. package/src/prover/errors.ts +7 -175
  170. package/src/prover/retry.test.ts +1 -1
  171. package/src/prover/retry.ts +10 -35
  172. package/src/prover/workflow.test.ts +40 -4
  173. package/src/prover/workflow.ts +16 -4
  174. package/src/retry/classify.ts +220 -0
  175. package/src/retry/runtime.ts +45 -0
  176. package/src/rpc/config.test.ts +45 -0
  177. package/src/rpc/config.ts +30 -0
  178. package/src/rpc/errors.test.ts +69 -0
  179. package/src/rpc/errors.ts +12 -0
  180. package/src/rpc/retry.test.ts +144 -0
  181. package/src/rpc/retry.ts +12 -0
  182. package/src/transaction/index.ts +7 -1
  183. package/src/transaction/p2id.test.ts +112 -31
  184. package/src/transaction/p2id.ts +39 -38
  185. package/src/transaction/summary.test.ts +32 -0
  186. package/src/transaction/summary.ts +83 -4
  187. package/src/transaction/updateGuardian.ts +15 -25
  188. package/src/transaction/updateProcedureThreshold.ts +13 -29
  189. package/src/transaction/updateSigners.ts +38 -30
  190. package/src/transaction.ts +8 -1
  191. package/src/types/proposal.ts +43 -4
  192. package/src/types.ts +0 -1
  193. package/src/utils/signature.ts +32 -65
  194. package/src/utils/word.ts +17 -0
  195. package/dist/account/masm/auth.d.ts +0 -5
  196. package/dist/account/masm/auth.d.ts.map +0 -1
  197. package/dist/account/masm/auth.js +0 -1509
  198. package/dist/account/masm/auth.js.map +0 -1
  199. package/masm/account_components/auth/multisig.masm +0 -12
  200. package/masm/account_components/auth/multisig_ecdsa.masm +0 -12
  201. package/masm/account_components/auth/multisig_guardian.masm +0 -16
  202. package/masm/account_components/auth/multisig_guardian_ecdsa.masm +0 -16
  203. package/masm/auth/guardian.masm +0 -199
  204. package/masm/auth/guardian_ecdsa.masm +0 -195
  205. package/masm/auth/multisig.masm +0 -554
  206. package/masm/auth/multisig_ecdsa.masm +0 -554
  207. package/src/account/masm/auth.ts +0 -1512
@@ -1,554 +0,0 @@
1
- # Multi-Signature RPO Falcon 512 Authentication Core Library
2
- #
3
- # This library provides the reusable multisig procedures used by account wrappers.
4
-
5
- use miden::protocol::active_account
6
- use miden::protocol::auth::AUTH_UNAUTHORIZED_EVENT
7
- use miden::protocol::native_account
8
- use miden::standards::auth
9
-
10
- # CONSTANTS
11
- # =================================================================================================
12
-
13
- # Auth Request Constants
14
-
15
- # Storage Layout Constants
16
- #
17
- # +-------------------------------+----------+------------+--------------+-------------------+
18
- # | THRESHOLD & APPROVERS CONFIG | PUB KEYS | SCHEME IDS | EXECUTED TXS | PROC THRESHOLDS |
19
- # | (slot) | (map) | (map) | (map) | (map) |
20
- # +-------------------------------+----------+------------+--------------+-------------------+
21
- # | 0 | 1 | 2 | 3 | 4 |
22
- # +-------------------------------+----------+------------+--------------+-------------------+
23
-
24
- # The slot in this component's storage layout where the default signature threshold and
25
- # number of approvers are stored as:
26
- # [default_threshold, num_approvers, 0, 0].
27
- # The threshold is guaranteed to be less than or equal to num_approvers.
28
- const THRESHOLD_CONFIG_SLOT=word("openzeppelin::multisig::threshold_config")
29
-
30
- # The slot in this component's storage layout where the public keys map is stored.
31
- # Map entries: [key_index, 0, 0, 0] => APPROVER_PUBLIC_KEY
32
- const PUBLIC_KEYS_MAP_SLOT=word("openzeppelin::multisig::signer_public_keys")
33
-
34
- # The slot in this component's storage layout where signer scheme IDs are stored.
35
- # Map entries: [key_index, 0, 0, 0] => [scheme_id, 0, 0, 0]
36
- const APPROVER_SCHEME_ID_SLOT=word("openzeppelin::multisig::signer_scheme_ids")
37
-
38
- # The slot in this component's storage layout where executed transactions are stored.
39
- # Map entries: transaction_message => [is_executed, 0, 0, 0]
40
- const EXECUTED_TXS_SLOT=word("openzeppelin::multisig::executed_transactions")
41
-
42
- # The slot in this component's storage layout where procedure thresholds are stored.
43
- # Map entries: PROC_ROOT => [proc_threshold, 0, 0, 0]
44
- const PROC_THRESHOLD_ROOTS_SLOT=word("openzeppelin::multisig::procedure_thresholds")
45
-
46
- # Executed Transaction Flag Constant
47
- const IS_EXECUTED_FLAG=[1, 0, 0, 0]
48
- const FALCON_512_POSEIDON2_SCHEME_WORD=[2, 0, 0, 0]
49
-
50
- # ERRORS
51
- const ERR_TX_ALREADY_EXECUTED="failed to approve multisig transaction as it was already executed"
52
-
53
- const ERR_MALFORMED_MULTISIG_CONFIG="number of approvers must be equal to or greater than threshold"
54
-
55
- const ERR_ZERO_IN_MULTISIG_CONFIG="number of approvers or threshold must not be zero"
56
-
57
- const ERR_PROC_THRESHOLD_NOT_U32="procedure threshold must be a u32 value"
58
-
59
- const ERR_NUM_APPROVERS_OR_PROC_THRESHOLD_NOT_U32="number of approvers and procedure threshold must be u32"
60
-
61
- const ERR_PROC_THRESHOLD_EXCEEDS_NUM_APPROVERS="procedure threshold exceeds number of approvers"
62
-
63
- # MULTISIG PROCEDURES
64
- # =================================================================================================
65
-
66
- #! Check if transaction has already been executed and add it to executed transactions for replay protection.
67
- #!
68
- #! Inputs: [MSG]
69
- #! Outputs: []
70
- #!
71
- #! Panics if:
72
- #! - the same transaction has already been executed
73
- pub proc assert_new_tx(msg: word)
74
- push.IS_EXECUTED_FLAG
75
- # => [[0, 0, 0, is_executed], MSG]
76
-
77
- swapw
78
- # => [MSG, IS_EXECUTED_FLAG]
79
-
80
- push.EXECUTED_TXS_SLOT[0..2]
81
- # => [txs_slot_prefix, txs_slot_suffix, MSG, IS_EXECUTED_FLAG]
82
-
83
- # Set the key value pair in the map to mark transaction as executed
84
- exec.native_account::set_map_item
85
- # => [[0, 0, 0, is_executed]]
86
-
87
- drop drop drop
88
- # => [is_executed]
89
-
90
- assertz.err=ERR_TX_ALREADY_EXECUTED
91
- # => []
92
- end
93
-
94
- #! Remove old approver public keys from the approver public key mapping.
95
- #!
96
- #! This procedure cleans up the storage by removing public keys of approvers that are no longer
97
- #! part of the multisig configuration. This procedure assumes that init_num_of_approvers and
98
- #! new_num_of_approvers are u32 values.
99
- #!
100
- #! Inputs: [init_num_of_approvers, new_num_of_approvers]
101
- #! Outputs: []
102
- #!
103
- #! Where:
104
- #! - init_num_of_approvers is the original number of approvers before the update
105
- #! - new_num_of_approvers is the new number of approvers after the update
106
- proc cleanup_pubkey_mapping(init_num_of_approvers: u32, new_num_of_approvers: u32)
107
- dup.1 dup.1
108
- u32assert2 u32lt
109
- # => [should_loop, i = init_num_of_approvers, new_num_of_approvers]
110
-
111
- while.true
112
- # => [i, new_num_of_approvers]
113
-
114
- sub.1
115
- # => [i-1, new_num_of_approvers]
116
-
117
- dup exec.create_approver_map_key
118
- # => [APPROVER_MAP_KEY, i-1, new_num_of_approvers]
119
-
120
- padw swapw
121
- # => [APPROVER_MAP_KEY, EMPTY_WORD, i-1, new_num_of_approvers]
122
-
123
- push.PUBLIC_KEYS_MAP_SLOT[0..2]
124
- # => [pub_key_slot_prefix, pub_key_slot_suffix, APPROVER_MAP_KEY, EMPTY_WORD, i-1, new_num_of_approvers]
125
-
126
- exec.native_account::set_map_item
127
- # => [OLD_MAP_VALUE, i-1, new_num_of_approvers]
128
-
129
- dropw
130
- # => [i-1, new_num_of_approvers]
131
-
132
- dup exec.create_approver_map_key
133
- # => [APPROVER_MAP_KEY, i-1, new_num_of_approvers]
134
-
135
- padw swapw
136
- # => [APPROVER_MAP_KEY, EMPTY_WORD, i-1, new_num_of_approvers]
137
-
138
- push.APPROVER_SCHEME_ID_SLOT[0..2]
139
- # => [scheme_slot_prefix, scheme_slot_suffix, APPROVER_MAP_KEY, EMPTY_WORD, i-1, new_num_of_approvers]
140
-
141
- exec.native_account::set_map_item
142
- # => [OLD_MAP_VALUE, i-1, new_num_of_approvers]
143
-
144
- dropw
145
- # => [i-1, new_num_of_approvers]
146
-
147
- dup.1 dup.1
148
- u32lt
149
- # => [should_loop, i-1, new_num_of_approvers]
150
- end
151
-
152
- drop drop
153
- # => []
154
- end
155
-
156
- proc create_approver_map_key
157
- push.0.0.0 movup.3
158
- # => [APPROVER_MAP_KEY]
159
- end
160
-
161
- proc get_threshold_and_num_approvers
162
- push.THRESHOLD_CONFIG_SLOT[0..2]
163
- exec.active_account::get_initial_item
164
- # => [threshold, num_approvers]
165
-
166
- movup.2 drop movup.2 drop
167
- # => [threshold, num_approvers]
168
- end
169
-
170
- proc assert_proc_thresholds_lte_num_approvers(num_approvers: u32)
171
- exec.active_account::get_num_procedures
172
- # => [num_procedures, num_approvers]
173
-
174
- dup neq.0
175
- # => [should_continue, num_procedures, num_approvers]
176
- while.true
177
- sub.1 dup
178
- # => [proc_index, proc_index, num_approvers]
179
-
180
- exec.active_account::get_procedure_root
181
- # => [PROC_ROOT, proc_index, num_approvers]
182
-
183
- push.PROC_THRESHOLD_ROOTS_SLOT[0..2]
184
- # => [proc_roots_slot_prefix, proc_roots_slot_suffix, PROC_ROOT, proc_index, num_approvers]
185
-
186
- exec.active_account::get_map_item
187
- # => [[proc_threshold, 0, 0, 0], proc_index, num_approvers]
188
-
189
- movdn.3 drop drop drop
190
- # => [proc_threshold, proc_index, num_approvers]
191
-
192
- dup.2
193
- # => [num_approvers, proc_threshold, proc_index, num_approvers]
194
-
195
- u32assert2.err=ERR_PROC_THRESHOLD_NOT_U32
196
- u32gt assertz.err=ERR_PROC_THRESHOLD_EXCEEDS_NUM_APPROVERS
197
- # => [proc_index, num_approvers]
198
-
199
- dup neq.0
200
- # => [should_continue, proc_index, num_approvers]
201
- end
202
-
203
- drop drop
204
- # => []
205
- end
206
-
207
- # Internal storage helper used by the public `update_procedure_threshold`
208
- # entrypoint after it receives direct stack arguments.
209
- proc set_procedure_threshold(proc_threshold: u32, proc_root: word)
210
- exec.get_threshold_and_num_approvers
211
- # => [threshold, num_approvers, proc_threshold, PROC_ROOT]
212
-
213
- drop
214
- # => [num_approvers, proc_threshold, PROC_ROOT]
215
-
216
- dup.1 swap
217
- # => [num_approvers, proc_threshold, proc_threshold, PROC_ROOT]
218
-
219
- u32assert2.err=ERR_NUM_APPROVERS_OR_PROC_THRESHOLD_NOT_U32
220
- u32gt assertz.err=ERR_PROC_THRESHOLD_EXCEEDS_NUM_APPROVERS
221
- # => [proc_threshold, PROC_ROOT]
222
-
223
- push.0.0.0
224
- movup.3
225
- swapw
226
- # => [PROC_ROOT, PROC_THRESHOLD_WORD]
227
-
228
- push.PROC_THRESHOLD_ROOTS_SLOT[0..2]
229
- # => [proc_roots_slot_prefix, proc_roots_slot_suffix, PROC_ROOT, PROC_THRESHOLD_WORD]
230
-
231
- exec.native_account::set_map_item
232
- # => [OLD_VALUE]
233
-
234
- dropw
235
- # => []
236
- end
237
-
238
- #! Update threshold config and add / remove approvers
239
- #!
240
- #! Inputs:
241
- #! Operand stack: [MULTISIG_CONFIG_HASH, pad(12)]
242
- #! Advice map: {
243
- #! MULTISIG_CONFIG_HASH => [CONFIG, PUB_KEY_N, PUB_KEY_N-1, ..., PUB_KEY_0]
244
- #! }
245
- #! Outputs:
246
- #! Operand stack: [TX_SUMMARY_COMMITMENT]
247
- #!
248
- #! Where:
249
- #! - MULTISIG_CONFIG_HASH is the hash of the threshold and new public key vector
250
- #! - MULTISIG_CONFIG is [threshold, num_approvers, 0, 0]
251
- #! - PUB_KEY_i is the public key of the i-th signer
252
- #!
253
- #! Locals:
254
- #! 0: new_num_of_approvers
255
- #! 1: init_num_of_approvers
256
- @locals(2)
257
- pub proc update_signers_and_threshold(multisig_config_hash: word)
258
- adv.push_mapval
259
- # => [MULTISIG_CONFIG_HASH, pad(12)]
260
-
261
- adv_loadw
262
- # => [MULTISIG_CONFIG, pad(12)]
263
-
264
- # store new_num_of_approvers for later
265
- dup.1 loc_store.0
266
- # => [MULTISIG_CONFIG, pad(12)]
267
-
268
- dup dup.2
269
- # => [num_approvers, threshold, MULTISIG_CONFIG, pad(12)]
270
-
271
- # make sure that the threshold is smaller than the number of approvers
272
- u32assert2.err=ERR_MALFORMED_MULTISIG_CONFIG
273
- u32gt assertz.err=ERR_MALFORMED_MULTISIG_CONFIG
274
- # => [MULTISIG_CONFIG, pad(12)]
275
-
276
- dup dup.2
277
- # => [num_approvers, threshold, MULTISIG_CONFIG, pad(12)]
278
-
279
- # make sure that threshold or num_approvers are not zero
280
- eq.0 assertz.err=ERR_ZERO_IN_MULTISIG_CONFIG
281
- eq.0 assertz.err=ERR_ZERO_IN_MULTISIG_CONFIG
282
- # => [MULTISIG_CONFIG, pad(12)]
283
-
284
- loc_load.0
285
- # => [num_approvers, MULTISIG_CONFIG, pad(12)]
286
-
287
- exec.assert_proc_thresholds_lte_num_approvers
288
- # => [MULTISIG_CONFIG, pad(12)]
289
-
290
- push.THRESHOLD_CONFIG_SLOT[0..2]
291
- # => [config_slot_prefix, config_slot_suffix, MULTISIG_CONFIG, pad(12)]
292
-
293
- exec.native_account::set_item
294
- # => [OLD_THRESHOLD_CONFIG, pad(12)]
295
-
296
- # store init_num_of_approvers for later
297
- drop loc_store.1 drop drop
298
- # => [pad(12)]
299
-
300
- loc_load.0
301
- # => [num_approvers]
302
-
303
- dup neq.0
304
- while.true
305
- sub.1
306
- # => [i-1, pad(12)]
307
-
308
- dup exec.create_approver_map_key
309
- # => [APPROVER_MAP_KEY, i-1, pad(12)]
310
-
311
- padw adv_loadw
312
- # => [PUB_KEY, APPROVER_MAP_KEY, i-1, pad(12)]
313
-
314
- swapw
315
- # => [APPROVER_MAP_KEY, PUB_KEY, i-1, pad(12)]
316
-
317
- push.PUBLIC_KEYS_MAP_SLOT[0..2]
318
- # => [pub_key_slot_prefix, pub_key_slot_suffix, APPROVER_MAP_KEY, PUB_KEY, i-1, pad(12)]
319
-
320
- exec.native_account::set_map_item
321
- # => [OLD_VALUE, i-1, pad(12)]
322
-
323
- dropw
324
- # => [i-1, pad(12)]
325
-
326
- dup exec.create_approver_map_key
327
- # => [APPROVER_MAP_KEY, i-1, pad(12)]
328
-
329
- push.FALCON_512_POSEIDON2_SCHEME_WORD
330
- # => [SCHEME_ID_WORD, APPROVER_MAP_KEY, i-1, pad(12)]
331
-
332
- swapw
333
- # => [APPROVER_MAP_KEY, [2, 0, 0, 0], i-1, pad(12)]
334
-
335
- push.APPROVER_SCHEME_ID_SLOT[0..2]
336
- # => [scheme_slot_prefix, scheme_slot_suffix, APPROVER_MAP_KEY, [2, 0, 0, 0], i-1, pad(12)]
337
-
338
- exec.native_account::set_map_item
339
- # => [OLD_VALUE, i-1, pad(12)]
340
-
341
- dropw
342
- # => [i-1, pad(12)]
343
-
344
- dup neq.0
345
- # => [is_non_zero, i-1, pad(12)]
346
- end
347
- # => [pad(13)]
348
-
349
- drop
350
- # => [pad(12)]
351
-
352
- loc_load.0 loc_load.1
353
- # => [init_num_of_approvers, new_num_of_approvers, pad(12)]
354
-
355
- dup.1 dup.1
356
- u32assert2 u32lt
357
- # => [should_cleanup, init_num_of_approvers, new_num_of_approvers, pad(12)]
358
-
359
- if.true
360
- exec.cleanup_pubkey_mapping
361
- # => [pad(12)]
362
- else
363
- drop drop
364
- # => [pad(12)]
365
- end
366
- end
367
-
368
- #! Update or clear the threshold override for a specific procedure.
369
- #!
370
- #! Inputs:
371
- #! Operand stack: [proc_threshold, PROC_ROOT]
372
- #! Outputs:
373
- #! Operand stack: []
374
- #! Invocation: call
375
- pub proc update_procedure_threshold(proc_threshold: u32, proc_root: word)
376
- exec.set_procedure_threshold
377
- end
378
-
379
- # Computes the effective transaction threshold based on called procedures and per-procedure
380
- # overrides stored in PROC_THRESHOLD_ROOTS_SLOT. Falls back to default_threshold if no
381
- # overrides apply.
382
- #
383
- #! Inputs: [default_threshold]
384
- #! Outputs: [transaction_threshold]
385
- @locals(1)
386
- proc compute_transaction_threshold(default_threshold: u32) -> u32
387
- # 1. initialize transaction_threshold = 0
388
- # 2. iterate through all account procedures
389
- # a. check if the procedure was called during the transaction
390
- # b. if called, get the override threshold of that procedure from the config map
391
- # c. if proc_threshold > transaction_threshold, set transaction_threshold = proc_threshold
392
- # 3. if transaction_threshold == 0 at the end, revert to using default_threshold
393
-
394
- # store default_threshold for later
395
- loc_store.0
396
- # => []
397
-
398
- # 1. initialize transaction_threshold = 0
399
- push.0
400
- # => [transaction_threshold]
401
-
402
- # get the number of account procedures
403
- exec.active_account::get_num_procedures
404
- # => [num_procedures, transaction_threshold]
405
-
406
- # 2. iterate through all account procedures
407
- dup neq.0
408
- # => [should_continue, num_procedures, transaction_threshold]
409
- while.true
410
- sub.1 dup
411
- # => [num_procedures-1, num_procedures-1, transaction_threshold]
412
-
413
- # get procedure root of the procedure with index i
414
- exec.active_account::get_procedure_root dupw
415
- # => [PROC_ROOT, PROC_ROOT, num_procedures-1, transaction_threshold]
416
-
417
- # 2a. check if this procedure has been called in the transaction
418
- exec.native_account::was_procedure_called
419
- # => [was_called, PROC_ROOT, num_procedures-1, transaction_threshold]
420
-
421
- # if it has been called, get the override threshold of that procedure
422
- if.true
423
- # => [PROC_ROOT, num_procedures-1, transaction_threshold]
424
-
425
- push.PROC_THRESHOLD_ROOTS_SLOT[0..2]
426
- # => [PROC_THRESHOLD_ROOTS_SLOT_prefix, PROC_THRESHOLD_ROOTS_SLOT_suffix, PROC_ROOT, num_procedures-1, transaction_threshold]
427
-
428
- # 2b. get the override proc_threshold of that procedure
429
- # if the procedure has no override threshold, the returned map item will be [0, 0, 0, 0]
430
- exec.active_account::get_initial_map_item
431
- # => [[proc_threshold, 0, 0, 0], num_procedures-1, transaction_threshold]
432
-
433
- movdn.3 drop drop drop dup dup.3
434
- # => [transaction_threshold, proc_threshold, proc_threshold, num_procedures-1, transaction_threshold]
435
-
436
- u32assert2.err="transaction threshold or procedure threshold are not u32"
437
- u32gt
438
- # => [is_gt, proc_threshold, num_procedures-1, transaction_threshold]
439
- # 2c. if proc_threshold > transaction_threshold, update transaction_threshold
440
- movup.2 movdn.3
441
- # => [is_gt, proc_threshold, transaction_threshold, num_procedures-1]
442
- cdrop
443
- # => [updated_transaction_threshold, num_procedures-1]
444
- swap
445
- # => [num_procedures-1, updated_transaction_threshold]
446
- # if it has not been called during this transaction, nothing to do, move to the next procedure
447
- else
448
- dropw
449
- # => [num_procedures-1, transaction_threshold]
450
- end
451
-
452
- dup neq.0
453
- # => [should_continue, num_procedures-1, transaction_threshold]
454
- end
455
-
456
- drop
457
- # => [transaction_threshold]
458
-
459
- loc_load.0
460
- # => [default_threshold, transaction_threshold]
461
-
462
- # 3. if transaction_threshold == 0 at the end, revert to using default_threshold
463
- dup.1 eq.0
464
- # => [is_zero, default_threshold, transaction_threshold]
465
-
466
- cdrop
467
- # => [effective_transaction_threshold]
468
- end
469
-
470
- #! Authenticate a transaction using the Falcon signature scheme with multi-signature support.
471
- #!
472
- #! This procedure implements multi-signature authentication by:
473
- #! 1. Computing the transaction summary message that needs to be signed
474
- #! 2. Verifying signatures from multiple required signers against their public keys
475
- #! 3. Ensuring the minimum threshold of valid signatures is met
476
- #! 4. Returning the transaction summary commitment for higher-level wrappers.
477
- #!
478
- #! Inputs:
479
- #! Operand stack: [SALT]
480
- #! Advice map: {
481
- #! h(SIG_0, MSG): SIG_0,
482
- #! h(SIG_1, MSG): SIG_1,
483
- #! h(SIG_n, MSG): SIG_n
484
- #! }
485
- #! Outputs:
486
- #! Operand stack: []
487
- #!
488
- #! Where:
489
- #! - SALT is a cryptographically random nonce that enables multiple concurrent
490
- #! multisig transactions while maintaining replay protection. Each transaction
491
- #! must use a unique SALT value to ensure transaction uniqueness.
492
- #! - SIG_i is the signature from the i-th signer.
493
- #! - MSG is the transaction message being signed.
494
- #! - h(SIG_i, MSG) is the hash of the signature and message used as the advice map key.
495
- #!
496
- #! Panics if:
497
- #! - insufficient number of valid signatures (below threshold).
498
- #! - insufficient number of valid signatures (below threshold).
499
- #!
500
- #! Invocation: exec
501
- @locals(1)
502
- pub proc auth_tx(salt: word)
503
- exec.native_account::incr_nonce drop
504
- # => [SALT]
505
-
506
- # ------ Computing transaction summary ------
507
-
508
- exec.auth::create_tx_summary
509
- # => [ACCOUNT_DELTA_COMMITMENT, INPUT_NOTES_COMMITMENT, OUTPUT_NOTES_COMMITMENT, SALT]
510
-
511
- # to build a tx_summary in the host, we need these four words in the advice provider
512
- adv.insert_hqword
513
- # => [ACCOUNT_DELTA_COMMITMENT, INPUT_NOTES_COMMITMENT, OUTPUT_NOTES_COMMITMENT, SALT]
514
-
515
- # the commitment to the tx summary is the message that is signed
516
- exec.auth::hash_tx_summary
517
- # => [TX_SUMMARY_COMMITMENT]
518
-
519
- # ------ Verifying approver signatures ------
520
-
521
- exec.get_threshold_and_num_approvers
522
- # => [default_threshold, num_of_approvers, TX_SUMMARY_COMMITMENT]
523
-
524
- movdn.5
525
- # => [num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
526
-
527
- push.PUBLIC_KEYS_MAP_SLOT[0..2]
528
- # => [pub_key_slot_prefix, pub_key_slot_suffix, num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
529
-
530
- push.APPROVER_SCHEME_ID_SLOT[0..2]
531
- # => [scheme_id_slot_prefix, scheme_id_slot_suffix, pub_key_slot_prefix, pub_key_slot_suffix, num_of_approvers, TX_SUMMARY_COMMITMENT, default_threshold]
532
-
533
- exec.::miden::standards::auth::signature::verify_signatures
534
- # => [num_verified_signatures, TX_SUMMARY_COMMITMENT, default_threshold]
535
-
536
- # ------ Checking threshold is >= num_verified_signatures ------
537
-
538
- movup.5
539
- # => [default_threshold, num_verified_signatures, TX_SUMMARY_COMMITMENT]
540
-
541
- exec.compute_transaction_threshold
542
- # => [transaction_threshold, num_verified_signatures, TX_SUMMARY_COMMITMENT]
543
-
544
- u32assert2 u32lt
545
- # => [is_unauthorized, TX_SUMMARY_COMMITMENT]
546
-
547
- # If signatures are non-existent the tx will fail here.
548
- if.true
549
- emit.AUTH_UNAUTHORIZED_EVENT
550
- push.0 assert.err="insufficient number of signatures"
551
- end
552
-
553
- # => [TX_SUMMARY_COMMITMENT]
554
- end