The Advanced Encryption Standard (AES)

In 1997 the United States government faced a quiet crisis. The reigning Data Encryption Standard had a key space so small. A dedicated machine could exhaust it in hours. Every bank transfer, VPN tunnel, and government cable leaning on DES was one custom chip away from exposure. The National Institute of Standards and Technology answered with an open worldwide competition. It invited cryptographers everywhere to submit a replacement. It also invited everyone else to try to break it. The winner, a Belgian design called Rijndael, became the Advanced Encryption Standard in 2001. AES is not a patch on an old idea. It is a different architectural philosophy. DES pushes bits through a narrow Feistel pipe one round at a time. AES instead treats an entire 128-bit block as a small rectangular array of bytes. It transforms the whole array simultaneously in each round. This is a substitution-permutation network (SPN). Every round mixes a nonlinear substitution step with a linear diffusion step. Together these spread the influence of a single input bit across the entire block within a few rounds. The stakes for getting this right are enormous. AES now protects nearly every TLS connection. It encrypts disks via BitLocker and FileVault. It secures Wi-Fi under WPA2/WPA3. It also underlies hardware secure enclaves in every modern phone and laptop. Intel and ARM built dedicated AES instructions directly into their CPUs (AES-NI, ARMv8 Crypto Extensions). The cipher is used so pervasively that a few clock cycles per byte matter at a planetary scale. This article builds AES from the ground up. It covers the finite-field arithmetic underneath its S-box. It explains the four round transformations and why each exists. It describes the key schedule that derives round keys. It also gives the reasoning — both structural and quantitative — behind why 10, 12, or 14 rounds resist every known practical attack. It closes by situating AES among its historical rivals. Finally, it previews how AES is embedded into the Modes of Operation that turn a single-block cipher into a system for encrypting real messages.

Key takeaways
  • AES is a substitution-permutation network operating on a 4×4 byte grid (the state), not a Feistel network like DES.
  • Key sizes of 128, 192, or 256 bits give 10, 12, or 14 rounds respectively; block size is fixed at 128 bits.
  • Each round applies SubBytes (nonlinear S-box), ShiftRows (byte permutation), MixColumns (linear diffusion), and AddRoundKey (XOR with a derived subkey).
  • The S-box is built from multiplicative inverse in GF(28)GF(2^8) composed with an affine map, giving strong resistance to linear and differential cryptanalysis.
  • The key schedule expands the master key into round keys using rotation, the S-box, and round constants, avoiding related-key weaknesses (mostly).
  • After 20+ years of public cryptanalysis, no attack against full-round AES is faster than brute force in any practical threat model — it remains the world's default symmetric cipher.
The core insight

AES achieves fast, provably-structured security by alternating an algebraic nonlinear substitution with linear diffusion across a byte-grid state, repeated enough rounds to make every output bit an intractably complex function of every input bit and key bit.

The idea

AES is a substitution-permutation network (SPN): a block cipher built from a fixed number of rounds, each combining a confusion layer (nonlinear substitution) with a diffusion layer (linear mixing). This contrasts with the PRP abstraction instantiated by DES's Feistel structure, where only half the block is transformed per round and diffusion accumulates slowly. AES instead transforms the entire 128-bit block at once, arranged as a 4×4 matrix of bytes called the state:

State=(s0,0s0,1s0,2s0,3s1,0s1,1s1,2s1,3s2,0s2,1s2,2s2,3s3,0s3,1s3,2s3,3)\text{State} = \begin{pmatrix} s_{0,0} & s_{0,1} & s_{0,2} & s_{0,3}\\ s_{1,0} & s_{1,1} & s_{1,2} & s_{1,3}\\ s_{2,0} & s_{2,1} & s_{2,2} & s_{2,3}\\ s_{3,0} & s_{3,1} & s_{3,2} & s_{3,3} \end{pmatrix}

The 16 input bytes fill this matrix column by column. AES supports three key lengths — 128, 192, and 256 bits — which fix the number of rounds NrN_r to 10, 12, and 14 respectively. A longer key does not change the block size (always 128 bits) but adds rounds, since a longer key schedule needs more mixing to fully "use up" the extra key material and resist related-key attacks. Every internal operation lives inside the finite field GF(28)GF(2^8), represented as polynomials over GF(2)GF(2) modulo the irreducible polynomial

m(x)=x8+x4+x3+x+1.m(x) = x^8 + x^4 + x^3 + x + 1.

Byte addition is XOR; byte multiplication is polynomial multiplication modulo m(x)m(x). This field structure is what makes the S-box (built from multiplicative inversion in the field) simultaneously algebraically clean — so its properties are provable — and cryptographically strong, since inversion in GF(28)GF(2^8) has near-optimal nonlinearity and no fixed points that would help a linear attacker.

