コンテンツにスキップ

S-box

AES 暗号の SubBytes にて使用される S-box についてです。

参考: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf

A non-linear substitution table used in SUBBYTES() and KEYEXPANSION() to perform a one-to-one substitution of a byte value.

とある 1 バイトのSr,cS_{r,c} を、S-box を使用してSr,cS'_{r,c}に置換します。

s0,0
s0,0
s0,1
s0,1
s0,2
s0,2
s0,3
s0,3
s1,0
s1,0
s1,1
s1,1
s1,2
s1,2
s1,3
s1,3
s2,0
s2,0
s2,1
s2,1
s2,2
s2,2
s2,3
s2,3
s3,0
s3,0
s3,1
s3,1
s3,2
s3,2
s3,3
s3,3
s'0,0
s'0,0
s'0,1
s'0,1
s'0,2
s'0,2
s'0,3
s'0,3
s'1,0
s'1,0
s'1,1
s'1,1
s'1,2
s'1,2
s'1,3
s'1,3
s'2,0
s'2,0
s'2,1
s'2,1
s'2,2
s'2,2
s'2,3
s'2,3
s'3,0
s'3,0
s'3,1
s'3,1
s'3,2
s'3,2
s'3,3
s'3,3
sr,c
sr,c
s'r,c
s'r,c
S-box
S-box
Text is not SVG - cannot display

以下のような表を使用します。

1 バイトの値が 16 進数表記で xy であれば、表の x0 行、0y 列を参照して置換を行います。

例: 0x35 → 0x96

sbox-perform

暗号化時に使用する S-box16×1616 \times 16) は以下です。

1
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
2
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
3
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
13行の折りたたみ
4
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
5
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
6
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
7
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
8
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
9
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
10
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
11
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
12
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
13
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
14
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
15
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
16
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16

復号時に使用する 逆 S-box16×1616 \times 16) は以下です。

1
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
2
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
3
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
13行の折りたたみ
4
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
5
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
6
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
7
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
8
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
9
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
10
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
11
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
12
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
13
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
14
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
15
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
16
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D

暗号化と復号で異なります。

計算

(主にサイズ面で)リソースが限られた環境やマルチパーティ計算などでは、表ではなく計算によって置換することもあります。

具体的には、GF(28)GF(2^8) 上での乗法的逆元をアフィン変換することによって求めます。

コード

1
#include <stdint.h>
2
#include <stdio.h>
3
4
#define POLY 0x1B
5
#define BITS 8
6
#define HI_BIT_MASK 0b10000000
7
8
uint8_t mul(uint8_t lhs, uint8_t rhs) {
9
uint8_t product = 0;
10
for (int i = 0; i < BITS; i++) {
11
if (rhs & 1) {
12
product ^= lhs;
13
}
14
uint8_t hi_bit_set = lhs & HI_BIT_MASK;
15
lhs <<= 1;
16
if (hi_bit_set) {
17
lhs ^= POLY;
18
}
19
rhs >>= 1;
20
}
21
return product;
22
}
23
24
uint8_t inv(uint8_t b) {
25
uint8_t b254 = 1;
26
for (int i = 0; i < 254; ++i) {
27
b254 = mul(b254, b);
28
}
29
return b254;
30
}
31
32
#define ROTL(x, shift) ((uint8_t)((x) << (shift)) | ((x) >> (BITS - (shift))))
33
34
uint8_t affine(uint8_t bt) {
35
return bt ^ ROTL(bt, 1) ^ ROTL(bt, 2) ^ ROTL(bt, 3) ^ ROTL(bt, 4) ^ 0x63;
36
}
37
38
uint8_t sub_bytes(uint8_t b) {
39
uint8_t bt = (b == 0) ? 0 : inv(b);
40
return affine(bt);
41
}
42
43
uint8_t inv_affine(uint8_t bt) {
44
return ROTL(bt, 1) ^ ROTL(bt, 3) ^ ROTL(bt, 6) ^ 0x05;
45
}
46
47
uint8_t inv_sub_bytes(uint8_t bt) {
48
uint8_t b = inv_affine(bt);
49
return (b == 0) ? 0 : inv(b);
50
}
51
52
int main() {
53
puts("sbox:");
54
for (int i = 0; i < 256; i++) {
55
uint8_t output = sub_bytes((uint8_t)i);
56
if (i % 16 == 15) {
57
printf("0x%02X%s\n", output, i != 255 ? "," : "");
58
} else {
59
printf("0x%02X, ", output);
60
}
61
}
62
63
puts("inv_sbox:");
64
for (int i = 0; i < 256; i++) {
65
uint8_t output = inv_sub_bytes((uint8_t)i);
66
if (i % 16 == 15) {
67
printf("0x%02X%s\n", output, i != 255 ? "," : "");
68
} else {
69
printf("0x%02X, ", output);
70
}
71
}
72
return 0;
73
}

