This is an article in a series on Cryptography for the Everyday Developer. Follow along to learn the basics of modern cryptography and encryption.


Last time we explored the Data Encryption Standard (DES), and how its Feistel network structure worked. We also saw why DES eventually became obsolete: its 56-bit key size was simply too small in the face of modern computing power.

To replace DES, the U.S. National Institute of Standards and Technology (NIST) held a public competition in the late 1990s. Fifteen different algorithms were submitted from around the world. Over the course of several years, this field was narrowed down to five finalists, each carefully analyzed by cryptographers. Finally, in 2000, an algorithm called Rijndael, created by two Belgian cryptographers, Joan Daemen and Vincent Rijmen, was selected as the winner. This became the Advanced Encryption Standard (AES), which has since become the most widely used block cipher in the world. It is used everywhere: encrypting TLS traffic in your browser, securing Wi-Fi connections, and protecting classified government data.

AES in a Nutshell

AES is a block cipher, meaning it operates on fixed-size chunks of data. Each block is 128 bits, or 16 bytes. The key length can be 128, 192, or 256 bits. The number of rounds AES performs depends on the key length: ten rounds for a 128-bit key, twelve rounds for 192 bits, and fourteen rounds for 256 bits.

A “round” in AES is a sequence of transformations applied to the block of data. With each round, the block becomes more scrambled, more nonlinear, and more dependent on the key. After the final round, the block is output as ciphertext. The beauty of AES lies in how these transformations are constructed: they are simple enough to implement efficiently in both hardware and software, but mathematically structured to resist decades of cryptanalysis.

AES is similar to DES, but it is not a Feistel cipher. In a Feistel cipher, each round only encrypts half of the block before swapping halves. AES instead transforms the entire block every round. This gives it a different structure, known as a substitution-permutation network, which alternates between substitution (confusion) and permutation (diffusion) steps.

The Mathematics of AES

Under the hood, AES operations are not performed with ordinary arithmetic. Instead, they are carried out within a mathematical construct known as a finite field, or Galois field.

A field is a set of elements where you can add, subtract, multiply, and divide, and always get another element in the same set. The real numbers form a field, as do the rational numbers. The natural numbers do not, because dividing does not always stay within the naturals.

A finite field is a field with a finite number of elements, and the sizes of these fields are always of the form \(p^m\), where \(p\) is prime and \(m\) is a positive integer. AES, in particular, uses the finite field with \(p=2\) and \(m=8\), which has 256 elements and can be written as \(GF(2^8)\). The reason for this choice is that it allows each element of the field to be represented as a byte, making this field a natural choice for a computer algorithm.

In \(GF(2^8)\), elements are represented as polynomials of degree at most seven, with coefficients of either 0 or 1 (since \(p\) is 2). Without going into too many mathematical details, we can note that by using this particular finite field for AES, we can implement addition and subtraction by performing bitwise XOR, multiplication can be implemented using a left shift followed by a bitwise XOR, and division is an inverse of multiplication.

While these details may feel abstract, they matter because they give AES its security properties while also allowing efficient computation in both hardware and software.

AES Transformations

AES represents its 128-bit block as a four-by-four matrix of bytes, called the state. You can imagine this as taking the 16 bytes of input and arranging them column by column into a grid.

Each round of AES applies four transformations to this state. The sequence is always the same: substitution, shifting, mixing, and key addition, using the steps SubBytes, ShiftRows, MixColumns, and AddRoundKey:

  • SubBytes – Confusion
    • Each byte is replaced using a nonlinear substitution table (S-box), which is built using finite field inversion followed by an affine transformation. This ensures strong resistance to algebraic attacks.
  • ShiftRows – Diffusion
    • Each row of the state matrix is cyclically shifted by a certain number of bytes. This mixes data between columns.
  • MixColumns – Diffusion
    • Each column is transformed by multiplying it with a fixed polynomial matrix over \(GF(2^8)\). This spreads each input byte’s influence across the entire column.
  • AddRoundKey – Key dependence
    • The state is XORed with a round key derived from the original key using the Key Schedule.

The first step, SubBytes, replaces each byte in the state with another according to the AES S-box. The S-box is carefully designed to be nonlinear and resistant to algebraic attacks, and its construction relies on finite field inversion. SubBytes provides confusion, making the relationship between the plaintext and ciphertext highly non-obvious.

The second step, ShiftRows, moves the bytes within each row of the state. The first row remains unchanged, the second row is shifted left by one position, the third by two, and the fourth by three. This step spreads bytes across columns and helps ensure diffusion: a change in one part of the input will eventually affect many parts of the output.

The third step, MixColumns, is where the finite field arithmetic shows up most clearly. Each column of the state is treated as a four-term polynomial and multiplied by a fixed polynomial modulo the AES irreducible polynomial. In practice, this transformation takes four input bytes and produces four output bytes, each one a mix of the original four. This ensures that changes in one byte quickly spread to others, amplifying diffusion.

The final step, AddRoundKey, XORs the state with a round key derived from the main encryption key. This ties the entire process to the secret key, ensuring that without the key, the transformations are impossible to reverse.

After several rounds of these transformations, the state has been scrambled into ciphertext. The final round omits the MixColumns step, slightly altering the structure, but the principle remains the same.

The Key Schedule

To support multiple rounds, AES must generate a different round key for each one. This is done through the key schedule, also known as key expansion. The process begins with the original key and repeatedly applies a series of transformations to produce new round keys.

Each new word in the expanded key is derived from the previous words, with special steps every few words that involve rotation, substitution with the S-box, and XOR with a round constant. This ensures that each round key is different but still related to the original key. Importantly, the schedule is designed so that small changes in the key ripple unpredictably through the round keys, further strengthening security.


AES is more than just “DES with longer keys.” It represents a different philosophy in cryptographic design: public competition, transparency, and reliance on deep mathematical structures like finite fields. For developers, the important lessons are that AES encrypts 128-bit blocks using 128, 192, or 256-bit keys, that its strength comes from the combination of substitution and permutation layers, and that its security lies not only in the algorithm but also in how we use it.

From TLS handshakes to encrypted databases, AES remains the backbone of modern cryptography. Understanding its structure not only deepens our appreciation of how data is protected but also makes us more informed developers, capable of recognizing both the strengths and the pitfalls of applied cryptography.