AES: Advanced Encryption Standard
AES is a non-Feistel cipher that encrypts and decrypts a data block . It uses 10, 12, or 14 rounds depending on the key size, which can be 128, 192, or 256 bits.
It is a symmetric block cipher , which means a single key will encrypt and decrypt all the data.
Block Cipher:
Block refers to the way in which the stuff you’re encoding (the plaintext) is turned into the ciphertext . Cipher refers to any algorithm for encryption. A block cipher operates on multiple bytes of plaintext at the same time, arranged into a 2D block.
For AES the block size will be 128 bits but the cipher key size can be different (128, 192 or 256) - for AES-128, AES-192, and AES-256 respectively.
The State:
graph TD
A(128 bits) --> |"divide by 8"| B(16 bytes) --> C(Block 4x4)
|
|
The AES will simple take the input bytes make it into block 4 by 4 and apply the encryption algorithm.
Input Bytes:
| a0 | a4 | a8 | a12 |
|---|---|---|---|
| a1 | a5 | a9 | a13 |
| a2 | a6 | a10 | a14 |
| a3 | a7 | a11 | a15 |
State Matrix
| s0,0 | s0,1 | s0,2 | s0,3 | |
|---|---|---|---|---|
| s1,0 | s1,1 | s1,2 | s1,3 | |
| s2,0 | s2,1 | s2,2 | s2,3 | |
| s3,0 | s3,1 | s3,2 | s3,3 |
Output - Cipher Text
| out0 | out4 | out8 | out12 |
|---|---|---|---|
| out1 | out5 | out9 | out13 |
| out2 | out6 | out10 | out14 |
| out3 | out7 | out11 | out15 |
Prerequisites:
We need to learn about finite field arithmetic for some (3) operations in AES: Mix Column, Add Round Keys, and Key Schedule.
Finite Field - Galois Field:
A Field is a Group which satisfied both addition and multiplication with some properties:
- F is an abelian group under addition
- F - {0} ( the set F without the additive identity 0) is an abelian group under multiplication
Finite Field is a field with finite element:
- If $Z/nZ$ with n is not a prime, then it is not a field because $(Z/nZ -{0}) \neq (Z/nZ)^{\times}$ . There exist a number with does not relatively prime to n so there is no inverse under multiplication.
All finite fields have $p^n$ elements where $p$ is prime and $n$ is an integer at least 1. The field with $p^n$ elements is sometimes called the Galois Field - GF$(p^n)$.
The Galois fields of order GF$(p)$ are simple integer mod p. If $n>1$, the elements of GF$(p^n)$ are polynomials of degree $n-1$ with coefficients from GF$(p)$.
In AES, for some transformation, each byte in the state array is interpreted as one of the 256 elements of GF($2^8$).
In order to define addition and multiplication in GF($2^8$), each bytes ${b_7 ; b_6 ; b_5 ; b_4 ; b_3 ; b_2 ; b_1 ; b_0 }$ is interpreted as a polynomial:
$$ b(x) = b_7x^7+b_6x^6+b_5x^5+b_4x^4+b_3x^3+b_2x^2+b_1x+b_0 $$
Addition in GF($2^8$):
Because ${b_7 ; b_6 ; b_5 ; b_4 ; b_3 ; b_2 ; b_1 ; b_0 }$ is from GF(2), the addition of each elements can be seen as exclusive-OR (XOR) operation:
| x | y | x ⊕ y |
|---|---|---|
| 1 | 1 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
Because the coefficients of the polynomials are reduced modulo 2, the coefficient 1 is equivalent to the coefficients –1:
$$ \begin{aligned} &(x^6 + x^4 + x^2 + x + 1) + (x^7 + x + 1) = x^7 + x^6 + x^4 + x^2 \ &{0101011} \oplus {10000011} = {11010100} \ &{57} \oplus {83} = {d4} \end{aligned} $$
Multiplication in GF($2^8$):
We will define the multiplication in GF($2^8$) to be the ordinary polynomial product except we will take the reminder after dividing with irreducible polynomial m(x) of degree 8:
$$ m(x) = x^8+x^4+x^3+x+1 $$
So if we have $b(x)$ and $c(x)$ represent bytes b and c. Then $b \times c$ is represented by:
$$ b(x)c(x) ; mod ; m(x) $$
Example: Let b = $0x57$ and c= $0x83$ so
$$ \begin{aligned}b(x) &= x^6+x^4+x^2+x+1 \ c(x) &= x^7+x+1 \end{aligned} $$
Multiply these polynomials:
$$ \begin{aligned} b(x) \cdot c(x) &= (x^6+x^4+x^2+x+1)(x^7+x+1) \&= x^{13} +x^{11} +x^9+x^7+x^6+x^5+x^4+x^3+x^2+x+1 \end{aligned} $$
Note:
- For the $x$ with have power more than 8, we just divide the polynomial with $m(x)$ until it do not have any.
After reduction and combination:
$$ x^{13} +x^{11} +x^9+x^7+x^6+x^5+x^4+x^3+x^2+x+1 ; mod(m(x)) \ = x^7+x^6+1 $$
So $b\times c$ is equal to ${0xC1}$. There is also a faster way to do it as describe in this article .
xTime:
In AES, To calculate the multiplication faster, we using the same idea as binary exponentiation - which means present the pow number in binary form and begin double and add sequence.
The function xTime is used to multiply number with $x$ or in hex $0x02$ in GF($2^8$).
$$ \text{xTime(b)} = \begin{cases} { b_6 , b_5 , b_4 , b_3 , b_2 , b_1 , b_0 , 0 } \quad \quad \quad \text{if} ; b_7 = 0.\ { b_6 , b_5 , b_4 , b_3 , b_2 , b_1 , b_0 , 0 }; \oplus ; {0, 0, 0, 1, 1, 0, 1, 1, } \quad \text{if} ; b_7 = 1 \end{cases} $$
Which can be present in python as lambda function:
|
|
Operation:
For each key length bits, the number of rounds in AES is different:
| Key Length | Number of rounds (N) | |
|---|---|---|
| AES-128 | 128 | 10 |
| AES-196 | 196 | 12 |
| AES-256 | 256 | 14 |
The AES consists of 5 operations:
- Substitute Bytes - Sub-Bytes:
- Shift Rows:
- Mix Columns:
- Add Round Key: - The original key is denote as K, and the round keys will be denoted as w.
- Key Expansion - for creating the round keys.
Substitute Bytes:
SubBytes is an invertible, non-linear transformation of the state using a substitution (look-up) table call S-box. This tables was designed by Joan Daemen and Vincent Rijndael- the creators of AES.
Note: this S-box is carefully calculated so that it is resistant to Linear cryptanalysis.
|
|
| 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 0a | 0b | 0c | 0d | 0e | 0f | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 00 | 63 | 7c | 77 | 7b | f2 | 6b | 6f | c5 | 30 | 01 | 67 | 2b | fe | d7 | ab | 76 |
| 10 | ca | 82 | c9 | 7d | fa | 59 | 47 | f0 | ad | d4 | a2 | af | 9c | a4 | 72 | c0 |
| 20 | b7 | fd | 93 | 26 | 36 | 3f | f7 | cc | 34 | a5 | e5 | f1 | 71 | d8 | 31 | 15 |
| 30 | 04 | c7 | 23 | c3 | 18 | 96 | 05 | 9a | 07 | 12 | 80 | e2 | eb | 27 | b2 | 75 |
| 40 | 09 | 83 | 2c | 1a | 1b | 6e | 5a | a0 | 52 | 3b | d6 | b3 | 29 | e3 | 2f | 84 |
| 50 | 53 | d1 | 00 | ed | 20 | fc | b1 | 5b | 6a | cb | be | 39 | 4a | 4c | 58 | cf |
| 60 | d0 | ef | aa | fb | 43 | 4d | 33 | 85 | 45 | f9 | 02 | 7f | 50 | 3c | 9f | a8 |
| 70 | 51 | a3 | 40 | 8f | 92 | 9d | 38 | f5 | bc | b6 | da | 21 | 10 | ff | f3 | d2 |
| 80 | cd | 0c | 13 | ec | 5f | 97 | 44 | 17 | c4 | a7 | 7e | 3d | 64 | 5d | 19 | 73 |
| 90 | 60 | 81 | 4f | dc | 22 | 2a | 90 | 88 | 46 | ee | b8 | 14 | de | 5e | 0b | db |
| a0 | e0 | 32 | 3a | 0a | 49 | 06 | 24 | 5c | c2 | d3 | ac | 62 | 91 | 95 | e4 | 79 |
| b0 | e7 | c8 | 37 | 6d | 8d | d5 | 4e | a9 | 6c | 56 | f4 | ea | 65 | 7a | ae | 08 |
| c0 | ba | 78 | 25 | 2e | 1c | a6 | b4 | c6 | e8 | dd | 74 | 1f | 4b | bd | 8b | 8a |
| d0 | 70 | 3e | b5 | 66 | 48 | 03 | f6 | 0e | 61 | 35 | 57 | b9 | 86 | c1 | 1d | 9e |
| e0 | e1 | f8 | 98 | 11 | 69 | d9 | 8e | 94 | 9b | 1e | 87 | e9 | ce | 55 | 28 | df |
| f0 | 8c | a1 | 89 | 0d | bf | e6 | 42 | 68 | 41 | 99 | 2d | 0f | b0 | 54 | bb | 16 |

