// Package childmnemonic derives a mnemonic from another mnemonic. package childmnemonic import ( "errors" "fmt" "git.eeqj.de/sneak/keyfunc/internal/derive" "git.eeqj.de/sneak/secret/pkg/bip85" "github.com/btcsuite/btcd/btcutil/hdkeychain" bip39 "github.com/tyler-smith/go-bip39" ) // english is the number BIP-85 gives the English word list. const english = 0 // The lengths a child mnemonic may have. BIP-85 also allows 15 and 21 // words; these three are the ones this tool offers. const ( twelve = 12 eighteen = 18 twentyFour = 24 ) // DefaultWords is how long a child mnemonic is when the user does not // say. const DefaultWords = twelve // ErrWordCount is returned for a length this tool does not offer. var ErrWordCount = errors.New("a child mnemonic has 12, 18 or 24 words") // Derive returns the English child mnemonic of that many words at that // key index, taken from the master key with BIP-85's own mnemonic // application, number 39. The words come straight from the BIP-85 // entropy, cut to the length the word count needs, rather than from // the generator the other key types read their bytes from. func Derive( master *hdkeychain.ExtendedKey, words, index uint32, ) (string, error) { switch words { case twelve, eighteen, twentyFour: default: return "", fmt.Errorf("%w, not %d", ErrWordCount, words) } err := derive.CheckIndex(index) if err != nil { return "", err } entropy, err := bip85.DeriveBIP39Entropy(master, english, words, index) if err != nil { return "", fmt.Errorf("deriving entropy: %w", err) } child, err := bip39.NewMnemonic(entropy) if err != nil { return "", fmt.Errorf("turning the entropy into words: %w", err) } return child, nil }