mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-18 11:01:06 +00:00
Move key derivation logic from GenerateNewKey to DeriveNewChildKey
This commit is contained in:
parent
f560d9564f
commit
e198c521d3
@ -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
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user