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

Multicode DID encoding #3

Open
oed opened this issue Nov 8, 2022 · 4 comments
Open

Multicode DID encoding #3

oed opened this issue Nov 8, 2022 · 4 comments

Comments

@oed
Copy link

oed commented Nov 8, 2022

Following up from #2:

So the idea with 2.1 Principal is that you would register new multicode for every DID method?
Imo it would make sense for DID Key to also have a multicode for symmertry?

No idea is that every DID can be represented via last DID variant of the the union and even then would be more compact than DID string
https://github.com/ucan-wg/ucan-ipld/blob/18d508456e1b6e2e385beb107a3c62124a720df7/README.md?plain=1#L71-L74

Commonly used DIDs could be further optimized by allocating varint for them like we do with bunch of did:key variants.

This way implementation can start simply with DID variant and propose new, more compact variant once it used widely enough to make sense. Given that UCAN spec is basically did:key we've defined those as specific variants to reduce amount of bytes used to represent them.

Currently Prinicipal is defined as follows:

type Principal union {
  -- This specification defines principals in terms of `did:key`s (multicodec
  -- identifiers for the public key type followed by the raw bytes of the key).
  -- We represent those as raw public key bytes prefixed with public key 
  -- multiformat code.
  | secp256k1  "0xe7"
  | BLS12381G1 "0xea"
  | BLS12381G2 "0xeb"
  | Ed25519    "0xed"
  | P256       "0x1200"
  | P384       "0x1201"
  | P512       "0x1202"
  | RSA        "0x1205"
  
  -- To accomodate additional DID methods we represent those as UTF8 encoding
  -- of the DID omitting `did:` prefix itself. E.g. `did:dns:ucan.xyz` can be
  -- represented as [0x0d1d, ...new TextEncoder().encode('dns:ucan.xyz')] bytes.
  | DID "0x0d1d"
} representation bytesprefix

A few observations:

  • Having a catchall for non-optimized DIDs as strings make sense
  • Not sure why we want to give did:key special treatment here. Ideally I'd like a completely self describing byte level description formats for DIDs that can be used anywhere

I would suggest we do something like this:

  • did:*: 0xd1d followed by utf8 encoded string as suggested above
  • did:key: 0xd1e followed by public key multicodec + raw public key bytes
  • did:pkh: 0xd1f followed by ...something...
  • etc...

This would allow us to have a generalizable approach to representing a DID as a bytestring.

Note however that ideally we'd also include a generalizable way to represent an entire DID URL

@bumblefudge
Copy link

bumblefudge commented Nov 15, 2022

DID URLs are a thing that exist-- they haven't gotten too much play in did v1 but i think some people are starting to use them in prod these days, such as the cheqd.io guys who are currently exploring and specifying using DID URLs to address immutable and in some cases content-addressed resources needed for some fancy VC use cases in the VCs themselves...

A DID URL combines all the chaos of a URN (the did part) with all the chaos of a URL (after the ? or #) so supporting them may take a little creativity on the processing. I like Joel's approach of prefixing the easy-to-parse, ?/#-free dids like did:key and did:pkh but also preserving a prefix for the "long-form"/uncompact/troublesome/potentially parameterized hell-DIDs that might need to be supported some day by less efficient systems :D

Sidenote, the easiest way to get answers about DID URLs if you have questions is to ask markus sabadello, @ / peacekeeper, he is lead editor on the DID Resolution spec (which includes all the parsing rules for ? and # params) and, coincidentally, also co-editor of the dnslink spec, active everywhere, very good dood and generous with his time on such matters.

@oed
Copy link
Author

oed commented Nov 18, 2022

New proposal that takes DID URLs into consideration. All DIDs are represented as:

0xd1d | <varint-url-length> | <method-specific-code> | <method-id-bytes> | <utf8-url-bytes>

Where:

  • varint-url-length is the length of the url component of the DID
  • method-specific-code - multicode that uniquely identifies the DID method
  • method-id-bytes - the DID identifer
  • utf8-url-bytes - the utf-8 bytes of the url component of the DID URL component (can be empty if varint-url-length is zero)

Examples:

// did:key - secp256k1
0xd1d | 0x00 | 0xe7 | <pubkey-bytes>

// did:key - ed25519
0xd1d | 0x00 | 0xed | <pubkey-bytes>

// did:pkh
0xd1d | 0x00 | 0xca | <caip50-bytes>

// did:* - we use raw multicodec to indicate
0xd1d | 0x00 | 0x00 | <utf8-bytes>

A nice thing about this approach is that all DIDs will be prefixed by 0xd1d

@bumblefudge
Copy link

nothing like looking into the binary for clues and seeing a D1D pop out right near the front 🤣

@bumblefudge
Copy link

TBH I'm kind of a binary ignoramus and defer to people with binary buidling/sniffing/needing experience but at least from my safe perch miles above the binary it seems elegant?

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

No branches or pull requests

2 participants