diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 82a1d50f..947ce1c9 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -512,15 +512,13 @@ class RSA $finalMax = $max; extract(self::_generateMinMax($temp)); - $generator = new BigInteger(); - - $n = self::$one->copy(); + $n = clone self::$one; if (!empty($partial)) { extract(unserialize($partial)); } else { $exponents = $coefficients = $primes = array(); $lcm = array( - 'top' => self::$one->copy(), + 'top' => clone self::$one, 'bottom' => false ); } @@ -552,9 +550,9 @@ class RSA if (!$temp->equals(self::$zero)) { $min = $min->add(self::$one); // ie. ceil() } - $primes[$i] = $generator->randomPrime($min, $finalMax, $timeout); + $primes[$i] = BigInteger::randomPrime($min, $finalMax, $timeout); } else { - $primes[$i] = $generator->randomPrime($min, $max, $timeout); + $primes[$i] = BigInteger::randomPrime($min, $max, $timeout); } if ($primes[$i] === false) { // if we've reached the timeout @@ -703,13 +701,13 @@ class RSA } if (is_object($key->modulus)) { - $this->modulus = $key->modulus->copy(); + $this->modulus = clone $key->modulus; } if (is_object($key->exponent)) { - $this->exponent = $key->exponent->copy(); + $this->exponent = clone $key->exponent; } if (is_object($key->publicExponent)) { - $this->publicExponent = $key->publicExponent->copy(); + $this->publicExponent = clone $key->publicExponent; } $this->primes = array(); @@ -717,13 +715,13 @@ class RSA $this->coefficients = array(); foreach ($this->primes as $prime) { - $this->primes[] = $prime->copy(); + $this->primes[] = clone $prime; } foreach ($this->exponents as $exponent) { - $this->exponents[] = $exponent->copy(); + $this->exponents[] = clone $exponent; } foreach ($this->coefficients as $coefficient) { - $this->coefficients[] = $coefficient->copy(); + $this->coefficients[] = clone $coefficient; } return true; @@ -1370,7 +1368,7 @@ class RSA } } - $r = self::$one->random(self::$one, $smallest->subtract(self::$one)); + $r = BigInteger::random(self::$one, $smallest->subtract(self::$one)); $m_i = array( 1 => $this->_blind($x, $r, 1), diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index 6befb591..60e18866 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -527,7 +527,7 @@ class BigInteger return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; } - $temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy(); + $temp = $comparison < 0 ? $this->add(new static(1)) : $this; $bytes = $temp->toBytes(); if (empty($bytes)) { // eg. if the number we're trying to convert is -1 @@ -580,13 +580,11 @@ class BigInteger if (!count($this->value)) { return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; } - $result = $this->_int2bytes($this->value[count($this->value) - 1]); + $result = self::_int2bytes($this->value[count($this->value) - 1]); - $temp = $this->copy(); - - for ($i = count($temp->value) - 2; $i >= 0; --$i) { - $temp->_base256_lshift($result, self::$base); - $result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT); + for ($i = count($this->value) - 2; $i >= 0; --$i) { + self::_base256_lshift($result, self::$base); + $result = $result | str_pad(self::_int2bytes($this->value[$i]), strlen($result), chr(0), STR_PAD_LEFT); } return $this->precision > 0 ? @@ -691,7 +689,7 @@ class BigInteger return '0'; } - $temp = $this->copy(); + $temp = clone $this; $temp->is_negative = false; $divisor = new static(); @@ -713,28 +711,6 @@ class BigInteger return $result; } - /** - * Copy an object - * - * PHP5 passes objects by reference while PHP4 passes by value. As such, we need a function to guarantee - * that all objects are passed by value, when appropriate. More information can be found here: - * - * {@link http://php.net/language.oop5.basic#51624} - * - * @access public - * @see self::__clone() - * @return \phpseclib\Math\BigInteger - */ - function copy() - { - $temp = new static(); - $temp->value = $this->value; - $temp->is_negative = $this->is_negative; - $temp->precision = $this->precision; - $temp->bitmask = $this->bitmask; - return $temp; - } - /** * __toString() magic method * @@ -749,23 +725,6 @@ class BigInteger return $this->toString(); } - /** - * __clone() magic method - * - * Although you can call BigInteger::__toString() directly in PHP5, you cannot call BigInteger::__clone() directly - * in PHP5. You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5 - * only syntax of $y = clone $x. As such, if you're trying to write an application that works on both PHP4 and - * PHP5, call BigInteger::copy(), instead. - * - * @access public - * @see self::copy() - * @return \phpseclib\Math\BigInteger - */ - function __clone() - { - return $this->copy(); - } - /** * __sleep() magic method * @@ -856,7 +815,7 @@ class BigInteger * @access public * @internal Performs base-2**52 addition */ - function add($y) + function add(BigInteger $y) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -871,7 +830,7 @@ class BigInteger return $this->_normalize($temp); } - $temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative); + $temp = self::_add($this->value, $this->is_negative, $y->value, $y->is_negative); $result = new static(); $result->value = $temp[self::VALUE]; @@ -890,7 +849,7 @@ class BigInteger * @return array * @access private */ - function _add($x_value, $x_negative, $y_value, $y_negative) + static function _add($x_value, $x_negative, $y_value, $y_negative) { $x_size = count($x_value); $y_size = count($y_value); @@ -916,8 +875,8 @@ class BigInteger ); } - $temp = $this->_subtract($x_value, false, $y_value, false); - $temp[self::SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ? + $temp = self::_subtract($x_value, false, $y_value, false); + $temp[self::SIGN] = self::_compare($x_value, false, $y_value, false) > 0 ? $x_negative : $y_negative; return $temp; @@ -960,7 +919,7 @@ class BigInteger } return array( - self::VALUE => $this->_trim($value), + self::VALUE => self::_trim($value), self::SIGN => $x_negative ); } @@ -985,7 +944,7 @@ class BigInteger * @access public * @internal Performs base-2**52 subtraction */ - function subtract($y) + function subtract(BigInteger $y) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -1000,7 +959,7 @@ class BigInteger return $this->_normalize($temp); } - $temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative); + $temp = self::_subtract($this->value, $this->is_negative, $y->value, $y->is_negative); $result = new static(); $result->value = $temp[self::VALUE]; @@ -1019,7 +978,7 @@ class BigInteger * @return array * @access private */ - function _subtract($x_value, $x_negative, $y_value, $y_negative) + static function _subtract($x_value, $x_negative, $y_value, $y_negative) { $x_size = count($x_value); $y_size = count($y_value); @@ -1038,13 +997,13 @@ class BigInteger // add, if appropriate (ie. -$x - +$y or +$x - -$y) if ($x_negative != $y_negative) { - $temp = $this->_add($x_value, false, $y_value, false); + $temp = self::_add($x_value, false, $y_value, false); $temp[self::SIGN] = $x_negative; return $temp; } - $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative); + $diff = self::_compare($x_value, $x_negative, $y_value, $y_negative); if (!$diff) { return array( @@ -1094,7 +1053,7 @@ class BigInteger } return array( - self::VALUE => $this->_trim($x_value), + self::VALUE => self::_trim($x_value), self::SIGN => $x_negative ); } @@ -1118,7 +1077,7 @@ class BigInteger * @return \phpseclib\Math\BigInteger * @access public */ - function multiply($x) + function multiply(BigInteger $x) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -1133,7 +1092,7 @@ class BigInteger return $this->_normalize($temp); } - $temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative); + $temp = self::_multiply($this->value, $this->is_negative, $x->value, $x->is_negative); $product = new static(); $product->value = $temp[self::VALUE]; @@ -1152,7 +1111,7 @@ class BigInteger * @return array * @access private */ - function _multiply($x_value, $x_negative, $y_value, $y_negative) + static function _multiply($x_value, $x_negative, $y_value, $y_negative) { //if ( $x_value == $y_value ) { // return array( @@ -1173,8 +1132,8 @@ class BigInteger return array( self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? - $this->_trim($this->_regularMultiply($x_value, $y_value)) : - $this->_trim($this->_karatsuba($x_value, $y_value)), + self::_trim(self::_regularMultiply($x_value, $y_value)) : + self::_trim(self::_karatsuba($x_value, $y_value)), self::SIGN => $x_negative != $y_negative ); } @@ -1189,7 +1148,7 @@ class BigInteger * @return array * @access private */ - function _regularMultiply($x_value, $y_value) + static function _regularMultiply($x_value, $y_value) { $x_length = count($x_value); $y_length = count($y_value); @@ -1207,7 +1166,7 @@ class BigInteger $y_length = count($y_value); } - $product_value = $this->_array_repeat(0, $x_length + $y_length); + $product_value = self::_array_repeat(0, $x_length + $y_length); // the following for loop could be removed if the for loop following it // (the one with nested for loops) initially set $i to 0, but @@ -1253,12 +1212,12 @@ class BigInteger * @return array * @access private */ - function _karatsuba($x_value, $y_value) + static function _karatsuba($x_value, $y_value) { $m = min(count($x_value) >> 1, count($y_value) >> 1); if ($m < self::KARATSUBA_CUTOFF) { - return $this->_regularMultiply($x_value, $y_value); + return self::_regularMultiply($x_value, $y_value); } $x1 = array_slice($x_value, $m); @@ -1266,20 +1225,20 @@ class BigInteger $y1 = array_slice($y_value, $m); $y0 = array_slice($y_value, 0, $m); - $z2 = $this->_karatsuba($x1, $y1); - $z0 = $this->_karatsuba($x0, $y0); + $z2 = self::_karatsuba($x1, $y1); + $z0 = self::_karatsuba($x0, $y0); - $z1 = $this->_add($x1, false, $x0, false); - $temp = $this->_add($y1, false, $y0, false); - $z1 = $this->_karatsuba($z1[self::VALUE], $temp[self::VALUE]); - $temp = $this->_add($z2, false, $z0, false); - $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false); + $z1 = self::_add($x1, false, $x0, false); + $temp = self::_add($y1, false, $y0, false); + $z1 = self::_karatsuba($z1[self::VALUE], $temp[self::VALUE]); + $temp = self::_add($z2, false, $z0, false); + $z1 = self::_subtract($z1, false, $temp[self::VALUE], false); $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); - $xy = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]); - $xy = $this->_add($xy[self::VALUE], $xy[self::SIGN], $z0, false); + $xy = self::_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xy = self::_add($xy[self::VALUE], $xy[self::SIGN], $z0, false); return $xy[self::VALUE]; } @@ -1291,11 +1250,11 @@ class BigInteger * @return array * @access private */ - function _square($x = false) + static function _square($x = false) { return count($x) < 2 * self::KARATSUBA_CUTOFF ? - $this->_trim($this->_baseSquare($x)) : - $this->_trim($this->_karatsubaSquare($x)); + self::_trim(self::_baseSquare($x)) : + self::_trim(self::_karatsubaSquare($x)); } /** @@ -1309,12 +1268,12 @@ class BigInteger * @return array * @access private */ - function _baseSquare($value) + static function _baseSquare($value) { if (empty($value)) { return array(); } - $square_value = $this->_array_repeat(0, 2 * count($value)); + $square_value = self::_array_repeat(0, 2 * count($value)); for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) { $i2 = $i << 1; @@ -1348,30 +1307,30 @@ class BigInteger * @return array * @access private */ - function _karatsubaSquare($value) + static function _karatsubaSquare($value) { $m = count($value) >> 1; if ($m < self::KARATSUBA_CUTOFF) { - return $this->_baseSquare($value); + return self::_baseSquare($value); } $x1 = array_slice($value, $m); $x0 = array_slice($value, 0, $m); - $z2 = $this->_karatsubaSquare($x1); - $z0 = $this->_karatsubaSquare($x0); + $z2 = self::_karatsubaSquare($x1); + $z0 = self::_karatsubaSquare($x0); - $z1 = $this->_add($x1, false, $x0, false); - $z1 = $this->_karatsubaSquare($z1[self::VALUE]); - $temp = $this->_add($z2, false, $z0, false); - $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false); + $z1 = self::_add($x1, false, $x0, false); + $z1 = self::_karatsubaSquare($z1[self::VALUE]); + $temp = self::_add($z2, false, $z0, false); + $z1 = self::_subtract($z1, false, $temp[self::VALUE], false); $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); - $xx = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]); - $xx = $this->_add($xx[self::VALUE], $xx[self::SIGN], $z0, false); + $xx = self::_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xx = self::_add($xx[self::VALUE], $xx[self::SIGN], $z0, false); return $xx[self::VALUE]; } @@ -1403,7 +1362,7 @@ class BigInteger * @access public * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. */ - function divide($y) + function divide(BigInteger $y) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -1446,8 +1405,8 @@ class BigInteger $zero = new static(); } - $x = $this->copy(); - $y = $y->copy(); + $x = clone $this; + $y = clone $y; $x_sign = $x->is_negative; $y_sign = $y->is_negative; @@ -1584,14 +1543,14 @@ class BigInteger * @return array * @access private */ - function _divide_digit($dividend, $divisor) + static function _divide_digit($dividend, $divisor) { $carry = 0; $result = array(); for ($i = count($dividend) - 1; $i >= 0; --$i) { $temp = self::$baseFull * $carry + $dividend[$i]; - $result[$i] = $this->_safe_divide($temp, $divisor); + $result[$i] = self::_safe_divide($temp, $divisor); $carry = (int) ($temp - $divisor * $result[$i]); } @@ -1638,7 +1597,7 @@ class BigInteger * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. */ - function modPow($e, $n) + function modPow(BigInteger $e, BigInteger $n) { $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); @@ -1672,26 +1631,26 @@ class BigInteger ); $components = array( - 'modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']), - 'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent']) + 'modulus' => pack('Ca*a*', 2, self::_encodeASN1Length(strlen($components['modulus'])), $components['modulus']), + 'publicExponent' => pack('Ca*a*', 2, self::_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent']) ); $RSAPublicKey = pack( 'Ca*a*a*', 48, - $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])), + self::_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])), $components['modulus'], $components['publicExponent'] ); $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA $RSAPublicKey = chr(0) . $RSAPublicKey; - $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey; + $RSAPublicKey = chr(3) . self::_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey; $encapsulated = pack( 'Ca*a*', 48, - $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)), + self::_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey ); @@ -1726,7 +1685,7 @@ class BigInteger if ($e->value == array(2)) { $temp = new static(); - $temp->value = $this->_square($this->value); + $temp->value = self::_square($this->value); list(, $temp) = $temp->divide($n); return $this->_normalize($temp); } @@ -1755,7 +1714,7 @@ class BigInteger } // at this point, 2^$j * $n/(2^$j) == $n - $mod1 = $n->copy(); + $mod1 = clone $n; $mod1->_rshift($j); $mod2 = new static(); $mod2->value = array(1); @@ -1789,7 +1748,7 @@ class BigInteger * @return \phpseclib\Math\BigInteger * @access public */ - function powMod($e, $n) + function powMod(BigInteger $e, BigInteger $n) { return $this->modPow($e, $n); } @@ -1831,23 +1790,23 @@ class BigInteger // precompute $this^0 through $this^$window_size $powers = array(); - $powers[1] = $this->_prepareReduce($this->value, $n_value, $mode); - $powers[2] = $this->_squareReduce($powers[1], $n_value, $mode); + $powers[1] = self::_prepareReduce($this->value, $n_value, $mode); + $powers[2] = self::_squareReduce($powers[1], $n_value, $mode); // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end // in a 1. ie. it's supposed to be odd. $temp = 1 << ($window_size - 1); for ($i = 1; $i < $temp; ++$i) { $i2 = $i << 1; - $powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode); + $powers[$i2 + 1] = self::_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode); } $result = array(1); - $result = $this->_prepareReduce($result, $n_value, $mode); + $result = self::_prepareReduce($result, $n_value, $mode); for ($i = 0; $i < $e_length;) { if (!$e_bits[$i]) { - $result = $this->_squareReduce($result, $n_value, $mode); + $result = self::_squareReduce($result, $n_value, $mode); ++$i; } else { for ($j = $window_size - 1; $j > 0; --$j) { @@ -1858,17 +1817,17 @@ class BigInteger // eg. the length of substr($e_bits, $i, $j + 1) for ($k = 0; $k <= $j; ++$k) { - $result = $this->_squareReduce($result, $n_value, $mode); + $result = self::_squareReduce($result, $n_value, $mode); } - $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode); + $result = self::_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode); $i += $j + 1; } } $temp = new static(); - $temp->value = $this->_reduce($result, $n_value, $mode); + $temp->value = self::_reduce($result, $n_value, $mode); return $temp; } @@ -1885,13 +1844,13 @@ class BigInteger * @param int $mode * @return array */ - function _reduce($x, $n, $mode) + static function _reduce($x, $n, $mode) { switch ($mode) { case self::MONTGOMERY: - return $this->_montgomery($x, $n); + return self::_montgomery($x, $n); case self::BARRETT: - return $this->_barrett($x, $n); + return self::_barrett($x, $n); case self::POWEROF2: $lhs = new static(); $lhs->value = $x; @@ -1922,12 +1881,12 @@ class BigInteger * @param int $mode * @return array */ - function _prepareReduce($x, $n, $mode) + static function _prepareReduce($x, $n, $mode) { if ($mode == self::MONTGOMERY) { - return $this->_prepMontgomery($x, $n); + return self::_prepMontgomery($x, $n); } - return $this->_reduce($x, $n, $mode); + return self::_reduce($x, $n, $mode); } /** @@ -1941,13 +1900,13 @@ class BigInteger * @param int $mode * @return array */ - function _multiplyReduce($x, $y, $n, $mode) + static function _multiplyReduce($x, $y, $n, $mode) { if ($mode == self::MONTGOMERY) { - return $this->_montgomeryMultiply($x, $y, $n); + return self::_montgomeryMultiply($x, $y, $n); } - $temp = $this->_multiply($x, false, $y, false); - return $this->_reduce($temp[self::VALUE], $n, $mode); + $temp = self::_multiply($x, false, $y, false); + return self::_reduce($temp[self::VALUE], $n, $mode); } /** @@ -1960,12 +1919,12 @@ class BigInteger * @param int $mode * @return array */ - function _squareReduce($x, $n, $mode) + static function _squareReduce($x, $n, $mode) { if ($mode == self::MONTGOMERY) { - return $this->_montgomeryMultiply($x, $x, $n); + return self::_montgomeryMultiply($x, $x, $n); } - return $this->_reduce($this->_square($x), $n, $mode); + return self::_reduce(self::_square($x), $n, $mode); } /** @@ -2010,7 +1969,7 @@ class BigInteger * @param array $m * @return array */ - function _barrett($n, $m) + static function _barrett($n, $m) { static $cache = array( self::VARIABLE => array(), @@ -2019,7 +1978,7 @@ class BigInteger $m_length = count($m); - // if ($this->_compare($n, $this->_square($m)) >= 0) { + // if (self::_compare($n, self::_square($m)) >= 0) { if (count($n) > 2 * $m_length) { $lhs = new static(); $rhs = new static(); @@ -2031,7 +1990,7 @@ class BigInteger // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced if ($m_length < 5) { - return $this->_regularBarrett($n, $m); + return self::_regularBarrett($n, $m); } // n = 2 * m.length @@ -2042,7 +2001,7 @@ class BigInteger $lhs = new static(); $lhs_value = &$lhs->value; - $lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value = self::_array_repeat(0, $m_length + ($m_length >> 1)); $lhs_value[] = 1; $rhs = new static(); $rhs->value = $m; @@ -2062,34 +2021,34 @@ class BigInteger $cutoff = $m_length + ($m_length >> 1); $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1) $msd = array_slice($n, $cutoff); // m.length >> 1 - $lsd = $this->_trim($lsd); - $temp = $this->_multiply($msd, false, $m1, false); - $n = $this->_add($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 + $lsd = self::_trim($lsd); + $temp = self::_multiply($msd, false, $m1, false); + $n = self::_add($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 if ($m_length & 1) { - return $this->_regularBarrett($n[self::VALUE], $m); + return self::_regularBarrett($n[self::VALUE], $m); } // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 $temp = array_slice($n[self::VALUE], $m_length - 1); // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 - $temp = $this->_multiply($temp, false, $u, false); + $temp = self::_multiply($temp, false, $u, false); // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1); // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) - $temp = $this->_multiply($temp, false, $m, false); + $temp = self::_multiply($temp, false, $m, false); // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). - $result = $this->_subtract($n[self::VALUE], false, $temp[self::VALUE], false); + $result = self::_subtract($n[self::VALUE], false, $temp[self::VALUE], false); - while ($this->_compare($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { - $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $m, false); + while (self::_compare($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { + $result = self::_subtract($result[self::VALUE], $result[self::SIGN], $m, false); } return $result[self::VALUE]; @@ -2107,7 +2066,7 @@ class BigInteger * @param array $n * @return array */ - function _regularBarrett($x, $n) + static function _regularBarrett($x, $n) { static $cache = array( self::VARIABLE => array(), @@ -2130,7 +2089,7 @@ class BigInteger $cache[self::VARIABLE][] = $n; $lhs = new static(); $lhs_value = &$lhs->value; - $lhs_value = $this->_array_repeat(0, 2 * $n_length); + $lhs_value = self::_array_repeat(0, 2 * $n_length); $lhs_value[] = 1; $rhs = new static(); $rhs->value = $n; @@ -2141,27 +2100,27 @@ class BigInteger // 2 * m.length - (m.length - 1) = m.length + 1 $temp = array_slice($x, $n_length - 1); // (m.length + 1) + m.length = 2 * m.length + 1 - $temp = $this->_multiply($temp, false, $cache[self::DATA][$key], false); + $temp = self::_multiply($temp, false, $cache[self::DATA][$key], false); // (2 * m.length + 1) - (m.length - 1) = m.length + 2 $temp = array_slice($temp[self::VALUE], $n_length + 1); // m.length + 1 $result = array_slice($x, 0, $n_length + 1); // m.length + 1 - $temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1); - // $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1) + $temp = self::_multiplyLower($temp, false, $n, false, $n_length + 1); + // $temp == array_slice(self::_multiply($temp, false, $n, false)->value, 0, $n_length + 1) - if ($this->_compare($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { - $corrector_value = $this->_array_repeat(0, $n_length + 1); + if (self::_compare($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { + $corrector_value = self::_array_repeat(0, $n_length + 1); $corrector_value[count($corrector_value)] = 1; - $result = $this->_add($result, false, $corrector_value, false); + $result = self::_add($result, false, $corrector_value, false); $result = $result[self::VALUE]; } // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits - $result = $this->_subtract($result, false, $temp[self::VALUE], $temp[self::SIGN]); - while ($this->_compare($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { - $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $n, false); + $result = self::_subtract($result, false, $temp[self::VALUE], $temp[self::SIGN]); + while (self::_compare($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { + $result = self::_subtract($result[self::VALUE], $result[self::SIGN], $n, false); } return $result[self::VALUE]; @@ -2181,7 +2140,7 @@ class BigInteger * @return array * @access private */ - function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop) + static function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop) { $x_length = count($x_value); $y_length = count($y_value); @@ -2202,7 +2161,7 @@ class BigInteger $y_length = count($y_value); } - $product_value = $this->_array_repeat(0, $x_length + $y_length); + $product_value = self::_array_repeat(0, $x_length + $y_length); // the following for loop could be removed if the for loop following it // (the one with nested for loops) initially set $i to 0, but @@ -2240,7 +2199,7 @@ class BigInteger } return array( - self::VALUE => $this->_trim($product_value), + self::VALUE => self::_trim($product_value), self::SIGN => $x_negative != $y_negative ); } @@ -2260,7 +2219,7 @@ class BigInteger * @param array $n * @return array */ - function _montgomery($x, $n) + static function _montgomery($x, $n) { static $cache = array( self::VARIABLE => array(), @@ -2270,7 +2229,7 @@ class BigInteger if (($key = array_search($n, $cache[self::VARIABLE])) === false) { $key = count($cache[self::VARIABLE]); $cache[self::VARIABLE][] = $x; - $cache[self::DATA][] = $this->_modInverse67108864($n); + $cache[self::DATA][] = self::_modInverse67108864($n); } $k = count($n); @@ -2280,15 +2239,15 @@ class BigInteger for ($i = 0; $i < $k; ++$i) { $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $this->_regularMultiply(array($temp), $n); + $temp = self::_regularMultiply(array($temp), $n); $temp = array_merge($this->_array_repeat(0, $i), $temp); - $result = $this->_add($result[self::VALUE], false, $temp, false); + $result = self::_add($result[self::VALUE], false, $temp, false); } $result[self::VALUE] = array_slice($result[self::VALUE], $k); - if ($this->_compare($result, false, $n, false) >= 0) { - $result = $this->_subtract($result[self::VALUE], false, $n, false); + if (self::_compare($result, false, $n, false) >= 0) { + $result = self::_subtract($result[self::VALUE], false, $n, false); } return $result[self::VALUE]; @@ -2308,10 +2267,10 @@ class BigInteger * @param array $m * @return array */ - function _montgomeryMultiply($x, $y, $m) + static function _montgomeryMultiply($x, $y, $m) { - $temp = $this->_multiply($x, false, $y, false); - return $this->_montgomery($temp[self::VALUE], $m); + $temp = self::_multiply($x, false, $y, false); + return self::_montgomery($temp[self::VALUE], $m); // the following code, although not callable, can be run independently of the above code // although the above code performed better in my benchmarks the following could might @@ -2326,25 +2285,25 @@ class BigInteger if (($key = array_search($m, $cache[self::VARIABLE])) === false) { $key = count($cache[self::VARIABLE]); $cache[self::VARIABLE][] = $m; - $cache[self::DATA][] = $this->_modInverse67108864($m); + $cache[self::DATA][] = self::_modInverse67108864($m); } $n = max(count($x), count($y), count($m)); $x = array_pad($x, $n, 0); $y = array_pad($y, $n, 0); $m = array_pad($m, $n, 0); - $a = array(self::VALUE => $this->_array_repeat(0, $n + 1)); + $a = array(self::VALUE => self::_array_repeat(0, $n + 1)); for ($i = 0; $i < $n; ++$i) { $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); $temp = $temp * $cache[self::DATA][$key]; $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false); - $a = $this->_add($a[self::VALUE], false, $temp[self::VALUE], false); + $temp = self::_add(self::_regularMultiply(array($x[$i]), $y), false, self::_regularMultiply(array($temp), $m), false); + $a = self::_add($a[self::VALUE], false, $temp[self::VALUE], false); $a[self::VALUE] = array_slice($a[self::VALUE], 1); } - if ($this->_compare($a[self::VALUE], false, $m, false) >= 0) { - $a = $this->_subtract($a[self::VALUE], false, $m, false); + if (self::_compare($a[self::VALUE], false, $m, false) >= 0) { + $a = self::_subtract($a[self::VALUE], false, $m, false); } return $a[self::VALUE]; } @@ -2359,10 +2318,10 @@ class BigInteger * @param array $n * @return array */ - function _prepMontgomery($x, $n) + static function _prepMontgomery($x, $n) { $lhs = new static(); - $lhs->value = array_merge($this->_array_repeat(0, count($n)), $x); + $lhs->value = array_merge(self::_array_repeat(0, count($n)), $x); $rhs = new static(); $rhs->value = $n; @@ -2434,7 +2393,7 @@ class BigInteger * @access public * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information. */ - function modInverse($n) + function modInverse(BigInteger $n) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -2498,7 +2457,7 @@ class BigInteger * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}. As the text above 14.61 notes, * the more traditional algorithim requires "relatively costly multiple-precision divisions". */ - function extendedGCD($n) + function extendedGCD(BigInteger $n) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -2545,8 +2504,8 @@ class BigInteger ); } - $y = $n->copy(); - $x = $this->copy(); + $y = clone $n; + $x = clone $this; $g = new static(); $g->value = array(1); @@ -2556,8 +2515,8 @@ class BigInteger $g->_lshift(1); } - $u = $x->copy(); - $v = $y->copy(); + $u = clone $x; + $v = clone $y; $a = new static(); $b = new static(); @@ -2627,7 +2586,7 @@ class BigInteger * @return \phpseclib\Math\BigInteger * @access public */ - function gcd($n) + function gcd(BigInteger $n) { extract($this->extendedGCD($n)); return $gcd; @@ -2675,7 +2634,7 @@ class BigInteger * @see self::equals() * @internal Could return $this->subtract($x), but that's not as fast as what we do do. */ - function compare($y) + function compare(BigInteger $y) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -2684,7 +2643,7 @@ class BigInteger return bccomp($this->value, $y->value, 0); } - return $this->_compare($this->value, $this->is_negative, $y->value, $y->is_negative); + return self::_compare($this->value, $this->is_negative, $y->value, $y->is_negative); } /** @@ -2698,7 +2657,7 @@ class BigInteger * @see self::compare() * @access private */ - function _compare($x_value, $x_negative, $y_value, $y_negative) + static function _compare($x_value, $x_negative, $y_value, $y_negative) { if ($x_negative != $y_negative) { return (!$x_negative && $y_negative) ? 1 : -1; @@ -2733,7 +2692,7 @@ class BigInteger * @access public * @see self::compare() */ - function equals($x) + function equals(BigInteger $x) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -2754,6 +2713,12 @@ class BigInteger */ function setPrecision($bits) { + if ($bits < 1) { + $this->precision = -1; + $this->bitmask = false; + + return; + } $this->precision = $bits; if (MATH_BIGINTEGER_MODE != self::MODE_BCMATH) { $this->bitmask = new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256); @@ -2765,6 +2730,18 @@ class BigInteger $this->value = $temp->value; } + /** + * Get Precision + * + * @return int + * @see self::setPrecision() + * @access public + */ + function getPrecision() + { + return $this->precision; + } + /** * Logical And * @@ -2773,7 +2750,7 @@ class BigInteger * @internal Implemented per a request by Lluis Pamies i Juarez * @return \phpseclib\Math\BigInteger */ - function bitwise_and($x) + function bitwise_and(BigInteger $x) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -2793,7 +2770,7 @@ class BigInteger return $this->_normalize(new static($left & $right, 256)); } - $result = $this->copy(); + $result = clone $this; $length = min(count($x->value), count($this->value)); @@ -2814,7 +2791,7 @@ class BigInteger * @internal Implemented per a request by Lluis Pamies i Juarez * @return \phpseclib\Math\BigInteger */ - function bitwise_or($x) + function bitwise_or(BigInteger $x) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -2835,7 +2812,7 @@ class BigInteger } $length = max(count($this->value), count($x->value)); - $result = $this->copy(); + $result = clone $this; $result->value = array_pad($result->value, $length, 0); $x->value = array_pad($x->value, $length, 0); @@ -2854,7 +2831,7 @@ class BigInteger * @internal Implemented per a request by Lluis Pamies i Juarez * @return \phpseclib\Math\BigInteger */ - function bitwise_xor($x) + function bitwise_xor(BigInteger $x) { switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: @@ -2875,7 +2852,7 @@ class BigInteger } $length = max(count($this->value), count($x->value)); - $result = $this->copy(); + $result = clone $this; $result->value = array_pad($result->value, $length, 0); $x->value = array_pad($x->value, $length, 0); @@ -2898,6 +2875,9 @@ class BigInteger // calculuate "not" without regard to $this->precision // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) $temp = $this->toBytes(); + if ($temp == '') { + return ''; + } $pre_msb = decbin(ord($temp[0])); $temp = ~$temp; $msb = decbin(ord($temp[0])); @@ -2915,7 +2895,8 @@ class BigInteger // generate as many leading 1's as we need to. $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3); - $this->_base256_lshift($leading_ones, $current_bits); + + self::_base256_lshift($leading_ones, $current_bits); $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT); @@ -3033,7 +3014,7 @@ class BigInteger $shift%= $precision; if (!$shift) { - return $this->copy(); + return clone $this; } $left = $this->bitwise_leftShift($shift); @@ -3066,7 +3047,7 @@ class BigInteger * @return \phpseclib\Math\BigInteger * @access private */ - function _random_number_helper($size) + static function _random_number_helper($size) { if (class_exists('\phpseclib\Crypt\Random')) { $random = Random::string($size); @@ -3093,30 +3074,16 @@ class BigInteger * Returns a random number between $min and $max where $min and $max * can be defined using one of the two methods: * - * $min->random($max) - * $max->random($min) + * BigInteger::random($min, $max) + * BigInteger::random($max, $min) * * @param \phpseclib\Math\BigInteger $arg1 * @param \phpseclib\Math\BigInteger $arg2 * @return \phpseclib\Math\BigInteger * @access public - * @internal The API for creating random numbers used to be $a->random($min, $max), where $a was a BigInteger object. - * That method is still supported for BC purposes. */ - function random($arg1, $arg2 = false) + static function random(BigInteger $min, BigInteger $max) { - if ($arg1 === false) { - return false; - } - - if ($arg2 === false) { - $max = $arg1; - $min = $this; - } else { - $min = $arg1; - $max = $arg2; - } - $compare = $max->compare($min); if (!$compare) { @@ -3152,7 +3119,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 = $this->_random_number_helper($size); + $random = static::_random_number_helper($size); list($max_multiple) = $random_max->divide($max); $max_multiple = $max_multiple->multiply($max); @@ -3161,14 +3128,14 @@ class BigInteger $random = $random->subtract($max_multiple); $random_max = $random_max->subtract($max_multiple); $random = $random->bitwise_leftShift(8); - $random = $random->add($this->_random_number_helper(1)); + $random = $random->add(self::_random_number_helper(1)); $random_max = $random_max->bitwise_leftShift(8); list($max_multiple) = $random_max->divide($max); $max_multiple = $max_multiple->multiply($max); } list(, $random) = $random->divide($max); - return $this->_normalize($random->add($min)); + return $random->add($min); } /** @@ -3177,27 +3144,15 @@ class BigInteger * 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. * - * @param \phpseclib\Math\BigInteger $arg1 - * @param \phpseclib\Math\BigInteger $arg2 + * @param \phpseclib\Math\BigInteger $min + * @param \phpseclib\Math\BigInteger $max * @param int $timeout * @return Math_BigInteger|false * @access public * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}. */ - function randomPrime($arg1, $arg2 = false, $timeout = false) + static function randomPrime(BigInteger $min, BigInteger $max, $timeout = false) { - if ($arg1 === false) { - return false; - } - - if ($arg2 === false) { - $max = $arg1; - $min = $this; - } else { - $min = $arg1; - $max = $arg2; - } - $compare = $max->compare($min); if (!$compare) { @@ -3217,7 +3172,7 @@ class BigInteger $start = time(); - $x = $this->random($min, $max); + $x = self::random($min, $max); // gmp_nextprime() requires PHP 5 >= 5.2.0 per . if (MATH_BIGINTEGER_MODE == self::MODE_GMP && extension_loaded('gmp')) { @@ -3232,7 +3187,7 @@ class BigInteger $x = $x->subtract($one); } - return $x->randomPrime($min, $x); + return self::randomPrime($min, $x); } if ($x->equals($two)) { @@ -3245,11 +3200,11 @@ class BigInteger if ($min->equals($max)) { return false; } - $x = $min->copy(); + $x = clone $min; $x->_make_odd(); } - $initial_x = $x->copy(); + $initial_x = clone $x; while (true) { if ($timeout !== false && time() - $start > $timeout) { @@ -3263,7 +3218,7 @@ class BigInteger $x = $x->add($two); if ($x->compare($max) > 0) { - $x = $min->copy(); + $x = clone $min; if ($x->equals($two)) { return $x; } @@ -3401,18 +3356,18 @@ class BigInteger } else { $value = $this->value; foreach ($primes as $prime) { - list(, $r) = $this->_divide_digit($value, $prime); + list(, $r) = self::_divide_digit($value, $prime); if (!$r) { return count($value) == 1 && $value[0] == $prime; } } } - $n = $this->copy(); + $n = clone $this; $n_1 = $n->subtract($one); $n_2 = $n->subtract($two); - $r = $n_1->copy(); + $r = clone $n_1; $r_value = $r->value; // ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) { @@ -3436,7 +3391,7 @@ class BigInteger } for ($i = 0; $i < $t; ++$i) { - $a = $this->random($two, $n_2); + $a = self::random($two, $n_2); $y = $a->modPow($r, $n); if (!$y->equals($one) && !$y->equals($n_1)) { @@ -3583,7 +3538,7 @@ class BigInteger * @return \phpseclib\Math\BigInteger * @access private */ - function _trim($value) + static function _trim($value) { for ($i = count($value) - 1; $i >= 0; --$i) { if ($value[$i]) { @@ -3603,7 +3558,7 @@ class BigInteger * @return array * @access private */ - function _array_repeat($input, $multiplier) + static function _array_repeat($input, $multiplier) { return ($multiplier) ? array_fill(0, $multiplier, $input) : array(); } @@ -3618,7 +3573,7 @@ class BigInteger * @return string * @access private */ - function _base256_lshift(&$x, $shift) + static function _base256_lshift(&$x, $shift) { if ($shift == 0) { return; @@ -3647,7 +3602,7 @@ class BigInteger * @return string * @access private */ - function _base256_rshift(&$x, $shift) + static function _base256_rshift(&$x, $shift) { if ($shift == 0) { $x = ltrim($x, chr(0)); @@ -3688,7 +3643,7 @@ class BigInteger * @return string * @access private */ - function _int2bytes($x) + static function _int2bytes($x) { return ltrim(pack('N', $x), chr(0)); } @@ -3700,7 +3655,7 @@ class BigInteger * @return int * @access private */ - function _bytes2int($x) + static function _bytes2int($x) { $temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT)); return $temp['int']; @@ -3716,7 +3671,7 @@ class BigInteger * @param int $length * @return string */ - function _encodeASN1Length($length) + static function _encodeASN1Length($length) { if ($length <= 0x7F) { return chr($length); @@ -3739,7 +3694,7 @@ class BigInteger * @param int $y * @return int */ - function _safe_divide($x, $y) + static function _safe_divide($x, $y) { if (self::$base === 26) { return (int) ($x / $y); diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index d5179e00..59ce16e0 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1495,7 +1495,7 @@ class SSH2 $max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength $max = $max->subtract($one); - $x = $one->random($one, $max); + $x = BigInteger::random($one, $max); $e = $g->modPow($x, $prime); $eBytes = $e->toBytes(true); diff --git a/tests/Unit/Math/BigInteger/TestCase.php b/tests/Unit/Math/BigInteger/TestCase.php index f352e7ed..338987b2 100644 --- a/tests/Unit/Math/BigInteger/TestCase.php +++ b/tests/Unit/Math/BigInteger/TestCase.php @@ -217,6 +217,11 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase $z = $this->getInstance('11111111111111111111111', 16); $this->assertSame($z->toHex(), $x->bitwise_NOT()->toHex()); + + $a = $this->getInstance(0); + $a->bitwise_not(); + + $this->assertSame($a->toString(), '0'); } public function testBitwiseLeftShift() @@ -268,29 +273,13 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase $min = $this->getInstance(0); $max = $this->getInstance('18446744073709551616'); - $rand1 = $min->random($min, $max); + $rand1 = \phpseclib\Math\BigInteger::random($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); $this->assertTrue($rand1->compare($max) < 0); } - public function testRandomOneArgument() - { - $min = $this->getInstance(0); - $max = $this->getInstance('18446744073709551616'); - - $rand1 = $min->random($max); - $this->assertTrue($rand1->compare($min) > 0); - $this->assertTrue($rand1->compare($max) < 0); - - $rand2 = $max->random($min); - $this->assertTrue($rand2->compare($min) > 0); - $this->assertTrue($rand2->compare($max) < 0); - - $this->assertFalse($rand1->equals($rand2)); - } - /** * @group github279 */ @@ -326,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 = $one->random($one, $max); - $bobPrivate = $one->random($one, $max); + $alicePrivate = \phpseclib\Math\BigInteger::random($one, $max); + $bobPrivate = \phpseclib\Math\BigInteger::random($one, $max); var_dump($alicePrivate->toHex(), $bobPrivate->toHex()); */ @@ -364,6 +353,20 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase $num = $this->getInstance(50); $str = print_r($num, true); $this->assertContains('[value] => 0x32', $str); - return $str; + } + + public function testPrecision() + { + $a = $this->getInstance(51); + $this->assertSame($a->getPrecision(), -1); + $b = $a; + $c = clone $a; + $b->setPrecision(1); + $this->assertSame($a->getPrecision(), 1); + $this->assertSame("$a", '1'); + $this->assertSame($b->getPrecision(), 1); + $this->assertSame("$b", '1'); + $this->assertSame($c->getPrecision(), -1); + $this->assertSame("$c", '51'); } }