/
wif.go
75 lines (62 loc) · 1.68 KB
/
wif.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
// LICENSE: GNU General Public License version 2
// CONTRIBUTORS AND COPYRIGHT HOLDERS (c) 2013:
// Dag Robøle (dag.robole AT gmail DOT com)
package enc
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/sha256"
"errors"
"math/big"
)
func EncodeWif(keys *ecdsa.PrivateKey) (string, error) {
var extended bytes.Buffer
extended.WriteByte(byte(0x80))
extended.Write(keys.D.Bytes())
sha1, sha2 := sha256.New(), sha256.New()
sha1.Write(extended.Bytes())
sha2.Write(sha1.Sum(nil))
checksum := sha2.Sum(nil)[:4]
extended.Write(checksum)
encoded, err := EncodeBase58(extended.Bytes())
if err != nil {
return "", err
}
return encoded, nil
}
func DecodeWif(wif string) (*ecdsa.PrivateKey, error) {
if len(wif) < 6 {
return nil, errors.New("wif.Decode: wif is too short")
}
extended, err := DecodeBase58(wif)
if err != nil {
return nil, err
}
decoded := extended[1 : len(extended)-4]
keys := new(ecdsa.PrivateKey)
keys.D = new(big.Int).SetBytes(decoded)
keys.PublicKey.Curve = elliptic.P384()
for keys.PublicKey.X == nil {
keys.PublicKey.X, keys.PublicKey.Y = keys.PublicKey.Curve.ScalarBaseMult(decoded)
}
if !keys.Curve.IsOnCurve(keys.PublicKey.X, keys.PublicKey.Y) {
return nil, errors.New("wif.Decode: Point is not on curve")
}
return keys, nil
}
func ValidateWif(wif string) (bool, error) {
if len(wif) < 6 {
return false, errors.New("wif.Validate: wif is too short")
}
extended, err := DecodeBase58(wif)
if err != nil {
return false, err
}
cs1 := extended[len(extended)-4:]
sha1, sha2 := sha256.New(), sha256.New()
sha1.Write(extended[:len(extended)-4])
sha2.Write(sha1.Sum(nil))
cs2 := sha2.Sum(nil)[:4]
return bytes.Compare(cs1, cs2) == 0, nil
}