The mnemonic command: child mnemonics (closes #4)
All checks were successful
check / check (push) Successful in 19s
All checks were successful
check / check (push) Successful in 19s
keyfunc mnemonic prints a child mnemonic derived from the main one with BIP-85's own mnemonic application, in English, at 12, 18 or 24 words. Its entropy is the BIP-85 entropy cut to the length the word count needs, which is what that application asks for, so it does not go through the generator the other key types read their bytes from. The BIP-85 specification's own test vectors for the application are the tests. Two pieces the derivation package already had inside one function are now named: the master key a mnemonic stands for, and the refusal of a key index that has no hardened child. Both key types call them. Model: opus-5
This commit is contained in:
@@ -35,24 +35,47 @@ func Path(application, index uint32) string {
|
||||
return fmt.Sprintf("m/%d'/%d'/%d'", purpose, application, index)
|
||||
}
|
||||
|
||||
// CheckIndex refuses a key index above MaxIndex, so that every key
|
||||
// type turns such an index down before deriving anything.
|
||||
func CheckIndex(index uint32) error {
|
||||
if index > MaxIndex {
|
||||
return fmt.Errorf(
|
||||
"%w: %d is above %d",
|
||||
ErrIndexTooLarge, index, MaxIndex,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Master returns the BIP-32 master key a mnemonic stands for: the
|
||||
// mnemonic becomes a seed with an empty passphrase, and the seed
|
||||
// becomes the key.
|
||||
func Master(words string) (*hdkeychain.ExtendedKey, error) {
|
||||
seed := bip39.NewSeed(words, "")
|
||||
|
||||
master, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("making the master key: %w", err)
|
||||
}
|
||||
|
||||
return master, nil
|
||||
}
|
||||
|
||||
// Bytes returns the bytes for an application number and a key index.
|
||||
// The mnemonic becomes a seed with an empty passphrase, the seed
|
||||
// becomes a master key, the master key gives BIP-85 entropy at the
|
||||
// path, and the entropy seeds the generator the bytes are read from.
|
||||
// An index above MaxIndex is refused before any of that happens.
|
||||
func Bytes(words string, application, index uint32) ([]byte, error) {
|
||||
if index > MaxIndex {
|
||||
return nil, fmt.Errorf(
|
||||
"%w: %d is above %d",
|
||||
ErrIndexTooLarge, index, MaxIndex,
|
||||
)
|
||||
err := CheckIndex(index)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
seed := bip39.NewSeed(words, "")
|
||||
|
||||
master, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
|
||||
master, err := Master(words)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("making the master key: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entropy, err := bip85.DeriveBIP85Entropy(master, Path(application, index))
|
||||
|
||||
Reference in New Issue
Block a user