diff --git a/build/psalm.xml b/build/psalm.xml index 09f14902..b521dbfe 100644 --- a/build/psalm.xml +++ b/build/psalm.xml @@ -7,17 +7,14 @@ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" findUnusedPsalmSuppress="true" sealAllMethods="true" + errorBaseline="psalm_baseline.xml" > - - - - - - - - - + + + + + @@ -31,4 +28,4 @@ - + \ No newline at end of file diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index 68cdec6b..564c8992 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -30,6 +30,7 @@ namespace phpseclib3\Math; use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Math\BigInteger\Engines\Engine; /** * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 @@ -44,21 +45,14 @@ class BigInteger /** * Main Engine * - * @var string + * @var class-string */ private static $mainEngine; - /** - * Modular Exponentiation Engine - * - * @var string - */ - private static $modexpEngine; - /** * Selected Engines * - * @var array + * @var list */ private static $engines; @@ -93,9 +87,10 @@ class BigInteger * Throws an exception if the type is invalid * * @param string $main - * @param array $modexps optional + * @param list $modexps optional + * @return void */ - public static function setEngine($main, $modexps = ['DefaultEngine']) + public static function setEngine($main, array $modexps = ['DefaultEngine']) { self::$engines = []; @@ -106,6 +101,7 @@ class BigInteger if (!$fqmain::isValidEngine()) { throw new BadConfigurationException("$main is not setup correctly on this system"); } + /** @var class-string $fqmain */ self::$mainEngine = $fqmain; if (!in_array('Default', $modexps)) { @@ -126,8 +122,6 @@ class BigInteger throw new BadConfigurationException("No valid modular exponentiation engine found for $main"); } - self::$modexpEngine = $modexp; - self::$engines = [$main, $modexp]; } @@ -173,7 +167,6 @@ class BigInteger * * @param string|int|BigInteger\Engines\Engine $x Base-10 number or base-$base number if $base set. * @param int $base - * @return BigInteger */ public function __construct($x = 0, $base = 10) { @@ -418,7 +411,7 @@ class BigInteger * __serialize() / __unserialize() were introduced in PHP 7.4: * https://wiki.php.net/rfc/custom_object_serialization * - * @return string + * @return array */ public function __sleep() { diff --git a/phpseclib/Math/BigInteger/Engines/BCMath.php b/phpseclib/Math/BigInteger/Engines/BCMath.php index 01e1c1c0..5d6e9507 100644 --- a/phpseclib/Math/BigInteger/Engines/BCMath.php +++ b/phpseclib/Math/BigInteger/Engines/BCMath.php @@ -44,48 +44,6 @@ class BCMath extends Engine */ const ENGINE_DIR = 'BCMath'; - /** - * Modular Exponentiation Engine - * - * @var string - */ - protected static $modexpEngine; - - /** - * Engine Validity Flag - * - * @var bool - */ - protected static $isValidEngine; - - /** - * BigInteger(0) - * - * @var \phpseclib3\Math\BigInteger\Engines\BCMath - */ - protected static $zero; - - /** - * BigInteger(1) - * - * @var \phpseclib3\Math\BigInteger\Engines\BCMath - */ - protected static $one; - - /** - * BigInteger(2) - * - * @var \phpseclib3\Math\BigInteger\Engines\BCMath - */ - protected static $two; - - /** - * Primes > 2 and < 1000 - * - * @var array - */ - protected static $primes; - /** * Test for engine validity * @@ -102,15 +60,14 @@ class BCMath extends Engine * * @param mixed $x integer Base-10 number or base-$base number if $base set. * @param int $base - * @return \phpseclib3\Math\BigInteger\Engines\BCMath * @see parent::__construct() */ public function __construct($x = 0, $base = 10) { - if (!isset(self::$isValidEngine)) { - self::$isValidEngine = self::isValidEngine(); + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = self::isValidEngine(); } - if (!self::$isValidEngine) { + if (!static::$isValidEngine[static::class]) { throw new BadConfigurationException('BCMath is not setup correctly on this system'); } @@ -258,7 +215,7 @@ class BCMath extends Engine * and the divisor (basically, the "common residue" is the first positive modulo). * * @param BCMath $y - * @return BCMath + * @return array{static, static} */ public function divide(BCMath $y) { @@ -297,7 +254,7 @@ class BCMath extends Engine * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. * * @param BCMath $n - * @return BCMath + * @return array{gcd: static, x: static, y: static} */ public function extendedGCD(BCMath $n) { @@ -503,7 +460,7 @@ class BCMath extends Engine protected function powModInner(BCMath $e, BCMath $n) { try { - $class = self::$modexpEngine; + $class = static::$modexpEngine[static::class]; return $class::powModHelper($this, $e, $n, static::class); } catch (\Exception $err) { return BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class); @@ -595,7 +552,7 @@ class BCMath extends Engine $value = $this->value; - foreach (self::$primes as $prime) { + foreach (self::PRIMES as $prime) { $r = bcmod($this->value, $prime); if ($r == '0') { return $this->value == $prime; @@ -618,7 +575,7 @@ class BCMath extends Engine { $r_value = &$r->value; $s = 0; - // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals(static::$one) check earlier + // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals(static::$one[static::class]) check earlier while ($r_value[strlen($r_value) - 1] % 2 == 0) { $r_value = bcdiv($r_value, '2', 0); ++$s; @@ -685,13 +642,13 @@ class BCMath extends Engine protected static function setBitmask($bits) { $temp = parent::setBitmask($bits); - return $temp->add(static::$one); + return $temp->add(static::$one[static::class]); } /** * Is Odd? * - * @return boolean + * @return bool */ public function isOdd() { @@ -701,7 +658,7 @@ class BCMath extends Engine /** * Tests if a bit is set * - * @return boolean + * @return bool */ public function testBit($x) { diff --git a/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php b/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php index d65e6d94..09d4fa79 100644 --- a/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php +++ b/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php @@ -78,7 +78,7 @@ abstract class EvalBarrett extends Base $u = "'$u'"; $m1 = "'$m1'"; - $code .= ' + $code = ' $lsd = substr($n, -' . $cutoff . '); $msd = substr($n, 0, -' . $cutoff . '); diff --git a/phpseclib/Math/BigInteger/Engines/Engine.php b/phpseclib/Math/BigInteger/Engines/Engine.php index edcc5ecb..b4769696 100644 --- a/phpseclib/Math/BigInteger/Engines/Engine.php +++ b/phpseclib/Math/BigInteger/Engines/Engine.php @@ -30,10 +30,59 @@ use phpseclib3\Math\BigInteger; */ abstract class Engine { + /* final protected */ const PRIMES = [ + 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, + 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, + 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, + 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, + 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, + 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, + 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, + 953, 967, 971, 977, 983, 991, 997, + ]; + + /** + * BigInteger(0) + * + * @var array, static> + */ + protected static $zero = []; + + /** + * BigInteger(1) + * + * @var array, static> + */ + protected static $one = []; + + /** + * BigInteger(2) + * + * @var array, static> + */ + protected static $two = []; + + /** + * Modular Exponentiation Engine + * + * @var array, class-string> + */ + protected static $modexpEngine; + + /** + * Engine Validity Flag + * + * @var array, bool> + */ + protected static $isValidEngine; + /** * Holds the BigInteger's value * - * @var mixed + * @var \GMP|string|array|int */ protected $value; @@ -48,6 +97,7 @@ abstract class Engine * Precision * * @see static::setPrecision() + * @var int */ protected $precision = -1; @@ -55,6 +105,7 @@ abstract class Engine * Precision Bitmask * * @see static::setPrecision() + * @var static|false */ protected $bitmask = false; @@ -77,28 +128,16 @@ abstract class Engine /** * Default constructor * - * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int|numeric-string $x integer Base-10 number or base-$base number if $base set. * @param int $base */ - public function __construct($x, $base) + public function __construct($x = 0, $base = 10) { - if (!isset(static::$primes)) { - static::$primes = [ - 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, - 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, - 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, - 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, - 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, - 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, - 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, - 953, 967, 971, 977, 983, 991, 997 - ]; - static::$zero = new static(0); - static::$one = new static(1); - static::$two = new static(2); + if (!array_key_exists(static::class, static::$zero)) { + static::$zero[static::class] = null; // Placeholder to prevent infinite loop. + static::$zero[static::class] = new static(0); + static::$one[static::class] = new static(1); + static::$two[static::class] = new static(2); } // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 @@ -118,7 +157,7 @@ abstract class Engine $this->is_negative = false; } - static::initialize($base); + $this->initialize($base); if ($this->is_negative) { $temp = $this->add(new static('-1')); @@ -141,7 +180,7 @@ abstract class Engine } $this->value = $x; - static::initialize($base); + $this->initialize($base); if ($is_negative) { $temp = $this->add(new static('-1')); @@ -157,7 +196,7 @@ abstract class Engine if (!strlen($this->value) || $this->value == '-') { $this->value = '0'; } - static::initialize($base); + $this->initialize($base); break; case -2: case 2: @@ -185,7 +224,7 @@ abstract class Engine * * Throws an exception if the type is invalid * - * @param string $engine + * @param class-string $engine */ public static function setModExpEngine($engine) { @@ -196,7 +235,7 @@ abstract class Engine if (!$fqengine::isValidEngine()) { throw new BadConfigurationException("$engine is not setup correctly on this system"); } - static::$modexpEngine = $fqengine; + static::$modexpEngine[static::class] = $fqengine; } /** @@ -268,15 +307,15 @@ abstract class Engine * * {@internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.} * - * @param \phpseclib3\Math\BigInteger\Engines\Engine $n - * @return \phpseclib3\Math\BigInteger\Engines\Engine|false + * @param Engine $n + * @return static|false */ protected function modInverseHelper(Engine $n) { // $x mod -$n == $x mod $n. $n = $n->abs(); - if ($this->compare(static::$zero) < 0) { + if ($this->compare(static::$zero[static::class]) < 0) { $temp = $this->abs(); $temp = $temp->modInverse($n); return $this->normalize($n->subtract($temp)); @@ -284,17 +323,17 @@ abstract class Engine extract($this->extendedGCD($n)); /** - * @var BigInteger $gcd - * @var BigInteger $x + * @var Engine $gcd + * @var Engine $x */ - if (!$gcd->equals(static::$one)) { + if (!$gcd->equals(static::$one[static::class])) { return false; } - $x = $x->compare(static::$zero) < 0 ? $x->add($n) : $x; + $x = $x->compare(static::$zero[static::class]) < 0 ? $x->add($n) : $x; - return $this->compare(static::$zero) < 0 ? $this->normalize($n->subtract($x)) : $this->normalize($x); + return $this->compare(static::$zero[static::class]) < 0 ? $this->normalize($n->subtract($x)) : $this->normalize($x); } /** @@ -302,7 +341,7 @@ abstract class Engine * * Will be called, automatically, when serialize() is called on a BigInteger object. * - * @return string + * @return array */ public function __sleep() { @@ -318,6 +357,8 @@ abstract class Engine * Serialize * * Will be called, automatically, when unserialize() is called on a BigInteger object. + * + * @return void */ public function __wakeup() { @@ -344,6 +385,8 @@ abstract class Engine * __debugInfo() magic method * * Will be called, automatically, when print_r() or var_dump() are called + * + * @return array */ public function __debugInfo() { @@ -390,7 +433,7 @@ abstract class Engine /** * Set Bitmask - * @return Engine + * @return static * @param int $bits * @see self::setPrecision() */ @@ -410,7 +453,7 @@ abstract class Engine // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) $temp = $this->toBytes(); if ($temp == '') { - return $this->normalize(static::$zero); + return $this->normalize(static::$zero[static::class]); } $pre_msb = decbin(ord($temp[0])); $temp = ~$temp; @@ -444,7 +487,7 @@ abstract class Engine * * @param string $x * @param int $shift - * @return string + * @return void */ protected static function base256_lshift(&$x, $shift) { @@ -471,7 +514,7 @@ abstract class Engine * Instead of the top x bits being dropped they're appended to the shifted bit string. * * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\Engine + * @return Engine */ public function bitwise_leftRotate($shift) { @@ -515,7 +558,7 @@ abstract class Engine * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. * * @param int $shift - * @return \phpseclib3\Math\BigInteger\Engines\Engine + * @return Engine */ public function bitwise_rightRotate($shift) { @@ -526,7 +569,7 @@ abstract class Engine * Returns the smallest and largest n-bit number * * @param int $bits - * @return \phpseclib3\Math\BigInteger\Engines\Engine[] + * @return array{min: static, max: static} */ public static function minMaxBits($bits) { @@ -571,7 +614,7 @@ abstract class Engine * * @param Engine $e * @param Engine $n - * @return bool|Engine + * @return static|false */ protected function powModOuter(Engine $e, Engine $n) { @@ -599,11 +642,12 @@ abstract class Engine * however, this function performs a modular reduction after every multiplication and squaring operation. * As such, this function has the same preconditions that the reductions being used do. * - * @param \phpseclib3\Math\BigInteger\Engines\Engine $x - * @param \phpseclib3\Math\BigInteger\Engines\Engine $e - * @param \phpseclib3\Math\BigInteger\Engines\Engine $n - * @param string $class - * @return \phpseclib3\Math\BigInteger\Engines\Engine + * @template T of Engine + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @param class-string $class + * @return T */ protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) { @@ -674,7 +718,7 @@ abstract class Engine * Bit length is equal to $size * * @param int $size - * @return \phpseclib3\Math\BigInteger\Engines\Engine + * @return Engine */ public static function random($size) { @@ -692,14 +736,14 @@ abstract class Engine * Bit length is equal to $size * * @param int $size - * @return \phpseclib3\Math\BigInteger\Engines\Engine + * @return Engine */ public static function randomPrime($size) { extract(static::minMaxBits($size)); /** - * @var BigInteger $min - * @var BigInteger $max + * @var static $min + * @var static $max */ return static::randomRangePrime($min, $max); } @@ -709,7 +753,7 @@ abstract class Engine * * @param Engine $min * @param Engine $max - * @return bool|Engine + * @return static|false */ protected static function randomRangePrimeOuter(Engine $min, Engine $max) { @@ -755,11 +799,11 @@ abstract class Engine $min = $temp; } - if (!isset(static::$one)) { - static::$one = new static(1); + if (!isset(static::$one[static::class])) { + static::$one[static::class] = new static(1); } - $max = $max->subtract($min->subtract(static::$one)); + $max = $max->subtract($min->subtract(static::$one[static::class])); $size = strlen(ltrim($max->toBytes(), chr(0))); @@ -804,12 +848,12 @@ abstract class Engine * @param Engine $x * @param Engine $min * @param Engine $max - * @return bool|Engine + * @return static|false */ protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) { - if (!isset(static::$two)) { - static::$two = new static('2'); + if (!isset(static::$two[static::class])) { + static::$two[static::class] = new static('2'); } $x->make_odd(); @@ -829,11 +873,11 @@ abstract class Engine return $x; } - $x = $x->add(static::$two); + $x = $x->add(static::$two[static::class]); if ($x->compare($max) > 0) { $x = clone $min; - if ($x->equals(static::$two)) { + if ($x->equals(static::$two[static::class])) { return $x; } $x->make_odd(); @@ -856,7 +900,7 @@ abstract class Engine // see HAC 4.49 "Note (controlling the error probability)" // @codingStandardsIgnoreStart - if ($length >= 163) { $t = 2; } // floor(1300 / 8) + if ($length >= 163) $t = 2; // floor(1300 / 8) else if ($length >= 106) { $t = 3; } // floor( 850 / 8) else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) @@ -889,20 +933,20 @@ abstract class Engine } $n = clone $this; - $n_1 = $n->subtract(static::$one); - $n_2 = $n->subtract(static::$two); + $n_1 = $n->subtract(static::$one[static::class]); + $n_2 = $n->subtract(static::$two[static::class]); $r = clone $n_1; $s = static::scan1divide($r); for ($i = 0; $i < $t; ++$i) { - $a = static::randomRange(static::$two, $n_2); + $a = static::randomRange(static::$two[static::class], $n_2); $y = $a->modPow($r, $n); - if (!$y->equals(static::$one) && !$y->equals($n_1)) { + if (!$y->equals(static::$one[static::class]) && !$y->equals($n_1)) { for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { - $y = $y->modPow(static::$two, $n); - if ($y->equals(static::$one)) { + $y = $y->modPow(static::$two[static::class], $n); + if ($y->equals(static::$one[static::class])) { return false; } } @@ -938,18 +982,18 @@ abstract class Engine * Performs a few preliminary checks on root * * @param int $n - * @return \phpseclib3\Math\BigInteger\Engines\Engine + * @return Engine */ protected function rootHelper($n) { if ($n < 1) { - return clone static::$zero; + return clone static::$zero[static::class]; } // we want positive exponents - if ($this->compare(static::$one) < 0) { - return clone static::$zero; + if ($this->compare(static::$one[static::class]) < 0) { + return clone static::$zero[static::class]; } // we want positive numbers - if ($this->compare(static::$two) < 0) { - return clone static::$one; + if ($this->compare(static::$two[static::class]) < 0) { + return clone static::$one[static::class]; } // n-th root of 1 or 2 is 1 return $this->rootInner($n); @@ -963,17 +1007,17 @@ abstract class Engine * {@internal This function is based off of {@link http://mathforum.org/library/drmath/view/52605.html this page} and {@link http://stackoverflow.com/questions/11242920/calculating-nth-root-with-bcmath-in-php this stackoverflow question}.} * * @param int $n - * @return \phpseclib3\Math\BigInteger\Engines\Engine + * @return Engine */ protected function rootInner($n) { $n = new static($n); // g is our guess number - $g = static::$two; + $g = static::$two[static::class]; // while (g^n < num) g=g*2 while ($g->pow($n)->compare($this) < 0) { - $g = $g->multiply(static::$two); + $g = $g->multiply(static::$two[static::class]); } // if (g^n==num) num is a power of 2, we're lucky, end of job // == 0 bccomp(bcpow($g, $n), $n->value)==0 @@ -984,15 +1028,15 @@ abstract class Engine // if we're here num wasn't a power of 2 :( $og = $g; // og means original guess and here is our upper bound - $g = $g->divide(static::$two)[0]; // g is set to be our lower bound - $step = $og->subtract($g)->divide(static::$two)[0]; // step is the half of upper bound - lower bound + $g = $g->divide(static::$two[static::class])[0]; // g is set to be our lower bound + $step = $og->subtract($g)->divide(static::$two[static::class])[0]; // step is the half of upper bound - lower bound $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval // while step>1 - while ($step->compare(static::$one) == 1) { + while ($step->compare(static::$one[static::class]) == 1) { $guess = $g->pow($n); - $step = $step->divide(static::$two)[0]; + $step = $step->divide(static::$two[static::class])[0]; $comp = $guess->compare($this); // compare our guess with real number switch ($comp) { case -1: // if guess is lower we add the new step @@ -1076,9 +1120,9 @@ abstract class Engine { $class = static::class; - $fqengine = !method_exists(static::$modexpEngine, 'reduce') ? + $fqengine = !method_exists(static::$modexpEngine[static::class], 'reduce') ? '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\DefaultEngine' : - static::$modexpEngine; + static::$modexpEngine[static::class]; if (method_exists($fqengine, 'generateCustomReduction')) { $func = $fqengine::generateCustomReduction($this, static::class); return eval('return function(' . static::class . ' $x) use ($func, $class) { @@ -1099,10 +1143,9 @@ abstract class Engine * Calculates the greatest common divisor and Bezout's identity. * * @param Engine $n - * @param Engine $stop (optional) - * @return Engine + * @return array{gcd: Engine, x: Engine, y: Engine} */ - protected function extendedGCDHelper(Engine $n, Engine $stop = null) + protected function extendedGCDHelper(Engine $n) { $u = clone $this; $v = clone $n; @@ -1144,7 +1187,7 @@ abstract class Engine * Splits BigInteger's into chunks of $split bits * * @param int $split - * @return \phpseclib3\Math\BigInteger\Engines\Engine[] + * @return Engine[] */ public function bitwise_split($split) { @@ -1152,12 +1195,12 @@ abstract class Engine throw new \RuntimeException('Offset must be greater than 1'); } - $mask = static::$one->bitwise_leftShift($split)->subtract(static::$one); + $mask = static::$one[static::class]->bitwise_leftShift($split)->subtract(static::$one[static::class]); $num = clone $this; $vals = []; - while (!$num->equals(static::$zero)) { + while (!$num->equals(static::$zero[static::class])) { $vals[] = $num->bitwise_and($mask); $num = $num->bitwise_rightShift($split); } diff --git a/phpseclib/Math/BigInteger/Engines/GMP.php b/phpseclib/Math/BigInteger/Engines/GMP.php index 0e4f37f4..e6cc3751 100644 --- a/phpseclib/Math/BigInteger/Engines/GMP.php +++ b/phpseclib/Math/BigInteger/Engines/GMP.php @@ -43,50 +43,6 @@ class GMP extends Engine */ const ENGINE_DIR = 'GMP'; - /** - * Modular Exponentiation Engine - * - * @var string - */ - protected static $modexpEngine; - - /** - * Engine Validity Flag - * - * @var bool - */ - protected static $isValidEngine; - - /** - * BigInteger(0) - * - * @var \phpseclib3\Math\BigInteger\Engines\GMP - */ - protected static $zero; - - /** - * BigInteger(1) - * - * @var \phpseclib3\Math\BigInteger\Engines\GMP - */ - protected static $one; - - /** - * BigInteger(2) - * - * @var \phpseclib3\Math\BigInteger\Engines\GMP - */ - protected static $two; - - /** - * Primes > 2 and < 1000 - * - * Unused for GMP Engine - * - * @var mixed - */ - protected static $primes; - /** * Test for engine validity * @@ -103,15 +59,14 @@ class GMP extends Engine * * @param mixed $x integer Base-10 number or base-$base number if $base set. * @param int $base - * @return \phpseclib3\Math\BigInteger\Engines\GMP * @see parent::__construct() */ public function __construct($x = 0, $base = 10) { - if (!isset(self::$isValidEngine)) { - self::$isValidEngine = self::isValidEngine(); + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = self::isValidEngine(); } - if (!self::$isValidEngine) { + if (!static::$isValidEngine[static::class]) { throw new BadConfigurationException('GMP is not setup correctly on this system'); } @@ -259,7 +214,7 @@ class GMP extends Engine * and the divisor (basically, the "common residue" is the first positive modulo). * * @param GMP $y - * @return GMP + * @return array{GMP, GMP} */ public function divide(GMP $y) { @@ -497,7 +452,7 @@ class GMP extends Engine */ protected function powModInner(GMP $e, GMP $n) { - $class = self::$modexpEngine; + $class = static::$modexpEngine[static::class]; return $class::powModHelper($this, $e, $n); } diff --git a/phpseclib/Math/BigInteger/Engines/PHP.php b/phpseclib/Math/BigInteger/Engines/PHP.php index 09560d1b..2bb0f505 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP.php +++ b/phpseclib/Math/BigInteger/Engines/PHP.php @@ -81,10 +81,10 @@ abstract class PHP extends Engine */ public function __construct($x = 0, $base = 10) { - if (!isset(static::$isValidEngine)) { - static::$isValidEngine = static::isValidEngine(); + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = static::isValidEngine(); } - if (!static::$isValidEngine) { + if (!static::$isValidEngine[static::class]) { throw new BadConfigurationException(static::class . ' is not setup correctly on this system'); } @@ -530,8 +530,7 @@ abstract class PHP extends Engine * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder * and the divisor (basically, the "common residue" is the first positive modulo). * - * @param \phpseclib3\Math\BigInteger\engines\PHP $y - * @return array + * @return array{static, static} * @internal This function is based off of * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. */ @@ -561,7 +560,7 @@ abstract class PHP extends Engine $temp = new static(); $temp->value = [1]; $temp->is_negative = $x_sign != $y_sign; - return [$this->normalize($temp), $this->normalize(static::$zero)]; + return [$this->normalize($temp), $this->normalize(static::$zero[static::class])]; } if ($diff < 0) { @@ -569,7 +568,7 @@ abstract class PHP extends Engine if ($x_sign) { $x = $y->subtract($x); } - return [$this->normalize(static::$zero), $this->normalize($x)]; + return [$this->normalize(static::$zero[static::class]), $this->normalize($x)]; } // normalize $x and $y as described in HAC 14.23 / 14.24 @@ -658,7 +657,7 @@ abstract class PHP extends Engine $x = $x->subtract($temp); - if ($x->compare(static::$zero) < 0) { + if ($x->compare(static::$zero[static::class]) < 0) { $temp_value = array_merge($adjust, $y_value); $x = $x->add($temp); @@ -724,14 +723,15 @@ abstract class PHP extends Engine } // static::BASE === 31 + /** @var int */ return ($x - ($x % $y)) / $y; } - /* + /** * Convert an array / boolean to a PHP BigInteger object * * @param array $arr - * @return \phpseclib3\Math\BigInteger\Engines\PHP + * @return static */ protected function convertToObj(array $arr) { @@ -748,7 +748,7 @@ abstract class PHP extends Engine * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision * * @param PHP $result - * @return PHP + * @return static */ protected function normalize(PHP $result) { @@ -776,7 +776,7 @@ abstract class PHP extends Engine return $result; } - /* + /** * Compares two numbers. * * @param array $x_value @@ -829,8 +829,8 @@ abstract class PHP extends Engine * * Removes leading zeros * - * @param array $value - * @return PHP + * @param list $value + * @return list */ protected static function trim(array $value) { @@ -983,7 +983,7 @@ abstract class PHP extends Engine protected function powModInner(PHP $e, PHP $n) { try { - $class = static::$modexpEngine; + $class = static::$modexpEngine[static::class]; return $class::powModHelper($this, $e, $n, static::class); } catch (\Exception $err) { return PHP\DefaultEngine::powModHelper($this, $e, $n, static::class); @@ -993,8 +993,8 @@ abstract class PHP extends Engine /** * Performs squaring * - * @param array $x - * @return array + * @param list $x + * @return list */ protected static function square(array $x) { @@ -1109,7 +1109,7 @@ abstract class PHP extends Engine } $value = $this->value; - foreach (static::$primes as $prime) { + foreach (static::PRIMES as $prime) { list(, $r) = self::divide_digit($value, $prime); if (!$r) { return count($value) == 1 && $value[0] == $prime; @@ -1152,14 +1152,14 @@ abstract class PHP extends Engine */ protected function powHelper(PHP $n) { - if ($n->compare(static::$zero) == 0) { + if ($n->compare(static::$zero[static::class]) == 0) { return new static(1); } // n^0 = 1 $temp = clone $this; - while (!$n->equals(static::$one)) { + while (!$n->equals(static::$one[static::class])) { $temp = $temp->multiply($this); - $n = $n->subtract(static::$one); + $n = $n->subtract(static::$one[static::class]); } return $temp; @@ -1168,7 +1168,7 @@ abstract class PHP extends Engine /** * Is Odd? * - * @return boolean + * @return bool */ public function isOdd() { @@ -1178,11 +1178,11 @@ abstract class PHP extends Engine /** * Tests if a bit is set * - * @return boolean + * @return bool */ public function testBit($x) { - $digit = floor($x / static::BASE); + $digit = (int) floor($x / static::BASE); $bit = $x % static::BASE; if (!isset($this->value[$digit])) { @@ -1195,7 +1195,7 @@ abstract class PHP extends Engine /** * Is Negative? * - * @return boolean + * @return bool */ public function isNegative() { @@ -1207,7 +1207,7 @@ abstract class PHP extends Engine * * Given $k, returns -$k * - * @return BigInteger + * @return static */ public function negate() { @@ -1223,7 +1223,7 @@ abstract class PHP extends Engine * Splits BigInteger's into chunks of $split bits * * @param int $split - * @return \phpseclib3\Math\BigInteger\Engines\PHP[] + * @return list */ public function bitwise_split($split) { @@ -1290,7 +1290,7 @@ abstract class PHP extends Engine * Bitwise Split where $split < static::BASE * * @param int $split - * @return \phpseclib3\Math\BigInteger\Engines\PHP[] + * @return list */ private function bitwise_small_split($split) { diff --git a/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php b/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php index 58334cc8..865beb6c 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php +++ b/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php @@ -41,11 +41,12 @@ abstract class Montgomery extends Base /** * Performs modular exponentiation. * - * @param \phpseclib3\Math\BigInteger\Engines\Engine $x - * @param \phpseclib3\Math\BigInteger\Engines\Engine $e - * @param \phpseclib3\Math\BigInteger\Engines\Engine $n - * @param string $class - * @return \phpseclib3\Math\BigInteger\Engines\Engine + * @template T of Engine + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @param class-string $class + * @return T */ protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) { diff --git a/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php b/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php index e45a261e..e5712b0e 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php +++ b/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php @@ -469,7 +469,7 @@ abstract class EvalBarrett extends Base private static function float2string($num) { if (!is_float($num)) { - return $num; + return (string) $num; } if ($num < 0) { diff --git a/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php b/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php index 54fd2bba..ce190e76 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php +++ b/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php @@ -15,6 +15,8 @@ namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; +use phpseclib3\Math\BigInteger\Engines\PHP; + /** * PHP Montgomery Modular Exponentiation Engine with interleaved multiplication * @@ -36,7 +38,7 @@ abstract class MontgomeryMult extends Montgomery * @param array $x * @param array $y * @param array $m - * @param string $class + * @param class-string $class * @return array */ public static function multiplyReduce(array $x, array $y, array $m, $class) diff --git a/phpseclib/Math/BigInteger/Engines/PHP32.php b/phpseclib/Math/BigInteger/Engines/PHP32.php index 169bd6d0..9f233c8b 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP32.php +++ b/phpseclib/Math/BigInteger/Engines/PHP32.php @@ -44,49 +44,6 @@ class PHP32 extends PHP */ const MAX10LEN = 7; const MAX_DIGIT2 = 4503599627370496; - /**#@-*/ - - /** - * Modular Exponentiation Engine - * - * @var string - */ - protected static $modexpEngine; - - /** - * Engine Validity Flag - * - * @var bool - */ - protected static $isValidEngine; - - /** - * Primes > 2 and < 1000 - * - * @var array - */ - protected static $primes; - - /** - * BigInteger(0) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP32 - */ - protected static $zero; - - /** - * BigInteger(1) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP32 - */ - protected static $one; - - /** - * BigInteger(2) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP32 - */ - protected static $two; /** * Initialize a PHP32 BigInteger Engine instance @@ -197,7 +154,7 @@ class PHP32 extends PHP * and the divisor (basically, the "common residue" is the first positive modulo). * * @param PHP32 $y - * @return PHP32 + * @return array{PHP32, PHP32} */ public function divide(PHP32 $y) { diff --git a/phpseclib/Math/BigInteger/Engines/PHP64.php b/phpseclib/Math/BigInteger/Engines/PHP64.php index 35b07fb7..a573e479 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP64.php +++ b/phpseclib/Math/BigInteger/Engines/PHP64.php @@ -44,49 +44,6 @@ class PHP64 extends PHP */ const MAX10LEN = 9; const MAX_DIGIT2 = 4611686018427387904; - /**#@-*/ - - /** - * Modular Exponentiation Engine - * - * @var string - */ - protected static $modexpEngine; - - /** - * Engine Validity Flag - * - * @var bool - */ - protected static $isValidEngine; - - /** - * Primes > 2 and < 1000 - * - * @var array - */ - protected static $primes; - - /** - * BigInteger(0) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP64 - */ - protected static $zero; - - /** - * BigInteger(1) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP64 - */ - protected static $one; - - /** - * BigInteger(2) - * - * @var \phpseclib3\Math\BigInteger\Engines\PHP64 - */ - protected static $two; /** * Initialize a PHP64 BigInteger Engine instance @@ -201,7 +158,7 @@ class PHP64 extends PHP * and the divisor (basically, the "common residue" is the first positive modulo). * * @param PHP64 $y - * @return PHP64 + * @return array{PHP64, PHP64} */ public function divide(PHP64 $y) { @@ -334,7 +291,7 @@ class PHP64 extends PHP * * @param PHP64 $e * @param PHP64 $n - * @return PHP64 + * @return PHP64|false */ public function powMod(PHP64 $e, PHP64 $n) { diff --git a/phpseclib/Math/BinaryField.php b/phpseclib/Math/BinaryField.php index 5c9d57d1..58f5c148 100644 --- a/phpseclib/Math/BinaryField.php +++ b/phpseclib/Math/BinaryField.php @@ -43,6 +43,9 @@ class BinaryField extends FiniteField */ protected $instanceID; + /** @var BigInteger */ + private $randomMax; + /** * Default constructor */ @@ -113,7 +116,7 @@ class BinaryField extends FiniteField * Returns an instance of a dynamically generated PrimeFieldInteger class * * @param string $num - * @return object + * @return Integer */ public function newInteger($num) { @@ -123,7 +126,7 @@ class BinaryField extends FiniteField /** * Returns an integer on the finite field between one and the prime modulo * - * @return object + * @return Integer */ public function randomInteger() { @@ -138,7 +141,7 @@ class BinaryField extends FiniteField /** * Returns the length of the modulo in bytes * - * @return integer + * @return int */ public function getLengthInBytes() { @@ -148,7 +151,7 @@ class BinaryField extends FiniteField /** * Returns the length of the modulo in bits * - * @return integer + * @return int */ public function getLength() { diff --git a/phpseclib/Math/BinaryField/Integer.php b/phpseclib/Math/BinaryField/Integer.php index 0df47a57..7816e625 100644 --- a/phpseclib/Math/BinaryField/Integer.php +++ b/phpseclib/Math/BinaryField/Integer.php @@ -53,7 +53,7 @@ class Integer extends Base /** * Holds the PrimeField's modulo * - * @var string[] + * @var array */ protected static $modulo; @@ -80,6 +80,8 @@ class Integer extends Base /** * Set the modulo for a given instance + * @param int $instanceID + * @param string $modulo */ public static function setModulo($instanceID, $modulo) { @@ -450,7 +452,7 @@ class Integer extends Base /** * Returns the modulo * - * @return integer + * @return string */ public static function getModulo($instanceID) { diff --git a/phpseclib/Math/PrimeField.php b/phpseclib/Math/PrimeField.php index d38991e0..48a8b619 100644 --- a/phpseclib/Math/PrimeField.php +++ b/phpseclib/Math/PrimeField.php @@ -61,8 +61,10 @@ class PrimeField extends FiniteField /** * Use a custom defined modular reduction function + * + * @return void */ - public function setReduction(callable $func) + public function setReduction(\Closure $func) { $this->reduce = $func->bindTo($this, $this); } @@ -70,7 +72,7 @@ class PrimeField extends FiniteField /** * Returns an instance of a dynamically generated PrimeFieldInteger class * - * @return object + * @return Integer */ public function newInteger(BigInteger $num) { @@ -80,7 +82,7 @@ class PrimeField extends FiniteField /** * Returns an integer on the finite field between one and the prime modulo * - * @return object + * @return Integer */ public function randomInteger() { @@ -95,7 +97,7 @@ class PrimeField extends FiniteField /** * Returns the length of the modulo in bytes * - * @return integer + * @return int */ public function getLengthInBytes() { @@ -105,7 +107,7 @@ class PrimeField extends FiniteField /** * Returns the length of the modulo in bits * - * @return integer + * @return int */ public function getLength() { diff --git a/phpseclib/Math/PrimeField/Integer.php b/phpseclib/Math/PrimeField/Integer.php index 71024882..5e911207 100644 --- a/phpseclib/Math/PrimeField/Integer.php +++ b/phpseclib/Math/PrimeField/Integer.php @@ -30,7 +30,7 @@ class Integer extends Base /** * Holds the PrimeField's value * - * @var \phpseclib3\Math\BigInteger + * @var BigInteger */ protected $value; @@ -44,32 +44,34 @@ class Integer extends Base /** * Holds the PrimeField's modulo * - * @var \phpseclib3\Math\BigInteger + * @var array */ protected static $modulo; /** * Holds a pre-generated function to perform modulo reductions * - * @var Callable + * @var array */ protected static $reduce; /** * Zero * - * @var \phpseclib3\Math\BigInteger + * @var BigInteger */ protected static $zero; /** * Default constructor + * + * @param int $instanceID */ public function __construct($instanceID, BigInteger $num = null) { $this->instanceID = $instanceID; if (!isset($num)) { - $this->value = clone static::$zero; + $this->value = clone static::$zero[static::class]; } else { $reduce = static::$reduce[$instanceID]; $this->value = $reduce($num); @@ -78,6 +80,9 @@ class Integer extends Base /** * Set the modulo for a given instance + * + * @param int $instanceID + * @return void */ public static function setModulo($instanceID, BigInteger $modulo) { @@ -86,12 +91,15 @@ class Integer extends Base /** * Set the modulo for a given instance + * + * @param int $instanceID + * @return void */ public static function setRecurringModuloFunction($instanceID, callable $function) { static::$reduce[$instanceID] = $function; - if (!isset(static::$zero)) { - static::$zero = new BigInteger(); + if (!isset(static::$zero[static::class])) { + static::$zero[static::class] = new BigInteger(); } } @@ -107,7 +115,8 @@ class Integer extends Base /** * Returns the modulo * - * @return integer + * @param int $instanceID + * @return BigInteger */ public static function getModulo($instanceID) { @@ -118,6 +127,8 @@ class Integer extends Base * Tests a parameter to see if it's of the right instance * * Throws an exception if the incorrect class is being utilized + * + * @return void */ public static function checkInstance(self $x, self $y) { @@ -278,7 +289,7 @@ class Integer extends Base /** * Is Odd? * - * @return boolean + * @return bool */ public function isOdd() { @@ -291,7 +302,7 @@ class Integer extends Base * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo * so 0-12 is the same thing as modulo-12 * - * @return object + * @return static */ public function negate() { @@ -339,7 +350,7 @@ class Integer extends Base * Returns the w-ary non-adjacent form (wNAF) * * @param int $w optional - * @return int[] + * @return array */ public function getNAF($w = 1) { @@ -352,20 +363,21 @@ class Integer extends Base $d_i = []; $i = 0; - while ($d->compare(static::$zero) > 0) { + while ($d->compare(static::$zero[static::class]) > 0) { if ($d->isOdd()) { // start mods - $d_i[$i] = $d->testBit($w - 1) ? + + $bigInteger = $d->testBit($w - 1) ? $d->bitwise_and($mask)->subtract($sub) : //$sub->subtract($d->bitwise_and($mask)) : $d->bitwise_and($mask); // end mods - $d = $d->subtract($d_i[$i]); - $d_i[$i] = (int) $d_i[$i]->toString(); + $d = $d->subtract($bigInteger); + $d_i[$i] = (int) $bigInteger->toString(); } else { $d_i[$i] = 0; } - $shift = !$d->equals(static::$zero) && $d->bitwise_and($mask)->equals(static::$zero) ? $w : 1; // $w or $w + 1? + $shift = !$d->equals(static::$zero[static::class]) && $d->bitwise_and($mask)->equals(static::$zero[static::class]) ? $w : 1; // $w or $w + 1? $d = $d->bitwise_rightShift($shift); while (--$shift > 0) { $d_i[++$i] = 0; @@ -379,7 +391,7 @@ class Integer extends Base /** * Converts an Integer to a BigInteger * - * @return string + * @return BigInteger */ public function toBigInteger() { @@ -390,6 +402,7 @@ class Integer extends Base * __toString() magic method * * @access public + * @return string */ public function __toString() { @@ -400,6 +413,7 @@ class Integer extends Base * __debugInfo() magic method * * @access public + * @return array */ public function __debugInfo() {