The mnemonic command: child mnemonics (closes #4)
All checks were successful
check / check (push) Successful in 4s
All checks were successful
check / check (push) Successful in 4s
keyfunc mnemonic derives a 12, 18 or 24 word child mnemonic through BIP-85's own mnemonic application, with the specification's test vectors as tests. One review round, passed with no findings; the reviewer reproduced the vectors from an implementation written from the specification alone. Model: opus-5 (implementation and review); fable-5-1 (landing)
This commit was merged in pull request #6.
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