github.com/pion/dtls/v2@v2.2.12/pkg/crypto/elliptic/elliptic.go (about) 1 // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly> 2 // SPDX-License-Identifier: MIT 3 4 // Package elliptic provides elliptic curve cryptography for DTLS 5 package elliptic 6 7 import ( 8 "crypto/elliptic" 9 "crypto/rand" 10 "errors" 11 "fmt" 12 13 "golang.org/x/crypto/curve25519" 14 ) 15 16 var errInvalidNamedCurve = errors.New("invalid named curve") 17 18 // CurvePointFormat is used to represent the IANA registered curve points 19 // 20 // https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 21 type CurvePointFormat byte 22 23 // CurvePointFormat enums 24 const ( 25 CurvePointFormatUncompressed CurvePointFormat = 0 26 ) 27 28 // Keypair is a Curve with a Private/Public Keypair 29 type Keypair struct { 30 Curve Curve 31 PublicKey []byte 32 PrivateKey []byte 33 } 34 35 // CurveType is used to represent the IANA registered curve types for TLS 36 // 37 // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-10 38 type CurveType byte 39 40 // CurveType enums 41 const ( 42 CurveTypeNamedCurve CurveType = 0x03 43 ) 44 45 // CurveTypes returns all known curves 46 func CurveTypes() map[CurveType]struct{} { 47 return map[CurveType]struct{}{ 48 CurveTypeNamedCurve: {}, 49 } 50 } 51 52 // Curve is used to represent the IANA registered curves for TLS 53 // 54 // https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 55 type Curve uint16 56 57 // Curve enums 58 const ( 59 P256 Curve = 0x0017 60 P384 Curve = 0x0018 61 X25519 Curve = 0x001d 62 ) 63 64 func (c Curve) String() string { 65 switch c { 66 case P256: 67 return "P-256" 68 case P384: 69 return "P-384" 70 case X25519: 71 return "X25519" 72 } 73 return fmt.Sprintf("%#x", uint16(c)) 74 } 75 76 // Curves returns all curves we implement 77 func Curves() map[Curve]bool { 78 return map[Curve]bool{ 79 X25519: true, 80 P256: true, 81 P384: true, 82 } 83 } 84 85 // GenerateKeypair generates a keypair for the given Curve 86 func GenerateKeypair(c Curve) (*Keypair, error) { 87 switch c { //nolint:revive 88 case X25519: 89 tmp := make([]byte, 32) 90 if _, err := rand.Read(tmp); err != nil { 91 return nil, err 92 } 93 94 var public, private [32]byte 95 copy(private[:], tmp) 96 97 curve25519.ScalarBaseMult(&public, &private) 98 return &Keypair{X25519, public[:], private[:]}, nil 99 case P256: 100 return ellipticCurveKeypair(P256, elliptic.P256(), elliptic.P256()) 101 case P384: 102 return ellipticCurveKeypair(P384, elliptic.P384(), elliptic.P384()) 103 default: 104 return nil, errInvalidNamedCurve 105 } 106 } 107 108 func ellipticCurveKeypair(nc Curve, c1, c2 elliptic.Curve) (*Keypair, error) { 109 privateKey, x, y, err := elliptic.GenerateKey(c1, rand.Reader) 110 if err != nil { 111 return nil, err 112 } 113 114 return &Keypair{nc, elliptic.Marshal(c2, x, y), privateKey}, nil 115 }