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