Add two new functions: EncodePrivateKey and DecodePrivateKey

EncodePrivateKey encodes a raw private key into Wallet Import Format.
DecodePrivateKey decodes the WIF string to a raw private key.
This commit is contained in:
David Hill 2013-10-31 23:51:45 -04:00
parent e53f3f5d13
commit 7e3c9c1aed
2 changed files with 81 additions and 0 deletions

View file

@ -95,3 +95,46 @@ func DecodeAddress(addr string) (addrHash []byte, net btcwire.BitcoinNet, err er
return addrHash, net, nil
}
// EncodePrivateKey takes a 32-byte raw private key address and encodes
// it into the Wallet Import Format (WIF)
func EncodePrivateKey(privKey []byte) (string, error) {
if len(privKey) != 32 {
return "", ErrMalformedAddress
}
tosum := append([]byte{0x80}, privKey...)
cksum := btcwire.DoubleSha256(tosum)
// Address before base58 encoding is 1 byte for 0x80 (5), 32 bytes for
// privKey, plus 4 bytes of checksum.
a := make([]byte, 37, 37)
a[0] = 0x80
copy(a[1:], privKey)
copy(a[32+1:], cksum[:4])
return Base58Encode(a), nil
}
// DecodePrivateKey takes a Wallet Import Format (WIF) string and
// decodes into a 32-byte private key.
func DecodePrivateKey(wif string) ([]byte, error) {
decoded := Base58Decode(wif)
// Length of decoded privkey must be 32 bytes + 1 byte for 0x80
// + 4 bytes of checksum
if len(decoded) != 32+5 {
return nil, ErrMalformedAddress
}
tosum := decoded[:32+1]
cksum := btcwire.DoubleSha256(tosum)[:4]
if !bytes.Equal(cksum, decoded[len(decoded)-4:]) {
return nil, ErrMalformedAddress
}
privKey := make([]byte, 32, 32)
copy(privKey[:], decoded[1:32+1])
return privKey, nil
}

View file

@ -11,6 +11,18 @@ import (
"testing"
)
var encodePrivateKeyTests = []struct {
in []byte
out string
}{
{[]byte{
0x0c, 0x28, 0xfc, 0xa3, 0x86, 0xc7, 0xa2, 0x27,
0x60, 0x0b, 0x2f, 0xe5, 0x0b, 0x7c, 0xae, 0x11,
0xec, 0x86, 0xd3, 0xbf, 0x1f, 0xbe, 0x47, 0x1b,
0xe8, 0x98, 0x27, 0xe1, 0x9d, 0x72, 0xaa, 0x1d,
}, "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ"},
}
var encodeTests = []struct {
raw []byte
net btcwire.BitcoinNet
@ -91,3 +103,29 @@ func TestDecodeAddresses(t *testing.T) {
}
}
}
func TestEncodeDecodePrivateKey(t *testing.T) {
for _, test := range encodePrivateKeyTests {
wif, err := btcutil.EncodePrivateKey(test.in)
if err != nil {
t.Error(err)
continue
}
if wif != test.out {
t.Errorf("TestEncodeDecodePrivateKey failed: want '%s', got '%s'",
test.out, wif)
continue
}
key, err := btcutil.DecodePrivateKey(test.out)
if err != nil {
t.Error(err)
continue
}
if !bytes.Equal(key, test.in) {
t.Errorf("TestEncodeDecodePrivateKey failed: want '%x', got '%x'",
test.out, key)
}
}
}