Inside Bitcoin
Opening the selected file…
Inside Bitcoin
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.
251s->slice[3] = L20 ^ L22;252s->slice[2] = L25 ^ L29;253s->slice[1] = ~(L13 ^ L27);254s->slice[0] = ~(L6 ^ L23);255}256}258#define BIT_RANGE(from,to) (((1 << ((to) - (from))) - 1) << (from))260#define BIT_RANGE_LEFT(x,from,to,shift) (((x) & BIT_RANGE((from), (to))) << (shift))261#define BIT_RANGE_RIGHT(x,from,to,shift) (((x) & BIT_RANGE((from), (to))) >> (shift))263static void ShiftRows(AES_state* s) {264int i;265for (i = 0; i < 8; i++) {266uint16_t v = s->slice[i];267s->slice[i] =268(v & BIT_RANGE(0, 4)) |269BIT_RANGE_LEFT(v, 4, 5, 3) | BIT_RANGE_RIGHT(v, 5, 8, 1) |270BIT_RANGE_LEFT(v, 8, 10, 2) | BIT_RANGE_RIGHT(v, 10, 12, 2) |271BIT_RANGE_LEFT(v, 12, 15, 1) | BIT_RANGE_RIGHT(v, 15, 16, 3);272}273}275static void InvShiftRows(AES_state* s) {276int i;277for (i = 0; i < 8; i++) {278uint16_t v = s->slice[i];279s->slice[i] =280(v & BIT_RANGE(0, 4)) |281BIT_RANGE_LEFT(v, 4, 7, 1) | BIT_RANGE_RIGHT(v, 7, 8, 3) |282BIT_RANGE_LEFT(v, 8, 10, 2) | BIT_RANGE_RIGHT(v, 10, 12, 2) |283BIT_RANGE_LEFT(v, 12, 13, 3) | BIT_RANGE_RIGHT(v, 13, 16, 1);284}285}287#define ROT(x,b) (((x) >> ((b) * 4)) | ((x) << ((4-(b)) * 4)))289static void MixColumns(AES_state* s, int inv) {290/* The MixColumns transform treats the bytes of the columns of the state as291* coefficients of a 3rd degree polynomial over GF(2^8) and multiplies them292* by the fixed polynomial a(x) = {03}x^3 + {01}x^2 + {01}x + {02}, modulo293* x^4 + {01}.294*295* In the inverse transform, we multiply by the inverse of a(x),296* a^-1(x) = {0b}x^3 + {0d}x^2 + {09}x + {0e}. This is equal to297* a(x) * ({04}x^2 + {05}), so we can reuse the forward transform's code298* (found in OpenSSL's bsaes-x86_64.pl, attributed to Jussi Kivilinna)299*300* In the bitsliced representation, a multiplication of every column by x301* mod x^4 + 1 is simply a right rotation.302*/304/* Shared for both directions is a multiplication by a(x), which can be305* rewritten as (x^3 + x^2 + x) + {02}*(x^3 + {01}).306*307* First compute s into the s? variables, (x^3 + {01}) * s into the s?_01308* variables and (x^3 + x^2 + x)*s into the s?_123 variables.309*/310uint16_t s0 = s->slice[0], s1 = s->slice[1], s2 = s->slice[2], s3 = s->slice[3];311uint16_t s4 = s->slice[4], s5 = s->slice[5], s6 = s->slice[6], s7 = s->slice[7];312uint16_t s0_01 = s0 ^ ROT(s0, 1), s0_123 = ROT(s0_01, 1) ^ ROT(s0, 3);313uint16_t s1_01 = s1 ^ ROT(s1, 1), s1_123 = ROT(s1_01, 1) ^ ROT(s1, 3);314uint16_t s2_01 = s2 ^ ROT(s2, 1), s2_123 = ROT(s2_01, 1) ^ ROT(s2, 3);315uint16_t s3_01 = s3 ^ ROT(s3, 1), s3_123 = ROT(s3_01, 1) ^ ROT(s3, 3);316uint16_t s4_01 = s4 ^ ROT(s4, 1), s4_123 = ROT(s4_01, 1) ^ ROT(s4, 3);317uint16_t s5_01 = s5 ^ ROT(s5, 1), s5_123 = ROT(s5_01, 1) ^ ROT(s5, 3);318uint16_t s6_01 = s6 ^ ROT(s6, 1), s6_123 = ROT(s6_01, 1) ^ ROT(s6, 3);319uint16_t s7_01 = s7 ^ ROT(s7, 1), s7_123 = ROT(s7_01, 1) ^ ROT(s7, 3);320/* Now compute s = s?_123 + {02} * s?_01. */321s->slice[0] = s7_01 ^ s0_123;322s->slice[1] = s7_01 ^ s0_01 ^ s1_123;323s->slice[2] = s1_01 ^ s2_123;324s->slice[3] = s7_01 ^ s2_01 ^ s3_123;325s->slice[4] = s7_01 ^ s3_01 ^ s4_123;326s->slice[5] = s4_01 ^ s5_123;327s->slice[6] = s5_01 ^ s6_123;328s->slice[7] = s6_01 ^ s7_123;329if (inv) {330/* In the reverse direction, we further need to multiply by331* {04}x^2 + {05}, which can be written as {04} * (x^2 + {01}) + {01}.332*333* First compute (x^2 + {01}) * s into the t?_02 variables: */334uint16_t t0_02 = s->slice[0] ^ ROT(s->slice[0], 2);335uint16_t t1_02 = s->slice[1] ^ ROT(s->slice[1], 2);336uint16_t t2_02 = s->slice[2] ^ ROT(s->slice[2], 2);337uint16_t t3_02 = s->slice[3] ^ ROT(s->slice[3], 2);338uint16_t t4_02 = s->slice[4] ^ ROT(s->slice[4], 2);339uint16_t t5_02 = s->slice[5] ^ ROT(s->slice[5], 2);340uint16_t t6_02 = s->slice[6] ^ ROT(s->slice[6], 2);341uint16_t t7_02 = s->slice[7] ^ ROT(s->slice[7], 2);342/* And then update s += {04} * t?_02 */343s->slice[0] ^= t6_02;344s->slice[1] ^= t6_02 ^ t7_02;345s->slice[2] ^= t0_02 ^ t7_02;346s->slice[3] ^= t1_02 ^ t6_02;347s->slice[4] ^= t2_02 ^ t6_02 ^ t7_02;348s->slice[5] ^= t3_02 ^ t7_02;349s->slice[6] ^= t4_02;350s->slice[7] ^= t5_02;351}352}354static void AddRoundKey(AES_state* s, const AES_state* round) {355int b;356for (b = 0; b < 8; b++) {357s->slice[b] ^= round->slice[b];358}359}361/** column_0(s) = column_c(a) */362static void GetOneColumn(AES_state* s, const AES_state* a, int c) {363int b;364for (b = 0; b < 8; b++) {365s->slice[b] = (a->slice[b] >> c) & 0x1111;366}367}369/** column_c1(r) |= (column_0(s) ^= column_c2(a)) */370static void KeySetupColumnMix(AES_state* s, AES_state* r, const AES_state* a, int c1, int c2) {371int b;372for (b = 0; b < 8; b++) {373r->slice[b] |= ((s->slice[b] ^= ((a->slice[b] >> c2) & 0x1111)) & 0x1111) << c1;374}375}377/** Rotate the rows in s one position upwards, and xor in r */378static void KeySetupTransform(AES_state* s, const AES_state* r) {379int b;380for (b = 0; b < 8; b++) {381s->slice[b] = ((s->slice[b] >> 4) | (s->slice[b] << 12)) ^ r->slice[b];382}383}385/* Multiply the cells in s by x, as polynomials over GF(2) mod x^8 + x^4 + x^3 + x + 1 */386static void MultX(AES_state* s) {387uint16_t top = s->slice[7];388s->slice[7] = s->slice[6];389s->slice[6] = s->slice[5];390s->slice[5] = s->slice[4];391s->slice[4] = s->slice[3] ^ top;392s->slice[3] = s->slice[2] ^ top;393s->slice[2] = s->slice[1];394s->slice[1] = s->slice[0] ^ top;395s->slice[0] = top;396}398/** Expand the cipher key into the key schedule.399*400* state must be a pointer to an array of size nrounds + 1.401* key must be a pointer to 4 * nkeywords bytes.402*403* AES128 uses nkeywords = 4, nrounds = 10404* AES192 uses nkeywords = 6, nrounds = 12405* AES256 uses nkeywords = 8, nrounds = 14406*/407static void AES_setup(AES_state* rounds, const uint8_t* key, int nkeywords, int nrounds)408{409int i;411/* The one-byte round constant */412AES_state rcon = {{1,0,0,0,0,0,0,0}};413/* The number of the word being generated, modulo nkeywords */414int pos = 0;415/* The column representing the word currently being processed */416AES_state column;418for (i = 0; i < nrounds + 1; i++) {419int b;420for (b = 0; b < 8; b++) {421rounds[i].slice[b] = 0;422}423}425/* The first nkeywords round columns are just taken from the key directly. */426for (i = 0; i < nkeywords; i++) {427int r;428for (r = 0; r < 4; r++) {429LoadByte(&rounds[i >> 2], *(key++), r, i & 3);430}431}433GetOneColumn(&column, &rounds[(nkeywords - 1) >> 2], (nkeywords - 1) & 3);435for (i = nkeywords; i < 4 * (nrounds + 1); i++) {436/* Transform column */437if (pos == 0) {438SubBytes(&column, 0);439KeySetupTransform(&column, &rcon);440MultX(&rcon);441} else if (nkeywords > 6 && pos == 4) {442SubBytes(&column, 0);443}444if (++pos == nkeywords) pos = 0;445KeySetupColumnMix(&column, &rounds[i >> 2], &rounds[(i - nkeywords) >> 2], i & 3, (i - nkeywords) & 3);446}447}449static void AES_encrypt(const AES_state* rounds, int nrounds, unsigned char* cipher16, const unsigned char* plain16) {450AES_state s = {{0}};451int round;453LoadBytes(&s, plain16);454AddRoundKey(&s, rounds++);456for (round = 1; round < nrounds; round++) {457SubBytes(&s, 0);458ShiftRows(&s);459MixColumns(&s, 0);460AddRoundKey(&s, rounds++);461}463SubBytes(&s, 0);464ShiftRows(&s);465AddRoundKey(&s, rounds);467SaveBytes(cipher16, &s);468}470static void AES_decrypt(const AES_state* rounds, int nrounds, unsigned char* plain16, const unsigned char* cipher16) {471/* Most AES decryption implementations use the alternate scheme472* (the Equivalent Inverse Cipher), which allows for more code reuse between473* the encryption and decryption code, but requires separate setup for both.474*/475AES_state s = {{0}};476int round;478rounds += nrounds;480LoadBytes(&s, cipher16);481AddRoundKey(&s, rounds--);483for (round = 1; round < nrounds; round++) {484InvShiftRows(&s);485SubBytes(&s, 1);486AddRoundKey(&s, rounds--);487MixColumns(&s, 1);488}490InvShiftRows(&s);491SubBytes(&s, 1);492AddRoundKey(&s, rounds);494SaveBytes(plain16, &s);495}497void AES128_init(AES128_ctx* ctx, const unsigned char* key16) {498AES_setup(ctx->rk, key16, 4, 10);499}
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.