check / check (push) Successful in 52s
REPO_POLICIES.md sets the Go module root to sneak.berlin/go/<name>. go.mod, every import of the old path and the -X path in the Makefile LDFLAGS now use sneak.berlin/go/keyfunc; make fmt moved those imports to their new place in the sort order. The old path keeps no alias. The README gives the go install line next to the build from a clone and drops this issue from its TODO list, which now names the open 1.0 issues. Model: opus-5-5
118 lines
3.3 KiB
Go
118 lines
3.3 KiB
Go
package childmnemonic_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/btcsuite/btcd/btcutil/hdkeychain"
|
|
"github.com/stretchr/testify/require"
|
|
bip39 "github.com/tyler-smith/go-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
|
|
}
|