树莓派的硬件随机数生成器
大部分计算机不能生成真正的随机数。他们使用生成很长伪随机数流的公式,但是真正的随机来自模拟元件的热噪音。Raspberry Pi有这样一个电子元件,它可以为安全传输提供种子数据(seed data)。直到最近才为这个电子元件提供了驱动。想要激活它(在Raspbian上):
确保你的系统是最新的
sudo apt-get update
sudo apt-get -y dist-upgrade
sudo rpi-update
and, if necessary, reboot.
安装模组:
sudo modprobe bcm2708-rng
想要确保它总是被加载,在/etc/modules中添加下述行(以root权限编辑):
bcm2708-rng
对于一些RNG相关工作,安装rng-tools:
sudo apt-get install rng-tools
现在/dev/hwrng设备就可用了,但是只能以root用户读取。
随机看起来是什么样子
随机数看起来相当枯燥。这是随机的RGB值:
sudo cat /dev/hwrng | rawtoppm -rgb 256 256 | pnmtopng > random$(date +%Y%m%d%H%M%S).png
(你需要安装netpbm工具包才能执行上述命令)
随机听起来是什么样子
两段简短的WAV噪音样本:
random20130603234239
random20130603234250
是的,听起来像静电干扰。这是使用rndsound.sh这个脚本做的。你需要安装sox才能执行它。
这不随机
如果听起来像静电干扰,即使有时候像静电干扰,那么它也有可能不是真正的随机噪音。伪随机数并不随机的一个声名狼藉的案例是RANDU,咋一看生成非常随机的结果,但是仔细研究发现结果是可预测的。
我写了(我认为是)一个C语言实现的RANDU:randu.c。虽然它可以生成听起来近似随机的音频数据(randu17.wav),但是如果你以图像的形式输出:
这些条纹泄露了真像;本来是不应该有规律的。测试随机数据是难的,然而——你确实需要大量的测试,即使其中某些测试对于真正的随机输出也可能会失败。谢天谢地,当你安装了rngtools,它包含rngtest,一个简单的随机数据检测器:
sudo cat /dev/hwrng | rngtest -c 1000
rngtest 2-unofficial-mt.14
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
rngtest: starting FIPS tests…
rngtest: bits received from input: 20000032
rngtest: FIPS 140-2 successes: 1000
rngtest: FIPS 140-2 failures: 0
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 0
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=67.969; avg=921.967; max=1953125.000)Kibits/s
rngtest: FIPS tests speed: (min=842.881; avg=3208.336; max=6407.890)Kibits/s
rngtest: Program run time: 27658884 microseconds
很幸运对于这次运行没有测试失败;有时会有一些失败。但是对于RANDU,情况就很糟糕了:
./randu 17 | rngtest -c 1000
rngtest 2-unofficial-mt.14
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
rngtest: starting FIPS tests…
rngtest: bits received from input: 20000032
rngtest: FIPS 140-2 successes: 0
rngtest: FIPS 140-2 failures: 1000
rngtest: FIPS 140-2(2001-10-10) Monobit: 730
rngtest: FIPS 140-2(2001-10-10) Poker: 1000
rngtest: FIPS 140-2(2001-10-10) Runs: 289
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=45.630; avg=14255.221; max=19073.486)Mibits/s
rngtest: FIPS tests speed: (min=23.694; avg=154.238; max=176.606)Mibits/s
rngtest: Program run time: 141071 microseconds
看到了么?好多失败。它一点儿都不随机。如果你真的想要测试随机性,可以采用dieharder测试。虽然它需要执行很长时间。