Refuse a key index with no hardened child
All checks were successful
check / check (push) Successful in 23s

Every element of the derivation path is hardened, so an index above
2147483647 has no child to derive: the hardened offset wrapped around
and the tool silently produced a non-hardened key that no other
implementation reading the path as written would reproduce. Such an
index is now refused with a message before anything is derived, and
tests pin the refusal at both the derivation and the command level.

Also use the hook path variable in script/install-precommit instead of
repeating the literal beside it.

Model: opus-5
This commit is contained in:
clawbot
2026-09-07 15:08:29 +00:00
parent 90a7c96cd1
commit 731ffffb5f
4 changed files with 53 additions and 4 deletions

View File

@@ -2,6 +2,7 @@
package derive
import (
"errors"
"fmt"
"git.eeqj.de/sneak/secret/pkg/bip85"
@@ -16,8 +17,18 @@ const (
// Size is how many bytes every key type is given.
Size = 32
// MaxIndex is the largest key index there is. Every element of
// the path is hardened, and a hardened BIP-32 child index stops
// here.
MaxIndex = 1<<31 - 1
)
// ErrIndexTooLarge is returned for a key index above MaxIndex. Such an
// index has no hardened child to derive, so there is no key to give
// back rather than a key nobody else would reproduce.
var ErrIndexTooLarge = errors.New("the key index is too large")
// Path returns the derivation path for an application number and a key
// index.
func Path(application, index uint32) string {
@@ -28,7 +39,15 @@ func Path(application, index uint32) string {
// 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,
)
}
seed := bip39.NewSeed(words, "")
master, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)