...
1
2
3 package eddsa
4
5 import (
6 "errors"
7 "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
8 "io"
9 )
10
11 type PublicKey struct {
12 X []byte
13 curve ecc.EdDSACurve
14 }
15
16 type PrivateKey struct {
17 PublicKey
18 D []byte
19 }
20
21 func NewPublicKey(curve ecc.EdDSACurve) *PublicKey {
22 return &PublicKey{
23 curve: curve,
24 }
25 }
26
27 func NewPrivateKey(key PublicKey) *PrivateKey {
28 return &PrivateKey{
29 PublicKey: key,
30 }
31 }
32
33 func (pk *PublicKey) GetCurve() ecc.EdDSACurve {
34 return pk.curve
35 }
36
37 func (pk *PublicKey) MarshalPoint() []byte {
38 return pk.curve.MarshalBytePoint(pk.X)
39 }
40
41 func (pk *PublicKey) UnmarshalPoint(x []byte) error {
42 pk.X = pk.curve.UnmarshalBytePoint(x)
43
44 if pk.X == nil {
45 return errors.New("eddsa: failed to parse EC point")
46 }
47 return nil
48 }
49
50 func (sk *PrivateKey) MarshalByteSecret() []byte {
51 return sk.curve.MarshalByteSecret(sk.D)
52 }
53
54 func (sk *PrivateKey) UnmarshalByteSecret(d []byte) error {
55 sk.D = sk.curve.UnmarshalByteSecret(d)
56
57 if sk.D == nil {
58 return errors.New("eddsa: failed to parse scalar")
59 }
60 return nil
61 }
62
63 func GenerateKey(rand io.Reader, c ecc.EdDSACurve) (priv *PrivateKey, err error) {
64 priv = new(PrivateKey)
65 priv.PublicKey.curve = c
66 priv.PublicKey.X, priv.D, err = c.GenerateEdDSA(rand)
67 return
68 }
69
70 func Sign(priv *PrivateKey, message []byte) (r, s []byte, err error) {
71 sig, err := priv.PublicKey.curve.Sign(priv.PublicKey.X, priv.D, message)
72 if err != nil {
73 return nil, nil, err
74 }
75
76 r, s = priv.PublicKey.curve.MarshalSignature(sig)
77 return
78 }
79
80 func Verify(pub *PublicKey, message, r, s []byte) bool {
81 sig := pub.curve.UnmarshalSignature(r, s)
82 if sig == nil {
83 return false
84 }
85
86 return pub.curve.Verify(pub.X, message, sig)
87 }
88
89 func Validate(priv *PrivateKey) error {
90 return priv.curve.ValidateEdDSA(priv.PublicKey.X, priv.D)
91 }
92
View as plain text