...
1
2 package ecc
3
4 import (
5 "crypto/subtle"
6 "io"
7
8 "github.com/ProtonMail/go-crypto/openpgp/errors"
9 ed448lib "github.com/cloudflare/circl/sign/ed448"
10 )
11
12 type ed448 struct{}
13
14 func NewEd448() *ed448 {
15 return &ed448{}
16 }
17
18 func (c *ed448) GetCurveName() string {
19 return "ed448"
20 }
21
22
23
24 func (c *ed448) MarshalBytePoint(x []byte) []byte {
25
26 return append([]byte{0x40}, x...)
27 }
28
29
30
31 func (c *ed448) UnmarshalBytePoint(point []byte) (x []byte) {
32 if len(point) != ed448lib.PublicKeySize+1 {
33 return nil
34 }
35
36
37 return point[1:]
38 }
39
40
41
42 func (c *ed448) MarshalByteSecret(d []byte) []byte {
43
44 return append([]byte{0x40}, d...)
45 }
46
47
48
49 func (c *ed448) UnmarshalByteSecret(s []byte) (d []byte) {
50
51 if len(s) != ed448lib.SeedSize+1 {
52 return nil
53 }
54
55
56 return s[1:]
57 }
58
59
60
61
62 func (c *ed448) MarshalSignature(sig []byte) (r, s []byte) {
63 return append([]byte{0x40}, sig...), []byte{}
64 }
65
66
67
68 func (c *ed448) UnmarshalSignature(r, s []byte) (sig []byte) {
69 if len(r) != ed448lib.SignatureSize+1 {
70 return nil
71 }
72
73 return r[1:]
74 }
75
76 func (c *ed448) GenerateEdDSA(rand io.Reader) (pub, priv []byte, err error) {
77 pk, sk, err := ed448lib.GenerateKey(rand)
78
79 if err != nil {
80 return nil, nil, err
81 }
82
83 return pk, sk[:ed448lib.SeedSize], nil
84 }
85
86 func getEd448Sk(publicKey, privateKey []byte) ed448lib.PrivateKey {
87 return append(privateKey, publicKey...)
88 }
89
90 func (c *ed448) Sign(publicKey, privateKey, message []byte) (sig []byte, err error) {
91
92
93 sig = ed448lib.Sign(getEd448Sk(publicKey, privateKey), message, "")
94
95 return sig, nil
96 }
97
98 func (c *ed448) Verify(publicKey, message, sig []byte) bool {
99
100
101 return ed448lib.Verify(publicKey, message, sig, "")
102 }
103
104 func (c *ed448) ValidateEdDSA(publicKey, privateKey []byte) (err error) {
105 priv := getEd448Sk(publicKey, privateKey)
106 expectedPriv := ed448lib.NewKeyFromSeed(priv.Seed())
107 if subtle.ConstantTimeCompare(priv, expectedPriv) == 0 {
108 return errors.KeyInvalidError("ecc: invalid ed448 secret")
109 }
110 return nil
111 }
112
View as plain text