mirror of
https://github.com/danog/phpseclib.git
synced 2025-01-22 04:51:19 +01:00
BigInteger: add randomRange / randomPrimeRange
...and redo random / randomPrime such that they take the byte size as the parameter instead of the range.
This commit is contained in:
parent
c17a2604a0
commit
8019baee62
@ -478,9 +478,8 @@ class RSA
|
||||
} else {
|
||||
$num_primes = 2;
|
||||
}
|
||||
extract(self::_generateMinMax($temp + $bits % $temp));
|
||||
$finalMax = $max;
|
||||
extract(self::_generateMinMax($temp));
|
||||
$regSize = $temp;
|
||||
$finalSize = $temp + $bits % $temp;
|
||||
|
||||
$n = clone self::$one;
|
||||
if (!empty($partial)) {
|
||||
@ -515,15 +514,8 @@ class RSA
|
||||
}
|
||||
}
|
||||
|
||||
if ($i == $num_primes) {
|
||||
list($min, $temp) = $absoluteMin->divide($n);
|
||||
if (!$temp->equals(self::$zero)) {
|
||||
$min = $min->add(self::$one); // ie. ceil()
|
||||
}
|
||||
$primes[$i] = BigInteger::randomPrime($min, $finalMax, $timeout);
|
||||
} else {
|
||||
$primes[$i] = BigInteger::randomPrime($min, $max, $timeout);
|
||||
}
|
||||
$size = $i == $num_primes ? $finalSize : $regSize;
|
||||
$primes[$i] = BigInteger::randomPrime($size, $timeout);
|
||||
|
||||
if ($primes[$i] === false) { // if we've reached the timeout
|
||||
if (count($primes) > 1) {
|
||||
@ -1067,32 +1059,6 @@ class RSA
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the smallest and largest numbers requiring $bits bits
|
||||
*
|
||||
* @access private
|
||||
* @param int $bits
|
||||
* @return array
|
||||
*/
|
||||
static function _generateMinMax($bits)
|
||||
{
|
||||
$bytes = $bits >> 3;
|
||||
$min = str_repeat(chr(0), $bytes);
|
||||
$max = str_repeat(chr(0xFF), $bytes);
|
||||
$msb = $bits & 7;
|
||||
if ($msb) {
|
||||
$min = chr(1 << ($msb - 1)) . $min;
|
||||
$max = chr((1 << $msb) - 1) . $max;
|
||||
} else {
|
||||
$min[0] = chr(0x80);
|
||||
}
|
||||
|
||||
return array(
|
||||
'min' => new BigInteger($min, 256),
|
||||
'max' => new BigInteger($max, 256)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the private key format
|
||||
*
|
||||
@ -1284,7 +1250,7 @@ class RSA
|
||||
}
|
||||
}
|
||||
|
||||
$r = BigInteger::random(self::$one, $smallest->subtract(self::$one));
|
||||
$r = BigInteger::randomRange(self::$one, $smallest->subtract(self::$one));
|
||||
|
||||
$m_i = array(
|
||||
1 => $this->_blind($x, $r, 1),
|
||||
|
@ -3010,15 +3010,15 @@ class BigInteger
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random BigInteger
|
||||
* Generates a random number of a certain size
|
||||
*
|
||||
* Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not.
|
||||
* Byte length is equal to $size. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not.
|
||||
*
|
||||
* @param int $length
|
||||
* @param int $size
|
||||
* @return \phpseclib\Math\BigInteger
|
||||
* @access private
|
||||
* @access public
|
||||
*/
|
||||
static function _random_number_helper($size)
|
||||
static function random($size)
|
||||
{
|
||||
if (class_exists('\phpseclib\Crypt\Random')) {
|
||||
$random = Random::string($size);
|
||||
@ -3040,20 +3040,20 @@ class BigInteger
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random number
|
||||
* Generate a random number between a range
|
||||
*
|
||||
* Returns a random number between $min and $max where $min and $max
|
||||
* can be defined using one of the two methods:
|
||||
*
|
||||
* BigInteger::random($min, $max)
|
||||
* BigInteger::random($max, $min)
|
||||
* BigInteger::randomRange($min, $max)
|
||||
* BigInteger::randomRange($max, $min)
|
||||
*
|
||||
* @param \phpseclib\Math\BigInteger $arg1
|
||||
* @param \phpseclib\Math\BigInteger $arg2
|
||||
* @return \phpseclib\Math\BigInteger
|
||||
* @access public
|
||||
*/
|
||||
static function random(BigInteger $min, BigInteger $max)
|
||||
static function randomRange(BigInteger $min, BigInteger $max)
|
||||
{
|
||||
$compare = $max->compare($min);
|
||||
|
||||
@ -3090,7 +3090,7 @@ class BigInteger
|
||||
http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string
|
||||
*/
|
||||
$random_max = new static(chr(1) . str_repeat("\0", $size), 256);
|
||||
$random = static::_random_number_helper($size);
|
||||
$random = static::random($size);
|
||||
|
||||
list($max_multiple) = $random_max->divide($max);
|
||||
$max_multiple = $max_multiple->multiply($max);
|
||||
@ -3099,7 +3099,7 @@ class BigInteger
|
||||
$random = $random->subtract($max_multiple);
|
||||
$random_max = $random_max->subtract($max_multiple);
|
||||
$random = $random->bitwise_leftShift(8);
|
||||
$random = $random->add(self::_random_number_helper(1));
|
||||
$random = $random->add(self::random(1));
|
||||
$random_max = $random_max->bitwise_leftShift(8);
|
||||
list($max_multiple) = $random_max->divide($max);
|
||||
$max_multiple = $max_multiple->multiply($max);
|
||||
@ -3110,7 +3110,36 @@ class BigInteger
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random prime number.
|
||||
* Generates a random prime number of a certain size
|
||||
*
|
||||
* Byte length is equal to $size
|
||||
*
|
||||
* @param int $size
|
||||
* @param int $timeout
|
||||
* @return \phpseclib\Math\BigInteger
|
||||
* @access public
|
||||
*/
|
||||
static function randomPrime($size, $timeout = false)
|
||||
{
|
||||
$min = str_repeat(chr(0), $bytes);
|
||||
$max = str_repeat(chr(0xFF), $bytes);
|
||||
$msb = $bits & 7;
|
||||
if ($msb) {
|
||||
$min = chr(1 << ($msb - 1)) . $min;
|
||||
$max = chr((1 << $msb) - 1) . $max;
|
||||
} else {
|
||||
$min[0] = chr(0x80);
|
||||
}
|
||||
|
||||
return self::randomRangePrime(
|
||||
new Math_BigInteger($min, 256),
|
||||
new Math_BigInteger($max, 256),
|
||||
$timeout
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random prime number between a range
|
||||
*
|
||||
* If there's not a prime within the given range, false will be returned.
|
||||
* If more than $timeout seconds have elapsed, give up and return false.
|
||||
@ -3122,7 +3151,7 @@ class BigInteger
|
||||
* @access public
|
||||
* @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}.
|
||||
*/
|
||||
static function randomPrime(BigInteger $min, BigInteger $max, $timeout = false)
|
||||
static function randomRangePrime(BigInteger $min, BigInteger $max, $timeout = false)
|
||||
{
|
||||
$compare = $max->compare($min);
|
||||
|
||||
|
@ -1515,7 +1515,7 @@ class SSH2
|
||||
$max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength
|
||||
$max = $max->subtract($one);
|
||||
|
||||
$x = BigInteger::random($one, $max);
|
||||
$x = BigInteger::randomRange($one, $max);
|
||||
$e = $g->modPow($x, $prime);
|
||||
|
||||
$eBytes = $e->toBytes(true);
|
||||
|
@ -273,7 +273,7 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
|
||||
$min = $this->getInstance(0);
|
||||
$max = $this->getInstance('18446744073709551616');
|
||||
|
||||
$rand1 = \phpseclib\Math\BigInteger::random($min, $max);
|
||||
$rand1 = \phpseclib\Math\BigInteger::randomRange($min, $max);
|
||||
// technically $rand1 can equal $min but with the $min and $max we've
|
||||
// chosen it's just not that likely
|
||||
$this->assertTrue($rand1->compare($min) > 0);
|
||||
@ -315,8 +315,8 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
|
||||
Code for generation of $alicePrivate and $bobPrivate.
|
||||
$one = $this->getInstance(1);
|
||||
$max = $one->bitwise_leftShift(512)->subtract($one);
|
||||
$alicePrivate = \phpseclib\Math\BigInteger::random($one, $max);
|
||||
$bobPrivate = \phpseclib\Math\BigInteger::random($one, $max);
|
||||
$alicePrivate = \phpseclib\Math\BigInteger::randomRange($one, $max);
|
||||
$bobPrivate = \phpseclib\Math\BigInteger::randomRange($one, $max);
|
||||
var_dump($alicePrivate->toHex(), $bobPrivate->toHex());
|
||||
*/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user