Skip to content

Commit 498a696

Browse files
authored
refactor(standards): Multisig Auth Component cycle-cost optimizations, comment fixes, and PROC_ROOT validation (#3211)
* fix multisig getters call API * reduce cycle costs * correct stack-layout and advice-map comments * warn that growing the signer set does not re-scale overrides * validate PROC_ROOT belongs to the account in set_procedure_threshold * changelog * apply suggestions * lint * clarify auth_tx replay protection comes from assert_new_tx, not SALT * remove unused @Locals(1) from auth_tx * remove redundant dupw/dropw in tx_policy proc-call check * explain advice-loaded config is covered by ACCOUNT_DELTA_COMMITMENT * rename assert_new_tx to record_and_assert_new_tx * fix inaccurate auth-component comments * assert reconciled threshold config before approver-map cleanup * use truncate_stack in tests * fix * apply suggestions
1 parent 32896b1 commit 498a696

15 files changed

Lines changed: 365 additions & 97 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
- [BREAKING] Moved asset callback flag from asset vault key to account ID, making it immutable ([#3167](https://github.com/0xMiden/protocol/pull/3167)).
8888
- [BREAKING] Added `@account_procedure` attribute to mark which procedures should be included in the account component interface ([#3171](https://github.com/0xMiden/protocol/pull/3171)).
8989
- Documented that the `ecdsa_k256_keccak` authentication scheme discloses the signer's public key and signature at proving time via precompile calldata ([#3178](https://github.com/0xMiden/protocol/pull/3178)).
90+
- Optimized the multisig auth component MASM (unconditional loop entry where the counter is guaranteed non-zero, single-step `scheme_id` extraction in `get_signer_at`, and a stack read instead of a local reload in `update_signers_and_threshold`), and documented that growing the signer set does not re-scale existing per-procedure threshold overrides ([#3211](https://github.com/0xMiden/protocol/pull/3211)).
9091
- Renamed the `Authority` config value slot, expressed the authority kind as a MASM `enum Authority : u8`, and enforced the canonical config-word encoding on read ([#3209](https://github.com/0xMiden/protocol/pull/3209)).
9192
- Unified procedure ordering and document sender-based access control's authentication assumption in the `ownable2step` and `rbac` access control modules ([#3205](https://github.com/0xMiden/protocol/pull/3205)).
9293
- Refactor `asset_vault::add_asset` and `faucet::mint` to use a unified path for all asset types, in preparation of custom asset ([#3217](https://github.com/0xMiden/protocol/pull/3217)).
@@ -100,6 +101,7 @@
100101
- [BREAKING] Fixed batch ID being serialized/deserialized and potentially not matching the serialized transaction headers ([#3061](https://github.com/0xMiden/protocol/pull/3061)).
101102
- Simplified the `ownable2step` ownership transitions ([#3170](https://github.com/0xMiden/protocol/pull/3170)).
102103
- Fixed `note_script_allowlist::assert_all_input_notes_allowed` and `tx_script_allowlist::assert_tx_script_allowed` to read the allowlist from the transaction's initial storage state via `active_account::get_initial_map_item` ([#3182](https://github.com/0xMiden/protocol/pull/3182)).
104+
- Fixed `set_procedure_threshold` now asserts `PROC_ROOT` is one of the account's procedures (`ERR_PROC_ROOT_NOT_IN_ACCOUNT`) before storing an override, and corrected the inaccurate `assert_new_tx`, `update_signers_and_threshold`, and `get_signer_at` stack-layout and advice-map comments ([#3211](https://github.com/0xMiden/protocol/pull/3211)).
103105

104106
## v0.15.2 (2026-06-05)
105107

crates/miden-standards/asm/components/auth/guarded_multisig/guarded_multisig.masm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ pub proc auth_tx_guarded_multisig(salt: word)
3232
exec.guardian::verify_signature
3333
# => [TX_SUMMARY_COMMITMENT]
3434

35-
exec.multisig::assert_new_tx
35+
exec.multisig::record_and_assert_new_tx
3636
# => []
3737
end

crates/miden-standards/asm/components/auth/multisig/multisig.masm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ pub proc auth_tx_multisig(salt: word)
2323
exec.multisig::auth_tx
2424
# => [TX_SUMMARY_COMMITMENT]
2525

26-
exec.multisig::assert_new_tx
26+
exec.multisig::record_and_assert_new_tx
2727
# => []
2828
end

crates/miden-standards/asm/components/auth/multisig_smart/multisig_smart.masm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ pub proc auth_tx_multisig_smart(salt: word)
2424
exec.multisig_smart::auth_tx
2525
# => [TX_SUMMARY_COMMITMENT]
2626

27-
exec.multisig::assert_new_tx
27+
exec.multisig::record_and_assert_new_tx
2828
# => []
2929
end

crates/miden-standards/asm/components/auth/network_account/network_account.masm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const ALLOWED_TX_SCRIPTS_SLOT = word("miden::standards::auth::network_account::a
3333
#! If both checks pass, the nonce is incremented when the account state changed or the account is
3434
#! new, matching the behavior of the NoAuth and SingleSig components.
3535
#!
36-
#! Inputs: [pad(16)]
36+
#! Inputs: [AUTH_ARGS, pad(12)]
3737
#! Outputs: [pad(16)]
3838
#!
3939
#! Invocation: call

crates/miden-standards/asm/components/auth/no_auth/no_auth.masm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ use miden::core::word
1010
#! This avoids unnecessary nonce increments for transactions that don't modify
1111
#! the account state.
1212
#!
13-
#! Inputs: [pad(16)]
13+
#! Inputs: [AUTH_ARGS, pad(12)]
1414
#! Outputs: [pad(16)]
15+
#!
16+
#! Invocation: call
1517
@auth_script
1618
pub proc auth_no_auth
1719
# check if the account state has changed by comparing initial and final commitments

crates/miden-standards/asm/components/auth/singlesig/singlesig.masm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ pub proc auth_tx(auth_args: word)
4242
# ---------------------------------------------------------------------------------------------
4343

4444
push.PUBLIC_KEY_SLOT[0..2] exec.active_account::get_initial_item
45-
# => [PUB_KEY, pad(16)]
45+
# => [PK_COMM, pad(16)]
4646

4747
push.SCHEME_ID_SLOT[0..2] exec.active_account::get_initial_item
48-
# => [scheme_id, 0, 0, 0, PUB_KEY, pad(16)]
48+
# => [scheme_id, 0, 0, 0, PK_COMM, pad(16)]
4949

5050
movdn.7 drop drop drop
51-
# => [PUB_KEY, scheme_id, pad(16)]
51+
# => [PK_COMM, scheme_id, pad(16)]
5252

5353
exec.signature::authenticate_transaction
5454
# => [pad(16)]

crates/miden-standards/asm/components/auth/singlesig_acl/singlesig_acl.masm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,14 @@ pub proc auth_tx_acl(auth_args: word)
108108
if.true
109109
# Fetch public key from storage.
110110
push.PUBLIC_KEY_SLOT[0..2] exec.active_account::get_initial_item
111-
# => [PUB_KEY, pad(16)]
111+
# => [PK_COMM, pad(16)]
112112

113113
# Fetch scheme_id from storage
114114
push.SCHEME_ID_SLOT[0..2] exec.active_account::get_initial_item
115-
# => [[scheme_id, 0, 0, 0], PUB_KEY, pad(16)]
115+
# => [[scheme_id, 0, 0, 0], PK_COMM, pad(16)]
116116

117117
movdn.7 drop drop drop
118-
# => [PUB_KEY, scheme_id, pad(16)]
118+
# => [PK_COMM, scheme_id, pad(16)]
119119

120120
exec.signature::authenticate_transaction
121121
else

crates/miden-standards/asm/standards/auth/guardian.masm

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub proc update_guardian_public_key(new_guardian_scheme_id: felt, new_guardian_p
7777
# => [GUARDIAN_MAP_KEY, NEW_GUARDIAN_PUBLIC_KEY]
7878

7979
push.GUARDIAN_PUBLIC_KEYS_SLOT[0..2]
80-
# => [guardian_pubkeys_slot_prefix, guardian_pubkeys_slot_suffix,
80+
# => [guardian_pubkeys_slot_suffix, guardian_pubkeys_slot_prefix,
8181
# GUARDIAN_MAP_KEY, NEW_GUARDIAN_PUBLIC_KEY]
8282

8383
exec.native_account::set_map_item
@@ -97,7 +97,7 @@ pub proc update_guardian_public_key(new_guardian_scheme_id: felt, new_guardian_p
9797
# => [GUARDIAN_MAP_KEY, NEW_GUARDIAN_SCHEME_ID_WORD]
9898

9999
push.GUARDIAN_SCHEME_ID_SLOT[0..2]
100-
# => [guardian_scheme_slot_prefix, guardian_scheme_slot_suffix,
100+
# => [guardian_scheme_slot_suffix, guardian_scheme_slot_prefix,
101101
# GUARDIAN_MAP_KEY, NEW_GUARDIAN_SCHEME_ID_WORD]
102102

103103
exec.native_account::set_map_item
@@ -140,11 +140,11 @@ pub proc verify_signature(msg: word)
140140
# => [1, MSG]
141141

142142
push.GUARDIAN_PUBLIC_KEYS_SLOT[0..2]
143-
# => [guardian_pubkeys_slot_prefix, guardian_pubkeys_slot_suffix, 1, MSG]
143+
# => [guardian_pubkeys_slot_suffix, guardian_pubkeys_slot_prefix, 1, MSG]
144144

145145
push.GUARDIAN_SCHEME_ID_SLOT[0..2]
146-
# => [guardian_scheme_slot_prefix, guardian_scheme_slot_suffix,
147-
# guardian_pubkeys_slot_prefix, guardian_pubkeys_slot_suffix, 1, MSG]
146+
# => [guardian_scheme_slot_suffix, guardian_scheme_slot_prefix,
147+
# guardian_pubkeys_slot_suffix, guardian_pubkeys_slot_prefix, 1, MSG]
148148

149149
exec.signature::verify_signatures
150150
# => [num_verified_signatures, MSG]

0 commit comments

Comments
 (0)