(2015-04-16 初期記載) Raspberry Pi 、というかRaspberry Pi に搭載されている SoC (CPUその他を詰め込んだLSI)には、ハードウェア乱数発生器(Random Number Generator, RNG、以下長いので乱数発生器)が搭載されているそうです。 ということでさっそくセッティングしてみます。 参考サイト
目次 前提環境 †対象機器:2号機 (2015-06-01 追加で 1号機も設定) OSのバージョンなど。 $ uname -a Linux rasp01 3.18.11+ #776 PREEMPT Mon Apr 6 13:13:58 BST 2015 armv6l GNU/Linux 設定手順 †モジュール bcm2708-rng のロード †(2016-07-05メモ:Raspbian Jessie あるいはカーネル 4.4.13では、モジュールのロードは不要になっている模様) SoC上の乱数発生器を使うためには bcm2708-rng モジュールが必要になります。 # /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. # Parameters can be specified after the module name. snd-bcm2835 bcm2708-rng # この行を追加 モジュールをロードするにはOSを再起動するか、下記コマンドを実行します。 $ su # modprobe bcm2708-rng モジュールがロードされると、/dev/hwrng ファイルが出来上がります。ここからデータを読み出すと、乱数発生器由来のデータを読み出すことができます。 $ su # dd if=/dev/hwrng bs=1 count=16 | od -t x1 0000000 ba 7d a2 6b 9d 4f 39 c9 b8 6d c8 83 d9 83 4c 96 0000020 16+0 レコード入力 16+0 レコード出力 16 バイト (16 B) コピーされました、 0.0173367 秒、 0.9 kB/秒 ん~うまく値を取得できているようです。 とりあえず乱数がほしいだけ、という場合はここまでの設定でOKです。 乱数発生器のデータを既存の /dev/random に反映 †rng-tools パッケージをインストールすると、/dev/random での乱数発生のために /dev/hwrng のデータを使うようになる(エントロピープール?)そうで、いつもの遅くて使えない/dev/random が大変身して、乱数を素早くた~くさん得ることができるようになります。 下記のパッケージをインストールします。 $ su # apt-get install rng-tools (途中省略) この操作後に追加で 160 kB のディスク容量が消費されます。 取得:1 http://mirrordirector.raspbian.org/raspbian/ wheezy/main rng-tools armhf 2-unofficial-mt.14-1 [48.7 kB] (途中省略) rng-tools (2-unofficial-mt.14-1) を設定しています ... Starting Hardware RNG entropy gatherer daemon: rngd. インストールが完了すると、rngd というデーモンが自動起動し、/dev/random で取得できる乱数に、乱数発生器のデータが使用されるようになります(どのように使用されるかは不明ですが・・)。 (2015-04-17追記) Apr 17 10:10:36 rasp01 rngd[22175]: stats: bits received from HRNG source: 3340064 Apr 17 10:10:36 rasp01 rngd[22175]: stats: bits sent to kernel pool: 3299968 Apr 17 10:10:36 rasp01 rngd[22175]: stats: entropy added to kernel pool: 3299968 Apr 17 10:10:36 rasp01 rngd[22175]: stats: FIPS 140-2 successes: 167 Apr 17 10:10:36 rasp01 rngd[22175]: stats: FIPS 140-2 failures: 0 Apr 17 10:10:36 rasp01 rngd[22175]: stats: FIPS 140-2(2001-10-10) Monobit: 0 Apr 17 10:10:36 rasp01 rngd[22175]: stats: FIPS 140-2(2001-10-10) Poker: 0 Apr 17 10:10:36 rasp01 rngd[22175]: stats: FIPS 140-2(2001-10-10) Runs: 0 Apr 17 10:10:36 rasp01 rngd[22175]: stats: FIPS 140-2(2001-10-10) Long run: 0 Apr 17 10:10:36 rasp01 rngd[22175]: stats: FIPS 140-2(2001-10-10) Continuous run: 0 Apr 17 10:10:36 rasp01 rngd[22175]: stats: HRNG source speed: (min=301.478; avg=575.581; max=903.932)Kibits/s Apr 17 10:10:36 rasp01 rngd[22175]: stats: FIPS tests speed: (min=896.052; avg=7401.071; max=8168.653)Kibits/s Apr 17 10:10:36 rasp01 rngd[22175]: stats: Lowest ready-buffers level: 0 Apr 17 10:10:36 rasp01 rngd[22175]: stats: Entropy starvations: 133 Apr 17 10:10:36 rasp01 rngd[22175]: stats: Time spent starving for entropy: (min=2508; avg=7703.767; max=24938)us Apr 17 10:10:36 rasp01 rngd[22175]: Exiting... 次節の「読み出し速度」のところに /dev/urandom が遅くなる~、などと書いていますが、/dev/urandom もある程度エントロピープールの状態に影響されるのかもしれません。これ以上の調べものはひとまず終了とします(またの機会に:-)。 (2015-06-01追記) 実験、動作確認など †読み出し速度 †乱数の読み出し速度を計ってみます。 ddコマンドのパラメーターを見なおして再テスト †(2015-10-23) ddコマンドでのリード多数発行によるオーバーヘッドやおよびI/Oの中断を防ぐため、パラメーターを修正して再度トライ。 /dev/hwrng $ sudo dd iflag=fullblock if=/dev/hwrng of=/dev/null bs=102400 count=1 1+0 レコード入力 1+0 レコード出力 102400 バイト (102 kB) コピーされました、 0.910275 秒、 112 kB/秒 /dev/random $ dd iflag=fullblock if=/dev/random of=/dev/null bs=102400 count=1 1+0 レコード入力 1+0 レコード出力 102400 バイト (102 kB) コピーされました、 2.56903 秒、 39.9 kB/秒 /dev/urandom $ dd iflag=fullblock if=/dev/urandom of=/dev/null bs=102400 count=1 1+0 レコード入力 1+0 レコード出力 102400 バイト (102 kB) コピーされました、 0.0500743 秒、 2.0 MB/秒 /dev/urandom (rngd を停止) $ sudo /etc/init.d/rng-tools stop Stopping Hardware RNG entropy gatherer daemon: rngd. $ dd iflag=fullblock if=/dev/urandom of=/dev/null bs=102400 count=1 1+0 レコード入力 1+0 レコード出力 102400 バイト (102 kB) コピーされました、 0.0496313 秒、 2.1 MB/秒 $ sudo /etc/init.d/rng-tools start Starting Hardware RNG entropy gatherer daemon: rngd. ん~どう解釈してよいかわからないが、/dev/randomがそこそこ使い物になるようになったってことか。 古いテスト(参考にしないよ~に!!) †/dev/hwrng $ sudo dd if=/dev/hwrng of=/dev/null bs=1 count=102400 102400+0 レコード入力 102400+0 レコード出力 102400 バイト (102 kB) コピーされました、 0.902975 秒、 113 kB/秒 /dev/random $ dd if=/dev/random of=/dev/null bs=1 count=102400 102400+0 レコード入力 102400+0 レコード出力 102400 バイト (102 kB) コピーされました、 3.65963 秒、 28.0 kB/秒 /dev/urandom $ dd if=/dev/urandom of=/dev/null bs=1 count=102400 102400+0 レコード入力 102400+0 レコード出力 102400 バイト (102 kB) コピーされました、 5.55596 秒、 18.4 kB/秒 /dev/urandom (rngd を停止) $ dd if=/dev/urandom of=/dev/null bs=1 count=102400 102400+0 レコード入力 102400+0 レコード出力 102400 バイト (102 kB) コピーされました、 1.02642 秒、 99.8 kB/秒 (2015-10-23)この記述も古いので削除っす^^; 乱数の品質 †冒頭の参考サイトの1個目では、読み出した乱数から画像ファイルを作成してその乱雑さを視覚的に見る、こいうことを行っています。 乱数発生源は下記のパターンとします。実行はすべてスーパーユーザーとしました(めんどいので)。
rngdを停止させた状態での /dev/random は、時間がかかりすぎるため実施しません。 mkrndimg.shの内容 #!/bin/bash echo /dev/hwrng(rngdは無関係) cat /dev/hwrng | rawtoppm -rgb 256 256 | pnmtopng > hwrng.png echo /dev/random(rngdを起動、よい乱数:-) cat /dev/random | rawtoppm -rgb 256 256 | pnmtopng > random.png echo /dev/urandom(rngdを起動、よい乱数:-) time cat /dev/urandom | rawtoppm -rgb 256 256 | pnmtopng > urandom.pn echo /dev/urandom(rngd停止状態、すなわち従来の疑似乱数) /etc/init.d/rng-tools stop cat /dev/urandom | rawtoppm -rgb 256 256 | pnmtopng > urandom-pseud.png /etc/init.d/rng-tools start で、出来上がった画像は下記。
あれれ~画像がどれも似たり寄ったり・・・、乱数発生器いらないんじゃないの・・・? まとめ †ふ~んこんなこともできるんだ。 (2020-03-01追記) |