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) 2016-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#include <crypto/aes.h>6#include <support/allocators/secure.h>8#include <cstring>10extern "C" {11#include <crypto/ctaes/ctaes.c>12}14AES256Encrypt::AES256Encrypt(const unsigned char key[32])15{16ctx = allocator.allocate(1);17AES256_init(ctx, key);18}20AES256Encrypt::~AES256Encrypt()21{22allocator.deallocate(ctx, 1);23}25void AES256Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const26{27AES256_encrypt(ctx, 1, ciphertext, plaintext);28}30AES256Decrypt::AES256Decrypt(const unsigned char key[32])31{32ctx = allocator.allocate(1);33AES256_init(ctx, key);34}36AES256Decrypt::~AES256Decrypt()37{38allocator.deallocate(ctx, 1);39}41void AES256Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const42{43AES256_decrypt(ctx, 1, plaintext, ciphertext);44}47template <typename T>48static int CBCEncrypt(const T& enc, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)49{50int written = 0;51int padsize = size % AES_BLOCKSIZE;52unsigned char mixed[AES_BLOCKSIZE];54if (!data || !size || !out)55return 0;57if (!pad && padsize != 0)58return 0;60memcpy(mixed, iv, AES_BLOCKSIZE);62// Write all but the last block63while (written + AES_BLOCKSIZE <= size) {64for (int i = 0; i != AES_BLOCKSIZE; i++)65mixed[i] ^= *data++;66enc.Encrypt(out + written, mixed);67memcpy(mixed, out + written, AES_BLOCKSIZE);68written += AES_BLOCKSIZE;69}70if (pad) {71// For all that remains, pad each byte with the value of the remaining72// space. If there is none, pad by a full block.73for (int i = 0; i != padsize; i++)74mixed[i] ^= *data++;75for (int i = padsize; i != AES_BLOCKSIZE; i++)76mixed[i] ^= AES_BLOCKSIZE - padsize;77enc.Encrypt(out + written, mixed);78written += AES_BLOCKSIZE;79}80return written;81}83template <typename T>84static int CBCDecrypt(const T& dec, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)85{86int written = 0;87bool fail = false;88const unsigned char* prev = iv;90if (!data || !size || !out)91return 0;93if (size % AES_BLOCKSIZE != 0)94return 0;96// Decrypt all data. Padding will be checked in the output.97while (written != size) {98dec.Decrypt(out, data + written);99for (int i = 0; i != AES_BLOCKSIZE; i++)100*out++ ^= prev[i];101prev = data + written;102written += AES_BLOCKSIZE;103}105// When decrypting padding, attempt to run in constant-time106if (pad) {107// If used, padding size is the value of the last decrypted byte. For108// it to be valid, It must be between 1 and AES_BLOCKSIZE.109unsigned char padsize = *--out;110fail = !padsize | (padsize > AES_BLOCKSIZE);112// If not well-formed, treat it as though there's no padding.113padsize *= !fail;115// All padding must equal the last byte otherwise it's not well-formed116for (int i = AES_BLOCKSIZE; i != 0; i--)117fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize));119written -= padsize;120}121return written * !fail;122}124AES256CBCEncrypt::AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)125: enc(key), pad(padIn)126{127iv = allocator.allocate(AES_BLOCKSIZE);128memcpy(iv, ivIn, AES_BLOCKSIZE);129}131int AES256CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const132{133return CBCEncrypt(enc, iv, data, size, pad, out);134}136AES256CBCEncrypt::~AES256CBCEncrypt()137{138allocator.deallocate(iv, AES_BLOCKSIZE);139}141AES256CBCDecrypt::AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)142: dec(key), pad(padIn)143{144iv = allocator.allocate(AES_BLOCKSIZE);145memcpy(iv, ivIn, AES_BLOCKSIZE);146}149int AES256CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const150{151return CBCDecrypt(dec, iv, data, size, pad, out);152}154AES256CBCDecrypt::~AES256CBCDecrypt()155{156allocator.deallocate(iv, AES_BLOCKSIZE);157}
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.