Skip to content

Instantly share code, notes, and snippets.

@Dynom
Created March 31, 2013 12:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dynom/5280484 to your computer and use it in GitHub Desktop.
Save Dynom/5280484 to your computer and use it in GitHub Desktop.
Result of a run from the POC-PRNG-test/PRNG-test.php script, using openssl_random_pseudo_bytes(32). Goal of the test is to measure entropy exhaustion.
...
Finished loop 1966 in 2.679142 seconds (500000 strings generated).
Finished loop 1967 in 2.656262 seconds (500000 strings generated).
Finished loop 1968 in 2.684833 seconds (500000 strings generated).
Finished loop 1969 in 2.676657 seconds (500000 strings generated).
Finished loop 1970 in 2.659669 seconds (500000 strings generated).
Finished loop 1971 in 3.616527 seconds (500000 strings generated).
===> Process took 15533.387 seconds until failure. We managed to generate at least ((loops - 1) * countPerLoop = ) 985000000 successful identifiers
Failure threshold was set to 40% above average processing time. It's possible that this has in fact nothing to do with a depleted entropy-pool, but given the setup, it's very likely.
The entropy pool was constantly between 100-200. The output of this test did not use a entropy feeder, such as RNG or Haveged.
<?php
/**
* This script will generate a bunch of random data to test the exhaustion of kernel entropy.
*
* @author Mark van der Velden <mark@dynom.nl>
*
*
* Entropy can be checked at: /proc/sys/kernel/random/entropy_avail
*
* Tools like RND-tools can help keep the entropy above acceptable ranges. While this doesn`t (necessarily) improve
* the cryptographic strength of the generated data, it does make sure the PRNG stays fast.
*/
// The amount of random numbers we generate, per inner-loop. You may want to play with this to get a certain amount per
// second.
$loop = 500000;
$bytesToGenerate = 32; // The amount of bytes to generate per cycle.
// Some defaults, don't change
$loopCounter = 0;
$averageTimes = array();
$start = microtime(true);
// Outer-loop
do {
// reset
$i = 0;
$a = array();
$loopStart = microtime(true);
// Inner-loop
while ($i < $loop) {
// Generate a 32 byte pseudo random number
$a[] = bin2hex(openssl_random_pseudo_bytes(32));
++$i;
}
// Some loop feedback
$loopCounter++;
$loopTime = microtime(true) - $loopStart;
printf(
"Finished loop %d in %0.6f seconds (%d strings generated).\n",
$loopCounter,
$loopTime,
$loop
);
// Collecting or calculating an average timing
if (count($averageTimes) < 5) {
$averageTimes[] = $loopTime;
} elseif (((array_sum($averageTimes) / 5) * 1.40) < $loopTime) {
// Break if it takes 40% longer then average, our PRNG might be depleted
break;
}
// Give some feedback ever n loops
if (($loopCounter % 50) === 0) {
printf(
"\tGenerated %s strings up to this point. Been running for %d seconds. Peak mem: %s KiB\n",
number_format($loopCounter * $loop),
(microtime(true) - $start),
number_format(memory_get_peak_usage(true) / 1024)
);
}
// If we generated a non-unique number in our sequence, we bail. Since that is bad [tm]
} while (count(array_unique($a)) === $loop);
// Conclusion of the run
printf(
"\n\n===> Process took %0.3f seconds until failure. ".
"We managed to generate at least ((loops - 1) * countPerLoop = ) %d successful identifiers\n",
microtime(true) - $start,
($loopCounter-1) * $loop
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment