Psalm coverage for phpseclib3\Math\

Psalm coverage for phpseclib3\Math\
This commit is contained in:
Jack Worman 2022-02-21 07:43:51 -06:00 committed by terrafrost
parent 574953061a
commit 6f2db49696
16 changed files with 252 additions and 369 deletions

View File

@ -7,17 +7,14 @@
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
findUnusedPsalmSuppress="true" findUnusedPsalmSuppress="true"
sealAllMethods="true" sealAllMethods="true"
errorBaseline="psalm_baseline.xml"
> >
<projectFiles> <projectFiles>
<directory name="../phpseclib/Common"/> <directory name="../phpseclib"/>
<!-- <directory name="../phpseclib/Crypt"/>--> <ignoreFiles>
<directory name="../phpseclib/Exception"/> <directory name="../phpseclib/Crypt"/>
<directory name="../phpseclib/File"/> <directory name="../tests"/>
<!-- <directory name="../phpseclib/Math"/>--> </ignoreFiles>
<directory name="../phpseclib/Net"/>
<directory name="../phpseclib/System"/>
<file name="../phpseclib/bootstrap.php"/>
<!-- <directory name="../tests"/>-->
</projectFiles> </projectFiles>
<issueHandlers> <issueHandlers>
<Trace> <Trace>
@ -31,4 +28,4 @@
</errorLevel> </errorLevel>
</UndefinedConstant> </UndefinedConstant>
</issueHandlers> </issueHandlers>
</psalm> </psalm>

View File

