-
Notifications
You must be signed in to change notification settings - Fork 312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cardano registration metadata changes and signature specification #75
Cardano registration metadata changes and signature specification #75
Conversation
mzabaluev
commented
Mar 19, 2021
- Documented upcoming changes for fund 4.
- Detailed description of the signature methods, with an additional method added to accommodate hardware wallets.
- Document usage for key revocation.
- Reflect changes in plans regarding token locking.
Document the slot number field that is about to be introduced. The changes related to token locking have been postponed, change the documentation to reflect that.
It's "methods" because we are introducing a way to hash the metadata for signing, discriminated by a different field number.
aacc58a
to
5fe4115
Compare
} | ||
|
||
registration_signature = { | ||
1 : $ed25519_signature | ||
1 : $ed25519_signature // |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here should probably be a comment that this field is not used anymore as the signature scheme changed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is that either of the schemes can be used interchangeably.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I think the key should be prefixed with ?
to mark its optionality (https://github.com/input-output-hk/cardano-ledger-specs/blob/2966737bbaf4952a2cf8cd185f253ea5b82d863f/shelley/chain-and-ledger/shelley-spec-ledger-test/cddl-files/shelley.cddl#L56) and explain with a comment that either key 1 or 2 should be specified, as I guess CDDL doesn't have that level of expressivity natively
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, do we want to allow both keys at the same time? I can see that leading to hard-to-predict behavior/implementation missalignment across different parts of the system for the case when one signature would be valid and the other not, so I'd advocate for enfocing a strict "either key 1 is present or key 2, but not both"
|
||
2: The blake2b-256 hash of `sign_data` is signed using Ed25519. | ||
|
||
Signature example: | ||
``` | ||
61285: { | ||
// signature - ED25119 signature CBOR byte array | ||
1: "0x8b508822ac89bacb1f9c3a3ef0dc62fd72a0bd3849e2381b17272b68a8f52ea8240dcc855f2264db29a8512bfcd522ab69b982cb011e5f43d0154e72f505f007" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't the key be updated to "2"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example is still valid, applications should be free to use scheme 1 if they prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it should use 1. 2 will be ignored by the snapshot tools. We will not support both signature options.
This reverts commit 5fe4115.
and the current slot number, respectively. A registration with these metadata | ||
will be considered valid if the following conditions hold: | ||
|
||
- The slot number of the block including this transaction is equal to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How could you possibly guarantee this? Slots in Cardano are only 2 seconds and not all of them have a block in it.
On top of that, it would allow any pool to censor Catalyst registration transactions by purposely skipping them rendering them invalid for future slots.
Additionally, signing a transaction for hardware wallets requires user steps, so by the time the user is done with all the steps the tx may very well no longer be valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree, the user may need even several minutes to sign the transaction on a hardware wallet (which needs to know the slot number in advance, making it de-facto impossible to sign a valid voting key registration). Could you @mzabaluev explain the rationale behind this constraint?
I gather that the motivation behind this constraint is likely preventing the users from submitting a key registration with too big of a value of the counter which would effectively make their key un-updatable - for that purpose a constraint that the slot number should be no higher than the slot number of the block in which the registration is submitted should do.
Another motivation could be avoiding state storage - Not sure how the current "active voting keys" are stored but they probably need to be stored somehow and storing a counter alongside them (to be able to compare it against subsequent re-registrations) seems more viable than forcing such strict consistency with the block number where the key registration would be submitted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the two slot time window is too short, so either a larger validity timeout is needed or a different mechanism to provide a unique nonce.
it would allow any pool to censor Catalyst registration transactions by purposely skipping them rendering them invalid for future slots.
What number of slots would be sufficient to prevent such censorship, assuming an honest majority among the pools?
This time window defines how far apart successive re-registrations need to be for the same staking key, to make it impossible to nullify the newer registration by replaying the older.
I gather that the motivation behind this constraint is likely preventing the users from submitting a key registration with too big of a value of the counter which would effectively make their key un-updatable
It's rather so that old registrations cannot be replayed, reverting a possible newer registration of a different voting key (or a revocation, whenever that use case is supported) with the same staking key. But it could also prevent the problem you describe, if we apply the "larger slot number wins" rule to resolving conflicting registrations rather than the order of transactions (which may be problematic if the transactions happen to be in the same block and there is no UTxO-imposed order between them).
Not sure how the current "active voting keys" are stored but they probably need to be stored somehow and storing a counter alongside them (to be able to compare it against subsequent re-registrations) seems more viable
It's certainly doable for the validation logic on the snapshotting tool, but I'm not sure about all wallets.
A wallet would be expected to recover the last successful registration transaction for the selected public staking key to obtain the value of the counter. If this is compatible with constraints posed by HW wallets, we can change the specification to use this stateful scheme.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A wallet would be expected to recover the last successful registration transaction for the selected public staking key to obtain the value of the counter.
I'm not sure why would a wallet need to recover the counter from a previous registration - if the counter is chosen as the current slot number, that's a global increasing value. If we are afraid about the counter getting bigger than it should be, Catalyst can just ignore registrations with a value of the counter higher than the slot where they have been submitted. However, if a user somehow signs by mistake a registration with a future slot number, somebody may abuse that to overwrite user's registration later on, but that's a problem that neither the currently proposed design addresses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
slot number is only a suggestion of what to use for the nonce. It's nice because it always increases, but fundamentally, it can be any number that never goes backwards. e.g. 1, 2, 3, 4, 3 would result in 4 being the one used and ignore the last. Note that this nonce is not implemented for fund4 (it's included, but snapshot ignores it). We want to get the schema correct so we can properly scope out adding this for fund 5, but also want to stabilize so teams aren't having to continuously make changes.
This data is signed with the staking key using one of the two methods, | ||
discriminated by the key number in the signature metadata map: | ||
|
||
1: `sign_data` is signed as is using Ed25519. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is no longer supported in fund4, it has to be hashed first.
} | ||
|
||
$voting_pub_key /= bytes .size 32 | ||
$staking_pub_key /= bytes .size 32 | ||
$ed25519_signature /= bytes .size 64 | ||
$address /= bytes | ||
$reward_address /= bytes | ||
$slot_number /= uint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this does not have to be a slot number, it can be any int, but slot makes it easy to not have to understand previous state to update a registration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see two potential issues with the slot number being an int without specific constraints:
-
if the int is supposed to be a uint64, then it would be bounded and a user could end up with a unupdatable key registration if they submit it with the nonce set to MAX_UINT64. If the int is unbounded, this can be complicated to implement on hw wallets with limited support for numerical types.
-
There doesn't seem to be a reasonably efficient way to check for the last active registration by wallets - db sync indexes metadata in a generic way and it's up to the wallet backend/frontend to filter out the valid voting key registrations which isn't a scalable approach. If each wallet chooses their own way of setting the nonce in a stateless manner, users may face issues re-registering their keys if they migrate to another walllet that does it differently.
If not enforced by the snapshotting tool, I would at least put in the CIP that standard wallet implementations shall choose as the nonce the current slot number to ensure users of standard wallets don't face issues re-registering their voting keys should they migrate to another wallet
Fund 3 added the `address` inside the `key_registration` field. | ||
Fund 3 added the `reward_address` inside the `key_registration` field. | ||
|
||
Fund 4 added the `slot_number` field to prevent replay attacks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd call this nonce rather than slot number
Superseded by #79. |
* promote CIP-0102 and fix some white space there * set CPS-0007 title to its official title in top README * author abandoned #530 * added implementors Co-authored-by: Sam Delaney <[email protected]> * added extension boilerplate Co-authored-by: Sam Delaney <[email protected]> --------- Co-authored-by: Sam Delaney <[email protected]>
…foundation#606) * promote CIP-0102 and fix some white space there * set CPS-0007 title to its official title in top README * author abandoned cardano-foundation#530 * added implementors Co-authored-by: Sam Delaney <[email protected]> * added extension boilerplate Co-authored-by: Sam Delaney <[email protected]> --------- Co-authored-by: Sam Delaney <[email protected]>