Skip to content
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

Conversation

mzabaluev
Copy link
Contributor

  • 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.
@mzabaluev mzabaluev force-pushed the catalyst-registration-nonce-and-hash-sig branch from aacc58a to 5fe4115 Compare March 19, 2021 06:13
}

registration_signature = {
1 : $ed25519_signature
1 : $ed25519_signature //
Copy link
Contributor

@refi93 refi93 Mar 19, 2021

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

Copy link
Contributor Author

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.

Copy link
Contributor

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

Copy link
Contributor

@refi93 refi93 Mar 20, 2021

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"
Copy link
Contributor

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"?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

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
Copy link
Collaborator

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.

Copy link
Contributor

@refi93 refi93 Mar 28, 2021

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

Copy link
Contributor Author

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.

Copy link
Contributor

@refi93 refi93 Mar 29, 2021

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.

Copy link
Contributor

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.
Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Contributor

@refi93 refi93 Mar 29, 2021

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:

  1. 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.

  2. 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.
Copy link
Contributor

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

@mzabaluev
Copy link
Contributor Author

Superseded by #79.

@mzabaluev mzabaluev closed this Apr 6, 2021
rphair added a commit that referenced this pull request Oct 26, 2023
* 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]>
Ryun1 pushed a commit to Ryun1/CIPs that referenced this pull request Nov 17, 2023
…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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants