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

Support key generation from seed as described in RFC 8032 section 5.1.5 #64

Closed
zamicol opened this issue Jun 3, 2022 · 6 comments
Closed

Comments

@zamicol
Copy link

zamicol commented Jun 3, 2022

Looking through the project, I did not see key generation from seed as describe in RFC 8032 section 5.1.5.

I would suggest ignoring the RFC's term "private key" and follow Go's term "seed". It makes the functions more readable while differentiating private key and seed.

Go's NewKeyFromSeed:
https://cs.opensource.google/go/go/+/refs/tags/go1.18.3:src/crypto/ed25519/ed25519.go;l=116

And Go's SetBytesWithClamping
https://cs.opensource.google/go/go/+/refs/tags/go1.18.3:src/crypto/internal/edwards25519/scalar.go;l=138;drc=7846e25418a087ca15122b88fc179405e26bf768;bpv=1;bpt=1

I would also point out Filippo's comment:

[I]t is lost to history why RFC 8032 adopted the irrelevant RFC 7748 clamping, but it is now required for compatibility.

Edit: The JavaScript TweetNaCl also is doing this like the Go implementation except they've dubbed it "secretKey" whereas the Go library has dubbed it "private key" (with the public 32 byte component appended). The first 32 bytes of secretKey is the secret component.
https://github.com/dchest/tweetnacl-js#naclsignkeypairfromsecretkeysecretkey

@paulmillr
Copy link
Owner

I don't understand. There's getPublicKey?

@paulmillr
Copy link
Owner

getPublicKey and getExtendedPublicKey

@paulmillr paulmillr closed this as not planned Won't fix, can't repro, duplicate, stale Jun 3, 2022
@zamicol
Copy link
Author

zamicol commented Jun 3, 2022

Thank you, but I don't think "private key" (not "seed") is being exported. It looks like seed (which is named PrivKey) is given, public key, named pointBytes is returned, but the private key is not exposed anywhere.

getPublicKey only returns the public key and getExtendedPublicKey itself isn't exported.

In function "getExtendedPublicKey", I need scalar.

Either:

  • A. From getExtendedPublicKey, scalar, which is bigint, needs to be exported in some way or
  • B. a new function that returns the private key bytes from scalar, like getPublicKey, should be created.

For comparison with the Go package,

This package refers to the RFC 8032 private key as the “seed”.

https://pkg.go.dev/crypto/ed25519

Edit: And another example from TweetNaCl Javascript:
https://github.com/dchest/tweetnacl-js#naclsignkeypair

Where they are appending the public key to the private key (that's why it's 64 bytes). Seed is distinct from private key.

@paulmillr
Copy link
Owner

paulmillr commented Jun 4, 2022

utils.getExtendedPublicKey is exported and described in readme in getPublicKey docs.

Use utils.getExtendedPublicKey if you need full SHA512 hash of seed

@zamicol
Copy link
Author

zamicol commented Jun 7, 2022

For anyone in the future sharing my confusion:

What TweetNaCL , Go, and other packages call the "private key" is simply the seed concatenated with the public key.

Also, NaCL used to return the the private key as the "secret scalar s" with the "prefix" (the second half of the digest of the seed). Instead of doing that most libraries simply regenerate both secrete scalar s and prefix from seed, and optionally cache public key.

Thank you Paul for you work on this fantastic library. 👍

@paulmillr
Copy link
Owner

paulmillr commented Jun 8, 2022

It's a shame they use 64-byte private keys:

  1. 64 > 32, it's harder to store
  2. The second (public) part of the 64-byte key can be corrupted e.g. by replacing one letter with another. This way, the private key would correspond to slightly different pubkey, and it could create all kinds of issues
  3. All other curves specify private key = private key, w/o pub key
  4. Spec says nothing about 64 byte keys

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