Skip to content

BIP93: Refactor format and seed sections - #2285

Open
BenWestgate wants to merge 5 commits into
bitcoin:masterfrom
BenWestgate:bip93-master-seed-refactor
Open

BenWestgate wants to merge 5 commits into
bitcoin:masterfrom
BenWestgate:bip93-master-seed-refactor

Conversation

@BenWestgate

@BenWestgate BenWestgate commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

BIP 93 is easier to follow if the specification goes from the general format to its specific uses:

  1. codex32 format and checksums
  2. optional secret sharing
  3. BIP-0032 master seed encoding

This PR reorganizes the specification in that order.

It also removes duplicated explanations, gives the encoding and decoding helpers their own heading after the checksums, makes the seed-size units consistent, and adds a retrospective changelog and Version: 0.2.1 preamble field.

Behavior neutral changes only. The inline Python is unchanged apart from where it sits.

Group the regular and long checksum definitions in the codex32 format
section. Move the master-seed application profile to the end of the
specification and keep seed-specific checksum motivation in the
rationale.

This is a behavior-neutral organization change on top of the bitcoin#2258
profile commit.
@BenWestgate

Copy link
Copy Markdown
Contributor Author

eb7bb6c is ready for review.

Most of the PR description is extra seasoning or nice-to-have house-keeping before I rebase #2040 on this PR.

@roconnor if you'd like you can propose a bits vs bytes consistency fixup commit and I will add it to this PR.

I'll add commits for any cACK'd idea in the description

@apoelstra

apoelstra commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

A bits vs bytes consistency fixup commit; and

I wouldn't mind adding this here in a separate commit. Up to you.

A cautionary warning to not convert bytes to shares.

Let's defer to another PR. This might require some discussion about whether we should allow shares to bytes, whether we should allow bytes to shares if you're super careful, etc etc

Optional: a changelog [for #2258]

Yes please!

@apoelstra

Copy link
Copy Markdown
Contributor

In the existing text we say "String validity may be further restricted by specific applications, see Master seed format below.". This is a run-on sentence. Can we change the "," to a "." and capitalize See?

(This is unrelated to the current diff but this PR seems like we could fit it in here since you also fixed a couple other typos/formatting things.)

Lol @ the old text saying overwhelming (1 - 2^65) probability. without a negative sign in front of 65. Negative 2^65 probability is overwhelming!

Other than these nits eb7bb6c looks good to me. This PR has no functional changes and is easy to review.

@BenWestgate

Copy link
Copy Markdown
Contributor Author

bits vs bytes belongs here, anything non-functional, really.

I will add a changelog and fix that run-on sentence. I dislike it too, too broad.
As far as I know, different applications may only restrict validity by: HRP, payload_len and secret payload construction.
We fixed, checksum selection and probably header so codex32_decode(codex) works well enough to say what the application even is.

without a negative sign in front of 65.

I added the correct number (but as base10 exponent) back in BenWestgate@98935ff we repeat numbers and phrases a lot in this standard.
Should I add a de-duplication commit here? This probably comes before the bits vs bytes commit as I know some of those sentences are nearby duplicates.

Did you ACK this TOC?

==Specification==
===codex32===
====Error Correction====
===SSSS-awareness===
====Generating Shares====
====Recovering Secret====
===Master seed format===

Doc should start with shares if they want to do secret sharing (and read this section), as they are the most general codex32 string, they all have the same random payloads (unless we want to permit SLIP-0039 style constraints), while secrets are already application specific decoded/encoded.

@apoelstra

Copy link
Copy Markdown
Contributor

Should I add a de-duplication commit here?

Yeah, I think that's a good idea.

Did you ACK this TOC?

Yep.

BenWestgate added a commit to BenWestgate/bips that referenced this pull request Sep 14, 2026
Keep the common format rules and checksum properties in one place, and replace the broad application-validity sentence with a concrete reference to the master seed requirements.

Remove the redundant symbol encoder and decoder examples. Preserve their validation rules in the format and master seed text, including the encoded-length restriction for both secrets and shares. Retained checksum and interpolation code is unchanged.

Checked retained Python ASTs against eb7bb6c, all 36 valid and 55 invalid vector occurrences, all six size mappings, legacy sizes, 1024 header combinations, checksum boundaries, share recovery, and nonzero padding. Link-format, README table, and whitespace checks pass.

Refs: bitcoin#2258, bitcoin#2285
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Sep 14, 2026
Let readers implement unshared master seeds from the format and master
seed sections without reading the secret sharing procedures. Keep the
common header and unshared-secret rules under codex32, and group share
generation and recovery under SSSS-awareness.

Give checksum and error correction one TOC entry each. Use bold labels
for the individual checksums and generation cases, and preserve both
MediaWiki anchors and GitHub permalinks for demoted headings. Put the
interpolation helpers with generation and its recovery wrapper afterward.
Retained executable code is unchanged.

Checked the retained Python ASTs, existing valid/invalid vectors, size
mappings, header combinations, checksum boundaries, recovery, and padding.
Inspected the rendered TOC and table and checked fragment targets.
Link-format, README table, and whitespace checks pass.

Refs: bitcoin#2285
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Sep 14, 2026
Describe seed sizes in bits in the encoding instructions, checksum
rationale, and retained-size list, matching generation and the vectors.
Keep bytes for decoded output and the historical contiguous byte-size
range, and retain both units in the size table.

The supported sizes and all numeric constraints are unchanged. The
existing rationale already explains that BIP39 produces 512-bit seeds.

Checked retained Python ASTs, all existing vector occurrences, size
mappings, header combinations, checksum boundaries, recovery, padding,
and rendered markup. Link-format, README table, and whitespace checks
pass.

Refs: bitcoin#2258, bitcoin#2285
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Sep 14, 2026
Add a reverse-chronological draft changelog and matching Version header
so readers can distinguish the earlier checksum-boundary and seed-size
changes from this behavior-neutral reorganization.

Assign retrospective versions to significant revisions and use their
upstream integration dates, rather than individual patch author dates.
Keep the Draft status and BSD-3-Clause license unchanged.

Checked the historical entries against first-parent upstream history,
the version and date ordering, and the metadata-only diff. Python ASTs,
existing vectors, size and checksum boundaries, header combinations,
recovery, padding, rendered markup, link formatting, README table, and
whitespace checks pass.

Refs: bitcoin#2258, bitcoin#2285
@baslabofhd777-lab

This comment has been minimized.

BenWestgate added a commit to BenWestgate/bips that referenced this pull request Sep 14, 2026
Define the integer-list representation once in the SSSS-awareness
introduction, before either procedure needs it. Move the unchanged
interpolation helpers there too, so recovery does not depend on code
inside Generating shares. Describe interpolation's arguments and result
beside its definition and refer to the shared representation from both
generation and recovery.

State that both checksum variants use the same procedures without an
early reference to the interpolation function. Label the existing casing
rules and remove the unnecessary word "workflows" from the rationale.
No algorithms, validity conditions, version, or changelog entries change.

Checked all Python blocks are byte-identical and that vectors, procedure
conditions, casing rules, headings, anchors, and metadata are unchanged.
Sixteen recovery cases pass using only the shared introduction and
recovery snippets, covering regular and long checksums. Existing vector,
size, header, checksum-boundary, recovery, and padding checks also pass.
Local rendering, link formatting, README table, and whitespace checks
pass; the casing label does not add a TOC entry.

Refs: bitcoin#2285
@BenWestgate

This comment was marked as outdated.

@jonatack jonatack added the Proposed BIP modification PR by non-owner to update BIP content label Sep 14, 2026
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Sep 22, 2026
Specify the human-readable part as in BIP-0173 instead of requiring
"ms", so other applications, such as the registered "cl", can use the
codex32 format. Master seeds and their shares keep "ms".

Pass the human-readable part to the checksum functions and cover its
BIP-0173 expansion, which already counts toward the checksum length
limits. Rename the ms32 functions and constants that now serve every
human-readable part to codex32. Results for "ms" are unchanged.

Require every share in a set to have the same human-readable part, state
that the interpolation helpers do not check the set conditions, and limit
fresh-secret generation to applications that accept every payload.
Implementations should not correct the human-readable part unless its
application specifies how.

Checked that the new functions match the previous ms32 functions for
"ms" on random data of every length from 0 to 1029, that interpolation
is unchanged, and that all 36 valid and 55 invalid vector occurrences
decode as before. Link-format, README table, and whitespace checks pass.

Refs: bitcoin#2040, bitcoin#2258, bitcoin#2285

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Sep 22, 2026
Specify the human-readable part as in BIP-0173 instead of requiring
"ms", so other applications, such as the registered "cl", can use the
codex32 format. Master seeds and their shares keep "ms".

Pass the human-readable part to the checksum functions and cover its
BIP-0173 expansion, which already counts toward the checksum length
limits. Rename the ms32 functions and constants that now serve every
human-readable part to codex32. Results for "ms" are unchanged.

Require every share in a set to have the same human-readable part, state
that the interpolation helpers do not check the set conditions, and limit
fresh-secret generation to applications that accept every payload.
Implementations should not correct the human-readable part unless its
application specifies how.

Checked that the new functions match the previous ms32 functions for
"ms" on random data parts of every length from 0 to 1029 symbols
(expanded lengths 5 to 1034), covering both checksums, the 94-95 gap,
and lengths past 1023. Also checked that interpolation is unchanged and
that all 36 valid and 55 invalid vector occurrences decode as before.
Link-format, README table, and whitespace checks pass.

Refs: bitcoin#2040, bitcoin#2258, bitcoin#2285

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@BenWestgate

This comment was marked as outdated.

BenWestgate added a commit to BenWestgate/bips that referenced this pull request Sep 22, 2026
Specify the human-readable part as in BIP-0173 instead of requiring
"ms", so other applications, such as the registered "cl", can use the
codex32 format. Master seeds and their shares keep "ms".

Pass the human-readable part to the checksum functions and cover its
BIP-0173 expansion, which already counts toward the checksum length
limits. Rename the ms32 functions and constants that now serve every
human-readable part to codex32. Results for "ms" are unchanged.

Require every share in a set to have the same human-readable part, state
that the interpolation helpers do not check the set conditions, and limit
fresh-secret generation to applications that accept every payload.
Implementations should not correct the human-readable part unless its
application specifies how.

Checked that the new functions match the previous ms32 functions for
"ms" on random data parts of every length from 0 to 1029 symbols
(expanded lengths 5 to 1034), covering both checksums, the 94-95 gap,
and lengths past 1023. Also checked that interpolation is unchanged and
that all 36 valid and 55 invalid vector occurrences decode as before.
Link-format, README table, and whitespace checks pass.

Refs: bitcoin#2040, bitcoin#2258, bitcoin#2285

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Sep 22, 2026
Specify the human-readable part as in BIP-0173 instead of requiring
"ms", so other applications, such as the registered "cl", can use the
codex32 format. Master seeds and their shares keep "ms".

Pass the human-readable part to the checksum functions and cover its
BIP-0173 expansion, which already counts toward the checksum length
limits. Rename the ms32 functions and constants that now serve every
human-readable part to codex32. Results for "ms" are unchanged.

Require every share in a set to have the same human-readable part, state
that the interpolation helpers do not check the set conditions, and limit
fresh-secret generation to applications that accept every payload, with
rejection sampling allowed for those that do not. Implementations should
not correct the human-readable part unless its application specifies how.

Checked that the new functions match the previous ms32 functions for
"ms" on random data parts of every length from 0 to 1029 symbols
(expanded lengths 5 to 1034), covering both checksums, the 94-95 gap,
and lengths past 1023. Also checked that interpolation is unchanged and
that all 36 valid and 55 invalid vector occurrences decode as before.
Link-format, README table, and whitespace checks pass.

Refs: bitcoin#2040, bitcoin#2258, bitcoin#2285
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Oct 1, 2026
Specify the human-readable part as in BIP-0173 instead of requiring
"ms", so other applications, such as the registered "cl", can use the
codex32 format. Master seeds and their shares keep "ms".

Pass the human-readable part to the checksum functions and cover its
BIP-0173 expansion, which already counts toward the checksum length
limits. Rename the ms32 functions and constants that now serve every
human-readable part to codex32. Results for "ms" are unchanged.

Require every share in a set to have the same human-readable part, state
that the interpolation helpers do not check the set conditions, and limit
fresh-secret generation to applications that accept every payload, with
rejection sampling allowed for those that do not. Implementations should
not correct the human-readable part unless its application specifies how.

Update the existing invalid-vector classifications for generalized human-
readable parts. Add vectors for a Core Lightning "cl" secret, an
11-character human-readable part requiring the long checksum, the
83-character maximum, the 94-95 expanded-length gap, an uppercase human-
readable-part checksum, and an overlong human-readable part.

Checked the checksum functions against the previous ms32 functions for
"ms" across data-part lengths 0 through 1029, and checked interpolation
is unchanged. Checked every new vector with the specification's Python
code and python-codex32, and checked each invalid group fails for its
stated reason. Link-format, README table, and whitespace checks pass.

Refs: bitcoin#2040, bitcoin#2258, bitcoin#2285
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Oct 22, 2026
Keep the common format rules and checksum properties in one place, and replace the broad application-validity sentence with a concrete reference to the master seed requirements.

Retained checksum, encoding, decoding and interpolation code is unchanged.

Checked retained Python ASTs against eb7bb6c, all 36 valid and 55 invalid vector occurrences, all six size mappings, legacy sizes, 1024 header combinations, checksum boundaries, share recovery, and nonzero padding. Link-format, README table, and whitespace checks pass.

Refs: bitcoin#2258, bitcoin#2285
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Oct 22, 2026
Let readers implement unshared master seeds from the format and master
seed sections without reading the secret sharing procedures. Keep the
common header and unshared-secret rules under codex32, and group share
generation and recovery under SSSS-awareness.

Give checksum, encoding and decoding, and error correction one TOC entry
each. Put ms32_encode and ms32_decode under Encoding and decoding, after
both checksums, so every function they call is defined above them. Use
bold labels for the individual checksums and generation cases, and
preserve both MediaWiki anchors and GitHub permalinks for demoted
headings.

Define the integer-list representation once in the SSSS-awareness
introduction, with the interpolation helpers, so generation and
recovery both refer to it and recovery does not depend on code inside
Generating shares. State that both checksum variants use the same
procedures. Label the existing casing rules, say "shared secret" for
the secret the shares encode, and remove the unnecessary word
"workflows" from the rationale.

Retained executable code is unchanged.

Checked the retained Python ASTs, existing valid/invalid vectors, size
mappings, header combinations, checksum boundaries, recovery, and padding.
Inspected the rendered TOC and table and checked fragment targets.
Link-format, README table, and whitespace checks pass.

Refs: bitcoin#2285
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Oct 22, 2026
Describe seed sizes in bits in the encoding instructions, checksum
rationale, and retained-size list, matching generation and the vectors.
Keep bytes for decoded output and the historical contiguous byte-size
range, and retain both units in the size table.

The supported sizes and all numeric constraints are unchanged. The
existing rationale already explains that BIP39 produces 512-bit seeds.

Checked retained Python ASTs, all existing vector occurrences, size
mappings, header combinations, checksum boundaries, recovery, padding,
and rendered markup. Link-format, README table, and whitespace checks
pass.

Refs: bitcoin#2258, bitcoin#2285
@BenWestgate
BenWestgate force-pushed the bip93-master-seed-refactor branch from 1978ac2 to da7a469 Compare October 22, 2026 20:40
BenWestgate added a commit to BenWestgate/bips that referenced this pull request Oct 22, 2026
Add a reverse-chronological draft changelog and matching Version header
so readers can distinguish the earlier checksum-boundary and seed-size
changes from this behavior-neutral reorganization.

Assign retrospective versions to significant revisions and use their
upstream integration dates, rather than individual patch author dates.
Keep the Draft status and BSD-3-Clause license unchanged.

Checked the historical entries against first-parent upstream history,
the version and date ordering, and the metadata-only diff. Python ASTs,
existing vectors, size and checksum boundaries, header combinations,
recovery, padding, rendered markup, link formatting, README table, and
whitespace checks pass.

Refs: bitcoin#2258, bitcoin#2285
@BenWestgate
BenWestgate force-pushed the bip93-master-seed-refactor branch from da7a469 to b9601b0 Compare October 29, 2026 06:52
State common format rules and checksum properties once. Refer to the
master seed requirements for application-specific validation.
Order the specification as format, secret sharing, then master seeds.
Place shared helpers before their callers and define the interpolation
data representation once. Preserve existing section links.
Use bits for seed sizes and bytes for decoded output. Supported sizes
are unchanged.
Add Version 0.2.1 and a changelog. Date earlier revisions by their
upstream integration dates.
@BenWestgate
BenWestgate force-pushed the bip93-master-seed-refactor branch from b9601b0 to ecbed1c Compare October 29, 2026 07:07
@BenWestgate

BenWestgate commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor Author

@apoelstra I force-pushed. eb7bb6c is unchanged and the follow-ups are now four commits:

  • 732b0bf: deduplicate specification +16/-33
  • 1af7a01: reorganize sections and headings
  • 89b1630: clarify seed-size units +3/-3
  • ecbed1c: add revision history and version +21

The Python, behavior and vectors are identical to master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Proposed BIP modification PR by non-owner to update BIP content

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants