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