@Override public int acceptEntropy(EntropySource source, long data, int entropyGuess) { return acceptEntropy(source, data, entropyGuess, 1.0); }
@Override public int acceptTimerEntropy(EntropySource timer) { return acceptTimerEntropy(timer, 1.0); }
private int acceptEntropy( EntropySource source, long data, int entropyGuess, double bias) { return accept_entropy( data, source, (int) (bias * Math.min( 32, Math.min(estimateEntropy(source, data), entropyGuess)))); }
private void generateOutput() { counterInc(); output_buffer = new byte[counter.length]; cipher_ctx.encipher(counter, output_buffer); if(output_count++ > Pg) { output_count = 0; nextBytes(tmp); rekey(tmp); } }
private void entropy_init(File seed, boolean reseedOnStartup) { if(reseedOnStartup) { Properties sys = System.getProperties(); EntropySource startupEntropy = new EntropySource(); // Consume the system properties list for(Enumeration<?> enu = sys.propertyNames(); enu.hasMoreElements();) { String key = (String) enu.nextElement(); consumeString(key); consumeString(sys.getProperty(key)); } // Consume the local IP address try { consumeString(InetAddress.getLocalHost().toString()); } catch(Exception e) { // Ignore } readStartupEntropy(startupEntropy); } read_seed(seed); }
Yarrow r = new Yarrow(new File("/dev/urandom"), "SHA1", "Rijndael", true, false); long start = System.currentTimeMillis(); for(int i = 0; i < 100; i++) r.nextBytes(b); System.out.println( (double) (System.currentTimeMillis() - start) / (100 * b.length) * 1024 + " ms/k"); start = System.currentTimeMillis(); for(int i = 0; i < 1000; i++) r.nextInt(); System.out.println( (double) (System.currentTimeMillis() - start) / 1000 + " ms/int"); start = System.currentTimeMillis(); for(int i = 0; i < 1000; i++) r.nextLong(); System.out.println( (double) (System.currentTimeMillis() - start) / 1000 + " ms/long"); int kb = Integer.parseInt(args[1]); for(int i = 0; i < kb; i++) { r.nextBytes(b); System.out.write(b); long start = System.currentTimeMillis(); for(int i = 0; i < 100000; i++) r.acceptEntropy(t, System.currentTimeMillis(), 32); System.err.println( (double) (System.currentTimeMillis() - start) / 100000);
accumulator_init(digest); reseed_init(digest); generator_init(cipher); } catch(NoSuchAlgorithmException e) { Logger.error(this, "Could not init pools trying to getInstance(" + digest + "): " + e, e); seedfile = null; if(reseedOnStartup) { entropy_init(seed, reseedOnStartup); seedFromExternalStuff(canBlock); fast_pool_reseed(); slow_pool_reseed(); } else { read_seed(seed);
public void testDouble() { Yarrow y = new Yarrow(SEED_FILE, "SHA1", "Rijndael", false, false, false); ScalarSampleStatistics sample = new ScalarSampleStatistics(); for(int i = 0; i < 10000; ++i) { sample.add(y.nextDouble()); } assertEquals(0.5, sample.getMean(), 0.02); assertEquals(1.0 / (2.0 * Math.sqrt(3.0)), sample.getStandardDeviation(), 0.002); }
public void testNextBoolean() { Yarrow y = new Yarrow(SEED_FILE, "SHA1", "Rijndael", false, false, false); int[] results = new int[2]; int RUNS = 1000000; for(int i=0; i<RUNS; i++) { if(y.nextBoolean()) results[0]++; else results[1]++; } assertEquals(RUNS, results[0]+results[1]); assertTrue(results[0] > RUNS/2 - RUNS/1000); assertTrue(results[1] > RUNS/2 - RUNS/1000); } }
RandomSource random = randomSource != null ? randomSource : new Yarrow();
/** * Seed handling */ private void read_seed(File filename) { FileInputStream fis = null; BufferedInputStream bis = null; DataInputStream dis = null; try { fis = new FileInputStream(filename); bis = new BufferedInputStream(fis); dis = new DataInputStream(bis); EntropySource seedFile = new EntropySource(); for(int i = 0; i < 32; i++) acceptEntropy(seedFile, dis.readLong(), 64); dis.close(); } catch(EOFException f) { // Okay. } catch(IOException e) { Logger.error(this, "IOE trying to read the seedfile from disk : " + e.getMessage()); } finally { Closer.close(dis); Closer.close(bis); Closer.close(fis); } fast_pool_reseed(); } private long timeLastWroteSeed = -1;
dis = new DataInputStream(fis); dis.readFully(buf); consumeBytes(buf); dis.readFully(buf); consumeBytes(buf); dis.close(); } catch(Throwable t) { dis = new DataInputStream(fis); dis.readFully(buf); consumeBytes(buf); dis.readFully(buf); consumeBytes(buf); } catch(Throwable t) { Logger.normal(this, "Can't read /dev/urandom: " + t, t); dis = new DataInputStream(fis); dis.readFully(buf); consumeBytes(buf); dis.readFully(buf); consumeBytes(buf); } catch(Throwable t) { Logger.normal(this, "Can't read /dev/random: " + t, t); consumeBytes(buf); buf = sr.generateSeed(32); consumeBytes(buf); consumeString(Long.toHexString(Runtime.getRuntime().freeMemory()));
private void consumeString(String str) { byte[] b; try { b = str.getBytes("UTF-8"); } catch(UnsupportedEncodingException e) { throw new Error("Impossible: JVM doesn't support UTF-8: " + e, e); } consumeBytes(b); }
entropyGatheringThread.start(); this.random = new Yarrow(seed);
@Override public int acceptTimerEntropy(EntropySource timer, double bias) { long now = System.currentTimeMillis(); return acceptEntropy(timer, now - timer.lastVal, 32, bias); }
protected void readStartupEntropy(EntropySource startupEntropy) { // Consume the current time acceptEntropy(startupEntropy, System.currentTimeMillis(), 0); acceptEntropy(startupEntropy, System.nanoTime(), 0); // Free memory acceptEntropy(startupEntropy, Runtime.getRuntime().freeMemory(), 0); // Total memory acceptEntropy(startupEntropy, Runtime.getRuntime().totalMemory(), 0); }
@Override public int acceptEntropyBytes(EntropySource source, byte[] buf, int offset, int length, double bias) { int totalRealEntropy = 0; for(int i = 0; i < length; i += 8) { long thingy = 0; int bytes = 0; for(int j = 0; j < Math.min(length, i + 8); j++) { thingy = (thingy << 8) + (buf[j] & 0xFF); bytes++; } totalRealEntropy += acceptEntropy(source, thingy, bytes * 8, bias); } return totalRealEntropy; }