forked from casper-ecosystem/casper-golang-sdk
/
secp256k1.go
145 lines (117 loc) · 3.82 KB
/
secp256k1.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
package secp256k1
import (
"crypto/x509"
"encoding/hex"
"encoding/pem"
"fmt"
"github.com/Ammer-Tech/casper-golang-sdk/keypair"
"github.com/tendermint/tendermint/crypto/secp256k1"
"golang.org/x/crypto/blake2b"
)
type secp256k1KeyPair struct {
seed []byte
PublKey []byte
PrivateKey []byte
}
func Secp256k1Random() keypair.KeyPair {
priv := secp256k1.GenPrivKey()
pub := priv.PubKey().Bytes()
return &secp256k1KeyPair{PublKey: pub, PrivateKey: priv}
}
func (key *secp256k1KeyPair) RawSeed() []byte {
return key.seed
}
func (key *secp256k1KeyPair) KeyTag() keypair.KeyTag {
return keypair.KeyTagSecp256k1
}
// PublicKey returns Secp256k1 public key
func (key *secp256k1KeyPair) PublicKey() keypair.PublicKey {
pubKey, _ := key.keys()
return keypair.PublicKey{
Tag: key.KeyTag(),
PubKeyData: pubKey,
}
}
// Sign signs the message by using the keyPair
func (key *secp256k1KeyPair) Sign(mes []byte) keypair.Signature {
_, privKey := key.keys()
sign, _ := privKey.Sign(mes)
return keypair.Signature{
Tag: key.KeyTag(),
SignatureData: sign,
}
}
// Verify verifies the signature along with the raw message
func (key *secp256k1KeyPair) Verify(mes []byte, sign []byte) bool {
pubKey, _ := key.keys()
return pubKey.VerifySignature(mes, sign)
}
// AccountHash generates the accountHash for the Secp256K1 public key
func (key *secp256k1KeyPair) AccountHash() string {
pubKey, _ := key.keys()
var buffer = append([]byte(keypair.StrKeyTagSecp256k1), keypair.Separator)
buffer = append(buffer, pubKey...)
hash := blake2b.Sum256(buffer)
return fmt.Sprintf("account-hash-%s", hex.EncodeToString(hash[:]))
}
func (key *secp256k1KeyPair) keys() (secp256k1.PubKey, secp256k1.PrivKey) {
priv := secp256k1.GenPrivKey()
pub := priv.PubKey().Bytes()
return pub, priv
}
// AccountHex generates the accountHex for the Secp256K1 public key
func AccountHex(publicKey []byte) string {
dst := make([]byte, hex.EncodedLen(len(publicKey)))
hex.Encode(dst, publicKey)
return "02" + string(dst)
}
// ExportPublicKeyInPem exports the public key encoded in pem
func ExportPublicKeyInPem(publicKey []byte) []byte {
x509EncodedPub, _ := x509.MarshalPKIXPublicKey(publicKey)
pemEncodedPub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: x509EncodedPub})
return pemEncodedPub
}
// ExportPrivateKeyInPem expects the private key encoded in pem
func ExportPrivateKeyInPem(privateKey []byte) []byte {
x509Encoded, _ := x509.MarshalPKCS8PrivateKey(privateKey)
pemEncoded := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: x509Encoded})
return pemEncoded
}
func ParsePublicKey(pemEncodedPub string) []byte {
blockPub, _ := pem.Decode([]byte(pemEncodedPub))
x509EncodedPub := blockPub.Bytes
genericPublicKey, _ := x509.ParsePKIXPublicKey(x509EncodedPub)
publicKey := genericPublicKey.([]byte)
return publicKey
}
func ParsePrivateKey(pemEncoded string) []byte {
block, _ := pem.Decode([]byte(pemEncoded))
x509Encoded := block.Bytes
privateKey, _ := x509.ParseECPrivateKey(x509Encoded)
res, _ := x509.MarshalECPrivateKey(privateKey)
return res
}
// ParseKeyPair constructs keyPair from public key and private key
func ParseKeyPair(publicKey, privateKey string) keypair.KeyPair {
pub := ParsePublicKey(publicKey)
priv := ParsePrivateKey(privateKey)
keyPair := secp256k1KeyPair{PublKey: pub, PrivateKey: priv}
return &keyPair
}
func ParsePublicKeyFile(path string) []byte {
key, _ := keypair.ReadBase64File(path)
return ParsePublicKey(string(key))
}
func ParsePrivateKeyFile(path string) []byte {
key, _ := keypair.ReadBase64File(path)
return ParsePrivateKey(string(key))
}
func ParseKeyFiles(pubKeyPath, privKeyPath string) keypair.KeyPair {
pub := ParsePublicKeyFile(pubKeyPath)
priv := ParsePrivateKeyFile(privKeyPath)
keyPair := secp256k1KeyPair{
PublKey: pub,
PrivateKey: priv,
}
return &keyPair
}