AES — 5 Worked Examples (Step-by-Step)
C&CS Assignment — every calculation broken into individual steps, using the official FIPS-197 test
vectors
AES-128 encrypts a 16-byte block with a 128-bit key over 10 rounds. Each round (except the last) applies
four transformations in order: SubBytes → ShiftRows → MixColumns → AddRoundKey. The five sums
below walk through one instance of each transformation, plus key expansion, in full step-by-step detail. All
numbers are in hexadecimal unless stated otherwise.
Sum 1: SubBytes Transformation
Question: Find the SubBytes output for the byte 0x53 using the AES S-box.
Step 1: Understand what SubBytes does.
SubBytes replaces every byte of the state with a new byte taken from a fixed 16×16 lookup table called
the S-box. It is a non-linear substitution that provides AES's confusion property.
Step 2: Split the byte into two hex digits.
0x53 splits into digit pair (5, 3): the first digit '5' is the row, the second digit '3' is the column.
Step 3: Locate row 5 of the S-box.
Row 5: 53 d1 00 ed 20 fc b1 5b 6a cb be 39 4a 4c 58 cf
Index: 0 1 2 3 4 5 6 7 8 9 a b c d e f
Step 4: Read off column 3.
Counting from index 0, column 3 in row 5 holds the value ed.
Final Answer: SubBytes(0x53) = 0xED
Sum 2: ShiftRows Transformation
Question: Apply ShiftRows to the 4×4 state matrix below (bytes given row-wise).
Row 0: d4 e0 b8 1e
Row 1: 27 bf b4 41
Row 2: 11 98 5d 52
Row 3: ae f1 e5 30
Step 1: Understand what ShiftRows does.
ShiftRows cyclically shifts each row of the 4×4 state to the left. Row 0 is untouched; row r is shifted left
by r positions. This spreads bytes across columns, giving AES its diffusion.
Step 2: Row 0 — shift left by 0 (no change).
d4 e0 b8 1e -> d4 e0 b8 1e
Step 3: Row 1 — shift left by 1.
Take the first byte (27) and move it to the end.
27 bf b4 41 -> bf b4 41 27
Step 4: Row 2 — shift left by 2.
Move the first two bytes (11, 98) to the end, in order.
11 98 5d 52 -> 5d 52 11 98
Step 5: Row 3 — shift left by 3.
Move the first three bytes (ae, f1, e5) to the end, in order.
ae f1 e5 30 -> 30 ae f1 e5
Final Answer: Resulting state:
Row 0: d4 e0 b8 1e | Row 1: bf b4 41 27 | Row 2: 5d 52 11 98 | Row 3: 30 ae f1 e5
Sum 3: MixColumns Transformation
Question: Apply MixColumns to the first column obtained after ShiftRows: (d4, bf, 5d, 30).
Step 1: Understand what MixColumns does.
Each column of the state is treated as a 4-term polynomial over GF(2■) and multiplied by a fixed
polynomial. In matrix form, the column is multiplied by:
| 02 03 01 01 |
| 01 02 03 01 |
| 01 01 02 03 |
| 03 01 01 02 |
Step 2: Learn the GF(2■) multiplication shortcuts.
'×1' = the byte unchanged. '×2' = shift the byte left by 1 bit; if the original top (MSB) bit was 1, XOR the
shifted result with 0x1B. '×3' = ('×2' of the byte) XOR (the original byte).
Step 3: Compute the '×2' values needed.
2•d4: d4=11010100, MSB=1 -> shift = 10101000(a8), XOR 1B -> b3
2•bf: bf=10111111, MSB=1 -> shift = 01111110(7e), XOR 1B -> 65
2•5d: 5d=01011101, MSB=0 -> shift = 10111010(ba) -> ba
2•30: 30=00110000, MSB=0 -> shift = 01100000(60) -> 60
Step 4: Compute the '×3' values needed (×2 result XOR original).
3•bf = 65 XOR bf = da
3•5d = ba XOR 5d = e7
3•30 = 60 XOR 30 = 50
3•d4 = b3 XOR d4 = 67
Step 5: New byte 0 = (2•d4) ⊕ (3•bf) ⊕ (1•5d) ⊕ (1•30).
b3 XOR da XOR 5d XOR 30 = 04
Step 6: New byte 1 = (1•d4) ⊕ (2•bf) ⊕ (3•5d) ⊕ (1•30).
d4 XOR 65 XOR e7 XOR 30 = 66
Step 7: New byte 2 = (1•d4) ⊕ (1•bf) ⊕ (2•5d) ⊕ (3•30).
d4 XOR bf XOR ba XOR 50 = 81
Step 8: New byte 3 = (3•d4) ⊕ (1•bf) ⊕ (1•5d) ⊕ (2•30).
67 XOR bf XOR 5d XOR 60 = e5
Final Answer: New column after MixColumns = (04, 66, 81, e5)
Sum 4: AddRoundKey Transformation
Question: XOR the MixColumns output column (04, 66, 81, e5) with the round-key column (a0, 88, 23,
a2).
Step 1: Understand what AddRoundKey does.
AddRoundKey performs a plain bitwise XOR between the current state and the round key for that round.
It is the only step where the secret key actually mixes into the data.
Step 2: XOR byte 0.
04 = 00000100
a0 = 10100000
XOR = 10100100 = a4
Step 3: XOR byte 1.
66 = 01100110
88 = 10001000
XOR = 11101110 = ee
Step 4: XOR byte 2.
81 = 10000001
23 = 00100011
XOR = 10100010 = a2
Step 5: XOR byte 3.
e5 = 11100101
a2 = 10100010
XOR = 01000111 = 47
Final Answer: Resulting column = (a4, ee, a2, 47)
Sum 5: Key Expansion (Generating word w4)
Question: Given AES-128 key words w0=2b7e1516, w1=28aed2a6, w2=abf71588, w3=09cf4f3c, find the
next key-schedule word w4.
Step 1: Understand the key-expansion rule.
AES-128 expands 4 key words into 44 words for 11 round keys. For every word whose index is a
multiple of 4, the rule is:
w[i] = w[i-4] XOR SubWord(RotWord(w[i-1])) XOR Rcon[i/4]
Step 2: Apply RotWord to w3.
RotWord cyclically rotates the 4 bytes of a word one position to the left.
RotWord(09 cf 4f 3c) = cf 4f 3c 09
Step 3: Apply SubWord (S-box lookup on each byte).
S(cf) = 8a
S(4f) = 84
S(3c) = eb
S(09) = 01
=> SubWord result = 8a 84 eb 01
Step 4: XOR with the round constant Rcon[1] = (01, 00, 00, 00).
Rcon values double (in GF(2■)) each round; Rcon[1] is simply 0x01 in the first byte.
8a XOR 01 = 8b
84 XOR 00 = 84
eb XOR 00 = eb
01 XOR 00 = 01
=> 8b 84 eb 01
Step 5: XOR the result with w0.
2b XOR 8b = a0
7e XOR 84 = fa
15 XOR eb = fe
16 XOR 01 = 17
Final Answer: w4 = a0 fa fe 17
All five sums use the official FIPS-197 test vectors, so every intermediate and final value can be cross-checked against
the published AES standard.