Written By

:

Adam Berent

Advanced Encryption Standard by Example
V.1.5

1.0 Preface
The following document provides a detailed and easy to understand explanation of the implementation of the AES (RIJNDAEL) encryption algorithm. The purpose of this paper is to give developers with little or no knowledge of cryptography the ability to implement AES.

2.0 Terminology
There are terms that are frequently used throughout this paper that need to be clarified. Block: AES is a block cipher. This means that the number of bytes that it encrypts is fixed. AES can currently encrypt blocks of 16 bytes at a time; no other block sizes are presently a part of the AES standard. If the bytes being encrypted are larger than the specified block then AES is executed concurrently. This also means that AES has to encrypt a minimum of 16 bytes. If the plain text is smaller than 16 bytes then it must be padded. Simply said the block is a reference to the bytes that are processed by the algorithm. State: Defines the current condition (state) of the block. That is the block of bytes that are currently being worked on. The state starts off being equal to the block, however it changes as each round of the algorithms executes. Plainly said this is the block in progress. XOR Refers to the bitwise operator Exclusive Or. XOR operates on the individual bits in a byte in the following way: 0 1 1 0 XOR XOR XOR XOR 0 0 1 1 = = = = 0 1 0 1

For example the Hex digits D4 XOR FF XOR = 11010100 11111111 00101011 (Hex 2B)

Another interesting property of the XOR operator is that it is reversible. So Hex 2B XOR FF = D4 Most programming languages have the XOR operator built in. Programming Language C C++ C# Java Visual Basic XOR Operator ^ ^ ^ ^ XOR

1

a sub keys for each operation round. AES is a secret key encryption algorithm. 2002 the National Institute of Science and Technology (NIST) has selected a block cipher called RIJNDAEL (named after its creators Vincent Rijmen and Joan Daemen) as the symmetric key encryption algorithm to be used to encrypt sensitive but unclassified American federal information. which is described at the end of this document. 24. the highest number that can be represented in a single digit is 15. This also makes it very useful in creating lookup tables where each HEX digit can represent a table index. This process is called KEY EXPANSION. As mentioned before AES is an iterated block cipher. RIJNDAEL was originally a variable block (16. This means that a single byte can always be represented by 2 HEX digits. Hex to Decimal table: 0 0 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 1 1 17 33 49 65 81 97 113 129 145 161 177 193 209 225 241 2 2 18 34 50 66 82 98 114 130 146 162 178 194 210 226 242 3 3 19 35 51 67 83 99 115 131 147 163 179 195 211 227 243 4 4 20 36 52 68 84 100 116 132 148 164 180 196 212 228 244 5 5 21 37 53 69 85 101 117 133 149 165 181 197 213 229 245 6 6 22 38 54 70 86 102 118 134 150 166 182 198 214 230 246 7 7 23 39 55 71 87 103 119 135 151 167 183 199 215 231 247 8 8 24 40 56 72 88 104 120 136 152 168 184 200 216 232 248 9 9 25 41 57 73 89 105 121 137 153 169 185 201 217 233 249 A 10 26 42 58 74 90 106 122 138 154 170 186 202 218 234 250 B 11 27 43 59 75 91 107 123 139 155 171 187 203 219 235 251 C 12 28 44 60 76 92 108 124 140 156 172 188 204 220 236 252 D 13 29 45 61 77 93 109 125 141 157 173 189 205 221 237 253 E 14 30 46 62 78 94 110 126 142 158 174 190 206 222 238 254 F 15 31 47 63 79 95 111 127 143 159 175 191 207 223 239 255 0 1 2 3 4 5 6 7 8 9 A B C D E F For example using the above table HEX D4 = DEC 212 All of the tables and examples in this paper are written in HEX. All that means is that the same operations are performed many times on a fixed number of bytes.HEX: Defines a notation of numbers in base 16. 32 bytes) encryption algorithm.0 AES Algorithm AES is an iterated symmetric block cipher. This key is expanded into individual sub keys. These operations can easily be broken down to the following functions: ADD ROUND KEY BYTE SUB SHIFT ROW MIX COLUMN 2 . which makes it simpler to implement and explain. AES operates on a fixed number of bytes AES as well as most encryption algorithms is reversible. NIST has however decided to define AES with a block size of 16 bytes while keeping their options open to future changes. The reason for this is that a single digit of Hex represents exactly 4 bits. This means that almost the same steps are performed to complete both encryption and decryption in reverse order. which means that: • • • AES works by repeating the same defined steps multiple times. 4. 3. This simply means that. 32 bytes) and variable key size (16. rather than the usual 9 in the decimal (base 10) system. The AES algorithm operates on bytes. 24.0 AES Brief History Effective May 26.

Round 0 1 2 3 4 5 6 7 8 Function Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Key(State) Key(Mix Column(Shift Key(Mix Column(Shift Key(Mix Column(Shift Key(Mix Column(Shift Key(Mix Column(Shift Key(Mix Column(Shift Key(Mix Column(Shift Key(Mix Column(Shift Key(Mix Column(Shift Row(Byte Row(Byte Row(Byte Row(Byte Row(Byte Row(Byte Row(Byte Row(Byte Row(Byte Sub(State)))) Sub(State)))) Sub(State)))) Sub(State)))) Sub(State)))) Sub(State)))) Sub(State)))) Sub(State)))) Sub(State)))) 3 .An iteration of the above steps is called a round.1 Encryption AES encryption cipher using a 16 byte key. 4. Key Size (bytes) 16 24 32 Block Size (bytes) 16 16 16 Rounds 10 12 14 The only exception being that in the last round the Mix Column step is not performed. to make the algorithm reversible during decryption. The amount of rounds of the algorithm depends on the key size. Round 0 1 2 3 4 5 6 7 8 9 10 11 Function Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Key(State) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Shift Row(Byte Sub(State))) AES encryption cipher using a 32 byte key. Round 0 1 2 3 4 5 6 7 8 9 Function Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Add Round Key(State) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Shift Row(Byte Sub(State))) AES encryption cipher using a 24 byte key.

