...
1
2 package ecc
3
4 import (
5 "crypto/subtle"
6 "io"
7
8 "github.com/ProtonMail/go-crypto/openpgp/errors"
9 x448lib "github.com/cloudflare/circl/dh/x448"
10 )
11
12 type x448 struct{}
13
14 func NewX448() *x448 {
15 return &x448{}
16 }
17
18 func (c *x448) GetCurveName() string {
19 return "x448"
20 }
21
22
23
24 func (c *x448) MarshalBytePoint(point []byte) []byte {
25 return append([]byte{0x40}, point...)
26 }
27
28
29
30 func (c *x448) UnmarshalBytePoint(point []byte) []byte {
31 if len(point) != x448lib.Size+1 {
32 return nil
33 }
34
35 return point[1:]
36 }
37
38
39
40 func (c *x448) MarshalByteSecret(d []byte) []byte {
41 return append([]byte{0x40}, d...)
42 }
43
44
45
46 func (c *x448) UnmarshalByteSecret(d []byte) []byte {
47 if len(d) != x448lib.Size+1 {
48 return nil
49 }
50
51
52 return d[1:]
53 }
54
55 func (c *x448) generateKeyPairBytes(rand io.Reader) (sk, pk x448lib.Key, err error) {
56 if _, err = rand.Read(sk[:]); err != nil {
57 return
58 }
59
60 x448lib.KeyGen(&pk, &sk)
61 return
62 }
63
64 func (c *x448) GenerateECDH(rand io.Reader) (point []byte, secret []byte, err error) {
65 priv, pub, err := c.generateKeyPairBytes(rand)
66 if err != nil {
67 return
68 }
69
70 return pub[:], priv[:], nil
71 }
72
73 func (c *x448) Encaps(rand io.Reader, point []byte) (ephemeral, sharedSecret []byte, err error) {
74 var pk, ss x448lib.Key
75 seed, e, err := c.generateKeyPairBytes(rand)
76 if err != nil {
77 return nil, nil, err
78 }
79 copy(pk[:], point)
80 x448lib.Shared(&ss, &seed, &pk)
81
82 return e[:], ss[:], nil
83 }
84
85 func (c *x448) Decaps(ephemeral, secret []byte) (sharedSecret []byte, err error) {
86 var ss, sk, e x448lib.Key
87
88 copy(sk[:], secret)
89 copy(e[:], ephemeral)
90 x448lib.Shared(&ss, &sk, &e)
91
92 return ss[:], nil
93 }
94
95 func (c *x448) ValidateECDH(point []byte, secret []byte) error {
96 var sk, pk, expectedPk x448lib.Key
97
98 copy(pk[:], point)
99 copy(sk[:], secret)
100 x448lib.KeyGen(&expectedPk, &sk)
101
102 if subtle.ConstantTimeCompare(expectedPk[:], pk[:]) == 0 {
103 return errors.KeyInvalidError("ecc: invalid curve25519 public point")
104 }
105
106 return nil
107 }
108
View as plain text