docs(rust,nodejs): expand TUTORIAL.md recovery-phrase section

Reworks the "Pick your primary key" → Option B block in both tutorials
into a proper "Recovery phrases" mini-chapter:

  • Table comparing 24-word (256 bits, bijection) vs 12-word (128 bits,
    one-way SHA-256 derivation).
  • Decision guide — why someone would actually pick 12 over 24 (and
    vice versa). Explicitly: "save the phrase, not just the seed" for
    the 12-word case.
  • Wallet-incompatibility callout — KEZ phrases don't produce the
    same key as the same phrase in Ledger / MetaMask / Bitcoin
    wallets. Explains the two deliberate reasons (no BIP-39 PBKDF2,
    no BIP-32 derivation tree), and the inverse — KEZ phrases can't be
    used to extract funds from a hardware-wallet recovery so a
    malicious importer can't phish that direction either.
  • Concrete backup advice — pencil on paper, numbered words, fireproof
    storage, don't photograph it, don't cloud-sync it, don't split it,
    don't permute it. Calls out which password-manager patterns are
    OK vs not.
  • "Working with phrases later" — clean examples of `identity mnemonic`
    (no key derived) and `identity from-mnemonic` (recover an existing
    key), with the note that the recovered output is byte-for-byte
    identical to what `identity new` originally printed.

Same content in both the Rust and Node tutorials, command examples
adapted to each CLI invocation style.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Jason Tudisco 2026-06-05 22:53:59 -06:00
parent 5ad47a917d
commit aeba28d9e5
2 changed files with 196 additions and 32 deletions

View File

