Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2009-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#ifndef BITCOIN_WALLET_CRYPTER_H6#define BITCOIN_WALLET_CRYPTER_H8#include <serialize.h>9#include <support/allocators/secure.h>10#include <script/signingprovider.h>13namespace wallet {14inline constexpr unsigned int WALLET_CRYPTO_KEY_SIZE = 32;15inline constexpr unsigned int WALLET_CRYPTO_SALT_SIZE = 8;16inline constexpr unsigned int WALLET_CRYPTO_IV_SIZE = 16;18/**19* Private key encryption is done based on a CMasterKey,20* which holds a salt and random encryption key.21*22* CMasterKeys are encrypted using AES-256-CBC using a key23* derived using derivation method nDerivationMethod24* (0 == EVP_sha512()) and derivation iterations nDeriveIterations.25* vchOtherDerivationParameters is provided for alternative algorithms26* which may require more parameters.27*28* Wallet Private Keys are then encrypted using AES-256-CBC29* with the double-sha256 of the public key as the IV, and the30* master key's key as the encryption key (see keystore.[ch]).31*/33/** Master key for wallet encryption */34class CMasterKey35{36public:37std::vector<unsigned char> vchCryptedKey;38std::vector<unsigned char> vchSalt;39//! 0 = EVP_sha512()40unsigned int nDerivationMethod;41unsigned int nDeriveIterations;42//! Use this for more parameters to key derivation (currently unused)43std::vector<unsigned char> vchOtherDerivationParameters;45//! Default/minimum number of key derivation rounds46// 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M47// ie slightly lower than the lowest hardware we need bother supporting48static constexpr unsigned int DEFAULT_DERIVE_ITERATIONS = 25000;50SERIALIZE_METHODS(CMasterKey, obj)51{52READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters);53}55CMasterKey()56{57nDeriveIterations = DEFAULT_DERIVE_ITERATIONS;58nDerivationMethod = 0;59vchOtherDerivationParameters = std::vector<unsigned char>(0);60}61};63typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;65namespace wallet_crypto_tests66{67class TestCrypter;68}70/** Encryption/decryption context with key information */71class CCrypter72{73friend class wallet_crypto_tests::TestCrypter; // for test access to chKey/chIV74private:75std::vector<unsigned char, secure_allocator<unsigned char>> vchKey;76std::vector<unsigned char, secure_allocator<unsigned char>> vchIV;77bool fKeySet;79[[nodiscard]] int BytesToKeySHA512AES(std::span<const unsigned char> salt, const SecureString& key_data, unsigned int count, unsigned char* key, unsigned char* iv) const;81public:82[[nodiscard]] bool SetKeyFromPassphrase(const SecureString& key_data, std::span<const unsigned char> salt, unsigned int rounds, unsigned int derivation_method);83[[nodiscard]] bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) const;84[[nodiscard]] bool Decrypt(std::span<const unsigned char> ciphertext, CKeyingMaterial& plaintext) const;85[[nodiscard]] bool SetKey(const CKeyingMaterial& new_key, std::span<const unsigned char> new_iv);87void CleanKey()88{89memory_cleanse(vchKey.data(), vchKey.size());90memory_cleanse(vchIV.data(), vchIV.size());91fKeySet = false;92}94CCrypter()95{96fKeySet = false;97vchKey.resize(WALLET_CRYPTO_KEY_SIZE);98vchIV.resize(WALLET_CRYPTO_IV_SIZE);99}101~CCrypter()102{103CleanKey();104}105};107[[nodiscard]] bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);108[[nodiscard]] bool DecryptSecret(const CKeyingMaterial& master_key, std::span<const unsigned char> ciphertext, const uint256& iv, CKeyingMaterial& plaintext);109[[nodiscard]] bool DecryptKey(const CKeyingMaterial& master_key, std::span<const unsigned char> crypted_secret, const CPubKey& pub_key, CKey& key);110} // namespace wallet112#endif // BITCOIN_WALLET_CRYPTER_H