summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/dtls/v2/pkg/crypto/elliptic/elliptic.go
blob: 5b0e4fa14ea5565a07956b985ae43aafb21faef9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// 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
}