perf(tx-cache): skip Argon2id for unencrypted wallets
Opening the transaction-history cache always derived its encryption key with Argon2id, even for an unencrypted wallet. For those wallets the passphrase is just a value derivable from the database itself, so the ~50-100 ms Argon2id stall bought no additional secrecy and ran on the UI thread at open. - Unencrypted wallets now derive the cache key with a cheap, domain-separated BLAKE2b KDF over the wallet identity, keyed by the per-wallet salt. The secret is derivable from the DB, so this is security-equivalent for the unencrypted case and avoids the stall. - Passphrase-encrypted wallets are unchanged: they keep the Argon2id key derivation. The two paths use separate domain labels, so the fast-path key and the Argon2id key never collide for the same DB and salt; a cache written under one cannot be read under the other. Tests cover the fast-path round-trip and reopen, and assert that an Argon2id unlock of the same DB produces a different key and fails to read the fast-path snapshot. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+1
-10
@@ -93,12 +93,6 @@ bool isPageEnabledForBuild(ui::NavPage page)
|
||||
wallet::currentWalletCapabilities(), ui::NavPageSurface(page));
|
||||
}
|
||||
|
||||
std::string unencryptedTransactionHistoryCacheKey(const std::string& walletIdentity)
|
||||
{
|
||||
return std::string("obsidian-dragon-unencrypted-tx-cache-v1:") +
|
||||
data::TransactionHistoryCache::walletIdentityHash(walletIdentity);
|
||||
}
|
||||
|
||||
class AppRefreshRpcGateway final : public NetworkRefreshService::RefreshRpcGateway {
|
||||
public:
|
||||
// `maintenanceOwner`: the App whose rpc_ this is, for callLong() (see App::MaintenanceCallScope).
|
||||
@@ -1961,10 +1955,7 @@ bool App::ensureTransactionHistoryCacheUnlockedFor(const std::string& walletIden
|
||||
}
|
||||
|
||||
if (state_.encryption_state_known && !state_.encrypted) {
|
||||
std::string cacheKey = unencryptedTransactionHistoryCacheKey(walletIdentity);
|
||||
bool unlocked = transaction_history_cache_.unlockWithPassphrase(walletIdentity, cacheKey);
|
||||
util::SecureVault::secureZero(cacheKey.data(), cacheKey.size());
|
||||
return unlocked;
|
||||
return transaction_history_cache_.unlockUnencrypted(walletIdentity);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user