実行

Terminal window
gcc sbox.c && ./a.out
実行結果
1
sbox:
2
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
3
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
4
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
13行の折りたたみ
5
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
6
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
7
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
8
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
9
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
10
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
11
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
12
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
13
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
14
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
15
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
16
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
17
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
18
inv_sbox:
19
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
20
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
21
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
13行の折りたたみ
22
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
23
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
24
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
25
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
26
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
27
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
28
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
29
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
30
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
31
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
32
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
33
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
34
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
bitslice
1
#include <stdint.h>
2
#include <stdio.h>
3
4
static void pack_bitslice(const uint8_t *in, int n, uint32_t state[8]) {
5
for (int plane = 0; plane < 8; ++plane) {
6
uint32_t w = 0;
7
for (int i = 0; i < n; ++i) {
8
uint8_t bit = (uint8_t)((in[i] >> plane) & 1u);
9
w |= ((uint32_t)bit) << i;
10
}
11
state[plane] = w;
12
}
13
}
14
15
static void unpack_bitslice(const uint32_t state[8], int n, uint8_t *out) {
16
for (int i = 0; i < n; ++i) {
17
uint8_t b = 0;
18
for (int plane = 0; plane < 8; ++plane) {
19
uint8_t bit = (uint8_t)((state[plane] >> i) & 1u);
20
b |= (uint8_t)(bit << plane);
21
}
22
out[i] = b;
23
}
24
}
25
26
void sub_bytes_bitsliced(uint32_t state[8]) {
27
uint32_t u7 = state[0];
28
uint32_t u6 = state[1];
29
uint32_t u5 = state[2];
30
uint32_t u4 = state[3];
31
uint32_t u3 = state[4];
32
uint32_t u2 = state[5];
33
uint32_t u1 = state[6];
34
uint32_t u0 = state[7];
35
36
uint32_t y14 = u3 ^ u5;
37
uint32_t y13 = u0 ^ u6;
38
uint32_t y12 = y13 ^ y14;
39
uint32_t t1 = u4 ^ y12;
40
uint32_t y15 = t1 ^ u5;
41
uint32_t t2 = y12 & y15;
42
uint32_t y6 = y15 ^ u7;
43
uint32_t y20 = t1 ^ u1;
44
uint32_t y9 = u0 ^ u3;
45
uint32_t y11 = y20 ^ y9;
46
uint32_t t12 = y9 & y11;
47
uint32_t y7 = u7 ^ y11;
48
uint32_t y8 = u0 ^ u5;
49
uint32_t t0 = u1 ^ u2;
50
uint32_t y10 = y15 ^ t0;
51
uint32_t y17 = y10 ^ y11;
52
uint32_t t13 = y14 & y17;
53
uint32_t t14 = t13 ^ t12;
54
uint32_t y19 = y10 ^ y8;
55
uint32_t t15 = y8 & y10;
56
uint32_t t16 = t15 ^ t12;
57
uint32_t y16 = t0 ^ y11;
58
uint32_t y21 = y13 ^ y16;
59
uint32_t t7 = y13 & y16;
60
uint32_t y18 = u0 ^ y16;
61
uint32_t y1 = t0 ^ u7;
62
uint32_t y4 = y1 ^ u3;
63
uint32_t t5 = y4 & u7;
64
uint32_t t6 = t5 ^ t2;
65
uint32_t t18 = t6 ^ t16;
66
uint32_t t22 = t18 ^ y19;
67
uint32_t y2 = y1 ^ u0;
68
uint32_t t10 = y2 & y7;
69
uint32_t t11 = t10 ^ t7;
70
uint32_t t20 = t11 ^ t16;
71
uint32_t t24 = t20 ^ y18;
72
uint32_t y5 = y1 ^ u6;
73
uint32_t t8 = y5 & y1;
74
uint32_t t9 = t8 ^ t7;
75
uint32_t t19 = t9 ^ t14;
76
uint32_t t23 = t19 ^ y21;
77
uint32_t y3 = y5 ^ y8;
78
uint32_t t3 = y3 & y6;
79
uint32_t t4 = t3 ^ t2;
80
uint32_t t17 = t4 ^ y20;
81
uint32_t t21 = t17 ^ t14;
82
uint32_t t26 = t21 & t23;
83
uint32_t t27 = t24 ^ t26;
84
uint32_t t31 = t22 ^ t26;
85
uint32_t t25 = t21 ^ t22;
86
uint32_t t28 = t25 & t27;
87
uint32_t t29 = t28 ^ t22;
88
uint32_t z14 = t29 & y2;
89
uint32_t z5 = t29 & y7;
90
uint32_t t30 = t23 ^ t24;
91
uint32_t t32 = t31 & t30;
92
uint32_t t33 = t32 ^ t24;
93
uint32_t t35 = t27 ^ t33;
94
uint32_t t36 = t24 & t35;
95
uint32_t t38 = t27 ^ t36;
96
uint32_t t39 = t29 & t38;
97
uint32_t t40 = t25 ^ t39;
98
uint32_t t43 = t29 ^ t40;
99
uint32_t z3 = t43 & y16;
100
uint32_t tc12 = z3 ^ z5;
101
uint32_t z12 = t43 & y13;
102
uint32_t z13 = t40 & y5;
103
uint32_t z4 = t40 & y1;
104
uint32_t tc6 = z3 ^ z4;
105
uint32_t t34 = t23 ^ t33;
106
uint32_t t37 = t36 ^ t34;
107
uint32_t t41 = t40 ^ t37;
108
uint32_t z8 = t41 & y10;
109
uint32_t z17 = t41 & y8;
110
uint32_t t44 = t33 ^ t37;
111
uint32_t z0 = t44 & y15;
112
uint32_t z9 = t44 & y12;
113
uint32_t z10 = t37 & y3;
114
uint32_t z1 = t37 & y6;
115
uint32_t tc5 = z1 ^ z0;
116
uint32_t tc11 = tc6 ^ tc5;
117
uint32_t z11 = t33 & y4;
118
uint32_t t42 = t29 ^ t33;
119
uint32_t t45 = t42 ^ t41;
120
uint32_t z7 = t45 & y17;
121
uint32_t tc8 = z7 ^ tc6;
122
uint32_t z16 = t45 & y14;
123
uint32_t z6 = t42 & y11;
124
uint32_t tc16 = z6 ^ tc8;
125
uint32_t z15 = t42 & y9;
126
uint32_t tc20 = z15 ^ tc16;
127
uint32_t tc1 = z15 ^ z16;
128
uint32_t tc2 = z10 ^ tc1;
129
uint32_t tc21 = tc2 ^ z11;
130
uint32_t tc3 = z9 ^ tc2;
131
uint32_t s0 = tc3 ^ tc16;
132
uint32_t s3 = tc3 ^ tc11;
133
uint32_t s1 = s3 ^ tc16;
134
uint32_t tc13 = z13 ^ tc1;
135
uint32_t z2 = t33 & u7;
136
uint32_t tc4 = z0 ^ z2;
137
uint32_t tc7 = z12 ^ tc4;
138
uint32_t tc9 = z8 ^ tc7;
139
uint32_t tc10 = tc8 ^ tc9;
140
uint32_t tc17 = z14 ^ tc10;
141
uint32_t s5 = tc21 ^ tc17;
142
uint32_t tc26 = tc17 ^ tc20;
143
uint32_t s2 = tc26 ^ z17;
144
uint32_t tc14 = tc4 ^ tc12;
145
uint32_t tc18 = tc13 ^ tc14;
146
uint32_t s6 = tc10 ^ tc18;
147
uint32_t s7 = z12 ^ tc18;
148
uint32_t s4 = tc14 ^ s3;
149
150
state[0] = s7;
151
state[1] = s6;
152
state[2] = s5;
153
state[3] = s4;
154
state[4] = s3;
155
state[5] = s2;
156
state[6] = s1;
157
state[7] = s0;
158
}
159
160
void sub_bytes_bitsliced_nots(uint32_t state[8]) {
161
state[0] ^= 0xFFFFFFFFu;
162
state[1] ^= 0xFFFFFFFFu;
163
state[5] ^= 0xFFFFFFFFu;
164
state[6] ^= 0xFFFFFFFFu;
165
}
166
167
void rijndael_sub_bytes_bitsliced(uint32_t state[8]) {
168
sub_bytes_bitsliced(state);
169
sub_bytes_bitsliced_nots(state);
170
}
171
172
int main() {
173
puts("sbox_bitsliced:");
174
const int W = 32;
175
uint8_t in[W];
176
uint8_t out[W];
177
uint32_t state[8];
178
for (int base = 0; base < 256; base += W) {
179
for (int i = 0; i < W; ++i) in[i] = (uint8_t)(base + i);
180
pack_bitslice(in, W, state);
181
rijndael_sub_bytes_bitsliced(state);
182
unpack_bitslice(state, W, out);
183
for (int i = 0; i < W; ++i) {
184
int idx = base + i;
185
if (idx % 16 == 15) {
186
printf("0x%02X%s\n", out[i], idx != 255 ? "," : "");
187
} else {
188
printf("0x%02X, ", out[i]);
189
}
190
}
191
}
192
193
return 0;
194
}
Terminal window
gcc sbox.c && ./a.out
実行結果
1
sbox_bitsliced:
2
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
3
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
4
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
13行の折りたたみ
5
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
6
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
7
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
8
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
9
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
10
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
11
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
12
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
13
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
14
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
15
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
16
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
17
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16