@ -30,6 +30,7 @@
namespace phpseclib3\Math; namespace phpseclib3\Math;
use phpseclib3\Exception\BadConfigurationException; 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 * 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 * Main Engine
* *
* @var string * @var class-string<Engine>
*/ */
private static $mainEngine; private static $mainEngine;
/**
* Modular Exponentiation Engine
*
* @var string
*/
private static $modexpEngine;
/** /**
* Selected Engines * Selected Engines
* *
* @var array * @var list<string>
*/ */
private static $engines; private static $engines;
@ -93,9 +87,10 @@ class BigInteger
* Throws an exception if the type is invalid * Throws an exception if the type is invalid
* *
* @param string $main * @param string $main
* @param array $modexps optional * @param list<string> $modexps optional
* @return void
*/ */
public static function setEngine($main, $modexps = ['DefaultEngine']) public static function setEngine($main, array $modexps = ['DefaultEngine'])
{ {
self::$engines = []; self::$engines = [];
@ -106,6 +101,7 @@ class BigInteger
if (!$fqmain::isValidEngine()) { if (!$fqmain::isValidEngine()) {
throw new BadConfigurationException("$main is not setup correctly on this system"); throw new BadConfigurationException("$main is not setup correctly on this system");
} }
/** @var class-string<Engine> $fqmain */
self::$mainEngine = $fqmain; self::$mainEngine = $fqmain;
if (!in_array('Default', $modexps)) { if (!in_array('Default', $modexps)) {
@ -126,8 +122,6 @@ class BigInteger
throw new BadConfigurationException("No valid modular exponentiation engine found for $main"); throw new BadConfigurationException("No valid modular exponentiation engine found for $main");
} }
self::$modexpEngine = $modexp;
self::$engines = [$main, $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 string|int|BigInteger\Engines\Engine $x Base-10 number or base-$base number if $base set.
* @param int $base * @param int $base
* @return BigInteger
*/ */
public function __construct($x = 0, $base = 10) public function __construct($x = 0, $base = 10)
{ {
@ -418,7 +411,7 @@ class BigInteger
* __serialize() / __unserialize() were introduced in PHP 7.4: * __serialize() / __unserialize() were introduced in PHP 7.4:
* https://wiki.php.net/rfc/custom_object_serialization * https://wiki.php.net/rfc/custom_object_serialization
* *
* @return string * @return array
*/ */
public function __sleep() public function __sleep()
{ {

View File

@ -44,48 +44,6 @@ class BCMath extends Engine
*/ */
const ENGINE_DIR = 'BCMath'; 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 * 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 mixed $x integer Base-10 number or base-$base number if $base set.
* @param int $base * @param int $base
* @return \phpseclib3\Math\BigInteger\Engines\BCMath
* @see parent::__construct() * @see parent::__construct()
*/ */
public function __construct($x = 0, $base = 10) public function __construct($x = 0, $base = 10)
{ {
if (!isset(self::$isValidEngine)) { if (!isset(static::$isValidEngine[static::class])) {
self::$isValidEngine = self::isValidEngine(); 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'); 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). * and the divisor (basically, the "common residue" is the first positive modulo).
* *
* @param BCMath $y * @param BCMath $y
* @return BCMath * @return array{static, static}
*/ */
public function divide(BCMath $y) 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. * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information.
* *
* @param BCMath $n * @param BCMath $n
* @return BCMath * @return array{gcd: static, x: static, y: static}
*/ */
public function extendedGCD(BCMath $n) public function extendedGCD(BCMath $n)
{ {
@ -503,7 +460,7 @@ class BCMath extends Engine
protected function powModInner(BCMath $e, BCMath $n) protected function powModInner(BCMath $e, BCMath $n)
{ {
try { try {
$class = self::$modexpEngine; $class = static::$modexpEngine[static::class];
return $class::powModHelper($this, $e, $n, static::class); return $class::powModHelper($this, $e, $n, static::class);
} catch (\Exception $err) { } catch (\Exception $err) {
return BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class); return BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class);
@ -595,7 +552,7 @@ class BCMath extends Engine
$value = $this->value; $value = $this->value;
foreach (self::$primes as $prime) { foreach (self::PRIMES as $prime) {
$r = bcmod($this->value, $prime); $r = bcmod($this->value, $prime);
if ($r == '0') { if ($r == '0') {
return $this->value == $prime; return $this->value == $prime;
@ -618,7 +575,7 @@ class BCMath extends Engine
{ {
$r_value = &$r->value; $r_value = &$r->value;
$s = 0; $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) { while ($r_value[strlen($r_value) - 1] % 2 == 0) {
$r_value = bcdiv($r_value, '2', 0); $r_value = bcdiv($r_value, '2', 0);
++$s; ++$s;
@ -685,13 +642,13 @@ class BCMath extends Engine
protected static function setBitmask($bits) protected static function setBitmask($bits)
{ {
$temp = parent::setBitmask($bits); $temp = parent::setBitmask($bits);
return $temp->add(static::$one); return $temp->add(static::$one[static::class]);
} }
/** /**
* Is Odd? * Is Odd?
* *
* @return boolean * @return bool
*/ */
public function isOdd() public function isOdd()
{ {
@ -701,7 +658,7 @@ class BCMath extends Engine
/** /**
* Tests if a bit is set * Tests if a bit is set
* *
* @return boolean * @return bool
*/ */
public function testBit($x) public function testBit($x)
{ {

View File

@ -78,7 +78,7 @@ abstract class EvalBarrett extends Base
$u = "'$u'"; $u = "'$u'";
$m1 = "'$m1'"; $m1 = "'$m1'";
$code .= ' $code = '
$lsd = substr($n, -' . $cutoff . '); $lsd = substr($n, -' . $cutoff . ');
$msd = substr($n, 0, -' . $cutoff . '); $msd = substr($n, 0, -' . $cutoff . ');

View File

@ -30,10 +30,59 @@ use phpseclib3\Math\BigInteger;
*/ */
abstract class Engine 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<class-string<static>, static>
*/
protected static $zero = [];
/**
* BigInteger(1)
*
* @var array<class-string<static>, static>
*/
protected static $one = [];
/**
* BigInteger(2)
*
* @var array<class-string<static>, static>
*/
protected static $two = [];
/**
* Modular Exponentiation Engine
*
* @var array<class-string<static>, class-string<static>>
*/
protected static $modexpEngine;
/**
* Engine Validity Flag
*
* @var array<class-string<static>, bool>
*/
protected static $isValidEngine;
/** /**
* Holds the BigInteger's value * Holds the BigInteger's value
* *
* @var mixed * @var \GMP|string|array|int
*/ */
protected $value; protected $value;
@ -48,6 +97,7 @@ abstract class Engine
* Precision * Precision
* *
* @see static::setPrecision() * @see static::setPrecision()
* @var int
*/ */
protected $precision = -1; protected $precision = -1;
@ -55,6 +105,7 @@ abstract class Engine
* Precision Bitmask * Precision Bitmask
* *
* @see static::setPrecision() * @see static::setPrecision()
* @var static|false
*/ */
protected $bitmask = false; protected $bitmask = false;
@ -77,28 +128,16 @@ abstract class Engine
/** /**
* Default constructor * 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 * @param int $base
*/ */
public function __construct($x, $base) public function __construct($x = 0, $base = 10)
{ {
if (!isset(static::$primes)) { if (!array_key_exists(static::class, static::$zero)) {
static::$primes = [ static::$zero[static::class] = null; // Placeholder to prevent infinite loop.
3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, static::$zero[static::class] = new static(0);
61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, static::$one[static::class] = new static(1);
139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, static::$two[static::class] = new static(2);
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);
} }
// '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 // '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; $this->is_negative = false;
} }
static::initialize($base); $this->initialize($base);
if ($this->is_negative) { if ($this->is_negative) {
$temp = $this->add(new static('-1')); $temp = $this->add(new static('-1'));
@ -141,7 +180,7 @@ abstract class Engine
} }
$this->value = $x; $this->value = $x;
static::initialize($base); $this->initialize($base);
if ($is_negative) { if ($is_negative) {
$temp = $this->add(new static('-1')); $temp = $this->add(new static('-1'));
@ -157,7 +196,7 @@ abstract class Engine
if (!strlen($this->value) || $this->value == '-') { if (!strlen($this->value) || $this->value == '-') {
$this->value = '0'; $this->value = '0';
} }
static::initialize($base); $this->initialize($base);
break; break;
case -2: case -2:
case 2: case 2:
@ -185,7 +224,7 @@ abstract class Engine
* *
* Throws an exception if the type is invalid * Throws an exception if the type is invalid
* *
* @param string $engine * @param class-string<Engine> $engine
*/ */
public static function setModExpEngine($engine) public static function setModExpEngine($engine)
{ {
@ -196,7 +235,7 @@ abstract class Engine
if (!$fqengine::isValidEngine()) { if (!$fqengine::isValidEngine()) {
throw new BadConfigurationException("$engine is not setup correctly on this system"); 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.} * {@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 * @param Engine $n
* @return \phpseclib3\Math\BigInteger\Engines\Engine|false * @return static|false
*/ */
protected function modInverseHelper(Engine $n) protected function modInverseHelper(Engine $n)
{ {
// $x mod -$n == $x mod $n. // $x mod -$n == $x mod $n.
$n = $n->abs(); $n = $n->abs();
if ($this->compare(static::$zero) < 0) { if ($this->compare(static::$zero[static::class]) < 0) {
$temp = $this->abs(); $temp = $this->abs();
$temp = $temp->modInverse($n); $temp = $temp->modInverse($n);
return $this->normalize($n->subtract($temp)); return $this->normalize($n->subtract($temp));
@ -284,17 +323,17 @@ abstract class Engine
extract($this->extendedGCD($n)); extract($this->extendedGCD($n));
/** /**
* @var BigInteger $gcd * @var Engine $gcd
* @var BigInteger $x * @var Engine $x
*/ */
if (!$gcd->equals(static::$one)) { if (!$gcd->equals(static::$one[static::class])) {
return false; 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. * Will be called, automatically, when serialize() is called on a BigInteger object.
* *
* @return string * @return array
*/ */
public function __sleep() public function __sleep()
{ {
@ -318,6 +357,8 @@ abstract class Engine
* Serialize * Serialize
* *
* Will be called, automatically, when unserialize() is called on a BigInteger object. * Will be called, automatically, when unserialize() is called on a BigInteger object.
*
* @return void
*/ */
public function __wakeup() public function __wakeup()
{ {
@ -344,6 +385,8 @@ abstract class Engine
* __debugInfo() magic method * __debugInfo() magic method
* *
* Will be called, automatically, when print_r() or var_dump() are called * Will be called, automatically, when print_r() or var_dump() are called
*
* @return array
*/ */
public function __debugInfo() public function __debugInfo()
{ {
@ -390,7 +433,7 @@ abstract class Engine
/** /**
* Set Bitmask * Set Bitmask
* @return Engine * @return static
* @param int $bits * @param int $bits
* @see self::setPrecision() * @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) // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
$temp = $this->toBytes(); $temp = $this->toBytes();
if ($temp == '') { if ($temp == '') {
return $this->normalize(static::$zero); return $this->normalize(static::$zero[static::class]);
} }
$pre_msb = decbin(ord($temp[0])); $pre_msb = decbin(ord($temp[0]));
$temp = ~$temp; $temp = ~$temp;
@ -444,7 +487,7 @@ abstract class Engine
* *
* @param string $x * @param string $x
* @param int $shift * @param int $shift
* @return string * @return void
*/ */
protected static function base256_lshift(&$x, $shift) 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. * Instead of the top x bits being dropped they're appended to the shifted bit string.
* *
* @param int $shift * @param int $shift
* @return \phpseclib3\Math\BigInteger\Engines\Engine * @return Engine
*/ */
public function bitwise_leftRotate($shift) 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. * Instead of the bottom x bits being dropped they're prepended to the shifted bit string.
* *
* @param int $shift * @param int $shift
* @return \phpseclib3\Math\BigInteger\Engines\Engine * @return Engine
*/ */
public function bitwise_rightRotate($shift) public function bitwise_rightRotate($shift)
{ {
@ -526,7 +569,7 @@ abstract class Engine
* Returns the smallest and largest n-bit number * Returns the smallest and largest n-bit number
* *
* @param int $bits * @param int $bits
* @return \phpseclib3\Math\BigInteger\Engines\Engine[] * @return array{min: static, max: static}
*/ */
public static function minMaxBits($bits) public static function minMaxBits($bits)
{ {
@ -571,7 +614,7 @@ abstract class Engine
* *
* @param Engine $e * @param Engine $e
* @param Engine $n * @param Engine $n
* @return bool|Engine * @return static|false
*/ */
protected function powModOuter(Engine $e, Engine $n) 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. * 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. * As such, this function has the same preconditions that the reductions being used do.
* *
* @param \phpseclib3\Math\BigInteger\Engines\Engine $x * @template T of Engine
* @param \phpseclib3\Math\BigInteger\Engines\Engine $e * @param Engine $x
* @param \phpseclib3\Math\BigInteger\Engines\Engine $n * @param Engine $e
* @param string $class * @param Engine $n
* @return \phpseclib3\Math\BigInteger\Engines\Engine * @param class-string<T> $class
* @return T
*/ */
protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class)
{ {
@ -674,7 +718,7 @@ abstract class Engine
* Bit length is equal to $size * Bit length is equal to $size
* *
* @param int $size * @param int $size
* @return \phpseclib3\Math\BigInteger\Engines\Engine * @return Engine
*/ */
public static function random($size) public static function random($size)
{ {
@ -692,14 +736,14 @@ abstract class Engine
* Bit length is equal to $size * Bit length is equal to $size
* *
* @param int $size * @param int $size
* @return \phpseclib3\Math\BigInteger\Engines\Engine * @return Engine
*/ */
public static function randomPrime($size) public static function randomPrime($size)
{ {
extract(static::minMaxBits($size)); extract(static::minMaxBits($size));
/** /**
* @var BigInteger $min * @var static $min
* @var BigInteger $max * @var static $max
*/ */
return static::randomRangePrime($min, $max); return static::randomRangePrime($min, $max);
} }
@ -709,7 +753,7 @@ abstract class Engine
* *
* @param Engine $min * @param Engine $min
* @param Engine $max * @param Engine $max
* @return bool|Engine * @return static|false
*/ */
protected static function randomRangePrimeOuter(Engine $min, Engine $max) protected static function randomRangePrimeOuter(Engine $min, Engine $max)
{ {
@ -755,11 +799,11 @@ abstract class Engine
$min = $temp; $min = $temp;
} }
if (!isset(static::$one)) { if (!isset(static::$one[static::class])) {
static::$one = new static(1); 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))); $size = strlen(ltrim($max->toBytes(), chr(0)));
@ -804,12 +848,12 @@ abstract class Engine
* @param Engine $x * @param Engine $x
* @param Engine $min * @param Engine $min
* @param Engine $max * @param Engine $max
* @return bool|Engine * @return static|false
*/ */
protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max)
{ {
if (!isset(static::$two)) { if (!isset(static::$two[static::class])) {
static::$two = new static('2'); static::$two[static::class] = new static('2');
} }
$x->make_odd(); $x->make_odd();
@ -829,11 +873,11 @@ abstract class Engine
return $x; return $x;
} }
$x = $x->add(static::$two); $x = $x->add(static::$two[static::class]);
if ($x->compare($max) > 0) { if ($x->compare($max) > 0) {
$x = clone $min; $x = clone $min;
if ($x->equals(static::$two)) { if ($x->equals(static::$two[static::class])) {
return $x; return $x;
} }
$x->make_odd(); $x->make_odd();
@ -856,7 +900,7 @@ abstract class Engine
// see HAC 4.49 "Note (controlling the error probability)" // see HAC 4.49 "Note (controlling the error probability)"
// @codingStandardsIgnoreStart // @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 >= 106) { $t = 3; } // floor( 850 / 8)
else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8)
else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8)
@ -889,20 +933,20 @@ abstract class Engine
} }
$n = clone $this; $n = clone $this;
$n_1 = $n->subtract(static::$one); $n_1 = $n->subtract(static::$one[static::class]);
$n_2 = $n->subtract(static::$two); $n_2 = $n->subtract(static::$two[static::class]);
$r = clone $n_1; $r = clone $n_1;
$s = static::scan1divide($r); $s = static::scan1divide($r);
for ($i = 0; $i < $t; ++$i) { 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); $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) { for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) {
$y = $y->modPow(static::$two, $n); $y = $y->modPow(static::$two[static::class], $n);
if ($y->equals(static::$one)) { if ($y->equals(static::$one[static::class])) {
return false; return false;
} }
} }
@ -938,18 +982,18 @@ abstract class Engine
* Performs a few preliminary checks on root * Performs a few preliminary checks on root
* *
* @param int $n * @param int $n
* @return \phpseclib3\Math\BigInteger\Engines\Engine * @return Engine
*/ */
protected function rootHelper($n) protected function rootHelper($n)
{ {
if ($n < 1) { if ($n < 1) {
return clone static::$zero; return clone static::$zero[static::class];
} // we want positive exponents } // we want positive exponents
if ($this->compare(static::$one) < 0) { if ($this->compare(static::$one[static::class]) < 0) {
return clone static::$zero; return clone static::$zero[static::class];
} // we want positive numbers } // we want positive numbers
if ($this->compare(static::$two) < 0) { if ($this->compare(static::$two[static::class]) < 0) {
return clone static::$one; return clone static::$one[static::class];
} // n-th root of 1 or 2 is 1 } // n-th root of 1 or 2 is 1
return $this->rootInner($n); 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}.} * {@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 * @param int $n
* @return \phpseclib3\Math\BigInteger\Engines\Engine * @return Engine
*/ */
protected function rootInner($n) protected function rootInner($n)
{ {
$n = new static($n); $n = new static($n);
// g is our guess number // g is our guess number
$g = static::$two; $g = static::$two[static::class];
// while (g^n < num) g=g*2 // while (g^n < num) g=g*2
while ($g->pow($n)->compare($this) < 0) { 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 // if (g^n==num) num is a power of 2, we're lucky, end of job
// == 0 bccomp(bcpow($g, $n), $n->value)==0 // == 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 :( // if we're here num wasn't a power of 2 :(
$og = $g; // og means original guess and here is our upper bound $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 $g = $g->divide(static::$two[static::class])[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 $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 $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval
// while step>1 // while step>1
while ($step->compare(static::$one) == 1) { while ($step->compare(static::$one[static::class]) == 1) {
$guess = $g->pow($n); $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 $comp = $guess->compare($this); // compare our guess with real number
switch ($comp) { switch ($comp) {
case -1: // if guess is lower we add the new step case -1: // if guess is lower we add the new step
@ -1076,9 +1120,9 @@ abstract class Engine
{ {
$class = static::class; $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' : '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\DefaultEngine' :
static::$modexpEngine; static::$modexpEngine[static::class];
if (method_exists($fqengine, 'generateCustomReduction')) { if (method_exists($fqengine, 'generateCustomReduction')) {
$func = $fqengine::generateCustomReduction($this, static::class); $func = $fqengine::generateCustomReduction($this, static::class);
return eval('return function(' . static::class . ' $x) use ($func, $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. * Calculates the greatest common divisor and Bezout's identity.
* *
* @param Engine $n * @param Engine $n
* @param Engine $stop (optional) * @return array{gcd: Engine, x: Engine, y: Engine}
* @return Engine
*/ */
protected function extendedGCDHelper(Engine $n, Engine $stop = null) protected function extendedGCDHelper(Engine $n)
{ {
$u = clone $this; $u = clone $this;
$v = clone $n; $v = clone $n;
@ -1144,7 +1187,7 @@ abstract class Engine
* Splits BigInteger's into chunks of $split bits * Splits BigInteger's into chunks of $split bits
* *
* @param int $split * @param int $split
* @return \phpseclib3\Math\BigInteger\Engines\Engine[] * @return Engine[]
*/ */
public function bitwise_split($split) public function bitwise_split($split)
{ {
@ -1152,12 +1195,12 @@ abstract class Engine
throw new \RuntimeException('Offset must be greater than 1'); 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; $num = clone $this;
$vals = []; $vals = [];
while (!$num->equals(static::$zero)) { while (!$num->equals(static::$zero[static::class])) {
$vals[] = $num->bitwise_and($mask); $vals[] = $num->bitwise_and($mask);
$num = $num->bitwise_rightShift($split); $num = $num->bitwise_rightShift($split);
} }

View File

@ -43,50 +43,6 @@ class GMP extends Engine
*/ */
const ENGINE_DIR = 'GMP'; 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 * 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 mixed $x integer Base-10 number or base-$base number if $base set.
* @param int $base * @param int $base
* @return \phpseclib3\Math\BigInteger\Engines\GMP
* @see parent::__construct() * @see parent::__construct()
*/ */
public function __construct($x = 0, $base = 10) public function __construct($x = 0, $base = 10)
{ {
if (!isset(self::$isValidEngine)) { if (!isset(static::$isValidEngine[static::class])) {
self::$isValidEngine = self::isValidEngine(); 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'); 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). * and the divisor (basically, the "common residue" is the first positive modulo).
* *
* @param GMP $y * @param GMP $y
* @return GMP * @return array{GMP, GMP}
*/ */
public function divide(GMP $y) public function divide(GMP $y)
{ {
@ -497,7 +452,7 @@ class GMP extends Engine
*/ */
protected function powModInner(GMP $e, GMP $n) protected function powModInner(GMP $e, GMP $n)
{ {
$class = self::$modexpEngine; $class = static::$modexpEngine[static::class];
return $class::powModHelper($this, $e, $n); return $class::powModHelper($this, $e, $n);
} }

View File

@ -81,10 +81,10 @@ abstract class PHP extends Engine
*/ */
public function __construct($x = 0, $base = 10) public function __construct($x = 0, $base = 10)
{ {
if (!isset(static::$isValidEngine)) { if (!isset(static::$isValidEngine[static::class])) {
static::$isValidEngine = static::isValidEngine(); 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'); 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 * 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). * and the divisor (basically, the "common residue" is the first positive modulo).
* *
* @param \phpseclib3\Math\BigInteger\engines\PHP $y * @return array{static, static}
* @return array
* @internal This function is based off of * @internal This function is based off of
* {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. * {@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 = new static();
$temp->value = [1]; $temp->value = [1];
$temp->is_negative = $x_sign != $y_sign; $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) { if ($diff < 0) {
@ -569,7 +568,7 @@ abstract class PHP extends Engine
if ($x_sign) { if ($x_sign) {
$x = $y->subtract($x); $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 // 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); $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); $temp_value = array_merge($adjust, $y_value);
$x = $x->add($temp); $x = $x->add($temp);
@ -724,14 +723,15 @@ abstract class PHP extends Engine
} }
// static::BASE === 31 // static::BASE === 31
/** @var int */
return ($x - ($x % $y)) / $y; return ($x - ($x % $y)) / $y;
} }
/* /**
* Convert an array / boolean to a PHP BigInteger object * Convert an array / boolean to a PHP BigInteger object
* *
* @param array $arr * @param array $arr
* @return \phpseclib3\Math\BigInteger\Engines\PHP * @return static
*/ */
protected function convertToObj(array $arr) 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 * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision
* *
* @param PHP $result * @param PHP $result
* @return PHP * @return static
*/ */
protected function normalize(PHP $result) protected function normalize(PHP $result)
{ {
@ -776,7 +776,7 @@ abstract class PHP extends Engine
return $result; return $result;
} }
/* /**
* Compares two numbers. * Compares two numbers.
* *
* @param array $x_value * @param array $x_value
@ -829,8 +829,8 @@ abstract class PHP extends Engine
* *
* Removes leading zeros * Removes leading zeros
* *
* @param array $value * @param list<static> $value
* @return PHP * @return list<static>
*/ */
protected static function trim(array $value) protected static function trim(array $value)
{ {
@ -983,7 +983,7 @@ abstract class PHP extends Engine
protected function powModInner(PHP $e, PHP $n) protected function powModInner(PHP $e, PHP $n)
{ {
try { try {
$class = static::$modexpEngine; $class = static::$modexpEngine[static::class];
return $class::powModHelper($this, $e, $n, static::class); return $class::powModHelper($this, $e, $n, static::class);
} catch (\Exception $err) { } catch (\Exception $err) {
return PHP\DefaultEngine::powModHelper($this, $e, $n, static::class); return PHP\DefaultEngine::powModHelper($this, $e, $n, static::class);
@ -993,8 +993,8 @@ abstract class PHP extends Engine
/** /**
* Performs squaring * Performs squaring
* *
* @param array $x * @param list<static> $x
* @return array * @return list<static>
*/ */
protected static function square(array $x) protected static function square(array $x)
{ {
@ -1109,7 +1109,7 @@ abstract class PHP extends Engine
} }
$value = $this->value; $value = $this->value;
foreach (static::$primes as $prime) { foreach (static::PRIMES as $prime) {
list(, $r) = self::divide_digit($value, $prime); list(, $r) = self::divide_digit($value, $prime);
if (!$r) { if (!$r) {
return count($value) == 1 && $value[0] == $prime; return count($value) == 1 && $value[0] == $prime;
@ -1152,14 +1152,14 @@ abstract class PHP extends Engine
*/ */
protected function powHelper(PHP $n) protected function powHelper(PHP $n)
{ {
if ($n->compare(static::$zero) == 0) { if ($n->compare(static::$zero[static::class]) == 0) {
return new static(1); return new static(1);
} // n^0 = 1 } // n^0 = 1
$temp = clone $this; $temp = clone $this;
while (!$n->equals(static::$one)) { while (!$n->equals(static::$one[static::class])) {
$temp = $temp->multiply($this); $temp = $temp->multiply($this);
$n = $n->subtract(static::$one); $n = $n->subtract(static::$one[static::class]);
} }
return $temp; return $temp;
@ -1168,7 +1168,7 @@ abstract class PHP extends Engine
/** /**
* Is Odd? * Is Odd?
* *
* @return boolean * @return bool
*/ */
public function isOdd() public function isOdd()
{ {
@ -1178,11 +1178,11 @@ abstract class PHP extends Engine
/** /**
* Tests if a bit is set * Tests if a bit is set
* *
* @return boolean * @return bool
*/ */
public function testBit($x) public function testBit($x)
{ {
$digit = floor($x / static::BASE); $digit = (int) floor($x / static::BASE);
$bit = $x % static::BASE; $bit = $x % static::BASE;
if (!isset($this->value[$digit])) { if (!isset($this->value[$digit])) {
@ -1195,7 +1195,7 @@ abstract class PHP extends Engine
/** /**
* Is Negative? * Is Negative?
* *
* @return boolean * @return bool
*/ */
public function isNegative() public function isNegative()
{ {
@ -1207,7 +1207,7 @@ abstract class PHP extends Engine
* *
* Given $k, returns -$k * Given $k, returns -$k
* *
* @return BigInteger * @return static
*/ */
public function negate() public function negate()
{ {
@ -1223,7 +1223,7 @@ abstract class PHP extends Engine
* Splits BigInteger's into chunks of $split bits * Splits BigInteger's into chunks of $split bits
* *
* @param int $split * @param int $split
* @return \phpseclib3\Math\BigInteger\Engines\PHP[] * @return list<static>
*/ */
public function bitwise_split($split) public function bitwise_split($split)
{ {
@ -1290,7 +1290,7 @@ abstract class PHP extends Engine
* Bitwise Split where $split < static::BASE * Bitwise Split where $split < static::BASE
* *
* @param int $split * @param int $split
* @return \phpseclib3\Math\BigInteger\Engines\PHP[] * @return list<int>
*/ */
private function bitwise_small_split($split) private function bitwise_small_split($split)
{ {

View File

@ -41,11 +41,12 @@ abstract class Montgomery extends Base
/** /**
* Performs modular exponentiation. * Performs modular exponentiation.
* *
* @param \phpseclib3\Math\BigInteger\Engines\Engine $x * @template T of Engine
* @param \phpseclib3\Math\BigInteger\Engines\Engine $e * @param Engine $x
* @param \phpseclib3\Math\BigInteger\Engines\Engine $n * @param Engine $e
* @param string $class * @param Engine $n
* @return \phpseclib3\Math\BigInteger\Engines\Engine * @param class-string<T> $class
* @return T
*/ */
protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class)
{ {

View File

@ -469,7 +469,7 @@ abstract class EvalBarrett extends Base
private static function float2string($num) private static function float2string($num)
{ {
if (!is_float($num)) { if (!is_float($num)) {
return $num; return (string) $num;
} }
if ($num < 0) { if ($num < 0) {

View File

@ -15,6 +15,8 @@
namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions;
use phpseclib3\Math\BigInteger\Engines\PHP;
/** /**
* PHP Montgomery Modular Exponentiation Engine with interleaved multiplication * PHP Montgomery Modular Exponentiation Engine with interleaved multiplication
* *
@ -36,7 +38,7 @@ abstract class MontgomeryMult extends Montgomery
* @param array $x * @param array $x
* @param array $y * @param array $y
* @param array $m * @param array $m
* @param string $class * @param class-string<PHP> $class
* @return array * @return array
*/ */
public static function multiplyReduce(array $x, array $y, array $m, $class) public static function multiplyReduce(array $x, array $y, array $m, $class)

View File

@ -44,49 +44,6 @@ class PHP32 extends PHP
*/ */
const MAX10LEN = 7; const MAX10LEN = 7;
const MAX_DIGIT2 = 4503599627370496; 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 * 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). * and the divisor (basically, the "common residue" is the first positive modulo).
* *
* @param PHP32 $y * @param PHP32 $y
* @return PHP32 * @return array{PHP32, PHP32}
*/ */
public function divide(PHP32 $y) public function divide(PHP32 $y)
{ {

View File

@ -44,49 +44,6 @@ class PHP64 extends PHP
*/ */
const MAX10LEN = 9; const MAX10LEN = 9;
const MAX_DIGIT2 = 4611686018427387904; 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 * 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). * and the divisor (basically, the "common residue" is the first positive modulo).
* *
* @param PHP64 $y * @param PHP64 $y
* @return PHP64 * @return array{PHP64, PHP64}
*/ */
public function divide(PHP64 $y) public function divide(PHP64 $y)
{ {
@ -334,7 +291,7 @@ class PHP64 extends PHP
* *
* @param PHP64 $e * @param PHP64 $e
* @param PHP64 $n * @param PHP64 $n
* @return PHP64 * @return PHP64|false
*/ */
public function powMod(PHP64 $e, PHP64 $n) public function powMod(PHP64 $e, PHP64 $n)
{ {

View File

@ -43,6 +43,9 @@ class BinaryField extends FiniteField
*/ */
protected $instanceID; protected $instanceID;
/** @var BigInteger */
private $randomMax;
/** /**
* Default constructor * Default constructor
*/ */
@ -113,7 +116,7 @@ class BinaryField extends FiniteField
* Returns an instance of a dynamically generated PrimeFieldInteger class * Returns an instance of a dynamically generated PrimeFieldInteger class
* *
* @param string $num * @param string $num
* @return object * @return Integer
*/ */
public function newInteger($num) 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 * Returns an integer on the finite field between one and the prime modulo
* *
* @return object * @return Integer
*/ */
public function randomInteger() public function randomInteger()
{ {
@ -138,7 +141,7 @@ class BinaryField extends FiniteField
/** /**
* Returns the length of the modulo in bytes * Returns the length of the modulo in bytes
* *
* @return integer * @return int
*/ */
public function getLengthInBytes() public function getLengthInBytes()
{ {
@ -148,7 +151,7 @@ class BinaryField extends FiniteField
/** /**
* Returns the length of the modulo in bits * Returns the length of the modulo in bits
* *
* @return integer * @return int
*/ */
public function getLength() public function getLength()
{ {

View File

@ -53,7 +53,7 @@ class Integer extends Base
/** /**
* Holds the PrimeField's modulo * Holds the PrimeField's modulo
* *
* @var string[] * @var array<int, string>
*/ */
protected static $modulo; protected static $modulo;
@ -80,6 +80,8 @@ class Integer extends Base
/** /**
* Set the modulo for a given instance * Set the modulo for a given instance
* @param int $instanceID
* @param string $modulo
*/ */
public static function setModulo($instanceID, $modulo) public static function setModulo($instanceID, $modulo)
{ {
@ -450,7 +452,7 @@ class Integer extends Base
/** /**
* Returns the modulo * Returns the modulo
* *
* @return integer * @return string
*/ */
public static function getModulo($instanceID) public static function getModulo($instanceID)
{ {

View File

@ -61,8 +61,10 @@ class PrimeField extends FiniteField
/** /**
* Use a custom defined modular reduction function * 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); $this->reduce = $func->bindTo($this, $this);
} }
@ -70,7 +72,7 @@ class PrimeField extends FiniteField
/** /**
* Returns an instance of a dynamically generated PrimeFieldInteger class * Returns an instance of a dynamically generated PrimeFieldInteger class
* *
* @return object * @return Integer
*/ */
public function newInteger(BigInteger $num) 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 * Returns an integer on the finite field between one and the prime modulo
* *
* @return object * @return Integer
*/ */
public function randomInteger() public function randomInteger()
{ {
@ -95,7 +97,7 @@ class PrimeField extends FiniteField
/** /**
* Returns the length of the modulo in bytes * Returns the length of the modulo in bytes
* *
* @return integer * @return int
*/ */
public function getLengthInBytes() public function getLengthInBytes()
{ {
@ -105,7 +107,7 @@ class PrimeField extends FiniteField
/** /**
* Returns the length of the modulo in bits * Returns the length of the modulo in bits
* *
* @return integer * @return int
*/ */
public function getLength() public function getLength()
{ {

View File

@ -30,7 +30,7 @@ class Integer extends Base
/** /**
* Holds the PrimeField's value * Holds the PrimeField's value
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $value; protected $value;
@ -44,32 +44,34 @@ class Integer extends Base
/** /**
* Holds the PrimeField's modulo * Holds the PrimeField's modulo
* *
* @var \phpseclib3\Math\BigInteger * @var array<int, BigInteger>
*/ */
protected static $modulo; protected static $modulo;
/** /**
* Holds a pre-generated function to perform modulo reductions * Holds a pre-generated function to perform modulo reductions
* *
* @var Callable * @var array<int, callable(BigInteger):BigInteger>
*/ */
protected static $reduce; protected static $reduce;
/** /**
* Zero * Zero
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected static $zero; protected static $zero;
/** /**
* Default constructor * Default constructor
*
* @param int $instanceID
*/ */
public function __construct($instanceID, BigInteger $num = null) public function __construct($instanceID, BigInteger $num = null)
{ {
$this->instanceID = $instanceID; $this->instanceID = $instanceID;
if (!isset($num)) { if (!isset($num)) {
$this->value = clone static::$zero; $this->value = clone static::$zero[static::class];
} else { } else {
$reduce = static::$reduce[$instanceID]; $reduce = static::$reduce[$instanceID];
$this->value = $reduce($num); $this->value = $reduce($num);
@ -78,6 +80,9 @@ class Integer extends Base
/** /**
* Set the modulo for a given instance * Set the modulo for a given instance
*
* @param int $instanceID
* @return void
*/ */
public static function setModulo($instanceID, BigInteger $modulo) public static function setModulo($instanceID, BigInteger $modulo)
{ {
@ -86,12 +91,15 @@ class Integer extends Base
/** /**
* Set the modulo for a given instance * Set the modulo for a given instance
*
* @param int $instanceID
* @return void
*/ */
public static function setRecurringModuloFunction($instanceID, callable $function) public static function setRecurringModuloFunction($instanceID, callable $function)
{ {
static::$reduce[$instanceID] = $function; static::$reduce[$instanceID] = $function;
if (!isset(static::$zero)) { if (!isset(static::$zero[static::class])) {
static::$zero = new BigInteger(); static::$zero[static::class] = new BigInteger();
} }
} }
@ -107,7 +115,8 @@ class Integer extends Base
/** /**
* Returns the modulo * Returns the modulo
* *
* @return integer * @param int $instanceID
* @return BigInteger
*/ */
public static function getModulo($instanceID) 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 * Tests a parameter to see if it's of the right instance
* *
* Throws an exception if the incorrect class is being utilized * Throws an exception if the incorrect class is being utilized
*
* @return void
*/ */
public static function checkInstance(self $x, self $y) public static function checkInstance(self $x, self $y)
{ {
@ -278,7 +289,7 @@ class Integer extends Base
/** /**
* Is Odd? * Is Odd?
* *
* @return boolean * @return bool
*/ */
public function isOdd() 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 * 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 * so 0-12 is the same thing as modulo-12
* *
* @return object * @return static
*/ */
public function negate() public function negate()
{ {
@ -339,7 +350,7 @@ class Integer extends Base
* Returns the w-ary non-adjacent form (wNAF) * Returns the w-ary non-adjacent form (wNAF)
* *
* @param int $w optional * @param int $w optional
* @return int[] * @return array<int, int>
*/ */
public function getNAF($w = 1) public function getNAF($w = 1)
{ {
@ -352,20 +363,21 @@ class Integer extends Base
$d_i = []; $d_i = [];
$i = 0; $i = 0;
while ($d->compare(static::$zero) > 0) { while ($d->compare(static::$zero[static::class]) > 0) {
if ($d->isOdd()) { if ($d->isOdd()) {
// start mods // start mods
$d_i[$i] = $d->testBit($w - 1) ?
$bigInteger = $d->testBit($w - 1) ?
$d->bitwise_and($mask)->subtract($sub) : $d->bitwise_and($mask)->subtract($sub) :
//$sub->subtract($d->bitwise_and($mask)) : //$sub->subtract($d->bitwise_and($mask)) :
$d->bitwise_and($mask); $d->bitwise_and($mask);
// end mods // end mods
$d = $d->subtract($d_i[$i]); $d = $d->subtract($bigInteger);
$d_i[$i] = (int) $d_i[$i]->toString(); $d_i[$i] = (int) $bigInteger->toString();
} else { } else {
$d_i[$i] = 0; $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); $d = $d->bitwise_rightShift($shift);
while (--$shift > 0) { while (--$shift > 0) {
$d_i[++$i] = 0; $d_i[++$i] = 0;
@ -379,7 +391,7 @@ class Integer extends Base
/** /**
* Converts an Integer to a BigInteger * Converts an Integer to a BigInteger
* *
* @return string * @return BigInteger
*/ */
public function toBigInteger() public function toBigInteger()
{ {
@ -390,6 +402,7 @@ class Integer extends Base
* __toString() magic method * __toString() magic method
* *
* @access public * @access public
* @return string
*/ */
public function __toString() public function __toString()
{ {
@ -400,6 +413,7 @@ class Integer extends Base
* __debugInfo() magic method * __debugInfo() magic method
* *
* @access public * @access public
* @return array
*/ */
public function __debugInfo() public function __debugInfo()
{ {