]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/ecdh: move ECDH method to PrivateKey
authorFilippo Valsorda <filippo@golang.org>
Mon, 14 Nov 2022 11:13:46 +0000 (12:13 +0100)
committerGopher Robot <gobot@golang.org>
Wed, 16 Nov 2022 14:37:29 +0000 (14:37 +0000)
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>

api/next/52221.txt
src/crypto/ecdh/ecdh.go
src/crypto/ecdh/ecdh_test.go
src/crypto/ecdh/nist.go
src/crypto/ecdh/x25519.go
src/crypto/tls/handshake_client_tls13.go
src/crypto/tls/handshake_server_tls13.go
src/crypto/tls/key_agreement.go

index c288e4660b3686c8f88392be253e6f4aa0edd0e6..ed4a487b8c27de114834b4e5773e5bb9dd594151 100644 (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
index 73a5c68d506aea08983a9784806fd1c2f4066250..e5270d840b9abf121cb267a092aad66e572280db 100644 (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
index 0846268c45287752dfef4532c83bb8100a686500..426850a146101e0e6dfe424bd5fb7f99f46a66e4 100644 (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")
 }
index 6d30b7bbb2bd9c9bd18d205df3ae544ac2489c3c..01354fa2cf0af238b6435e54526144bc4e195dbf 100644 (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
index 21127ffb957aa7bfa5c59ce237e322a969fa3985..dbc3ea9dc89622b808995129a3db5b32f9601f37 100644 (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) {
index 12ff3a4a4ff9341c79f4220792477a0bc03ed1ad..3bdd9373d668efd2d1f4365bdce6952d64657d15 100644 (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")
index 9b7356a32b485deb7faff4e71409694ea4a7439e..80d4dce3c5d6ed3691d083213450cdcb99c74837 100644 (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")
index 027060d090e71b71e73ae36034aba21c37edd8f5..2c8c5b8d77135906a04c550ce2545c70530079c7 100644 (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
        }