The solution would be to have multiple independent entropy pools and either bind them to cores(/sets of cores) or pick a non-busy one in a contention case.
If urandom is really "one for all cores" somebody should be able to demonstrate the speed drop by just writing some bash script? Volunteers?
$ time dd if=/dev/urandom of=/dev/null bs=1 count=10000000
real 0m10.640s
user 0m0.696s
sys 0m9.940s
$ time (for i in $(seq 1 50); do dd if=/dev/urandom of=/dev/null bs=1 count=200000 2>/dev/null & done; wait)
real 0m11.199s
user 0m1.232s
sys 0m42.828s
$ time (for i in $(seq 1 500); do dd if=/dev/urandom of=/dev/null bs=1 count=20000 2>/dev/null & done; wait)
real 0m11.234s
user 0m1.252s
sys 0m42.536s
whereas for /dev/zero: $ time dd if=/dev/zero of=/dev/null bs=1 count=10000000
real 0m3.268s
user 0m0.660s
sys 0m2.604s
$ time (for i in $(seq 1 50); do dd if=/dev/zero of=/dev/null bs=1 count=200000 2>/dev/null & done; wait)
real 0m2.550s
user 0m1.192s
sys 0m8.760s
$ time (for i in $(seq 1 500); do dd if=/dev/zero of=/dev/null bs=1 count=20000 2>/dev/null & done; wait)
real 0m2.612s
user 0m1.228s
sys 0m8.112s
Of course, the bash for-loop here together with the forking has some considerable overhead, so these values should likely be interpreted carefully (Linux 3.14-rc7, Core i5 520M).>This patch solves a problem where simultaneous reads to /dev/urandom can cause two processes on different processors to get the same value. We're not using a spinlock around the random generation loop because this will be a huge hit to preempt latency. So instead we just use a mutex around random_read and urandom_read. Yeah, it's not as efficient in the case of contention, if an application is calling /dev/urandom a huge amount, it's there's something really misdesigned with it, and we don't want to optimize for stupid applications.
2 - You don't need the crypto qualities of it and you're emptying the entropy pool for nothing
3 - You're doing much more work, especially if you're reading one byte at a time from /dev/urandom (doing a syscall, etc), while rand is just a calculation
For 2, entropy pool depletion is a fictitious problem if you're worried about security. Some discussion here:
https://news.ycombinator.com/item?id=7361694
If you're worried about blocking apps that use /dev/random, the answer there is to fix them to use /dev/urandom so they don't block.
In the current security environment, from heartbleed to the NSA, it's becoming clear that security issues need to be systematically dealt with from an industry perspective or people will start to lose faith in secure Internet communication, which would undermine too much of what's valuable about the Internet.
What we need is great APIs/frameworks/design patterns to simplify cryptography so that a newbie ruby on rails programmer CAN create actually secure applications and not even realize that it was complicated in the first place.
In cryptography you make one misstep and the entire chain is broken. It's thus important for things like the linux kernel to provide great implementations so that people don't think twice about using it and never want their own PRNG.
There's no reason for the kernel to provide standard library functions. In fact, I'd argue that syscalls should be reserved for only actions that cannot be done wholly in userspace (futex is a good example of this). The current model of "hardware randomness to seed a PRNG" makes sense. It is up to the userspace libraries to provide good implementations.
Similarly there's a need for great "APIs/frameworks/design patterns" for what the kernel doesn't provide. I predict over the next 5 years this will become a far bigger priority in how people develop software and thus use libraries.
It seems the author admits in the comments: "All the application needs to do is open a socket and generate a GET request." So why complaining about the kernel?
If there's problem with urandom, demonstrate it on the reasonable use case example, don't try to impress anybody by showing how much different libraries, modules and programs you combine for one key-value query.
We have the abillity to make the /dev/urandom CSPRNG secure enough and fast enough for (almost) any randomness purpose. We need to cut all the rest of this insane crap.
People choose the wrong RNGs and get burned, or wont use the right ones because of speed or imaginary entropy exhaustion issues. This matters.
The guy uses PHP and instead of built-in HTTPRequest he uses curl to make a request to "a bucketed key-value store built on PostgreSQL that speaks HTTP which uses Clojure and the Compojure web framework to provide a REST interface over HTTP." A bit of shooting the flies with cannons on every side?
On another side, if it can be proved that urandom has serious problems in reasonable use cases it should be checked what can be changed and how.
> The guy uses PHP and instead of built-in HTTPRequest he uses curl to make a request
HTTPRequest is not built-in to PHP. It is a PECL extension that is usually installed separately from PHP.
Curl is more built-in to PHP - it's a PHP compile-time flag, and it is distributed with PHP source.
We're not nearly at the theoretical limit of what /dev/urandom can provide.
The problem comes with multiple processes competing for the lock.
One preson may have multiple processes reading from /dev/urandom.