-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
Proposal Details
At this point this is more a number of thoughts and description of issues I've encountered trying to work with crypto/ecdh rather than a proposal to change things in a specific way. crypto/ecdh is used by a lot of people, so breaking changes are out of the picture unless maybe if a /v2 version is created, but I am not sure this is warranted or even qualifies.
My goal here is first to start a discussion.
Golang's crypto package is nice because objects like crypto.PrivateKey are interfaces that allows both the use of local secrets managed via the standard libraries, or hardware encryption where secrets aren't stored on the machine at all.
It seems that this was a goal, as crypto/ecdh.Curve is an interface that could be implemented by a third party package, for the exception that it has private functions and it is impossible to implement NewPrivateKey or NewPublicKey because both are opaque objects.
Ideally both ecdh.PublicKey and ecdh.PrivateKey would be interfaces, however now that the package is widely used it is not possible to change that without causing a lot of breakage.
An alternative would be to have a method to create private/public key objects by specifying the data (bytes) and curve interface, and making the private elements of the curve interface public. Actually it would be better if the private key data could be an interface for the private key, as in the case of a tpm it would be a Handle, and in some cases libraries may prefer keeping track of specific values for performance.
Point is, the ecdh interface as it exists is very nice. Creating an ephemeral private key to encode a message to a recipient is as easy as recipient.Curve().GenerateKey(rand.Reader), it's a shame however that it is not possible to implement other curves.
Current library has a nice API, the part about PrivateKey can actually be worked around fairly easily as long as the curve is one supported by crypto/ecdh. Working with other curves however is proving to be extremely difficult, dirty alternatives include things like implementing GenerateKey directly on the public key object that returns not a *ecdh.PrivateKey but a custom object that simply implements the minimum required.
Some suggestions here:
type PrivateKeyInterface interface {
Curve() Curve
ECDH(remote *PublicKey) ([]byte, error)
Equal(x crypto.PrivateKey) bool
Public() crypto.PublicKey
}
type GenericCurve interface {
// Using a different name so that to not break existing Curve
GeneratePrivateKey(rand io.Reader) (PrivateKeyInterface, error)
// The current ecdh package does not expose the following methods, making these public would allow custom implementations so I'm curious for the more specific reason than "breaking backward compatibility" for an interface that cannot be implemented externally anyway
ECDH(local *PrivateKey, remote *PublicKey) ([]byte, error)
PrivateKeyToPublicKey(PrivateKeyInterface) *PublicKey
}
// NewPublicKey would simply return a public key object
func NewPublicKey(c Curve, data []byte) *PublicKey
// This could be nice to allow custom curve objects to be marshalable, and maybe parsable if there is some method to register a type
type X509Marshalable interface {
GetOID() pkix.AlgorithmIdentifier
Bytes() []byte // current name in ecdh
}More curves are being requested, and being able to extend things without the need for users of crypto/ecdh to think too much about makes sense I believe.
- proposal: crypto/ecdh: support for secp256k1 curve #59368 about support for adding a specific curve
- proposal: crypto/ecdh: support for P224 #59783
Metadata
Metadata
Assignees
Labels
Type
Projects
Status