@ -97,8 +97,8 @@ A new nostr keypair:
npm run cli -- identity new
```
Or a new Ed25519 keypair, which comes with a 24-word BIP-39 phrase
alongside the hex seed (both are equivalent backups):
Or a new Ed25519 keypair, which comes with a BIP-39 phrase alongside
the hex seed (both are equivalent backups):
```sh
npm run cli -- identity new --key-type ed25519 # 24-word
@ -114,25 +114,107 @@ Secret: 9e3f51… (32-byte seed)
Mnemonic (24 words): "abandon ability able about above absent academy accident…"
```
> **12 vs 24.** 24 words is fully round-trippable: phrase ↔ seed are
> bijective. 12 words is shorter to memorize, but the seed is derived
> from the phrase one-way (KEZ-specific SHA-256 step), so you cannot
> derive a 12-word phrase from a hex seed. Pick whichever you'll
> actually back up.
You can also get just a phrase, or restore an existing one:
```sh
npm run cli -- identity mnemonic # fresh 24 words
npm run cli -- identity mnemonic --words 12 # fresh 12 words
npm run cli -- identity from-mnemonic "abandon ability able …" # recover the key
```
> **Save the backup.** Seed *or* phrase — at least one. Lose them both
> and the identity is gone. There's no recovery flow.
### Recovery phrases — what's actually going on
A KEZ recovery phrase is a [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
mnemonic — the same 2048-word English wordlist that Bitcoin, Ethereum,
and most hardware wallets use. The words encode random bits:
| Phrase length | Random bits | Resulting Ed25519 seed |
|---|---|---|
| **24 words** | 256 bits of entropy | The 32-byte seed *is* those 256 bits (1:1). Phrase ↔ seed round-trips. |
| **12 words** | 128 bits of entropy | 16 bytes → 32-byte seed via `SHA-256("kez-bip39-12-v1" \|\| entropy)`. Phrase → seed only (one-way). |
#### Picking 12 vs 24
- **Pick 24 words** when you want full round-trip-ability — i.e. you'd
like to be able to *recover the phrase from the hex seed* at any time
in the future. Anyone's 32-byte Ed25519 secret can be re-encoded into
the unique 24-word phrase that produced it. Bigger security margin
(256 bits of entropy vs 128).
- **Pick 12 words** when you want a shorter thing to write down on
paper or remember. 128 bits of entropy is still enormously beyond
brute-forcing. The trade-off: the path is *one-way only* — you can
always derive the seed from the phrase, but you cannot derive the
phrase from the seed. So if you only ever have the seed, you'll
never know what 12-word phrase produced it. **Save the phrase
itself**, not just the resulting seed.
Either way the resulting Ed25519 identity is exactly the same shape;
peers can't tell which word count you used. The choice is purely about
your backup ergonomics.
#### ⚠ Not compatible with hardware-wallet derivations
A KEZ 12-word phrase **does not** produce the same Bitcoin or Ethereum
key as the same 12 words typed into a Ledger or MetaMask, and vice
versa. The reasons are deliberate:
1. Other wallets feed the phrase through BIP-39's PBKDF2 to get a
64-byte "seed", then run that through BIP-32 hierarchical
derivation at a coin-specific path. KEZ doesn't — it takes the
raw entropy and uses it directly (24-word case) or hashes it with
a domain tag (12-word case).
2. KEZ identities aren't part of a derivation tree. There's one
identity per phrase; there's no path component.
That means: **don't paste your existing hardware-wallet recovery
phrase into KEZ** expecting to get a key you've already seen. It'll
produce a *new* KEZ identity uncorrelated with anything else.
Conversely: a KEZ phrase you saved is *only* useful for KEZ. A
malicious wallet that says "import this phrase" can't extract your
existing Bitcoin / Ethereum funds from a KEZ phrase, because the
phrase wasn't derived through the same path.
#### Backing up — concrete advice
The phrase is the master key to your identity. Practical guidance:
- **Write it on paper, with a pencil. Number each word (112 or 124)
so you can later verify the order.** A photograph or cloud document
is one breach away from compromise.
- **Store the paper somewhere fireproof.** Safe-deposit boxes, lockable
desk drawers, etched-stainless-steel cards if you're paranoid.
- **Never type the phrase into a website, chat app, or password
manager that auto-syncs.** Local-only password managers (KeePassXC,
1Password locked vault) are OK; cloud-synced managers are a softer
target.
- **Don't split it across two locations "for safety".** Half a BIP-39
phrase weakens the entropy more than it protects against loss. If you
need redundancy, make two complete paper copies in different physical
locations.
- **Don't be cute.** Don't permute the words "because they're easy to
remember in this order." The wordlist position matters; reorder and
you change the key (and the BIP-39 checksum will reject it on
restore anyway).
### Working with phrases later
You can generate a fresh phrase without producing a key, or recover
the key from a phrase you wrote down earlier:
```sh
# Print a fresh 24-word phrase (or 12, with --words 12). No key derived.
npm run cli -- identity mnemonic
npm run cli -- identity mnemonic --words 12
# Recover the Ed25519 key from a phrase. Word count auto-detected.
npm run cli -- identity from-mnemonic "abandon ability able about above absent
academy accident account accuse achieve acid acoustic acquire across act
action actor actress actual adapt add addict address"
```
The recovered output is identical, byte-for-byte, to what was printed
when you first ran `identity new` — same `Primary:`, same `Public:`,
same `Secret:`.
Throughout the rest of this tutorial you can substitute
`--mnemonic "your phrase here"` anywhere `--ed25519-seed <hex>` appears.
Both are accepted on every command that takes a signing key.
For the rest of this tutorial we'll use a nostr key for examples and
write the secret as `nsec1FAKE...` — substitute your real one.

View File

@ -81,7 +81,8 @@ kez identity new --key-type nostr # only if you want a NEW key
### Option B: generate a fresh Ed25519 primary
If you'd rather start clean, generate a new Ed25519 key:
If you'd rather start clean, generate a new Ed25519 key with a BIP-39
recovery phrase you can write down on paper:
```sh
kez identity new --key-type ed25519 # 24-word phrase (default)
@ -101,26 +102,107 @@ You now have **two equivalent backups** — the hex seed *and* the 24-word
BIP-39 phrase. Either restores the same identity. Most people back up
the phrase (easier to write down, easier to verify by hand).
> **12 vs 24.** 24 words is fully round-trippable: phrase ↔ seed are
> bijective. 12 words is shorter to memorize, but the seed is derived
> from the phrase one-way (KEZ-specific SHA-256 step), so you cannot
> derive a 12-word phrase from a hex seed. Pick whichever you'll
> actually remember to back up.
You can also get just a phrase without a key, or restore from a phrase
you wrote down earlier:
```sh
kez identity mnemonic # print a fresh 24-word phrase
kez identity mnemonic --words 12 # 12-word
kez identity from-mnemonic "abandon ability able …" # recover the key
```
> **Save the backup.** Seed *or* phrase — at least one. Lose them both
> and the identity is gone. There's no recovery flow.
### Recovery phrases — what's actually going on
A KEZ recovery phrase is a [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
mnemonic — the same 2048-word English wordlist that Bitcoin, Ethereum,
and most hardware wallets use. The words encode random bits:
| Phrase length | Random bits | Resulting Ed25519 seed |
|---|---|---|
| **24 words** | 256 bits of entropy | The 32-byte seed *is* those 256 bits (1:1). Phrase ↔ seed round-trips. |
| **12 words** | 128 bits of entropy | 16 bytes → 32-byte seed via `SHA-256("kez-bip39-12-v1" \|\| entropy)`. Phrase → seed only (one-way). |
#### Picking 12 vs 24
- **Pick 24 words** when you want full round-trip-ability — i.e. you'd
like to be able to *recover the phrase from the hex seed* at any time
in the future. Anyone's 32-byte ed25519 secret can be re-encoded into
the unique 24-word phrase that produced it. Bigger security margin
(256 bits of entropy vs 128).
- **Pick 12 words** when you want a shorter thing to write down on
paper or remember. 128 bits of entropy is still enormously beyond
brute-forcing. The trade-off: the path is *one-way only* — you can
always derive the seed from the phrase, but you cannot derive the
phrase from the seed. So if you only ever have the seed, you'll
never know what 12-word phrase produced it. **Save the phrase
itself**, not just the resulting seed.
Either way the resulting Ed25519 identity is exactly the same shape;
peers can't tell which word count you used. The choice is purely about
your backup ergonomics.
#### ⚠ Not compatible with hardware-wallet derivations
A KEZ 12-word phrase **does not** produce the same Bitcoin or Ethereum
key as the same 12 words typed into a Ledger or MetaMask, and vice
versa. The reasons are deliberate:
1. Other wallets feed the phrase through BIP-39's PBKDF2 to get a
64-byte "seed", then run that through BIP-32 hierarchical
derivation at a coin-specific path. KEZ doesn't — it takes the
raw entropy and uses it directly (24-word case) or hashes it with
a domain tag (12-word case).
2. KEZ identities aren't part of a derivation tree. There's one
identity per phrase; there's no path component.
That means: **don't paste your existing hardware-wallet recovery
phrase into KEZ** expecting to get a key that you've already seen.
It'll produce a *new* KEZ identity uncorrelated with anything else.
Conversely: a KEZ phrase you saved is *only* useful for KEZ. A
malicious wallet that says "import this phrase" can't extract your
existing Bitcoin / Ethereum funds from a KEZ phrase, because the
phrase wasn't derived through the same path.
#### Backing up — concrete advice
The phrase is the master key to your identity. Practical guidance:
- **Write it on paper, with a pencil. Number each word (112 or 124)
so you can later verify the order.** A photograph or cloud document
is one breach away from compromise.
- **Store the paper somewhere fireproof.** Safe-deposit boxes, lockable
desk drawers, etched-stainless-steel cards if you're paranoid.
- **Never type the phrase into a website, chat app, or password
manager that auto-syncs.** Local-only password managers (KeePassXC,
1Password locked vault) are OK; cloud-synced managers are a softer
target.
- **Don't split it across two locations "for safety".** Half a BIP-39
phrase weakens the entropy more than it protects against loss. If you
need redundancy, make two complete paper copies in different physical
locations.
- **Don't be cute.** Don't permute the words "because they're easy to
remember in this order." The wordlist position matters; reorder and
you change the key (and the BIP-39 checksum will reject it on
restore anyway).
### Working with phrases later
You can generate a fresh phrase without producing a key, or recover
the key from a phrase you wrote down earlier:
```sh
# Print a fresh 24-word phrase (or 12, with --words 12). No key derived.
kez identity mnemonic
kez identity mnemonic --words 12
# Recover the Ed25519 key from a phrase. Word count auto-detected.
kez identity from-mnemonic "abandon ability able about above absent academy
accident account accuse achieve acid acoustic acquire across act action
actor actress actual adapt add addict address"
```
The recovered output is identical, byte-for-byte, to what was printed
when you first ran `identity new` — same `Primary:`, same `Public:`,
same `Secret:`.
Throughout the rest of this tutorial you can substitute
`--mnemonic "your phrase here"` anywhere `--ed25519-seed <hex>` appears.
Both are accepted on every command that takes a signing key.
For the rest of this tutorial we'll use a nostr key for examples and
write the secret as `nsec1FAKE...` — substitute your real one.