擬似乱数(PRNG)の基礎から実務まで:アルゴリズム選択・セキュリティ注意点・検定ツールガイド
擬似乱数とは何か
擬似乱数(擬似乱数列、Pseudo-Random Number, PRN/PRNG)は、数学的に定義されたアルゴリズムによって生成される「見かけ上ランダムに見える数列」を指します。真の乱数(真乱数、True Random Number)は物理現象(熱雑音、放射性崩壊など)に由来するのに対し、擬似乱数は有限の状態遷移で再現可能であり、初期状態(シード)を知っていれば将来の出力を完全に予測できます。
なぜ擬似乱数が重要か
計算の再現性:同じシードを使えば同じ乱数列を再現できるため、シミュレーションやデバッグに便利です。
効率性:物理乱数装置に比べ高速で大量の乱数を生成できます。
用途の多様性:統計的シミュレーション(モンテカルロ法)、ゲームの挙動、手続き的生成、統計検定、暗号処理(ただし注意が必要)など。
代表的なアルゴリズムと特徴
擬似乱数生成器には多くの種類があり、用途に応じて選択します。主なものを概説します。
線形合同法(LCG)
最も古典的な方法の一つ。次の漸化式で定義される:X_{n+1} = (a X_n + c) mod m。実装が簡単で高速ですが、低次元での相関が問題になりやすく、周期は最大でもmであり大規模用途には不十分な場合があります。Mersenne Twister(MT19937)
非常に長い周期(2^19937−1)と良好な統計特性を持ち、科学技術計算で広く使われます。ただし内部状態が大きく復元可能なため暗号用途には不適切です。xorshift系
ビット単位の排他的論理和(XOR)とビットシフトのみで高速に動作するアルゴリズム群(Marsagliaら)。軽量で高速ですが、設計に注意を要し、単純な実装は周期や特性で制約があります。PCG(Permuted Congruential Generator)
Melissa O'Neillらによる比較的新しい設計。良好な統計特性と小さめの状態、かつ実装が高速であり、MTよりも実用上扱いやすいとされます。暗号学的擬似乱数生成器(CSPRNG/DRBG)
暗号用途向けに設計された生成器で、内部状態から出力を逆算したり、将来の出力を予測することが計算上困難であることが求められます。代表例は、NISTのSP800-90Aで規定されるHash-DRBG、HMAC-DRBG、CTR-DRBG(AESベース)や、ChaCha20を利用した実装、Fortunaなど。Blum Blum Shub(BBS)
数論に基づく暗号学的生成器。理論的性質は良好ですが遅く、実用上は主に研究的用途に留まります。
品質を評価する指標
擬似乱数の「良さ」は用途に依存しますが、一般的に以下の点で評価します。
周期(Period):生成器が繰り返すまでの長さ。長い方が望ましい。
分布特性:一様性(均等分布)や多次元での等分布性(equidistribution)。
相関の低さ:ビット間や連続値間の自己相関が小さいこと。
統計テスト合格:Diehard、Dieharder、TestU01、NIST STSなどのバッテリによる検査。
暗号的性質(CSPRNGの場合):復元困難性や次の出力予測困難性。
種(シード)と初期化、エントロピー
擬似乱数の初期状態はシードによって決まります。良いシードが不可欠で、特にセキュリティ用途では高品質のエントロピー源(物理乱数やOS提供のエントロピープール)から得る必要があります。シードが小さかったり予測可能だと、生成される乱数列全体が予測可能になります。
OSや環境で提供される乱数源
現代のOSは信頼できる乱数取得APIを提供します。例:
Linux: /dev/random, /dev/urandom, getrandom(2)、カーネル内部ではエントロピープールとCSPRNGを利用(最新のカーネルではChaCha系アルゴリズムが採用されることがある)。
Windows: RtlGenRandom(SystemFunction036)やCNGのBCryptGenRandomなど。
macOS/iOS: Security.frameworkのセキュア乱数API。
暗号用途ではこれらのOS提供APIを直接利用することが推奨されます。独自実装の擬似乱数器を暗号目的に用いるのは危険です。
暗号用途での注意点
一般的なPRNG(MT19937など)は暗号に使うな:内部状態が復元されれば将来の出力を推測可能。
シード管理:シード生成時のエントロピーが不足していると安全性は失われます。適切な乱数収集(ハードウェア乱数、OSソース)を行う。
標準に従う:NIST SP800-90A等の実装や、広く検証されたライブラリ(OpenSSL、libsodiumなど)を利用する。
再利用禁止:同じ鍵や同じIVを使い回すと致命的な脆弱性になる場合がある。
検定と評価ツール
擬似乱数の統計的性質は複数のツールで検証します。代表的なもの:
Diehard / Dieharder:伝統的なテストスイート。
TestU01:L'Ecuyerらによる高機能なテストライブラリで、Crush/BigCrushなど強力なバッテリがある。
NIST SP800-22(STS):暗号用途向けのテストセット。
これらのテストは「合格=安全」を保証するものではなく、「特定の欠陥を検出する」ための手段であることに注意が必要です。
ハードウェア乱数と乱数抽出
物理現象に基づく真の乱数(TRNG)はノイズを直接取り込みますが、生の物理出力には偏りや相関があるため、乱数抽出器(whitening, entropy extractor)で均質化します。ホワイトニングには暗号的ハッシュ関数やストリーム暗号などが使われます。ハードウェア乱数はエントロピー供給源としてOSのCSPRNGを強化するのに有効です。
並列・分散環境での乱数
並列計算では各スレッド/プロセスで独立した乱数列が必要です。方法:
各ワーカーに異なるシードを割り当て(シード空間の分割やランクベースのシード)。
並列向けの設計(MPI向けの拡張、Leapfrog、Sequence-splitting等)。
同じPRNGを単に複製すると周期分割や相関の問題が起きるので注意。
実務的な推奨
暗号的用途:OSのCSPRNG(getrandom/BCryptGenRandom等)やlibsodium/OpenSSLの高品質APIを使用。自作は避ける。
シミュレーション等の一般用途:MT19937やPCGのような高速で統計特性の良いPRNGを使用。再現性が必要ならシードを記録する。
性能要件が厳しい場面:xorshiftやPCG等の軽量なPRNGが適するが、使う前に統計テストを行う。
テストと監査:重要な用途では複数の検定(TestU01等)とコードレビューを行う。
まとめ
擬似乱数は計算機上でランダムに見える値を効率的に生成するための重要な技術です。用途に応じて適切なアルゴリズムを選び、特にセキュリティ用途ではOS提供のCSPRNGや検証済みライブラリを利用することが重要です。品質評価は統計テストや設計上の評価によって行われますが、「テストに合格した=万能に安全」という誤解は避け、設計思想や脅威モデルに基づく判断が必要です。
参考文献
- Wikipedia: Pseudorandom number generator
- Wikipedia: Mersenne Twister
- PCG: A Family of Better Random Number Generators (pcg-random.org)
- Marsaglia's xorshift generators (解説)
- NIST SP 800-90A Rev.1: Recommendation for Random Number Generation Using Deterministic Random Bit Generators
- RFC 4086: Randomness Requirements for Security (2005)
- TestU01: A C Library for Empirical Testing of Random Number Generators (L'Ecuyer & Simard)
- Fortuna (Ferguson & Schneier) - 設計概観
- Linux kernel: Random Number Generator (ドキュメント)
- getrandom(2) - Linux manual page
- RFC 6979: Deterministic Usage of the Digital Signature Algorithm (ECDSAにおける決定論的kの生成)


