コンテンツにスキップ

Rcon

AES で使用する Rcon(Round constants、ラウンド定数)を作成する方法についてです。

AES はデータを暗号化する際に複数のラウンド処理(ループ処理のようなもの)を行います。このラウンド処理に使用するサブ鍵は、元の暗号鍵(128 ビット、192 ビット、256 ビット)から導出されます。Rconは、サブ鍵生成の過程で使用される定数です。

FIPS 197 を確認

https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdfより引用しています。

KEYEXPANSION() invokes 10 fixed words denoted by Rcon[j]Rcon[j] for 1j101≤j≤10. These 10 words are called the round constants. For AES-128, a distinct round constant is called in the generation of each of the 10 round keys. For AES-192 and AES-256, the key expansion routine calls the first eight and seven of these same constants, respectively. The values of Rcon[j]Rcon[j] are given in hexadecimal notation in Table 5:

以下は一部を意訳したものです。

KEYEXPANSION() は、1j101≤j≤10 の範囲で Rcon[j]Rcon[j] と呼ばれる 10 個の固定ワード(1 ワードは通常 32 ビット)を使用します。これらの 10 個のワードはラウンド定数と呼ばれます。

コード

https://github.com/TheAlgorithms/Rust/blob/3cbb841f58b0227a3e5bb01c8cbd49878d851960/src/ciphers/aes.rs#L12のように、Rcon は事前に定義しておくことが可能なので、わざわざ計算して作成しなくてもよいと思います。

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_
test_rcon.c
1
#include <stdio.h>
2
#include <string.h>
3
4
#include "rcon.h"
5
6
#define Nr 10
7
static const int rcon[Nr + 1] = {0x8D, 0x01, 0x02, 0x04, 0x08, 0x10,
8
0x20, 0x40, 0x80, 0x1B, 0x36};
9
10
static int test_rcon(void);
11
12
int main(void) {
13
int exit;
14
exit = test_rcon();
15
16
return exit;
17
}
18
19
static int test_rcon(void) {
20
int num_rounds = Nr + 1;
21
int out[Nr + 1];
22
23
calculate_rcon(num_rounds, out);
24
25
printf("AES Rcon test: ");
26
27
if (0 == memcmp((char*)out, (char*)rcon, Nr + 1)) {
28
printf("SUCCESS!\n");
29
return (0);
30
} else {
31
printf("FAILURE!\n");
32
return (1);
33
}
34
}

実行

Terminal window
gcc rcon.c test_rcon.c && ./a.out
実行結果
AES Rcon test: SUCCESS!

Live Code

以下の Calculate RCON ボタンをクリックすると、指定したラウンド数に対応する RCON の値を計算します。

Example

AES RCON Calculator

RCON Values:

6行の折りたたみ
import React, { useState } from 'react'
const AesRconCalculator = () => {
const [rounds, setRounds] = useState(10)
const [rcon, setRcon] = useState([])
const calculateRcon = (numRounds) => {
let rconArray = new Array(numRounds + 1)
rconArray[0] = 0x8d
for (let i = 1; i <= numRounds; ++i) {
rconArray[i] = rconArray[i - 1] << 1
if (rconArray[i] & 0x100) {
rconArray[i] ^= 0x11b
}
}
return rconArray
}
23行の折りたたみ
const handleCalculate = () => {
const rconValues = calculateRcon(rounds)
setRcon(rconValues)
}
return (
<div>
<h1>AES RCON Calculator</h1>
<div>
<label>Number of Rounds: </label>
<input
type="number"
value={rounds}
onChange={(e) => setRounds(parseInt(e.target.value))}
min="1"
/>
<button onClick={handleCalculate}>Calculate RCON</button>
</div>
<div>
<h2>RCON Values:</h2>
<div>
{rcon.map((value, index) => (
<span key={index}>
0x{value.toString(16).toUpperCase().padStart(2, '0')},{' '}
</span>
))}
</div>
</div>
</div>
4行の折りたたみ
)
}
export default AesRconCalculator