This article describes the S-box used by the Rijndael (aka AES) cryptographic algorithm.
|
Contents
|
The S-box is generated by determining the multiplicative inverse for a given number in GF(28) = GF(2)[x]/(x8 + x4 + x3 + x + 1), Rijndael's finite field (zero, which has no inverse, is set to zero). The multiplicative inverse is then transformed using the following affine transformation:

where [x0, ..., x7] is the multiplicative inverse as a vector.
This affine transformation is the sum of multiple rotations of the byte as a vector, where addition is the XOR operation.
For example, the multiplicative inverse of 0x11 is 0xb4. The affine transformation is defined as:
A4b4 + A3b4 + A2b4 + A1b4 + A0b4 + 63
where A is the matrix:

This can further be simplified as:
(A4 + A3 + A2 + A + I)b4 + 63
The rotational matrices simplify to:

which is equal to 0x82.
The matrix multiplication can be calculated by the following algorithm:
After the matrix multiplication is done, exclusive or the value by the decimal number 99 (the hexadecimal number 0x63, the binary number 1100011, and the bit string 11000110 representing the number in LSb first notation).
This will generate the following S-box, which is represented here with hexadecimal notation:
| 0 1 2 3 4 5 6 7 8 9 a b c d e f ---|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--| 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
Here the column is determined by the least significant nibble, and the row is determined by the most significant nibble. For example, the value 0x9a is converted in to 0xb8 by Rijndael's S-box. Note that the multiplicative inverse of 0x00 is defined as itself.
For C, C++ here is the initialization of the table:
unsigned char s[256] = { 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 };
The inverse S-box is simply the S-box run in reverse. For example, the inverse S-box of 0xdb is 0x9f. It is calculated by first calculating the inverse affine transformation of the input value, followed by the multiplicative inverse. The inverse affine transformation is as follows:

The following table represents Rijndael's inverse S-box:
| 0 1 2 3 4 5 6 7 8 9 a b c d e f ---|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--| 00 |52 09 6a d5 30 36 a5 38 bf 40 a3 9e 81 f3 d7 fb 10 |7c e3 39 82 9b 2f ff 87 34 8e 43 44 c4 de e9 cb 20 |54 7b 94 32 a6 c2 23 3d ee 4c 95 0b 42 fa c3 4e 30 |08 2e a1 66 28 d9 24 b2 76 5b a2 49 6d 8b d1 25 40 |72 f8 f6 64 86 68 98 16 d4 a4 5c cc 5d 65 b6 92 50 |6c 70 48 50 fd ed b9 da 5e 15 46 57 a7 8d 9d 84 60 |90 d8 ab 00 8c bc d3 0a f7 e4 58 05 b8 b3 45 06 70 |d0 2c 1e 8f ca 3f 0f 02 c1 af bd 03 01 13 8a 6b 80 |3a 91 11 41 4f 67 dc ea 97 f2 cf ce f0 b4 e6 73 90 |96 ac 74 22 e7 ad 35 85 e2 f9 37 e8 1c 75 df 6e a0 |47 f1 1a 71 1d 29 c5 89 6f b7 62 0e aa 18 be 1b b0 |fc 56 3e 4b c6 d2 79 20 9a db c0 fe 78 cd 5a f4 c0 |1f dd a8 33 88 07 c7 31 b1 12 10 59 27 80 ec 5f d0 |60 51 7f a9 19 b5 4a 0d 2d e5 7a 9f 93 c9 9c ef e0 |a0 e0 3b 4d ae 2a f5 b0 c8 eb bb 3c 83 53 99 61 f0 |17 2b 04 7e ba 77 d6 26 e1 69 14 63 55 21 0c 7d
For C, C++ implementation, here is the initialization of the table:
unsigned char inv_s[256] = { 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D };
The Rijndael S-Box was specifically designed to be resistant to linear and differential cryptanalysis. This was done by minimizing the correlation between linear transformations of input/output bits, and at the same time minimizing the difference propagation probability.
In addition, to strengthen the S-Box against algebraic attacks, the affine transformation was added. In the case of suspicion of a trapdoor being built into the cipher, the current S-box might be replaced by another one. The authors claim that the Rijndael cipher structure should provide enough resistance against differential and linear cryptanalysis, even if an S-Box with "average" correlation / difference propagation properties is used.
An equivalent equation for the affine transformation is

where b' b and c are 8 bit arrays and c is 01100011.[1]
This can be done with the following Java code:
public static boolean[] affineX (boolean[] bprime, boolean[] b, boolean[] c) { for (int j=0; j<8; j++) { bprime[j] = b[j] ^ b[(j+4)%8]; bprime[j] ^= b[(j+5)%8]; bprime[j] ^= b[(j+6)%8]; bprime[j] ^= b[(j+7)%8]; bprime[j] ^= c[j]; } return bprime; }
This entry is from Wikipedia, the leading user-contributed encyclopedia. It may not have been reviewed by professional editors (see full disclaimer)