You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
typePrivateKeyInterfaceinterface {
Curve() CurveECDH(remote*PublicKey) ([]byte, error)
Equal(x crypto.PrivateKey) boolPublic() crypto.PublicKey
}
typeGenericCurveinterface {
// Using a different name so that to not break existing CurveGeneratePrivateKey(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 anywayECDH(local*PrivateKey, remote*PublicKey) ([]byte, error)
PrivateKeyToPublicKey(PrivateKeyInterface) *PublicKey
}
// NewPublicKey would simply return a public key objectfuncNewPublicKey(cCurve, 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 typetypeX509Marshalableinterface {
GetOID() pkix.AlgorithmIdentifierBytes() []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 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 likecrypto.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
andecdh.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 implementingGenerateKey
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:
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.The text was updated successfully, but these errors were encountered: