Skip to content

Commit dafc915

Browse files
FiloSottilegopherbot
authored andcommitted
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 <[email protected]> Reviewed-by: Roland Shoemaker <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Joedian Reid <[email protected]> Auto-Submit: Filippo Valsorda <[email protected]>
1 parent 5947a07 commit dafc915

File tree

8 files changed

+32
-26
lines changed

8 files changed

+32
-26
lines changed

api/next/52221.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ pkg crypto/ecdh, func P521() Curve #52221
44
pkg crypto/ecdh, func X25519() Curve #52221
55
pkg crypto/ecdh, method (*PrivateKey) Bytes() []uint8 #52221
66
pkg crypto/ecdh, method (*PrivateKey) Curve() Curve #52221
7+
pkg crypto/ecdh, method (*PrivateKey) ECDH(*PublicKey) ([]uint8, error) #52221
78
pkg crypto/ecdh, method (*PrivateKey) Equal(crypto.PrivateKey) bool #52221
89
pkg crypto/ecdh, method (*PrivateKey) Public() crypto.PublicKey #52221
910
pkg crypto/ecdh, method (*PrivateKey) PublicKey() *PublicKey #52221
1011
pkg crypto/ecdh, method (*PublicKey) Bytes() []uint8 #52221
1112
pkg crypto/ecdh, method (*PublicKey) Curve() Curve #52221
1213
pkg crypto/ecdh, method (*PublicKey) Equal(crypto.PublicKey) bool #52221
13-
pkg crypto/ecdh, type Curve interface, ECDH(*PrivateKey, *PublicKey) ([]uint8, error) #52221
1414
pkg crypto/ecdh, type Curve interface, GenerateKey(io.Reader) (*PrivateKey, error) #52221
1515
pkg crypto/ecdh, type Curve interface, NewPrivateKey([]uint8) (*PrivateKey, error) #52221
1616
pkg crypto/ecdh, type Curve interface, NewPublicKey([]uint8) (*PublicKey, error) #52221

src/crypto/ecdh/ecdh.go

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,6 @@ import (
1515
)
1616

1717
type Curve interface {
18-
// ECDH performs a ECDH exchange and returns the shared secret.
19-
//
20-
// For NIST curves, this performs ECDH as specified in SEC 1, Version 2.0,
21-
// Section 3.3.1, and returns the x-coordinate encoded according to SEC 1,
22-
// Version 2.0, Section 2.3.5. The result is never the point at infinity.
23-
//
24-
// For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If
25-
// the result is the all-zero value, ECDH returns an error.
26-
ECDH(local *PrivateKey, remote *PublicKey) ([]byte, error)
27-
2818
// GenerateKey generates a new PrivateKey from rand.
2919
GenerateKey(rand io.Reader) (*PrivateKey, error)
3020

@@ -49,15 +39,19 @@ type Curve interface {
4939
// selected public keys can cause ECDH to return an error.
5040
NewPublicKey(key []byte) (*PublicKey, error)
5141

42+
// ecdh performs a ECDH exchange and returns the shared secret. It's exposed
43+
// as the PrivateKey.ECDH method.
44+
//
45+
// The private method also allow us to expand the ECDH interface with more
46+
// methods in the future without breaking backwards compatibility.
47+
ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error)
48+
5249
// privateKeyToPublicKey converts a PrivateKey to a PublicKey. It's exposed
5350
// as the PrivateKey.PublicKey method.
5451
//
5552
// This method always succeeds: for X25519, the zero key can't be
5653
// constructed due to clamping; for NIST curves, it is rejected by
5754
// NewPrivateKey.
58-
//
59-
// The private method also allow us to expand the ECDH interface with more
60-
// methods in the future without breaking backwards compatibility.
6155
privateKeyToPublicKey(*PrivateKey) *PublicKey
6256
}
6357

@@ -107,6 +101,18 @@ type PrivateKey struct {
107101
publicKeyOnce sync.Once
108102
}
109103

