Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion bip32.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,25 @@ func (key *Bip32Key) ChildNumber() uint32 {
return key.child_number
}

// EncodeWIF encodes this key in Bip32 WIF format (dgpv,dgub)
// EncodeWIF encodes this key in BIP32 extended-key serialization (dgpv/dgub).
//
// Historical name: this is NOT classic Wallet Import Format (the single private
// key "WIF" used by dumpprivkey / importprivkey). For classic WIF of the EC
// private key, use EncodePrivateWIF. See https://github.com/dogeorg/doge/issues/2
func (key *Bip32Key) EncodeWIF() string {
return EncodeBip32WIF(key)
}

// EncodePrivateWIF returns classic Wallet Import Format (compressed pubkey
// marker) for a private Bip32Key. Returns an error if this key is public-only.
func (key *Bip32Key) EncodePrivateWIF() (string, error) {
pk, err := key.GetECPrivKey()
if err != nil {
return "", err
}
return EncodeECPrivKeyWIF(pk, key.chain), nil
}

// Public returns the Public Bip32Key corresponding to a Private Bip32Key.
// If key is already a Public Bip32Key, the same *Bip32Key is returned.
func (key *Bip32Key) Public() *Bip32Key {
Expand Down
40 changes: 40 additions & 0 deletions bip32_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package doge

import (
"bytes"
"fmt"
"testing"
)
Expand Down Expand Up @@ -420,3 +421,42 @@ func TestBip32InvalidKeys(t *testing.T) {
//log.Printf("%v", err)
}
}

func TestBip32EncodePrivateWIF(t *testing.T) {
// EncodePrivateWIF must return classic WIF, not BIP32 extended (dgpv/dgub).
// Seed from BIP32 test vector 1.
master, err := Bip32MasterFromSeed(hx2b("000102030405060708090a0b0c0d0e0f"), &BitcoinMainChain)
if err != nil {
t.Fatalf("Bip32MasterFromSeed: %v", err)
}
classic, err := master.EncodePrivateWIF()
if err != nil {
t.Fatalf("EncodePrivateWIF: %v", err)
}
extended := master.EncodeWIF()
if classic == extended {
t.Fatalf("EncodePrivateWIF returned extended key: %s", classic)
}
// Classic WIF starts with K/L (compressed mainnet) or 5 (uncompressed); BIP32 xprv with xprv/dgpv
if len(classic) < 50 {
t.Fatalf("EncodePrivateWIF too short: %s", classic)
}
pk, chain, err := DecodeECPrivKeyWIF(classic, nil)
if err != nil {
t.Fatalf("DecodeECPrivKeyWIF failed for EncodePrivateWIF output: %v (%s)", err, classic)
}
if chain != &BitcoinMainChain {
t.Fatalf("wrong chain from decoded WIF")
}
want, err := master.GetECPrivKey()
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(pk[:], want[:]) {
t.Fatalf("decoded key mismatch")
}
// Public key cannot produce classic private WIF
if _, err := master.Public().EncodePrivateWIF(); err == nil {
t.Fatalf("expected error encoding private WIF from public key")
}
}