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 R c o n [ j ] Rcon[j] R co n [ j ] for 1 ≤ j ≤ 10 1≤j≤10 1 ≤ 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 R c o n [ j ] Rcon[j] R co n [ j ] are given in hexadecimal notation in Table 5:
以下は一部を意訳したものです。
KEYEXPANSION() は、1 ≤ j ≤ 10 1≤j≤10 1 ≤ j ≤ 10 の範囲で R c o n [ j ] Rcon[j] R co n [ j ] と呼ばれる 10 個の固定ワード(1 ワードは通常 32 ビット)を使用します。これらの 10 個のワードはラウンド定数 と呼ばれます。
コード
https://github.com/TheAlgorithms/Rust/blob/3cbb841f58b0227a3e5bb01c8cbd49878d851960/src/ciphers/aes.rs#L12 のように、Rcon は事前に定義しておくことが可能なので、わざわざ計算して作成しなくてもよいと思います。
void calculate_rcon ( int num_rounds , int* rcon ) {
for ( int i = 1 ; i < num_rounds ; ++ i ) {
rcon [ i ] = rcon [ i - 1 ] << 1 ;
void calculate_rcon ( int num_rounds , int* rcon );
static const int rcon [ Nr + 1 ] = { 0x 8D , 0x 01 , 0x 02 , 0x 04 , 0x 08 , 0x 10 ,
0x 20 , 0x 40 , 0x 80 , 0x 1B , 0x 36 };
static int test_rcon ( void );
static int test_rcon ( void ) {
calculate_rcon ( num_rounds , out );
printf ( " AES Rcon test: " );
if ( 0 == memcmp (( char* ) out , ( char* ) rcon , Nr + 1 )) {
実行
ダウンロード
curl -OL https://tah5.com/assets/aes/rcon.c
curl -OL https://tah5.com/assets/aes/rcon.h
curl -OL https://tah5.com/assets/aes/test_rcon.c
gcc rcon.c test_rcon.c && ./a.out
Live Code
以下の Calculate RCON ボタンをクリックすると、指定したラウンド数に対応する RCON の値を計算します。
Example
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 )
for ( let i = 1 ; i <= numRounds ; ++ i ) {
rconArray [ i ] = rconArray [ i - 1 ] << 1
if ( rconArray [ i ] & 0x100 ) {
const handleCalculate = () => {
const rconValues = calculateRcon ( rounds )
< h1 > AES RCON Calculator </ h1 >
< label > Number of Rounds: </ label >
onChange ={( e ) => setRounds ( parseInt ( e . target . value ))}
< button onClick ={ handleCalculate }> Calculate RCON </ button >
{ rcon . map (( value , index ) => (
0x { value . toString ( 16 ). toUpperCase (). padStart ( 2 , ' 0 ' )} , { ' ' }
export default AesRconCalculator