/
keys.go
194 lines (158 loc) · 5.13 KB
/
keys.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package crypto
import (
"encoding/hex"
"errors"
"fmt"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcutil/base58"
"github.com/libonomy/wallet-cli/os/log"
)
// Key defines basic key caps.
type Key interface {
String() string // this is a base58 encoded of Bytes()
Bytes() []byte // raw key binary data
Pretty() string // pretty print key id
}
// PrivateKey defines a private encryption key.
type PrivateKey interface {
Key
GetPublicKey() PublicKey // get the pub key corresponding to this priv key
Sign([]byte) ([]byte, error)
// Decrypt binary data encrypted with the public key of this private key
Decrypt(in []byte) ([]byte, error)
InternalKey() *btcec.PrivateKey
}
// PublicKey defines a public encryption key.
type PublicKey interface { // 33 bytes
Key
Verify(data []byte, sig []byte) (bool, error)
VerifyString(data []byte, sig string) (bool, error)
// encrypt data so it is only decryptable w the private key of this key
Encrypt(in []byte) ([]byte, error)
InternalKey() *btcec.PublicKey
}
type publicKeyImpl struct {
k *btcec.PublicKey
}
type privateKeyImpl struct {
k *btcec.PrivateKey
}
// GenerateKeyPair generates a private and public key pair.
func GenerateKeyPair() (PrivateKey, PublicKey, error) {
privKey, err := btcec.NewPrivateKey(btcec.S256())
if err != nil {
return nil, nil, err
}
return &privateKeyImpl{privKey}, &publicKeyImpl{privKey.PubKey()}, nil
}
// NewPrivateKey creates a new private key from data
func NewPrivateKey(data []byte) (PrivateKey, error) {
if len(data) != 32 {
return nil, errors.New("expected 32 bytes input")
}
privk, _ := btcec.PrivKeyFromBytes(btcec.S256(), data)
return &privateKeyImpl{privk}, nil
}
// NewPrivateKeyFromString creates a new private key a base58 encoded string.
func NewPrivateKeyFromString(s string) (PrivateKey, error) {
data := base58.Decode(s)
return NewPrivateKey(data)
}
// InternalKey gets the internal key associated with a private key
func (p *privateKeyImpl) InternalKey() *btcec.PrivateKey {
return p.k
}
// Bytes returns the private key binary data
func (p *privateKeyImpl) Bytes() []byte {
return p.k.Serialize()
}
// String returns a base58 encoded string of the private key binary data
func (p *privateKeyImpl) String() string {
bytes := p.Bytes()
return base58.Encode(bytes)
}
// GetPublicKey generates and returns the public key associated with a private key
func (p *privateKeyImpl) GetPublicKey() PublicKey {
pubKey := p.k.PubKey()
return &publicKeyImpl{k: pubKey}
}
// Pretty returns a readable string of the private key data.
func (p *privateKeyImpl) Pretty() string {
pstr := p.String()
maxRunes := 6
if len(pstr) < maxRunes {
maxRunes = len(pstr)
}
return fmt.Sprintf("<PrivKey %s>", pstr[:maxRunes])
}
// Sign signs binary data with the private key.
func (p *privateKeyImpl) Sign(in []byte) ([]byte, error) {
signature, err := p.k.Sign(in)
if err != nil {
return nil, err
}
return signature.Serialize(), nil
}
// Decrypt decrypts data encrypted with a public key using its matching private key
func (p *privateKeyImpl) Decrypt(in []byte) ([]byte, error) {
return btcec.Decrypt(p.k, in)
}
// NewPublicKey creates a new public key from provided binary key data.
func NewPublicKey(data []byte) (PublicKey, error) {
k, err := btcec.ParsePubKey(data, btcec.S256())
if err != nil {
log.Error("Failed to parse public key from binay data", err)
return nil, err
}
return &publicKeyImpl{k}, nil
}
// NewPublicKeyFromString creates a new public key from a base58 encoded string data.
func NewPublicKeyFromString(s string) (PublicKey, error) {
data := base58.Decode(s)
return NewPublicKey(data)
}
// InternalKey returns the internal public key data.
func (p *publicKeyImpl) InternalKey() *btcec.PublicKey {
return p.k
}
// Bytes returns the raw public key data (33 bytes compressed format).
func (p *publicKeyImpl) Bytes() []byte {
return p.k.SerializeCompressed()
}
// String returns a base58 encoded string of the key binary data.
func (p *publicKeyImpl) String() string {
return base58.Encode(p.Bytes())
}
// Pretty returns a readable short string of the public key.
func (p *publicKeyImpl) Pretty() string {
pstr := p.String()
maxRunes := 6
if len(pstr) < maxRunes {
maxRunes = len(pstr)
}
return fmt.Sprintf("<PUBK %s>", pstr[:maxRunes])
}
// VerifyString verifies data signed with the private key matching this public key.
// sig: hex encoded binary data string
func (p *publicKeyImpl) VerifyString(data []byte, sig string) (bool, error) {
bin, err := hex.DecodeString(sig)
if err != nil {
return false, err
}
return p.Verify(data, bin)
}
// Verify verifies data was signed by provided signature.
// It returns true iff data was signed using the private key matching this public key.
/// sig: signature binary data
func (p *publicKeyImpl) Verify(data []byte, sig []byte) (bool, error) {
signature, err := btcec.ParseSignature(sig, btcec.S256())
if err != nil {
return false, err
}
verified := signature.Verify(data, p.k)
return verified, nil
}
// Encrypt encrypts data that can only be decrypted using the private key matching this public key.
func (p *publicKeyImpl) Encrypt(in []byte) ([]byte, error) {
return btcec.Encrypt(p.k, in)
}