/
public-key.go
240 lines (186 loc) · 5.21 KB
/
public-key.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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// Copyright © 2020-2022 The EVEN Solutions Developers Team
package crypto
import (
"encoding/base64"
"encoding/hex"
"github.com/evenlab/go-kit/equal"
"github.com/evenlab/go-kit/errors"
json "github.com/json-iterator/go"
"github.com/libp2p/go-libp2p/core/crypto"
"google.golang.org/protobuf/proto"
"github.com/evenlab/go-kit/crypto/proto/pb"
)
type (
// PublicKey represents public key interface.
PublicKey interface {
// Equaler embedded equaler interface.
equal.Equaler
// Algo returns the public key Algo.
Algo() Algo
// Base64 encodes a public key to base64 string.
Base64() (string, error)
// Decode sets decoded data from protobuf message.
Decode(*pb.PublicKey) error
// Encode converts data to protobuf message.
Encode() (*pb.PublicKey, error)
// Equals checks whether two public keys are the same.
Equals(PublicKey) bool
// Hash224 calculates SHA224 checksum
// over SHA256 checksum over public key value.
Hash224() (Hash224, error)
// Marshal implements marshaler interface for types
// that can marshal themselves into bytes.
Marshal() ([]byte, error)
// MarshalJSON implements marshaler interface for types
// that can marshal themselves into valid JSON.
MarshalJSON() ([]byte, error)
// String implements stringer interface for types
// that can converts themselves to string format.
String() string
// Unmarshal implements unmarshaler interface for types
// that can unmarshal bytes of themselves.
Unmarshal([]byte) error
// UnmarshalJSON implements unmarshaler interface for types
// that can unmarshal a JSON description of themselves.
UnmarshalJSON([]byte) error
// Verify verifies signable object.
Verify(Signable) (bool, error)
}
// publicKey implements PublicKey interface.
publicKey struct {
ki crypto.PubKey
}
)
var (
// Make sure publicKey implements PublicKey interface.
_ PublicKey = (*publicKey)(nil)
)
// NewPublicKey returns PublicKey interface.
func NewPublicKey(ki crypto.PubKey) PublicKey {
return &publicKey{ki: ki}
}
// DecodePublicKey decodes a protobuf encoded message.
func DecodePublicKey(pbuf *pb.PublicKey) (PublicKey, error) {
pbKey := publicKey{}
if err := pbKey.Decode(pbuf); err != nil {
return nil, err
}
return &pbKey, nil
}
// Algo implements PublicKey.Algo method of interface.
func (c *publicKey) Algo() Algo {
if c.ki == nil {
return UNKNOWN
}
return Algo(c.ki.Type())
}
// Base64 implements PublicKey.Base64 method of interface.
func (c *publicKey) Base64() (string, error) {
b, err := c.Raw()
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(b), nil
}
// Decode implements PublicKey.Decode method of interface.
func (c *publicKey) Decode(pbuf *pb.PublicKey) error {
ki, err := crypto.UnmarshalPublicKey(pbuf.Blob)
if err != nil {
return err
}
c.ki = ki
return nil
}
// Encode implements PublicKey.Encode method of interface.
func (c *publicKey) Encode() (*pb.PublicKey, error) {
if c.ki == nil {
return nil, ErrPublicKeyCannotBeNil()
}
blob, err := crypto.MarshalPublicKey(c.ki)
if err != nil {
return nil, err
}
pbuf := pb.PublicKey{Blob: blob}
return &pbuf, nil
}
// Equals implements PublicKey.Equals method of interface.
func (c *publicKey) Equals(pbKey PublicKey) bool {
return equal.BasicEqual(c, pbKey)
}
// Hash224 implements PublicKey.Hash224 method of interface.
func (c *publicKey) Hash224() (Hash224, error) {
b, err := c.Raw()
if err != nil {
return Hash224{}, err
}
return NewHash224(b), nil
}
// Marshal implements PublicKey.Marshal method of interface.
func (c *publicKey) Marshal() ([]byte, error) {
pbuf, err := c.Encode()
if err != nil {
return nil, err
}
return proto.Marshal(pbuf)
}
// MarshalJSON implements PublicKey.MarshalJSON method of interface.
func (c *publicKey) MarshalJSON() ([]byte, error) {
pbuf, err := c.Encode()
if err != nil {
return nil, err
}
return json.Marshal(pbuf)
}
// Raw implements method of equal.Equaler interface.
func (c *publicKey) Raw() ([]byte, error) {
if c.ki == nil {
return nil, errors.ErrNilPointerValue()
}
return c.ki.Raw()
}
// String implements PublicKey.String method of interface.
func (c *publicKey) String() string {
b, err := c.Raw()
if err != nil {
return "<nil>"
}
return hex.EncodeToString(b)
}
// Unmarshal implements PublicKey.Unmarshal method of interface.
func (c *publicKey) Unmarshal(b []byte) error {
pbuf := new(pb.PublicKey)
if err := proto.Unmarshal(b, pbuf); err != nil {
return err
}
return c.Decode(pbuf)
}
// UnmarshalJSON implements PublicKey.UnmarshalJSON method of interface.
func (c *publicKey) UnmarshalJSON(data []byte) error {
pbuf := pb.PublicKey{}
if err := json.Unmarshal(data, &pbuf); err != nil {
return err
}
return c.Decode(&pbuf)
}
// Verify implements PublicKey.Verify method of interface.
func (c *publicKey) Verify(signable Signable) (bool, error) {
if c.ki == nil {
return false, ErrPublicKeyCannotBeNil()
}
if signable == nil {
return false, ErrSignableCannotBeNil()
}
sign := signable.GetSignature()
if sign == nil {
return false, ErrSignatureCannotBeNil()
}
blob, err := sign.Raw()
if err != nil {
return false, err
}
hash, err := signable.Hash()
if err != nil {
return false, err
}
return c.ki.Verify(hash[:], blob)
}