When decrypting, the inverse s-box is used. If s-box is (state, value) so the inverse s-box is (value, state).

|
|
Shift Row:
Shift Row is a transformation of the state where the bytes in the last three rows are cyclically shifted.
The position by which the bytes are shifted depend on the row index r:
$$ s’{r,c}=s{r,(c+r) ; mod; 4} $$
In r row, we shift each bytes by r positions to the left, and cycling left-most r bytes around to the right end.
Note: the first row (r = 0) is unchanged.

The inverse shift row can be easily define by changing the direction of the shift row:
$$ s’{r,c}=s{r,(c-r) ; mod; 4} $$
|
|
Mix Column:
The transformation can be expressed in terms of matrix multiplication in GF$(2^8)$. For the matrix, each of the 16 entries of the matrix is a byte of a single word - $[a_0, a_1, a_2, a_3].$ If we were given an input $[b_0, b_1, b_2, b_3]$ , the output $[d_0, d_1, d_2, d_3]$ is determined as:
$$ \begin{pmatrix} d_{0} \ d_{1} \ d_{2} \ d_{3} \end{pmatrix} = \begin{pmatrix} a_{0} & a_{3} & a_{2} & a_{1} \ a_{1} & a_{0} & a_{3} & a_{2} \ a_{2} & a_{1} & a_{0} & a_{3} \ a_{3} & a_{2} & a_{1} & a_{0} \end{pmatrix} * \begin{pmatrix} b_{0} \ b_{1} \ b_{2} \ b_{3} \end{pmatrix}\ $$
$$d_0 = (a_0 \times b_0) \oplus (a_3 \times b_1) \oplus (a_2 \times b_2)\oplus (a_1 \times b_3)…$$
$$d_3 = (a_3 \times b_0) \oplus (a_2 \times b_1) \oplus (a_1 \times b_2)\oplus (a_0 \times b_3). $$
In AES the chosen word $[a_0, a_1, a_2, a_3]$ = $[{02}, {01},{01}, {03}]$, so the formula will become:
$$ \begin{pmatrix} s_{0,c}^{’} \ s_{1,c}^{’} \ s_{2,c}^{’} \ s_{3,c}^{’} \end{pmatrix} = \begin{pmatrix} 02 & 03 & 01 & 01\ 01 & 02 & 03 & 01\ 01 & 01 & 02 & 03\ 03 & 01 & 01 & 02 \end{pmatrix} * \begin{pmatrix} s_{0,c} \ s_{1,c} \ s_{2,c} \ s_{3,c} \end{pmatrix} \text{with} ; 0 \leq c \leq 4. \ $$
$$s_{0,c}^{’} = ({02} \times s_{0,c}) \oplus ({03} \times s_{1,c}) \oplus ({01} \times s_{2,c})\oplus ({01} \times s_{3,c})$$
$$s_{3,c}^{’} = ({03} \times s_{0,c}) \oplus ({01} \times s_{1,c}) \oplus ({01} \times s_{2,c})\oplus ({02} \times s_{3.c}).$$
For the inverse mix column, we just multiply the encrypted word with inverse transformation matrix.
|
|
Add Round Keys:
This is a transformation of the state in which a round key is combined with the state by applying the bitwise XOR operation. A round key consists of four words from the key schedule. we denote t as $4*round+c$
$$ \begin{pmatrix} s_{0,c}^{’} \ s_{1,c}^{’} \ s_{2,c}^{’} \ s_{3,c}^{’} \end{pmatrix} = \begin{pmatrix} s_{0,c} \ s_{1,c} \ s_{2,c} \ s_{3,c} \end{pmatrix} \oplus \begin{pmatrix} w_{t0} \ w_{t1} \ w_{t2} \ w_{t3} \end{pmatrix} \text{with} ; 0 \leq c \leq 3 $$
- Round can be 10, 12, 14 depend on the type of AES.
- $w$ is the key schedule.
Because it is using XOR operation so the inverse of add round keys transformation is itself.
|
|
Key Expansion:
The transformation is used to make the secret key, and expanding it into series of round keys called the key schedule. The process of generating is different for each of AES-128, AES-192, and AES-256, but the core process is the same, so we just focus into AES-128 key expansion.