How it works

Each AES round (except the last) applies four transformations in sequence to the state:

1. SubBytes — every byte is replaced independently using a fixed 256-entry lookup table, the S-box. Mathematically, byte bb maps to b−1b^{-1} in GF(28)GF(2^8) (with 0↦00 \mapsto 0), followed by a fixed GF(2)GF(2)-affine transformation:

S(b)=A⋅b−1+cS(b) = A \cdot b^{-1} + c

where AA is a fixed invertible matrix over GF(2)GF(2) and cc is a fixed constant byte. This is the confusion layer: it is the only nonlinear step in the whole cipher, and it is applied to every byte independently.

2. ShiftRows — row ii of the state is cyclically shifted left by ii bytes (i=0,1,2,3i = 0,1,2,3). Row 0 is untouched; row 3 shifts by three positions. This diffuses bytes across columns, since MixColumns (next) only mixes within a column — ShiftRows ensures that after a few rounds, every output byte depends on bytes from every input column.

3. MixColumns — each column, viewed as a 4-term polynomial over GF(28)GF(2^8), is multiplied by a fixed polynomial modulo x4+1x^4+1. Equivalently, each column vector c=(s0,s1,s2,s3)Tc = (s_0,s_1,s_2,s_3)^T is left-multiplied by the fixed matrix

(2311123111233112)\begin{pmatrix} 2&3&1&1\\1&2&3&1\\1&1&2&3\\3&1&1&2\end{pmatrix}

with all arithmetic in GF(28)GF(2^8). This matrix is MDS (maximum distance separable): any change to a single input byte changes all four output bytes, giving maximal diffusion within a column with minimal cost.

