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

Keyset ID V2 #182

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

Keyset ID V2 #182

wants to merge 6 commits into from

Conversation

davidcaseria
Copy link

@davidcaseria davidcaseria commented Oct 30, 2024

This PR introduces a new keyset ID version that commits to the keyset's unit and avoids keyset ambiguity between mints. Keyset IDs are now 33 bytes, with a one-byte version prefix before a 32-byte SHA256 hash.

Tokens maintain the same length by abbreviating the 33-byte keyset ID to the first 8 bytes: a one-byte version prefix before the first 7 bytes of the 32-byte SHA256 hash. While unlikely in practice, implementors should ensure that token keyset IDs are unambiguous to the mint when serializing.

Wallets will be responsible for expanding the abbreviated keyset ID to the full-length keyset ID.

It is now recommended to store the entire 33-byte keyset ID in a wallet's proof database.

Comment on lines +80 to +81
keyset_id_bytes = b"".join([p.serialize() for p in sorted_keys.values()])
keyset_id_bytes += b"unit:sat"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering ... since we already depend for CBOR (for Token v4), maybe we can use CBOR here too instead of this custom serialization?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would the structure of the CBOR be?

02.md Outdated Show resolved Hide resolved
@callebtc
Copy link
Contributor

Thank you!

Please:

  • add a verbose description in the PR what this is about
  • we should keep at least 7 bytes, as others have mentioned
  • this PR seems to replace the old keyset ID instead of adding a new version. Everything would break. We should instead add a new additional version.

@davidcaseria davidcaseria marked this pull request as ready for review November 1, 2024 19:34
@davidcaseria davidcaseria changed the title Define Keyset ID V2 Keyset ID V2 Nov 1, 2024
02.md Outdated Show resolved Hide resolved
def derive_keyset_id(keys: Dict[int, PublicKey]) -> str:
sorted_keys = dict(sorted(keys.items()))
keyset_id_bytes = b"".join([p.serialize() for p in sorted_keys.values()])
keyset_id_bytes += b"unit:sat"
Copy link
Contributor

@ok300 ok300 Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once optimization could be to change b"unit:sat" -> b"u:sat" or even just b"sat".
(Edit: nevermind that, it will all be hashed in the end, so reducing the length of what's inside won't matter)

Might also be worth specifying the unit should be lowercased first.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have specified the units as case-insensitive yet. We should probably also do that if we include this change, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the keyset ID commits to the unit, then it would make sense IMO.

If a client derives the keyset ID using a different capitalization, or if the mint changes the capitalization later on, the keyset ID would be invalid.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@callebtc what do you think about units being case-insensitive and hashing the lowercase unit value?

@@ -148,24 +172,24 @@ To receive the public keys of a specific keyset, a wallet can call the `GET /v1/

Request of `Alice`:

We request the keys for the keyset `009a1f293253e41e`.
We request the keys for the keyset `01c9c20fb8b348b389e296227c6cc7a63f77354b7388c720dbba6218f720f9b785`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a wallet that does not yet support V2 keysets makes a GET v1/keys/{8-byte-keyset-id} request?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A request with a keyset ID prefix 00 should still be supported. A wallet that doesn't support keyset IDs with a prefix of 01 shouldn't get to where they are making this request since the keyset ID parsing will have already failed if the wallet is checking the version.

If a wallet doesn't check the version and sends a request for an 8-byte keyset ID from a token, we can consider having the mint resolve it for the wallet from the URL. But that feels like an optional requirement for the mint.

Does that address your question?

02.md Outdated Show resolved Hide resolved
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.

5 participants