The Rijndael S-box is a substitution box (lookup table) used in the Rijndael cipher, on which the Advanced Encryption Standard (AES) cryptographic algorithm is based.[1]

Forward S-box

AES S-box
x0x1x2x3x4x5x6x7x8x9xaxbxcxdxexf
0x 637c777bf26b6fc53001672bfed7ab76
1x ca82c97dfa5947f0add4a2af9ca472c0
2x b7fd9326363ff7cc34a5e5f171d83115
3x 04c723c31896059a071280e2eb27b275
4x 09832c1a1b6e5aa0523bd6b329e32f84
5x 53d100ed20fcb15b6acbbe394a4c58cf
6x d0efaafb434d338545f9027f503c9fa8
7x 51a3408f929d38f5bcb6da2110fff3d2
8x cd0c13ec5f974417c4a77e3d645d1973
9x 60814fdc222a908846eeb814de5e0bdb
ax e0323a0a4906245cc2d3ac629195e479
bx e7c8376d8dd54ea96c56f4ea657aae08
cx ba78252e1ca6b4c6e8dd741f4bbd8b8a
dx 703eb5664803f60e613557b986c11d9e
ex e1f8981169d98e949b1e87e9ce5528df
fx 8ca1890dbfe6426841992d0fb054bb16
The column is determined by the least significant nibble, and the row by the most significant nibble. For example, the value 9a16 is converted into b816.

The S-box maps an 8-bit input, c, to an 8-bit output, s = S(c). Both the input and output are interpreted as polynomials over GF(2). First, the input is mapped to its multiplicative inverse in GF(28) = GF(2) [x]/(x8 + x4 + x3 + x + 1), Rijndael's finite field. Zero, as the identity, is mapped to itself. This transformation is known as the Nyberg S-box after its inventor Kaisa Nyberg.[2] The multiplicative inverse is then transformed using the following affine transformation:

where [s7, ..., s0] is the S-box output and [b7, ..., b0] 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:

where b represents the multiplicative inverse, is the bitwise XOR operator, is a left bitwise circular shift, and the constant 6316 = 011000112 is given in hexadecimal.

An equivalent formulation of the affine transformation is

where s, b, and c are 8 bit arrays, c is 011000112, and subscripts indicate a reference to the indexed bit.[3]

Another equivalent is:

[4][5]

where is polynomial multiplication of and taken as bit arrays.

Inverse S-box

Inverse S-box
x0x1x2x3x4x5x6x7x8x9xaxbxcxdxexf
0x 52096ad53036a538bf40a39e81f3d7fb
1x 7ce339829b2fff87348e4344c4dee9cb
2x 547b9432a6c2233dee4c950b42fac34e
3x 082ea16628d924b2765ba2496d8bd125
4x 72f8f66486689816d4a45ccc5d65b692
5x 6c704850fdedb9da5e154657a78d9d84
6x 90d8ab008cbcd30af7e45805b8b34506
7x d02c1e8fca3f0f02c1afbd0301138a6b
8x 3a9111414f67dcea97f2cfcef0b4e673
9x 96ac7422e7ad3585e2f937e81c75df6e
ax 47f11a711d29c5896fb7620eaa18be1b
bx fc563e4bc6d279209adbc0fe78cd5af4
cx 1fdda8338807c731b11210592780ec5f
dx 60517fa919b54a0d2de57a9f93c99cef
ex a0e03b4dae2af5b0c8ebbb3c83539961
fx 172b047eba77d626e169146355210c7d

The inverse S-box is simply the S-box run in reverse. For example, the inverse S-box of b816 is 9a16. 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 inverse affine transformation also represents the sum of multiple rotations of the byte as a vector, where addition is the XOR operation:

where is the bitwise XOR operator, is a left bitwise circular shift, and the constant 516 = 000001012 is given in hexadecimal.

Design criteria

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.

The Rijndael S-box can be replaced in the Rijndael cipher,[1] which defeats the suspicion of a backdoor built into the cipher that exploits a static S-box. The authors claim that the Rijndael cipher structure is likely to provide enough resistance against differential and linear cryptanalysis even if an S-box with "average" correlation / difference propagation properties is used (cf. the "optimal" properties of the Rijndael S-box).

Example implementation in C language

The following C code calculates the S-box:

#include <stdint.h>

#define ROTL8(x,shift) ((uint8_t) ((x) << (shift)) | ((x) >> (8 - (shift))))

void initialize_aes_sbox(uint8_t sbox[256]) {
	uint8_t p = 1, q = 1;
	
	/* loop invariant: p * q == 1 in the Galois field */
	do {
		/* multiply p by 3 */
		p = p ^ (p << 1) ^ (p & 0x80 ? 0x1B : 0);

		/* divide q by 3 (equals multiplication by 0xf6) */
		q ^= q << 1;
		q ^= q << 2;
		q ^= q << 4;
		q ^= q & 0x80 ? 0x09 : 0;

		/* compute the affine transformation */
		uint8_t xformed = q ^ ROTL8(q, 1) ^ ROTL8(q, 2) ^ ROTL8(q, 3) ^ ROTL8(q, 4);

		sbox[p] = xformed ^ 0x63;
	} while (p != 1);

	/* 0 is a special case since it has no inverse */
	sbox[0] = 0x63;
}

References

  1. 1 2 "The Rijndael Block Cipher" (PDF). Retrieved 2013-11-11.
  2. ↑ Nyberg K. (1991) Perfect nonlinear S-boxes. In: Davies D.W. (eds) Advances in Cryptology – EUROCRYPT ’91. EUROCRYPT 1991. Lecture Notes in Computer Science, vol 547. Springer, Berlin, Heidelberg
  3. ↑ "The Advanced Encryption Standard" (PDF). FIPS PUB 197: the official AES standard. Federal Information Processing Standard. 2001-11-26. Retrieved 2010-04-29.
  4. ↑ Jörg J. Buchholz (2001-12-19). "Matlab implementation of the Advanced Encryption Standard" (PDF).
  5. ↑ Jie Cui; Liusheng Huang; Hong Zhong; Chinchen Chang; Wei Yang (May 2011). "An Improved AES S-box and Its Performance Analysis" (PDF). Archived from the original (PDF) on 2016-03-04.