w3c / vc-di-ecdsa

Data Integrity specification for ECDSA using NIST-compliant curves
https://w3c.github.io/vc-di-ecdsa/
Other
9 stars 9 forks source link

Confirming `EcdsaSecp256r1VerificationKey2019` -> `Multikey` transition #22

Closed bnewbold closed 6 months ago

bnewbold commented 11 months ago

Hi folks,

It looks like between:

ECDSA Cryptosuite v2019
Achieving Data Integrity using ECDSA with NIST-compliant curves
Final Community Group Report 24 July 2022
https://www.w3.org/community/reports/credentials/CG-FINAL-di-ecdsa-2019-20220724/

and

Data Integrity ECDSA Cryptosuites v1.0
Achieving Data Integrity using ECDSA with NIST-compliant curves
W3C Working Draft 23 July 2023
https://www.w3.org/TR/2023/WD-vc-di-ecdsa-20230723/

the intended type for representing P-256 keys went from EcdsaSecp256r1VerificationKey2019 to Multikey.

I can find some earlier discussion about the proliferation of cryptosuites at https://lists.w3.org/Archives/Public/public-vc-wg/2022Jul/0044.html

My questions are: was multikey the solution selected for streamlining? And can folks use Multikey for both new cryptosuites (like P-256) and older curves (like K-256 with the existing EcdsaSecp256k1VerificationKey2019), with the multikey prefix being all that distinguishes the curves? Seems reasonable, just checking.

cc: @OR13 who hinted at this over in https://github.com/w3c/did-spec-registries/pull/515

OR13 commented 11 months ago

Multikey works with any keys that have been registered with multicodec

msporny commented 10 months ago

My questions are: was multikey the solution selected for streamlining?

Yes, correct.

And can folks use Multikey for both new cryptosuites (like P-256)

Yes, as described here:

https://w3c.github.io/vc-di-ecdsa/#multikey

and older curves (like K-256 with the existing EcdsaSecp256k1VerificationKey2019), with the multikey prefix being all that distinguishes the curves? Seems reasonable, just checking.

Yes.

Specifically, the multicodec entries you're looking for are this one for public secp256k1 keys:

https://github.com/multiformats/multicodec/blob/master/table.csv#L92

... and this one, if you want to express a private secp256k1 key:

https://github.com/multiformats/multicodec/blob/master/table.csv#L168

You will want to pay attention to this section (which is being updated as we speak) to make it more clear about how Multikey is used:

https://pr-preview.s3.amazonaws.com/w3c/vc-data-integrity/pull/152.html#multikey

There is no specification for ecdsa-k1 at present, but it would be fairly trivial to create one. You'd be looking at something that looks almost exactly like this (if you use RDF Canonicalization):

https://w3c.github.io/vc-di-ecdsa/#ecdsa-2019

or this (if you use JSON Canonicalization):

https://w3c.github.io/vc-di-ecdsa/#jcs-ecdsa-2019

with the k1 key format described in a section that looks like this:

https://w3c.github.io/vc-di-ecdsa/#multikey

@bnewbold, if I may ask, what are you using / planning to use this stuff for? How can we help?

bnewbold commented 10 months ago

@msporny thanks for these helpful resources and references!

I work on https://atproto.com, a protocol for federated social web applications, built by Bluesky (https://blueskyweb.xyz). We have a DID method (https://github.com/bluesky-social/did-method-plc) that we use, along with did:web, as part of our identity system (described in https://atproto.com/specs/atp#protocol-structure). We support the P-256/ secp256r1 and K-256/secp256k1 curves, and i'm trying to ensure that we are representing them well in our DID documents. Or at least, have a clear picture of how we should be representing them in the near future.

OR13 commented 10 months ago

@bnewbold you will probably be forced to choose a key representation, and it will either be multikey or json web key... I don't recommend supporting both.

Maybe take a look at https://github.com/w3c/vc-di-eddsa/issues/4#issuecomment-1670430711

dmitrizagidulin commented 10 months ago

@bnewbold I would give the exact opposite advice :)

  1. Support both multikey and JSON Web Key representations.
  2. If you're dead-set on supporting only one, you should go with Multikey. ATProto is at its heart a green-field project, aiming to fix the shortcomings of many existing methodologies (RPC, schemas, etc). And Multikey is a chance to fix the absolutely horrible DX (developer usability) that JWK presents. (heheh, I can never forgive naming your secret key d -- yes, that's very mnemonic and understandable to developers.)
bnewbold commented 10 months ago

We would almost certainly go with Multikey. We use several multiformats and are comfortable with them, and even use did:key to serialize public keys as strings internally. Unless i'm confused, with type=Multikey, the publicKeyMultibase format would be encoded the same as the identifier part of did:key (multibase prefix char 'z' for base58btc; varint-encoded multicodec table value for the key, which also clarifies if compressed or not; then the serialized key bytes).

msporny commented 10 months ago

We would almost certainly go with Multikey. We use several multiformats and are comfortable with them, and even use did:key to serialize public keys as strings internally.

