True Random Number Generator

Hi everyone :slight_smile:

I'm new to the forum and need some help with a project I'm working on. What I'm trying to do is to get my arduino to produce true random numbers. Basically, I have a long wire attached to analog pin 0 and am reading the ADC values from it. If the ADC value is odd it returns a 1, if it is even it returns a 0. I tested this part by generating 199980 bits and found it to be almost (within a fraction of a percent) 50/50 chance. The next part of my program converts 8 bits at a time into a number in base 10 between 0 and 255. The problem i have is that i know that half of the time i get 1's and half the time I get 0's, but i do not know for sure if they favor certain combinations over others.

Any help would be appreciated and I can give a sample of the base 10 numbers I am getting if you need it :slight_smile:

I'm a little confused. If you know that out of 199980 bits there is an even distribution of 1's and 0's then why would certain combinations be favored over others? What do you mean by "favor certain combinations over others"?

I think you might be asking whether there is some structure to the random numbers (perhaps a sinusoidal oscillation, for example) that, despite the distribution of 1's and 0's being the same, does not truly lead to a random sequence of integers.

A good way to check is to perform a "spectral test" (Google it...but be prepared for some hard math). A gentle introduction is to plot a histogram of all your base-10 numbers. Ideally, the histogram is flat: there is the same number of each number.

--
The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, speaker, microphone, light sensor, potentiometer, pushbuttons

(certified) true randomness has its price ...

Check - http://www.idquantique.com/true-random-number-generator/quantis-oem.html -
datasheet - http://www.idquantique.com/images/stories/PDF/quantis-random-generator/quantis-oem-specs.pdf - (sounds Arduino compatible)
prices - http://www.idquantique.com/ordering/shop.html -

or - http://www.random.org/ - => http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1294239019#13

-- update --
A geiger counter can also be used for RNG, - Geiger Counter (Slightly Less Old-School) - SEN-09848 - SparkFun Electronics - measure the time between pulses and use the last bit(s)

RuggedCircuits:
I think you might be asking whether there is some structure to the random numbers (perhaps a sinusoidal oscillation, for example) that, despite the distribution of 1's and 0's being the same, does not truly lead to a random sequence of integers.

I had some thoughts a while back about what I could try for generating TRNGs, mostly running to something resembling an electrostatic tweeter, except reading from it. Obviously, the "element" would have to be something very low mass. I usually consult Schneier on questions such as this. Here's a remark [not from Bruce] in randomness from quantum noise that rings true to me (which isn't particularly meaningful, since I'm not a cryptographer -- but I do read about this stuff).

As people are finding out TRNG's are not as good as they appear on paper, and are extrodinarly sensitive to influance from the environment they operate in. And importantly it is not always easy to tell the TRNG has been influenced by an external entity via a modulated RF carrier etc.

As was shown a little while ago by a couple of bods over at the Cambridge Labs, an unmodulated RF carrier can take a TRNG from 32bits to 8bits equivalent.

Which I'll leave as an exercise for interested parties to look up.

A 'long wire' sounds to me like an AM radio antenna. As such, I'm not sure there's any way for it to be non-deterministic. One obvious crack an attacker could employ would be to set up another long wire and read the same local RF noise you are.

And, somewhat echoing others here, a 50/50 distribution of ones and zeros could be the repeating pattern '10101010', or 1001110011' or some other longer repeating pattern. Sure, seems unlikely from RF noise.

Is your project just for demonstration, or are you planning some important real-world application for it? I found interesting reading searching Bruce Schneier's blog for 'random number generator'.

Also, I'm reminded of LavaRND.

Thanks for you help RuggedCircuits!

I think you might be asking whether there is some structure to the random numbers (perhaps a sinusoidal oscillation, for example) that, despite the distribution of 1's and 0's being the same, does not truly lead to a random sequence of integers.

That is exactly what I meant and it seems that the histogram would be the easiest method to see if the number sequence is actually random. I'm looking in to making a program that can read the data from the arduino serially to plot the points for me as it would be the only way to quickly plot a large amount of points.

That is exactly what I meant and it seems that the histogram would be the easiest method to see if the number sequence is actually random

This...

uint8_t i;
i = 0;
while ( true )
{
  Serial.write( i );
  ++i;
}

...generates a perfectly balanced histogram. You will need to perform substantially more analysis than a histogram. This is a good place to start...

More information here...

i analyzed about 9000 of the numbers in a program and found that the distribution of the numbers seemed fairly consistent. However there are 32 numbers that never occur. The one thing that they have in common is that the 4th bit should be a 1. Any guesses as to why these numbers never occur?

In a list of 9000 8-bit numbers you'd expect each number to show up about 35 times if the bits were truly random. That 32 numbers occur 0 times strongly suggests the data is not random. I'm not sure what the 4th bit significance is other than to suggest that you are probably picking up some oscillation and it is happening to coincide with your sampling rate.

--
The Rugged Motor Driver: two H-bridges, more power than an L298, fully protected

Any guesses as to why these numbers never occur?

Maybe a bug in your code. Post your Sketch.

Maybe what @RuggedCircuits suggested. What do you have connected to AREF?

here is my sketch

int j = 0;
int randomInput = 0;
int ranInteger = 0;
int bitValue = 0;
int number = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly
if (number < 10001) // make 10000 random numbers
{
for (j = 0 ; j < 8 ; j++) // takes 8 bits
{
randomInput = analogRead(A0); // reads input from analog pin 0
randomInput = randomInput % 2; // determines if the number is odd or even.
// if it is even, then total = 0, if it is odd, total = 1
delay(50); // this is to experiment with the rate at which i collect the numbers
if (randomInput == 1) // if the bit is a 1
{
bitValue = pow(2,j); // take the base 10 value of the bit
ranInteger = ranInteger + bitValue; // adds up the values of the bits to make the base 10 number
}
if (j == 7) // after 8 bits have been collected, print the number
{
Serial.print(ranInteger);
Serial.print(",");
ranInteger =0;

}
}
number = number + 1; // counts how many numbers have been made
}
}

I haven't done much programming with the arduino so this may not be the most efficient code, but it seems to work :stuck_out_tongue:

There are three two flaws in your Sketch which prevent it from producing good results. Would like to be spoon-fed or would you prefer to try and find the flaws yourself?

I think I'll be spoon fed this time. I'm still learning to program my arduino and I think I'd benefit more from the mistakes being pointed out than trying to find them myself :stuck_out_tongue:

This...

    bitValue = pow(2,j); // take the base 10 value of the bit

...does not work the way you expect. This Sketch illustrates the problem...

int j = 0;
int bitValue = 0;

void setup( void )
{
  Serial.begin( 9600 );
}

void loop( void )
{
  Serial.println();
  Serial.println();
  Serial.println();
  
  for (j = 0 ; j < 8 ; j++)  // takes 8 bits
  {
      bitValue = pow(2,j); // take the base 10 value of the bit
      Serial.println( bitValue );
  }
  
  delay( 10000 );
}

The output is...
1 2 3 7 15 31 63 127

The desired output is...
1 2 4 8 16 32 64 128

Change that line of code to this...

    bitValue = 1 << j; // take the base 10 value of the bit

Adding bits is technically not correct...

      ranInteger = ranInteger + bitValue; // adds up the values of the bits to make the base 10 number

Change that line of code to use a bitwise-or...

      ranInteger = ranInteger | bitValue; // adds up the values of the bits to make the base 10 number

Wow thanks! I just made another set of 10000 numbers and when I analyzed them, the distribution seemed to be pretty even! I'll probably do some more tests on the numbers but for now everything seems to be working perfectly!

Thanks to everyone who helped!