Files
keyfunc/internal/childmnemonic/childmnemonic_test.go
T
clawbot 45d302a6f0
check / check (push) Successful in 4m53s
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 five lines that only go-bip39's own requirements needed.

Model: opus-5-5
2026-10-06 00:32:11 +00:00

118 lines
3.3 KiB
Go

package childmnemonic_test
import (
"strings"
"testing"
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/stretchr/testify/require"
"sneak.berlin/go/keyfunc/internal/bip39"
"sneak.berlin/go/keyfunc/internal/childmnemonic"
"sneak.berlin/go/keyfunc/internal/derive"
)
// The lengths the tool offers, and one it does not.
const (
twelve = 12
eighteen = 18
twentyFour = 24
fifteen = 15
)
// specificationKey is the master key the BIP-85 specification gives
// every one of its test vectors for.
const specificationKey = "xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBq" +
"sx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb"
// The three English child mnemonics at key index 0 that the BIP-85
// specification gives for that master key.
const (
twelveWords = "girl mad pet galaxy egg matter matrix prison refuse " +
"sense ordinary nose"
eighteenWords = "near account window bike charge season chef number " +
"sketch tomorrow excuse sniff circle vital hockey outdoor " +
"supply token"
twentyFourWords = "puppy ocean match cereal symbol another shed " +
"magic wrap hammer bulb intact gadget divorce twin tonight " +
"reason outdoor destroy simple truth cigar social volcano"
)
// example returns the mnemonic every BIP-39 document uses to show its
// test vectors: eleven abandons and about.
func example() string {
return strings.Repeat("abandon ", 11) + "about"
}
func TestTheSpecificationTestVectors(t *testing.T) {
t.Parallel()
require.Equal(t, twelveWords, fromSpecificationKey(t, twelve))
require.Equal(t, eighteenWords, fromSpecificationKey(t, eighteen))
require.Equal(t, twentyFourWords, fromSpecificationKey(t, twentyFour))
}
func TestTheLongestChildMnemonicPassesItsOwnChecksum(t *testing.T) {
t.Parallel()
child := fromSpecificationKey(t, twentyFour)
require.Len(t, strings.Fields(child), twentyFour)
require.True(t, bip39.IsMnemonicValid(child))
}
func TestEachKeyIndexGivesItsOwnChildMnemonic(t *testing.T) {
t.Parallel()
master, err := derive.Master(example())
require.NoError(t, err)
first, err := childmnemonic.Derive(master, twelve, 0)
require.NoError(t, err)
require.True(t, bip39.IsMnemonicValid(first))
second, err := childmnemonic.Derive(master, twelve, 1)
require.NoError(t, err)
require.True(t, bip39.IsMnemonicValid(second))
require.NotEqual(t, first, second)
}
func TestALengthTheToolDoesNotOfferIsRefused(t *testing.T) {
t.Parallel()
master, err := hdkeychain.NewKeyFromString(specificationKey)
require.NoError(t, err)
_, err = childmnemonic.Derive(master, fifteen, 0)
require.ErrorIs(t, err, childmnemonic.ErrWordCount)
}
func TestAnIndexWithNoHardenedChildIsRefused(t *testing.T) {
t.Parallel()
master, err := hdkeychain.NewKeyFromString(specificationKey)
require.NoError(t, err)
_, err = childmnemonic.Derive(master, twelve, derive.MaxIndex+1)
require.ErrorIs(t, err, derive.ErrIndexTooLarge)
_, err = childmnemonic.Derive(master, twelve, derive.MaxIndex)
require.NoError(t, err)
}
// fromSpecificationKey derives the child mnemonic of that length at key
// index 0 from the master key the specification gives.
func fromSpecificationKey(t *testing.T, words uint32) string {
t.Helper()
master, err := hdkeychain.NewKeyFromString(specificationKey)
require.NoError(t, err)
child, err := childmnemonic.Derive(master, words, 0)
require.NoError(t, err)
return child
}