From d3512bdcef9b5ef89cf4f321c9b5958f2f45dd82 Mon Sep 17 00:00:00 2001 From: ethicnology Date: Fri, 20 Mar 2026 12:54:13 +0000 Subject: [PATCH 1/7] feat(BIP-85): add Nostr application 86' --- bip-0085.mediawiki | 54 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index b0f00abbef..24a35cd60c 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -423,6 +423,52 @@ OUTPUT * DERIVED ENTROPY=5e41f8f5d5d9ac09a20b8a5797a3172b28c806aead00d27e36609e2dd116a59176a738804236586f668da8a51b90c708a4226d7f92259c69f64c51124b6f6cd2 * DERIVED ROLLS=1,0,0,2,0,1,5,5,2,4 +===Nostr=== + +Application number: 86' + +The application number is the sum of the alphabetical positions of the letters in Nostr (n=14 + o=15 + s=19 + t=20 + r=18) to avoid the confusion with NIP06. + +The derivation path format is: m/83696968'/86'/{identity}'/{account}' + +Uses the entropy as a Nostr private key. + +Identity index 0' is reserved for future protocol use. +Account index 0' is reserved across all identities for key management operations. +Usable keys start at identity >= 1' and account >= 1'. + +The resulting 32-byte private key is Bech32 encoded as an nsec per NIP19. + +====identity=1, account=1==== + +INPUT: +* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb +* PATH: m/83696968'/86'/1'/1' + +OUTPUT +* DERIVED ENTROPY=7f3313b1bdeacc4f395c666b473982550cdc66c225fd7e7b0f5d11d33cddde31 +* DERIVED NSEC=nsec10ue38vdaatxy7w2uve45wwvz25xdcekzyh7hu7c0t5gax0xamccsyuyesn + +====identity=1, account=2==== + +INPUT: +* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb +* PATH: m/83696968'/86'/1'/2' + +OUTPUT +* DERIVED ENTROPY=41fbfba9227f7d261ccb90f61264fd0b38e1f762108c31135f8fc138329594ff +* DERIVED NSEC=nsec1g8alh2fz0a7jv8xtjrmpye8apvuwramzzzxrzy6l3lqnsv54jnlsuxjsql + +====identity=2, account=1==== + +INPUT: +* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb +* PATH: m/83696968'/86'/2'/1' + +OUTPUT +* DERIVED ENTROPY=a159a41860a18457855511334a3c813430468ec3c1ef17700d4917d0e881a45a +* DERIVED NSEC=nsec159v6gxrq5xz90p24zye550ypxscydrkrc8h3wuqdfytap6yp53dq5gdpd6 + ==Backwards Compatibility== This specification is not backwards compatible with any other existing specification. @@ -431,7 +477,7 @@ This specification relies on BIP32 but is agnostic to how the BIP32 root key is ==References== -BIP32, BIP39 +BIP32, BIP39, [https://github.com/nostr-protocol/nips/blob/master/01.md NIP01], [https://github.com/nostr-protocol/nips/blob/master/06.md NIP06], [https://github.com/nostr-protocol/nips/blob/master/19.md NIP19] ==Reference Implementations== @@ -441,6 +487,12 @@ BIP32, BIP39 ==Changelog== +===2.1.0=== + +====Added==== + +* Nostr application 86' + ===2.0.0 (2025-09-19)=== ====Fixed==== From 371277d2e09a47c71aa8612d1e2351164e73babd Mon Sep 17 00:00:00 2001 From: ethicnology Date: Fri, 20 Mar 2026 13:23:08 +0000 Subject: [PATCH 2/7] fix: exclude nsec from typos --- .typos.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.typos.toml b/.typos.toml index e30e9e6bd4..2cf21bd17f 100644 --- a/.typos.toml +++ b/.typos.toml @@ -17,6 +17,7 @@ extend-ignore-re = [ "value: .*", "pqNTRUsign", "Strnad", + "nsec1.*", ] [default.extend-words] From cdf115e6c2ea8fd21c25084e3fdcf0f489358f0b Mon Sep 17 00:00:00 2001 From: ethicnology Date: Thu, 26 Mar 2026 19:52:01 +0000 Subject: [PATCH 3/7] BIP-85: use bold text for Nostr test vector labels to reduce TOC entries --- bip-0085.mediawiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 24a35cd60c..cf11aa86ee 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -439,7 +439,7 @@ Usable keys start at identity >= 1' and account >= 1'. The resulting 32-byte private key is Bech32 encoded as an nsec per NIP19. -====identity=1, account=1==== +'''identity=1, account=1''' INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb @@ -449,7 +449,7 @@ OUTPUT * DERIVED ENTROPY=7f3313b1bdeacc4f395c666b473982550cdc66c225fd7e7b0f5d11d33cddde31 * DERIVED NSEC=nsec10ue38vdaatxy7w2uve45wwvz25xdcekzyh7hu7c0t5gax0xamccsyuyesn -====identity=1, account=2==== +'''identity=1, account=2''' INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb @@ -459,7 +459,7 @@ OUTPUT * DERIVED ENTROPY=41fbfba9227f7d261ccb90f61264fd0b38e1f762108c31135f8fc138329594ff * DERIVED NSEC=nsec1g8alh2fz0a7jv8xtjrmpye8apvuwramzzzxrzy6l3lqnsv54jnlsuxjsql -====identity=2, account=1==== +'''identity=2, account=1''' INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb From 819db6a31aa715d7992560057f4bba9c4df3de6c Mon Sep 17 00:00:00 2001 From: ethicnology Date: Wed, 6 May 2026 14:43:01 +0300 Subject: [PATCH 4/7] refactor: according to @jonatack review --- .typos.toml | 2 +- bip-0085.mediawiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.typos.toml b/.typos.toml index 2cf21bd17f..02d7d5016a 100644 --- a/.typos.toml +++ b/.typos.toml @@ -16,7 +16,6 @@ extend-ignore-re = [ "prefix.*", "value: .*", "pqNTRUsign", - "Strnad", "nsec1.*", ] @@ -30,6 +29,7 @@ Atack = "Atack" Falke = "Falke" Meni = "Meni" Ono = "Ono" +Strnad = "Strnad" [files] extend-exclude = [ diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index cf11aa86ee..b08adaf4c7 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -429,7 +429,7 @@ Application number: 86' The application number is the sum of the alphabetical positions of the letters in Nostr (n=14 + o=15 + s=19 + t=20 + r=18) to avoid the confusion with NIP06. -The derivation path format is: m/83696968'/86'/{identity}'/{account}' +The derivation path format is: m/83696968'/86'/{identity}'/{account_index}' Uses the entropy as a Nostr private key. From 13f307b55e0beb3a3392244cce63af7e07942f15 Mon Sep 17 00:00:00 2001 From: ethicnology Date: Thu, 14 May 2026 10:47:06 +0000 Subject: [PATCH 5/7] BIP-86: rename Nostr application 86' to 9000', bump to 2.1.0, list rust-bip85 + dart-bip85-entropy reference implementations --- bip-0085.mediawiki | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index b08adaf4c7..2b08eb17f3 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.0.0 + Version: 2.1.0 ==Abstract== @@ -425,17 +425,17 @@ OUTPUT ===Nostr=== -Application number: 86' +Application number: 9000' -The application number is the sum of the alphabetical positions of the letters in Nostr (n=14 + o=15 + s=19 + t=20 + r=18) to avoid the confusion with NIP06. +9000 is the zip code of Funchal in Madeira, Portugal, where this specification was written during the Sovereign Engineering event. -The derivation path format is: m/83696968'/86'/{identity}'/{account_index}' +The derivation path format is: m/83696968'/9000'/{identity}'/{account_index}' Uses the entropy as a Nostr private key. Identity index 0' is reserved for future protocol use. Account index 0' is reserved across all identities for key management operations. -Usable keys start at identity >= 1' and account >= 1'. +Usable keys start at identity >= 1' and account_index >= 1'. The resulting 32-byte private key is Bech32 encoded as an nsec per NIP19. @@ -443,31 +443,31 @@ The resulting 32-byte private key is Bech32 encoded as an nsec per INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb -* PATH: m/83696968'/86'/1'/1' +* PATH: m/83696968'/9000'/1'/1' OUTPUT -* DERIVED ENTROPY=7f3313b1bdeacc4f395c666b473982550cdc66c225fd7e7b0f5d11d33cddde31 -* DERIVED NSEC=nsec10ue38vdaatxy7w2uve45wwvz25xdcekzyh7hu7c0t5gax0xamccsyuyesn +* DERIVED ENTROPY=552ad1d578fe1bc927cec9612651652b07c52dde4017911bc23bc953568075ff +* DERIVED NSEC=nsec1254dr4tclcdujf7we9sjv5t99vru2tw7gqtezx7z80y4x45qwhlsmxapst '''identity=1, account=2''' INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb -* PATH: m/83696968'/86'/1'/2' +* PATH: m/83696968'/9000'/1'/2' OUTPUT -* DERIVED ENTROPY=41fbfba9227f7d261ccb90f61264fd0b38e1f762108c31135f8fc138329594ff -* DERIVED NSEC=nsec1g8alh2fz0a7jv8xtjrmpye8apvuwramzzzxrzy6l3lqnsv54jnlsuxjsql +* DERIVED ENTROPY=4fd36c0061a65db375b4350f44bb62a6d7f716ee93bd0f59887ac50b35fa8b96 +* DERIVED NSEC=nsec1flfkcqrp5ewmxad5x585fwmz5mtlw9hwjw7s7kvg0tzskd063wtq34wlgr '''identity=2, account=1''' INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb -* PATH: m/83696968'/86'/2'/1' +* PATH: m/83696968'/9000'/2'/1' OUTPUT -* DERIVED ENTROPY=a159a41860a18457855511334a3c813430468ec3c1ef17700d4917d0e881a45a -* DERIVED NSEC=nsec159v6gxrq5xz90p24zye550ypxscydrkrc8h3wuqdfytap6yp53dq5gdpd6 +* DERIVED ENTROPY=b2d3b48992d46f98beac0196c4e258417087e467dbec1503342785368f4402c2 +* DERIVED NSEC=nsec1ktfmfzvj63he304vqxtvfcjcg9cg0er8m0kp2qe5y7zndr6yqtpq7q5y44 ==Backwards Compatibility== @@ -482,16 +482,14 @@ BIP32, BIP39, [https://github.com/nostr-protocol/nips/blob/master/01.md NIP01], ==Reference Implementations== * 1.3.0 Python 3.x library implementation: [https://github.com/akarve/bipsea] -* 1.1.0 Python 2.x library implementation: [https://github.com/ethankosakovsky/bip85] -* 1.0.0 JavaScript library implementation: [https://github.com/hoganri/bip85-js] ==Changelog== -===2.1.0=== +===2.1.0 (2026-05-15)=== ====Added==== -* Nostr application 86' +* Nostr application 9000' ===2.0.0 (2025-09-19)=== From 60498282aa6c68ad2c5dba64bec8ce89a4e63e10 Mon Sep 17 00:00:00 2001 From: ethicnology Date: Mon, 29 Jun 2026 15:00:58 +0000 Subject: [PATCH 6/7] bip85: address review on Nostr application, renumber to 128002' Incorporate akarve's review of the Nostr application: - Renumber 9000' -> 128002' and drop the origin explanation, per the convention of leaving the app number's meaning implicit. - State explicitly that the Nostr private key is the first 32 bytes (most significant 256 bits) of the 64-byte BIP-85 entropy. - Move the private-key sentence below the path and consolidate it with the encoding description. - Justify the reserved identity 0' and account 0' indices. - Show the full 64-byte DERIVED ENTROPY in all test vectors for consistency with the other applications. --- bip-0085.mediawiki | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index 2b08eb17f3..b29ee9256f 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -425,49 +425,45 @@ OUTPUT ===Nostr=== -Application number: 9000' +Application number: 128002' -9000 is the zip code of Funchal in Madeira, Portugal, where this specification was written during the Sovereign Engineering event. +The derivation path format is: m/83696968'/128002'/{identity}'/{account_index}' -The derivation path format is: m/83696968'/9000'/{identity}'/{account_index}' +Each identity is an independent, unlinkable Nostr key namespace, and each account_index is a distinct key within that identity. -Uses the entropy as a Nostr private key. +Identity index 0' is reserved for future protocol-level use. Within every identity, account index 0' is reserved as a management key for that identity (for example proof-of-linkage between an identity's keys, key rotation, and revocation). Usable signing keys therefore start at identity >= 1' and account_index >= 1'. The exact semantics of these reserved indices are defined by an external NIP that references this application. -Identity index 0' is reserved for future protocol use. -Account index 0' is reserved across all identities for key management operations. -Usable keys start at identity >= 1' and account_index >= 1'. - -The resulting 32-byte private key is Bech32 encoded as an nsec per NIP19. +The standard application of BIP-85 produces 64 bytes of entropy. Take the first 32 bytes (the 256 most significant bits) as the Nostr private key and discard the trailing 32 bytes, as in the HEX application. This 32-byte private key is then Bech32 encoded as an nsec per NIP19. '''identity=1, account=1''' INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb -* PATH: m/83696968'/9000'/1'/1' +* PATH: m/83696968'/128002'/1'/1' OUTPUT -* DERIVED ENTROPY=552ad1d578fe1bc927cec9612651652b07c52dde4017911bc23bc953568075ff -* DERIVED NSEC=nsec1254dr4tclcdujf7we9sjv5t99vru2tw7gqtezx7z80y4x45qwhlsmxapst +* DERIVED ENTROPY=ff6eb0fcdf1ef87a2a06b0d7884d495b486d0faa210e9f80f23fd649d6e114d27873d12f3b57c469f684e4dc9f4abf10beeacb59b385fde8e33f1947bc5c6c17 +* DERIVED NSEC=nsec1lahtplxlrmu852sxkrtcsn2ftdyx6ra2yy8flq8j8ltyn4hpznfq23uvqz '''identity=1, account=2''' INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb -* PATH: m/83696968'/9000'/1'/2' +* PATH: m/83696968'/128002'/1'/2' OUTPUT -* DERIVED ENTROPY=4fd36c0061a65db375b4350f44bb62a6d7f716ee93bd0f59887ac50b35fa8b96 -* DERIVED NSEC=nsec1flfkcqrp5ewmxad5x585fwmz5mtlw9hwjw7s7kvg0tzskd063wtq34wlgr +* DERIVED ENTROPY=917628689652288f6983c8a01db516d0697d5198dcf9de9010597f5e322fba6e435a731d85fbcc5768c06ff95ff34bf577f63f415cb170473659753acf14722d +* DERIVED NSEC=nsec1j9mzs6yk2g5g76vrezspmdgk6p5h65vcmnuaayqst9l4uv30hfhqje0jyh '''identity=2, account=1''' INPUT: * MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb -* PATH: m/83696968'/9000'/2'/1' +* PATH: m/83696968'/128002'/2'/1' OUTPUT -* DERIVED ENTROPY=b2d3b48992d46f98beac0196c4e258417087e467dbec1503342785368f4402c2 -* DERIVED NSEC=nsec1ktfmfzvj63he304vqxtvfcjcg9cg0er8m0kp2qe5y7zndr6yqtpq7q5y44 +* DERIVED ENTROPY=fa2e784291b1fd347ba3624672e3090cb2cee34b8567180336e3aa290d02715b8f4b18f02f07cb2aa3023afd34735282cc6594370f47e6e1fa48d8d0dda93096 +* DERIVED NSEC=nsec1lgh8ss53k87ng7arvfr89ccfpjevac6ts4n3sqekuw4zjrgzw9dsq3uelh ==Backwards Compatibility== @@ -489,7 +485,7 @@ BIP32, BIP39, [https://github.com/nostr-protocol/nips/blob/master/01.md NIP01], ====Added==== -* Nostr application 9000' +* Nostr application 128002' ===2.0.0 (2025-09-19)=== From e6df9dbf1093444302331565a1a8f58144175a21 Mon Sep 17 00:00:00 2001 From: ethicnology Date: Mon, 29 Jun 2026 15:18:35 +0000 Subject: [PATCH 7/7] bip85: reword reserved Nostr indices to defer semantics to a future NIP --- bip-0085.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0085.mediawiki b/bip-0085.mediawiki index b29ee9256f..ad91f9f124 100644 --- a/bip-0085.mediawiki +++ b/bip-0085.mediawiki @@ -431,7 +431,7 @@ The derivation path format is: m/83696968'/128002'/{identity}'/{account_in Each identity is an independent, unlinkable Nostr key namespace, and each account_index is a distinct key within that identity. -Identity index 0' is reserved for future protocol-level use. Within every identity, account index 0' is reserved as a management key for that identity (for example proof-of-linkage between an identity's keys, key rotation, and revocation). Usable signing keys therefore start at identity >= 1' and account_index >= 1'. The exact semantics of these reserved indices are defined by an external NIP that references this application. +Identity index 0' and account index 0' are reserved for future key-management use, such as proof-of-linkage between an identity's keys, key rotation, and revocation. Their semantics are out of scope for this BIP and may be specified by a future NIP. Usable signing keys therefore start at identity >= 1' and account_index >= 1'. The standard application of BIP-85 produces 64 bytes of entropy. Take the first 32 bytes (the 256 most significant bits) as the Nostr private key and discard the trailing 32 bytes, as in the HEX application. This 32-byte private key is then Bech32 encoded as an nsec per NIP19.