feat(auth): add ECDSA single sig and multisig authentication component#2083
feat(auth): add ECDSA single sig and multisig authentication component#2083bobbinth merged 11 commits into0xMiden:mainfrom
Conversation
|
Thank you, @onurinanc! Once question (w/o having looked at the code): should this go into |
|
@bobbinth I think there are no any breaking changes in this PR. I’ll update the base branch to main. |
0cabf38 to
8191ed1
Compare
mmagician
left a comment
There was a problem hiding this comment.
Just a superficial review on the MASM structure for now - I think we can reduce the diff significantly
| proc assert_new_tx(msg: BeWord) | ||
| push.IS_EXECUTED_FLAG | ||
| # => [[0, 0, 0, is_executed], MSG] | ||
|
|
||
| swapw | ||
| # => [MSG, IS_EXECUTED_FLAG] | ||
|
|
||
| push.EXECUTED_TXS_SLOT | ||
| # => [index, MSG, IS_EXECUTED_FLAG] | ||
|
|
||
| # Set the key value pair in the map to mark transaction as executed | ||
| exec.native_account::set_map_item | ||
| # => [OLD_MAP_ROOT, [0, 0, 0, is_executed]] | ||
|
|
||
| dropw drop drop drop | ||
| # => [is_executed] | ||
|
|
||
| assertz.err=ERR_TX_ALREADY_EXECUTED | ||
| # => [] | ||
| end |
There was a problem hiding this comment.
AFAICS, this is the same logic as in the falcon file?
In that case, it would be best to reduce code duplication and move this file into a common file (see e.g. https://github.com/0xMiden/miden-base/blob/b160cabba65b6af4bbc6473e12bf0692dff7c855/crates/miden-lib/asm/miden/auth/mod.masm)
There was a problem hiding this comment.
Yes, this and other similar procedures can probably go into miden::auth::multisig module. But also, in the interest of time, I'm also fine keeping this as is for this PR and addressing de-duplication in a follow-up.
| #! Where: | ||
| #! - init_num_of_approvers is the original number of approvers before the update | ||
| #! - new_num_of_approvers is the new number of approvers after the update | ||
| proc cleanup_pubkey_mapping(init_num_of_approvers: u32, new_num_of_approvers: u32) |
| #! Locals: | ||
| #! 0: new_num_of_approvers | ||
| #! 1: init_num_of_approvers | ||
| pub proc update_signers_and_threshold.2(multisig_config_hash: BeWord) |
bobbinth
left a comment
There was a problem hiding this comment.
Looks good! Thank you! I reviewed all non-test code and left some comments inline - most of them are small nits and thoughts for the future.
crates/miden-lib/src/account/auth/ecdsa_k256_keccak_multisig.rs
Outdated
Show resolved
Hide resolved
| exec.auth::create_tx_summary | ||
| # => [SALT, OUTPUT_NOTES_COMMITMENT, INPUT_NOTES_COMMITMENT, ACCOUNT_DELTA_COMMITMENT, PUB_KEY] | ||
|
|
||
| exec.auth::adv_insert_hqword |
There was a problem hiding this comment.
Not for this PR, but I believe we can now replace this with adv.insert_hqword instruction.
@Fumuran could you create an issue for this?
| const.PUBLIC_KEY_SLOT=0 | ||
|
|
||
| # Local Memory Addresses for multisig operations | ||
| const.NUM_OF_APPROVERS_LOC=0 |
There was a problem hiding this comment.
Not from this PR, but I'm not seeing NUM_OF_APPROVERS_LOC. Maybe worth creating an issue to remove it. cc @partylikeits1983.
| proc assert_new_tx(msg: BeWord) | ||
| push.IS_EXECUTED_FLAG | ||
| # => [[0, 0, 0, is_executed], MSG] | ||
|
|
||
| swapw | ||
| # => [MSG, IS_EXECUTED_FLAG] | ||
|
|
||
| push.EXECUTED_TXS_SLOT | ||
| # => [index, MSG, IS_EXECUTED_FLAG] | ||
|
|
||
| # Set the key value pair in the map to mark transaction as executed | ||
| exec.native_account::set_map_item | ||
| # => [OLD_MAP_ROOT, [0, 0, 0, is_executed]] | ||
|
|
||
| dropw drop drop drop | ||
| # => [is_executed] | ||
|
|
||
| assertz.err=ERR_TX_ALREADY_EXECUTED | ||
| # => [] | ||
| end |
There was a problem hiding this comment.
Yes, this and other similar procedures can probably go into miden::auth::multisig module. But also, in the interest of time, I'm also fine keeping this as is for this PR and addressing de-duplication in a follow-up.
| pub proc auth_tx_ecdsa_k256_keccak(auth_args: BeWord) | ||
| dropw | ||
| # => [pad(16)] | ||
|
|
||
| # Fetch public key from storage. | ||
| # --------------------------------------------------------------------------------------------- | ||
| push.PUBLIC_KEY_SLOT exec.active_account::get_item | ||
| # => [PUB_KEY, pad(16)] | ||
|
|
||
| exec.ecdsa_k256_keccak::authenticate_transaction | ||
| # => [pad(16)] | ||
| end |
There was a problem hiding this comment.
Not for this PR, but we should start thinking about how to reduce code duplication. Ideally, instead of have two (or more) identical components that differ only in signature scheme used, we would have something like AuthBasicSinglesig and AuthBasicMultisig and the signature scheme would be defined internally.
There are at least two ways to do this:
- We could store the root of the signature procedure in the storage. In the case of single-sig authentication, the storage layout would be
[PUB_KEY, VERIFY_PROC_ROOT]. Then, we'd just usedynexecinstruction to execute the stored procedure. - We could still keep just the public key in the storage and add an event to retrieve the type of the public key. Then, we could have a set of
if-elsestatements to figure out which verification procedure to run for a given public key.
Both of these have their prons and cons:
- The first approach is more extensible: we don't need to modify the code to add support for a new signature scheme. But, we can't easily "mix" different signature schemes (mostly relevant in the context of the multisig).
- The second approach avoids the use of
dynexec(which feels a bit risky) and it allows us to easily mix different signature schemes (e.g., in the same multisig we could have both ECDSA and Falcon public keys) - but it is not as extensible: adding a new signature scheme would require MASM code changes. It is also a bit more work as we'll need to get the public key type from the authenticator (though, we may need to do this for other reasons anyways).
There may be other approaches to reducing code duplication as well - e.g., something along the lines of #1956. But I haven't thought about this too much.
We should create an issue to discuss this and ideally come up with the improved approach for v0.13.0 release.
bobbinth
left a comment
There was a problem hiding this comment.
Looks good! Thank you! As mentioned in the pervious comments, I'll merge this as is, and we can work on code de-duplication in follow-up PRs and try to wrap up with work for v0.13 release.
This PR implements the ECDSA Authentication Component for both single and multisig accounts.
Next Steps:
rust-clientwithinmiden-client.web-clientwithinmiden-client.Future Improvements:
This PR currently shares similar code patterns with the
RpoFalcon512andRpoFalcon512Multisigauthentication components. A more pluggable design that unifies these authentication mechanisms into a single, configurable component will be explored.