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 for . 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 are given in hexadecimal notation in Table 5:
以下は一部を意訳したものです。
KEYEXPANSION() は、 の範囲で と呼ばれる 10 個の固定ワード(1 ワードは通常 32 ビット)を使用します。これらの 10 個のワードはラウンド定数と呼ばれます。
コード
https://github.com/TheAlgorithms/Rust/blob/3cbb841f58b0227a3e5bb01c8cbd49878d851960/src/ciphers/aes.rs#L12のように、Rcon は事前に定義しておくことが可能なので、わざわざ計算して作成しなくてもよいと思います。
1#define Nr 102
3int rcon[Nr + 1];4
5void 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}
1#ifndef _RCON_H_2#define _RCON_H_3
4void calculate_rcon(int num_rounds, int* rcon);5
6#endif // _RCON_H_
1#include <stdio.h>2#include <string.h>3
4#include "rcon.h"5
6#define Nr 107static const int rcon[Nr + 1] = {0x8D, 0x01, 0x02, 0x04, 0x08, 0x10,8 0x20, 0x40, 0x80, 0x1B, 0x36};9
10static int test_rcon(void);11
12int main(void) {13 int exit;14 exit = test_rcon();15
16 return exit;17}18
19static 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}
実行
gcc rcon.c test_rcon.c && ./a.out
AES Rcon test: SUCCESS!
Live Code
以下の Calculate RCON ボタンをクリックすると、指定したラウンド数に対応する RCON の値を計算します。
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