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

proposal: x/crypto/ed25519: add NewKeyFromPlain to generate a PublicKey from a PrivateKey #33997

Closed
ston1th opened this issue Aug 31, 2019 · 3 comments
Labels
FrozenDueToAge Proposal Proposal-Crypto Proposal related to crypto packages or other security issues
Milestone

Comments

@ston1th
Copy link

ston1th commented Aug 31, 2019

Hi guys,

I would like to propose a new function NewKeyFromPlain for the crypto/ed25519 package as there seems no way to generate a public key from only a private key.

The new NewKeyFromPlain would behave the same as NewKeyFromSeed but without the sha512 hashing part.

Maybe related to: #33923

@odeke-em odeke-em changed the title crypto/ed25519,x/crypto/ed25519: add NewKeyFromPlain function proposal: x/crypto/ed25519: add NewKeyFromPlain function Aug 31, 2019
@gopherbot gopherbot added this to the Proposal milestone Aug 31, 2019
@odeke-em
Copy link
Member

Thank you for filing this request @ston1th!

You say

NewKeyFromPlain for the crypto/ed25519 package as there seems no way to generate a public key from only a private key.

However, from the godoc for x/crypto/ed25519 https://godoc.org/golang.org/x/crypto/ed25519 there is a method on PrivateKey that retrieves the corresponding PublicKey as per https://godoc.org/golang.org/x/crypto/ed25519#PrivateKey.Public

and here is a playground link https://play.golang.org/p/ImukvRBYlH_p or inlined below

package main

import (
	"crypto/rand"
	"fmt"
	"io"
	"io/ioutil"

	"golang.org/x/crypto/ed25519"
)

func main() {
	seed, _ := ioutil.ReadAll(io.LimitReader(rand.Reader, 32))
	privKey := ed25519.NewKeyFromSeed(seed)

	pubKey := privKey.Public()
	fmt.Printf("PrivateKey: %#v\nPublicKey: %#v\n", privKey, pubKey)
}

Could you please clarify that? Do you mean generate an entirely new public key or did you have trouble getting the corresponding public key? If the latter, perhaps this just might be a documentation discovery problem? I am totally not a crypto expert but my responses are just based off my experience using these packages in applications.

It would also be nice to perhaps provide a preview of what your proposed signature would look like, this can help expedite and make proposal review easy.

Kindly looping in @FiloSottile @agl

@ston1th
Copy link
Author

ston1th commented Sep 1, 2019

Yes, I know about privKey.Public() but looking in the implementation this just returns the last 32 bytes of the privKey slice instead of generating the public key based on the private key (I assume for performance reasons): https://github.com/golang/crypto/blob/master/ed25519/ed25519.go#L53

So let's say I already have a 32 byte private key but not the corresponding public key.
Since the privKey.Public() does no calculation based on the private key its not possible to generate the public key.

A example (may be not cryptographically correct) would look like this:

func NewKeyFromPlain(key []byte) ed25519.PrivateKey {
	if l := len(key); l != ed25519.SeedSize {
		panic("ed25519: bad key length: " + strconv.Itoa(l))
	}
	key[0] &= 248
	key[31] &= 127
	key[31] |= 64

	var A edwards25519.ExtendedGroupElement
	var hBytes [32]byte
	copy(hBytes[:], key[:])
	edwards25519.GeScalarMultBase(&A, &hBytes)
	var publicKeyBytes [32]byte
	A.ToBytes(&publicKeyBytes)

	privateKey := make([]byte, ed25519.PrivateKeySize)
	copy(privateKey, key)
	copy(privateKey[32:], publicKeyBytes[:])

	return privateKey
}

So basically the same as ed25519.NewKeyFromSeed but without sha512-hashing the input: https://github.com/golang/crypto/blob/master/ed25519/ed25519.go#L104

@odeke-em odeke-em changed the title proposal: x/crypto/ed25519: add NewKeyFromPlain function proposal: x/crypto/ed25519: add NewKeyFromPlain to generate a PublicKey from a PrivateKey Sep 1, 2019
@ianlancetaylor ianlancetaylor added the Proposal-Crypto Proposal related to crypto packages or other security issues label Sep 3, 2019
@FiloSottile
Copy link
Contributor

The Seed vs PrivateKey situation in that API is already too confused. Let's stick to RFC 8032, which does not even acknowledge the existence of the intermediate private key, and just calls the seed private key.

@golang golang locked and limited conversation to collaborators Dec 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge Proposal Proposal-Crypto Proposal related to crypto packages or other security issues
Projects
None yet
Development

No branches or pull requests

5 participants