(2015-04-16 初期記載)
(2015-10-23 ddコマンドによる動作確認をやり直し)
(2016-07-05) モジュール bcm2708-rng のロードはもはや不要の模様(Raspbian Jessie あるいは Linuxカーネル4.4.13)。

Raspberry Pi 、というかRaspberry Pi に搭載されている SoC (CPUその他を詰め込んだLSI)には、ハードウェア乱数発生器(Random Number Generator, RNG、以下長いので乱数発生器)が搭載されているそうです。
えーっとつまり、普段OSから得ている乱数は「疑似乱数」というもので一見乱数っぽいんだけど実は規則性があったりするのですが、この「乱数発生器」では疑似ではない乱数を得ることができますよ、というシロモノ、ということになります。

ということでさっそくセッティングしてみます。
手順などは下記のサイトを参考(というかほぼそのまんま)にさせていただきました。Thanks!!

参考サイト

設定関連
http://scruss.com/blog/2013/06/07/well-that-was-unexpected-the-raspberry-pis-hardware-random-number-generator/
Linuxでの乱数生成の解説
http://moriwaka.blogspot.jp/2013/12/cpu.html

目次

前提環境

対象機器: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 モジュールが必要になります。
下記のファイルに1行追記して、モジュールがロードされるようにします。
ファイル名 /etc/modules
ファイル内容

# /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追記)
実は、rngdは /dev/hwrng のデータを /dev/randomへ提供するのではなく、カーネルのエントロピープールへ提供する、らしいです。rng-tools を停止した際に出力される syslog に、そのような記載がありました(下記の上から2行目)。

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追記)
rngdのステータスらしきログが定期的に(1時間に1回、15行程度) syslog へ出力されるようになります。
ログ出力の抑止方法は・・・宿題ということで。

実験、動作確認など

読み出し速度

乱数の読み出し速度を計ってみます。
ちなみにCPUクロックは、通常700MHz、最高900MHzとして可変にしてあります(何かするとすぐに900MHzになるようですが・・・)。
/dev/hwrngだけはスーパーユーザーでないと読み出せませんので sudo しています。

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/randomなので、擬似ではない乱数が使えるってことで。
/dev/urandom (擬似乱数)に対してrngd が影響しているかどうかは不明。

古いテスト(参考にしないよ~に!!)

/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)この記述も古いので削除っす^^;
4番目のrngdを停止した状態での/dev/urandomの読み出し速度が、3番目(rngd起動状態)より早くなっています。しかも、/dev/randomより遅くなってるし・・・。
もしかしたら rngd 起動状態だと、/dev/random だけでなく /dev/urandom の乱数も、乱数発生器由来になるのかもしれません(きっとマニュアルかドキュメントのどこかに書いてあるんだろうけど)。

乱数の品質

冒頭の参考サイトの1個目では、読み出した乱数から画像ファイルを作成してその乱雑さを視覚的に見る、こいうことを行っています。
さっそく猿真似してやってみることにします。
画像生成には netpbm toolkit というのが必要ですが、デフォルトでインストールされていました。

乱数発生源は下記のパターンとします。実行はすべてスーパーユーザーとしました(めんどいので)。

  • /dev/hwrng(rngdは無関係)
  • /dev/random(rngdを起動、よい乱数:-)
  • /dev/urandom(rngd起動状態)
  • /dev/urandom(rngd停止状態、従来の疑似乱数)

rngdを停止させた状態での /dev/random は、時間がかかりすぎるため実施しません。
画像を一気に作成すべく、下記のファイルをスクリプトにして実行します。
スクリプトは mkrndimg.sh とでもしておきますか。

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

で、出来上がった画像は下記。
容量が各200KB弱ほどありますので、興味のある方のみリンクをクリックして画像を表示してみてください。

filehwrng.png filerandom.png fileurandom.png fileurandom-pseud.png

あれれ~画像がどれも似たり寄ったり・・・、乱数発生器いらないんじゃないの・・・?
乱数ってどう評価したらいいのかねぇ。

まとめ

ふ~んこんなこともできるんだ。
おしまい。

(2020-03-01追記)
busterではデフォルトで起動するようです。


添付ファイル: fileurandom-pseud.png 343件 [詳細] fileurandom.png 336件 [詳細] filehwrng.png 290件 [詳細] filerandom.png 383件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2020-03-08 (日) 17:14:46 (154d)