104+
// ECDH performs a ECDH exchange and returns the shared secret.
105+
//
106+
// For NIST curves, this performs ECDH as specified in SEC 1, Version 2.0,
107+
// Section 3.3.1, and returns the x-coordinate encoded according to SEC 1,
108+
// Version 2.0, Section 2.3.5. The result is never the point at infinity.
109+
//
110+
// For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If
111+
// the result is the all-zero value, ECDH returns an error.
112+
func (k *PrivateKey) ECDH(remote *PublicKey) ([]byte, error) {
113+
return k.curve.ecdh(k, remote)
114+
}
115+
110116
// Bytes returns a copy of the encoding of the private key.
111117
func (k *PrivateKey) Bytes() []byte {
112118
// Copy the private key to a fixed size buffer that can get allocated on the

src/crypto/ecdh/ecdh_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ func TestECDH(t *testing.T) {
6868
t.Error("encoded and decoded private keys are different")
6969
}
7070

71-
bobSecret, err := curve.ECDH(bobKey, aliceKey.PublicKey())
71+
bobSecret, err := bobKey.ECDH(aliceKey.PublicKey())
7272
if err != nil {
7373
t.Fatal(err)
7474
}
75-
aliceSecret, err := curve.ECDH(aliceKey, bobKey.PublicKey())
75+
aliceSecret, err := aliceKey.ECDH(bobKey.PublicKey())
7676
if err != nil {
7777
t.Fatal(err)
7878
}
@@ -169,7 +169,7 @@ func TestVectors(t *testing.T) {
169169
if err != nil {
170170
t.Fatal(err)
171171
}
172-
secret, err := curve.ECDH(key, peer)
172+
secret, err := key.ECDH(peer)
173173
if err != nil {
174174
t.Fatal(err)
175175
}
@@ -216,7 +216,7 @@ func testX25519Failure(t *testing.T, private, public []byte) {
216216
if err != nil {
217217
t.Fatal(err)
218218
}
219-
secret, err := ecdh.X25519().ECDH(priv, pub)
219+
secret, err := priv.ECDH(pub)
220220
if err == nil {
221221
t.Error("expected ECDH error")
222222
}
@@ -392,7 +392,7 @@ func BenchmarkECDH(b *testing.B) {
392392
if err != nil {
393393
b.Fatal(err)
394394
}
395-
secret, err := curve.ECDH(key, peerPubKey)
395+
secret, err := key.ECDH(peerPubKey)
396396
if err != nil {
397397
b.Fatal(err)
398398
}
@@ -432,7 +432,7 @@ func main() {
432432
if err != nil { panic(err) }
433433
_, err = curve.NewPrivateKey(key.Bytes())
434434
if err != nil { panic(err) }
435-
_, err = curve.ECDH(key, key.PublicKey())
435+
_, err = key.ECDH(key.PublicKey())
436436
if err != nil { panic(err) }
437437
println("OK")
438438
}

src/crypto/ecdh/nist.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func (c *nistCurve[Point]) NewPublicKey(key []byte) (*PublicKey, error) {
188188
return k, nil
189189
}
190190

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

src/crypto/ecdh/x25519.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (c *x25519Curve) NewPublicKey(key []byte) (*PublicKey, error) {
7474
}, nil
7575
}
7676

77-
func (c *x25519Curve) ECDH(local *PrivateKey, remote *PublicKey) ([]byte, error) {
77+
func (c *x25519Curve) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error) {
7878
out := make([]byte, x25519SharedSecretSize)
7979
x25519ScalarMult(out, local.privateKey, remote.publicKey)
8080
if isZero(out) {

src/crypto/tls/handshake_client_tls13.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
353353
c.sendAlert(alertIllegalParameter)
354354
return errors.New("tls: invalid server key share")
355355
}
356-
sharedKey, err := hs.ecdheKey.Curve().ECDH(hs.ecdheKey, peerKey)
356+
sharedKey, err := hs.ecdheKey.ECDH(peerKey)
357357
if err != nil {
358358
c.sendAlert(alertIllegalParameter)
359359
return errors.New("tls: invalid server key share")

src/crypto/tls/handshake_server_tls13.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ GroupSelection:
220220
c.sendAlert(alertIllegalParameter)
221221
return errors.New("tls: invalid client key share")
222222
}
223-
hs.sharedKey, err = key.Curve().ECDH(key, peerKey)
223+
hs.sharedKey, err = key.ECDH(peerKey)
224224
if err != nil {
225225
c.sendAlert(alertIllegalParameter)
226226
return errors.New("tls: invalid client key share")

src/crypto/tls/key_agreement.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Cert
264264
if err != nil {
265265
return nil, errClientKeyExchange
266266
}
267-
preMasterSecret, err := ka.key.Curve().ECDH(ka.key, peerKey)
267+
preMasterSecret, err := ka.key.ECDH(peerKey)
268268
if err != nil {
269269
return nil, errClientKeyExchange
270270
}
@@ -307,7 +307,7 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
307307
if err != nil {
308308
return errServerKeyExchange
309309
}
310-
ka.preMasterSecret, err = key.Curve().ECDH(key, peerKey)
310+
ka.preMasterSecret, err = key.ECDH(peerKey)
311311
if err != nil {
312312
return errServerKeyExchange
313313
}

0 commit comments

Comments
 (0)