Hardware Random Number Generator with 18F2550

Posted By Cantareus on September 6, 2009

This is a hardware rng I made over the weekend. It uses my PSU based power supply for the 12v and -5v and USB for 5v.

It’s based on http://robseward.com/misc/RNG2/. The voltage is read using the ADC on a 18F2550 and the bits of the voltage are XORed together to create a single random bit. Von Neumann’s algorithm is used to remove bias which reduces the number of bits by 4 times, I’m not sure if this is necessary I’ll check it out tomorrow. The resulting bits are saved up in a buffer and then sent to the computer over usb. The digital to analog conversion really slows things down. I’m getting about 500 B/s. I might see if I can do it digitally.

Here are the results on 12MB of random data that took over 6 hours to generate.

Entropy (->8) Birthday Spacing Matrix Ranks 6×8 Matrix Ranks Minimum Distance Test Random Spheres Test The Sqeeze Test Overlapping Sums Test
7.999986 0.000527 0.665 0.535 0.945358 0.287282 0.802857 0.128108

http://www.cacert.at/cgi-bin/rngresults

I’m not sure why it came close to failing that one test. It’s listed as “Potentially deterministic”.

This is the schematic I used:

Schematic

Schematic

And the relevant part of the code:

if(currentbyte < 64)
{
  randompair = 0;

  if(currentbit == 0)
    USB_Out_Buffer[currentbyte] = 0;

  for(i = 0; i < 2; i++)
  {
    Delay10TCYx(10);
    ConvertADC();
    while( BusyADC() );
    randombit = ReadADC();

    for(j = 1; j < 10; j++)
      randombit ^= (randombit >> j) & 1;  //Messy, the assembly created to do this is too long.

    randompair <<= 1;
    randompair |= randombit & 1;
  }

  if(randompair == 2)
  {
    USB_Out_Buffer[currentbyte] |= 1 << currentbit;
    currentbit++;
  }
  else if(randompair == 1)
    currentbit++;

  if(currentbit == 8){
    currentbit = 0;
    currentbyte++;                    
  }
}

if(mUSBUSARTIsTxTrfReady() && currentbyte == 64)
{
  putUSBUSART(USB_Out_Buffer, 64);
  currentbyte = 0;
}

Comments

Leave a Reply