The key expansion consist of 3 sub process called: RotWord, SubWord, and Rcon.
RotWord:
We will rotate the bytes in the column, which was similar to ShiftRow, but we just need to rotate one byte.

SubWord:
It is the same as SubBytes.
Rcon - Round constants:
The Rcon values is define as:
$$ rcon_i =[ rc_i ; 00_{16} ; 00_{16}; 00_{16}] \ r_{c_i} = \begin{cases} 1 & \text{if } i = 1 \ 2 \cdot r_{c_{i-1}} & \text{if } i > 1 \text{ and } r_{c_{i-1}} < 80_{16} \ (2 \cdot r_{c_{i-1}}) \oplus 11B_{16} & \text{if } i > 1 \text{ and } r_{c_{i-1}} \geq 80_{16} \end{cases} $$
So the Rcon Table will be:

The key will be present as a 4 by 4 matrix and the step of Key Expansion is as follow: Images are take from this.

We will take the last column, do the following RotWord → SubWord → Rcon and XOR it which the first column then it become the 1 first column of the next key round.

The second, third, and fourth column of the block will be XORed with the first column and we will successfully build the next key round.

Repeat this process N times and then we will have the key expansion $w$.
|
|
Encryption:
The Pseudocode:
|
|

Operation for each round:

The encryption function is just for one block - with padding.
|
|
This is the code for encrypting a plaintext - with any length → using ECB mode:
|
|
Decryption:
The Pseudocode:
|
|