4. AddRoundKey — the state is XORed, byte by byte, with a 128-bit round key derived from the master key by the key schedule. The final round omits MixColumns (a design choice that makes encryption and decryption structurally symmetric and doesn't weaken security, since one more linear layer at the very end would not add nonlinear confusion).

Key schedule

The master key is expanded into Nr+1N_r+1 round keys (each 128 bits, i.e. 4 words of 32 bits) via a recursive schedule. For 128-bit keys, the total expanded key is 4×(Nr+1)=444 \times (N_r+1) = 44 words. Every fourth word applies a nonlinear transformation: rotate the word's bytes, substitute each byte through the S-box, then XOR with a round constant Rcon[i]\text{Rcon}[i] that breaks symmetry between rounds and prevents slide-style attacks. ``` PSEUDOCODE — AES Encryption (128-bit key, Nr = 10) function AES_Encrypt(plaintext[16], key[16]): state ← plaintext arranged column-major into 4x4 byte matrix w[0..43] ← KeyExpansion(key) // 44 words, 4 per round key state ← AddRoundKey(state, w[0..3]) // whitening: round 0 for round in 1 .. Nr - 1: state ← SubBytes(state) state ← ShiftRows(state) state ← MixColumns(state) state ← AddRoundKey(state, w[4round .. 4round+3]) // final round: no MixColumns state ← SubBytes(state) state ← ShiftRows(state) state ← AddRoundKey(state, w[4Nr .. 4Nr+3]) return state as ciphertext[16]

function KeyExpansion(key[16]): w[0..3] ← key split into 4 words (32 bits each) for i in 4 .. 43: temp ← w[i-1] if i mod 4 == 0: temp ← SubWord(RotWord(temp)) XOR Rcon[i/4] w[i] ← w[i-4] XOR temp return w

function SubBytes(state): for each byte b in state: b ← S_BOX[b] // fixed 256-entry table return state function ShiftRows(state): for row r in 0..3: state[r] ← CyclicLeftShift(state[r], r) return state function MixColumns(state): for each column c in state: c ← MDS_MATRIX × c // multiplication in GF(2^8) return state function AddRoundKey(state, roundKeyWords[4]): state ← state XOR roundKeyWords // byte-wise XOR return state ``` Decryption applies the inverse transformations (`InvSubBytes`, `InvShiftRows`, `InvMixColumns`) in reverse order with round keys used in reverse. Because MixColumns is linear and invertible over GF(28)GF(2^8), and SubBytes is a fixed invertible S-box, every step has a clean, efficiently computable inverse — this is essential for AES to be a genuine pseudorandom permutation rather than a one-way function.

Figure
One AES round: SubBytes → ShiftRows → MixColumns → AddRoundKey acting on the 4×4 state
State → SubBytes S[byte] per cell → ShiftRows shift 0 shift 1 → shift 2 →→ shift 3 →→→ → MixColumns GF(2⁸) mix per column → AddRoundKey ⊕ round key

Complexity & correctness

Time complexity. Each round performs O(1)O(1) work per byte across a fixed 16-byte state: SubBytes is 16 table lookups, ShiftRows is a fixed byte permutation, MixColumns is 16 constant-size field multiplications, AddRoundKey is 16 XORs. With Nr∈{10,12,14}N_r \in \{10,12,14\} fixed rounds, one block encryption is O(1)O(1) time in the block size (constant work per fixed-size block), or more precisely Θ(Nr)\Theta(N_r) table operations — a small constant. On modern hardware with AES-NI, an entire round compiles to a single instruction, giving throughput of several GB/s per core. Encrypting an nn-byte message under a chosen mode of operation costs Θ(n)\Theta(n) block operations, i.e. linear in message length.

Space complexity. O(1)O(1) beyond the message itself: the state is a fixed 16 bytes, the expanded key schedule is a fixed 4(Nr+1)4(N_r+1) words (176, 208, or 240 bytes), and the S-box table is a fixed 256-byte constant. No dynamic memory scales with input size except for the buffer holding the message being processed.

Correctness (decryptability). Decryption is correct because every round function is a bijection on the state space and the inverse pipeline applies the true inverses in reverse order. Formally, if round rr applies fr=AddRoundKeyr∘MixColumns∘ShiftRows∘SubBytesf_r = \text{AddRoundKey}_r \circ \text{MixColumns} \circ \text{ShiftRows} \circ \text{SubBytes}, then

fr−1=SubBytes−1∘ShiftRows−1∘MixColumns−1∘AddRoundKeyrf_r^{-1} = \text{SubBytes}^{-1} \circ \text{ShiftRows}^{-1} \circ \text{MixColumns}^{-1} \circ \text{AddRoundKey}_r

(AddRoundKey is its own inverse under XOR). Composing these in reverse order recovers the original state exactly — this is a straightforward induction on rounds, using that g∘g−1=idg \circ g^{-1} = \text{id} for each layer and that composition of bijections is invertible by reversing the order.

Security argument (why it resists cryptanalysis). AES's security is not proven in an absolute sense — like all practical block ciphers, its strength rests on 20+ years of failed attacks — but its design gives quantitative resistance guarantees against the two classical attack families:

  • Differential cryptanalysis looks for input differences that propagate to output differences with high probability. The AES S-box has maximum differential probability 2−62^{-6} for any nontrivial input/output difference, and the MixColumns matrix being MDS guarantees that any active S-box in one round forces at least 4 active S-boxes in the next two rounds combined (the branch number is 5). Over 4 rounds this forces at least 25 active S-boxes, driving the best differential trail probability down to roughly 2−6×25=2−1502^{-6 \times 25} = 2^{-150} — far below the 2−1282^{-128} security target, meaning full-round differential attacks are infeasible.
  • Linear cryptanalysis similarly exploits linear approximations to the S-box; the AES S-box has maximum linear bias 2−42^{-4} relative to 2−12^{-1} (uniform), and the same branch-number argument bounds the best linear approximation's correlation to well below what's needed to recover key bits faster than brute force.

The number of rounds (10 for 128-bit keys) is chosen with margin: the best known attacks on reduced-round AES-128 reach about 7 rounds with impractical time/data complexity, leaving a comfortable security margin over the full 10 rounds actually used.

Tradeoffs. AES's design trades a slightly larger, more structured state (versus DES's narrow Feistel channel) for far superior parallelism and diffusion speed — a good tradeoff on modern hardware but one reason it needed dedicated silicon support (AES-NI) to match DES's decades of hand-optimized software implementations at launch. Its clean algebraic structure (everything reduces to GF(28)GF(2^8) arithmetic) also made it the first major cipher subjected to serious algebraic cryptanalysis (XSL attacks), though these remain theoretical and far from practical.

Worked example

Trace one round of AES-128 acting on a single state, focusing on how a one-byte change diffuses. Suppose the state (shown as hex bytes, column-major) begins as:

col0col1col2col3
row0328831E0
row1435A3137
row2F6309807
row3A88DA234

This is the well-known FIPS-197 test-vector plaintext state. Step through one round:

SubBytes. Each byte is replaced via the S-box, e.g. `32 → 23`, `88 → C4`, `31 → C7`, `E0 → E1`, ... (looked up from the fixed table). The transformation is nonlinear and byte-local: changing input byte `32` to `33` changes the S-box output completely (avalanche within the byte), but at this stage the change has not yet spread to other bytes.