Round 0 1 2 3 4 5 6 7 8 9 10 11 12 13 Function Add Round Key(State) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Add Round Key(Byte Sub(Shift Row(State))) 4 .9 10 11 12 13 Add Add Add Add Add Round Round Round Round Round Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Mix Column(Shift Row(Byte Sub(State)))) Key(Shift Row(Byte Sub(State))) 4.2 Decryption AES decryption cipher using a 16 byte key. Round 0 1 2 3 4 5 6 7 8 9 Function Add Round Key(State) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Add Round Key(Byte Sub(Shift Row(State))) AES decryption cipher using a 24 byte key. Round 0 1 2 3 4 5 6 7 8 9 10 11 Function Add Round Key(State) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Mix Column(Add Round Key(Byte Sub(Shift Row(State)))) Add Round Key(Byte Sub(Shift Row(State))) AES decryption cipher using a 32 byte key.

The next time the Add Round Key function is called bytes 17-32 are XORed against the state.0 AES Cipher Functions 5. So once the first 16 bytes are XORed against the first 16 bytes of the expanded key then the expanded key bytes 1-16 are never used again.5. The first time Add Round Key gets executed State 1 XOR 2 XOR 3 XOR 4 XOR 5 XOR 6 XOR 7 XOR 8 XOR 9 XOR 10 XOR 11 XOR 12 XOR 13 XOR 14 XOR 15 XOR 16 XOR Exp Key 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 The second time Add Round Key is executed State 1 XOR 2 XOR 3 XOR 4 XOR 5 XOR 6 XOR 7 XOR 8 XOR 9 XOR 10 XOR 11 XOR 12 XOR 13 XOR 14 XOR 15 XOR 16 XOR Exp Key 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 And so on for each round of execution.0 5. The Expanded Key bytes are never reused.1 Add Round Key Each of the 16 bytes of the state is XORed against each of the 16 bytes of a portion of the expanded key for the current round.2 Byte Sub During encryption each value of the state is replaced with the corresponding SBOX value AES S-Box Lookup Table 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 63 CA B7 04 09 53 D0 51 CD 60 E0 E7 BA 70 E1 8C 1 7C 82 FD C7 83 D1 EF A3 0C 81 32 C8 78 3E F8 A1 2 77 C9 93 23 2C 00 AA 40 13 4F 3A 37 25 B5 98 89 3 7B 7D 26 C3 1A ED FB 8F EC DC 0A 6D 2E 66 11 0D 4 F2 FA 36 18 1B 20 43 92 5F 22 49 8D 1C 48 69 BF 5 6B 59 3F 96 6E FC 4D 9D 97 2A 06 D5 A6 03 D9 E6 6 6F 47 F7 05 5A B1 33 38 44 90 24 4E B4 F6 8E 42 7 C5 F0 CC 9A A0 5B 85 F5 17 88 5C A9 C6 0E 94 68 8 30 AD 34 07 52 6A 45 BC C4 46 C2 6C E8 61 9B 41 9 01 D4 A5 12 3B CB F9 B6 A7 EE D3 56 DD 35 1E 99 A 67 A2 E5 80 D6 BE 02 DA 7E B8 AC F4 74 57 87 2D B 2B AF F1 E2 B3 39 7F 21 3D 14 62 EA 1F B9 E9 0F C FE 9C 71 EB 29 4A 50 10 64 DE 91 65 4B 86 CE B0 D D7 A4 D8 27 E3 4C 3C FF 5D 5E 95 7A BD C1 55 54 E AB 72 31 B2 2F 58 9F F3 19 0B E4 AE 8B 1D 28 BB F 76 C0 15 75 84 CF A8 D2 73 DB 79 08 8A 9E DF 16 For example HEX 19 would get replaced with HEX D4 5 . The method for deriving the expanded key is described in section 6.

