“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.)

52 comments

  1. The concept of a computer generating a true random number has always boggled my mind. Thanks for the interesting and insightful analysis!

  2. Thanks for this article.

    Just a quick note on FIPS 140-2. These tests are a bunch of simple statistical calculations. Those statistics will occasionally fail on truly random data at an interval of around 2,500 iterations/failure. If it isn’t failing occasionally, you’re not seeing random data. Seeing a failure is not a problem. Seeing too many or too few is a problem.

    Source: “random number guy” for over a decade, and working on a FIPS 140-2 Level 3 hardware project right now.

    CHEERS

  3. Really cool analysis. It’s amazing how randomly generated numbers can be constructed into pictures – almost like synethesia.

  4. Re: computers generating random numbers: It’s not that the computers in the usual sense – digital circuitry – is generating random numbers, it’s that some CPUs have special, mostly analog circuitry which generates data based on thermal and / or quantum events.

  5. Do you know what type of random number generator is on the pi’s SoC (i.e. photoelectric, thermal, etc.)? Great article thanks

  6. Not sure why, but one of the images says “stolen from scruss.com”, but I’m reading it on scruss.com.

  7. The problem with Rdrand mentioned at the end of this article is that it is newly suspect as a piece of the linux kernel that the NSA could use to get not-truly-random numbers to spit out, be used for encryption that they can now predict. I LOVE the idea of using random thermal data to generate random numbers, just wish this method was used in desktop linux instead of the NSA backdoor Linus allowed in. I love this approach and would love to see it used elsewhere.

  8. Yeah, I made that point (if rather weakly) in the article. Some failures are okay, but getting exactly the same %age of failures every time would be suspect.

  9. Well, you could always use any of the many other hardware RNGs that are available, Jason — assuming that you trust them not to have been compomised by the NSA. RdRand output looks and sounds random enough to me, but then again, I would say that… ☺

  10. Robert Coveyou Einstein said the generation of random numbers is too important to be left to chance.

  11. What are you calling the FIPS 140-2 tests? Do you mean the suite of tests in NIST SP 800-22? They are not a requirement for FIPS 140-2 validation. There are new tests in Draft NIST SP 800-90B that will eventually be used to validate entropy sources.

  12. Please remember that a hardware source of random data does not have to output statistically perfect (identically uniformly distributed independent random bits) to be useful. It is actually no problem if there is quite a bit of redundancy left in the raw output of a hardware source of randomness, as long as there is a guaranteed minimum amount of entropy left per output bit. You can then use a hash function to distill that (possibly quite thinly spread) randomness into a much shorter sequence of extremely high quality random bits, which you can then use to seed a high-quality cryptographic pseudo-random number generator to get high bit-rate output.

    It would be foolish for the device designer to invest a lot of energy and costly device-calibration effort into generating a perfect hardware random source if you can much more easily get all the desired statistical qualities by hashing a long-but-mediocre output sequence from a simple HRNG into a shorter high-quality bit string.

    Do you see any problems if I read 16 kilobyte of noisy data from /dev/hwrng, and feed it through sha-512 (or almost any other hash function) to obtain 512 high-quality random bits, e.g. to generate a few crypto keys?

    What is much more important than the statistical quality of the raw (unprocessed) data that you get out of a hardware random source is that you can easily test the device for circuit defects or manipulation. A transistor in the random source could have died or shorted, thereby dramatically reducing the remaining entropy, or an attacker could create environmental conditions (e.g., unusual signals added to the power-supply line, external EM fields applied, unusual temperatures, etc.) to force the random source into an externally controlled state. The driver/user of the device must be able to detect such manipulation in software.

    The documentation of the device should have come with detailed information of what statistical properties you can and cannot expect from the device, and with advice on how to post-process its output before using it in application.

  13. IMHO it is right, that a “real” TRNG can/should have failures in statistical tests. The most TRNGs in HW have some kind of bias in the 0/1 distribution, so some tests will fail most the time on raw source. After some kind of post processing (von Neuman for example) these defects should go away. In the end, after post processing, no one really can distinguish hw-generated from pseudo random.

  14. I don’t think Broadcom released the specs.

    Further down in the forum thread you linked to, dom (Broadcom engineer) says “The spec doesn’t say how it works, but I believe it amplifies thermal noise as its entoypy source” and then also provides a link to the software-interface specs http://pastehtml.com/view/crkxyohmp.rtxt

  15. I did run some dieharder tests.

    Here are the results of a 3 GB file of random data from the RPi:
    ssh -v pi@xxx.xx.x.xx dd if=/dev/hwrng iflag=fullblock count=3072 bs=1024k > random.pi

    $ dieharder -a -g 201 -f random.pi
    #=============================================================================#
    # dieharder version 3.31.1 Copyright 2003 Robert G. Brown #
    #=============================================================================#
    rng_name | filename |rands/second|
    file_input_raw| random.pi| 5.76e+07 |
    #=============================================================================#
    test_name |ntup| tsamples |psamples| p-value |Assessment
    #=============================================================================#
    diehard_birthdays| 0| 100| 100|0.44162256| PASSED
    diehard_operm5| 0| 1000000| 100|0.97834683| PASSED
    diehard_rank_32x32| 0| 40000| 100|0.22875509| PASSED
    diehard_rank_6x8| 0| 100000| 100|0.90591011| PASSED
    diehard_bitstream| 0| 2097152| 100|0.98154299| PASSED
    diehard_opso| 0| 2097152| 100|0.58496940| PASSED
    diehard_oqso| 0| 2097152| 100|0.67230635| PASSED
    diehard_dna| 0| 2097152| 100|0.68077916| PASSED
    diehard_count_1s_str| 0| 256000| 100|0.52161513| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_count_1s_byt| 0| 256000| 100|0.36657051| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_parking_lot| 0| 12000| 100|0.14615348| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_2dsphere| 2| 8000| 100|0.51948592| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_3dsphere| 3| 4000| 100|0.99784735| WEAK
    # The file file_input_raw was rewound 1 times
    diehard_squeeze| 0| 100000| 100|0.49502475| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_sums| 0| 100| 100|0.01205431| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_runs| 0| 100000| 100|0.55519208| PASSED
    diehard_runs| 0| 100000| 100|0.70469294| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_craps| 0| 200000| 100|0.94919295| PASSED
    diehard_craps| 0| 200000| 100|0.99772536| WEAK
    # The file file_input_raw was rewound 4 times
    marsaglia_tsang_gcd| 0| 10000000| 100|0.47879497| PASSED
    marsaglia_tsang_gcd| 0| 10000000| 100|0.21523906| PASSED
    # The file file_input_raw was rewound 4 times
    sts_monobit| 1| 100000| 100|0.74877259| PASSED
    # The file file_input_raw was rewound 4 times
    sts_runs| 2| 100000| 100|0.35536912| PASSED
    # The file file_input_raw was rewound 4 times
    sts_serial| 1| 100000| 100|0.21470789| PASSED
    sts_serial| 2| 100000| 100|0.29920573| PASSED
    sts_serial| 3| 100000| 100|0.02786242| PASSED
    sts_serial| 3| 100000| 100|0.11339900| PASSED
    sts_serial| 4| 100000| 100|0.50410922| PASSED
    sts_serial| 4| 100000| 100|0.93818269| PASSED
    sts_serial| 5| 100000| 100|0.34317098| PASSED
    sts_serial| 5| 100000| 100|0.66083335| PASSED
    sts_serial| 6| 100000| 100|0.89327453| PASSED
    sts_serial| 6| 100000| 100|0.87256388| PASSED
    sts_serial| 7| 100000| 100|0.89769711| PASSED
    sts_serial| 7| 100000| 100|0.36542931| PASSED
    sts_serial| 8| 100000| 100|0.97782591| PASSED
    sts_serial| 8| 100000| 100|0.96048082| PASSED
    sts_serial| 9| 100000| 100|0.46104148| PASSED
    sts_serial| 9| 100000| 100|0.15143815| PASSED
    sts_serial| 10| 100000| 100|0.97860495| PASSED
    sts_serial| 10| 100000| 100|0.89142340| PASSED
    sts_serial| 11| 100000| 100|0.93996626| PASSED
    sts_serial| 11| 100000| 100|0.70116494| PASSED
    sts_serial| 12| 100000| 100|0.90461086| PASSED
    sts_serial| 12| 100000| 100|0.35340505| PASSED
    sts_serial| 13| 100000| 100|0.92847186| PASSED
    sts_serial| 13| 100000| 100|0.87854496| PASSED
    sts_serial| 14| 100000| 100|0.75618383| PASSED
    sts_serial| 14| 100000| 100|0.91748650| PASSED
    sts_serial| 15| 100000| 100|0.98876227| PASSED
    sts_serial| 15| 100000| 100|0.87472238| PASSED
    sts_serial| 16| 100000| 100|0.82187199| PASSED
    sts_serial| 16| 100000| 100|0.94553460| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 1| 100000| 100|0.43746469| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 2| 100000| 100|0.09116648| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 3| 100000| 100|0.18602663| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 4| 100000| 100|0.58410035| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 5| 100000| 100|0.98299756| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 6| 100000| 100|0.68959231| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 7| 100000| 100|0.68859609| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 8| 100000| 100|0.40919814| PASSED
    # The file file_input_raw was rewound 5 times
    rgb_bitdist| 9| 100000| 100|0.83476731| PASSED
    # The file file_input_raw was rewound 5 times
    rgb_bitdist| 10| 100000| 100|0.70701922| PASSED
    # The file file_input_raw was rewound 5 times
    rgb_bitdist| 11| 100000| 100|0.73324807| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_bitdist| 12| 100000| 100|0.06218252| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_minimum_distance| 2| 10000| 1000|0.95029870| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_minimum_distance| 3| 10000| 1000|0.94791832| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_minimum_distance| 4| 10000| 1000|0.22161113| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_minimum_distance| 5| 10000| 1000|0.95225684| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_permutations| 2| 100000| 100|0.99248941| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_permutations| 3| 100000| 100|0.98844051| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_permutations| 4| 100000| 100|0.28058355| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_permutations| 5| 100000| 100|0.12208743| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_lagged_sum| 0| 1000000| 100|0.30328442| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_lagged_sum| 1| 1000000| 100|0.05415472| PASSED
    # The file file_input_raw was rewound 7 times
    rgb_lagged_sum| 2| 1000000| 100|0.95754412| PASSED
    # The file file_input_raw was rewound 7 times
    rgb_lagged_sum| 3| 1000000| 100|0.18664151| PASSED
    # The file file_input_raw was rewound 8 times
    rgb_lagged_sum| 4| 1000000| 100|0.33370349| PASSED
    # The file file_input_raw was rewound 8 times
    rgb_lagged_sum| 5| 1000000| 100|0.47502111| PASSED
    # The file file_input_raw was rewound 9 times
    rgb_lagged_sum| 6| 1000000| 100|0.94283881| PASSED
    # The file file_input_raw was rewound 10 times
    rgb_lagged_sum| 7| 1000000| 100|0.16916360| PASSED
    # The file file_input_raw was rewound 11 times
    rgb_lagged_sum| 8| 1000000| 100|0.37909411| PASSED
    # The file file_input_raw was rewound 13 times
    rgb_lagged_sum| 9| 1000000| 100|0.43806456| PASSED
    # The file file_input_raw was rewound 16 times
    rgb_lagged_sum| 11| 1000000| 100|0.12769616| PASSED
    # The file file_input_raw was rewound 17 times
    rgb_lagged_sum| 12| 1000000| 100|0.07845188| PASSED
    # The file file_input_raw was rewound 19 times
    rgb_lagged_sum| 13| 1000000| 100|0.08909310| PASSED
    # The file file_input_raw was rewound 21 times
    rgb_lagged_sum| 14| 1000000| 100|0.29332492| PASSED
    # The file file_input_raw was rewound 23 times
    rgb_lagged_sum| 15| 1000000| 100|0.12703405| PASSED
    # The file file_input_raw was rewound 25 times
    rgb_lagged_sum| 16| 1000000| 100|0.03174042| PASSED
    # The file file_input_raw was rewound 27 times
    rgb_lagged_sum| 17| 1000000| 100|0.17517386| PASSED
    # The file file_input_raw was rewound 29 times
    rgb_lagged_sum| 18| 1000000| 100|0.15280091| PASSED
    # The file file_input_raw was rewound 32 times
    rgb_lagged_sum| 19| 1000000| 100|0.60967828| PASSED
    # The file file_input_raw was rewound 35 times
    rgb_lagged_sum| 20| 1000000| 100|0.10194318| PASSED
    # The file file_input_raw was rewound 37 times
    rgb_lagged_sum| 21| 1000000| 100|0.03507058| PASSED
    # The file file_input_raw was rewound 40 times
    rgb_lagged_sum| 22| 1000000| 100|0.13422522| PASSED
    # The file file_input_raw was rewound 43 times
    rgb_lagged_sum| 23| 1000000| 100|0.01067772| PASSED
    # The file file_input_raw was rewound 46 times
    rgb_lagged_sum| 24| 1000000| 100|0.46862183| PASSED
    # The file file_input_raw was rewound 49 times
    rgb_lagged_sum| 25| 1000000| 100|0.98195161| PASSED
    # The file file_input_raw was rewound 53 times
    rgb_lagged_sum| 26| 1000000| 100|0.97621690| PASSED
    # The file file_input_raw was rewound 56 times
    rgb_lagged_sum| 27| 1000000| 100|0.83544717| PASSED
    # The file file_input_raw was rewound 60 times
    rgb_lagged_sum| 28| 1000000| 100|0.58451929| PASSED
    # The file file_input_raw was rewound 64 times
    rgb_lagged_sum| 29| 1000000| 100|0.50212375| PASSED
    # The file file_input_raw was rewound 67 times
    rgb_lagged_sum| 30| 1000000| 100|0.40818183| PASSED
    # The file file_input_raw was rewound 71 times
    rgb_lagged_sum| 31| 1000000| 100|0.01224834| PASSED
    # The file file_input_raw was rewound 76 times
    rgb_lagged_sum| 32| 1000000| 100|0.53921762| PASSED
    # The file file_input_raw was rewound 76 times
    rgb_kstest_test| 0| 10000| 1000|0.22225407| PASSED
    # The file file_input_raw was rewound 76 times
    dab_bytedistrib| 0| 51200000| 1|0.96307866| PASSED
    # The file file_input_raw was rewound 76 times
    dab_dct| 256| 50000| 1|0.17016735| PASSED
    Preparing to run test 207. ntuple = 0
    # The file file_input_raw was rewound 76 times
    dab_filltree| 32| 15000000| 1|0.74706518| PASSED
    dab_filltree| 32| 15000000| 1|0.78180928| PASSED
    Preparing to run test 208. ntuple = 0
    # The file file_input_raw was rewound 76 times
    dab_filltree2| 0| 5000000| 1|0.36853946| PASSED
    dab_filltree2| 1| 5000000| 1|0.82642793| PASSED
    Preparing to run test 209. ntuple = 0
    # The file file_input_raw was rewound 76 times
    dab_monobit2| 12| 65000000| 1|0.73830796| PASSED

    As you can see some tests failed, but it’s still better than when I check /dev/random on my i7 desktop with Linux 3.10 and haveged (you really want to wait that long ?):

    diehard_sums| 0| 100| 100|0.00018507| WEAK
    sts_serial| 8| 100000| 100|0.99995184| WEAK
    sts_serial| 14| 100000| 100|0.99988629| WEAK
    rgb_lagged_sum| 16| 1000000| 100|0.99957501| WEAK

    This is the result from /dev/urandom on the same desktop machine without haveged:
    diehard_craps| 0| 200000| 100|0.99996478| WEAK
    sts_serial| 3| 100000| 100|0.99564125| WEAK
    rgb_lagged_sum| 7| 1000000| 100|0.99804114| WEAK

    So you be the judge. I did not have time to do multiple tests (especially with the RPi).

    I do wonder what results others have.

  16. Does anyone know if there is a description of the RNG in the chip to understand how these are generated internally? Thanks.

  17. The article gives the wrong impression that being PRNG means the output will never be truly uniform, whilst a HWRNG guarantees it. It’s not stated that way outright, but its structure and wording strongly suggest that, and it doesn’t disclaim enough to make it clear that’s not the case to a reader not already knowledgeable about the subject, which is precisely the category of readers who will need a description of what an RNG, PRNG and HWRNG is.

    In reality, a good quality PRNG may well be much more uniform and of statistically higher quality than most available HWRNGs. The “pseudo” in PRNG doesn’t refer to “not being really uniform”, but to being uniform only with respect to any given seed, which obviously results in deterministic outputs in a fully deterministic system. But it’s the only pseudo-random quality in there, and has nothing to do with pseudo-random numbers being statistically distinguishable from truly random data.

  18. It wasn’t intended to give that impression. If anyone gets anything from the article, it’s that making an RNG is hard.

  19. Right, I didn’t think you did it on purpose, I just wanted to bring to your attention that this is largely what you ended up (unintentionally) conveying. Much like RNGs, writing is hard 🙂

  20. …but real randomness comes from thermal noise in analogue components

    Yes, but not only from thermal noise. True random behavior can come from both quantum events and non-quantum events found in nature. Thermal fluctuations are a byproduct of a non-quantum event. But other sources can exhibit true random behaviors:

    * Atmospheric noise, which is caused largely due to lightning. Weather analysis shows that there are roughly 100 lightning strikes per second on the Earth at any given second.
    * Radioactive decay of alpha, beta, gamma and x-ray particles is completely unpredictable and 100% random.
    * “Shot Noise” in electronic circuits.
    * “Avalanche Noise” in Zener diodes.
    * Photons travelling through a semi-transparent mirror.
    * Thermal fluctuations in resistors, as you mentioned in your post, and probably what the Broadcom chip is doing.

    Etc. There are many sources of true randomness. Even humans can actually be a good source of randomness, believe it or not. Timing key switch presses on a keyboard, or measuring the speed, distance and location of mouse movements on a screen are generally how operating systems fill their entropy pools.

  21. @Lennie

    I did the same Dieharder test on a 3GB generated file from the RPi. The only weak i got was:

    rgb_lagged_sum| 8| 1000000| 100|0.99917509| WEAK

  22. Very cool post but now I have the million dollar question. How can I import the random numbers into a desktop running Debian? I would like to use the Pi as a cheap random number generator for my desktop. Thanks

  23. If it’s a recent x86 box, there should be a way of enabling hardware RdRand as one of your entropy sources. This will be very much faster than piping from the Raspberry Pi.

  24. I don’t trust RdRand ideally would like to use the Pi as an additional entropy source. Any idea how to pipe this over to desktop dev/random?

  25. Why don’t you trust Intel’s RdRand, but you do trust Broadcom’s hwrand? There are papers written about the former, but a few handwavey comments about the latter.

    I don’t know how. I have only a vague idea how /dev/random works. I certainly wouldn’t know (or be interested in) how to write a daemon on the Raspberry Pi to expose hwrand to the network for other clients to read and add to their entropy pools. Random googling has turned up Using RNDADDENTROPY to add entropy to /dev/random and Feeding /dev/random entropy pool?. You might be better off with an Entropy Key than trying to homebrew this.

  26. To obtain some entropy from the Raspberry Pi’s HWRNG, on your desktop you might issue the command:

    ssh root@[rpi-ip-addr] “dd if=/dev/hwrng bs=1024 count=1” > /dev/urandom

    Read man 4 random for details of what it means to write to /dev/urandom.

  27. Awesome thank you Jack. The reason I wanted this is because Entropy Key is apparently out of business unfortunately. Additionally I wanted an extra entropy source since even adding bad sources will not diminish security as long as there is one good source.

  28. @Jason Martinez:

    The nice thing about the Linux kernel’s random number pool is the elegant approach they took to it:

    1. They mix bits into the pool using a reversible algorithm, which guarantees that new data can’t remove old entropy. (If you know the random values you added, you can reverse the process… but you’ll still be stuck trying to predict every single bit you didn’t supply.)

    2. Because diluting the pool is still a concern, the API is designed so low-quality entropy sources can be mixed in with lower value (eg. You can mix in 1K of data that’s only worth 256 bytes of entropy) or even no value (which allows you to mix in a completely untrusted source and, because of point #1, it can’t hurt but might help.)

    @scruss:

    Another alternative to the Entropy Key would be the recently-released TrueRNG which costs $50 US and has 12 times the throughput.

    (I don’t have an Entropy Key to verify the 32kbit figure given on Wikipedia but I can confirm the ~392kbit figure for the TrueRNG as well as verify that it passes rngtest at a rate of roughly 1.5 failures per thousand.

    According to my calculations, I’ll need to leave it for roughly 18 hours to gather 3GiB of data so I can compare it to Lennie’s dieharder run.

  29. To finish off my previous post, here’s the dieharder result for 3GiB of TrueRNG output to inform anyone considering purchasing one:


    $ dd if=/dev/TrueRNG iflag=fullblock count=3072 bs=1024k > random.trng
    3072+0 records in
    3072+0 records out
    3221225472 bytes (3.2 GB) copied, 64325.9 s, 50.1 kB/s
    $ dieharder -a -g 201 -f random.trng
    #=============================================================================#
    # dieharder version 3.31.1 Copyright 2003 Robert G. Brown #
    #=============================================================================#
    rng_name | filename |rands/second|
    file_input_raw| random.trng| 1.72e+07 |
    #=============================================================================#
    test_name |ntup| tsamples |psamples| p-value |Assessment
    #=============================================================================#
    diehard_birthdays| 0| 100| 100|0.48864015| PASSED
    diehard_operm5| 0| 1000000| 100|0.90950277| PASSED
    diehard_rank_32x32| 0| 40000| 100|0.87431209| PASSED
    diehard_rank_6x8| 0| 100000| 100|0.96845359| PASSED
    diehard_bitstream| 0| 2097152| 100|0.43627780| PASSED
    diehard_opso| 0| 2097152| 100|0.61670544| PASSED
    diehard_oqso| 0| 2097152| 100|0.84487860| PASSED
    diehard_dna| 0| 2097152| 100|0.97252682| PASSED
    diehard_count_1s_str| 0| 256000| 100|0.94697487| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_count_1s_byt| 0| 256000| 100|0.94266678| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_parking_lot| 0| 12000| 100|0.89432206| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_2dsphere| 2| 8000| 100|0.26694983| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_3dsphere| 3| 4000| 100|0.77429021| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_squeeze| 0| 100000| 100|0.86056318| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_sums| 0| 100| 100|0.06338568| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_runs| 0| 100000| 100|0.01934904| PASSED
    diehard_runs| 0| 100000| 100|0.07354992| PASSED
    # The file file_input_raw was rewound 1 times
    diehard_craps| 0| 200000| 100|0.91718615| PASSED
    diehard_craps| 0| 200000| 100|0.85542623| PASSED
    # The file file_input_raw was rewound 4 times
    marsaglia_tsang_gcd| 0| 10000000| 100|0.03013470| PASSED
    marsaglia_tsang_gcd| 0| 10000000| 100|0.00001468| WEAK
    # The file file_input_raw was rewound 4 times
    sts_monobit| 1| 100000| 100|0.00247346| WEAK
    # The file file_input_raw was rewound 4 times
    sts_runs| 2| 100000| 100|0.46540581| PASSED
    # The file file_input_raw was rewound 4 times
    sts_serial| 1| 100000| 100|0.04689626| PASSED
    sts_serial| 2| 100000| 100|0.77705147| PASSED
    sts_serial| 3| 100000| 100|0.91930075| PASSED
    sts_serial| 3| 100000| 100|0.29061789| PASSED
    sts_serial| 4| 100000| 100|0.98861182| PASSED
    sts_serial| 4| 100000| 100|0.99672759| WEAK
    sts_serial| 5| 100000| 100|0.92879820| PASSED
    sts_serial| 5| 100000| 100|0.29198638| PASSED
    sts_serial| 6| 100000| 100|0.05925901| PASSED
    sts_serial| 6| 100000| 100|0.12537048| PASSED
    sts_serial| 7| 100000| 100|0.23159627| PASSED
    sts_serial| 7| 100000| 100|0.88723762| PASSED
    sts_serial| 8| 100000| 100|0.00035843| WEAK
    sts_serial| 8| 100000| 100|0.00015060| WEAK
    sts_serial| 9| 100000| 100|0.04351237| PASSED
    sts_serial| 9| 100000| 100|0.41980074| PASSED
    sts_serial| 10| 100000| 100|0.34094269| PASSED
    sts_serial| 10| 100000| 100|0.93567344| PASSED
    sts_serial| 11| 100000| 100|0.62333284| PASSED
    sts_serial| 11| 100000| 100|0.58367507| PASSED
    sts_serial| 12| 100000| 100|0.08716572| PASSED
    sts_serial| 12| 100000| 100|0.06673086| PASSED
    sts_serial| 13| 100000| 100|0.01587018| PASSED
    sts_serial| 13| 100000| 100|0.05907081| PASSED
    sts_serial| 14| 100000| 100|0.20643464| PASSED
    sts_serial| 14| 100000| 100|0.79744968| PASSED
    sts_serial| 15| 100000| 100|0.63358933| PASSED
    sts_serial| 15| 100000| 100|0.83478940| PASSED
    sts_serial| 16| 100000| 100|0.68294766| PASSED
    sts_serial| 16| 100000| 100|0.91380580| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 1| 100000| 100|0.10604077| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 2| 100000| 100|0.47250848| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 3| 100000| 100|0.24608314| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 4| 100000| 100|0.44634971| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 5| 100000| 100|0.97510248| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 6| 100000| 100|0.78720870| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 7| 100000| 100|0.85836560| PASSED
    # The file file_input_raw was rewound 4 times
    rgb_bitdist| 8| 100000| 100|0.00159130| WEAK
    # The file file_input_raw was rewound 5 times
    rgb_bitdist| 9| 100000| 100|0.66890621| PASSED
    # The file file_input_raw was rewound 5 times
    rgb_bitdist| 10| 100000| 100|0.91913344| PASSED
    # The file file_input_raw was rewound 5 times
    rgb_bitdist| 11| 100000| 100|0.69292456| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_bitdist| 12| 100000| 100|0.48899791| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_minimum_distance| 2| 10000| 1000|0.39013516| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_minimum_distance| 3| 10000| 1000|0.82809292| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_minimum_distance| 4| 10000| 1000|0.55682616| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_minimum_distance| 5| 10000| 1000|0.17018312| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_permutations| 2| 100000| 100|0.94793954| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_permutations| 3| 100000| 100|0.02890277| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_permutations| 4| 100000| 100|0.41275274| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_permutations| 5| 100000| 100|0.97883857| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_lagged_sum| 0| 1000000| 100|0.22201166| PASSED
    # The file file_input_raw was rewound 6 times
    rgb_lagged_sum| 1| 1000000| 100|0.32467689| PASSED
    # The file file_input_raw was rewound 7 times
    rgb_lagged_sum| 2| 1000000| 100|0.02610942| PASSED
    # The file file_input_raw was rewound 7 times
    rgb_lagged_sum| 3| 1000000| 100|0.00979909| PASSED
    # The file file_input_raw was rewound 8 times
    rgb_lagged_sum| 4| 1000000| 100|0.15666654| PASSED
    # The file file_input_raw was rewound 8 times
    rgb_lagged_sum| 5| 1000000| 100|0.26592420| PASSED
    # The file file_input_raw was rewound 9 times
    rgb_lagged_sum| 6| 1000000| 100|0.02476300| PASSED
    # The file file_input_raw was rewound 10 times
    rgb_lagged_sum| 7| 1000000| 100|0.16198799| PASSED
    # The file file_input_raw was rewound 11 times
    rgb_lagged_sum| 8| 1000000| 100|0.01653963| PASSED
    # The file file_input_raw was rewound 13 times
    rgb_lagged_sum| 9| 1000000| 100|0.11422321| PASSED
    # The file file_input_raw was rewound 14 times
    rgb_lagged_sum| 10| 1000000| 100|0.00758701| PASSED
    # The file file_input_raw was rewound 16 times
    rgb_lagged_sum| 11| 1000000| 100|0.75977813| PASSED
    # The file file_input_raw was rewound 17 times
    rgb_lagged_sum| 12| 1000000| 100|0.02891375| PASSED
    # The file file_input_raw was rewound 19 times
    rgb_lagged_sum| 13| 1000000| 100|0.00852932| PASSED
    # The file file_input_raw was rewound 21 times
    rgb_lagged_sum| 14| 1000000| 100|0.00955642| PASSED
    # The file file_input_raw was rewound 23 times
    rgb_lagged_sum| 15| 1000000| 100|0.05910791| PASSED
    # The file file_input_raw was rewound 25 times
    rgb_lagged_sum| 16| 1000000| 100|0.12966678| PASSED
    # The file file_input_raw was rewound 27 times
    rgb_lagged_sum| 17| 1000000| 100|0.04014969| PASSED
    # The file file_input_raw was rewound 29 times
    rgb_lagged_sum| 18| 1000000| 100|0.84879048| PASSED
    # The file file_input_raw was rewound 32 times
    rgb_lagged_sum| 19| 1000000| 100|0.04194055| PASSED
    # The file file_input_raw was rewound 35 times
    rgb_lagged_sum| 20| 1000000| 100|0.06119578| PASSED
    # The file file_input_raw was rewound 37 times
    rgb_lagged_sum| 21| 1000000| 100|0.00005935| WEAK
    # The file file_input_raw was rewound 40 times
    rgb_lagged_sum| 22| 1000000| 100|0.47702160| PASSED
    # The file file_input_raw was rewound 43 times
    rgb_lagged_sum| 23| 1000000| 100|0.18157846| PASSED
    # The file file_input_raw was rewound 46 times
    rgb_lagged_sum| 24| 1000000| 100|0.00356869| WEAK
    # The file file_input_raw was rewound 49 times
    rgb_lagged_sum| 25| 1000000| 100|0.00404224| WEAK
    # The file file_input_raw was rewound 53 times
    rgb_lagged_sum| 26| 1000000| 100|0.12990486| PASSED
    # The file file_input_raw was rewound 56 times
    rgb_lagged_sum| 27| 1000000| 100|0.10030167| PASSED
    # The file file_input_raw was rewound 60 times
    rgb_lagged_sum| 28| 1000000| 100|0.16296284| PASSED
    # The file file_input_raw was rewound 64 times
    rgb_lagged_sum| 29| 1000000| 100|0.95314868| PASSED
    # The file file_input_raw was rewound 67 times
    rgb_lagged_sum| 30| 1000000| 100|0.02757200| PASSED
    # The file file_input_raw was rewound 71 times
    rgb_lagged_sum| 31| 1000000| 100|0.01946262| PASSED
    # The file file_input_raw was rewound 76 times
    rgb_lagged_sum| 32| 1000000| 100|0.17015364| PASSED
    # The file file_input_raw was rewound 76 times
    rgb_kstest_test| 0| 10000| 1000|0.72486592| PASSED
    # The file file_input_raw was rewound 76 times
    dab_bytedistrib| 0| 51200000| 1|0.00000000| FAILED
    # The file file_input_raw was rewound 76 times
    dab_dct| 256| 50000| 1|0.53170434| PASSED
    Preparing to run test 207. ntuple = 0
    # The file file_input_raw was rewound 76 times
    dab_filltree| 32| 15000000| 1|0.20076652| PASSED
    dab_filltree| 32| 15000000| 1|0.10899010| PASSED
    Preparing to run test 208. ntuple = 0
    # The file file_input_raw was rewound 76 times
    dab_filltree2| 0| 5000000| 1|0.22646731| PASSED
    dab_filltree2| 1| 5000000| 1|0.21476108| PASSED
    Preparing to run test 209. ntuple = 0
    # The file file_input_raw was rewound 76 times
    dab_monobit2| 12| 65000000| 1|0.99999985| FAILED

  30. Isn’t that more a twig up OpenBSD’s butt than any of my problem? Also, a paper in Comic Sans I’m supposed to take seriously…?

  31. Hello

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

    Is there a qualitative difference between the random number generator of the Raspberry PI and the TrueRNG V3?
    Princeton uses the TrueRNG V3 for psychophysical experiments (e.g. “Global Consciousness Project”).
    Is there a reason for that?

    For scientific micropsychokinesis experiments such as those carried out by PEAR at Princeton University and occasionally at universities (currently e.g. at LMU Munich), you need simple software for a true random number generator.
    Unfortunately such software does not seem to exist.

    No dice or coin toss, but measurement of the 50/50 distribution over a certain period of time.

    E.g. so:

    000526.|.000523
    50.15%..|..49.85%
    0:29……|……. 3:00

    Is there such software?

Leave a comment

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