diff options
Diffstat (limited to 'vendor/fgrosse/phpasn1/lib/Utility')
-rw-r--r-- | vendor/fgrosse/phpasn1/lib/Utility/BigInteger.php | 195 | ||||
-rw-r--r-- | vendor/fgrosse/phpasn1/lib/Utility/BigIntegerBcmath.php | 133 | ||||
-rw-r--r-- | vendor/fgrosse/phpasn1/lib/Utility/BigIntegerGmp.php | 133 |
3 files changed, 461 insertions, 0 deletions
diff --git a/vendor/fgrosse/phpasn1/lib/Utility/BigInteger.php b/vendor/fgrosse/phpasn1/lib/Utility/BigInteger.php new file mode 100644 index 0000000..866162c --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/Utility/BigInteger.php @@ -0,0 +1,195 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\Utility; + +/** + * Class BigInteger + * Utility class to remove dependence on a single large number library. Not intended for external use, this class only + * implements the functionality needed throughout this project. + * + * Instances are immutable, all operations return a new instance with the result. + * + * @package FG\Utility + * @internal + */ +abstract class BigInteger +{ + /** + * Force a preference on the underlying big number implementation, useful for testing. + * @var string|null + */ + private static $_prefer; + + public static function setPrefer($prefer = null) + { + self::$_prefer = $prefer; + } + + /** + * Create a BigInteger instance based off the base 10 string or an integer. + * @param string|int $val + * @return BigInteger + * @throws \InvalidArgumentException + */ + public static function create($val) + { + if (self::$_prefer) { + switch (self::$_prefer) { + case 'gmp': + $ret = new BigIntegerGmp(); + break; + case 'bcmath': + $ret = new BigIntegerBcmath(); + break; + default: + throw new \UnexpectedValueException('Unknown number implementation: ' . self::$_prefer); + } + } + else { + // autodetect + if (function_exists('gmp_add')) { + $ret = new BigIntegerGmp(); + } + elseif (function_exists('bcadd')) { + $ret = new BigIntegerBcmath(); + } else { + throw new \RuntimeException('Requires GMP or bcmath extension.'); + } + } + + if (is_int($val)) { + $ret->_fromInteger($val); + } + else { + // convert to string, if not already one + $val = (string)$val; + + // validate string + if (!preg_match('/^-?[0-9]+$/', $val)) { + throw new \InvalidArgumentException('Expects a string representation of an integer.'); + } + $ret->_fromString($val); + } + + return $ret; + } + + /** + * BigInteger constructor. + * Prevent directly instantiating object, use BigInteger::create instead. + */ + protected function __construct() + { + + } + + /** + * Subclasses must provide clone functionality. + * @return BigInteger + */ + abstract public function __clone(); + + /** + * Assign the instance value from base 10 string. + * @param string $str + */ + abstract protected function _fromString($str); + + /** + * Assign the instance value from an integer type. + * @param int $integer + */ + abstract protected function _fromInteger($integer); + + /** + * Must provide string implementation that returns base 10 number. + * @return string + */ + abstract public function __toString(); + + /* INFORMATIONAL FUNCTIONS */ + + /** + * Return integer, if possible. Throws an exception if the number can not be represented as a native integer. + * @return int + * @throws \OverflowException + */ + abstract public function toInteger(); + + /** + * Is represented integer negative? + * @return bool + */ + abstract public function isNegative(); + + /** + * Compare the integer with $number, returns a negative integer if $this is less than number, returns 0 if $this is + * equal to number and returns a positive integer if $this is greater than number. + * @param BigInteger|string|int $number + * @return int + */ + abstract public function compare($number); + + /* MODIFY */ + + /** + * Add another integer $b and returns the result. + * @param BigInteger|string|int $b + * @return BigInteger + */ + abstract public function add($b); + + /** + * Subtract $b from $this and returns the result. + * @param BigInteger|string|int $b + * @return BigInteger + */ + abstract public function subtract($b); + + /** + * Multiply value. + * @param BigInteger|string|int $b + * @return BigInteger + */ + abstract public function multiply($b); + + /** + * The value $this modulus $b. + * @param BigInteger|string|int $b + * @return BigInteger + */ + abstract public function modulus($b); + + /** + * Raise $this to the power of $b and returns the result. + * @param BigInteger|string|int $b + * @return BigInteger + */ + abstract public function toPower($b); + + /** + * Shift the value to the right by a set number of bits and returns the result. + * @param int $bits + * @return BigInteger + */ + abstract public function shiftRight($bits = 8); + + /** + * Shift the value to the left by a set number of bits and returns the result. + * @param int $bits + * @return BigInteger + */ + abstract public function shiftLeft($bits = 8); + + /** + * Returns the absolute value. + * @return BigInteger + */ + abstract public function absoluteValue(); +} diff --git a/vendor/fgrosse/phpasn1/lib/Utility/BigIntegerBcmath.php b/vendor/fgrosse/phpasn1/lib/Utility/BigIntegerBcmath.php new file mode 100644 index 0000000..25ad891 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/Utility/BigIntegerBcmath.php @@ -0,0 +1,133 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\Utility; + +/** + * Class BigIntegerBcmath + * Integer representation of big numbers using the bcmath library to perform large operations. + * @package FG\Utility + * @internal + */ +class BigIntegerBcmath extends BigInteger +{ + protected $_str; + + public function __clone() + { + // nothing needed to copy + } + + protected function _fromString($str) + { + $this->_str = (string)$str; + } + + protected function _fromInteger($integer) + { + $this->_str = (string)$integer; + } + + public function __toString() + { + return $this->_str; + } + + public function toInteger() + { + if ($this->compare(PHP_INT_MAX) > 0 || $this->compare(PHP_INT_MIN) < 0) { + throw new \OverflowException(sprintf('Can not represent %s as integer.', $this->_str)); + } + return (int)$this->_str; + } + + public function isNegative() + { + return bccomp($this->_str, '0', 0) < 0; + } + + protected function _unwrap($number) + { + if ($number instanceof self) { + return $number->_str; + } + return $number; + } + + public function compare($number) + { + return bccomp($this->_str, $this->_unwrap($number), 0); + } + + public function add($b) + { + $ret = new self(); + $ret->_str = bcadd($this->_str, $this->_unwrap($b), 0); + return $ret; + } + + public function subtract($b) + { + $ret = new self(); + $ret->_str = bcsub($this->_str, $this->_unwrap($b), 0); + return $ret; + } + + public function multiply($b) + { + $ret = new self(); + $ret->_str = bcmul($this->_str, $this->_unwrap($b), 0); + return $ret; + } + + public function modulus($b) + { + $ret = new self(); + if ($this->isNegative()) { + // bcmod handles negative numbers differently + $b = $this->_unwrap($b); + $ret->_str = bcsub($b, bcmod(bcsub('0', $this->_str, 0), $b), 0); + } + else { + $ret->_str = bcmod($this->_str, $this->_unwrap($b)); + } + return $ret; + } + + public function toPower($b) + { + $ret = new self(); + $ret->_str = bcpow($this->_str, $this->_unwrap($b), 0); + return $ret; + } + + public function shiftRight($bits = 8) + { + $ret = new self(); + $ret->_str = bcdiv($this->_str, bcpow('2', $bits)); + return $ret; + } + + public function shiftLeft($bits = 8) { + $ret = new self(); + $ret->_str = bcmul($this->_str, bcpow('2', $bits)); + return $ret; + } + + public function absoluteValue() + { + $ret = new self(); + if (-1 === bccomp($this->_str, '0', 0)) { + $ret->_str = bcsub('0', $this->_str, 0); + } + else { + $ret->_str = $this->_str; + } + return $ret; + } +} diff --git a/vendor/fgrosse/phpasn1/lib/Utility/BigIntegerGmp.php b/vendor/fgrosse/phpasn1/lib/Utility/BigIntegerGmp.php new file mode 100644 index 0000000..0791226 --- /dev/null +++ b/vendor/fgrosse/phpasn1/lib/Utility/BigIntegerGmp.php @@ -0,0 +1,133 @@ +<?php +/* + * This file is part of the PHPASN1 library. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\Utility; + +/** + * Class BigIntegerGmp + * Integer representation of big numbers using the GMP extension to perform operations. + * @package FG\Utility + * @internal + */ +class BigIntegerGmp extends BigInteger +{ + /** + * Resource handle. + * @var \GMP + */ + protected $_rh; + + public function __clone() + { + $this->_rh = gmp_add($this->_rh, 0); + } + + protected function _fromString($str) + { + $this->_rh = gmp_init($str, 10); + } + + protected function _fromInteger($integer) + { + $this->_rh = gmp_init($integer, 10); + } + + public function __toString() + { + return gmp_strval($this->_rh, 10); + } + + public function toInteger() + { + if ($this->compare(PHP_INT_MAX) > 0 || $this->compare(PHP_INT_MIN) < 0) { + throw new \OverflowException(sprintf('Can not represent %s as integer.', $this)); + } + return gmp_intval($this->_rh); + } + + public function isNegative() + { + return gmp_sign($this->_rh) === -1; + } + + protected function _unwrap($number) + { + if ($number instanceof self) { + return $number->_rh; + } + return $number; + } + + public function compare($number) + { + return gmp_cmp($this->_rh, $this->_unwrap($number)); + } + + public function add($b) + { + $ret = new self(); + $ret->_rh = gmp_add($this->_rh, $this->_unwrap($b)); + return $ret; + } + + public function subtract($b) + { + $ret = new self(); + $ret->_rh = gmp_sub($this->_rh, $this->_unwrap($b)); + return $ret; + } + + public function multiply($b) + { + $ret = new self(); + $ret->_rh = gmp_mul($this->_rh, $this->_unwrap($b)); + return $ret; + } + + public function modulus($b) + { + $ret = new self(); + $ret->_rh = gmp_mod($this->_rh, $this->_unwrap($b)); + return $ret; + } + + public function toPower($b) + { + if ($b instanceof self) { + // gmp_pow accepts just an integer + if ($b->compare(PHP_INT_MAX) > 0) { + throw new \UnexpectedValueException('Unable to raise to power greater than PHP_INT_MAX.'); + } + $b = gmp_intval($b->_rh); + } + $ret = new self(); + $ret->_rh = gmp_pow($this->_rh, $b); + return $ret; + } + + public function shiftRight($bits=8) + { + $ret = new self(); + $ret->_rh = gmp_div($this->_rh, gmp_pow(2, $bits)); + return $ret; + } + + public function shiftLeft($bits=8) + { + $ret = new self(); + $ret->_rh = gmp_mul($this->_rh, gmp_pow(2, $bits)); + return $ret; + } + + public function absoluteValue() + { + $ret = new self(); + $ret->_rh = gmp_abs($this->_rh); + return $ret; + } +} |