feat: migrate to miden VM 0.21 and miden crypto 0.22#2508
Conversation
bobbinth
left a comment
There was a problem hiding this comment.
All looks good! Thank you!
1e2ca48 to
24a98a6
Compare
partylikeits1983
left a comment
There was a problem hiding this comment.
I only took a close look at MASM code just to familiarize myself with the upcoming changes. Only found one small issue, where there were two swapw swapw opcodes back to back. Otherwise everything looks really good.
Regarding the two back to back swapw swapw opcodes, I checked out your branch, and applied the suggestions I left, and all tests passed.
mmagician
left a comment
There was a problem hiding this comment.
I selectively reviewed a few kernel, protocol and standards files, the changes seem to be similar in nature across the other changed files from briefly skimming over them. So not a full review, but LGTM ✅
| exec.poseidon2::init_no_padding | ||
| adv_pipe exec.poseidon2::permute | ||
| adv_pipe exec.poseidon2::permute | ||
| adv_pipe exec.poseidon2::permute | ||
| adv_pipe exec.poseidon2::permute | ||
| adv_pipe exec.poseidon2::permute | ||
| exec.poseidon2::squeeze_digest |
There was a problem hiding this comment.
nothing for this PR, but I'd like to move away from this hand-coded hashing, and either wrap these in helper procedures here or move them to the poseidon2 module.
Ideally, we would do something like:
const BLOCK_DATA_NUM_WORDS = 10
proc your_favorite_proc
push.BLOCK_DATA_NUM_WORDS
# => [num_words]
exec.poseidon2::hash_advice_words
end
this would be less error prone, and waaay easier to follow and reason about. If you think this is a valid suggestion, let's make an issue for this.
There was a problem hiding this comment.
I think the code could be simplified and made a bit more explicit with something like:
exec.poseidon2::init_no_padding
repeat.BLOCK_DATA_NUM_DOUBLE_WORDS
adv_pipe exec.poseidon2::permute
end
exec.poseidon2::squeeze_digest
The main reason I can think of to keep using this instead of a helper is that it would not require any looping/branching, though I haven't benchmarked how many cycles this saves.
We could encapsulate the above in a hash_advice_words procedure with a loop, but we wouldn't save that many lines of code and readability would probably be about the same, so I'm not sure what is better.
| exec.poseidon2::init_no_padding | ||
| adv_pipe exec.poseidon2::permute | ||
| adv_pipe exec.poseidon2::permute | ||
| exec.poseidon2::squeeze_digest |
There was a problem hiding this comment.
Useful across the board:
push.ACCT_DETAILS_NUM_WORDS
# => [num_words]
exec.poseidon2::hash_advice_words
| # => [assets_ptr, assets_end_ptr, note_ptr] | ||
|
|
||
| exec.rpo256::init_no_padding | ||
| exec.poseidon2::init_no_padding |
There was a problem hiding this comment.
We could benefit from similar helpers here
| proc create_id_key | ||
| push.0 movdn.2 push.0 movdn.2 | ||
| # => [account_id_prefix, account_id_suffix, 0, 0] | ||
| push.0.0 | ||
| # => [0, 0, account_id_suffix, account_id_prefix] | ||
| # => [ACCOUNT_ID_KEY] | ||
| end |
There was a problem hiding this comment.
For a follow-up issue/PR: this would be useful in a lot of other places:
- https://github.com/0xMiden/miden-base/blob/e85700616ecadf8f48600776297d250e51e02bbd/crates/miden-protocol/asm/protocol/active_account.masm#L515
- https://github.com/0xMiden/miden-base/blob/e85700616ecadf8f48600776297d250e51e02bbd/crates/miden-protocol/asm/protocol/active_account.masm#L547
- https://github.com/0xMiden/miden-base/blob/e85700616ecadf8f48600776297d250e51e02bbd/crates/miden-protocol/asm/shared_utils/util/asset.masm#L177
- etc. (search for
push.0.0in the codebase, most of them constructACCOUNT_ID_KEY)
There was a problem hiding this comment.
I think the ones you listed and the ones I can find aren't actually account ID keys but asset keys. They happen to have the same layout, but I would say they have a semantic difference. The first two entries in an account ID key are just unnamed zeros, but the first two entries in an asset key are the asset ID limbs, which are explicitly set to 0 for fungible assets. So I think account::create_id_key doesn't need to be exposed, because, at least currently, miden::protocol doesn't construct account ID keys and user code should probably rarely need to do that.
I think it would be useful to expose a miden::protocol::asset::create_fungible_key procedure for the purpose of creating asset keys (that internally happens to work the same way as create_id_key).
Opened #2541.
| # prepare the stack for the `pipe_double_words_to_memory` procedure. | ||
| # | ||
| # To match `rpo256::hash_elements` (used for NOTE_STORAGE_COMMITMENT), we set the first capacity | ||
| # To match `poseidon2::hash_elements` (used for NOTE_STORAGE_COMMITMENT), we set the first capacity |
There was a problem hiding this comment.
this usage pattern is quite more involved, but I think here in the user-facing protocol lib it would be especially important to move away from hand-crafting the hasher states
There was a problem hiding this comment.
I tried to replace this using poseidon2::prepare_hasher_state, but for subtle reasons this only works for hash_elements_with_state but not for initializing hasher states for pipe_double_words_to_memory, otherwise this would've been simplified some.
It sounds like what you want would be basically a single procedure that takes care of all of that. I guess that would be ideal and will require changes in miden::core. I'm not yet sure if we can have procedures for all our use cases, but this requires a bit more in-depth analysis. Will open an issue.
Changes
miden-air,winterfell,winter-rand-utils,winter-airagglayerbranch.StackInputsandStackOutputssince this changed in the VM.PartialSmthas changed which is why aPartialAccountTreetest needed an update (upsert_state_commitments_fails_on_untracked_key).constfrom someAccountIdmethods due toas_canonical_u64not beingconst(which replaces the previouslyconst fn as_int).RATE0, RATE1, CAPACITYas the hasher state. Previously the order of the rate words was not documented (RATE, RATE) and after hashing we sometimes usedPERM, PERM, PERMwhich doesn't say much. Not yet fully converted in this PR -> done as a follow-up.NOTE_ATTACHMENTandNOTE_METADATA_HEADER.swapwin the kernel if we re-arranged how the hash is defined (though this isn't done in this PR, and I'm not fully convinced yet it's worth doing).1to fix the cargo deny check that complained about two versions being used.tiny-keccak.Migration
[prefix, suffix]was changed to[suffix, prefix]for all slot IDs and account IDs (and the newly introduced asset ID). Note that slot IDs can still be pushed withpush.SLOT_NAME[0..2]. See the diff ofdocs/src/protocol_library.mdwith the previous version for what has changed inmiden::protocol.TokenMetadatachanges from stack[token_symbol, decimals, max_supply, token_supply]to[token_supply, max_supply, decimals, token_symbol].Follow-Ups
Done in #2512 except for the agglayer ones.
TODO(bele). Some of these are agglayer-related.adv.insert_hqwordcan be used.Signature,AuthScheme,AuthSecretKeytoFalcon512Poseidon2.Thanks to @Al-Kindi-0 and @huitseeker for their prior migration work that was a great reference, and the support in DMs!