1
0
mirror of https://github.com/golang/go synced 2024-11-11 19:51:37 -07:00

crypto/ecdh: move ECDH method to PrivateKey

Fixes #56052

Change-Id: Icacba0ed0f77519bca2140c8af68407af97f9734
Reviewed-on: https://go-review.googlesource.com/c/go/+/450335
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Joedian Reid <joedian@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
Filippo Valsorda 2022-11-14 12:13:46 +01:00 committed by Gopher Robot
parent 5947a07d72
commit dafc915204
8 changed files with 32 additions and 26 deletions

View File

@ -4,13 +4,13 @@ pkg crypto/ecdh, func P521() Curve #52221
pkg crypto/ecdh, func X25519() Curve #52221
pkg crypto/ecdh, method (*PrivateKey) Bytes() []uint8 #52221
pkg crypto/ecdh, method (*PrivateKey) Curve() Curve #52221
pkg crypto/ecdh, method (*PrivateKey) ECDH(*PublicKey) ([]uint8, error) #52221
pkg crypto/ecdh, method (*PrivateKey) Equal(crypto.PrivateKey) bool #52221
pkg crypto/ecdh, method (*PrivateKey) Public() crypto.PublicKey #52221
pkg crypto/ecdh, method (*PrivateKey) PublicKey() *PublicKey #52221
pkg crypto/ecdh, method (*PublicKey) Bytes() []uint8 #52221
pkg crypto/ecdh, method (*PublicKey) Curve() Curve #52221
pkg crypto/ecdh, method (*PublicKey) Equal(crypto.PublicKey) bool #52221
pkg crypto/ecdh, type Curve interface, ECDH(*PrivateKey, *PublicKey) ([]uint8, error) #52221
pkg crypto/ecdh, type Curve interface, GenerateKey(io.Reader) (*PrivateKey, error) #52221
pkg crypto/ecdh, type Curve interface, NewPrivateKey([]uint8) (*PrivateKey, error) #52221
pkg crypto/ecdh, type Curve interface, NewPublicKey([]uint8) (*PublicKey, error) #52221

View File

