diff --git a/lib/RandomLib/Source/ExecTime.php b/lib/RandomLib/Source/ExecTime.php new file mode 100644 index 0000000..ee390a5 --- /dev/null +++ b/lib/RandomLib/Source/ExecTime.php @@ -0,0 +1,129 @@ + + * @copyright 2011 The Authors + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version Build @@version@@ + */ + +/* +* Author: +* George Argyros +* +* Copyright (c) 2012, George Argyros +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL GEORGE ARGYROS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +* +* The function is providing, at least at the systems tested :), +* $len bytes of entropy under any PHP installation or operating system. +* The execution time should be at most 10-20 ms in any system. +*/ + +namespace RandomLib\Source; + +use SecurityLib\Strength; + +/** + * The ExecTime Random Number Source + * + * This source generates low strength random numbers by measuring the execution + * time to perform a sequence of SHA1 computations seeded by mt_rand(). + * + * @category PHPCryptLib + * @package Random + * @subpackage Source + * @author Anthony Ferrara + * @codeCoverageIgnore + */ +class ExecTime implements \RandomLib\Source { + + /** + * Return an instance of Strength indicating the strength of the source + * + * @return Strength An instance of one of the strength classes + */ + public static function getStrength() { + return new Strength(Strength::LOW); + } + + /** + * Generate a random string of the specified size + * + * @param int $size The size of the requested random string + * + * @return string A string of the requested size + */ + public function generate($size) { + $result = ''; + $entropy = ''; + $msec_per_round = 400; + $bits_per_round = 2; + $total = $size; + $bytes = 0; + $hash_length = 20; + $rounds = 0; + while (strlen($result) < $size) { + $bytes = ($total > $hash_length)? $hash_length : $total; + $total -= $bytes; + for ($i=1; $i < 3; $i++) { + $t1 = microtime(true); + $seed = mt_rand(); + for ($j=1; $j < 50; $j++) { + $seed = sha1($seed); + } + $t2 = microtime(true); + $entropy .= $t1 . $t2; + } + $rounds = (int) ($msec_per_round * 50 / (int) (($t2 - $t1) * 1000000)); + $iter = $bytes * (int) (ceil(8 / $bits_per_round)); + for ($i = 0; $i < $iter; $i ++) + { + $t1 = microtime(); + $seed = sha1(mt_rand()); + for ($j = 0; $j < $rounds; $j++) + { + $seed = sha1($seed); + } + $t2 = microtime(); + $entropy .= $t1 . $t2; + } + $result .= sha1($entropy, true); + } + return substr($result, 0, $size); + } + +} diff --git a/test/Unit/RandomLib/Source/ExecTimeTest.php b/test/Unit/RandomLib/Source/ExecTimeTest.php new file mode 100644 index 0000000..d71e9c1 --- /dev/null +++ b/test/Unit/RandomLib/Source/ExecTimeTest.php @@ -0,0 +1,38 @@ + 0 ? str_repeat(chr(0), $i) : chr(0); + $data[] = array($i, $not); + } + return $data; + } + + /** + */ + public function testGetStrength() { + $strength = new Strength(Strength::LOW); + $actual = ExecTime::getStrength(); + $this->assertEquals($actual, $strength); + } + + /** + * @dataProvider provideGenerate + */ + public function testGenerate($length, $not) { + $rand = new ExecTime; + $stub = $rand->generate($length); + $this->assertEquals($length, strlen($stub)); + $this->assertNotEquals($not, $stub); + } + +}