“Well, that was unexpected …”: The Raspberry Pi’s Hardware Random Number Generator

Hey! This is a bit old! Things may have changed and I haven’t necessarily fixed them.

Most computers can’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 SoC, as it helps making the seed data for secure transactions. It was only recently that a driver for this circuit was supplied. To enable it (on Raspbian): I think the module is enabled by default now for the different versions of the SoC.

  1. Make sure your system is up to date with
    sudo apt-get update
    sudo apt -y upgrade
  2. Install the module:
    sudo modprobe bcm2708-rng
  3. To make sure it’s always loaded, add the following line to /etc/modules (editing as root):
    bcm2708-rng
  4. For some RNG-related stuff, install rng-tools:
    sudo apt-get install rng-tools

The /dev/hwrng device should now be available, but can only be read by the root user.

Nico pointed out that you also need to:

  1. Edit /etc/default/rng-tools, and remove the # at the start of the line
    HRNGDEVICE=/dev/hwrng
  2. Restart rng-tools with
    sudo service rng-tools restart

What random looks like

random20130606210642random20130606210630

Random data look pretty dull. Here are random RGB values made with:

sudo cat /dev/hwrng  | rawtoppm -rgb 256 256 | pnmtopng > random$(date +%Y%m%d%H%M%S).png

(you’ll need to install the netpbm toolkit to do this.)

What random sounds like

Two short WAV samples of, well, noise:

Yup, sounds like static. It was made with the rndsound.sh script. You’ll need to install sox to run it.

This is not random

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 RANDU, which at first glance appeared to produce nearly random results, but close study showed it to be very predictable.

I wrote (what I think to be) a C implementation of RANDU: randu.c. While it produces appropriately random-sounding audio data (randu17.wav), if you output it as an image:

randu17_rgbThose stripes are a giveaway; there should be no order in the output. (Then again, I have no idea if I’ve implemented RANDU correctly.) Testing random data is hard, then — 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:

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

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:

./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

See? Lots of failures there. It’s hardly random at all. If you really want to get out testing randomness, there are the dieharder tests. They takes ages to run, though.

(Note: newish Intel machines also have a real hardware RNG in the shape of Rdrand.)

I trust you all got the obvious Strictly Ballroom reference in the title?

54 comments

  1. → How can I use such a real hardware random number generator?

    By installing the rng-tools package and accessing data from /dev/urandom. That’ll be good enough.

    → Is there a qualitative difference between the random number generator of the Raspberry PI and the TrueRNG V3?

    I can’t say. The details of the Raspberry Pi’s HWRNG are proprietary, as are any software filters applied to it. I don’t have a TrueRNG v3 (I may have an older version somewhere) and have neither the time nor interest to investigate.

    The devices will give different results when passed through test suites, naturally, but it’s up to the researcher to decide if they’re random enough for their purpose. You can’t prove randomness: it’s an absence of order, hence a negative.

    → For scientific micropsychokinesis experiments … you need simple software for a true random number generator.
    Unfortunately such software does not seem to exist. … Is there such software?

    Neumann János Lajos’s quip about anyone generating random numbers by deterministic means living in a state of sin is as true now as it was in the 1950s. But it sounds like you’re looking for a function like R’s rnorm() that returns values from a normal distribution. Most routines like that are seeded by default from a pseudo-random number generator such as a Mersenne Twister, so may not be exactly what you’re looking for. Sadly, I don’t know how to seed them any other way.

  2. If for some reason the TRNG on the Raspberry Pi should cease to work, maybe in later versions, like the Version 5, then just use the webcam as a source. Capture with python images from the webcam, compare two images with each other and use the difference as bits for filling up integers. But in the initially phase skip the first 20 images or so, then compare some of the images for repeating patterns and skip them as well, by memorizing which pixel to skip in a map. Point the webcam to the ceiling or a blank sheet of paper and not to a volcano lamp as some suggest. The true randomness derives from the noise of the thousands even millions of diodes inside the sensor chip.

Leave a comment

Your email address will not be published. Required fields are marked *