ShiftRows. Row 1 shifts left by 1, row 2 by 2, row 3 by 3. A byte originally in row 1, column 0 moves to row 1, column 3. This step alone does not mix values — it only relocates bytes — but it guarantees that MixColumns (which only operates within a column) will next combine bytes that originated from different original columns.

MixColumns. Column 0, say (63,47,F6,A8)(63, 47, F6, A8) after the previous steps, is treated as a polynomial and multiplied by the fixed MDS matrix in GF(28)GF(2^8). Concretely the first output byte is:

s0,0′=(2⋅63)⊕(3⋅47)⊕(1⋅F6)⊕(1⋅A8)(modm(x))s'_{0,0} = (2 \cdot 63) \oplus (3 \cdot 47) \oplus (1 \cdot F6) \oplus (1 \cdot A8) \pmod{m(x)}

where 2⋅b2 \cdot b means "multiply by xx in GF(28)GF(2^8)" (a left shift, XORed with `0x1B` if overflow occurs) and 3⋅b=(2⋅b)⊕b3\cdot b = (2\cdot b)\oplus b. Because the matrix is MDS, this single output byte now depends on all four input bytes of the column — a one-bit change anywhere in the column changes this byte with overwhelming probability.

AddRoundKey. The mixed state is XORed with round key 1 (derived via `KeyExpansion`), completing the round.

Diffusion trace. If we flip a single bit in the original plaintext byte at row0,col0 and re-run the pipeline: after round 1, the change has spread to all 4 bytes of column 0 (via MixColumns) but no others (ShiftRows hasn't yet mixed columns together for this round's output). After round 2, because ShiftRows moved column-0's transformed bytes into rows 1, 2, 3 of other columns before the next MixColumns, the change spreads to all 16 bytes of the state. This is the strict avalanche criterion in action: by round 2–3, roughly half of all output bits flip on average for a single input bit flip — exactly the diffusion behavior a secure block cipher requires, and it is measurable, not merely asserted, by running the pipeline explicitly as above.

Common pitfalls & traps

PitfallWhy it happensConsequence
Confusing AES (the algorithm) with a mode of operationAES itself only encrypts one 128-bit blockUsing raw "AES encrypt" repeatedly (ECB) leaks patterns; see Modes of Operation
Treating GF(2⁸) multiplication as ordinary integer multiplicationThe `xtime` (×2) operation needs conditional XOR with `0x1B` on overflowSilently wrong ciphertext, breaks interoperability
Skipping the final round's MixColumns omissionSymmetry with earlier rounds looks "cleaner" in naive codeProduces ciphertext incompatible with the standard
Reusing key schedule words instead of recomputing Rcon correctlyOff-by-one in round-constant indexingWrong round keys, garbage plaintext on decrypt
Assuming a longer key alone gives proportionally more security margin256-bit AES has 14 rounds, not double the "strength" of 128-bit's 10Related-key attacks on AES-256's key schedule are a known (if impractical) weak spot
Implementing table lookups without cache-timing protectionS-box lookups indexed by secret data leak timing informationCache-timing side-channel attacks recover key bits

Pioneers & history

AES emerged from an open, adversarial competition rather than a closed design process — a deliberate contrast to earlier standards designed behind closed government doors.

Origins · 1 minJoan Daemen and Vincent Rijmen and how this was discovered
JD
Joan Daemen and Vincent Rijmen
1965– / 1970– · Belgian cryptographers whose joint submission, Rijndael, won the AES competition in 2000 after four years of public cryptanalysis by the global research community

History
1997
NIST announces an open competition to replace DES.
1998
Fifteen candidate ciphers are submitted for public analysis.
2000
Rijndael, by Daemen and Rijmen, is selected as the winner.
2001
FIPS-197 formally publishes AES as a US federal standard.
2010
s: AES-NI hardware instructions become standard in mainstream CPUs.

The competition itself was historic: unlike DES, whose S-boxes were altered by the NSA without public justification (later found to strengthen resistance to differential cryptanalysis, a technique not yet public at the time), every AES candidate and every design decision was published, scrutinized, and attacked in the open by academic teams worldwide. This transparency is now the accepted model for cryptographic standardization — the same open process was later used to select SHA-3 and post-quantum cryptographic standards.

Where this matters

