Say why a mnemonic is refused (closes #76) #86

Merged
clawbot merged 1 commits from issue-76-mnemonic-error-messages into next 2026-10-14 22:05:38 +02:00
Collaborator

Every way a mnemonic could be invalid was reported as the mnemonic fails its BIP-39 checksum, even when the mnemonic command printed nothing. checked in internal/mnemonic/mnemonic.go now tells the cases apart, in this order:

  • no words at all: the mnemonic is empty;
  • a word count other than 12, 15, 18, 21 or 24: a mnemonic has 12, 15, 18, 21 or 24 words, not 3;
  • a word not on the BIP-39 word list: word 12 of the mnemonic is not on the BIP-39 word list, giving its position and never the word;
  • a checksum mismatch: the checksum message, as before; nothing else reaches it.

The checks live in internal/mnemonic rather than in internal/bip39, which is a copy of upstream and stays unchanged: its error for an unknown word contains the word, and it reports an empty mnemonic the same way as a wrong word count.

Tests in internal/mnemonic/mnemonic_test.go cover the three new cases and check that none of them mentions the checksum; the unknown-word test also checks the word is not in the message. The README's "Giving it the mnemonic" now lists what is refused.

Judgement call: the word count is checked before the words, so a mnemonic with a wrong count and a typo is reported for its count.
Judgement call: words are not lower-cased, so Abandon is reported as not on the word list; before this change it was refused with the checksum message.

Closes #76

Model: opus-5-5

Every way a mnemonic could be invalid was reported as `the mnemonic fails its BIP-39 checksum`, even when the mnemonic command printed nothing. `checked` in `internal/mnemonic/mnemonic.go` now tells the cases apart, in this order: - no words at all: `the mnemonic is empty`; - a word count other than 12, 15, 18, 21 or 24: `a mnemonic has 12, 15, 18, 21 or 24 words, not 3`; - a word not on the BIP-39 word list: `word 12 of the mnemonic is not on the BIP-39 word list`, giving its position and never the word; - a checksum mismatch: the checksum message, as before; nothing else reaches it. The checks live in `internal/mnemonic` rather than in `internal/bip39`, which is a copy of upstream and stays unchanged: its error for an unknown word contains the word, and it reports an empty mnemonic the same way as a wrong word count. Tests in `internal/mnemonic/mnemonic_test.go` cover the three new cases and check that none of them mentions the checksum; the unknown-word test also checks the word is not in the message. The README's "Giving it the mnemonic" now lists what is refused. Judgement call: the word count is checked before the words, so a mnemonic with a wrong count and a typo is reported for its count. Judgement call: words are not lower-cased, so `Abandon` is reported as not on the word list; before this change it was refused with the checksum message. Closes https://git.eeqj.de/sneak/keyfunc/issues/76 Model: opus-5-5
clawbot added the needs-review label 2026-10-14 21:01:06 +02:00
clawbot self-assigned this 2026-10-14 21:01:06 +02:00
Author
Collaborator

One finding.

  • internal/mnemonic/mnemonic_test.go: no test checks that a valid mnemonic of 15, 18, 21 or 24 words is still accepted. checked in internal/mnemonic/mnemonic.go now decides for itself which word counts pass. If an entry dropped out of that list (24, say), every mnemonic of that length would be refused, and every test would still pass, because the existing tests only read 12-word mnemonics. Acceptable: a test that Read returns a valid mnemonic of each allowed length other than 12, for example abandon 23 times followed by art for 24 words.

Model: opus-5-5

One finding. - `internal/mnemonic/mnemonic_test.go`: no test checks that a valid mnemonic of 15, 18, 21 or 24 words is still accepted. `checked` in `internal/mnemonic/mnemonic.go` now decides for itself which word counts pass. If an entry dropped out of that list (24, say), every mnemonic of that length would be refused, and every test would still pass, because the existing tests only read 12-word mnemonics. Acceptable: a test that `Read` returns a valid mnemonic of each allowed length other than 12, for example `abandon` 23 times followed by `art` for 24 words. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-14 21:23:45 +02:00
clawbot added 1 commit 2026-10-14 21:41:19 +02:00
Say why a mnemonic is refused (closes #76)
check / check (push) Waiting to run
727fa8977b
Every way a mnemonic could be invalid was reported as a checksum
failure, including an empty one. It is now refused as empty, as having
a word count other than 12, 15, 18, 21 or 24, as having a word that is
not on the BIP-39 word list, or as failing the checksum. A word not on
the list is named by its position, never by the word itself.

Model: opus-5-5
clawbot force-pushed issue-76-mnemonic-error-messages from 4aae5925af to 727fa8977b 2026-10-14 21:41:19 +02:00 Compare
Author
Collaborator

Rework: internal/mnemonic/mnemonic_test.go now has a test that Read accepts a valid mnemonic of 15, 18, 21 and 24 words, so a length dropped from checked makes it fail. The branch is rebased onto next, still one commit.

Model: opus-5-5

Rework: `internal/mnemonic/mnemonic_test.go` now has a test that `Read` accepts a valid mnemonic of 15, 18, 21 and 24 words, so a length dropped from `checked` makes it fail. The branch is rebased onto `next`, still one commit. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-14 21:41:33 +02:00
Author
Collaborator

Review passed: each way a mnemonic can be refused now gets its own message, and the earlier finding about the 15- to 24-word lengths is fixed.

Model: opus-5-5

Review passed: each way a mnemonic can be refused now gets its own message, and the earlier finding about the 15- to 24-word lengths is fixed. Model: opus-5-5
clawbot merged commit 5582c02edf into next 2026-10-14 22:05:38 +02:00
clawbot deleted branch issue-76-mnemonic-error-messages 2026-10-14 22:05:39 +02:00
Sign in to join this conversation.