forked from iotexproject/iotex-core
/
keypair.go
112 lines (99 loc) · 3.18 KB
/
keypair.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
// Copyright (c) 2018 IoTeX
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache
// License 2.0 that can be found in the LICENSE file.
package keypair
import (
"crypto/ecdsa"
"encoding/hex"
"io/ioutil"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/pkg/errors"
)
const (
secp256pubKeyLength = 65
secp256prvKeyLength = 32
)
var (
// ErrInvalidKey is the error that the key format is invalid
ErrInvalidKey = errors.New("invalid key format")
// ErrPublicKey indicates the error of public key
ErrPublicKey = errors.New("invalid public key")
// ErrPrivateKey indicates the error of private key
ErrPrivateKey = errors.New("invalid private key")
)
type (
// PublicKey represents a public key
PublicKey interface {
Bytes() []byte
HexString() string
EcdsaPublicKey() *ecdsa.PublicKey
Hash() []byte
Verify([]byte, []byte) bool
}
// PrivateKey represents a private key
PrivateKey interface {
Bytes() []byte
HexString() string
EcdsaPrivateKey() *ecdsa.PrivateKey
PublicKey() PublicKey
Sign([]byte) ([]byte, error)
Zero()
}
)
// GenerateKey generates a SECP256K1 PrivateKey
func GenerateKey() (PrivateKey, error) {
return newSecp256k1PrvKey()
}
// HexStringToPublicKey decodes a string to SECP256K1 PublicKey
func HexStringToPublicKey(pubKey string) (PublicKey, error) {
b, err := hex.DecodeString(pubKey)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode public key %s", pubKey)
}
return BytesToPublicKey(b)
}
// HexStringToPrivateKey decodes a string to SECP256K1 PrivateKey
func HexStringToPrivateKey(prvKey string) (PrivateKey, error) {
b, err := hex.DecodeString(prvKey)
if err != nil {
return nil, errors.Wrapf(err, "failed to decode public key %s", prvKey)
}
return BytesToPrivateKey(b)
}
// BytesToPublicKey converts a byte slice to SECP256K1 PublicKey
func BytesToPublicKey(pubKey []byte) (PublicKey, error) {
return newSecp256k1PubKeyFromBytes(pubKey)
}
// BytesToPrivateKey converts a byte slice to SECP256K1 PrivateKey
func BytesToPrivateKey(prvKey []byte) (PrivateKey, error) {
return newSecp256k1PrvKeyFromBytes(prvKey)
}
// KeystoreToPrivateKey generates PrivateKey from Keystore account
func KeystoreToPrivateKey(account accounts.Account, password string) (PrivateKey, error) {
// load the key from the keystore
keyJSON, err := ioutil.ReadFile(account.URL.Path)
if err != nil {
return nil, err
}
key, err := keystore.DecryptKey(keyJSON, password)
if err != nil {
return nil, err
}
return &secp256k1PrvKey{
PrivateKey: key.PrivateKey,
}, nil
}
// StringToPubKeyBytes converts a string of public key to byte slice
func StringToPubKeyBytes(pubKey string) ([]byte, error) {
pubKeyBytes, err := hex.DecodeString(pubKey)
if err != nil {
return nil, err
}
if len(pubKeyBytes) != secp256pubKeyLength {
return nil, errors.Wrap(ErrPublicKey, "Invalid public key length")
}
return pubKeyBytes, nil
}