blob: 6b2d5ec216a3e0ebee93e24c416ca9dc95cd214b [file] [log] [blame]
package org.bouncycastle.crypto.prng;
/**
* A thread based seed generator - one source of randomness.
* <p>
* Based on an idea from Marcus Lippert.
* </p>
*/
public class ThreadedSeedGenerator
{
private class SeedGenerator
implements Runnable
{
private volatile int counter = 0;
private volatile boolean stop = false;
public void run()
{
while (!this.stop)
{
this.counter++;
}
}
public byte[] generateSeed(
int numbytes,
boolean fast)
{
Thread t = new Thread(this);
byte[] result = new byte[numbytes];
this.counter = 0;
this.stop = false;
int last = 0;
int end;
t.start();
if(fast)
{
end = numbytes;
}
else
{
end = numbytes * 8;
}
for (int i = 0; i < end; i++)
{
while (this.counter == last)
{
try
{
Thread.sleep(1);
}
catch (InterruptedException e)
{
// ignore
}
}
last = this.counter;
if (fast)
{
result[i] = (byte) (last & 0xff);
}
else
{
int bytepos = i/8;
result[bytepos] = (byte) ((result[bytepos] << 1) | (last & 1));
}
}
stop = true;
return result;
}
}
/**
* Generate seed bytes. Set fast to false for best quality.
* <p>
* If fast is set to true, the code should be round about 8 times faster when
* generating a long sequence of random bytes. 20 bytes of random values using
* the fast mode take less than half a second on a Nokia e70. If fast is set to false,
* it takes round about 2500 ms.
* </p>
* @param numBytes the number of bytes to generate
* @param fast true if fast mode should be used
*/
public byte[] generateSeed(
int numBytes,
boolean fast)
{
SeedGenerator gen = new SeedGenerator();
return gen.generateSeed(numBytes, fast);
}
}