乱数アルゴリズム完全ガイド:TRNG/PRNG/CSPRNGの特徴と実装ポイント
はじめに — 「乱数アルゴリズム」とは何か
乱数アルゴリズム(乱数生成アルゴリズム)は、プログラムやハードウェアで疑似的または真の乱数(random numbers)を生成するための方法論を指します。乱数は暗号、シミュレーション、統計的サンプリング、ゲーム、セキュアな鍵生成など幅広い用途で不可欠です。しかし「乱数」の要件は用途によって大きく異り、特に暗号用途では予測不可能性(不確定性)が強く求められます。本稿では原理、代表的なアルゴリズム、評価法、実装上の注意点、推奨事項をできるだけ実践的に解説します。
乱数の分類:TRNG と PRNG(および CSPRNG)
- TRNG(True Random Number Generator):物理現象(熱雑音、放射線、量子揺らぎ、リングオシレータなど)を元にした真の乱数。物理的に非決定的で、理論上は高いエントロピーを持つ。ただしハードウェアのバイアス補正や故障検出が必要。
- PRNG(Pseudo-Random Number Generator):決定的なアルゴリズムで、内部状態(シード)から長い「見かけ上の乱数列」を生成する。高速で再現可能だが、シードが分かれば将来値が予測可能。
- CSPRNG(Cryptographically Secure PRNG):PRNGの一種だが「予測不可能性」「逆算困難性」「前方後方秘匿性(forward/backward secrecy)」など暗号的性質を満たすよう設計されたもの。暗号用途では必須。
PRNG の基本特性
- 周期(Period):生成列が繰り返すまでの長さ。例えば Mersenne Twister(MT19937)の周期は 2^19937 − 1 と非常に長い。
- 状態サイズ:内部に保持するビット数。状態が大きいほど推測や逆算が難しい。
- 均一性(分布):出力が期待される確率分布(通常は一様)に従うか。
- 相関・自己相関:隣接値や長距離の相関が小さいか。シミュレーション精度に影響する。
- 速度とメモリ消費:用途によってはこれらのトレードオフが重要。
代表的なアルゴリズム(概要と特徴)
ここではよく使われる代表的アルゴリズムを取り上げ、長所・短所を示します。
線形合同法(LCG)
式:X_{n+1} = (a X_n + c) mod m。実装が非常に簡単で高速だが、低次元では格子構造(層状の分布)を示し、暗号用途には不適。良好なパラメータ選定(Hull–Dobell 条件)で最大周期を得られるが、近年の用途には制限あり。
Mersenne Twister(MT19937)
1997年に松本・西村が提案。非常に長い周期(2^19937−1)と良好な統計特性でシミュレーションに広く利用される。しかし状態が大きく(~624ワード)、初期シード復元や内部状態からの予測耐性は暗号用途レベルではない。初期出力のバイアス("warm-up")にも注意。
XORShift / xoroshiro / xorshiro128+ 系列
ビット単位の排他的論理和とシフト操作で高速かつ小メモリ。統計的に良好なバリエーションも多いが、設計により周期や分布特性が左右される。暗号用途には単体では不十分。
PCG(Permuted Congruential Generator)
Melissa O'Neill が提案。LCGの出力に位相置換(Permutation)を施して良好な統計性と速度を両立。小さな状態で高い品質を実現するため、一般的用途で注目される。
暗号的 PRNG(例:ChaCha20、AES-CTR、HMAC-DRBG、CTR-DRBG)
暗号用ブロック・ストリーム暗号(AES、ChaCha20)やHMACをベースにした DRBG(Deterministic Random Bit Generator)は、CSPRNG として推奨される。高速であり、適切にシードされれば予測困難性や復元耐性がある。NIST の SP800-90A は AES/HMAC/Hash ベースの DRBG を規定しているが、Dual_EC_DRBG のような疑義のある方式は避けるべき。
Blum Blum Shub(BBS)
素因数分解の難しさに基づく CSPRNG。理論的安全性は高いが非常に遅く、実運用では速度面で不利。
ハードウェアTRNG(RDRAND, RDSEED, 量子乱数生成器など)
Intel の RDRAND 命令や RDSEED、または専用ハードウェア(量子乱数ジェネレータ、ノイズベース回路)で直接真の乱数/高品質なシードを取得できる。RDRAND は CPU 内部で擬似的に処理されるため、システム設計上の懸念や実装バグに注意が必要。また RDSEED はシード供給向けに設計されている。
乱数の評価と検定
乱数品質を評価するための統計的検定群が存在します。主なものを挙げます。
- NIST SP800-22:暗号用乱数の統計的検定スイート。
- Diehard / Dieharder:古典的な検定セット。
- TestU01:より厳密かつ詳細な検定を多数含む研究者向けツール。
これらのテストに合格することは必要条件だが十分条件ではありません。特に「暗号的安全性」は統計テストだけでは保証できず、設計の数学的根拠や攻撃モデルに基づく評価が必要です。
実装上の注意点と落とし穴
- rand() を使うな:C言語標準の rand() は実験的用途や教育用であり、分布や周期、実装差により本番用途(特にセキュリティ)には不適。
- シードの管理:再現性が欲しい科学計算では明示的にシードを与える。一方、暗号用途では十分なエントロピー(推測困難なシード)を確保し、必要に応じ再シードする。シードの再利用は重大なリスク。
- /dev/random と /dev/urandom、getrandom:Linux の /dev/random はエントロピーが枯渇するとブロックする場合がある。/dev/urandom はブロックしないが、システム起動直後などエントロピー不足のタイミングでの使用には注意が必要。現代の Linux では getrandom(2) を使うことが推奨される。
- 暗号には CSPRNG を:鍵生成、セッション ID、トークン、初期化ベクトル(IV)などセキュリティに関わる乱数は必ず CSPRNG または OS 提供の安全な API を利用する。
- ハードウェア RNG の信頼性:TRNG を利用する場合、バイアス除去、健康チェック、フェイルセーフが必要。単一ベンダやブラックボックスに完全依存するのはリスク。
- 法令・規格遵守:金融や医療など特定分野では乱数生成に関する規格や検証要件がある場合があるため、適切なアルゴリズムや証明済み実装を採用する。
暗号的考慮点(攻撃モデルと防御)
暗号用途では、次のような攻撃を想定し対策を講じる必要があります。
- シード復元攻撃:内部状態やシードを復元されると将来の出力が予測される。大きな状態空間と安全な初期化が必要。
- バックトラック攻撃(過去の出力復元):出力から内部状態を復元し過去の値を推定されないことが望ましい(forward/backward secrecy)。
- サイドチャネル:ハードウェア RNG や実装上の副作用から情報漏洩する可能性(タイミング、電力、統計など)。
実務的な推奨事項(開発者向け)
- 暗号用途:OS の推奨 API(Linux の getrandom(), /dev/urandom、Windows の BCryptGenRandom/NCryptGenRandom)または検証済みの CSPRNG 実装(ChaCha20, AES-CTR DRBG, HMAC-DRBG)を使用する。
- シミュレーション・統計用途:MT19937 や PCG、xoroshiro など高速で統計的に良好な PRNG を利用。ただし同じ系列を複数スレッドで共有する場合は注意(スレッドセーフでない実装がある)。
- テストとモニタリング:乱数生成の品質やハードウェア RNG の健康を定期的にチェックし、統計検定ツールを導入する。
- ライブラリ依存の把握:外部ライブラリやランタイム(例えば言語の標準ライブラリ)がどの乱数アルゴリズムを採用しているかを確認し、要件に合わない場合は差し替える。
用途別の選び方まとめ
- 暗号(鍵生成・非公開情報):検証済み CSPRNG または OS 提供の乱数API。
- 科学計算・再現性が必要な解析:MT19937 や PCG 等、シードを固定して再現できる PRNG。
- 高速で分散システムの乱数(多数の独立ストリーム):ストリーム毎に独立したシードを与えられる設計(PCG のストリーム機能等)や乱数ジェネレータのパラメータ化。
- 高信頼が必要な特殊用途:TRNG を使い、さらに CSPRNG での拡張・混合(TRNG をシードとして用いる)を行う。
最後に — 乱数アルゴリズムの「正しい使い方」
乱数は単に“ランダムに見える数列”を生成するだけでなく、用途に応じた性質(再現性、予測不可能性、速度、メモリなど)を満たすことが求められます。特にセキュリティ関連では「見かけ上ランダム」では不十分であり、設計原理、エントロピー源の管理、実装の検証、継続的なモニタリングが重要です。既存の実績あるライブラリや OS 機能を活用すること、単純な自作実装や古い乱数関数に頼らないことが最大の近道です。
参考文献
- Crypto++: Random Number Generator (解説)
- RFC 4086 - Randomness Requirements for Security
- M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator" (英語)
- PCG: A Family of Better Random Number Generators(Melissa E. O'Neill)
- NIST SP 800-90A Rev.1 — Recommendation for Random Number Generation Using Deterministic Random Bit Generators
- NIST SP 800-22 — A Statistical Test Suite for Random and Pseudorandom Number Generators for Cryptographic Applications
- Bruce Schneier et al., "Fortuna: A Cryptographically Secure PRNG" 解説
- Dieharder — Random Number Test Suite
- TestU01 — A software library in C for empirical testing of RNGs
- Linux Kernel — Random Number Generator (カーネルドキュメント)
- Dual_EC_DRBG(疑義と批判) — Wikipedia(背景理解用)


