/
ecdsa.go
73 lines (63 loc) · 1.46 KB
/
ecdsa.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package ndn
import (
"crypto/ecdsa"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"math/big"
"github.com/NDNLink/tlv"
)
// ECDSAKey implements Key.
type ECDSAKey struct {
Name
*ecdsa.PrivateKey
}
// Locator returns public key locator.
func (key *ECDSAKey) Locator() Name {
return key.Name
}
// Private encodes private key.
func (key *ECDSAKey) Private() ([]byte, error) {
return x509.MarshalECPrivateKey(key.PrivateKey)
}
// Public encodes public key.
func (key *ECDSAKey) Public() ([]byte, error) {
return x509.MarshalPKIXPublicKey(key.PrivateKey.Public())
}
// SignatureType returns signature type generated from the key.
func (key *ECDSAKey) SignatureType() uint64 {
return SignatureTypeSHA256WithECDSA
}
type ecdsaSignature struct {
R, S *big.Int
}
// Sign creates signature.
func (key *ECDSAKey) Sign(v interface{}) ([]byte, error) {
digest, err := tlv.Hash(sha256.New, v)
if err != nil {
return nil, err
}
var sig ecdsaSignature
sig.R, sig.S, err = ecdsa.Sign(rand.Reader, key.PrivateKey, digest)
if err != nil {
return nil, err
}
return asn1.Marshal(sig)
}
// Verify checks signature.
func (key *ECDSAKey) Verify(v interface{}, signature []byte) error {
digest, err := tlv.Hash(sha256.New, v)
if err != nil {
return err
}
var sig ecdsaSignature
_, err = asn1.Unmarshal(signature, &sig)
if err != nil {
return err
}
if !ecdsa.Verify(&key.PrivateKey.PublicKey, digest, sig.R, sig.S) {
return ErrInvalidSignature
}
return nil
}