hdkeychain: Update NewMaster to accept network.
This changes the NewMaster function to accept the network the generated extended master key is associated with. This could previously be done by calling SetNet on the returned extended key, but that approach is more error prone since it is easy for a caller to forget to do it or never know they should to begin with.
This commit is contained in:
parent
e8bab6bc19
commit
ff82dacded
3 changed files with 76 additions and 9 deletions
|
@ -22,7 +22,7 @@ func ExampleNewMaster() {
|
|||
}
|
||||
|
||||
// Generate a new master node using the seed.
|
||||
key, err := hdkeychain.NewMaster(seed)
|
||||
key, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
|
|
|
@ -440,7 +440,7 @@ func (k *ExtendedKey) Zero() {
|
|||
// will derive to an unusable secret key. The ErrUnusable error will be
|
||||
// returned if this should occur, so the caller must check for it and generate a
|
||||
// new seed accordingly.
|
||||
func NewMaster(seed []byte) (*ExtendedKey, error) {
|
||||
func NewMaster(seed []byte, net *chaincfg.Params) (*ExtendedKey, error) {
|
||||
// Per [BIP32], the seed must be in range [MinSeedBytes, MaxSeedBytes].
|
||||
if len(seed) < MinSeedBytes || len(seed) > MaxSeedBytes {
|
||||
return nil, ErrInvalidSeedLen
|
||||
|
@ -465,8 +465,8 @@ func NewMaster(seed []byte) (*ExtendedKey, error) {
|
|||
}
|
||||
|
||||
parentFP := []byte{0x00, 0x00, 0x00, 0x00}
|
||||
return newExtendedKey(chaincfg.MainNetParams.HDPrivateKeyID[:], secretKey,
|
||||
chainCode, parentFP, 0, 0, true), nil
|
||||
return newExtendedKey(net.HDPrivateKeyID[:], secretKey, chainCode,
|
||||
parentFP, 0, 0, true), nil
|
||||
}
|
||||
|
||||
// NewKeyFromString returns a new extended key instance from a base58-encoded
|
||||
|
|
|
@ -33,6 +33,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path []uint32
|
||||
wantPub string
|
||||
wantPriv string
|
||||
net *chaincfg.Params
|
||||
}{
|
||||
// Test vector 1
|
||||
{
|
||||
|
@ -41,6 +42,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{},
|
||||
wantPub: "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
|
||||
wantPriv: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H",
|
||||
|
@ -48,6 +50,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{hkStart},
|
||||
wantPub: "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw",
|
||||
wantPriv: "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H/1",
|
||||
|
@ -55,6 +58,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{hkStart, 1},
|
||||
wantPub: "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
|
||||
wantPriv: "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H/1/2H",
|
||||
|
@ -62,6 +66,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{hkStart, 1, hkStart + 2},
|
||||
wantPub: "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5",
|
||||
wantPriv: "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H/1/2H/2",
|
||||
|
@ -69,6 +74,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{hkStart, 1, hkStart + 2, 2},
|
||||
wantPub: "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV",
|
||||
wantPriv: "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H/1/2H/2/1000000000",
|
||||
|
@ -76,6 +82,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{hkStart, 1, hkStart + 2, 2, 1000000000},
|
||||
wantPub: "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy",
|
||||
wantPriv: "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
|
||||
// Test vector 2
|
||||
|
@ -85,6 +92,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{},
|
||||
wantPub: "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB",
|
||||
wantPriv: "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 2 chain m/0",
|
||||
|
@ -92,6 +100,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{0},
|
||||
wantPub: "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH",
|
||||
wantPriv: "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 2 chain m/0/2147483647H",
|
||||
|
@ -99,6 +108,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{0, hkStart + 2147483647},
|
||||
wantPub: "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a",
|
||||
wantPriv: "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 2 chain m/0/2147483647H/1",
|
||||
|
@ -106,6 +116,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{0, hkStart + 2147483647, 1},
|
||||
wantPub: "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon",
|
||||
wantPriv: "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 2 chain m/0/2147483647H/1/2147483646H",
|
||||
|
@ -113,6 +124,7 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{0, hkStart + 2147483647, 1, hkStart + 2147483646},
|
||||
wantPub: "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL",
|
||||
wantPriv: "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
{
|
||||
name: "test vector 2 chain m/0/2147483647H/1/2147483646H/2",
|
||||
|
@ -120,6 +132,57 @@ func TestBIP0032Vectors(t *testing.T) {
|
|||
path: []uint32{0, hkStart + 2147483647, 1, hkStart + 2147483646, 2},
|
||||
wantPub: "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt",
|
||||
wantPriv: "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
|
||||
// Test vector 1 - Testnet
|
||||
{
|
||||
name: "test vector 1 chain m - testnet",
|
||||
master: testVec1MasterHex,
|
||||
path: []uint32{},
|
||||
wantPub: "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp",
|
||||
wantPriv: "tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5khqjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m",
|
||||
net: &chaincfg.TestNet3Params,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H - testnet",
|
||||
master: testVec1MasterHex,
|
||||
path: []uint32{hkStart},
|
||||
wantPub: "tpubD8eQVK4Kdxg3gHrF62jGP7dKVCoYiEB8dFSpuTawkL5YxTus5j5pf83vaKnii4bc6v2NVEy81P2gYrJczYne3QNNwMTS53p5uzDyHvnw2jm",
|
||||
wantPriv: "tprv8bxNLu25VazNnppTCP4fyhyCvBHcYtzE3wr3cwYeL4HA7yf6TLGEUdS4QC1vLT63TkjRssqJe4CvGNEC8DzW5AoPUw56D1Ayg6HY4oy8QZ9",
|
||||
net: &chaincfg.TestNet3Params,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H/1 - testnet",
|
||||
master: testVec1MasterHex,
|
||||
path: []uint32{hkStart, 1},
|
||||
wantPub: "tpubDApXh6cD2fZ7WjtgpHd8yrWyYaneiFuRZa7fVjMkgxsmC1QzoXW8cgx9zQFJ81Jx4deRGfRE7yXA9A3STsxXj4CKEZJHYgpMYikkas9DBTP",
|
||||
wantPriv: "tprv8e8VYgZxtHsSdGrtvdxYaSrryZGiYviWzGWtDDKTGh5NMXAEB8gYSCLHpFCywNs5uqV7ghRjimALQJkRFZnUrLHpzi2pGkwqLtbubgWuQ8q",
|
||||
net: &chaincfg.TestNet3Params,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H/1/2H - testnet",
|
||||
master: testVec1MasterHex,
|
||||
path: []uint32{hkStart, 1, hkStart + 2},
|
||||
wantPub: "tpubDDRojdS4jYQXNugn4t2WLrZ7mjfAyoVQu7MLk4eurqFCbrc7cHLZX8W5YRS8ZskGR9k9t3PqVv68bVBjAyW4nWM9pTGRddt3GQftg6MVQsm",
|
||||
wantPriv: "tprv8gjmbDPpbAirVSezBEMuwSu1Ci9EpUJWKokZTYccSZSomNMLytWyLdtDNHRbucNaRJWWHANf9AzEdWVAqahfyRjVMKbNRhBmxAM8EJr7R15",
|
||||
net: &chaincfg.TestNet3Params,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H/1/2H/2 - testnet",
|
||||
master: testVec1MasterHex,
|
||||
path: []uint32{hkStart, 1, hkStart + 2, 2},
|
||||
wantPub: "tpubDFfCa4Z1v25WTPAVm9EbEMiRrYwucPocLbEe12BPBGooxxEUg42vihy1DkRWyftztTsL23snYezF9uXjGGwGW6pQjEpcTpmsH6ajpf4CVPn",
|
||||
wantPriv: "tprv8iyAReWmmePqZv8hsVZzpx4KHXRyT4chmHdriW95m11R8Tyi3fDLYDM93bq4NGn1V6eCu5cE3zSQ6hPd31F2ApKXkZgTyn1V78pHjkq1V2v",
|
||||
net: &chaincfg.TestNet3Params,
|
||||
},
|
||||
{
|
||||
name: "test vector 1 chain m/0H/1/2H/2/1000000000 - testnet",
|
||||
master: testVec1MasterHex,
|
||||
path: []uint32{hkStart, 1, hkStart + 2, 2, 1000000000},
|
||||
wantPub: "tpubDHNy3kAG39ThyiwwsgoKY4iRenXDRtce8qdCFJZXPMCJg5dsCUHayp84raLTpvyiNA9sXPob5rgqkKvkN8S7MMyXbnEhGJMW64Cf4vFAoaF",
|
||||
wantPriv: "tprv8kgvuL81tmn36Fv9z38j8f4K5m1HGZRjZY2QxnXDy5PuqbP6a5TzoKWCgTcGHBu66W3TgSbAu2yX6sPza5FkHmy564Sh6gmCPUNeUt4yj2x",
|
||||
net: &chaincfg.TestNet3Params,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -132,7 +195,7 @@ tests:
|
|||
continue
|
||||
}
|
||||
|
||||
extKey, err := hdkeychain.NewMaster(masterSeed)
|
||||
extKey, err := hdkeychain.NewMaster(masterSeed, test.net)
|
||||
if err != nil {
|
||||
t.Errorf("NewMaster #%d (%s): unexpected error when "+
|
||||
"creating new master key: %v", i, test.name,
|
||||
|
@ -585,14 +648,15 @@ func TestNet(t *testing.T) {
|
|||
// the errors are handled properly.
|
||||
func TestErrors(t *testing.T) {
|
||||
// Should get an error when seed has too few bytes.
|
||||
_, err := hdkeychain.NewMaster(bytes.Repeat([]byte{0x00}, 15))
|
||||
net := &chaincfg.MainNetParams
|
||||
_, err := hdkeychain.NewMaster(bytes.Repeat([]byte{0x00}, 15), net)
|
||||
if err != hdkeychain.ErrInvalidSeedLen {
|
||||
t.Errorf("NewMaster: mismatched error -- got: %v, want: %v",
|
||||
err, hdkeychain.ErrInvalidSeedLen)
|
||||
}
|
||||
|
||||
// Should get an error when seed has too many bytes.
|
||||
_, err = hdkeychain.NewMaster(bytes.Repeat([]byte{0x00}, 65))
|
||||
_, err = hdkeychain.NewMaster(bytes.Repeat([]byte{0x00}, 65), net)
|
||||
if err != hdkeychain.ErrInvalidSeedLen {
|
||||
t.Errorf("NewMaster: mismatched error -- got: %v, want: %v",
|
||||
err, hdkeychain.ErrInvalidSeedLen)
|
||||
|
@ -604,7 +668,7 @@ func TestErrors(t *testing.T) {
|
|||
t.Errorf("GenerateSeed: unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
extKey, err := hdkeychain.NewMaster(seed)
|
||||
extKey, err := hdkeychain.NewMaster(seed, net)
|
||||
if err != nil {
|
||||
t.Errorf("NewMaster: unexpected error: %v", err)
|
||||
return
|
||||
|
@ -681,12 +745,14 @@ func TestZero(t *testing.T) {
|
|||
name string
|
||||
master string
|
||||
extKey string
|
||||
net *chaincfg.Params
|
||||
}{
|
||||
// Test vector 1
|
||||
{
|
||||
name: "test vector 1 chain m",
|
||||
master: "000102030405060708090a0b0c0d0e0f",
|
||||
extKey: "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
|
||||
// Test vector 2
|
||||
|
@ -694,6 +760,7 @@ func TestZero(t *testing.T) {
|
|||
name: "test vector 2 chain m",
|
||||
master: "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
|
||||
extKey: "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
|
||||
net: &chaincfg.MainNetParams,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -767,7 +834,7 @@ func TestZero(t *testing.T) {
|
|||
i, test.name, err)
|
||||
continue
|
||||
}
|
||||
key, err := hdkeychain.NewMaster(masterSeed)
|
||||
key, err := hdkeychain.NewMaster(masterSeed, test.net)
|
||||
if err != nil {
|
||||
t.Errorf("NewMaster #%d (%s): unexpected error when "+
|
||||
"creating new master key: %v", i, test.name,
|
||||
|
|
Loading…
Reference in a new issue