AES sits underneath nearly the entire modern encrypted internet. TLS 1.2 and 1.3 use AES (typically in GCM mode) as the default symmetric cipher for HTTPS traffic. Disk encryption systems — BitLocker, FileVault, LUKS — use AES to protect data at rest. Wi-Fi security protocols WPA2 and WPA3 rely on AES for frame encryption. Messaging apps (Signal, WhatsApp) use AES as a building block inside their end-to-end encryption ratchets. Government and military systems use AES-256 for classified data under NSA Suite B / CNSA guidance. Hardware vendors — Intel, AMD, ARM — bake AES round functions directly into silicon (AES-NI, Crypto Extensions) because its ubiquity justifies dedicated transistors. Every use case builds AES into a system by first choosing a mode of operation (CBC, CTR, GCM) that specifies how successive blocks are chained — a decision every bit as important to overall security as the cipher itself.

Ask the tutor: How does choosing CBC versus GCM mode change the security guarantees AES alone doesn't provide?

Why does AES use a 4×4 byte grid instead of processing bits sequentially like DES?

Processing the whole 128-bit block as a matrix lets AES apply parallel, hardware-friendly operations (row shifts, column mixes) that diffuse information across the entire block within just a few rounds. DES's Feistel structure only transforms half the block per round, so full diffusion takes many more rounds to achieve comparable mixing. The matrix view also makes AES's linear algebra over GF(28)GF(2^8) explicit and analyzable, letting designers prove bounds on differential and linear attack probabilities rather than relying purely on empirical testing, as was largely the case for DES's original S-boxes.

Is AES-256 meaningfully more secure than AES-128 in practice?

Against brute-force key search, yes — 22562^{256} dwarfs 21282^{128}, though both are astronomically infeasible with classical computers. However, AES-256's key schedule has known theoretical weaknesses under related-key attacks, reducing its effective margin somewhat, though these attacks require an adversary who can obtain ciphertexts under multiple related (not just different) keys, a scenario rarely achievable in real protocols. For nearly all practical purposes, AES-128 already exceeds any realistic security requirement; AES-256 is chosen mainly for compliance mandates or long-term data protection against future computational advances, including quantum attacks via Grover's algorithm, which only halves the effective key length.

Does AES require padding, and is that part of AES itself?

No — AES itself only encrypts exactly one 128-bit block; it has no notion of padding. Padding schemes (like PKCS#7) and multi-block chaining are the responsibility of a mode of operation built on top of AES, such as CBC or GCM. This separation of concerns is deliberate: AES is a fixed-length pseudorandom permutation, and turning it into a general-purpose encryption system for arbitrary-length messages is a distinct engineering problem with its own security requirements (like avoiding ECB's pattern leakage).

Has AES ever been broken?

No practical attack breaks full-round AES faster than brute-force key search under realistic conditions. Academic results exist against reduced-round variants (attacks reaching roughly 7 of 10 rounds for AES-128), and biclique attacks shave a small constant factor off exhaustive search (finding the key in about 21262^{126} operations for AES-128 instead of 21282^{128}) — still utterly infeasible. Side-channel attacks against specific implementations (cache timing, power analysis) have succeeded, but these exploit implementation flaws, not the algorithm's mathematical structure, and are mitigated by constant-time and hardware-accelerated implementations.

Why does AES use finite field arithmetic instead of ordinary integer or bitwise operations?

Finite field GF(28)GF(2^8) arithmetic gives every byte operation clean algebraic properties: every nonzero element has a multiplicative inverse, multiplication distributes over addition (XOR), and the resulting S-box and MixColumns matrix have provable nonlinearity and diffusion bounds. Ordinary integer arithmetic lacks these closure properties for 8-bit values (multiplication overflows unpredictably), so it cannot deliver the same guaranteed algebraic structure that lets cryptanalysts bound differential and linear attack probabilities rigorously.

How does AES compare to the confusion-diffusion ideas from Shannon's original theory of secrecy?

Claude Shannon's 1949 theory identified confusion (obscuring the relationship between key and ciphertext) and diffusion (spreading plaintext statistics across the ciphertext) as the two pillars any strong cipher needs. AES is arguably the cleanest realization of Shannon's vision: SubBytes provides confusion via a nonlinear, algebraically hard-to-invert map, while ShiftRows and MixColumns provide diffusion via linear mixing across rows and columns. Iterating this pair enough times (10–14 rounds) achieves Shannon's goal at a scale and speed he could not have anticipated in the pre-transistor era.

Why does the key schedule use round constants (Rcon) at all?

Without round constants, the key expansion would exhibit exploitable symmetries — in particular, slide attacks that pair rounds with structurally identical subkey-derivation steps. The Rcon values, which grow via powers of xx in GF(28)GF(2^8), break this periodicity, ensuring each round key is derived through a distinguishable nonlinear path even though the underlying SubWord/RotWord machinery repeats. This closes off an entire class of structural attacks that plagued earlier, more naively scheduled ciphers.

Before this

Where this leads