@ -15,16 +15,6 @@ import (
)
type Curve interface {
// ECDH performs a ECDH exchange and returns the shared secret.
//
// For NIST curves, this performs ECDH as specified in SEC 1, Version 2.0,
// Section 3.3.1, and returns the x-coordinate encoded according to SEC 1,
// Version 2.0, Section 2.3.5. The result is never the point at infinity.
//
// For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If
// the result is the all-zero value, ECDH returns an error.
ECDH(local *PrivateKey, remote *PublicKey) ([]byte, error)
// GenerateKey generates a new PrivateKey from rand.
GenerateKey(rand io.Reader) (*PrivateKey, error)
@ -49,15 +39,19 @@ type Curve interface {
// selected public keys can cause ECDH to return an error.
NewPublicKey(key []byte) (*PublicKey, error)
// ecdh performs a ECDH exchange and returns the shared secret. It's exposed
// as the PrivateKey.ECDH method.
//
// The private method also allow us to expand the ECDH interface with more
// methods in the future without breaking backwards compatibility.
ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error)
// privateKeyToPublicKey converts a PrivateKey to a PublicKey. It's exposed
// as the PrivateKey.PublicKey method.
//
// This method always succeeds: for X25519, the zero key can't be
// constructed due to clamping; for NIST curves, it is rejected by
// NewPrivateKey.
//
// The private method also allow us to expand the ECDH interface with more
// methods in the future without breaking backwards compatibility.
privateKeyToPublicKey(*PrivateKey) *PublicKey
}
@ -107,6 +101,18 @@ type PrivateKey struct {
publicKeyOnce sync.Once
}
// ECDH performs a ECDH exchange and returns the shared secret.
//
// For NIST curves, this performs ECDH as specified in SEC 1, Version 2.0,
// Section 3.3.1, and returns the x-coordinate encoded according to SEC 1,
// Version 2.0, Section 2.3.5. The result is never the point at infinity.
//
// For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If
// the result is the all-zero value, ECDH returns an error.
func (k *PrivateKey) ECDH(remote *PublicKey) ([]byte, error) {
return k.curve.ecdh(k, remote)
}
// Bytes returns a copy of the encoding of the private key.
func (k *PrivateKey) Bytes() []byte {
// Copy the private key to a fixed size buffer that can get allocated on the

View File

@ -68,11 +68,11 @@ func TestECDH(t *testing.T) {
t.Error("encoded and decoded private keys are different")
}
bobSecret, err := curve.ECDH(bobKey, aliceKey.PublicKey())
bobSecret, err := bobKey.ECDH(aliceKey.PublicKey())
if err != nil {
t.Fatal(err)
}
aliceSecret, err := curve.ECDH(aliceKey, bobKey.PublicKey())
aliceSecret, err := aliceKey.ECDH(bobKey.PublicKey())
if err != nil {
t.Fatal(err)
}
@ -169,7 +169,7 @@ func TestVectors(t *testing.T) {
if err != nil {
t.Fatal(err)
}
secret, err := curve.ECDH(key, peer)
secret, err := key.ECDH(peer)
if err != nil {
t.Fatal(err)
}
@ -216,7 +216,7 @@ func testX25519Failure(t *testing.T, private, public []byte) {
if err != nil {
t.Fatal(err)
}
secret, err := ecdh.X25519().ECDH(priv, pub)
secret, err := priv.ECDH(pub)
if err == nil {
t.Error("expected ECDH error")
}
@ -392,7 +392,7 @@ func BenchmarkECDH(b *testing.B) {
if err != nil {
b.Fatal(err)
}
secret, err := curve.ECDH(key, peerPubKey)
secret, err := key.ECDH(peerPubKey)
if err != nil {
b.Fatal(err)
}
@ -432,7 +432,7 @@ func main() {
if err != nil { panic(err) }
_, err = curve.NewPrivateKey(key.Bytes())
if err != nil { panic(err) }
_, err = curve.ECDH(key, key.PublicKey())
_, err = key.ECDH(key.PublicKey())
if err != nil { panic(err) }
println("OK")
}

View File

@ -188,7 +188,7 @@ func (c *nistCurve[Point]) NewPublicKey(key []byte) (*PublicKey, error) {
return k, nil
}
func (c *nistCurve[Point]) ECDH(local *PrivateKey, remote *PublicKey) ([]byte, error) {
func (c *nistCurve[Point]) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error) {
// Note that this function can't return an error, as NewPublicKey rejects
// invalid points and the point at infinity, and NewPrivateKey rejects
// invalid scalars and the zero value. BytesX returns an error for the point

View File

@ -74,7 +74,7 @@ func (c *x25519Curve) NewPublicKey(key []byte) (*PublicKey, error) {
}, nil
}
func (c *x25519Curve) ECDH(local *PrivateKey, remote *PublicKey) ([]byte, error) {
func (c *x25519Curve) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error) {
out := make([]byte, x25519SharedSecretSize)
x25519ScalarMult(out, local.privateKey, remote.publicKey)
if isZero(out) {

View File

@ -353,7 +353,7 @@ func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: invalid server key share")
}
sharedKey, err := hs.ecdheKey.Curve().ECDH(hs.ecdheKey, peerKey)
sharedKey, err := hs.ecdheKey.ECDH(peerKey)
if err != nil {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: invalid server key share")

View File

@ -220,7 +220,7 @@ GroupSelection:
c.sendAlert(alertIllegalParameter)
return errors.New("tls: invalid client key share")
}
hs.sharedKey, err = key.Curve().ECDH(key, peerKey)
hs.sharedKey, err = key.ECDH(peerKey)
if err != nil {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: invalid client key share")

View File

@ -264,7 +264,7 @@ func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Cert
if err != nil {
return nil, errClientKeyExchange
}
preMasterSecret, err := ka.key.Curve().ECDH(ka.key, peerKey)
preMasterSecret, err := ka.key.ECDH(peerKey)
if err != nil {
return nil, errClientKeyExchange
}
@ -307,7 +307,7 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
if err != nil {
return errServerKeyExchange
}
ka.preMasterSecret, err = key.Curve().ECDH(key, peerKey)
ka.preMasterSecret, err = key.ECDH(peerKey)
if err != nil {
return errServerKeyExchange
}