/
public_key.go
80 lines (67 loc) · 1.87 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
package wif
import (
"bytes"
"hash"
secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/steemit/steemutil/consts"
btcec "github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil/base58"
"golang.org/x/crypto/ripemd160"
"github.com/pkg/errors"
)
type PublicKey struct {
Raw *secp256k1.PublicKey
}
// Get a raw public key from []byte.
func (p *PublicKey) FromByte(raw []byte) (err error) {
pubKey, err := btcec.ParsePubKey(raw)
if err != nil {
return errors.Wrap(err, "failed to decode Public Key")
}
p.Raw = pubKey
return nil
}
// Get a raw public key from Public String (STM...).
func (p *PublicKey) FromStr(pubKey string) (err error) {
// check prefix
prefixLen := len(consts.ADDRESS_PREFIX)
prefix := pubKey[0:prefixLen]
if prefix != consts.ADDRESS_PREFIX {
return errors.New("public key has an error prefix")
}
// get pub key without prefix
pubKeyWithoutPrefix := pubKey[prefixLen:]
pubKeyByte := base58.Decode(pubKeyWithoutPrefix)
// check checksum
pubKeyOri := pubKeyByte[0 : len(pubKeyByte)-4]
checkSum := pubKeyByte[len(pubKeyByte)-4:]
calcCheckSum := calcHash(pubKeyOri, ripemd160.New())
if !bytes.Equal(checkSum, calcCheckSum[0:4]) {
return errors.New("public key checksum failed")
}
// save
err = p.FromByte(pubKeyOri)
return err
}
func (p *PublicKey) FromWif(wif string) (err error) {
tmp := &PrivateKey{}
err = tmp.FromWif(wif)
if err != nil {
return
}
err = p.FromStr(tmp.ToPubKeyStr())
return
}
func (p *PublicKey) ToStr() string {
checkSum := calcHash(p.Raw.SerializeCompressed(), ripemd160.New())
pubByte := append(p.Raw.SerializeCompressed(), checkSum[0:4]...)
pubStr := base58.Encode(pubByte)
return consts.ADDRESS_PREFIX + pubStr
}
func (p *PublicKey) ToByte() []byte {
return p.Raw.SerializeCompressed()
}
func calcHash(buf []byte, hasher hash.Hash) []byte {
_, _ = hasher.Write(buf)
return hasher.Sum(nil)
}