# userspace-random
userspace-random is a rust crate that is intended to provde secure entropy to
the caller even if the operating system entropy is not secure.
`userspace_rng::Csprng` implements `rand_core::CryptoRng` and
`rand_core::RngCore`.
Usage:
```rs
// Generate an ed25519 key.
let mut rng = userspace_rng::Csprng{};
let keypair = ed25519_dalek::Keypair::generate(&mut rng);
// Generate 32 bytes of randomness.
let rand_data = userspace_rng::random256();
```
Modern operating systems like Linux, Mac, and Windows will all provide reliable
entropy, however more niche operating systems and environments often will
provide broken RNGs to the user. This concern is especially relevant to IoT and
embedded hardware, where the engineers are deliberately taking as many
shortcuts as they can to trim down the size and overhead of the operating
system and hardware. The result may be an unintentionally compromised operating
system RNG which can put users at risk.
This worry has precedent. When Android was newer, a broken RNG in Android put
user funds at risk: https://bitcoin.org/en/alert/2013-08-11-android
To protect users against insecure hardware, we developed a library that
generates reliable entropy in userspace. We have constructed the library to
ensure that the randomness can only be compromised if both the operating system
RNG is broken and also the assumptions made by our library are incorrect. Had
the Android wallets used userspace-random to generate their entropy, user funds
likely would have been safe despite the flaw in Android itself.
This library draws entropy from CPU jitter. Specifically, the number of
nanoseconds required to complete a cryptographic hash function has a high
amount of variance. My own testing suggested that under normal circumstances
the variance is around 100ns with a standard deviation of around 40ns. This
suggests that using time elapsed during a cryptographic hashing function as a
source of entropy will provide between 4 and 6 bits of entropy per measurement.
When the library starts up, it performs 25 milliseconds of hashing, performing
a strict minimum of 512 hashing operations total. This theoretically provides
more than 2000 bits of entropy, which means there is a comfortable safety
margin provided by the library. Even hardware that is more stable and reliable
should be producing at least 1/4 bits of entropy per hash operation owing to
the natural physical limitations of CPUs.
To give some brief intuition: a CPU is a physical device that consumes
electricity and produces heat. The speed at which a CPU operates (at least,
with our current technology) is surprisingly dependent on factors like voltage
and temperature. Further, these factors tend to vary rapidly as a CPU performs
computations. Empirical measurements demonstrate that the variance is
sufficiently significant to cause material variance in the total execution time
of a cryptographic hash operation. Other factors such as background activity by
the operating system can also play a role.
For fun, this library also incorporates some ideas from the fortuna paper to
protect users against an adversary that has the ability to use side channels to
compromise the user entropy. In reality, these extra choices are probably not
necessary to protect against real-world attackers. Fortuna was designed with a
very different threat model in mind than the one we face with this library.
Fortuna paper: https://www.schneier.com/wp-content/uploads/2015/12/fortuna.pdf