Skip to content

Generate Final Word: does it present all 8 candidates or resolve the 3 entropy bits internally? #656

Description

@so7ow

Hi, question about Generate Final Word on Passport Core (2.3.0+).

I generate my seed entropy by hand with dice and want the device only to compute the checksum, contributing no randomness of its own. Word 24 of a 24-word seed carries 3 entropy bits alongside the 8 checksum bits, which means 8 valid completions exist for any 23 words.

When I enter 23 words and choose Generate Final Word, does Passport present all 8 candidates, offer a way for me to supply those 3 bits, or pick one itself? And if it picks, is the choice zero-padded or random?

The docs say "a valid final word," singular, which is why I'm unsure. Thanks.


Answer from the code, 2026-08-02

Passport picks one. It does not present all 8, and it does not offer a way to supply the 3 bits. The choice is random, not zero-padded.

ports/stm32/boards/Passport/modules/predictive_utils.py, get_last_word:

index_bytes = bytearray(4)
common.noise.random_bytes(index_bytes, common.noise.ALL)
index = int.from_bytes(index_bytes, "little") % SEED_WORD_LIST_LENGTH
mock_last_word = trezorcrypto.bip39.get_word(index)
copy_words = ' '.join(seed_words) + ' ' + mock_last_word
entropy = get_seed_from_words(copy_words)
(final_words, error) = get_words_from_seed(entropy)
return final_words[-1]

The device draws 4 bytes from the full three-source entropy mixer, picks a random word index from it, then recomputes the checksum and returns the single valid completion. No modulo bias (2^32 mod 2048 = 0).

So the reporter's concern is correct. Someone supplying their own dice entropy for 23 words is receiving 3 bits of device entropy in the final word whether they want them or not, and has no way to opt out or to see the other 7 valid completions.

Whether that matters is a judgement call. It is 3 bits out of 256, and it comes from the same hardware mixer as everything else, so it does not weaken the seed. But it does mean the device is not purely computing a checksum, which is what the docs imply and what a dice-only user is trying to achieve.

Two things worth deciding

  1. Docs. "A valid final word" is accurate but incomplete. Worth saying the device selects one of the 8 valid completions at random.
  2. Feature. Offering all 8 candidates, or a way to supply the 3 bits, would satisfy users who want the device to contribute nothing. Design question rather than a bug.

Related

This same line is covered from two other angles: the return value of random_bytes is discarded here (SFT-7320), and the 4-byte buffer receives no secure element contribution (SFT-7321). Also raised independently in the AnchorWatch/Kimi report as ENT-003 and the Mike Andrews report as Finding 6, both tracked in SFT-7330 and SFT-7344.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions