[BIP Proposal] Add BIP-0093 (Codex32) as application to BIP-0085

214 views
Skip to first unread message

Ben Westgate

unread,
Aug 31, 2025, 6:29:46 PM (7 days ago) Aug 31
to Bitcoin Development Mailing List

Hello bitcoin-dev,

I’m Ben Westgate, a contributor interested in deterministic wallet backups and seed management.

Per BIP-0002, I propose listing BIP-0093 (codex32) as an application of
BIP-0085 (Deterministic Entropy from BIP32 Keychains), similar to the existing BIP39 application. This allows wallets to derive codex32 backups from BIP-0032 master keys.

Summary

  • Application number: 93'

  • Derivation path: m/83696968'/93'/{hrp}'/{threshold}'/{n}'/{byte_length}'/{id0}'/{id1}'/{id2}'/{id3}'/{index}'

Codex32, defined in BIP-93, is a human-readable encoding with checksumming and share indexing designed for SSS backups of BIP-0032 seeds. This PR proposes a deterministic way to generate codex32 strings using BIP-85.

Rationale

  • Mirrors the existing BIP-85 application for BIP-39.

  • Codex32 offers error correction, hand verification, identifiers, and secret sharing features compared to BIP-39.

  • Adds a standardized way for wallets to generate codex32 backups from BIP-85-derived entropy

  • Test vectors and reference implementation are linked to in the PR.

Risks and alternatives

  • Wallet adoption of codex32 is still limited, though a draft PR #32652 for importing codex32 strings to Bitcoin Core has support.

  • Codex32 implementers could use the BIP-85 dice application, but defining a direct application improves interoperability.

PR: https://github.com/bitcoin/bips/compare/master...BenWestgate:bips:codex32

Feedback is welcome.

Best regards,
Ben Westgate

Javier Mateos

unread,
Sep 1, 2025, 7:34:39 AM (7 days ago) Sep 1
to Bitcoin Development Mailing List
Hi Ben,

Thank you for your proposal to integrate BIP-0093 (codex32) as an application within BIP-0085

Reviewing the specification,  I believe I see two areas where we could improve clarity for implementers:

1) The DRNG→5-bit extraction process could benefit from explicit pseudocode to avoid implementation variations
2) The rule 'threshold == 0 implies n == 1' currently appears as a note but could be clearer as a normative requirement"

Best Regards,
Javier Mateos

Ben Westgate

unread,
Sep 1, 2025, 7:15:11 PM (6 days ago) Sep 1
to Bitcoin Development Mailing List

Hi Javier,

Thank you for your feedback.

I added pseudocode for the character value selection. I added a column and row to the n table to clarify the t==0 constraint on n, removed the notes and in the unshared secret section made the normative statement: 'When threshold == "0", n MUST be 1 and the output is a codex32 secret.'

I’ve updated the PR with these changes and would appreciate your review.

Commit: https://github.com/BenWestgate/bips/commit/fa6e9788bf04d271792ed4ea89a112d12284ef02

Best regards, Ben Westgate

Javier Mateos

unread,
Sep 2, 2025, 5:37:20 AM (6 days ago) Sep 2
to Bitcoin Development Mailing List

Hi Ben,

Thank you for implementing those changes so promptly. I reviewed the commit and the updates address both concerns effectively.

These changes should ensure consistent implementations across different codex32 tooling that uses BIP-85 derivation.

The proposal looks technically sound, follows BIP-85's established pattern for applications, and is supported by comprehensive test vectors and a reference implementation.

Looking forward to hearing feedback from other reviewers as well.

Best regards,
Javier Mateos

Ben Westgate

unread,
Sep 4, 2025, 12:50:57 PM (3 days ago) Sep 4
to Bitcoin Development Mailing List

Thanks Javier for confirming my updates address your concerns,

Andrew Poelstra and Russell O'Connor gave feedback on the bip85 codex32 application, they:
- support it for recoverable "uncle-Jim"-style child codex32 strings for forgetful relatives.
- prefer wallets generate fresh initial strings by directly encoding RNG entropy to maintain information-theoretic security.
- see value in it to stretch entropy when users won’t provide enough for direct encoding but don't trust their hRNG.
- consider codex32 backups for a bip85 root keys a very good idea.

I welcome further feedback on the proposed before I submit it as a PR: https://github.com/bitcoin/bips/compare/master...BenWestgate:bips:codex32

Best regards, Ben Westgate


Aneesh Karve

unread,
Sep 7, 2025, 9:09:27 PM (3 hours ago) Sep 7
to Bitcoin Development Mailing List
Howdy, a few issues to address for the benefit of future implementers:
  1. The reference implementation should be a PR to the 1.3.0 implementation (I'll help) so we don't confuse the history or introduce compatibility issues. 1.3.0 brings a lot more unit tests, composability, etc. Ethan's original repo, which the proposed reference hangs off, has been stagnant for about 4 years, doesn't implement the fixes in 1.3.0, etc.
  2. The usage of the hrp (human readable prefix) is unclear to me. Traditional path segments are integers and in the examples so is the hrp but it's also defaulted to"ms" and not clear for implementers how the path should be represented numerically if at all?
  3. Similarly the role, nature (relative to the SSSS), and programmatic structure of the identifiers (idX) is unclear.
2 & 3 should be easily addressed with small changes to the diff; I'd suggest breaking down and explaining each path segment more clearly.

Aneesh Karve

unread,
Sep 7, 2025, 9:09:31 PM (3 hours ago) Sep 7
to Bitcoin Development Mailing List
Regarding my comment on 'hrp' I do see you have a table for that, which is clear enough. It's intended as an enum, although I don't see "cl" in BIP-93, the same way I see "ms"?

Is there anything we can do to simplify or clarify the derivation paths? They are not "wrong" per se but these will be the longest derivation paths in the BIP-85 spec and I'm wondering if there's room for "less is more" in the derivation path.

> Pseudocode: character_value = int.from_bytes(drng.read(1), "big") >> 3

This is sensible with respect to deriving a single bech32 character but here and in the description above the number of characters we are drawing could be clarified consistent with the "Bytes Length Table" and there also it should be clarified if this is bytes drawn or bytes retained or something else. It could further be clarified that all draws are from the same DRNG instance. For example, elsewhere in BIP-85 we pass the .read method (not an invocation) since in RSA key gen the number of draws is unknown ahead of time. In your case the number of draws is known but again the pseudocode should clarify how many draws or iterations to obtain a complete share or secret as a function of the derivation path segments.

Drawing and truncating a single byte per character is certainly clear to understand but I keep wondering if implementers shouldn't draw ((chars * 5) // 8) bytes in one shot? These bytes aren't expensive or anything but it's less iterations, less total reads, etc. If my suggestion becomes hard to read or write then feel free to keep as is.

On Thursday, September 4, 2025 at 9:50:57 AM UTC-7 Ben Westgate wrote:
Reply all
Reply to author
Forward
0 new messages