Javaで乱数を生成する(1)

書こうと思ってメモしていたのだが、すっかり忘れていた。お正月にメモを見て思い出す。
のっけからだが、タイトルがウソだ。ソフトウェアだけで(真の)乱数を生成することはできない。なので、Javaでは乱数が生成できない*1。乱数の定義にもよる*2が、例えば、乱数を生成するソフトウェア*3を同じ初期状態で2回実行すると、同じ乱数が得られる。決定論的な性質があると、再現が不可能な乱数は生成できない*4
ソフトウェアで生成できる乱数もどきを、疑似乱数(pseudo-random number)と呼ぶ。また、疑似乱数を生成するソフトウェアを疑似乱数生成器(PRNG:Pseudo-Random Number Generator)と呼ぶ。


今日は、疑似乱数生成器がどのように疑似乱数を生成するのか、簡単に説明する。
疑似乱数生成器は、内部状態を持っている。疑似乱数生成器を利用する際には、まずこの内部状態を初期化する。内部状態を初期化するために用いる値を「シード(seed)」や「種」と呼ぶ。

疑似乱数を生成する際には、内部状態を変化させながら、内部状態に応じた値を出力する。

なお、ソフトウェアであれば、この内部状態の数は有限である。いつかは最初の内部状態に遷移して、同じ疑似乱数列を出力し始めるだろう。なのでやはり、ソフトウェアでは再現が不可能な乱数は生成できない。


さて、ここでセキュリティ上重要なことは、内部状態がバレないことである。そこで、疑似乱数生成器を用いる際には、次の2点に注意する必要がある。

  • 推測困難なシードを用いて内部状態を初期化する
  • 出力された値から内部状態が推測されないような(内部で一方向ハッシュ演算を行っているような)疑似乱数生成器を用いる


安全な疑似乱数*5を生成することは難しそうだ。
(つづく)

*1:ハードウェアの乱数生成器から乱数を取得するJavaAPIでもあれば、話は別だが。

*2:新版暗号技術入門 秘密の国のアリス」では、乱数の性質を弱い順に「無作為性」「予測不可能性」「再現不可能性」としている。

*3:乱数を生成するソフトウェアがあったとして。

*4:だから、デタラメにマウスを動かして、マウスの軌跡から乱数を生成するソフトウェアがあるのだ。

*5:暗号学的に安全な(暗号で使える)疑似乱数の意味。