Files
keyfunc/internal/childmnemonic/childmnemonic.go
T
clawbot 17579504e3
check / check (push) Successful in 5m38s
Copy go-bip39 into internal/bip39 (closes #42)
go-bip39's repository no longer exists, so keyfunc now carries the
part of v1.1.0 it uses, with the upstream LICENSE beside it, and
imports it from internal/bip39. Upstream's tests and test vectors for
the kept code come along unchanged; where they called a removed
function, crypto/rand stands in for NewEntropy and EntropyFromMnemonic
for MnemonicToByteArray.

Changes beyond the trimming are what the linter asked for: the
package-level variables moved into the functions that use them, three
error strings were lower-cased, and the unknown-word error now wraps
ErrInvalidMnemonic.

go.mod no longer requires go-bip39. go mod tidy keeps its two go.sum
lines, because a test in sneak/secret's bip85 package imports it, and
drops six lines that only go-bip39's own requirements needed.

Model: opus-5-5
2026-10-06 01:00:18 +00:00

64 lines
1.7 KiB
Go

// Package childmnemonic derives a mnemonic from another mnemonic.
package childmnemonic
import (
"errors"
"fmt"
"git.eeqj.de/sneak/secret/pkg/bip85"
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"sneak.berlin/go/keyfunc/internal/bip39"
"sneak.berlin/go/keyfunc/internal/derive"
)
// 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
}