Software random number generators are usually so-called pseudo-random number
generators, because they produce a deterministic sequence of numbers that have
some of the properties of true random numbers. Obtaining genuinly random
numbers howerver requires a non-deterministic processus as the source of
randomness. Thermal noise in electronics or radioactive decay have been used,
usually requiring an external device to be built and plugged to the computer.
Peter Knight's TrueRandom
generates random bits by using the Arduino's ADC (with nothing connected to
the analog input pin) to measure electronic noise. It flips the pin's
internal pull-up resistor while the measure takes place to increase the amount
of noise. The software then keeps only the least significant bit of the
result, filters it using Von Neumann's whitening algorithm (read pairs of bits
until they are of different values and return 0 (respectively 1) on a 01
(respectively 10) transition). There are several functions that generate
different types of numbers based on those random bits.
I reused that code, modified it to allow using another pin than the Arduino's
Analog0 and I made my own random number generator. I also wrote a Python script
that reads the bits from the serial port, uses the SHA-1 hashing algorithm to
distil the data (the raw data has about 6 bit of entropy per byte, distillation
produces data with 7.999 bits of entropy per byte; based on the work of Jeff
Connelly on IMOTP) and writes them to the
standard output or into a file. On my Duemilanove, it can output about 1500
bits/s, while it outputs 1300 bits/s on a JeeLink.
The latter makes it an easy-to-transport device that is reasonnably sturdy and
fits in the pocket, even if its features (it contains a radio transceiver) are
a bit overkill for the job (not to mention expensive).
I also adapted the core of the TrueRandom software to run on my
ButtonBox (which
is conveniently always connected to my desktop computer). There the
output rate is a mere 300 bps, but it's still reasonnably fast for generating
a few random numbers when needed (for example for generating one's own
PasswordCard).
The access to the ButtonBox is shared among multiple clients using
button_box_server.py,
so a modified Python script was used for obtaining the stream of random bits
through the button_box_server
.
I haven't had the patience to generate a few megabytes of random data to test
the generator with the DieHarder
test suite, but the output of Fourmilab's ent
test tool looks reasonnable.