コンテンツにスキップ

KeyExpansion

key_expansion.c
1
#include "key_expansion.h"
2
3
#define Nb 4
4
#define Nk 4
5
#define Nr 10
6
7
extern uint8_t sbox[256];
8
extern int rcon[Nr + 1];
9
10
#define get_sbox_value(num) (sbox[(num)])
11
12
void key_expansion(uint8_t* round_key, const uint8_t* key) {
13
unsigned i, j, k;
14
uint8_t tempa[4];
15
16
for (i = 0; i < Nk; ++i) {
17
round_key[(i * 4) + 0] = key[(i * 4) + 0];
18
round_key[(i * 4) + 1] = key[(i * 4) + 1];
19
round_key[(i * 4) + 2] = key[(i * 4) + 2];
20
round_key[(i * 4) + 3] = key[(i * 4) + 3];
21
}
22
23
for (i = Nk; i < Nb * (Nr + 1); ++i) {
24
{
25
k = (i - 1) * 4;
26
tempa[0] = round_key[k + 0];
27
tempa[1] = round_key[k + 1];
28
tempa[2] = round_key[k + 2];
29
tempa[3] = round_key[k + 3];
30
}
31
32
if (i % Nk == 0) {
33
// Function RotWord()
34
{
35
const uint8_t u8tmp = tempa[0];
36
tempa[0] = tempa[1];
37
tempa[1] = tempa[2];
38
tempa[2] = tempa[3];
39
tempa[3] = u8tmp;
40
}
41
42
// Function Subword()
43
{
44
tempa[0] = get_sbox_value(tempa[0]);
45
tempa[1] = get_sbox_value(tempa[1]);
46
tempa[2] = get_sbox_value(tempa[2]);
47
tempa[3] = get_sbox_value(tempa[3]);
48
}
49
50
tempa[0] = tempa[0] ^ rcon[i / Nk];
51
}
52
53
j = i * 4;
54
k = (i - Nk) * 4;
55
round_key[j + 0] = round_key[k + 0] ^ tempa[0];
56
round_key[j + 1] = round_key[k + 1] ^ tempa[1];
57
round_key[j + 2] = round_key[k + 2] ^ tempa[2];
58
round_key[j + 3] = round_key[k + 3] ^ tempa[3];
59
}
60
}
key_expansion.h
1
#ifndef _KEY_EXPANSION_H_
2
#define _KEY_EXPANSION_H_
3
4
#include <stdint.h>
5
6
void key_expansion(uint8_t* round_key, const uint8_t* key);
7
8
#endif // _KEY_EXPANSION_H_
test_key_expansion.c
1
#include <stdio.h>
2
#include <string.h>
3
4
#include "key_expansion.h"
5
#include "rcon.h"
6
#include "sbox.h"
7
8
#define Nb 4
9
#define Nk 4
10
#define Nr 10
11
12
static const uint8_t test_key[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE,
13
0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88,
14
0x09, 0xCF, 0x4F, 0x3C};
15
static const uint8_t test_round_key[176] = {
16
0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88,
17
0x09, 0xCF, 0x4F, 0x3C, 0xA0, 0xFA, 0xFE, 0x17, 0x88, 0x54, 0x2C, 0xB1,
18
0x23, 0xA3, 0x39, 0x39, 0x2A, 0x6C, 0x76, 0x05, 0xF2, 0xC2, 0x95, 0xF2,
19
0x7A, 0x96, 0xB9, 0x43, 0x59, 0x35, 0x80, 0x7A, 0x73, 0x59, 0xF6, 0x7F,
20
0x3D, 0x80, 0x47, 0x7D, 0x47, 0x16, 0xFE, 0x3E, 0x1E, 0x23, 0x7E, 0x44,
21
0x6D, 0x7A, 0x88, 0x3B, 0xEF, 0x44, 0xA5, 0x41, 0xA8, 0x52, 0x5B, 0x7F,
22
0xB6, 0x71, 0x25, 0x3B, 0xDB, 0x0B, 0xAD, 0x00, 0xD4, 0xD1, 0xC6, 0xF8,
23
0x7C, 0x83, 0x9D, 0x87, 0xCA, 0xF2, 0xB8, 0xBC, 0x11, 0xF9, 0x15, 0xBC,
24
0x6D, 0x88, 0xA3, 0x7A, 0x11, 0x0B, 0x3E, 0xFD, 0xDB, 0xF9, 0x86, 0x41,
25
0xCA, 0x00, 0x93, 0xFD, 0x4E, 0x54, 0xF7, 0x0E, 0x5F, 0x5F, 0xC9, 0xF3,
26
0x84, 0xA6, 0x4F, 0xB2, 0x4E, 0xA6, 0xDC, 0x4F, 0xEA, 0xD2, 0x73, 0x21,
27
0xB5, 0x8D, 0xBA, 0xD2, 0x31, 0x2B, 0xF5, 0x60, 0x7F, 0x8D, 0x29, 0x2F,
28
0xAC, 0x77, 0x66, 0xF3, 0x19, 0xFA, 0xDC, 0x21, 0x28, 0xD1, 0x29, 0x41,
29
0x57, 0x5C, 0x00, 0x6E, 0xD0, 0x14, 0xF9, 0xA8, 0xC9, 0xEE, 0x25, 0x89,
30
0xE1, 0x3F, 0x0C, 0xC8, 0xB6, 0x63, 0x0C, 0xA6};
31
32
extern uint8_t sbox[256];
33
extern int rcon[Nr + 1];
34
35
static int test_key_expansion(void);
36
37
int main(void) {
38
int exit;
39
40
int num_rounds = Nr + 1;
41
initialize_aes_sbox(sbox);
42
calculate_rcon(num_rounds, rcon);
43
44
exit = test_key_expansion();
45
46
return exit;
47
}
48
49
static int test_key_expansion(void) {
50
uint8_t out[176];
51
52
key_expansion(out, test_key);
53
54
printf("AES KeyExpansion test: ");
55
56
if (0 == memcmp((char*)out, (char*)test_round_key, sizeof test_round_key)) {
57
printf("SUCCESS!\n");
58
return (0);
59
} else {
60
printf("FAILURE!\n");
61
return (1);
62
}
63
}
その他のソースコード
sbox.c
1
#include "sbox.h"
2
3
uint8_t sbox[256];
4
uint8_t inv_sbox[256];
5
6
#define ROTL8(x, shift) ((uint8_t)((x) << (shift)) | ((x) >> (8 - (shift))))
7
8
void initialize_aes_sbox(uint8_t sbox[256]) {
9
uint8_t p = 1, q = 1;
10
11
do {
12
p = p ^ (p << 1) ^ (p & 0x80 ? 0x1B : 0);
13
14
q ^= q << 1;
15
q ^= q << 2;
16
q ^= q << 4;
17
q ^= q & 0x80 ? 0x09 : 0;
18
19
uint8_t xformed =
20
q ^ ROTL8(q, 1) ^ ROTL8(q, 2) ^ ROTL8(q, 3) ^ ROTL8(q, 4);
21
22
sbox[p] = xformed ^ 0x63;
23
} while (p != 1);
24
25
sbox[0] = 0x63;
26
}
27
28
void initialize_inverse_aes_sbox(uint8_t inv_sbox[256],
29
const uint8_t sbox[256]) {
30
for (int i = 0; i < 256; i++) {
31
inv_sbox[sbox[i]] = i;
32
}
33
}
sbox.h
1
#ifndef _SBOX_H_
2
#define _SBOX_H_
3
4
#include <stdint.h>
5
6
void initialize_aes_sbox(uint8_t sbox[256]);
7
void initialize_inverse_aes_sbox(uint8_t inv_sbox[256],
8
const uint8_t sbox[256]);
9
10
#endif // _SBOX_H_
rcon.c
1
#define Nr 10
2
3
int rcon[Nr + 1];
4
5
void calculate_rcon(int num_rounds, int* rcon) {
6
rcon[0] = 0x8d;
7
for (int i = 1; i < num_rounds; ++i) {
8
rcon[i] = rcon[i - 1] << 1;
9
if (rcon[i] & 0x100) {
10
rcon[i] ^= 0x11B;
11
}
12
}
13
}
rcon.h
1
#ifndef _RCON_H_
2
#define _RCON_H_
3
4
void calculate_rcon(int num_rounds, int* rcon);
5
6
#endif // _RCON_H_

実行

Terminal window
gcc key_expansion.c test_key_expansion.c sbox.c rcon.c && ./a.out
実行結果
AES KeyExpansion test: SUCCESS!