Browse Source

Merge #8851: [wallet] Move key derivation logic from GenerateNewKey to DeriveNewChildKey (pstratem)

e198c52 Move key derivation logic from GenerateNewKey to DeriveNewChildKey (Patrick Strateman)
0.14
Wladimir J. van der Laan 8 years ago
parent
commit
940748b4b0
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 78
      src/wallet/wallet.cpp
  2. 1
      src/wallet/wallet.h

78
src/wallet/wallet.cpp

@ -100,43 +100,7 @@ CPubKey CWallet::GenerateNewKey()
// use HD key derivation if HD was enabled during wallet creation // use HD key derivation if HD was enabled during wallet creation
if (IsHDEnabled()) { if (IsHDEnabled()) {
// for now we use a fixed keypath scheme of m/0'/0'/k DeriveNewChildKey(metadata, secret);
CKey key; //master key seed (256bit)
CExtKey masterKey; //hd master key
CExtKey accountKey; //key at m/0'
CExtKey externalChainChildKey; //key at m/0'/0'
CExtKey childKey; //key at m/0'/0'/<n>'
// 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'/0'
accountKey.Derive(externalChainChildKey, BIP32_HARDENED_KEY_LIMIT);
// derive child key at next index, skip keys already known to the wallet
do
{
// always derive hardened keys
// childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
// example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
metadata.hdKeypath = "m/0'/0'/"+std::to_string(hdChain.nExternalChainCounter)+"'";
metadata.hdMasterKeyID = hdChain.masterKeyID;
// increment childkey index
hdChain.nExternalChainCounter++;
} while(HaveKey(childKey.key.GetPubKey().GetID()));
secret = childKey.key;
// update the chain model in the database
if (!CWalletDB(strWalletFile).WriteHDChain(hdChain))
throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
} else { } else {
secret.MakeNewKey(fCompressed); secret.MakeNewKey(fCompressed);
} }
@ -157,6 +121,46 @@ CPubKey CWallet::GenerateNewKey()
return pubkey; return pubkey;
} }
void CWallet::DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret)
{
// for now we use a fixed keypath scheme of m/0'/0'/k
CKey key; //master key seed (256bit)
CExtKey masterKey; //hd master key
CExtKey accountKey; //key at m/0'
CExtKey externalChainChildKey; //key at m/0'/0'
CExtKey childKey; //key at m/0'/0'/<n>'
// 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'/0'
accountKey.Derive(externalChainChildKey, BIP32_HARDENED_KEY_LIMIT);
// derive child key at next index, skip keys already known to the wallet
do {
// always derive hardened keys
// childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
// example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
metadata.hdKeypath = "m/0'/0'/" + std::to_string(hdChain.nExternalChainCounter) + "'";
metadata.hdMasterKeyID = hdChain.masterKeyID;
// increment childkey index
hdChain.nExternalChainCounter++;
} while (HaveKey(childKey.key.GetPubKey().GetID()));
secret = childKey.key;
// update the chain model in the database
if (!CWalletDB(strWalletFile).WriteHDChain(hdChain))
throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
}
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
{ {
AssertLockHeld(cs_wallet); // mapKeyMetadata AssertLockHeld(cs_wallet); // mapKeyMetadata

1
src/wallet/wallet.h

@ -698,6 +698,7 @@ public:
* Generate a new key * Generate a new key
*/ */
CPubKey GenerateNewKey(); CPubKey GenerateNewKey();
void DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret);
//! Adds a key to the store, and saves it to disk. //! Adds a key to the store, and saves it to disk.
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
//! Adds a key to the store, without saving it to disk (used by LoadWallet) //! Adds a key to the store, without saving it to disk (used by LoadWallet)

Loading…
Cancel
Save