Neat. While there are a bunch of Geiger counter RNG kits you can get, I appreciate the author's thoroughness.
I will say, one thing that's unclear to me from the write up(s), is how the author implemented the logic for deciding an individual bit value. The typical way folks do this (with a geiger counter), is to measure three events per bit (although you could potentially optimize this in a sequence). With 3 events, you then have two durations, the time between events 0 and 1, and events 1 and 2. Based on which duration is longer decides the value of the bit.
The numbers are generated directly from the current timer/counter value at the moment of the event. I'm not at all measuring time BETWEEN events. It's just a counter that overflows ~300 times per second (20MHz clock in a 16 bit counter), while the radioactive events happen every ~1-3 seconds. This ensures that the numbers are uniformly distributed and uncorrelated.
I am actually throwing away some enthropy bits doing this, as there will be significant bits to the left that i'm discarding. A somewhat next step in the future could be the assesment of how many bits can the counter be, without impacting the quality of the output. Maybe i can get something like 20 bits per event.
IANA cryptographer. But it seems like this results in readings not being truly independent.
Also I feel like there might be some element of nonuniformity, akin to generating a number out of n possible values, and modding it by k, where n is not divisible by k. n and k being the timer period and event in this analogy.
That would be the case if i was resetting the counter at every read. Instead, it does not reset the counter, so it does not always start from 0. So the analogy would hold only for the very first number.
Using multiple events for a single bit seemed pretty inefficient to me when I built a random number generator based on radioactive decay [0].
I ended up toggling a bit every time an ADC was sampled. When an event was detected (rising edge triggered with hysteresis), the bit associated with the rising edge sample becomes the output random bit. I think this is acceptable as long as the ADC sampling rate is >> the expected event rate, but I haven't done the analysis to prove this to be the case. The result is one random bit per event (unless events pile up in which case only the first event counts).
[Edit] It looks like the author did the same thing per their comment!
Hi, I'm the author of this one ( I lost the other account password). I'm happy I found someone else doing this stuff to be able to talk about it. I discarded time related algorithms because I thought they could introduce sneaky bugs related to event dependencies. So, having had to work in the gamble industry, I opted for a simpler algorithm: roulette. I have a loop increasing a register from 0 to 15, when a particle is detected the value present in that registry is returned and it's used as an half of a 8 bits ( 1 byte ) random number and, after every extraction, the counter is restarted from zero. If anyone think the algorithm is unreliable, any suggestion to improve it's welcome.
It's pretty similar to mine, you could improve yours by relying on an hardware timer/counter that can go faster and thus provide more entropy.
Also you should not reset the counter at every event, this would lead to a poisson distribution if event ever became of comparable time scale to the timer
No he's a friend of mine, I also have my nuclear RNG based on different vintage counter. I think his project is older. I like your project too! This is him:
https://news.ycombinator.com/item?id=30252171
I will say, one thing that's unclear to me from the write up(s), is how the author implemented the logic for deciding an individual bit value. The typical way folks do this (with a geiger counter), is to measure three events per bit (although you could potentially optimize this in a sequence). With 3 events, you then have two durations, the time between events 0 and 1, and events 1 and 2. Based on which duration is longer decides the value of the bit.