diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b085fc40a5d..eadf7a6da8d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -123,6 +123,33 @@ CPubKey CWallet::GenerateNewKey() return pubkey; } +void CWallet::DeriveBlindingKey(CKeyMetadata& metadata, CKey& secret) +{ + // Key is derived at m/0'/2' to avoid collision with hd split wallets + CKey key; //master key seed (256bit) + CExtKey masterKey; //hd master key + CExtKey accountKey; //key at m/0' + CExtKey externalChainChildKey; //key at m/0'/2' + + // try to get the master key + if (!GetKey(hdChain.masterKeyID, key)) + throw std::runtime_error(std::string(__func__) + ": Master key not found"); + + masterKey.SetMaster(key.begin(), key.size()); + + // derive m/0' + // use hardened derivation (child keys >= 0x80000000 are hardened after bip32) + masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT); + + // derive m/0'/2' + accountKey.Derive(externalChainChildKey, 2 | BIP32_HARDENED_KEY_LIMIT); + + metadata.hdKeypath = "m/0'/2'"; + metadata.hdMasterKeyID = hdChain.masterKeyID; + secret = externalChainChildKey.key; + return; +} + void CWallet::DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret) { // for now we use a fixed keypath scheme of m/0'/0'/k diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 37911914eb7..e596f731979 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -793,6 +793,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface */ CPubKey GenerateNewKey(); void DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret); + //! Derives static blinding key at m/0'/2' + void DeriveBlindingKey(CKeyMetadata& metadata, CKey& secret); //! Adds a key to the store, and saves it to disk. bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override; //! Adds a key to the store, without saving it to disk (used by LoadWallet) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index e792367089d..a75df6bdbd3 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -686,7 +686,13 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) if (result == DB_LOAD_OK && pwallet->blinding_derivation_key.IsNull()) { CKey key; - key.MakeNewKey(true); + if (pwallet->IsHDEnabled()) { + int64_t nCreationTime = GetTime(); + CKeyMetadata metadata(nCreationTime); + pwallet->DeriveBlindingKey(metadata, key); + } else { + key.MakeNewKey(true); + } uint256 keybin; memcpy(keybin.begin(), key.begin(), key.size()); pwallet->blinding_derivation_key = keybin;