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
)
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)
// 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
}
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
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)
}
if err != nil {
t.Fatal(err)
}
- secret, err := curve.ECDH(key, peer)
+ secret, err := key.ECDH(peer)
if err != nil {
t.Fatal(err)
}
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")
}
if err != nil {
b.Fatal(err)
}
- secret, err := curve.ECDH(key, peerPubKey)
+ secret, err := key.ECDH(peerPubKey)
if err != nil {
b.Fatal(err)
}
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")
}
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
}, 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) {
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")
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")
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
}
if err != nil {
return errServerKeyExchange
}
- ka.preMasterSecret, err = key.Curve().ECDH(key, peerKey)
+ ka.preMasterSecret, err = key.ECDH(peerKey)
if err != nil {
return errServerKeyExchange
}