linuxでは乱数を取得するために /dev/random と /dev/urandom の2種類のデバイスがあります。それぞれの説明は man 4 random にみっちり書いてありますが、かいつまんで言うと:
- random: カーネルがあつめてきたノイズを元に品質の高い疑似乱数を生成します。ノイズが不足するとblockします。
- urandom: カーネルがあつめてきたノイズを元にそこそこの品質の疑似乱数を生成します。品質はそこそこですがblockしないので速いです。
いいかげんな乱数でよければurandomなのですが、sshのキーをつくるとかsslちゃんとやろうとか証明書発行しようとかしたいときは/dev/randomをつかいたい、でも周辺装置とかチップセットの制約とかめんどいなー。 という事情がありました。
そこでIvy Bridge世代ではrdrand命令を追加して、CPUのチップ内で乱数生成をして専用命令で読みだせるようにしました。このテクノロジー自体もかなりおもしろいです。IEEE Spectrumの記事がおすすめ。
実際つかってみましょう。rngdの最近のバージョンでは、rdrand命令に対応しています。最近のfedoraであればデフォルトでrngdが動いていますが、有効でなければ systemctl start rngd.service とか叩いて有効にします。
ddで1バイトずつ乱数読みだしをおこないます。乱数生成器がない環境とかrngd止まってるとかだとこれがblockしてずーーっと待つことになるので注意。
$ dd if=/dev/random of=/dev/null bs=1 count=1000000比較対象としてurandomでも同じことをしてみましょう。
1000000+0 records in
1000000+0 records out
1000000 bytes (1.0 MB) copied, 4.32184 s, 231 kB/s
$ dd if=/dev/urandom of=/dev/null bs=1 count=1000000urandomのほうがまだ速いですけど1/3くらいの速度はでますね。これくらい出てくれるなら乱数つかい放題といってもいいんじゃないかしら。
1000000+0 records in
1000000+0 records out
1000000 bytes (1.0 MB) copied, 1.3472 s, 742 kB/s
2013-12-16追記
Debianではrng-toolsが独自forkなためrdrand対応がまだ入っていないらしい。rng-toolsのアップデートについてのケースがfileされている。一方UbuntuにはDebianはforkだから独自に新版入れてくれというケースが。Debianの動き悪いのはわかるけどUbuntuだけ対応するってなんだかなあ。