Skip to content

Conversation

@BenWestgate
Copy link
Contributor

@BenWestgate BenWestgate commented Oct 17, 2025

Closes #64

This is a draft of unshared secrets generation support.

Summary: Updated to discourage weird bitlengths, improve error correction handling. Added details on generation support for codex32 secrets.

Guidance for codex32 share sets generation can come in a later PR as it will depend largely this seed export guidance.

I covered string display and confirmation, from my experience designing these and receiving user feedback.

Confirm section presents two methods depending on keyboard available:

  1. Full-verification method I used in Bails that is very easy and well liked by beta testers, and
  2. Partial-verification method Blockstream used in Jade, borrowed near verbatim from: https://github.com/Blockstream/Jade/blob/690c8b1c5f9ccaf18954111a6ee8e124f2b75eec/main/process/mnemonic.c#L269-L398
  • Essentially, change only word-list and Jade can display and confirm 128-bit codex32 strings just as well as bip39.

Missing/TBD:

  • BIP85 app (if it merges).
  • Reference GUI
    • I have had for years a complete reference Gtk GUI of the "Full confirm" dialog, Bails uses it. I'll try to package that with the display and import views to make a PyPI codex32-gui I package for devs to play with.
  • Reference CLI/Library
    • I wrote a codex32 PyPI library, my apologies if I was not supposed to take this name. The implementation is at least as clean as the rust in this repo and passes all BIP93 test vectors.

Updated import support specifications for wallet seed lengths and error correction handling. Added details on generation support for codex32 secrets and share sets.
@BenWestgate BenWestgate changed the title WIP: Revise wallet import and add generation specifications WIP: Add generation specifications Oct 17, 2025
Clarified wallet behavior for invalid headers and checksums, improved error correction guidance, and refined display and confirmation processes for codex32 strings. Removed SSS section for brevity.
@BenWestgate BenWestgate marked this pull request as ready for review October 19, 2025 03:23
@BenWestgate BenWestgate changed the title WIP: Add generation specifications doc: Add unshared secret generation to wallets.md Oct 22, 2025
Refine guidance on generating unshared secrets and update codex32 secret backup process. Improve clarity on identifier policies and human-readable parts.
@BenWestgate
Copy link
Contributor Author

@roconnor-blockstream This is ready for review.

@roconnor-blockstream
Copy link
Collaborator

roconnor-blockstream commented Oct 24, 2025

I don't know if I'm quite ready to completely abandon 160-bit and 192-bit seeds just yet. Maybe I could be convinced.

@BenWestgate
Copy link
Contributor Author

BenWestgate commented Oct 24, 2025

I don't know if I'm quite ready to completely abandon 160-bit and 192-bit seeds just yet. Maybe I could be convinced.

We should discourage lengths too close they prevent insert/delete-correcting ECWs from assuming the correct valid length.

Lets start with the BIP39 lengths:

image

A 128-bit seed with 6-8 erroneous insertions can be corrected easily by a desktop, IF the insert-correcting ECW can assume 128-bit length. (removing 8 insertions has 1.6% chance of two solutions, 64% for 9.)

160-bit seeds MUST be discouraged as they can be mistaken for a 128-bit seed with a correctable amount of insertions.

A seed with 3 deletions can be corrected using your haskell impl to check every combo of 3 positions as erasures. (3 deletions has <6% chance of two solutions, ~100% for 4+.)

Now say we have an invalid but correctable length string, for software to know whether to try insertions or deletions, the next recommended length after 128-bits can be 128 + 8 * 5 + 3 * 5 = 183 < bitlength < 201 = 256 - 8 * 5 - 3 * 5.

So 128, 192, 256 and 512 bitlengths are safe to recommended.
160, 224 and others must be discouraged since they complicate insert/delete ECWs assumptions about length.

@BenWestgate BenWestgate marked this pull request as draft November 25, 2025 18:55
@BenWestgate
Copy link
Contributor Author

BenWestgate commented Nov 25, 2025

As suggested in bitcoin/bips#2040 (comment):

Lets define deterministic encoding defaults (identifier, padding, output share indices order) here and/or here first.

I think encoders/wallets SHOULD:

  1. select padding using a CRC-w where: w = pad_bits_needed, poly = 1 << w | 3, init = 1, const = 1 << w - 1, refIn = false, and refOut = false.
  2. use the first 4 characters of the bech32-encoded bip32 masterkey fingerprint as the secret seed identifier if unspecified.
  3. deterministically shuffle the n share indices output.
    • Previously the bip85 app shuffled share indices but reviewers wanted it to output single strings so it was removed.

@BenWestgate
Copy link
Contributor Author

@roconnor-blockstream, as for 160-bit seeds:

I do not think "ms" secret seeds MUST NOT use them, I am saying "ms" secret seeds SHOULD use bitlengths divisible by 64 bits to simplify "insert/delete"-correcting ECWs (IDC-ECW) assumptions about valid lengths."

3. SHOULD This word, or the adjective "RECOMMENDED", mean that there
may exist valid reasons in particular circumstances to ignore a
particular item, but the full implications must be understood and
carefully weighed before choosing a different course.

The implications of using 160-bits would not be the wallet rejects your valid secret seed. But rather that invalid 160-bit entries might receive 128-bit master seed correction suggestions from an IDC-ECW.

As I think "MS" IDC-ECWs MAY not check this length as their correction performance is maximized by a wider spacing.

This means 160-bit seeds are not interoperable with all IDC-ECW.

This RECOMMENDATION impacts the lengths our generators SHOULD generate. As we don't want to produce seed lengths that harm ECW performance if they choose to support them.

Again valid reasons exist to deviate, both on generation and IDC-ECW assumptions about lengths but improving error correction seems more important than not discouraging 160-bit, when 192-bit can be used instead.

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.

Suggest standard implementation for electronic share set generation

2 participants