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:
parent
5ad47a917d
commit
aeba28d9e5
@ -97,8 +97,8 @@ A new nostr keypair:
|
|||||||
npm run cli -- identity new
|
npm run cli -- identity new
|
||||||
```
|
```
|
||||||
|
|
||||||
Or a new Ed25519 keypair, which comes with a 24-word BIP-39 phrase
|
Or a new Ed25519 keypair, which comes with a BIP-39 phrase alongside
|
||||||
alongside the hex seed (both are equivalent backups):
|
the hex seed (both are equivalent backups):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run cli -- identity new --key-type ed25519 # 24-word
|
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…"
|
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
|
> **Save the backup.** Seed *or* phrase — at least one. Lose them both
|
||||||
> and the identity is gone. There's no recovery flow.
|
> 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 (1–12 or 1–24)
|
||||||
|
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
|
Throughout the rest of this tutorial you can substitute
|
||||||
`--mnemonic "your phrase here"` anywhere `--ed25519-seed <hex>` appears.
|
`--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
|
For the rest of this tutorial we'll use a nostr key for examples and
|
||||||
write the secret as `nsec1FAKE...` — substitute your real one.
|
write the secret as `nsec1FAKE...` — substitute your real one.
|
||||||
|
|||||||
114
rust/TUTORIAL.md
114
rust/TUTORIAL.md
@ -81,7 +81,8 @@ kez identity new --key-type nostr # only if you want a NEW key
|
|||||||
|
|
||||||
### Option B: generate a fresh Ed25519 primary
|
### 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
|
```sh
|
||||||
kez identity new --key-type ed25519 # 24-word phrase (default)
|
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
|
BIP-39 phrase. Either restores the same identity. Most people back up
|
||||||
the phrase (easier to write down, easier to verify by hand).
|
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
|
> **Save the backup.** Seed *or* phrase — at least one. Lose them both
|
||||||
> and the identity is gone. There's no recovery flow.
|
> 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 (1–12 or 1–24)
|
||||||
|
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
|
Throughout the rest of this tutorial you can substitute
|
||||||
`--mnemonic "your phrase here"` anywhere `--ed25519-seed <hex>` appears.
|
`--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
|
For the rest of this tutorial we'll use a nostr key for examples and
|
||||||
write the secret as `nsec1FAKE...` — substitute your real one.
|
write the secret as `nsec1FAKE...` — substitute your real one.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user