dockerfiles/anylink/dtls-2.0.9/pkg/crypto/elliptic/elliptic.go

100 lines
2.3 KiB
Go

// Package elliptic provides elliptic curve cryptography for DTLS
package elliptic
import (
"crypto/elliptic"
"crypto/rand"
"errors"
"golang.org/x/crypto/curve25519"
)
var errInvalidNamedCurve = errors.New("invalid named curve")
// CurvePointFormat is used to represent the IANA registered curve points
//
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
type CurvePointFormat byte
// CurvePointFormat enums
const (
CurvePointFormatUncompressed CurvePointFormat = 0
)
// Keypair is a Curve with a Private/Public Keypair
type Keypair struct {
Curve Curve
PublicKey []byte
PrivateKey []byte
}
// CurveType is used to represent the IANA registered curve types for TLS
//
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-10
type CurveType byte
// CurveType enums
const (
CurveTypeNamedCurve CurveType = 0x03
)
// CurveTypes returns all known curves
func CurveTypes() map[CurveType]struct{} {
return map[CurveType]struct{}{
CurveTypeNamedCurve: {},
}
}
// Curve is used to represent the IANA registered curves for TLS
//
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
type Curve uint16
// Curve enums
const (
P256 Curve = 0x0017
P384 Curve = 0x0018
X25519 Curve = 0x001d
)
// Curves returns all curves we implement
func Curves() map[Curve]bool {
return map[Curve]bool{
X25519: true,
P256: true,
P384: true,
}
}
// GenerateKeypair generates a keypair for the given Curve
func GenerateKeypair(c Curve) (*Keypair, error) {
switch c { //nolint:golint
case X25519:
tmp := make([]byte, 32)
if _, err := rand.Read(tmp); err != nil {
return nil, err
}
var public, private [32]byte
copy(private[:], tmp)
curve25519.ScalarBaseMult(&public, &private)
return &Keypair{X25519, public[:], private[:]}, nil
case P256:
return ellipticCurveKeypair(P256, elliptic.P256(), elliptic.P256())
case P384:
return ellipticCurveKeypair(P384, elliptic.P384(), elliptic.P384())
default:
return nil, errInvalidNamedCurve
}
}
func ellipticCurveKeypair(nc Curve, c1, c2 elliptic.Curve) (*Keypair, error) {
privateKey, x, y, err := elliptic.GenerateKey(c1, rand.Reader)
if err != nil {
return nil, err
}
return &Keypair{nc, elliptic.Marshal(c2, x, y), privateKey}, nil
}