Note 4/20/17: Due to circumstances I have had to move my web pages here.

The Rijndael algorithm was announced as the winner of the Advanced Encryption Standard (AES) in 2001. This algorithm is intended to replace the DES algorithm. AES was designed to be efficient in both hardware and software, and supports a block length of 128 bits and key lengths of 128, 192, and 256 bits. AES is defined in Fips 197. Click here for a description of how AES works.

10/27/06: I have decided to not allow the key to changed to reduce the chance of this page being used to solve homework problems
An input ASCII string that is less than 16 characters long will be padded with NULL characters.

 Message: ASCII Hexadecimal Key 0f 15 71 c9 47 d9 e8 59 0c b7 ad d6 af 7f 67 98 f6 cc 34 cd c5 55 c5 41 82 54 26 02 03 ad 3e cd 30 70 97 1a b7 ce 45 06 3f d2 57 3f 49 f5 42 0d a9 aa 1f 9f d1 53 bc b6 c7 83 42 12 c5 1f 5c 41 d2 f6 0c 43 6e 7c ce bb 8e ac ea f3 f8 6c 8b ad 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c Output message ASCII Hexadecimal

Details:

## How AES Works

This page only describes the 128-bit version, but the 192-bit and 256-bit key versions are similar.

AES is designed to work on bytes. However, each byte is interperted as a representation of the polynomial:

b7x7 + b6x6 + b5x5 + b4x4 + b3x3 + b2x2 + b1x + b0 Where each bi is either 0 or 1.

Addition then becomes exclusive-or, but multiplication is defined as polynomial multiplication modulo x8 + x4 + x3 + x + 1. For example 2d * a3 would be calculated as follows (remembering xy + xy = 0):
 2d = 00101101 = x5 + x3 + x2 + 1 a3 = 10100011 = x7 + x5 + x + 1 2d * a3 = (x12 + x10 + x9 + x7) + (x10 + x8 + x7 + x5) + (x6 + x4 + x3 + x) + (x5 + x3 + x2 + 1) = x12 + x9 + x8 + x6 + x4 + x2 + x + 1 - modulus * x4 = x9 + x7 + x6 + x5 + x2 + x + 1 - modulus * x = x7 + x6 + x4 + 1 2d * a3 = 11010001 = d1
Although this seems not efficient, all multiplications are by a constant, so they can be calculated in advance and turned into a simple table lookup.

#### Algorithm State

The 128-bit state can be represented as a 4 by 4 table of bytes. The cipher will perform various operations on this array.

#### Encryption Algorithm (128-bit version)

Cipher(byte in, byte out, word w)
begin
byte state[4,4]
state = in
for round = 1 step 1 to 10
SubBytes(state)
ShiftRows(state)
MixColumns(state)
end for
SubBytes(state)
ShiftRows(state)
out = state
end

#### SubBytes Routine

In this routine, each byte of the state is replaced according to the following formula: For each bit i, set bi to bi xor b(i+4) mod 8 xor b(i+5) mod 8 xor b(i+6) mod 8 xor b(i+7) mod 8 + ci where c = 63 hex. As with multiplication, this is usually implemented as a table lookup.

#### ShiftRows Routine

This routine modifies each row of the state matrix. The top row is not changed, the next row is rotated left one position, the following row two positions, and the bottom row three positions.

#### MixColumns Routine

This function mixes up the data in each column according to the following formulas:
• Set s0,c to 2*s0,c xor 3*s1,c xor s2,c xor s3,c
• Set s1,c to 0,c xor 2*s1,c xor 3*s2,c xor s3,c
• Set s2,c to s0,c xor s1,c xor 2*s2,c xor 3*s3,c
• Set s3,c to 3*s0,c xor s1,c xor s2,c xor 2*s3,c

This function does an XOR between each column of the state and a 32-bit word from the key schedule.

#### Key Expansion

The key schedule w is generated in the following form:

## AES Decryption

Decryption basically consists of performing each of the encryption steps in reverse, using the following algorithm: InvCipher(byte in, byte out, word w)])
begin
byte state[4,4]
state = in
for round = 9 step -1 downto 1
InvShiftRows(state)
InvSubBytes(state)
end for
InvShiftRows(state)
InvSubBytes(state)