Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add function to calculate checksum and last word of a manually generated mnemonic #7

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

JosephGoulden
Copy link

If someone generates a mnemonic manually (e.g. picking words from a hat) they still need to calculate the checksum and append the last work of their mnemonic. The convention is to pick the first (alphabetically) valid checksum word, see Seedpicker and Human-RNG.

I think it would be convenient to include that function in this library as well.

@stevenroose
Copy link
Collaborator

Aha, that's a good feature. I'm waiting on some review for the no-std refactor, but when that lands, I can try rebase this or add this function afterwards. It won't be able to rebase this simply, because the entire internals change.

@stevenroose
Copy link
Collaborator

@JosephGoulden would you mind to update this MR? Otherwise I might give it a go.

@JosephGoulden
Copy link
Author

Hi. I've updated it, let me know what you think.

src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK c0b9d39

@stevenroose
Copy link
Collaborator

Hmm, thinking about this a little. The table from bip39 shows this:

|  ENT  | CS | ENT+CS |  MS  |
+-------+----+--------+------+
|  128  |  4 |   132  |  12  |
|  160  |  5 |   165  |  15  |
|  192  |  6 |   198  |  18  |
|  224  |  7 |   231  |  21  |
|  256  |  8 |   264  |  24  |

Every word is 11 bits, so the checksum ranges from 4 to 8 bits. Which is always less than 11 bits. So for every possible mnemonic length, the last word will still contain part of the entropy and not just checksum. So it's possible that there's two different valid last words that actually correspond to different entropies. Furthermore, since the seed is not generated from the entropy, but from the mnemonic, even if the last word was purely checksum based, you could still have different valid wallets for the same n-1 first words.

So this feature seems a little tricky to me. What kind of scenario do you envision this to be used in? I guess a safe way to use this that I can think of would be to manually generate the first n-1 words (how? 😅) and then give up some entropy in return for a valid checksum to be provided. But the naming of the method can be misleading.. "Finalize" or "complete" might imply that the result will be the only valid result. Maybe we could better word this in the API. Or provide an iterator over the possible correct resulting mnemonics, so that it's pretty clear that there are multiple..

@pezcore
Copy link
Contributor

pezcore commented Jan 29, 2024

I'm not a huge fan of this. The last word of a BIP39 Mnemonic encodes both the checksum and some entropy. Using a deterministic method for evaluating the last word given the first n-1 words removes entropy from the final mnemonic and users should never be allowed to do that because it weakens the security of the mnemonic. All BIP39 Mnemonic generators should only generate mnemonics containing the full entropy for the given word count as per the spec. They should never silently return mnemonics that appear valid but actually contain less entropy than the spec.

@tcharding
Copy link
Member

After reading the two concerns above I'd like to please rescind my ack.

@marimes
Copy link

marimes commented Apr 4, 2024

Do you know if this has been implemented somewhere? I could use such a function well; the function could return an array of all possible checksum words. One application is to use this function in combination with https://seedsticks.org/.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants