diff options
| author | Bitflash <btf01@proton.me> | 2026-08-03 16:08:55 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-03 16:08:55 -0300 |
| commit | 9176d5b3f32b907e4bafde5152828b2ae04ae8a1 (patch) | |
| tree | 4963b9d45c17d323c89e80802d77e93aadd7a983 /src/selftest.cpp | |
| parent | f6e197573464268174edc6f8d3b0d5c2b194b1ed (diff) | |
doc: write down the derivation, so the words work without us (#128)
The twelve words were only as good as this binary staying alive. The
derivation path, the address version byte and the public-key encoding
existed nowhere outside src/, so anyone holding a phrase and no working
Bitflash had the keys and no way to find them.
doc/derivation.md states all of it: BIP-39 to seed, BIP-32 to children,
both layouts this wallet has used (legacy m/i' and BIP-44
m/44'/4346950'/0'/{0,1}/i), secp256k1 with UNCOMPRESSED public keys, and
Base58Check with version byte 25.
The uncompressed part is the trap worth naming. Hashing the same key in
compressed form yields a different, perfectly valid-looking address that
holds nothing, and nothing in the source says out loud which one is
used -- it falls out of OpenSSL's default in code inherited from 0.1.0.
doc/verify-derivation.py implements the document from scratch, sharing
no code with this project and importing nothing outside the standard
library, then checks it against addresses the wallet actually produced.
Both tables were generated by a binary first: the legacy one by the
published v1.2.15, which knows only that layout, and the BIP-44 one by
the current tree. The script reproduces all eight.
That is the point of shipping the checker rather than only the prose: if
the two ever drift, the script fails and says which side is wrong.
Diffstat (limited to 'src/selftest.cpp')
0 files changed, 0 insertions, 0 deletions