Sorry for my delay in responding. I'm fairly satisfied on this topic, but I'm going to give my final "conclusions" and "findings" for the sake of posterity.
First, there is a simple test to see if bitcoin-qt and openssl are using /dev/urandom or not on a particular machine with pretty high certainty:
strace -o output bitcoin-qt
On my system (and probably on practically all modern linux desktops), you will find a read of /dev/urandom in that trace, meaning yes, /dev/urandom is being used.
Interestingly enough, man 4 random has some warnings about NOT using /dev/urandom for certain OTHER (non-bitcoin) cryptographic purposes (obviously, the man page predates bitcoin)...
A read from the /dev/urandom device will not block waiting for more
entropy. As a result, if there is not sufficient entropy in the
entropy pool, the returned values are theoretically vulnerable to a
cryptographic attack on the algorithms used by the driver. Knowledge
of how to do this is not available in the current unclassified lit‐
erature, but it is theoretically possible that such an attack may exist.
If this is a concern in your application, use /dev/random instead.
Also:
If you are unsure about whether you should use /dev/random or /dev/urandom,
then probably you want to use the latter. As a general rule, /dev/urandom
should be used for everything except long-lived GPG/SSL/SSH keys.
I checked out gnupg for the sake of comparison, and it's using /dev/random, which is in accordance with the above advice.
So, from someone who knows enough about cryptography to know that I don't know anything about cryptography , all this is troubling.However, gmaxwell has
repeatedly (on multiple occasions) assured me on IRC that he knows enough about cryptography to know that it's just not something we should be worried about. Even after I specifically brought up the above warnings. For example:
(12:10:30 AM) gmaxwell: Under certain threat models, like the attacker being on
a common multiuser system with you and being able to monitor 99.9% of the
urandom output, then it's potentially interesting.
It would be nice (though probably suboptimal for other reasons) if bitcoin and openssl had opted to take the route that would be
obviously safe to people who are not crypto experts, allowing us to avoid this whole conversation altogether, and allowing people like me to not have to think about how much we "trust" the bitcoin and openssl devs on this. Of course, I
do trust those people, but I also lock my doors at night, even though I trust that I live in a safe enough place to not need to.
That's not actually a request or complaint; actually relying on /dev/random would (a) almost certainly be an issue to bring up with openssl, not the bitcoin devs; and (b) would have other major downsides.
Anyway, moving on to more practical matters,
here is something (below) that other paranoid people like me can actually do about the situation. (Note that simply simlinking /dev/urandom to /dev/random just caused errors for me, and the post-compile checks for openssl failed for me when I tried to change the openssl code
)
I found on my desktop machine, my entropy is often in the low hundreds, which by all accounts is abnormal. I don't know why - perhaps part of it is that I use a very simply window manager, don't have a lot of stuff running, and hardly ever use the mouse. Probably nothing to be worried about, but it's clearly abnormal, so I was a bit worried.
However, when I went to actually generate my offline wallets, I
did use the mouse a lot (plus I was using a different distro than normal), and there was
plenty of entropy. How do I know? I wrote a program that checks the entropy in a loop and exits with a complaint if it falls below a user-provided threshhold. The program is provided below for anyone who wants it.
#include
#include
#include
#define DEFAULT_THRESH 2000
int get_thresh(int argc, char** argv) {
int thresh = DEFAULT_THRESH;
if (argc == 2) {
thresh = atoi(argv[1]);
}
return thresh;
}
int get_ent() {
int fd = open("/proc/sys/kernel/random/entropy_avail",O_RDONLY);
char *buf = malloc(4);
read(fd, buf, 4);
close(fd);
int num = atoi(buf);
free(buf);
return num;
}
int main(int argc, char** argv) {
int thresh = get_thresh(argc, argv);
int last = get_ent();
int new = 0;
while(1) {
new = get_ent();
if (new != last) {
printf("%d\n", new);
if (new < thresh) {
printf("INSUFFICIENT ENTROPY\n");
exit(1);
}
}
last = new;
}
return 0;
}