Add BIP39 seed phrases (SilentDragonXLite-compatible) and HD transparent keys
Derive transparent (t-addr) keys from the HD seed and add BIP39 mnemonic seed phrases that are byte-for-byte compatible with SilentDragonXLite, so the same 24 words recover the same shielded and transparent addresses in either wallet. HD transparent keys: - Derive t-keys from the seed at m/44'/coin'/0'/0/i (were random CKeys). - CHDChain gains a version-gated transparent counter; existing wallets load unchanged. GenerateNewKey routes through DeriveNewChildKey when enabled (-hdtransparent, default on). - Restore from a seed hex via -hdseed with gap-limit pre-derivation; birthday pinned to genesis so the rescan is not clipped. BIP39 seed phrases: - Wire the vendored trezor BIP39 lib (src/crypto/bip39) into the build, fix its BIP39_WORDS guard, and disable the insecure mnemonic cache. - Match SDXLite exactly: English wordlist, empty passphrase, PBKDF2 64-byte seed, coin type 141, ZIP-32 m/32'/141'/i' and BIP44 m/44'/141'/0'/0/i. Store the 32-byte entropy and expand to the 64-byte seed on demand. - Restore via -mnemonic, create via -usemnemonic, reveal via z_exportmnemonic. Verified by gtests including a known-answer BIP39 seed vector and z/t address derivation checks (src/gtest/test_hdtransparent.cpp, test_mnemonic_compat.cpp). Docs in doc/hd-transparent-keys.md and doc/seed-phrase.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1063,6 +1063,9 @@ public:
|
||||
* Generate a new key
|
||||
*/
|
||||
CPubKey GenerateNewKey();
|
||||
//! Derive a new transparent key from the HD seed along the BIP44 external
|
||||
//! chain m/44'/coin_type'/0'/0/i, advancing hdChain.transparentChildCounter.
|
||||
void DeriveNewChildKey(CKeyMetadata& metadata, CKey& secretRet);
|
||||
//! Adds a key to the store, and saves it to disk.
|
||||
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
|
||||
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
|
||||
@@ -1294,6 +1297,10 @@ public:
|
||||
/* Returns true if HD is enabled for all address types, false if only for Sapling */
|
||||
bool IsHDFullyEnabled() const;
|
||||
|
||||
/* Returns true if transparent keys should be HD-derived from the seed.
|
||||
Requires an HD seed and the -hdtransparent option (default on). */
|
||||
bool IsHDTransparentEnabled() const;
|
||||
|
||||
/* Generates a new HD seed (will reset the chain child index counters)
|
||||
Sets the seed's version based on the current wallet version (so the
|
||||
caller must ensure the current wallet version is correct before calling
|
||||
@@ -1303,6 +1310,41 @@ public:
|
||||
bool SetHDSeed(const HDSeed& seed);
|
||||
bool SetCryptedHDSeed(const uint256& seedFp, const std::vector<unsigned char> &vchCryptedSecret);
|
||||
|
||||
/* Restore a wallet's HD seed from a hex string (as exported in the
|
||||
z_exportwallet "# HDSeed=" comment): 32 bytes for a legacy raw seed, or
|
||||
64 bytes for a BIP39-derived seed. Only succeeds on a wallet that has no
|
||||
seed yet. Sets the chain birthday to genesis so a rescan finds all
|
||||
historical (coinbase) funds. Returns false on bad input or existing seed. */
|
||||
bool SetHDSeedFromHex(const std::string& seedHex);
|
||||
|
||||
/* Restore/create a wallet from a BIP39 mnemonic phrase, byte-compatible with
|
||||
SilentDragonXLite: stores the 32-byte entropy, marks the chain mnemonic,
|
||||
and derives the 64-byte BIP39 seed on demand. Only succeeds on a wallet
|
||||
with no seed yet. Returns false on an invalid phrase or existing seed. */
|
||||
bool SetHDSeedFromMnemonic(const std::string& phrase);
|
||||
|
||||
/* Return the wallet's 24-word BIP39 recovery phrase, if this is a mnemonic
|
||||
wallet and the seed is available (unlocked). Returns false otherwise. */
|
||||
bool GetMnemonicPhrase(std::string& phraseOut) const;
|
||||
|
||||
/* True if the HD seed was derived from a BIP39 mnemonic (stored as entropy). */
|
||||
bool IsMnemonicSeed() const { return hdChain.fMnemonicSeed; }
|
||||
|
||||
/* Return the seed to feed into HD derivation. For mnemonic wallets this
|
||||
expands the stored 32-byte entropy into the 64-byte BIP39 seed; for legacy
|
||||
wallets it is the stored seed unchanged. Use this everywhere keys/OVKs are
|
||||
derived so behaviour matches SilentDragonXLite. */
|
||||
bool GetHDSeedForDerivation(HDSeed& seedOut) const;
|
||||
|
||||
/* Shared tail of the seed-install paths: stores `seed` and a fresh CHDChain
|
||||
(mnemonic vs raw) with the given birthday. Caller must hold cs_wallet. */
|
||||
bool InstallHDSeed(const HDSeed& seed, bool fMnemonic, int64_t nCreateTime);
|
||||
|
||||
/* Pre-derive `count` HD transparent keys (external chain) into the keystore,
|
||||
stamped with creation time `nBirthday`, so a subsequent rescan can find
|
||||
funds paid to them after a seed-only restore. */
|
||||
void TopUpHDTransparentKeys(unsigned int count, int64_t nBirthday);
|
||||
|
||||
/* Set the HD chain model (chain child index counters) */
|
||||
void SetHDChain(const CHDChain& chain, bool memonly);
|
||||
const CHDChain& GetHDChain() const { return hdChain; }
|
||||
|
||||
Reference in New Issue
Block a user