Operation for each round:

All the description for the inverse functions are being presented above in Substitute Bytes, Shift Row, Mix Column, and Add Round Key respectively.
|
|
Code for decrypting ciphertext with any length → using ECB mode.
|
|
Encrypting random data:
Some (all) the times, the data do not long (or short) enough to fit in a block - we divide the data into block of 16 bytes but there still remains some bytes off. Then the remained bytes will be padded with some random bytes - (often the number of bytes needed) - pkcs 7 to make it to 16.

Mode:
Based on this.
ECB -Electronic Code Book:
The Electronic Codebook (ECB) mode is a confidentiality mode that features, for a given key, the assignment of a fixed ciphertext block to each plaintext block, analogous to the assignment of code words in a codebook.
- ECB encryption: $ciphertext = AES(message)$.
- ECB decryption: $message =$ $AES(ciphertext)$.
In both encryption and decryption, message (ciphertext) is divided into block and then directly to block cipher.

But it contains some major vulnerabilities: ECB oracle, or more characteristic still can be observed after encryption.
CBC -The Cipher Block Chaining Mode:
The Cipher Block Chaining (CBC) mode is a confidentiality mode whose encryption process features the combining (“chaining”) of the plaintext blocks with the previous ciphertext blocks. The CBC mode requires an IV to combine with the first plaintext block. IV: Initialization vector
CBC Encryption
-
$ciphertext_1 = AES(message_1 \oplus IV)$
-
$ciphertext_n = AES(message_n \oplus ciphertext_{n-1})$

CBC Decryption:
- $message_1 = AES^{-1} (ciphertext_1)\oplus IV$
- $message_{n} = AES^{-1}(ciphertext_{n}) \oplus ciphertext_{n-1}$

CTR - The Counter Mode:
It make a block cipher become a stream cipher by generating output base on counter and then XOR with the plaintext to create ciphertext and vise versa. The sequence of counters must have the property that each block in the sequence is different from every other block.
Note: Nonce is the start of the counter → reuse nonce very dangerous because the ciphertext will XOR with the same output → can leak key.

Full AES implementation:
|
|