Skip to content
Merged
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
- [BREAKING] Updated note tag length to support up to 32 bits ([#2329](https://github.com/0xMiden/miden-base/pull/2329)).
- [BREAKING] Moved standard note code into individual note modules ([#2363](https://github.com/0xMiden/miden-base/pull/2363)).
- [BREAKING] Added `miden::standards::note_tag` module for account target note tags ([#2366](https://github.com/0xMiden/miden-base/pull/2366)).
- [BREAKING] Refactored account ID and nonce memory and advice stack layout ([#2442](https://github.com/0xMiden/miden-base/pull/2442)).
- [BREAKING] Removed `hash_account` ([#2442](https://github.com/0xMiden/miden-base/pull/2442)).
- [BREAKING] Renamed `AccountHeader::commitment`, `Account::commitment` and `PartialAccount::commitment` to `to_commitment` ([#2442](https://github.com/0xMiden/miden-base/pull/2442)).

## 0.13.3 (2026-01-27)

Expand Down
68 changes: 43 additions & 25 deletions crates/miden-protocol/asm/kernels/transaction/lib/account.masm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use $kernel::constants::EMPTY_SMT_ROOT
use $kernel::constants::STORAGE_SLOT_TYPE_MAP
use $kernel::constants::STORAGE_SLOT_TYPE_VALUE
use $kernel::memory
use $kernel::memory::ACCT_ID_SUFFIX_OFFSET
use $kernel::memory::ACCT_ID_PREFIX_OFFSET
use miden::core::collections::smt
use miden::core::collections::sorted_array
use miden::core::crypto::hashes::rpo256
Expand Down Expand Up @@ -218,9 +220,7 @@ pub use memory::get_account_id->get_id
#! - nonce is the account nonce.
pub use memory::get_account_nonce->get_nonce

#! Increments the account nonce by one and returns the new nonce.
#!
#! Assumes that it is executed only when the active account is the native account.
#! Increments the native account's nonce by one and returns the new nonce.
#!
#! Inputs: []
#! Outputs: [new_nonce]
Expand All @@ -238,7 +238,7 @@ pub proc incr_nonce
# emit event to signal that account nonce is being incremented
emit.ACCOUNT_BEFORE_INCREMENT_NONCE_EVENT

exec.memory::get_account_nonce
exec.memory::get_native_account_nonce
# => [current_nonce]

# if the current nonce is the maximum felt value, then incrementing the nonce would overflow
Expand All @@ -249,7 +249,7 @@ pub proc incr_nonce
add.1
# => [new_nonce]

dup exec.memory::set_account_nonce
dup exec.memory::set_native_account_nonce
# => [new_nonce]

emit.ACCOUNT_AFTER_INCREMENT_NONCE_EVENT
Expand Down Expand Up @@ -848,8 +848,9 @@ pub proc validate_seed
# => [EMPTY_WORD]

# push the advice map key at which the seed is located
exec.memory::get_account_id push.0.0
# => [0, 0, account_id_prefix, account_id_suffix, EMPTY_WORD]
exec.memory::get_native_account_id
exec.create_id_key
# => [ACCOUNT_ID_KEY, EMPTY_WORD]

# populate first four elements of the rate with the account ID seed
adv.push_mapval adv_loadw
Expand Down Expand Up @@ -1042,18 +1043,18 @@ pub proc load_foreign_account
emit.ACCOUNT_BEFORE_FOREIGN_LOAD_EVENT
# => [account_id_prefix, account_id_suffix]

# construct the word with account ID to load the core account data from the advice map
push.0.0
# OS => [0, 0, account_id_prefix, account_id_suffix]
# construct the advice map key from the account ID to load the core account data
exec.create_id_key
# OS => [ACCOUNT_ID_KEY]

# move the core account data to the advice stack
adv.push_mapval
# OS => [0, 0, account_id_prefix, account_id_suffix]
# AS => [[account_id_suffix, account_id_prefix, 0, account_nonce], VAULT_ROOT, STORAGE_COMMITMENT, CODE_COMMITMENT]
# OS => [ACCOUNT_ID_KEY]
# AS => [ACCOUNT_ID_AND_NONCE, VAULT_ROOT, STORAGE_COMMITMENT, CODE_COMMITMENT]

# store the id and nonce of the foreign account to the memory
# store the id and nonce of the foreign account to memory
adv_loadw
# OS => [account_nonce, 0, account_id_prefix, account_id_suffix]
# OS => [account_id_prefix, account_id_suffix, 0, account_nonce]
# AS => [VAULT_ROOT, STORAGE_COMMITMENT, CODE_COMMITMENT]

exec.memory::set_account_id_and_nonce
Expand Down Expand Up @@ -1738,14 +1739,13 @@ pub proc get_account_data_ptr
exec.memory::get_account_data_length add
# => [curr_account_ptr', foreign_account_id_prefix, foreign_account_id_suffix]

# load the first data word at the current account pointer
padw dup.4 mem_loadw_be
# => [FIRST_DATA_WORD, curr_account_ptr', foreign_account_id_prefix, foreign_account_id_suffix]
dup add.ACCT_ID_SUFFIX_OFFSET mem_load
dup.1 add.ACCT_ID_PREFIX_OFFSET mem_load
# => [account_id_prefix, account_id_suffix, curr_account_ptr', foreign_account_id_prefix, foreign_account_id_suffix]

# check whether the last value in the word equals zero
# if so it means this memory block was not yet initialized
drop drop dup.1 eq.0
# => [is_empty_block, maybe_account_id_prefix, maybe_account_id_suffix, curr_account_ptr', foreign_account_id_prefix, foreign_account_id_suffix]
# check whether the ID is equal to zero, if so it means this memory block was not yet initialized
dup.1 dup.1 push.0 push.0 exec.account_id::is_equal
# => [is_empty_block, account_id_prefix, account_id_suffix, curr_account_ptr', foreign_account_id_prefix, foreign_account_id_suffix]

# check whether the current id matches the foreign id
movdn.2 dup.5 dup.5 exec.account_id::is_equal
Expand Down Expand Up @@ -1775,15 +1775,18 @@ end
#! Outputs: []
#!
#! Panics if:
#! - the hash of the active account is not represented in the account database.
#! - the commitment of the loaded foreign account does not match the commitment stored in the
#! account tree.
pub proc validate_active_foreign_account
# get the account database root
exec.memory::get_account_db_root
# => [ACCOUNT_DB_ROOT]

# get the active account ID
push.0.0 exec.memory::get_account_id
# => [account_id_prefix, account_id_suffix, 0, 0, ACCOUNT_DB_ROOT]
# get the account ID of the foreign account (the currently active account) and build the
# corresponding key in the account tree
exec.memory::get_account_id
exec.create_id_key
# => [ACCOUNT_ID_KEY, ACCOUNT_DB_ROOT]

# retrieve the commitment of the foreign account from the active account tree
# this would abort if the proof for the commitment was invalid for the account root,
Expand Down Expand Up @@ -1990,3 +1993,18 @@ pub proc has_procedure
dropw drop drop
# => [is_procedure_available']
end

#! Returns the key build from the provided account ID for use in the advice map or the account
#! tree.
#!
#! Inputs: [account_id_prefix, account_id_suffix]
#! Outputs: [ACCOUNT_ID_KEY]
#!
#! Where:
#! - account_id_{prefix,suffix} are the prefix and suffix felts of the account ID.
#! - ACCOUNT_ID_KEY is the key word built from the provided account ID.
proc create_id_key
push.0 movdn.2 push.0 movdn.2
# => [account_id_prefix, account_id_suffix, 0, 0]
# => [ACCOUNT_ID_KEY]
end
72 changes: 40 additions & 32 deletions crates/miden-protocol/asm/kernels/transaction/lib/memory.masm
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ const GLOBAL_INPUTS_SECTION_OFFSET=400
# The memory address at which the transaction reference block's commitment is stored.
const BLOCK_COMMITMENT_PTR=400

# The memory address at which the native account ID is stored.
const NATIVE_ACCT_ID_PTR=404
# The memory address at which the native account ID provided as a global transaction input is
# stored.
const GLOBAL_ACCOUNT_ID_SUFFIX_PTR = 404
const GLOBAL_ACCOUNT_ID_PREFIX_PTR = GLOBAL_ACCOUNT_ID_SUFFIX_PTR + 1

# The memory address at which the initial account commitment is stored.
const INIT_ACCOUNT_COMMITMENT_PTR=408
Expand Down Expand Up @@ -145,12 +147,16 @@ const VALIDATOR_KEY_COMMITMENT_PTR=824
const BLOCK_METADATA_PTR=828

# The memory address at which the fee parameters are stored. These occupy a double word.
# [native_asset_id_suffix, native_asset_id_prefix, verification_base_fee, 0]
# [0, verification_base_fee, native_asset_id_suffix, native_asset_id_prefix]
# [0, 0, 0, 0]
const FEE_PARAMETERS_PTR=832

# The memory address at which the verification base fee is stored.
const VERIFICATION_BASE_FEE_PTR=FEE_PARAMETERS_PTR+2
const VERIFICATION_BASE_FEE_PTR = FEE_PARAMETERS_PTR + 1

# The memory address at which the native asset ID is stored.
const NATIVE_ASSET_ID_SUFFIX_PTR = FEE_PARAMETERS_PTR + 2
const NATIVE_ASSET_ID_PREFIX_PTR = FEE_PARAMETERS_PTR + 3

# The memory address at which the note root is stored
const NOTE_ROOT_PTR=840
Expand Down Expand Up @@ -186,13 +192,17 @@ const MAX_FOREIGN_ACCOUNT_PTR=524288

# The memory address at which the native account data is stored.
const NATIVE_ACCOUNT_DATA_PTR=8192
const NATIVE_ACCOUNT_ID_SUFFIX_PTR = NATIVE_ACCOUNT_DATA_PTR + ACCT_ID_SUFFIX_OFFSET
const NATIVE_ACCOUNT_ID_PREFIX_PTR = NATIVE_ACCOUNT_DATA_PTR + ACCT_ID_PREFIX_OFFSET

# The length of the memory interval that the account data occupies.
const ACCOUNT_DATA_LENGTH=8192

# The offsets at which the account data is stored relative to the start of the account data segment.
const ACCT_NONCE_OFFSET=0
const ACCT_ID_AND_NONCE_OFFSET=0
const ACCT_NONCE_OFFSET=3
const ACCT_ID_SUFFIX_OFFSET=2
const ACCT_ID_PREFIX_OFFSET=3
const ACCT_VAULT_ROOT_OFFSET=4
const ACCT_STORAGE_COMMITMENT_OFFSET=8
const ACCT_CODE_COMMITMENT_OFFSET=12
Expand Down Expand Up @@ -481,32 +491,30 @@ pub proc get_block_commitment
padw mem_loadw_be.BLOCK_COMMITMENT_PTR
end

#! Sets the ID of the native account.
#! Sets the global ID of the native account.
#!
#! Inputs: [account_id_prefix, account_id_suffix]
#! Outputs: []
#!
#! Where:
#! - account_id_{prefix,suffix} are the prefix and suffix felts of the account ID.
pub proc set_global_account_id
push.0.0
# => [0, 0, account_id_prefix, account_id_suffix]
mem_storew_be.NATIVE_ACCT_ID_PTR
dropw
mem_store.GLOBAL_ACCOUNT_ID_PREFIX_PTR
mem_store.GLOBAL_ACCOUNT_ID_SUFFIX_PTR
# => []
end

#! Returns the ID of the native account.
#! Returns the global ID of the native account.
#!
#! Inputs: []
#! Outputs: [account_id_prefix, account_id_suffix]
#!
#! Where:
#! - account_id_{prefix,suffix} are the prefix and suffix felts of the account ID.
pub proc get_global_account_id
padw mem_loadw_be.NATIVE_ACCT_ID_PTR
# => [0, 0, account_id_prefix, account_id_suffix]
drop drop
mem_load.GLOBAL_ACCOUNT_ID_SUFFIX_PTR
mem_load.GLOBAL_ACCOUNT_ID_PREFIX_PTR
# => [account_id_prefix, account_id_suffix]
end

#! Sets the native account commitment at the beginning of the transaction.
Expand Down Expand Up @@ -771,7 +779,8 @@ end
#! - native_asset_id_{prefix,suffix} are the prefix and suffix felts of the faucet ID that defines
#! the native asset.
pub proc get_native_asset_id
padw mem_loadw_be.FEE_PARAMETERS_PTR drop drop
mem_load.NATIVE_ASSET_ID_SUFFIX_PTR
mem_load.NATIVE_ASSET_ID_PREFIX_PTR
# => [native_asset_id_prefix, native_asset_id_suffix]
end

Expand Down Expand Up @@ -1092,9 +1101,13 @@ end
#! Where:
#! - account_id_{prefix,suffix} are the prefix and suffix felts of the ID of the active account.
pub proc get_account_id
padw exec.get_active_account_data_ptr add.ACCT_ID_AND_NONCE_OFFSET mem_loadw_be
# => [nonce, 0, account_id_prefix, account_id_suffix]
drop drop
exec.get_active_account_data_ptr
# => [active_account_data_ptr]

dup add.ACCT_ID_SUFFIX_OFFSET mem_load
# => [account_id_suffix, active_account_data_ptr]

swap add.ACCT_ID_PREFIX_OFFSET mem_load
# => [account_id_prefix, account_id_suffix]
end

Expand All @@ -1107,16 +1120,15 @@ end
#! - account_id_{prefix,suffix} are the prefix and suffix felts of the ID of the native account
#! of the transaction.
pub proc get_native_account_id
padw push.NATIVE_ACCOUNT_DATA_PTR add.ACCT_ID_AND_NONCE_OFFSET mem_loadw_be
# => [nonce, 0, account_id_prefix, account_id_suffix]
drop drop
mem_load.NATIVE_ACCOUNT_ID_SUFFIX_PTR
mem_load.NATIVE_ACCOUNT_ID_PREFIX_PTR
# => [account_id_prefix, account_id_suffix]
end

#! Sets the account ID and nonce.
#!
#! Inputs: [nonce, 0, account_id_prefix, account_id_suffix]
#! Outputs: [nonce, 0, account_id_prefix, account_id_suffix]
#! Inputs: [account_id_prefix, account_id_suffix, 0, nonce]
#! Outputs: [account_id_prefix, account_id_suffix, 0, nonce]
#!
#! Where:
#! - account_id_{prefix,suffix} are the prefix and suffix felts of the ID of the active account.
Expand Down Expand Up @@ -1150,20 +1162,16 @@ pub proc get_native_account_nonce
mem_load
end

#! Sets the nonce of the active account.
#! Sets the nonce of the native account.
#!
#! Inputs: [nonce]
#! Outputs: []
#!
#! Where:
#! - nonce is the nonce of the active account.
pub proc set_account_nonce
exec.get_active_account_data_ptr add.ACCT_ID_AND_NONCE_OFFSET padw
# => [0, 0, 0, 0, account_id_and_nonce_ptr, new_nonce]
dup.4 mem_loadw_be
# => [old_nonce, 0, old_id_prefix, old_id_suffix, account_id_and_nonce_ptr, new_nonce]
drop movup.4 movup.4 mem_storew_be dropw
# => []
#! - nonce is the new nonce of the native account.
pub proc set_native_account_nonce
push.NATIVE_ACCOUNT_DATA_PTR add.ACCT_NONCE_OFFSET
mem_store
end

### ACCOUNT VAULT #################################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ end
#! TX_KERNEL_COMMITMENT
#! VALIDATOR_KEY_COMMITMENT,
#! [block_num, version, timestamp, 0],
#! [native_asset_id_suffix, native_asset_id_prefix, verification_base_fee, 0],
#! [0, verification_base_fee, native_asset_id_suffix, native_asset_id_prefix],
#! [0, 0, 0, 0],
#! NOTE_ROOT,
#! ]
Expand Down Expand Up @@ -335,7 +335,7 @@ end
#! Inputs:
#! Operand stack: []
#! Advice stack: [
#! account_id_suffix, account_id_prefix, 0, account_nonce,
#! account_nonce, 0, account_id_suffix, account_id_prefix
#! ACCOUNT_VAULT_ROOT,
#! ACCOUNT_STORAGE_COMMITMENT,
#! ACCOUNT_CODE_COMMITMENT
Expand Down Expand Up @@ -1103,9 +1103,11 @@ end
#! TX_KERNEL_COMMITMENT
#! VALIDATOR_KEY_COMMITMENT,
#! [block_num, version, timestamp, 0],
#! [0, verification_base_fee, native_asset_id_suffix, native_asset_id_prefix]
#! [0, 0, 0, 0]
#! NOTE_ROOT,
#! kernel_version
#! [account_id_suffix, account_id_prefix, 0, account_nonce],
#! [account_nonce, 0, account_id_suffix, account_id_prefix]
#! ACCOUNT_VAULT_ROOT,
#! ACCOUNT_STORAGE_COMMITMENT,
#! ACCOUNT_CODE_COMMITMENT,
Expand Down
Loading