...
1
2
3 package ecdsa
4
5 import (
6 "errors"
7 "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
8 "io"
9 "math/big"
10 )
11
12 type PublicKey struct {
13 X, Y *big.Int
14 curve ecc.ECDSACurve
15 }
16
17 type PrivateKey struct {
18 PublicKey
19 D *big.Int
20 }
21
22 func NewPublicKey(curve ecc.ECDSACurve) *PublicKey {
23 return &PublicKey{
24 curve: curve,
25 }
26 }
27
28 func NewPrivateKey(key PublicKey) *PrivateKey {
29 return &PrivateKey{
30 PublicKey: key,
31 }
32 }
33
34 func (pk *PublicKey) GetCurve() ecc.ECDSACurve {
35 return pk.curve
36 }
37
38 func (pk *PublicKey) MarshalPoint() []byte {
39 return pk.curve.MarshalIntegerPoint(pk.X, pk.Y)
40 }
41
42 func (pk *PublicKey) UnmarshalPoint(p []byte) error {
43 pk.X, pk.Y = pk.curve.UnmarshalIntegerPoint(p)
44 if pk.X == nil {
45 return errors.New("ecdsa: failed to parse EC point")
46 }
47 return nil
48 }
49
50 func (sk *PrivateKey) MarshalIntegerSecret() []byte {
51 return sk.curve.MarshalIntegerSecret(sk.D)
52 }
53
54 func (sk *PrivateKey) UnmarshalIntegerSecret(d []byte) error {
55 sk.D = sk.curve.UnmarshalIntegerSecret(d)
56
57 if sk.D == nil {
58 return errors.New("ecdsa: failed to parse scalar")
59 }
60 return nil
61 }
62
63 func GenerateKey(rand io.Reader, c ecc.ECDSACurve) (priv *PrivateKey, err error) {
64 priv = new(PrivateKey)
65 priv.PublicKey.curve = c
66 priv.PublicKey.X, priv.PublicKey.Y, priv.D, err = c.GenerateECDSA(rand)
67 return
68 }
69
70 func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
71 return priv.PublicKey.curve.Sign(rand, priv.X, priv.Y, priv.D, hash)
72 }
73
74 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
75 return pub.curve.Verify(pub.X, pub.Y, hash, r, s)
76 }
77
78 func Validate(priv *PrivateKey) error {
79 return priv.curve.ValidateECDSA(priv.X, priv.Y, priv.D.Bytes())
80 }
81
View as plain text