From 120c923647dcb7117dcaa1fa6a85a5ded7546a6e Mon Sep 17 00:00:00 2001 From: Ben Westgate Date: Thu, 20 Aug 2026 20:49:52 -0500 Subject: [PATCH 1/2] bip85: add codex32 application 93' Define a deterministic BIP85 derivation for canonical initial codex32 strings as specified by BIP93. Serialize the six-character codex32 header into the final hardened path element so each valid path identifies one canonical output for a fixed root key. Reserve profiles for future secret formats and define profile 0 for BIP32 master seeds using the ms HRP. Keep byte length and zero-padding rules specific to master seed construction while making random share payload construction common to assigned profiles. Include reproducible vectors for an unshared master seed and a threshold-2 initial basis. Organize the specification around master seeds and shares so the table of contents exposes the two output concepts while each example follows the existing BIP85 INPUT/OUTPUT style. --- bip-0085.mediawiki | 131 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index c6a7d2b8f3..1710833d2a 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -8,7 +8,7 @@ Type: Informational Assigned: 2020-03-20 License: BSD-2-Clause OR OPUBL-1.0 - Version: 2.1.0 + Version: 2.2.0 ==Abstract== @@ -223,6 +223,127 @@ OUTPUT: * DERIVED ENTROPY=ae131e2312cdc61331542efe0d1077bac5ea803adf24b313a4f0e48e9c51f37f * DERIVED BIP39 MNEMONIC=puppy ocean match cereal symbol another shed magic wrap hammer bulb intact gadget divorce twin tonight reason outdoor destroy simple truth cigar social volcano +===BIP93=== +Application number: 93' + +Generates canonical initial codex32 strings. + +The derivation path format is: + +m/83696968'/93'/{profile}'/{payload_len}'/{index}' + +{profile} selects the secret-payload construction and human-readable part. +Profile 0 uses the human-readable part ms. +An unassigned {profile} has no application-93 output. + +{payload_len} is the number of bech32 characters in the payload. + +For application 93, {index} is the 30-bit integer serialization +of the six-character codex32 header. + +Let u5(c) be the 5-bit value of c +in the bech32 character table from BIP173. + +
+header_chars = threshold_char || identifier || share_idx
+
+index =
+    u5(threshold_char) << 25 |
+    u5(identifier[0])  << 20 |
+    u5(identifier[1])  << 15 |
+    u5(identifier[2])  << 10 |
+    u5(identifier[3])  <<  5 |
+    u5(share_idx)
+
+ +{index} MUST be less than 2^30 +and decode to a valid codex32 header. + +At threshold 0, the canonical initial basis consists of +share_idx = s. +Otherwise, for threshold k, the canonical initial basis consists of +the first k share indices in the sequence a, +c, d, e, f, +g, h, j, k. + +A path whose header is outside the canonical initial basis +has no application-93 output. + +For a fixed BIP85 root key, each valid fully specified path MUST produce exactly one +canonical initial codex32 string. +Each resulting string MUST correspond to exactly one valid fully specified path. + +To generate a canonical initial codex32 string, +create a BIP85 DRNG whose seed is the derived entropy. +The constructions below produce exactly 5 * payload_len payload bits. +Re-arrange these bits into groups of 5 and translate them to characters +using the bech32 character table from BIP173. +Assemble the output from the human-readable part selected by {profile}, +the header encoded by {index}, and the payload. +Generate the checksum as specified by BIP93. +The application-93 output MUST be lowercase. + +====Master seed==== + +Profile 0 encodes a BIP32 HD master seed +using the BIP93 master seed format. + +Let byte_len = floor(5 * payload_len / 8) +and pad_len = (5 * payload_len) mod 8. + +{payload_len} MUST satisfy 16 ≤ byte_len ≤ 64 +and pad_len ≤ 4. + +Read byte_len bytes from the DRNG +and append pad_len zero bits. + +INPUT: +* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb +* HEADER: 0secrs +* INDEX: 520937584 +* PATH: m/83696968'/93'/0'/26'/520937584' + +OUTPUT: +* DERIVED ENTROPY=a95e647c44382b2c6f7aa9f6f57461a42a2f77af83f0b23ca305f5c3076ca518c237cd41e56e9d8c7e7e8e0dd6c22d4deae2dda8931c18ffbe6cc2e097cf6116 +* DERIVED MASTER SEED=cba51fa2f647f538872fbfbb9271e420 +* DERIVED CODEX32 SECRET=ms10secrsewj3lghkgl6n3pe0h7aeyu0yyqlws7qlpv4takg + +Here payload_len = 26, byte_len = 16, +and pad_len = 2. + +====Shares==== + +For a share in the canonical initial basis, +read ceil(5 * payload_len / 8) bytes from the DRNG +and keep the first 5 * payload_len bits, most significant bit first. + +Additional shares are obtained by BIP93 interpolation. +A canonical initial basis can be generated from one or multiple BIP85 root keys. + +The following outputs form a threshold-2 initial basis. + +INPUT: +* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb +* PAYLOAD LENGTH: 26 +* HEADER: 2shara +* INDEX: 353105021 +* PATH: m/83696968'/93'/0'/26'/353105021' + +OUTPUT: +* DERIVED ENTROPY=c95df7678fd370b68c419e694c04ed65a86df7368c0371bf3310cc9f5ed474ae02a8eeab8f5c64e7fadbccde17cfd68275570a88039c242c6b2053b13aa764f2 +* DERIVED CODEX32 SHARE=ms12sharan26hdftg98lnz68h3p2c796vyvc3w06df5kav9m + +INPUT: +* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb +* PAYLOAD LENGTH: 26 +* HEADER: 2sharc +* INDEX: 353105016 +* PATH: m/83696968'/93'/0'/26'/353105016' + +OUTPUT: +* DERIVED ENTROPY=be19028ae7a81c558c9fe9f461ceddda629318a6eb1ff309cd408b0e3cd4a031788117f50d551ff38200e96afb5d14c443b7bb91e05e190b360751cb81bd6750 +* DERIVED CODEX32 SHARE=ms12sharcjlku4rmnudpgw7h8yup99c8yjk6qe7fnm4nlla4 + ===HD-Seed WIF=== Application number: 2' @@ -481,7 +602,7 @@ This specification relies on BIP32 but is agnostic to how the BIP32 root key is ==References== -BIP32, BIP39, +BIP32, BIP39, BIP93, BIP173, [https://github.com/nostr-protocol/nips/blob/master/01.md NIP-01], [https://github.com/nostr-protocol/nips/blob/master/06.md NIP-06], [https://github.com/nostr-protocol/nips/blob/master/19.md NIP-19] @@ -492,6 +613,12 @@ BIP32, BIP39, ==Changelog== +===2.2.0 (2026-08-20)=== + +====Added==== + +* codex32 application 93' + ===2.1.0 (2026-08-02)=== ====Added==== From 294108c9237a8e5b698d555c65c9a8ba839de9c4 Mon Sep 17 00:00:00 2001 From: Ben Westgate Date: Thu, 3 Sep 2026 13:10:03 -0500 Subject: [PATCH 2/2] bip85: Update {payload_len} reqs for application '93 Clarify {payload_len} requirements are in relation to the selected {profile}. --- bip-0085.mediawiki | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 1710833d2a..47e0282d91 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -236,7 +236,7 @@ The derivation path format is: Profile 0 uses the human-readable part ms. An unassigned {profile} has no application-93 output. -{payload_len} is the number of bech32 characters in the payload. +{payload_len} is the number of bech32 characters in the payload and MUST be valid for the selected {profile}. For application 93, {index} is the 30-bit integer serialization of the six-character codex32 header. @@ -291,9 +291,6 @@ using the BIP93 master seed format. Let byte_len = floor(5 * payload_len / 8) and pad_len = (5 * payload_len) mod 8. -{payload_len} MUST satisfy 16 ≤ byte_len ≤ 64 -and pad_len ≤ 4. - Read byte_len bytes from the DRNG and append pad_len zero bits.