Computers are deterministic by nature. This may sound untrue if you live in the applications’ realm – don’t we nickname threading as the Heisenberg’s uncertainty principle after all? But you should have no doubt, from power up to the moment you are reading these lines, everything was deterministic in your computer. So, how can you inject randomness? Indeed, you may know – or have noticed – that computers are not good at generating random numbers. Sometimes, this is a blessing. For example, and paradoxically, when you design a program with a random component. Because of their shortcomings, at each run, you may obtain the very same sequence of random numbers. This is great for validation. By the way, we conveniently name them pseudo-random numbers (generators). But, once your code is working as expected, the problem is that you still have your pseudo-random numbers at hand. It is true that you can use some randomness to seed the generator to get the illusion of true randomness (usually the current time), but it is still an illusion. So how do we achieve true randomness? Well, we need a source of entropy. If you are not versed in physics, consider entropy as a disorder or the phenomenon that, with the help of time, kills us all in fine.
Where to Find Entropy
Entropy comes from a truly random physical phenomenon, such as heat or radioactive decay. But all sources of entropy are not equal. In particular, assuming they have the same randomness, the speed at which the phenomenon allows the generation of random numbers must be considered. Indeed, often, the circuitry generating the random numbers needs to see enough of the phenomenon before spitting out a value. Think about it as a blocking read (assuming your entropy pools are empty). Few CPUs have dedicated instructions with the backing entropy source of course to generate random numbers. Intel introduced the RDRAND and RDSEED instructions (~3 Gbit/s – check bit 30 of the ECX using CPUID). If your compiler supports intrinsics to use them (rdrand_64 or rdseed_64 – these are just a few forms of the instruction), then you are all set. Otherwise, you will need to emit these opcodes (0x0F 0xC7 for RDRAND) in assembler, either in-lining in 32-bits or via an assembler for 64-bits. This also means that your code may not always have access to these instructions. In which case, you can buy additional hardware to connect to your computer. I use a TrueRNGpro by ubld.it which has an output speed of ~3 Mbit/s (~ 2.3 x 3.5 x 0.5 inches, ~100 mA) and costs less than $100. This device uses two noise generators relying upon the avalanche breakdown effect of reverse-biased diodes. Other options are more costly, such as the Quantis random number PCI or USB generators by IDQ. If you want some detail on the avalanche breakdown effect, you can watch this video on EEVblog: https://youtu.be/O0ifJ4oVdG4.