Skip to content

Commit 7af905e

Browse files
committed
[Stealth] Derive stealth scan and spend keys from wallet key pool address
1 parent bed9572 commit 7af905e

File tree

5 files changed

+40
-17
lines changed

5 files changed

+40
-17
lines changed

src/key.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,17 @@ bool CKey::Derive(CKey& keyChild, ChainCode& ccChild, unsigned int nChild, const
267267
return ret;
268268
}
269269

270+
bool CKey::DeriveChildKey(CKey& keyChild) const
271+
{
272+
assert(IsValid());
273+
assert(IsCompressed());
274+
SecureVector newkeyData(32);
275+
CSHA256().Write(&keydata[0], 32).Finalize(&newkeyData[0]);
276+
keyChild.Set(newkeyData.begin(), newkeyData.end(), true);
277+
keyChild.fCompressed = true;
278+
return keyChild.fValid;
279+
}
280+
270281
bool CExtKey::Derive(CExtKey& out, unsigned int _nChild) const
271282
{
272283
out.nDepth = nDepth + 1;

src/key.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ class CKey
150150

151151
//! Load private key and check that public key matches.
152152
bool Load(CPrivKey& privkey, CPubKey& vchPubKey, bool fSkipCheck);
153+
154+
bool DeriveChildKey(CKey& keyChild) const;
153155
};
154156

155157
struct CExtKey {

src/wallet/rpcwallet.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -163,25 +163,11 @@ static UniValue getnewstealthaddress(const JSONRPCRequest &request)
163163

164164
LOCK2(cs_main, pwalletMain->cs_wallet);
165165

166-
// Get a new scan key from pool.
167-
CPubKey scanPubKey;
168-
if (!pwalletMain->GetKeyFromPool(scanPubKey, false))
166+
CPubKey walletPubKey;
167+
CStealthAddress sxAddr;
168+
if (!pwalletMain->GetStealthAddressFromPool(walletPubKey, sxAddr, false))
169169
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
170-
CKeyID scanKeyID = scanPubKey.GetID();
171-
CKey scanKey;
172-
if (!pwalletMain->GetKey(scanKeyID, scanKey))
173-
throw std::runtime_error(strprintf("%s -- Failed to get scan private key for stealth address\n", __func__));
174-
175-
// Get a new spend key from pool.
176-
CPubKey spendPubKey;
177-
if (!pwalletMain->GetKeyFromPool(spendPubKey, false))
178-
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
179-
CKeyID spendKeyID = spendPubKey.GetID();
180-
CKey spendKey;
181-
if (!pwalletMain->GetKey(spendKeyID, spendKey))
182-
throw std::runtime_error(strprintf("%s -- Failed to get spend private key for stealth address\n", __func__));
183170

184-
CStealthAddress sxAddr(scanKey, spendKey);
185171
if (!pwalletMain->AddStealthAddress(sxAddr))
186172
throw std::runtime_error(strprintf("%s -- Failed to write stealth address to local wallet.\n", __func__));
187173

src/wallet/wallet.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4473,6 +4473,29 @@ void CWallet::ReturnKey(int64_t nIndex, bool fInternal)
44734473
LogPrintf("keypool return %d\n", nIndex);
44744474
}
44754475

4476+
bool CWallet::GetStealthAddressFromPool(CPubKey& pubkeyWallet, CStealthAddress& sxAddr, bool fInternal)
4477+
{
4478+
if (IsLocked())
4479+
return false;
4480+
4481+
if (!GetKeyFromPool(pubkeyWallet, fInternal))
4482+
return false;
4483+
4484+
CKey walletKey, spendKey, scanKey;
4485+
if (!GetKey(pubkeyWallet.GetID(), walletKey))
4486+
return false;
4487+
4488+
if (!walletKey.DeriveChildKey(spendKey))
4489+
return false;
4490+
4491+
if (!spendKey.DeriveChildKey(scanKey))
4492+
return false;
4493+
4494+
CStealthAddress sx(scanKey, spendKey);
4495+
sxAddr = sx;
4496+
return true;
4497+
}
4498+
44764499
bool CWallet::GetKeyFromPool(CPubKey& result, bool fInternal)
44774500
{
44784501
int64_t nIndex = 0;

src/wallet/wallet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
12331233
bool AddToStealthQueue(const std::pair<CKeyID, CStealthKeyQueueData>& pairStealthQueue);
12341234
CWalletDB* GetWalletDB();
12351235
bool HaveStealthAddress(const CKeyID& address) const;
1236+
bool GetStealthAddressFromPool(CPubKey& pubkeyWallet, CStealthAddress& sxAddr, bool fInternal);
12361237

12371238
};
12381239

0 commit comments

Comments
 (0)