📄 csprng.java
字号:
else { hash.update(buf, i - hashSize, hashSize); } // Now the next 64 bytes. if (i + 64 < buf.length) { hash.update(buf, i, 64); } else { hash.update(buf, i, buf.length - i); hash.update(buf, 0, 64 - (buf.length - i)); } byte[] digest = hash.digest(); System.arraycopy(digest, 0, buf, i, hashSize); } } private void mixRandomPool() { mixRandomPool(pool); mixCount++; } private void generateX917(byte[] buf) { int off = 0; for (int i = 0; i < buf.length; i += X917_POOL_SIZE) { int copy = Math.min(buf.length - i, X917_POOL_SIZE); for (int j = 0; j < copy; j++) { x917pool[j] ^= pool[off + j]; } cipher.encryptBlock(x917pool, 0, x917pool, 0); System.arraycopy(x917pool, 0, buf, off, copy); cipher.encryptBlock(x917pool, 0, x917pool, 0); off += copy; x917count++; } } /** * Add random data always immediately available into the random pool, such * as the values of the eight asynchronous counters, the current time, the * current memory usage, the calling thread name, and the current stack * trace. * * <p>This method does not alter the quality counter, and is provided more * to maintain randomness, not to seriously improve the current random * state. */ private void fastPoll() { byte b = 0; for (int i = 0; i < SPINNER_COUNT; i++) b ^= SPINNERS[i].counter; addRandomByte(b); addRandomByte((byte) System.currentTimeMillis()); addRandomByte((byte) Runtime.getRuntime().freeMemory()); String s = Thread.currentThread().getName(); if (s != null) { byte[] buf = s.getBytes(); addRandomBytes(buf, 0, buf.length); } ByteArrayOutputStream bout = new ByteArrayOutputStream(1024); PrintStream pout = new PrintStream(bout); Throwable t = new Throwable(); t.printStackTrace(pout); pout.flush(); byte[] buf = bout.toByteArray(); addRandomBytes(buf, 0, buf.length); } private void slowPoll() throws LimitReachedException { if (DEBUG) { debug("poller is alive? " + (pollerThread == null ? false : pollerThread.isAlive())); } if (pollerThread == null || !pollerThread.isAlive()) { boolean interrupted = false; pollerThread = new Thread(poller); pollerThread.setDaemon(true); pollerThread.setPriority(Thread.NORM_PRIORITY - 1); pollerThread.start(); if (blocking) { try { pollerThread.join(); } catch (InterruptedException ie) { interrupted = true; } } // If the full slow poll has completed after we waited for it, // and there in insufficient randomness, throw an exception. if (!interrupted && blocking && quality < 100.0) { if (DEBUG) { debug("insufficient quality: " + quality); } throw new LimitReachedException( "insufficient randomness was polled"); } } } protected void finalize() throws Throwable { if (poller != null && pollerThread != null && pollerThread.isAlive()) { pollerThread.interrupt(); poller.stopUpdating(); pollerThread.interrupt(); } Arrays.fill(pool, (byte) 0); Arrays.fill(x917pool, (byte) 0); Arrays.fill(buffer, (byte) 0); } // Inner classes. // ------------------------------------------------------------------------- /** * A simple thread that constantly updates a byte counter. This class is * used in a group of lowest-priority threads and the values of their * counters (updated in competition with all other threads) is used as a * source of entropy bits. */ private static class Spinner implements Runnable { // Field. // ----------------------------------------------------------------------- private byte counter; // Constructor. // ----------------------------------------------------------------------- private Spinner() { } // Instance methods. // ----------------------------------------------------------------------- public void run() { while (true) { counter++; try { Thread.sleep(100); } catch (InterruptedException ie) { } } } } private final class Poller implements Runnable { // Fields. // ----------------------------------------------------------------------- private final List files; private final List urls; private final List progs; private final List other; private final CSPRNG pool; private boolean running; // Constructor. // ----------------------------------------------------------------------- Poller(List files, List urls, List progs, List other, CSPRNG pool) { super(); this.files = Collections.unmodifiableList(files); this.urls = Collections.unmodifiableList(urls); this.progs = Collections.unmodifiableList(progs); this.other = Collections.unmodifiableList(other); this.pool = pool; } // Instance methods. // ----------------------------------------------------------------------- public void run() { running = true; if (DEBUG) { debug("files: " + files); debug("URLs: " + urls); debug("progs: " + progs); } Iterator files_it = files.iterator(); Iterator urls_it = urls.iterator(); Iterator prog_it = progs.iterator(); Iterator other_it = other.iterator(); while (files_it.hasNext() || urls_it.hasNext() || prog_it.hasNext() || other_it.hasNext()) { // There is enough random data. Go away. if (pool.getQuality() >= 100.0 || !running) { return; } if (files_it.hasNext()) { try { List l = (List) files_it.next(); if (DEBUG) { debug(l.toString()); } double qual = ((Double) l.get(0)).doubleValue(); int offset = ((Integer) l.get(1)).intValue(); int count = ((Integer) l.get(2)).intValue(); String src = (String) l.get(3); InputStream in = new FileInputStream(src); byte[] buf = new byte[count]; if (offset > 0) { in.skip(offset); } int len = in.read(buf); if (len >= 0) { pool.addRandomBytes(buf, 0, len); pool.addQuality(qual * ((double) len / (double) count)); } if (DEBUG) { debug("got " + len + " bytes from " + src); } } catch (Exception x) { if (DEBUG) { debug(x.toString()); x.printStackTrace(); } } } if (pool.getQuality() >= 100.0 || !running) { return; } if (urls_it.hasNext()) { try { List l = (List) urls_it.next(); if (DEBUG) { debug(l.toString()); } double qual = ((Double) l.get(0)).doubleValue(); int offset = ((Integer) l.get(1)).intValue(); int count = ((Integer) l.get(2)).intValue(); URL src = (URL) l.get(3); InputStream in = src.openStream(); byte[] buf = new byte[count]; if (offset > 0) { in.skip(offset); } int len = in.read(buf); if (len >= 0) { pool.addRandomBytes(buf, 0, len); pool.addQuality(qual * ((double) len / (double) count)); } if (DEBUG) { debug("got " + len + " bytes from " + src); } } catch (Exception x) { if (DEBUG) { debug(x.toString()); x.printStackTrace(); } } } if (pool.getQuality() >= 100.0 || !running) { return; } Process proc = null; if (prog_it.hasNext()) { try { List l = (List) prog_it.next(); if (DEBUG) { debug(l.toString()); } double qual = ((Double) l.get(0)).doubleValue(); int offset = ((Integer) l.get(1)).intValue(); int count = ((Integer) l.get(2)).intValue(); String src = (String) l.get(3); proc = null; proc = Runtime.getRuntime().exec(src); InputStream in = proc.getInputStream(); byte[] buf = new byte[count]; if (offset > 0) { in.skip(offset); } int len = in.read(buf); if (len >= 0) { pool.addRandomBytes(buf, 0, len); pool.addQuality(qual * ((double) len / (double) count)); } proc.destroy(); proc.waitFor(); if (DEBUG) { debug("got " + len + " bytes from " + src); } } catch (Exception x) { if (DEBUG) { debug(x.toString()); x.printStackTrace(); } try { if (proc != null) { proc.destroy(); proc.waitFor(); } } catch (Exception ignored) { } } } if (pool.getQuality() >= 100.0 || !running) { return; } if (other_it.hasNext()) { try { EntropySource src = (EntropySource) other_it.next(); byte[] buf = src.nextBytes(); if (pool == null) { return; } pool.addRandomBytes(buf, 0, buf.length); pool.addQuality(src.quality()); if (DEBUG) { debug("got " + buf.length + " bytes from " + src); } } catch (Exception x) { if (DEBUG) { debug(x.toString()); x.printStackTrace(); } } } } } public void stopUpdating() { running = false; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -