書こうと思ってメモしていたのだが、すっかり忘れていた。お正月にメモを見て思い出す。
のっけからだが、タイトルがウソだ。ソフトウェアだけで(真の)乱数を生成することはできない。なので、Javaでは乱数が生成できない*1。乱数の定義にもよる*2が、例えば、乱数を生成するソフトウェア*3を同じ初期状態で2回実行すると、同じ乱数が得られる。決定論的な性質があると、再現が不可能な乱数は生成できない*4。
ソフトウェアで生成できる乱数もどきを、疑似乱数(pseudo-random number)と呼ぶ。また、疑似乱数を生成するソフトウェアを疑似乱数生成器(PRNG:Pseudo-Random Number Generator)と呼ぶ。
今日は、疑似乱数生成器がどのように疑似乱数を生成するのか、簡単に説明する。
疑似乱数生成器は、内部状態を持っている。疑似乱数生成器を利用する際には、まずこの内部状態を初期化する。内部状態を初期化するために用いる値を「シード(seed)」や「種」と呼ぶ。
疑似乱数を生成する際には、内部状態を変化させながら、内部状態に応じた値を出力する。
なお、ソフトウェアであれば、この内部状態の数は有限である。いつかは最初の内部状態に遷移して、同じ疑似乱数列を出力し始めるだろう。なのでやはり、ソフトウェアでは再現が不可能な乱数は生成できない。
さて、ここでセキュリティ上重要なことは、内部状態がバレないことである。そこで、疑似乱数生成器を用いる際には、次の2点に注意する必要がある。
- 推測困難なシードを用いて内部状態を初期化する
- 出力された値から内部状態が推測されないような(内部で一方向ハッシュ演算を行っているような)疑似乱数生成器を用いる
安全な疑似乱数*5を生成することは難しそうだ。
(つづく)