Use SecureRandom.generateSeed() to generate ThreadLocalRandom's initialSeedUniquifier
Motivation: Previously, we used SecureRandom.nextLong() to generate the initialSeedUniquifier. This required more entrophy than necessary because it has to 1) generate the seed of SecureRandom first and then 2) generate a random long integer. Instead, we can use generateSeed() to skip the step (2) Modifications: Use generateSeed() instead of nextLong() Result: ThreadLocalRandom requires less amount of entrphy to start up
This commit is contained in:
parent
b5c97bcc82
commit
2215ed0a35
@ -82,12 +82,12 @@ public class ThreadLocalRandom extends Random {
|
|||||||
if (initialSeedUniquifier == 0) {
|
if (initialSeedUniquifier == 0) {
|
||||||
// Try to generate a real random number from /dev/random.
|
// Try to generate a real random number from /dev/random.
|
||||||
// Get from a different thread to avoid blocking indefinitely on a machine without much entrophy.
|
// Get from a different thread to avoid blocking indefinitely on a machine without much entrophy.
|
||||||
final BlockingQueue<Long> queue = new LinkedBlockingQueue<Long>();
|
final BlockingQueue<byte[]> queue = new LinkedBlockingQueue<byte[]>();
|
||||||
Thread generatorThread = new Thread("initialSeedUniquifierGenerator") {
|
Thread generatorThread = new Thread("initialSeedUniquifierGenerator") {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
SecureRandom random = new SecureRandom(); // Get the real random seed from /dev/random
|
SecureRandom random = new SecureRandom(); // Get the real random seed from /dev/random
|
||||||
queue.add(random.nextLong());
|
queue.add(random.generateSeed(8));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
generatorThread.start();
|
generatorThread.start();
|
||||||
@ -99,15 +99,23 @@ public class ThreadLocalRandom extends Random {
|
|||||||
long waitTime = deadLine - System.nanoTime();
|
long waitTime = deadLine - System.nanoTime();
|
||||||
if (waitTime <= 0) {
|
if (waitTime <= 0) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
"Failed to get the secure random number from SecureRandom within {} seconds. " +
|
"Failed to generate a seed from SecureRandom within {} seconds. " +
|
||||||
"Not enough entrophy?", timeoutSeconds);
|
"Not enough entrophy?", timeoutSeconds);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Long result = queue.poll(waitTime, TimeUnit.NANOSECONDS);
|
byte[] seed = queue.poll(waitTime, TimeUnit.NANOSECONDS);
|
||||||
if (result != null) {
|
if (seed != null) {
|
||||||
initialSeedUniquifier = result;
|
initialSeedUniquifier =
|
||||||
|
((long) seed[0] & 0xff) << 56 |
|
||||||
|
((long) seed[1] & 0xff) << 48 |
|
||||||
|
((long) seed[2] & 0xff) << 40 |
|
||||||
|
((long) seed[3] & 0xff) << 32 |
|
||||||
|
((long) seed[4] & 0xff) << 24 |
|
||||||
|
((long) seed[5] & 0xff) << 16 |
|
||||||
|
((long) seed[6] & 0xff) << 8 |
|
||||||
|
(long) seed[7] & 0xff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user