main
Raw Download raw file
 1// Package ecdsa implements ECDSA signature, suitable for OpenPGP,
 2// as specified in RFC 6637, section 5.
 3package ecdsa
 4
 5import (
 6	"errors"
 7	"github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
 8	"io"
 9	"math/big"
10)
11
12type PublicKey struct {
13	X, Y  *big.Int
14	curve ecc.ECDSACurve
15}
16
17type PrivateKey struct {
18	PublicKey
19	D *big.Int
20}
21
22func NewPublicKey(curve ecc.ECDSACurve) *PublicKey {
23	return &PublicKey{
24		curve: curve,
25	}
26}
27
28func NewPrivateKey(key PublicKey) *PrivateKey {
29	return &PrivateKey{
30		PublicKey: key,
31	}
32}
33
34func (pk *PublicKey) GetCurve() ecc.ECDSACurve {
35	return pk.curve
36}
37
38func (pk *PublicKey) MarshalPoint() []byte {
39	return pk.curve.MarshalIntegerPoint(pk.X, pk.Y)
40}
41
42func (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
50func (sk *PrivateKey) MarshalIntegerSecret() []byte {
51	return sk.curve.MarshalIntegerSecret(sk.D)
52}
53
54func (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
63func 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
70func 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
74func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
75	return pub.curve.Verify(pub.X, pub.Y, hash, r, s)
76}
77
78func Validate(priv *PrivateKey) error {
79	return priv.curve.ValidateECDSA(priv.X, priv.Y, priv.D.Bytes())
80}