**by Neal R. Wagner**

**Copyright © 2001 by Neal R. Wagner. All rights reserved.**

**
NOTE: This site is obsolete. See book draft (in PDF):**

**The constant Nb = 4**: This was mentioned earlier.is the number of words in an AES block, and right now it is always`Nb`.`4`**The key,**: the input key consists of`key`words, or`Nk`bytes.`4*Nk`**The expanded key,**: This consists of`w`words, or`Nb*(Nk+1)`bytes. The range of sizes are in the table below:`4*Nb*(Nk+1)`Expanded Key Sizes in Words Key Length *(Nk words)*Number of Rounds *(Nr)*Exp. Key Size *(Nb(Nr+1) words)*4 10 44 6 12 52 8 14 60 : This does the following simple cyclic permutation of a word: change`RotWord()`to`[a`_{0},a_{1},a_{2},a_{3}].`[a`_{1},a_{2},a_{3},a_{0}]: This is defined as the word:`Rcon[i]`. The following table contains values of powers of`[x`^{i-1},0,0,0]:`x`Powers of x = 0x02 i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 x ^{i}01 02 04 08 10 20 40 80 1b 36 6c d8 ab 4d 9a Notice that in the algorithm for key expansion, the first reference to

is`Rcon`, where`Rcon[i/Nk]`has value`i`, so that the smallest index to`Nk`is`Rcon`, and this uses`0`.`x`^{0}: This just applies the S-box value used in`SubWord()`to each of the`SubBytes`bytes in the argument.`4`

In a simple cipher, one might exclusive-or the key with the plaintext. Such a step is easily reversed by another exclusive-or of the same key with the ciphertext. In the case of the AES, there are a number of rounds, each needing its own key, so the actual key is ``stretched out'' and transformed to give portions of key for each round. This is the key expansion that is the topic of this section.

The key expansion routine, as part of the overall AES algorithm,
takes an *input key* (denoted ** key** below) of

The key expansion routine below states most of the actions
in terms of *words* or 4-byte units, since the AES specification
itself emphasizes words, but my implementation uses bytes
exclusively.

void KeyExpansion(byte[] key, word[] w, int Nw) {
int Nr = Nk + 6;
w = new byte[4*Nb*(Nr+1)];
int temp;
int i = 0;
while ( i < Nk) {
w[i] = word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]);
i++;
}
i = Nk;
while(i < Nb*(Nr+1)) {
temp = w[i-1];
if (i % Nk == 0)
temp = SubWord(RotWord(temp)) ^ Rcon[i/Nk];
else if (Nk > 6 && (i%Nk) == 4)
temp = SubWord(temp);
w[i] = w[i-Nk] ^ temp;
i++;
}
} |

Discussion of items in the above pseudo-code in order:

The function ** KeyExpansion()** merely supplies a
much expanded (and transformed) key for use by the