# 暗号論的擬似乱数生成器
暗号論的擬似乱数生成器（CSPRNG、英語: cryptographically secure pseudo random number generator、暗号論的にセキュアな疑似乱数生成器）とは、暗号技術での利用に適した特性を持つ擬似乱数生成器 (PRNG) である。
暗号の応用では様々な場面で乱数を必要とする。例えば、以下のようなものがある。
- 鍵生成
- Nonce （プロトコル上1度だけ使われる数、number used once）
- Salt （ECDSA、RSASSA-PSS などの署名スキーマで使われる）
- ワンタイムパッド

その際に必要な乱数の性質は様々である。例えば、何らかの暗号プロトコルで Nonce を生成する際に求められるのは一意性だけである。一方、鍵の生成には高い無作為性が求められる。ワンタイムパッドには暗号論的擬似乱数も不適で、高いエントロピーを持つ真の無作為情報源が必要であり、それにより情報理論的安全性を得る。
理想的には、暗号プロトコル等に使用する乱数生成には高品質の情報源から得られるエントロピーを利用すべきである。それは、例えば量子論的な乱数生成器や予測不可能な何らかの系のプロセスである。情報理論的観点では、無作為性の程度とはエントロピーであり、ある系の入力のエントロピー以上のエントロピーは出力できないからである。しかし、実用システムでは、利用可能なエントロピー以上の乱数を必要とすることがある。無作為性を引き出すプロセスには時間が掛かるためである。そのような場合に CSPRNG を使うことがある。CSPRNG は利用可能なエントロピーをより多くのビット数に拡張する。

## 要求仕様
通常のPRNGの要求仕様は、CSPRNG でも満足される。しかし、逆は真ではない。CSPRNG の要求仕様は2つに分類される。第一に、その統計的特性がよいこと（統計的無作為性の試験に合格すること）、第二に、激しい攻撃にも耐えること（初期状態や途中の状態が攻撃者に明らかになっても破られないこと）である。
- 全てのCSPRNGは "next-bit test" に合格する。next-bit test とは、乱数列の最初の k ビットを与えられたとき、k+1 番目のビットの値を多項式時間で2分の1をこえる確率で予測するアルゴリズムが存在しないことを確認する試験である。アンドリュー・チーチー・ヤオは1982年、next-bit test に合格した生成器は、無作為性に関する他の多項式時間統計試験にも合格することを証明した。
- 全てのCSPRNGは "state compromise extensions" に耐える。その状態の一部または全部が明らかになっても（あるいは正しく推測されても）、明らかにされた状態より以前に生成された乱数列は再現できない。さらに、実行中にエントロピーの入力がある場合、その入力を知っていてもCSPRNGの将来の状態を予測できない。

例: 円周率の数列から出力を生成するCSPRNGがあり、2進数化した数列のどこからを使うのか不明であるとする。これはnext-bit testを満足するが暗号論的に安全ではない。なぜなら、アルゴリズムの状態にあたる「円周率のどの部分が現在使われているか」を攻撃者が突き止めた場合、その攻撃者は先行するビットをすべて計算できるからである。
多くのPRNGはCSPRNGとしては不適であり、上記の2つを満足しない。第一にPRNGの出力は統計的に無作為に見えるが、リバースエンジニアリングには耐性がない。従って、アルゴリズムを解析することで特別な統計的試験を設計でき、PRNG の出力が真の乱数ではないことを示すことができる。第二に状態が明らかであれば、過去の乱数列を再現でき、攻撃者が全ての過去のメッセージを読むことが可能となる。当然、将来の暗号も解読可能となる。
CSPRNGは、このような暗号解読に対抗するものとして設計される。

## 背景
Santha と Vazirani は、無作為性の弱いビット列を複数組み合わせることで高品質な擬似乱数列を生成できることを証明した。それ以前にジョン・フォン・ノイマンはビット列からバイアスの大部分を除去できる簡単なアルゴリズムがあることを証明し、Santha-Vazirani の設計に基づいたCSPRNGでフォン・ノイマンのアルゴリズムを入力ビット列に適用する必要がある。これを entropy extraction（エントロピー抽出）と呼び、研究が盛んな領域である。

## 設計
ここでは、CSPRNGの設計を
1. ブロック暗号や暗号学的ハッシュ関数などの暗号プリミティブに基づく設計
2. 数学的に解くのが難しい問題に基づく設計
3. 特殊な設計

に分けて解説する。

### 暗号プリミティブに基づく設計
- 安全なブロック暗号は、CTRモードで動作させることでCSPRNGとして使うことができる。これは、ランダムな鍵を選んで0を暗号化し、次に1を暗号化し、さらに2を暗号化し、というように行う。カウンタを0以外の任意の値から開始することもできる。明らかに、その周期は n-ビットブロック暗号では 2n であり、鍵と平文の初期値が攻撃者に知られてしまうと、全く安全でなくなる。また、誕生日のパラドックスから2n/2の出力で真の乱数と1/2の確率で識別可能である。
- 暗号学的ハッシュ関数もCSPRNGとして利用可能である。カウンタ値のハッシュ値を次々に計算すればよい。しかし、これについて安全ではないとする主張もある[3]。
- ストリーム暗号は、平文を擬似乱数列と（通常 XOR で）結合することで暗号文を生成する。カウンタを平文として暗号文を生成すれば、新たな擬似乱数列が生成され、おそらく内部の疑似乱数列より周期を長くできる。この生成法は、内部で生成する擬似乱数列がCSPRNGであるときだけ安全であるが、一般にそうでないことが多い（RC4参照）。
- ANSI X9.17 標準（Financial Institution Key Management (wholesale)）[4]では、ブロック暗号であるDESを用いた疑似乱数の生成法を挙げており、FIPSにも採用されている。この生成法では、64ビットのシード s とDESの鍵 kを用いて、次のように64ビット乱数を生成する。まず現在日時情報 D （可能な限り詳しい値）を使って、中間値 {\displaystyle I=DES_{k}(D)} を計算、次に {\displaystyle x=DES_{k}(I\oplus s)} を計算して乱数として出力し、シードを {\displaystyle s=DES_{k}(x\oplus I)} と更新する。64ビット以上の乱数が必要な場合は、上記の手続きを必要回数繰り返す。DESを別の任意のブロック暗号に置き換えることもでき、AESの利用が推奨されている[5]。


### 数論的設計
- Blum-Blum-Shub は、素因数分解の難しさに基づいたCSPRNGであり、条件付きでセキュリティが証明されている。ただし、実装すると他の手法よりも非常に性能が悪い。
- Micali–Schnorr generator, Naor-Reingold pseudorandom function


### 特殊な設計
以下のような、暗号論的に安全となるよう設計された実用的PRNGがある。
- Yarrow algorithm は入力のエントロピー的品質を評価する。一方Fortuna はそれをしない。
- マイクロソフトのCAPIにある関数CryptGenRandom
- ISAAC（RC4から派生）


## 標準
標準規格化されたCSPRNGとして、以下のものがある。
- FIPS 186-2
- NIST SP 800-90: Hash_DRBG, HMAC_DRBG, CTR_DRBG, Dual_EC_DRBG
- ANSI X9.17-1985 Appendix C
- ANSI X9.31-1998 Appendix A.2.4
- ANSI X9.62-1998 Annex A.4, obsoleted by ANSI X9.62-2005, Annex D (HMAC_DRBG)

NIST では、これに関するよいリンク集を管理している。
CSPRNG の統計的試験についての標準もある。
- A Statistical Test Suite for Random and Pseudorandom Number Generators, NIST Special Publication 800-22.