Secure Random Number Generation with a Quartz Crystal, Raspberry Pi and PHP
One thing I always remember from my radio communications badge training was how crystals (quartz specifically) have very unique properties that allow us to tweak the oscillation of their internal structure using electricity, light or pressure to produce a signature akin to a fingerprint.
This fingerprint, as most know was used to allow super heterodyne receivers / transceivers to talk to each other on a shared phone call and all you needed to join in on the conversation was the phone number which in this case is the unique frequency.
Systems that rely on pure randomness have been on the rise and as such have resulted in expensive SAAS systems offering themselves as a solution. But the tinkerer in me can’t help but think why ? Surely PRNG can’t be that hard to do yourself, can it ?
With pure software based PRNG systems they're only as good as their architect and their randomness cannot be defined or guaranteed without seeing the process from the company producing the numbers.
PRNG can be used in everything from encryption of data to cryptographic address generation in a secure way that's hardware based and completely verifiable.
So how do we build a system that allows us to do this ourselves ?
Raspberry Pi
By now we’ve all heard about these wonderful little machines they are a hobbyists dream ! This will be used as the base logic board and microcontroller for our quartz crystal oscillator.
Quartz Crystal Oscillator Circuit
The secret of this whole thing is the controlled oscillation of the quartz crystal. You can buy a neat little oscillator here. We will use GPIO to detect the frequency across the quartz oscillator using two pin inputs on the board.
Installation
Connect the oscillator to two of the pins on the GPIO of the raspberry pi you can do this by using a breadboard or a direct connection through wiring so long as the two pins reach the GPIO any method will do.
Setup the PI
Ensure the raspberry Pi has linux installed and use the following commands to install the required libraries for php GPIO.
git clone https://github.com/mkoppanen/php-gpio.git
cd php-gpio
phpize
./configure
make
sudo make install
The Script (PHP)
<?php
use PiPHP\GPIO\GPIO;
use PiPHP\GPIO\Pin\PinInterface;
// Set up the GPIO controller and the input pin for the crystal
$gpio = new GPIO();
$oscillatorPin = $gpio->getInputPin(1);
// Use a Random object to generate random numbers
$random = new Random();
$oscillatorPin->onChange(function() use ($random) {
// When the oscillator pin changes state, record the current time
if ($oscillatorPin->getValue() == GPIO::HIGH) {
$endTime = microtime(true);
// Calculate the frequency and use it to set the seed for the random number generator
$frequency = ($endTime - $startTime) / 2;
$random->setSeed($frequency);
$startTime = $endTime;
}
});
// Get a random number from the generator
$randomNumber = $random->nextInt();
echo "Random number: " . $randomNumber . "\n";
Run the Generator
php crystal-oscillator-random.php
Final Note
That's all you need to produce the basis for a fair hardware based PRNG using the frequency banding of a unique physical oscillator. The Raspberry Pi was just my board of choice you could use Arduino instead so long as you can interface with the IO.
This is by no means a full real world example this is just a tutorial to give you the starting point of understanding implementing a hardware based PRNG at home !