mirror of https://github.com/bjdgyc/anylink.git
100 lines
2.3 KiB
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
|
|
}
|