2 or 3 spaces over to the right. So bytes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Will form a matrix: 1 2 3 4 5 9 13 6 10 14 7 11 15 8 12 16 Each row is then moved over (shifted) 1. A byte that was in the second position may end up in the third position after the shift.3 Shift Row Arranges the state in a matrix and then performs a circular shift for each row.During decryption each value in the state is replaced with the corresponding inverse of the SBOX 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 52 7C 54 08 72 6C 90 D0 3A 96 47 FC 1F 60 A0 17 1 09 E3 7B 2E F8 70 D8 2C 91 AC F1 56 DD 51 E0 2B 2 6A 39 94 A1 F6 48 AB 1E 11 74 1A 3E A8 7F 3B 04 3 D5 82 32 66 64 50 00 8F 41 22 71 4B 33 A9 4D 7E 4 30 9B A6 28 86 FD 8C CA 4F E7 1D C6 88 19 AE BA 5 36 2F C2 D9 68 ED BC 3F 67 AD 29 D2 07 B5 2A 77 6 A5 FF 23 24 98 B9 D3 0F DC 35 C5 79 C7 4A F5 D6 7 38 87 3D B2 16 DA 0A 02 EA 85 89 20 31 0D B0 26 8 BF 34 EE 76 D4 5E F7 C1 97 E2 6F 9A B1 2D C8 E1 9 40 8E 4C 5B A4 15 E4 AF F2 F9 B7 DB 12 E5 EB 69 A A3 43 95 A2 5C 46 58 BD CF 37 62 C0 10 7A BB 14 B 9E 44 0B 49 CC 57 05 03 CE E8 0E FE 59 9F 3C 63 C 81 C4 42 6D 5D A7 B8 01 F0 1C AA 78 27 93 83 55 D F3 DE FA 8B 65 8D B3 13 B4 75 18 CD 80 C9 53 21 E D7 E9 C3 D1 B6 9D 45 8A E6 DF BE 5A EC 9C 99 0C F FB CB 4E 25 92 84 06 6B 73 6E 1B F4 5F EF 61 7D For example HEX D4 would get replaced with HEX 19 5. In Detail: The state is arranged in a 4x4 matrix (square) The confusing part is that the matrix is formed vertically but shifted horizontally. The circular part of it specifies that the byte in the last position shifted one space will end up in the first position in the same row. First row is never shifted Row1 Row2 Row3 Roe4 0 1 2 3 The following table shows how the individual bytes are first arranged in the table and then moved over (shifted). The circular shift just moves each byte one space over. Blocks 16 bytes long: From 1 2 5 9 13 6 10 14 To 1 5 9 13 6 10 14 2 6 . So the first 4 bytes of the state will form the first bytes in each row. depending on the row of the state. This is not a bit wise shift.

The results of these multiplications are XORed together to produce only 4 result bytes for the next state. b2 = (b1 * 1) XOR (b2*2) XOR (b3*3) XOR (b4*1) The third result byte is calculated by multiplying the same 4 values of the state column against 4 values of the third row of the matrix. Each value in the column is eventually multiplied against every value of the matrix (16 total multiplications). b3 = (b1 * 1) XOR (b2*1) XOR (b3*2) XOR (b4*3) The fourth result byte is calculated by multiplying the same 4 values of the state column against 4 values of the fourth row of the matrix. The result of each multiplication is then XORed to produce 1 Byte. There are two parts to this step. The result of each multiplication is then XORed to produce 1 Byte.4 Mix Column This is perhaps the hardest step to both understand and explain. 7 . The multiplication is performed one column at a time (4 bytes). The result of each multiplication is then XORed to produce 1 Byte. Multiplication Matrix 2 1 1 3 3 2 1 1 1 3 2 1 1 1 3 2 16 byte State b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 The first result byte is calculated by multiplying 4 values of the state column against 4 values of the first row of the matrix.4. The second will explain how this multiplication is implemented over what’s called a Galois Field 5. The first will explain which parts of the state are multiplied against which parts of the matrix. The multiplication is performed one matrix row at a time against each value of a state column. 16 multiplications 12 XORs and 4 bytes output.3 4 7 11 15 8 12 16 11 15 16 4 3 7 8 12 During decryption the same process is reversed and all rows are shifted to the left: From 1 2 3 4 5 9 13 6 10 14 7 11 15 8 12 16 To 1 5 9 13 14 2 6 10 11 15 3 7 8 12 16 4 5.1 Matrix Multiplication The sate is arranged into a 4 row table (as described in the Shift Row function). There fore 4 bytes input. The result of each multiplication is then XORed to produce 1 Byte. b1 = (b1 * 2) XOR (b2*3) XOR (b3*1) XOR (b4*1) The second result byte is calculated by multiplying the same 4 values of the state column against 4 values of the second row of the matrix.

