The concept I have here is to take bytes from a source that may not have the random characteristics needed for a pRNG and filtering those results using an XOR against a nonce hash to produce bytes that are suitable for pRNG purposes.
This is more an exercise fot fun, but listening to network traffic noise as the source of random data is what I want to do.
Network traffic noise is not generated by a seeded algorithm like a deterministic pRNG is. One thought I had is to create a fake bitcoin node that listens for transactions being broadcast on over port 8333. Maybe hash what comes in against a salted timestamp before sending it through the filter just in case someone is attempting to influence the generated data by controlling the network noise.
The PoC is written in PHP. It requires PHP 7 with libsodium.
The PoC script has two functions that create horrid random numbers and then
one that just uses random_bytes
which is a CSpRNG.
The point is to show that the filter cleans up the output of the horrid functions so that the end result is as good as the CSpRNG in randomness tests.
If the filter can clean up the horrid sources so the output is as good as the CSpRNG source in tests and also does not reduce the quality of the output of the CSpRNG then the filter probably works and is suitable for cleaning up network noise as a source of data even if an attacker controls the noise.
The PHP script generates six very large files:
- shitRandom.bin
- weakRandom.bin
- goodRandom.bin
- shitRandomFiltered.bin
- weakRandomFiltered.bin
- goodRandomFiltered.bin
The tests are in the file test.sh
and the results are in the various
report.txt files. Summary below.
+----- rngtest from rng-tool-5.11.el7.x86_64 -----+
| |
| Source Data Failures Successes |
+-------------------------------------------------+
| shitRandom.bin 50000 0 |
| weakRandom.bin 49976 24 |
| goodRandom.bin 38 49962 |
+-------------------------------------------------+
| shitRandomFiltered.bin 34 49966 |
| weakRandomFiltered.bin 50 49950 |
| goodRandomFiltered.bin 41 49959 |
+-------------------------------------------------+
+--- dieharder from dieharder-3.31.1-9.el7.x86_64 --+
| |
| Source Data FAILED WEAK PASSED |
+---------------------------------------------------+
| shitRandom.bin 85 11 18 |
| weakRandom.bin 114 0 0 |
| goodRandom.bin 0 6 108 |
+---------------------------------------------------+
| shitRandomFiltered.bin 0 6 108 |
| weakRandomFiltered.bin 0 4 110 |
| goodRandpmFiltered.bin 0 2 112 |
+---------------------------------------------------+
As you can see, at least with the rngtest
and dieharder
test suites, the
results of passing the very poor data through the filter is not distinguishable
for the results of a quality CSpRNG. Also passing the quality data through the
filter did not produce results that show a deterioration in quality of the
pseudo-Random data.
It is thus my opinion that the filter method works and could be used to take network noise and turn it into data with random characteristics suitable for adding it to the operating system entropy pool.
I have to write that part still. This PHP is just proof of concept.
In the PHP when the filter function is called, it uses 16 bytes for the nonce and starts with an empty salt.
I think when I write this a daemon that listens to network noise, it will take 16 bytes of blocking data from /dev/random but take 48 bytes of non-blocking data from /dev/urandom for the initial salt.