Yes, there are a number of us in the community that are strongly recommending Multikey over JWK due to the bad developer/security experience w/ JWK. That said, some ecosystems will almost certainly need to implement both, and there is language in the Data Integrity specifications noting that internal conversion from one key format to another is an acceptable operation.

Unless i'm confused, with type=Multikey, the publicKeyMultibase format would be encoded the same as the identifier part of did:key (multibase prefix char 'z' for base58btc; varint-encoded multicodec table value for the key, which also clarifies if compressed or not; then the serialized key bytes).

Yes, exactly. More details on exact key formats are here:

https://w3c.github.io/vc-di-ecdsa#multikey https://w3c.github.io/vc-di-eddsa#multikey

I work on https://atproto.com/, a protocol for federated social web applications, built by Bluesky (https://blueskyweb.xyz/). We have a DID method (https://github.com/bluesky-social/did-method-plc) that we use, along with did:web, as part of our identity system (described in https://atproto.com/specs/atp#protocol-structure). We support the P-256/ secp256r1 and K-256/secp256k1 curves, and i'm trying to ensure that we are representing them well in our DID documents. Or at least, have a clear picture of how we should be representing them in the near future.

Excellent! I have spoken with Paul Frazee and Jay Graber over the years about how DIDs and VCs could play a part in atproto... and while there was not complete alignment in what ended up being built into atproto, I'm glad to hear that some of the primitives are being shared between these communities.

All that to say, @bnewbold -- let us know how we can help. We are motivated to help you in whatever way we can. It feels like what might be missing right now is a cryptosuite for secp256k1 -- you can easily go off and create your own spec for that, or we could create a template for you. If Bluesky / atproto is going to use that cryptosuite, and you signal strongly that you are, I could see an argument to add it to the global standard. We (the W3C VCWG) /are/ chartered to deliver k1 support, but to date, no one has stepped up and said that they wanted it (and committed to doing the work/implementation).

In any case, let us know how we can help.

OR13 commented 10 months ago

@bnewbold do you use application/did+ld+json or application/did+json ?

Do you plan to implement this specification (data integrity proofs with RDF Canonicalization), as part of at protocol?

bnewbold commented 10 months ago

@msporny: these detailed responses to questions are very helpful, thank you. We are planning to roll out changes to our did:plc DID Document formatting soon to comply with several specifications.

We definitely are using secp256k1 already, in a way that aligns very closely with secp256r1, and hopefully will align with any future specification for that crypto suite. We have a bunch of balls in the air right now and I can't specifically commit to contributing to pushing through a W3C specification for that. Would be willing to review and lend a hand if somebody else volunteers to lead that work.

@OR13 we are using application/did+ld+json as a Content-Type right now, but we don't make use of any JSON-LD aware software/libraries/etc in any systems currently, and don't have any plans to do so. I don't think it makes much of a difference for us either way; perhaps application/did+json would be a simplification?

OR13 commented 10 months ago

I'd not recommend application/did+json over application/json or application/did+ld+json

All of the structure of did core v1 comes from the RDF data model, and to the extent that it's been made abstract, there is essentially 0 value in the none JSON-LD representation.

When it comes to representing verification methods, I don't think it helps with integrations or adoption to use multikey, or IPLD, but if you have muliformats as a dependency already I can see the value of making your "native key format multikey".

The same is true of building on ethereum, once you rely on it, you have incentive to keep using it, disincentive to look for the same features in other places.

Perhaps data integrity proofs are similarly worth choosing then, since they also rely on multibase.

On the other side of the picture, you have OAuth, SD-JWTs, SIOP, OIDC, JOSE... Maybe COSE in the future.

Of course you can add multiformats to this mix, or translate from them to the representations needed to have interop with the above standards.

In the context of DIDs, your method can enforce a single key format, or allow users to invent their own key formats.

When you try to interop with a different method, you will both support the same formats, or you will have to translate to communicate.

Lots of blockchain based did methods use multibase, very few of them define all the terms in their JSON LD did document correctly.

peacekeeper commented 10 months ago

It may be worth mentioning that there's an extension DID parameter called "transformKeys" which some resolvers support. You can use this to instruct the resolver to return a DID document where the verification methods are converted to a specific format, to make it easier for clients to consume them.

See https://github.com/decentralized-identity/did-spec-extensions/blob/main/parameters/transform-keys.md

Examples:

did:example:123?transformKeys=EcdsaSecp256r1VerificationKey2019
did:example:123?transformKeys=JsonWebKey2020
did:example:123?transformKeys=MultiKey
OR13 commented 10 months ago

It's weird to see that in URLs since it changes the identifier for the resource.

Also lots of places in a did document do not support DID URLs, only DIDs.

I would expect to see that as a media type or some other header parameter, so the identifiers and relationships would not change based on the key representation requested.

msporny commented 6 months ago

This issue is fairly old and the question was answered some time ago. Seems like discussion on the issue has ended. I'm closing this issue. @bnewbold, please re-open a new issue if there is further discussion to be had.