package ecdh
import (
)
type nistCurve struct {
name string
generate func(io.Reader) (*ecdh.PrivateKey, error)
newPrivateKey func([]byte) (*ecdh.PrivateKey, error)
newPublicKey func(publicKey []byte) (*ecdh.PublicKey, error)
sharedSecret func(*ecdh.PrivateKey, *ecdh.PublicKey) (sharedSecret []byte, err error)
}
func ( *nistCurve) () string {
return .name
}
func ( *nistCurve) ( io.Reader) (*PrivateKey, error) {
if boring.Enabled && == boring.RandReader {
, , := boring.GenerateKeyECDH(.name)
if != nil {
return nil,
}
, := .PublicKey()
if != nil {
return nil,
}
:= &PrivateKey{
curve: ,
privateKey: ,
publicKey: &PublicKey{curve: , publicKey: .Bytes(), boring: },
boring: ,
}
return , nil
}
if fips140only.Enabled && !fips140only.ApprovedRandomReader() {
return nil, errors.New("crypto/ecdh: only crypto/rand.Reader is allowed in FIPS 140-only mode")
}
, := .generate()
if != nil {
return nil,
}
:= &PrivateKey{
curve: ,
privateKey: .Bytes(),
fips: ,
publicKey: &PublicKey{
curve: ,
publicKey: .PublicKey().Bytes(),
fips: .PublicKey(),
},
}
if boring.Enabled {
, := boring.NewPrivateKeyECDH(.name, .privateKey)
if != nil {
return nil,
}
, := .PublicKey()
if != nil {
return nil,
}
.boring =
.publicKey.boring =
}
return , nil
}
func ( *nistCurve) ( []byte) (*PrivateKey, error) {
if boring.Enabled {
, := boring.NewPrivateKeyECDH(.name, )
if != nil {
return nil, errors.New("crypto/ecdh: invalid private key")
}
, := .PublicKey()
if != nil {
return nil, errors.New("crypto/ecdh: invalid private key")
}
:= &PrivateKey{
curve: ,
privateKey: bytes.Clone(),
publicKey: &PublicKey{curve: , publicKey: .Bytes(), boring: },
boring: ,
}
return , nil
}
, := .newPrivateKey()
if != nil {
return nil,
}
:= &PrivateKey{
curve: ,
privateKey: bytes.Clone(),
fips: ,
publicKey: &PublicKey{
curve: ,
publicKey: .PublicKey().Bytes(),
fips: .PublicKey(),
},
}
return , nil
}
func ( *nistCurve) ( []byte) (*PublicKey, error) {
if len() == 0 || [0] != 4 {
return nil, errors.New("crypto/ecdh: invalid public key")
}
:= &PublicKey{
curve: ,
publicKey: bytes.Clone(),
}
if boring.Enabled {
, := boring.NewPublicKeyECDH(.name, .publicKey)
if != nil {
return nil, errors.New("crypto/ecdh: invalid public key")
}
.boring =
} else {
, := .newPublicKey()
if != nil {
return nil,
}
.fips =
}
return , nil
}
func ( *nistCurve) ( *PrivateKey, *PublicKey) ([]byte, error) {
if boring.Enabled {
return boring.ECDH(.boring, .boring)
}
return .sharedSecret(.fips, .fips)
}
func () Curve { return p256 }
var p256 = &nistCurve{
name: "P-256",
generate: func( io.Reader) (*ecdh.PrivateKey, error) {
return ecdh.GenerateKey(ecdh.P256(), )
},
newPrivateKey: func( []byte) (*ecdh.PrivateKey, error) {
return ecdh.NewPrivateKey(ecdh.P256(), )
},
newPublicKey: func( []byte) (*ecdh.PublicKey, error) {
return ecdh.NewPublicKey(ecdh.P256(), )
},
sharedSecret: func( *ecdh.PrivateKey, *ecdh.PublicKey) ( []byte, error) {
return ecdh.ECDH(ecdh.P256(), , )
},
}
func () Curve { return p384 }
var p384 = &nistCurve{
name: "P-384",
generate: func( io.Reader) (*ecdh.PrivateKey, error) {
return ecdh.GenerateKey(ecdh.P384(), )
},
newPrivateKey: func( []byte) (*ecdh.PrivateKey, error) {
return ecdh.NewPrivateKey(ecdh.P384(), )
},
newPublicKey: func( []byte) (*ecdh.PublicKey, error) {
return ecdh.NewPublicKey(ecdh.P384(), )
},
sharedSecret: func( *ecdh.PrivateKey, *ecdh.PublicKey) ( []byte, error) {
return ecdh.ECDH(ecdh.P384(), , )
},
}
func () Curve { return p521 }
var p521 = &nistCurve{
name: "P-521",
generate: func( io.Reader) (*ecdh.PrivateKey, error) {
return ecdh.GenerateKey(ecdh.P521(), )
},
newPrivateKey: func( []byte) (*ecdh.PrivateKey, error) {
return ecdh.NewPrivateKey(ecdh.P521(), )
},
newPublicKey: func( []byte) (*ecdh.PublicKey, error) {
return ecdh.NewPublicKey(ecdh.P521(), )
},
sharedSecret: func( *ecdh.PrivateKey, *ecdh.PublicKey) ( []byte, error) {
return ecdh.ECDH(ecdh.P521(), , )
},
}