# A Raspberry Pi-based Truly Random Number Generator

Contents

Random numbers are essential for all kinds of things, especially cryptography. Computers, however, can only produce pseudorandom numbers, which can be āguessedā by using sophisticated software. Truly random numbers are hard to come by. Luckily, with a few wires and a Ras Pi, one can create a lot of random numbers very quickly.

For this project you will need:
1x Raspberry Pi

And, for the optional LED output section:
1x LED
1x current-limiting resistor (for the LED)

## Step 1: Wiring

This is the easiest wiring project youāve ever done.
For the RNG inputs, connect breadboard wires to GPIO 4, 17, and 22. If thatās all you want, youāre done. skip to the coding.
For the LED output, connect a resistor and an LED in series (with the resistor on the positive pin of the LED), then connect the Piās ground to the ground rail on the breadboard. Connect the other end of the LED to ground and the other end of the resistor to GPIO 25.

## Step 2: Code

This code has 6 configurable parameters: Ā Length of the random numbers to output (in bits), the three input pins, the output pin, and the Time to Sleep (tts). A shorter TTS speeds up the generator but reduces entropy. TTS defaults to 0.01 seconds.

#!/usr/bin/env python
#Uses floating inputs on GPIO4, GPIO17, and GPIO22 to generate truly random numbers
#Outputs to GPIO 25 when a new number is done and sends the number to STDOUT

import RPi.GPIO as GPIO
import sys
from time import sleep

GPIO.setmode(GPIO.BCM)

def getRBit(pin1, pin2, pin3, tts):Ā Ā  #gets a random set of bits, XORs them, and outputs one random bit
bit1 = 0
bit2 = 0
bit3 = 0
bitv = 0
GPIO.setup(pin1, GPIO.IN)
GPIO.setup(pin2, GPIO.IN)
GPIO.setup(pin3, GPIO.IN)
sleep(tts) #Sleep so the CPU can mess around and change the EMF environment
bit1 = GPIO.input(pin1)
if bit1:
bit1 = 1
else:
bit1 = 0
sleep(tts) #Sleep so the CPU can mess around and change the EMF environment
bit2 = GPIO.input(pin2)
if bit2:
bit2 = 1
else:
bit2 = 0
sleep(tts) #Sleep so the CPU can mess around and change the EMF environment
bit3 = GPIO.input(pin3)
if bit3:
bit3 = 1
else:
bit3 = 0
#Now do some XOR logic
bitv = bit1 ^ bit2
out = bitv ^ bit3
return out

def getRInt(x, pin1, pin2, pin3, pin4, tts=0.01): #get an x-bit number by looping through a string a bunch. Pin4 is LEDout.
GPIO.setup(pin4, GPIO.OUT)
binstr = āā #Set up to be converted to binary
rint = 0
rbit = 0
i = 0
for i in range (0, x-1):
i += 1
rbit = getRBit(pin1, pin2, pin3, tts)
binstr = binstr + str(rbit)
#print(binstr)Ā Ā  # For debug purposes
rint = int(binstr, 2)
GPIO.output(pin4, True)
sleep(0.2)
GPIO.output(pin4, False)
return rint
while True:
print(getRInt(64, 4, 17, 22, 25, 0.01)) #bits, in1, in2, in3, out, tts

## Step 3: Uses and Notes

I suggest using this generator for encryption as the numbers that it generates are highly entropic and pretty much unguessable, barring a bruteforce attack. Using these numbers to seed, for example, the PHP PRNG is a great way to make its output unguessable.
A small note: it may take a VERY long time (~ several minutes) for the generator to make numbers with lots of bits (above 1k). Instead of doing that, I suggest seeding a pseudorandom generator with this truly random output. Itās still unguessable.