{"id":8508,"date":"2013-06-07T22:06:40","date_gmt":"2013-06-08T02:06:40","guid":{"rendered":"http:\/\/scruss.com\/blog\/?p=8508"},"modified":"2024-05-17T19:43:30","modified_gmt":"2024-05-17T23:43:30","slug":"well-that-was-unexpected-the-raspberry-pis-hardware-random-number-generator","status":"publish","type":"post","link":"https:\/\/scruss.com\/blog\/2013\/06\/07\/well-that-was-unexpected-the-raspberry-pis-hardware-random-number-generator\/","title":{"rendered":"\u201cWell, that was unexpected\u00a0\u2026\u201d\u009d: The Raspberry Pi&#8217;s Hardware Random Number Generator"},"content":{"rendered":"<p><span style=\"color: #ff0000;\"><strong>Hey! This is a bit old! Things may have changed and I haven&#8217;t necessarily fixed them.<\/strong><\/span><\/p>\n<p>Most computers can&#8217;t create true random numbers. They use a formula which makes a very long stream of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Pseudorandom_number_generator\">pseudo-random<\/a> numbers, but real randomness comes from thermal noise in analogue components. The Raspberry Pi has such a circuit in its SoC, as it helps making the seed data for secure transactions. It was only <a href=\"http:\/\/www.raspberrypi.org\/phpBB3\/viewtopic.php?f=29&amp;t=19334&amp;p=273944&amp;hilit=hwrng#p273944\">recently<\/a> that a driver for this circuit was supplied. <del>To enable it (on Raspbian):<\/del> I think the module is enabled by default now for the different versions of the SoC.<\/p>\n<ol>\n<li>Make sure your system is up to date with<br \/><span style=\"font-family: andale mono,times;\">sudo apt-get update<\/span><br \/><span style=\"font-family: andale mono,times;\">sudo apt -y upgrade<\/span><\/li>\n<li><del>Install the module:<\/del><br \/><del> <span style=\"font-family: andale mono,times;\">sudo modprobe bcm2708-rng<\/span><\/del><\/li>\n<li><del>To make sure it&#8217;s always loaded, add the following line to \/etc\/modules (editing as root):<\/del><br \/><del> <span style=\"font-family: andale mono,times;\">bcm2708-rng<\/span><\/del><\/li>\n<li>For some RNG-related stuff, install rng-tools:<br \/><span style=\"font-family: andale mono,times;\"><code>sudo apt-get install rng-tools<\/code><\/span><\/li>\n<\/ol>\n<p>The \/dev\/hwrng device should now be available, but can only be read by the root user.<\/p>\n<p><a href=\"https:\/\/www.nico-maas.de\/?p=1562\">Nico <\/a>pointed out that you also need to:<\/p>\n<ol>\n<li>Edit \/etc\/default\/rng-tools, and remove the # at the start of the line<br \/><span style=\"font-family: andale mono,times;\">HRNGDEVICE=\/dev\/hwrng<\/span><\/li>\n<li>Restart rng-tools with<br \/><span style=\"font-family: andale mono,times;\">sudo service rng-tools restart<\/span><\/li>\n<\/ol>\n<h2>What random looks like<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-8535\" src=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/random20130606210642.png\" alt=\"random20130606210642\" width=\"256\" height=\"256\" srcset=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/random20130606210642.png 256w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/random20130606210642-160x160.png 160w\" sizes=\"auto, (max-width: 256px) 100vw, 256px\" \/><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-8534\" src=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/random20130606210630.png\" alt=\"random20130606210630\" width=\"256\" height=\"256\" srcset=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/random20130606210630.png 256w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/random20130606210630-160x160.png 160w\" sizes=\"auto, (max-width: 256px) 100vw, 256px\" \/><\/p>\n<p>Random data look pretty dull. Here are random RGB values made with:<\/p>\n<pre><span style=\"font-family: andale mono,times;\">sudo cat \/dev\/hwrng\u00a0 | rawtoppm -rgb 256 256 | pnmtopng &gt; random$(date +%Y%m%d%H%M%S).png<\/span><\/pre>\n<p style=\"text-align: left;\">(you&#8217;ll need to install the netpbm toolkit to do this.)<\/p>\n<h2>What random sounds like<\/h2>\n<p>Two short WAV samples of, well, <em>noise<\/em>:<\/p>\n<ul>\n<li><a href=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/random20130603234239.wav\">random20130603234239<\/a><\/li>\n<li><a href=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/random20130603234250.wav\">random20130603234250<\/a><\/li>\n<\/ul>\n<p>Yup, sounds like static. It was made with the <a href=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/rndsound.sh_.txt\">rndsound.sh<\/a> script. You&#8217;ll need to install sox to run it.<\/p>\n<h2>This is not random<\/h2>\n<p>If it sounds like static, and even if it sometimes looks like static, it may not actually be true random noise. An infamous case of a pseudo random number generator being not very random at all was <a href=\"https:\/\/en.wikipedia.org\/wiki\/RANDU\">RANDU<\/a>, which at first glance appeared to produce nearly random results, but close study showed it to be very predictable.<\/p>\n<p>I wrote (what I think to be) a C implementation of RANDU: <a href=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/randu.c\">randu.c<\/a>. While it produces appropriately random-sounding audio data (<a href=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/randu17.wav\">randu17.wav<\/a>), if you output it as an image:<\/p>\n<p><a href=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/randu17_rgb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8536\" src=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/randu17_rgb.png\" alt=\"randu17_rgb\" width=\"256\" height=\"256\" srcset=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/randu17_rgb.png 256w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/06\/randu17_rgb-160x160.png 160w\" sizes=\"auto, (max-width: 256px) 100vw, 256px\" \/><\/a>Those stripes are a giveaway; there should be no order in the output. (<em>Then again, I have no idea if I&#8217;ve implemented RANDU correctly.<\/em>) Testing random data is hard, then \u2014 you really need a barrage of tests, and even some of them might fail even for truly random output. Thankfully, when you installed rngtools, it included rngtest, a simple checker for random data:<\/p>\n<p><span style=\"font-family: andale mono,times;\">sudo cat \/dev\/hwrng | rngtest -c 1000<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest 2-unofficial-mt.14<\/span><br \/><span style=\"font-family: andale mono,times;\">Copyright (c) 2004 by Henrique de Moraes Holschuh<\/span><br \/><span style=\"font-family: andale mono,times;\">This is free software; see the source for copying conditions.\u00a0 There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.<\/span><\/p>\n<p><span style=\"font-family: andale mono,times;\">rngtest: starting FIPS tests&#8230;<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: bits received from input: 20000032<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2 successes: 1000<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2 failures: 0<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Monobit: 0<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Poker: 0<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Runs: 0<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Long run: 0<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Continuous run: 0<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: input channel speed: (min=67.969; avg=921.967; max=1953125.000)Kibits\/s<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS tests speed: (min=842.881; avg=3208.336; max=6407.890)Kibits\/s<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: Program run time: 27658884 microseconds<\/span><\/p>\n<p>We were lucky that none of the tests failed for that run; sometimes there are a few failures. RANDU, on the other hand fares very badly:<\/p>\n<p><span style=\"font-family: andale mono,times;\">.\/randu 17\u00a0 | rngtest -c 1000<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest 2-unofficial-mt.14<\/span><br \/><span style=\"font-family: andale mono,times;\">Copyright (c) 2004 by Henrique de Moraes Holschuh<\/span><br \/><span style=\"font-family: andale mono,times;\">This is free software; see the source for copying conditions.\u00a0 There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.<\/span><\/p>\n<p><span style=\"font-family: andale mono,times;\">rngtest: starting FIPS tests&#8230;<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: bits received from input: 20000032<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2 successes: 0<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2 failures: 1000<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Monobit: 730<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Poker: 1000<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Runs: 289<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Long run: 0<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS 140-2(2001-10-10) Continuous run: 0<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: input channel speed: (min=45.630; avg=14255.221; max=19073.486)Mibits\/s<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: FIPS tests speed: (min=23.694; avg=154.238; max=176.606)Mibits\/s<\/span><br \/><span style=\"font-family: andale mono,times;\">rngtest: Program run time: 141071 microseconds<\/span><\/p>\n<p>See? Lots of failures there. It&#8217;s hardly random at all. If you really want to get out testing randomness, there are the <a href=\"http:\/\/www.phy.duke.edu\/~rgb\/General\/dieharder.php\">dieharder<\/a> tests. They takes ages to run, though.<\/p>\n<p>(Note: newish Intel machines also have a real hardware RNG in the shape of <a href=\"http:\/\/software.intel.com\/en-us\/articles\/user-manual-for-the-rdrand-library-linux-version\">Rdrand<\/a>.)<\/p>\n\n\n<p>I trust you all got the obvious <em>Strictly Ballroom<\/em> reference in the title?<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey! This is a bit old! Things may have changed and I haven&#8217;t necessarily fixed them. Most computers can&#8217;t create true random numbers. They use a formula which makes a very long stream of pseudo-random numbers, but real randomness comes from thermal noise in analogue components. The Raspberry Pi has such a circuit in its [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[7],"tags":[1403,2668,1473,1384,3263,2510,2669],"class_list":["post-8508","post","type-post","status-publish","format-standard","hentry","category-computers-suck","tag-crypto","tag-hardware","tag-noise","tag-random","tag-randu","tag-raspberrypi","tag-rng"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pQNZZ-2de","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/8508","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/comments?post=8508"}],"version-history":[{"count":19,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/8508\/revisions"}],"predecessor-version":[{"id":17561,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/8508\/revisions\/17561"}],"wp:attachment":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/media?parent=8508"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/categories?post=8508"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/tags?post=8508"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}