diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 0dd7da65545..fa15f02c8c6 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -42,6 +42,11 @@ public: //! Use this for more parameters to key derivation (currently unused) std::vector vchOtherDerivationParameters; + //! Default/minimum number of key derivation rounds + // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M + // ie slightly lower than the lowest hardware we need bother supporting + static constexpr unsigned int DEFAULT_DERIVE_ITERATIONS = 25000; + SERIALIZE_METHODS(CMasterKey, obj) { READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters); @@ -49,9 +54,7 @@ public: CMasterKey() { - // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M - // ie slightly lower than the lowest hardware we need bother supporting - nDeriveIterations = 25000; + nDeriveIterations = DEFAULT_DERIVE_ITERATIONS; nDerivationMethod = 0; vchOtherDerivationParameters = std::vector(0); } diff --git a/src/wallet/test/fuzz/crypter.cpp b/src/wallet/test/fuzz/crypter.cpp index 7869f5f39c8..c1454c6e059 100644 --- a/src/wallet/test/fuzz/crypter.cpp +++ b/src/wallet/test/fuzz/crypter.cpp @@ -38,7 +38,7 @@ FUZZ_TARGET(crypter, .init = initialize_crypter) // Limiting the value of rounds since it is otherwise uselessly expensive and causes a timeout when fuzzing. crypt.SetKeyFromPassphrase(/*key_data=*/secure_string, /*salt=*/ConsumeFixedLengthByteVector(fuzzed_data_provider, WALLET_CRYPTO_SALT_SIZE), - /*rounds=*/fuzzed_data_provider.ConsumeIntegralInRange(0, 25000), + /*rounds=*/fuzzed_data_provider.ConsumeIntegralInRange(0, CMasterKey::DEFAULT_DERIVE_ITERATIONS), /*derivation_method=*/derivation_method); } diff --git a/src/wallet/test/wallet_crypto_tests.cpp b/src/wallet/test/wallet_crypto_tests.cpp index 7c74c313088..e01c7a4e5cf 100644 --- a/src/wallet/test/wallet_crypto_tests.cpp +++ b/src/wallet/test/wallet_crypto_tests.cpp @@ -83,7 +83,7 @@ static void TestEncrypt(const CCrypter& crypt, const std::span salt{"0000deadbeef0000"_hex_u8}; CCrypter crypt; - crypt.SetKeyFromPassphrase("passphrase", salt, 25000, 0); + crypt.SetKeyFromPassphrase("passphrase", salt, CMasterKey::DEFAULT_DERIVE_ITERATIONS, 0); TestCrypter::TestEncrypt(crypt, "22bcade09ac03ff6386914359cfe885cfeb5f77ff0d670f102f619687453b29d"_hex_u8); for (int i = 0; i != 100; i++) @@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(encrypt) { BOOST_AUTO_TEST_CASE(decrypt) { constexpr std::array salt{"0000deadbeef0000"_hex_u8}; CCrypter crypt; - crypt.SetKeyFromPassphrase("passphrase", salt, 25000, 0); + crypt.SetKeyFromPassphrase("passphrase", salt, CMasterKey::DEFAULT_DERIVE_ITERATIONS, 0); // Some corner cases the came up while testing TestCrypter::TestDecrypt(crypt,"795643ce39d736088367822cdc50535ec6f103715e3e48f4f3b1a60a08ef59ca"_hex_u8); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index dd9dfcd516a..1f34bea4415 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -628,8 +628,8 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start))) / 2; - if (pMasterKey.second.nDeriveIterations < 25000) - pMasterKey.second.nDeriveIterations = 25000; + if (pMasterKey.second.nDeriveIterations < CMasterKey::DEFAULT_DERIVE_ITERATIONS) + pMasterKey.second.nDeriveIterations = CMasterKey::DEFAULT_DERIVE_ITERATIONS; WalletLogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations); @@ -825,15 +825,15 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) CCrypter crypter; constexpr MillisecondsDouble target{100}; auto start{SteadyClock::now()}; - crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); - kMasterKey.nDeriveIterations = static_cast(25000 * target / (SteadyClock::now() - start)); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, CMasterKey::DEFAULT_DERIVE_ITERATIONS, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = static_cast(CMasterKey::DEFAULT_DERIVE_ITERATIONS * target / (SteadyClock::now() - start)); start = SteadyClock::now(); crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod); kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast(kMasterKey.nDeriveIterations * target / (SteadyClock::now() - start))) / 2; - if (kMasterKey.nDeriveIterations < 25000) - kMasterKey.nDeriveIterations = 25000; + if (kMasterKey.nDeriveIterations < CMasterKey::DEFAULT_DERIVE_ITERATIONS) + kMasterKey.nDeriveIterations = CMasterKey::DEFAULT_DERIVE_ITERATIONS; WalletLogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);