This section will instead concentrate on the implementation of the multiplication which can be done quite easily with the use of the following two tables in (HEX). 5. E Table 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 01 5F E5 53 4C 83 B5 FE FB C3 9F 9B FC 45 12 39 1 03 E1 34 F5 D4 9E C4 19 16 5E BA B6 1F CF 36 4B 2 05 38 5C 04 67 B9 57 2B 3A E2 D5 C1 21 4A 5A DD 3 0F 48 E4 0C A9 D0 F9 7D 4E 3D 64 58 63 DE EE 7C 4 11 D8 37 14 E0 6B 10 87 D2 47 AC E8 A5 79 29 84 5 33 73 59 3C 3B BD 30 92 6D C9 EF 23 F4 8B 7B 97 6 55 95 EB 44 4D DC 50 AD B7 40 2A 65 07 86 8D A2 7 FF A4 26 CC D7 7F F0 EC C2 C0 7E AF 09 91 8C FD 8 1A F7 6A 4F 62 81 0B 2F 5D 5B 82 EA 1B A8 8F 1C 9 2E 02 BE D1 A6 98 1D 71 E7 ED 9D 25 2D E3 8A 24 A 72 06 D9 68 F1 B3 27 93 32 2C BC 6F 77 3E 85 6C B 96 0A 70 B8 08 CE 69 AE 56 74 DF B1 99 42 94 B4 C A1 1E 90 D3 18 49 BB E9 FA 9C 7A C8 B0 C6 A7 C7 D F8 22 AB 6E 28 DB D6 20 15 BF 8E 43 CB 51 F2 52 E 13 66 E6 B2 78 76 61 60 3F DA 89 C5 46 F3 0D F6 F 35 AA 31 CD 88 9A A3 A0 41 75 80 54 CA 0E 17 01 L Table 0 1 2 3 4 5 6 7 8 0 64 7D 65 96 66 7E 2B AF 1 00 04 C2 2F 8F DD 6E 79 58 2 19 E0 1D 8A DB FD 48 0A A8 3 01 0E B5 05 BD 30 C3 15 50 4 32 34 F9 21 36 BF A3 9B F4 5 02 8D B9 0F D0 06 B6 9F EA 6 1A 81 27 E1 CE 8B 1E 5E D6 7 C6 EF 6A 24 94 62 42 CA 74 8 4B 4C 4D 12 13 B3 3A 4E 4F 9 C7 71 E4 F0 5C 25 6B D4 AE A 1B 08 A6 82 D2 E2 28 AC E9 B 68 C8 72 45 F1 98 54 E5 D5 C 33 F8 9A 35 40 22 FA F3 E7 D EE 69 C9 93 46 88 85 73 E6 E DF 1C 09 DA 83 91 3D A7 AD F 03 C1 78 8E 38 10 BA 57 E8 8 . until there are no more state columns.b4 = (b1 * 3) XOR (b2*1) XOR (b3*1) XOR (b4*2) This procedure is repeated again with the next column of the state. b5 b6 b7 b8 = = = = (b5 (b5 (b5 (b5 * * * * 2) 1) 1) 3) XOR XOR XOR XOR (b6*3) (b6*2) (b6*1) (b6*1) XOR XOR XOR XOR (b7*1) (b7*3) (b7*2) (b7*1) XOR XOR XOR XOR (b8*1) (b8*1) (b8*3) (b8*2) And so on until all columns of the state are exhausted. Putting it all together: The first column will include state bytes 1-4 and will be multiplied against the matrix in the following manner: b1 b2 b3 b4 = = = = (b1 (b1 (b1 (b1 * * * * 2) 1) 1) 3) XOR XOR XOR XOR (b2*3) (b2*2) (b2*1) (b2*1) XOR XOR XOR XOR (b3*1) (b3*3) (b3*2) (b3*1) XOR XOR XOR XOR (b4*1) (b4*1) (b4*3) (b4*2) (b1= specifies the first byte of the state) The second column will be multiplied against the second row of the matrix in the following manner.2 Galois Field Multiplication The multiplication mentioned above is performed over a Galois Field.4. The mathematics behind this is beyond the scope of this paper.

followed by the addition of the results. For example if the two Hex values being multiplied are AF * 8 we first lookup L (AF) index which returns B7 and then lookup L (08) which returns 4B. Again we take the first digit to look up the vertical index and the second digit to look up the horizontal index. For example E(67)=F0 There fore the result of multiplying AF * 8 over a Galois Field is F0 Two last exceptions are that: • • Any number multiplied by one is equal to its self and does not need to go through the above procedure. 5. 5. The last step is to look up the addition result on the E table.4. followed by a lookup to the E table. All numbers being multiplied using the Mix Column function converted to HEX will form a maximum of 2 digit Hex number. For example AF+B7= 166. we perform: 166-FF which gives us 67. We use the first digit in the number on the vertical index and the second number on the horizontal index.4 Mix Column Example The following examples are denoted in HEX. For example: FF * 1 = FF Any number multiplied by zero equals zero 5. Because 166 > FF.9 A B C D E F 2C 7F CC 97 53 44 67 D7 0C BB B2 39 11 4A 75 F6 3E 87 84 92 ED 7A 6F 5A 90 3C D9 DE EB 17 FB 61 41 23 C5 16 C4 60 BE A2 20 31 0B 49 B1 DC 6D 2E FE F5 EC 86 FC 47 89 18 59 D8 3B BC 14 B4 0D CB 43 52 95 2A 7C 63 5F 1F A1 CF 9E B8 8C B0 2D 6C CD 5D 26 80 9C A4 AA 37 56 77 C0 A9 76 55 3F F2 99 F7 51 7B 29 5B D3 E3 70 A0 B7 9D D1 AB A5 07 The result of the multiplication is simply the result of a lookup of the L table. The addition is a regular mathematical addition represented by +.4.3 Mix Column Inverse During decryption the Mix Column the multiplication matrix is changed to: 0E 09 0D 0B 0B 0E 09 0D 0D 0B 0E 09 09 0D 0B 0E Other then the change to the matrix table the function performs the same steps as during encryption.1 Mix Column Example During Encryption Input = D4 BF 5D 30 Output(0) = = = = (D4 * 2) XOR (BF*3) XOR (5D*1) XOR (30*1) E(L(D4) + L(02)) XOR E(L(BF) + L(03)) XOR 5D XOR 30 E(41 + 19) XOR E(9D + 01) XOR 5D XOR 30 E(5A) XOR E(9E) XOR 5D XOR 30 9 . The only trick being that if the addition result is greater then FF we subtract FF from the addition result. If the value being multiplied is composed of only one digit we use 0 on the vertical index.4. not a bitwise AND. Once the L table lookup is complete we can then simply add the numbers together.4.

