decred.org/dcrdex@v1.0.5/dex/keygen/keygen.go (about) 1 package keygen 2 3 import ( 4 "fmt" 5 6 "github.com/decred/dcrd/hdkeychain/v3" 7 ) 8 9 // RootKeyParams implements hdkeychain.NetworkParams for master 10 // hdkeychain.ExtendedKey creation. 11 type RootKeyParams struct{} 12 13 func (*RootKeyParams) HDPrivKeyVersion() [4]byte { 14 return [4]byte{0x74, 0x61, 0x63, 0x6f} // ASCII "taco" 15 } 16 func (*RootKeyParams) HDPubKeyVersion() [4]byte { 17 return [4]byte{0x64, 0x65, 0x78, 0x63} // ASCII "dexc" 18 } 19 20 // GenDeepChild derives the leaf of a path of children from a root extended key. 21 func GenDeepChild(seed []byte, kids []uint32) (*hdkeychain.ExtendedKey, error) { 22 root, err := hdkeychain.NewMaster(seed, &RootKeyParams{}) 23 if err != nil { 24 return nil, err 25 } 26 defer root.Zero() 27 28 return GenDeepChildFromXPriv(root, kids) 29 } 30 31 // GenDeepChildFromXPriv derives the leaf of a path of children from a parent 32 // extended key. 33 func GenDeepChildFromXPriv(root *hdkeychain.ExtendedKey, kids []uint32) (*hdkeychain.ExtendedKey, error) { 34 genChild := func(parent *hdkeychain.ExtendedKey, childIdx uint32) (*hdkeychain.ExtendedKey, error) { 35 err := hdkeychain.ErrInvalidChild 36 for err == hdkeychain.ErrInvalidChild { 37 var kid *hdkeychain.ExtendedKey 38 kid, err = parent.ChildBIP32Std(childIdx) 39 if err == nil { 40 return kid, nil 41 } 42 fmt.Printf("Child derive skipped a key index %d -> %d", childIdx, childIdx+1) // < 1 in 2^127 chance 43 childIdx++ 44 } 45 return nil, err 46 } 47 48 extKey := root 49 for i, childIdx := range kids { 50 childExtKey, err := genChild(extKey, childIdx) 51 if i > 0 { // don't zero the input arg 52 extKey.Zero() 53 } 54 extKey = childExtKey 55 if err != nil { 56 return nil, fmt.Errorf("genChild error: %w", err) 57 } 58 } 59 60 return extKey, nil 61 }