Tools: Open Source How I Built A Random Number Generator (sort Of)

Tools: Open Source How I Built A Random Number Generator (sort Of)

TL;DR: I made an Hybrid Hardware Random Number Generator (HHRNG) using radio noise. You can find the full source code on my GitHub.

Generating randomness is fascinating, and I always wanted to go deeper than just importing some library into my python project and calling .random(). So I set out to build my own library with its own .random() function. Revolutionary, I know.

But I didn't want to just cobble together pseudo-random values. I wanted to build a hardware random number generator (HRNG): one that uses actual physical processes to generate entropy. Think Linux's /dev/random, which harvests entropy from environmental noise: keyboard timings, mouse movements, disk I/O patterns. Windows also have a component named CNG (Cryptography Next Generation) that uses similar inputs.

When I hear noise, the first thing that comes to mind is this:

For the uninitiated, this is an SDR (Software Defined Radio), a real-time visualization of the radio spectrum around me. Notice the constant flickering at the bottom? That's noise, pure and simple. Nothing is transmitting there, yet the intensity is constantly dancing. It's the same static you hear when tuning to an empty FM frequency. If we could capture and measure that movement, we'd have a source of true randomness, unpredictable and nearly impossible to manipulate.

So, based on that, I decided to get to work. Note that I will be using a SDR blog v4 to capture radio signals and compute them.

Here is a global overview of what I needed to do to get this project done:

So, first of all, I needed to find a way to programmatically access my radio data, served as samples. I'd tried this on Windows before with no luck, so this time I went straight to a template that connects over the network on an rtl_tcp server running on one of my Raspberry Pis.

Once everything setup, I was able to receive samples. The code is quite simple, it uses a socket to connect to the rtl_tcp server, and then reads samples from it. Here is a part of the read_samples function, that reads and processes the signals:

As we can see, it computes IQ samples. I and Q refer to two components of a complex baseband signal. They capture both amplitude and phase of the RF signal.

The next step is building the "randomizer". It is basically a function that will take, as an input, samples from our SDR, and output a seed we will base our calculations on later. To do this, I've tried a couple of ways (2, actually), but the most efficient method was using Ph

Source: Dev.to