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.
1/*********************************************************************2* Copyright (c) 2016 Pieter Wuille *3* Distributed under the MIT software license, see the accompanying *4* file COPYING or http://www.opensource.org/licenses/mit-license.php.*5**********************************************************************/7/* Constant time, unoptimized, concise, plain C, AES implementation8* Based On:9* Emilia Kasper and Peter Schwabe, Faster and Timing-Attack Resistant AES-GCM10* http://www.iacr.org/archive/ches2009/57470001/57470001.pdf11* But using 8 16-bit integers representing a single AES state rather than 8 128-bit12* integers representing 8 AES states.13*/15#include "ctaes.h"17/* Slice variable slice_i contains the i'th bit of the 16 state variables in this order:18* 0 1 2 319* 4 5 6 720* 8 9 10 1121* 12 13 14 1522*/24/** Convert a byte to sliced form, storing it corresponding to given row and column in s */25static void LoadByte(AES_state* s, unsigned char byte, int r, int c) {26int i;27for (i = 0; i < 8; i++) {28s->slice[i] |= (byte & 1) << (r * 4 + c);29byte >>= 1;30}31}33/** Load 16 bytes of data into 8 sliced integers */34static void LoadBytes(AES_state *s, const unsigned char* data16) {35int c;36for (c = 0; c < 4; c++) {37int r;38for (r = 0; r < 4; r++) {39LoadByte(s, *(data16++), r, c);40}41}42}44/** Convert 8 sliced integers into 16 bytes of data */45static void SaveBytes(unsigned char* data16, const AES_state *s) {46int c;47for (c = 0; c < 4; c++) {48int r;49for (r = 0; r < 4; r++) {50int b;51uint8_t v = 0;52for (b = 0; b < 8; b++) {53v |= ((s->slice[b] >> (r * 4 + c)) & 1) << b;54}55*(data16++) = v;56}57}58}60/* S-box implementation based on the gate logic from:61* Joan Boyar and Rene Peralta, A depth-16 circuit for the AES S-box.62* https://eprint.iacr.org/2011/332.pdf63*/64static void SubBytes(AES_state *s, int inv) {65/* Load the bit slices */66uint16_t U0 = s->slice[7], U1 = s->slice[6], U2 = s->slice[5], U3 = s->slice[4];67uint16_t U4 = s->slice[3], U5 = s->slice[2], U6 = s->slice[1], U7 = s->slice[0];69uint16_t T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16;70uint16_t T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, D;71uint16_t M1, M6, M11, M13, M15, M20, M21, M22, M23, M25, M37, M38, M39, M40;72uint16_t M41, M42, M43, M44, M45, M46, M47, M48, M49, M50, M51, M52, M53, M54;73uint16_t M55, M56, M57, M58, M59, M60, M61, M62, M63;75if (inv) {76uint16_t R5, R13, R17, R18, R19;77/* Undo linear postprocessing */78T23 = U0 ^ U3;79T22 = ~(U1 ^ U3);80T2 = ~(U0 ^ U1);81T1 = U3 ^ U4;82T24 = ~(U4 ^ U7);83R5 = U6 ^ U7;84T8 = ~(U1 ^ T23);85T19 = T22 ^ R5;86T9 = ~(U7 ^ T1);87T10 = T2 ^ T24;88T13 = T2 ^ R5;89T3 = T1 ^ R5;90T25 = ~(U2 ^ T1);91R13 = U1 ^ U6;92T17 = ~(U2 ^ T19);93T20 = T24 ^ R13;94T4 = U4 ^ T8;95R17 = ~(U2 ^ U5);96R18 = ~(U5 ^ U6);97R19 = ~(U2 ^ U4);98D = U0 ^ R17;99T6 = T22 ^ R17;100T16 = R13 ^ R19;101T27 = T1 ^ R18;102T15 = T10 ^ T27;103T14 = T10 ^ R18;104T26 = T3 ^ T16;105} else {106/* Linear preprocessing. */107T1 = U0 ^ U3;108T2 = U0 ^ U5;109T3 = U0 ^ U6;110T4 = U3 ^ U5;111T5 = U4 ^ U6;112T6 = T1 ^ T5;113T7 = U1 ^ U2;114T8 = U7 ^ T6;115T9 = U7 ^ T7;116T10 = T6 ^ T7;117T11 = U1 ^ U5;118T12 = U2 ^ U5;119T13 = T3 ^ T4;120T14 = T6 ^ T11;121T15 = T5 ^ T11;122T16 = T5 ^ T12;123T17 = T9 ^ T16;124T18 = U3 ^ U7;125T19 = T7 ^ T18;126T20 = T1 ^ T19;127T21 = U6 ^ U7;128T22 = T7 ^ T21;129T23 = T2 ^ T22;130T24 = T2 ^ T10;131T25 = T20 ^ T17;132T26 = T3 ^ T16;133T27 = T1 ^ T12;134D = U7;135}137/* Non-linear transformation (shared between the forward and backward case) */138M1 = T13 & T6;139M6 = T3 & T16;140M11 = T1 & T15;141M13 = (T4 & T27) ^ M11;142M15 = (T2 & T10) ^ M11;143M20 = T14 ^ M1 ^ (T23 & T8) ^ M13;144M21 = (T19 & D) ^ M1 ^ T24 ^ M15;145M22 = T26 ^ M6 ^ (T22 & T9) ^ M13;146M23 = (T20 & T17) ^ M6 ^ M15 ^ T25;147M25 = M22 & M20;148M37 = M21 ^ ((M20 ^ M21) & (M23 ^ M25));149M38 = M20 ^ M25 ^ (M21 | (M20 & M23));150M39 = M23 ^ ((M22 ^ M23) & (M21 ^ M25));151M40 = M22 ^ M25 ^ (M23 | (M21 & M22));152M41 = M38 ^ M40;153M42 = M37 ^ M39;154M43 = M37 ^ M38;155M44 = M39 ^ M40;156M45 = M42 ^ M41;157M46 = M44 & T6;158M47 = M40 & T8;159M48 = M39 & D;160M49 = M43 & T16;161M50 = M38 & T9;162M51 = M37 & T17;163M52 = M42 & T15;164M53 = M45 & T27;165M54 = M41 & T10;166M55 = M44 & T13;167M56 = M40 & T23;168M57 = M39 & T19;169M58 = M43 & T3;170M59 = M38 & T22;171M60 = M37 & T20;172M61 = M42 & T1;173M62 = M45 & T4;174M63 = M41 & T2;176if (inv){177/* Undo linear preprocessing */178uint16_t P0 = M52 ^ M61;179uint16_t P1 = M58 ^ M59;180uint16_t P2 = M54 ^ M62;181uint16_t P3 = M47 ^ M50;182uint16_t P4 = M48 ^ M56;183uint16_t P5 = M46 ^ M51;184uint16_t P6 = M49 ^ M60;185uint16_t P7 = P0 ^ P1;186uint16_t P8 = M50 ^ M53;187uint16_t P9 = M55 ^ M63;188uint16_t P10 = M57 ^ P4;189uint16_t P11 = P0 ^ P3;190uint16_t P12 = M46 ^ M48;191uint16_t P13 = M49 ^ M51;192uint16_t P14 = M49 ^ M62;193uint16_t P15 = M54 ^ M59;194uint16_t P16 = M57 ^ M61;195uint16_t P17 = M58 ^ P2;196uint16_t P18 = M63 ^ P5;197uint16_t P19 = P2 ^ P3;198uint16_t P20 = P4 ^ P6;199uint16_t P22 = P2 ^ P7;200uint16_t P23 = P7 ^ P8;201uint16_t P24 = P5 ^ P7;202uint16_t P25 = P6 ^ P10;203uint16_t P26 = P9 ^ P11;204uint16_t P27 = P10 ^ P18;205uint16_t P28 = P11 ^ P25;206uint16_t P29 = P15 ^ P20;207s->slice[7] = P13 ^ P22;208s->slice[6] = P26 ^ P29;209s->slice[5] = P17 ^ P28;210s->slice[4] = P12 ^ P22;211s->slice[3] = P23 ^ P27;212s->slice[2] = P19 ^ P24;213s->slice[1] = P14 ^ P23;214s->slice[0] = P9 ^ P16;215} else {216/* Linear postprocessing */217uint16_t L0 = M61 ^ M62;218uint16_t L1 = M50 ^ M56;219uint16_t L2 = M46 ^ M48;220uint16_t L3 = M47 ^ M55;221uint16_t L4 = M54 ^ M58;222uint16_t L5 = M49 ^ M61;223uint16_t L6 = M62 ^ L5;224uint16_t L7 = M46 ^ L3;225uint16_t L8 = M51 ^ M59;226uint16_t L9 = M52 ^ M53;227uint16_t L10 = M53 ^ L4;228uint16_t L11 = M60 ^ L2;229uint16_t L12 = M48 ^ M51;230uint16_t L13 = M50 ^ L0;231uint16_t L14 = M52 ^ M61;232uint16_t L15 = M55 ^ L1;233uint16_t L16 = M56 ^ L0;234uint16_t L17 = M57 ^ L1;235uint16_t L18 = M58 ^ L8;236uint16_t L19 = M63 ^ L4;237uint16_t L20 = L0 ^ L1;238uint16_t L21 = L1 ^ L7;239uint16_t L22 = L3 ^ L12;240uint16_t L23 = L18 ^ L2;241uint16_t L24 = L15 ^ L9;242uint16_t L25 = L6 ^ L10;243uint16_t L26 = L7 ^ L9;244uint16_t L27 = L8 ^ L10;245uint16_t L28 = L11 ^ L14;246uint16_t L29 = L11 ^ L17;247s->slice[7] = L6 ^ L24;248s->slice[6] = ~(L16 ^ L26);249s->slice[5] = ~(L19 ^ L28);250s->slice[4] = L6 ^ L21;
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.