= B3 XOR DA XOR 5D XOR 30 = 04 Output(1) = = = = = = = = = = = = (D4 * 1) XOR (BF*2) XOR (5D*3) XOR (30*1) D4 XOR E(L(BF)+L(02)) XOR E(L(5D)+L(03)) XOR 30 D4 XOR E(9D+19) XOR E(88+01) XOR 30 D4 XOR E(B6) XOR E(89) XOR 30 D4 XOR 65 XOR E7 XOR 30 66 (D4 * 1) XOR (BF*1) XOR (5D*2) XOR (30*3) D4 XOR BF XOR E(L(5D)+L(02)) XOR E(L(30)+L(03)) D4 XOR BF XOR E(88+19) XOR E(65+01) D4 XOR BF XOR E(A1) XOR E(66) D4 XOR BF XOR BA XOR 50 81 Output(2) Output(3) = (D4 * 3) XOR (BF*1) XOR (5D*1) XOR (30*2) = E(L(D4)+L(3)) XOR BF XOR 5D XOR E(L(30)+L(02)) = E(41+01) XOR BF XOR 5D XOR E(65+19) = E(42) XOR BF XOR 5D XOR E(7E) = 67 XOR BF XOR 5D XOR 60 = E5 5. The expanded key is used in the Add Round Key function defined above.4. There fore the size of the expanded key will always be equal to: 10 . In order for this to work the Expanded Key must be large enough so that it can provide key material for every time the Add Round Key function is executed.2 Mix Column During Decryption Input 04 66 81 E5 Output(0) = = = = = = = = = = = = = = = = = = = = = = = = = = = = (04 * 0E) XOR (66*0B) XOR (81*0D) XOR (E5*09) E(L(04)+L(0E)) XOR E(L(66)+L(0B)) XOR E(L(81)+L(0D)) XOR E(L(E5)+L(09)) E(32+DF) XOR E(1E+68) XOR E(58+EE) XOR E(20+C7) E(111-FF) XOR E(86) XOR E(146-FF) XOR E(E7) E(12) XOR E(86) XOR E(47) XOR E(E7) 38 XOR B7 XOR D7 XOR 8C D4 (04 * 09) XOR (66*0E) XOR (81*0B) XOR (E5*0D) E(L(04)+L(09)) XOR E(L(66)+L(0E)) XOR E(L(81)+L(0B)) XOR E(L(E5)+L(0D)) E(32+C7) XOR E(1E+DF) XOR E(58+68) XOR E(20+ EE) E(F9) XOR E(FD) XOR E(C0) XOR E(10E-FF) E(F9) XOR E(FD) XOR E(C0) XOR E(0F) 24 XOR 52 XOR FC XOR 35 BF (04 * 0D) XOR (66*09) XOR (81*0E) XOR (E5*0B) E(L(04)+L(0D)) XOR E(L(66)+L(09) XOR E(L(81)+L(0E)) XOR E(L(E5)+(0B)) E(32+EE) XOR E(1E+C7) XOR E(58+DF) XOR E(20+68) E(120-FF) XOR E(E5) XOR E(137-FF) XOR E(88) E(21) XOR E(E5) XOR E(38) XOR E(88) 34 XOR 7B XOR 4F XOR 5D 5D (04 * 0B) XOR (66*0D) XOR (81*09) XOR (E5*0E) E(L(04)+L(0B)) XOR E(L(66)+L(0D)) XOR E(L(81)+L(09)) XOR E(L(E5)+L(0E)) E(32+68) XOR E(1E+EE) XOR E(58+C7) XOR E(20+DF) E(9A) XOR E(10C-FF) XOR E(11F-FF) XOR E(FF) E(9A) XOR E(0D) XOR E(20) XOR E(FF) 2C XOR F8 XOR E5 XOR 01 30 Output(1) Output(2) Output(3) 6. Each time the Add Round Key function is called a different part of the expanded key is XORed against the state.4.0 AES Key Expansion Prior to encryption or decryption the key must be expanded. The Add Round Key function gets called for each round as well as one extra time at the beginning of the algorithm.

If the key is 16 bytes long the first 16 bytes of the expanded key will be the same as the original key. Key Size (bytes) 16 24 32 Block Size (bytes) 16 16 16 Expansion Algorithm Rounds 44 52 60 Expanded Bytes / Round 4 4 4 Rounds Key Copy 4 6 8 Rounds Key Expansion 40 46 52 Expanded Key (bytes) 176 208 240 The first bytes of the expanded key are always equal to the key.1 11 . With the exception of the first rounds each round also takes the previous rounds 4 bytes as input operates and returns 4 bytes. There is an exception of this rule where if the key is 32 bytes long an additional call to the Sub Word function is called every 8 rounds starting on the 13th round. Each round adds 4 bytes to the Expanded Key. These functions are: ROT WORD SUB WORD RCON EK K An iteration of the above steps is called a round. If the key size is 32 bytes then the first 32 bytes of the expanded key will be the same as the original key. The amount of rounds of the key expansion algorithm depends on the key size.3. One more important note is that not all of the 4 functions are always called in each round.4 to 2.16 * (number of rounds + 1). 1. The algorithm only calls all 4 of the functions every: 4 Rounds for a 16 byte Key 6 Rounds for a 24 byte Key 8 Rounds for a 32 byte Key The rest of the rounds only a K function result is XORed with the result of the EK function. This provides key material for every byte in the block during every round +1 Key Size (bytes) 16 24 32 Block Size (bytes) 16 16 16 Expanded Key (bytes) 176 208 240 Since the key size is much smaller than the size of the sub keys. The key expansion routine executes a maximum of 4 consecutive functions.1 AES Key Expansion Functions Rot Word (4 bytes) This does a circular shift on 4 bytes similar to the Shift Row Function. The 16 in the above function is actually the size of the block in bytes.3. the key is actually “stretched out” to provide enough key space for the algorithm. 6.4.2.

For example if offset is 0 then EK will return bytes 0. This is why the explanation of the Key Expansion Algorithm is provided in a table format.2 AES Key Expansion Algorithm Since the expansion algorithm changes depending on the length of the key. think of this as a loop counter Expanded key bytes effected by the result of the function(s) The function(s) that will return the 4 bytes written to the effected expanded key bytes 12 . Each table has 3 fields: Field Round Expanded Key Bytes Function Description A counter representing the current step in the key expansion algorithm. one for each AES key sizes (16. For example if offset is 0 then K will return bytes 0.3 of the Expanded Key K(Offset) K function returns 4 bytes of the Key after the specified offset.2.1. Rcon((Round/(KeySize/4))-1) This function returns a 4 byte value based on the following table Rcon(0) Rcon(1) Rcon(2) Rcon(3) Rcon(4) Rcon(5) Rcon(6) Rcon(7) Rcon(8) Rcon(9) Rcon(10) Rcon(11) Rcon(12) Rcon(13) Rcon(14) = = = = = = = = = = = = = = = 01000000 02000000 04000000 08000000 10000000 20000000 40000000 80000000 1B000000 36000000 6C000000 D8000000 AB000000 4D000000 9A000000 For example for a 16 byte key Rcon is first called in the 4th round (4/(16/4))-1=0 In this case Rcon will return 01000000 For a 24 byte key Rcon is first called in the 6th round (6/(24/4))-1=0 In this case Rcon will also return 01000000 EK(Offset) EK function returns 4 bytes of the Expanded Key after the specified offset. and 32). 24. it is extremely difficult to explain in writing.3 of the Expanded Key 6.Sub Word (4 bytes) This step applies the S-box value substitution as described in Bytes Sub function to each of the 4 bytes in the argument. There are 3 tables.2.1.

Notice the first 6 rounds simply copy the total of 24 bytes of the key. 13 .Notice that most numbers that change in following tables match the current round number. 1. 1. This makes implementation in code much easier as these numbers can easily be replaced with loop variables. 16 byte Key Expansion Each round (except rounds 0. 3. Notice the first 4 rounds simply copy the total of 16 bytes of the key Round 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 Expanded Key Bytes 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 85 89 93 97 101 105 109 113 117 121 125 129 133 137 141 145 149 153 157 161 165 169 173 2 6 10 14 18 22 26 30 34 38 42 46 50 54 58 62 66 70 74 78 82 86 90 94 98 102 106 110 114 118 122 126 130 134 138 142 146 150 154 158 162 166 170 174 3 7 11 15 19 23 27 31 35 39 43 47 51 55 59 63 67 71 75 79 83 87 91 95 99 103 107 111 115 119 123 127 131 135 139 143 147 151 155 159 163 167 171 175 Function K(0) K(4) K(8) K(12) Sub Word(Rot Word(EK((4-1)*4))) XOR Rcon((4/4)-1) XOR EK((4-4)*4) EK((5-1)*4)XOR EK((5-4)*4) EK((6-1)*4)XOR EK((6-4)*4) EK((7-1)*4)XOR EK((7-4)*4) Sub Word(Rot Word(EK((8-4)*4))) XOR Rcon((8/4)-1) XOR EK((8-4)*4) EK((8-1)*4)XOR EK((9-4)*4) EK((10-1)*4)XOR EK((10-4)*4) EK((11-1)*4)XOR EK((11-4)*4) Sub Word(Rot Word(EK((12-4)*4))) XOR Rcon((12/4)-1) XOR EK((12-4)*4) EK((13-1)*4)XOR EK((13-4)*4) EK((14-1)*4)XOR EK((14-4)*4) EK((15-1)*4)XOR EK((15-4)*4) Sub Word(Rot Word(EK((16-4)*4))) XOR Rcon((16/4)-1) XOR EK((16-4)*4) EK((17-1)*4)XOR EK((17-4)*4) EK((18-1)*4)XOR EK((18-4)*4) EK((19-1)*4)XOR EK((19-4)*4) Sub Word(Rot Word(EK((20-4)*4))) XOR Rcon((20/4)-1) XOR EK((20-4)*4) EK((21-1)*4)XOR EK((21-4)*4) EK((22-1)*4)XOR EK((22-4)*4) EK((23-1)*4)XOR EK((23-4)*4) Sub Word(Rot Word(EK((24-4)*4))) XOR Rcon((24/4)-1) XOR EK((24-4)*4) EK((25-1)*4)XOR EK((25-4)*4) EK((26-1)*4)XOR EK((26-4)*4) EK((27-1)*4)XOR EK((27-4)*4) Sub Word(Rot Word(EK((28-4)*4))) XOR Rcon((28/4)-1) XOR EK((28-4)*4) EK((29-1)*4)XOR EK((29-4)*4) EK((30-1)*4)XOR EK((30-4)*4) EK((31-1)*4)XOR EK((31-4)*4) Sub Word(Rot Word(EK((32-4)*4))) XOR Rcon((32/4)-1) XOR EK((32-4)*4) EK((33-1)*4)XOR EK((33-4)*4) EK((34-1)*4)XOR EK((34-4)*4) EK((35-1)*4)XOR EK((35-4)*4) Sub Word(Rot Word(EK((36-4)*4))) XOR Rcon((36/4)-1) XOR EK((36-4)*4) EK((37-1)*4)XOR EK((37-4)*4) EK((38-1)*4)XOR EK((38-4)*4) EK((39-1)*4)XOR EK((39-4)*4) Sub Word(Rot Word(EK((40-4)*4))) XOR Rcon((40/4)-1) XOR EK((40-4)*4) EK((41-1)*4)XOR EK((41-4)*4) EK((42-1)*4)XOR EK((42-4)*4) EK((43-1)*4)XOR EK((43-4)*4) 24 byte Key Expansion Each round (except rounds 0. 2. 4 and 5) will take the result of the previous round and produce a 4 byte result for the current round. 2 and 3) will take the result of the previous round and produce a 4 byte result for the current round.

Notice the first 8 rounds simply copy the total of 32 bytes of the key. 4. 14 . 2. 3. 1. 6 and 7) will take the result of the previous round and produce a 4 byte result for the current round. 5.Round 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 Expanded Key Bytes 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 85 89 93 97 101 105 109 113 117 121 125 129 133 137 141 145 149 153 157 161 165 169 173 177 181 185 189 193 197 201 205 2 6 10 14 18 22 26 30 34 38 42 46 50 54 58 62 66 70 74 78 82 86 90 94 98 102 106 110 114 118 122 126 130 134 138 142 146 150 154 158 162 166 170 174 178 182 186 190 194 198 202 206 3 7 11 15 19 23 27 31 35 39 43 47 51 55 59 63 67 71 75 79 83 87 91 95 99 103 107 111 115 119 123 127 131 135 139 143 147 151 155 159 163 167 171 175 179 183 187 191 195 199 203 207 Function K(0) K(4) K(8) K(12) K(16) K(20) Sub Word(Rot Word(EK((6-1)*4))) XOR Rcon((6/6)-1) XOR EK((6-6)*4) EK((7-1)*4)XOR EK((7-6)*4) EK((8-1)*4)XOR EK((8-6)*4) EK((9-1)*4)XOR EK((9-6)*4) EK((10-1)*4)XOR EK((10-6)*4) EK((11-1)*4)XOR EK((11-6)*4) Sub Word(Rot Word(EK((12-1)*4))) XOR Rcon((12/6)-1) XOR EK((12-6)*4) EK((13-1)*4)XOR EK((13-6)*4) EK((14-1)*4)XOR EK((14-6)*4) EK((15-1)*4)XOR EK((15-6)*4) EK((16-1)*4)XOR EK((16-6)*4) EK((17-1)*4)XOR EK((17-6)*4) Sub Word(Rot Word(EK((18-1)*4))) XOR Rcon((18/6)-1) XOR EK((18-6)*4) EK((19-1)*4)XOR EK((19-6)*4) EK((20-1)*4)XOR EK((20-6)*4) EK((21-1)*4)XOR EK((21-6)*4) EK((22-1)*4)XOR EK((22-6)*4) EK((23-1)*4)XOR EK((23-6)*4) Sub Word(Rot Word(EK((24-1)*4))) XOR Rcon((24/6)-1) XOR EK((24-6)*4) EK((25-1)*4)XOR EK((25-6)*4) EK((26-1)*4)XOR EK((26-6)*4) EK((27-1)*4)XOR EK((27-6)*4) EK((28-1)*4)XOR EK((28-6)*4) EK((29-1)*4)XOR EK((29-6)*4) Sub Word(Rot Word(EK((30-1)*4))) XOR Rcon((30/6)-1) XOR EK((30-6)*4) EK((31-1)*4)XOR EK((31-6)*4) EK((32-1)*4)XOR EK((32-6)*4) EK((33-1)*4)XOR EK((33-6)*4) EK((34-1)*4)XOR EK((34-6)*4) EK((35-1)*4)XOR EK((35-6)*4) Sub Word(Rot Word(EK((36-1)*4))) XOR Rcon((36/6)-1) XOR EK((36-6)*4) EK((37-1)*4)XOR EK((37-6)*4) EK((38-1)*4)XOR EK((38-6)*4) EK((39-1)*4)XOR EK((39-6)*4) EK((40-1)*4)XOR EK((40-6)*4) EK((41-1)*4)XOR EK((41-6)*4) Sub Word(Rot Word(EK((42-1)*4))) XOR Rcon((42/6)-1) XOR EK((42-6)*4) EK((43-1)*4)XOR EK((43-6)*4) EK((44-1)*4)XOR EK((44-6)*4) EK((45-1)*4)XOR EK((45-6)*4) EK((46-1)*4)XOR EK((46-6)*4) EK((47-1)*4)XOR EK((47-6)*4) Sub Word(Rot Word(EK((48-1)*4))) XOR Rcon((48/6)-1) XOR EK((48-6)*4) EK((49-1)*4)XOR EK((49-6)*4) EK((50-1)*4)XOR EK((50-6)*4) EK((51-1)*4)XOR EK((51-6)*4) 32 byte Key Expansion Each round (except rounds 0.

Roun d 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 Expanded Key Bytes 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 234 228 232 1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 85 89 93 97 101 105 109 113 117 121 125 129 133 137 141 145 149 153 157 161 165 169 173 177 181 185 189 193 197 201 205 209 213 217 221 225 229 233 2 6 10 14 18 22 26 30 34 38 42 46 50 54 58 62 66 70 74 78 82 86 90 94 98 102 106 110 114 118 122 126 130 134 138 142 146 150 154 158 162 166 170 174 178 182 186 190 194 198 202 206 210 214 218 222 226 230 234 3 7 11 15 19 23 27 31 35 39 43 47 51 55 59 63 67 71 75 79 83 87 91 95 99 103 107 111 115 119 123 127 131 135 139 143 147 151 155 159 163 167 171 175 179 183 187 191 195 199 203 207 211 215 219 223 227 231 235 Function K(0) K(4) K(8) K(12) K(16) K(20) K(24) K(28) Sub Word(Rot Word(EK((8-1)*4))) XOR Rcon((8/8)-1) XOR EK((8-8)*4) EK((9-1)*4)XOR EK((9-8)*4) EK((10-1)*4)XOR EK((10-8)*4) EK((11-1)*4)XOR EK((11-8)*4) Sub Word(EK((12-1)*4))XOR EK((12-8)*4) EK((13-1)*4)XOR EK((13-8)*4) EK((14-1)*4)XOR EK((14-8)*4) EK((15-1)*4)XOR EK((15-8)*4) Sub Word(Rot Word(EK((16-1)*4))) XOR Rcon((16/8)-1) XOR EK((16-8)*4) EK((17-1)*4)XOR EK((17-8)*4) EK((18-1)*4)XOR EK((18-8)*4) EK((19-1)*4)XOR EK((19-8)*4) Sub Word(EK((20-1)*4))XOR EK((20-8)*4) EK((21-1)*4)XOR EK((21-8)*4) EK((22-1)*4)XOR EK((22-8)*4) EK((23-1)*4)XOR EK((23-8)*4) Sub Word(Rot Word(EK((24-1)*4))) XOR Rcon((24/8)-1) XOR EK((24-8)*4) EK((25-1)*4)XOR EK((25-8)*4) EK((26-1)*4)XOR EK((26-8)*4) EK((27-1)*4)XOR EK((27-8)*4) Sub Word(EK((28-1)*4))XOR EK((28-8)*4) EK((29-1)*4)XOR EK((29-8)*4) EK((30-1)*4)XOR EK((30-8)*4) EK((31-1)*4)XOR EK((31-8)*4) Sub Word(Rot Word(EK((32-1)*4))) XOR Rcon((32/8)-1) XOR EK((32-8)*4) EK((33-1)*4)XOR EK((33-8)*4) EK((34-1)*4)XOR EK((34-8)*4) EK((35-1)*4)XOR EK((35-8)*4) Sub Word(EK((36-1)*4))XOR EK((36-8)*4) EK((37-1)*4)XOR EK((37-8)*4) EK((38-1)*4)XOR EK((38-8)*4) EK((39-1)*4)XOR EK((39-8)*4) Sub Word(Rot Word(EK((40-1)*4))) XOR Rcon((40/8)-1) XOR EK((40-8)*4) EK((41-1)*4)XOR EK((41-8)*4) EK((42-1)*4)XOR EK((42-8)*4) EK((43-1)*4)XOR EK((43-8)*4) Sub Word(EK((44-1)*4))XOR EK((44-8)*4) EK((45-1)*4)XOR EK((45-8)*4) EK((46-1)*4)XOR EK((46-8)*4) EK((47-1)*4)XOR EK((47-8)*4) Sub Word(Rot Word(EK((48-1)*4))) XOR Rcon((48/8)-1) XOR EK((48-8)*4) EK((49-1)*4)XOR EK((49-8)*4) EK((50-1)*4)XOR EK((50-8)*4) EK((51-1)*4)XOR EK((51-8)*4) Sub Word(EK((52-1)*4))XOR EK((52-8)*4) EK((53-1)*4)XOR EK((53-8)*4) EK((54-1)*4)XOR EK((54-8)*4) EK((55-1)*4)XOR EK((55-8)*4) Sub Word(Rot Word(EK((56-1)*4))) XOR Rcon((56/8)-1) XOR EK((56-8)*4) EK((57-1)*4)XOR EK((57-8)*4) EK((58-1)*4)XOR EK((58-8)*4) 15 .

net.edu/~wagner/laws/ 16 .esat.0 References FIPS 197. If you would like to contact me feel free to do so at aberent@abisoft.mcgill. For more information on these topics I suggest you visit the Rijndael Home Page at: http://www.html The Laws of Cryptography http://www.ac.ratchkov.be/~rijmen/rijndael/ This document was written by Adam Berent and can be distributed without copyright as long as proper credit is given.html RIJNDAEL http://www. "Advanced Encryption Standard" Advanced Encryption Standard (AES) http://www. The mathematics and design reasons behind AES were purposely left out.utsa.com/vpn/aes/aes.59 236 237 238 239 EK((59-1)*4)XOR EK((59-8)*4) 7.ca/~kaleigh/computers/crypto_rijndael.abisoft.kuleuven. 8.cs.cs.net or visit www.0 Conclusion The above document provides you with only the basic information needed to implement the AES encryption algorithm.