ektrah / nsec

A modern and easy-to-use cryptographic library for .NET 8+ based on libsodium
https://nsec.rocks
MIT License
374 stars 52 forks source link

Add support for passing seed in key creation #56

Closed RinkalBhojani closed 2 years ago

RinkalBhojani commented 3 years ago

Hey @ektrah @joemphilips

Key generation is an important part of cryptographic library. User may want to generate same key multiple times, hence "seed" plays an important role. Internal functions support seed as an option but it is a randomly generated one in current implementation as far as I can see. Please correct.

Accepting seed from the user can be a useful feature to implement. Please give your opinion on this.

Below is the existing code reference : image

Regards, Rinkal Bhojani

ektrah commented 3 years ago

There are currently two ways to "generate same key multiple times":

RinkalBhojani commented 3 years ago

We want to generate keypair using signature algorithm(ED25519), hence we will not be able to use KeyDerivationAlgorithm.DeriveKey

Also, there can be two discrete systems intend to generate same keypair. Persisting key will not work here.

ektrah commented 3 years ago

Could you provide a link to the specification you’re implementing?

RinkalBhojani commented 3 years ago

We are trying to implement decentralized identifier(DID). Below are the specifications.

https://www.w3.org/TR/did-core/#did-syntax https://www.w3.org/TR/did-spec-registries/#ed25519verificationkey2018

We are referring this class to create keys. https://nsec.rocks/docs/api/nsec.cryptography.key

Below is the sample code.

        Key key = Key.Create(SignatureAlgorithm.Ed25519, KeyCreationParams());
        byte[] privateKey = key.Export(KeyBlobFormat.RawPrivateKey);
        byte[] publicKey = key.Export(KeyBlobFormat.RawPublicKey);

We need to generate this keys by passing seed, so that we can generate same key multiple times.

ektrah commented 3 years ago

Thanks for providing the link to the specification! The linked example looks like this:

{
  "id": "did:example:123#ZC2jXTO6t4R501bfCXv3RxarZyUbdP2w_psLwMuY6ec",
  "type": "Ed25519VerificationKey2018",
  "controller": "did:example:123",
  "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}

I assume that you're trying to a create a PublicKey instance from the "publicKeyBase58" field. You can do that as follows:

string publicKeyBase58 = "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV";
byte[] publicKeyBytes = YourBase58Decode(publicKeyBase58);
PublicKey publicKey = PublicKey.Import(SignatureAlgorithm.Ed25519, publicKeyBytes, KeyBlobFormat.RawPublicKey);

That is, the DID format for Ed25519 public keys seems to be the Base58 encoding of the RawPublicKey format provided by NSec.

using Key privateKey = Key.Create(SignatureAlgorithm.Ed25519, ...);
PublicKey publicKey = privateKey.PublicKey;
byte[] publicKeyBytes =publicKey.Export(KeyBlobFormat.RawPublicKey);
string publicKeyBase58 = YourBase58Encode(publicKeyBytes);

Does that solve your issue?

ektrah commented 2 years ago

I'm not sure if the question has been answered or not. Closing this due to inactivity now.