multiformats / multicodec

Compact self-describing codecs. Save space by using predefined multicodec tables.
MIT License
340 stars 204 forks source link

Add ed25519 secret key codec #194

Closed pukkamustard closed 4 years ago

pukkamustard commented 4 years ago

This adds a code for Ed25519 secret keys.

Ed25519 public keys have been previously added (https://github.com/multiformats/multicodec/pull/46).

Secret keys don't need to be shared as often as public keys, but there are valid use-cases and it also makes sense to have a multicodec code for internal storage of keys.

rvagg commented 4 years ago

-priv might be a more appropriate suffix?

I'm interested in a possible use-case for this; not saying it doesn't exist but this would be the first private key in the table.

pukkamustard commented 4 years ago

-priv might be a more appropriate suffix?

It seems like IPFS uses the term "private key". Agree then that -priv is more appropriate.

libsodium uses term "secret key" (https://libsodium.gitbook.io/doc/public-key_cryptography/authenticated_encryption), however inconsistently - "private key" is also used in the docs.

I have a slight bias towards secret but that is only a stylistic preference.

I'm interested in a possible use-case for this; not saying it doesn't exist but this would be the first private key in the table.

I must admit that I was partly just curious why there were no private keys in the table. This PR was in part to figure out why... :)

Primary use-case is definitely local storage of key-pairs. It seems reasonable to be able to encode the secret key in the same way the public key is encoded.

Note: Sorry, for closing and re-opening pull request. I messed up with GitHub keyboard shortcuts.

rvagg commented 4 years ago

I must admit that I was partly just curious why there were no private keys in the table. This PR was in part to figure out why... :)

Yeah, fair enough! I honestly don't see a reason not to, but I think that because we're dealing with a use-case with not very popular use then we'd better not take up the single-byte range for this because there's so few of them left. We're trying to be a bit more consistent with pushing new entries into the >1 byte range unless there's a good reason not to.

There's a block up around 0x1200 that's being used for curves, maybe we can divide that up and make space for a collection of related private keys, maybe jump to 0x1300?

pukkamustard commented 4 years ago

We're trying to be a bit more consistent with pushing new entries into the >1 byte range unless there's a good reason not to.

That makes sense.

There's a block up around 0x1200 that's being used for curves, maybe we can divide that up and make space for a collection of related private keys, maybe jump to 0x1300?

+1, pushed the jump to 0x1300.

pukkamustard commented 4 years ago

A use-case I am working on is a RDF signature scheme (https://gitlab.com/openengiadina/rdf-signify/-/blob/main/rdf-signify.org). I would like to encode public key and private key in a URN. It seems reasonable to use multiformats to do so.

E.g. a public key currently looks like this:

urn:ed25519:pk:CL6VDCRFNQOSNWMQGCZ6WT3WLKITSLUZN4J6FWQYL4FNUHAXOVVQ

With multicodecs it could maybe just look like this:

urn:crypto:XXXXXXXXXXLKJDASFSDFS

As the key type is encoded in the part after urn:crypto.

Encoding the private key should be possible for consistency and for the case where you want to delegate signing capability (without creating a new delegated key-pair).

Ping @tarcieri who seems to be working on the related https://github.com/cryptouri/cryptouri.rs.

rvagg commented 4 years ago

:thumbsup:

msporny commented 4 years ago

@pukkamustard wrote:

I have a slight bias towards secret but that is only a stylistic preference.

Agree with @pukkamustard that it should really be secret. There have been a number of names picked in the cryptographic community multiple decades ago that have not panned out... "private" vs. "secret" -- some developers new to the space still think it's ok to share 'private' things.

urn:ed25519:pk:CL6VDCRFNQOSNWMQGCZ6WT3WLKITSLUZN4J6FWQYL4FNUHAXOVVQ

Have you looked at did:key yet, @pukkamustard? https://w3c-ccg.github.io/did-method-key/#format

It's for public keys, primarily... we've considered it for private keys before but felt like that would be dangerous... same thing w/ registering private key types in multicodec. I can see the allure of expressing private keys using multicodec... but remember that it's a two-edged sword... you've now made it easy to accidentally express a public and private key and it's very hard for a programmer to distinguish one from the other in Ed25519 by just looking at a multibase encoding of it.