PageRenderTime 67ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php

https://bitbucket.org/openemr/openemr
PHP | 3754 lines | 2027 code | 494 blank | 1233 comment | 399 complexity | 9dff1fa96f84567b85082175a13679f5 MD5 | raw file
Possible License(s): Apache-2.0, AGPL-1.0, GPL-2.0, LGPL-3.0, BSD-3-Clause, Unlicense, MPL-2.0, GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Pure-PHP arbitrary precision integer arithmetic library.
  4. *
  5. * Supports base-2, base-10, base-16, and base-256 numbers. Uses the GMP or BCMath extensions, if available,
  6. * and an internal implementation, otherwise.
  7. *
  8. * PHP version 5
  9. *
  10. * {@internal (all DocBlock comments regarding implementation - such as the one that follows - refer to the
  11. * {@link self::MODE_INTERNAL self::MODE_INTERNAL} mode)
  12. *
  13. * BigInteger uses base-2**26 to perform operations such as multiplication and division and
  14. * base-2**52 (ie. two base 2**26 digits) to perform addition and subtraction. Because the largest possible
  15. * value when multiplying two base-2**26 numbers together is a base-2**52 number, double precision floating
  16. * point numbers - numbers that should be supported on most hardware and whose significand is 53 bits - are
  17. * used. As a consequence, bitwise operators such as >> and << cannot be used, nor can the modulo operator %,
  18. * which only supports integers. Although this fact will slow this library down, the fact that such a high
  19. * base is being used should more than compensate.
  20. *
  21. * Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format. ie.
  22. * (new \phpseclib\Math\BigInteger(pow(2, 26)))->value = array(0, 1)
  23. *
  24. * Useful resources are as follows:
  25. *
  26. * - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)}
  27. * - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)}
  28. * - Java's BigInteger classes. See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip
  29. *
  30. * Here's an example of how to use this library:
  31. * <code>
  32. * <?php
  33. * $a = new \phpseclib\Math\BigInteger(2);
  34. * $b = new \phpseclib\Math\BigInteger(3);
  35. *
  36. * $c = $a->add($b);
  37. *
  38. * echo $c->toString(); // outputs 5
  39. * ?>
  40. * </code>
  41. *
  42. * @category Math
  43. * @package BigInteger
  44. * @author Jim Wigginton <terrafrost@php.net>
  45. * @copyright 2006 Jim Wigginton
  46. * @license http://www.opensource.org/licenses/mit-license.html MIT License
  47. * @link http://pear.php.net/package/Math_BigInteger
  48. */
  49. namespace phpseclib\Math;
  50. use phpseclib\Crypt\Random;
  51. /**
  52. * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256
  53. * numbers.
  54. *
  55. * @package BigInteger
  56. * @author Jim Wigginton <terrafrost@php.net>
  57. * @access public
  58. */
  59. class BigInteger
  60. {
  61. /**#@+
  62. * Reduction constants
  63. *
  64. * @access private
  65. * @see BigInteger::_reduce()
  66. */
  67. /**
  68. * @see BigInteger::_montgomery()
  69. * @see BigInteger::_prepMontgomery()
  70. */
  71. const MONTGOMERY = 0;
  72. /**
  73. * @see BigInteger::_barrett()
  74. */
  75. const BARRETT = 1;
  76. /**
  77. * @see BigInteger::_mod2()
  78. */
  79. const POWEROF2 = 2;
  80. /**
  81. * @see BigInteger::_remainder()
  82. */
  83. const CLASSIC = 3;
  84. /**
  85. * @see BigInteger::__clone()
  86. */
  87. const NONE = 4;
  88. /**#@-*/
  89. /**#@+
  90. * Array constants
  91. *
  92. * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and
  93. * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them.
  94. *
  95. * @access private
  96. */
  97. /**
  98. * $result[self::VALUE] contains the value.
  99. */
  100. const VALUE = 0;
  101. /**
  102. * $result[self::SIGN] contains the sign.
  103. */
  104. const SIGN = 1;
  105. /**#@-*/
  106. /**#@+
  107. * @access private
  108. * @see BigInteger::_montgomery()
  109. * @see BigInteger::_barrett()
  110. */
  111. /**
  112. * Cache constants
  113. *
  114. * $cache[self::VARIABLE] tells us whether or not the cached data is still valid.
  115. */
  116. const VARIABLE = 0;
  117. /**
  118. * $cache[self::DATA] contains the cached data.
  119. */
  120. const DATA = 1;
  121. /**#@-*/
  122. /**#@+
  123. * Mode constants.
  124. *
  125. * @access private
  126. * @see BigInteger::__construct()
  127. */
  128. /**
  129. * To use the pure-PHP implementation
  130. */
  131. const MODE_INTERNAL = 1;
  132. /**
  133. * To use the BCMath library
  134. *
  135. * (if enabled; otherwise, the internal implementation will be used)
  136. */
  137. const MODE_BCMATH = 2;
  138. /**
  139. * To use the GMP library
  140. *
  141. * (if present; otherwise, either the BCMath or the internal implementation will be used)
  142. */
  143. const MODE_GMP = 3;
  144. /**#@-*/
  145. /**
  146. * Karatsuba Cutoff
  147. *
  148. * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication?
  149. *
  150. * @access private
  151. */
  152. const KARATSUBA_CUTOFF = 25;
  153. /**#@+
  154. * Static properties used by the pure-PHP implementation.
  155. *
  156. * @see __construct()
  157. */
  158. protected static $base;
  159. protected static $baseFull;
  160. protected static $maxDigit;
  161. protected static $msb;
  162. /**
  163. * $max10 in greatest $max10Len satisfying
  164. * $max10 = 10**$max10Len <= 2**$base.
  165. */
  166. protected static $max10;
  167. /**
  168. * $max10Len in greatest $max10Len satisfying
  169. * $max10 = 10**$max10Len <= 2**$base.
  170. */
  171. protected static $max10Len;
  172. protected static $maxDigit2;
  173. /**#@-*/
  174. /**
  175. * Holds the BigInteger's value.
  176. *
  177. * @var array
  178. * @access private
  179. */
  180. var $value;
  181. /**
  182. * Holds the BigInteger's magnitude.
  183. *
  184. * @var bool
  185. * @access private
  186. */
  187. var $is_negative = false;
  188. /**
  189. * Precision
  190. *
  191. * @see self::setPrecision()
  192. * @access private
  193. */
  194. var $precision = -1;
  195. /**
  196. * Precision Bitmask
  197. *
  198. * @see self::setPrecision()
  199. * @access private
  200. */
  201. var $bitmask = false;
  202. /**
  203. * Mode independent value used for serialization.
  204. *
  205. * If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for
  206. * a variable that'll be serializable regardless of whether or not extensions are being used. Unlike $this->value,
  207. * however, $this->hex is only calculated when $this->__sleep() is called.
  208. *
  209. * @see self::__sleep()
  210. * @see self::__wakeup()
  211. * @var string
  212. * @access private
  213. */
  214. var $hex;
  215. /**
  216. * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers.
  217. *
  218. * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using
  219. * two's compliment. The sole exception to this is -10, which is treated the same as 10 is.
  220. *
  221. * Here's an example:
  222. * <code>
  223. * <?php
  224. * $a = new \phpseclib\Math\BigInteger('0x32', 16); // 50 in base-16
  225. *
  226. * echo $a->toString(); // outputs 50
  227. * ?>
  228. * </code>
  229. *
  230. * @param $x base-10 number or base-$base number if $base set.
  231. * @param int $base
  232. * @return \phpseclib\Math\BigInteger
  233. * @access public
  234. */
  235. function __construct($x = 0, $base = 10)
  236. {
  237. if (!defined('MATH_BIGINTEGER_MODE')) {
  238. switch (true) {
  239. case extension_loaded('gmp'):
  240. define('MATH_BIGINTEGER_MODE', self::MODE_GMP);
  241. break;
  242. case extension_loaded('bcmath'):
  243. define('MATH_BIGINTEGER_MODE', self::MODE_BCMATH);
  244. break;
  245. default:
  246. define('MATH_BIGINTEGER_MODE', self::MODE_INTERNAL);
  247. }
  248. }
  249. if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
  250. // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
  251. ob_start();
  252. @phpinfo();
  253. $content = ob_get_contents();
  254. ob_end_clean();
  255. preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
  256. $versions = array();
  257. if (!empty($matches[1])) {
  258. for ($i = 0; $i < count($matches[1]); $i++) {
  259. $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
  260. // Remove letter part in OpenSSL version
  261. if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
  262. $versions[$matches[1][$i]] = $fullVersion;
  263. } else {
  264. $versions[$matches[1][$i]] = $m[0];
  265. }
  266. }
  267. }
  268. // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
  269. switch (true) {
  270. case !isset($versions['Header']):
  271. case !isset($versions['Library']):
  272. case $versions['Header'] == $versions['Library']:
  273. define('MATH_BIGINTEGER_OPENSSL_ENABLED', true);
  274. break;
  275. default:
  276. define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
  277. }
  278. }
  279. if (!defined('PHP_INT_SIZE')) {
  280. define('PHP_INT_SIZE', 4);
  281. }
  282. if (empty(self::$base) && MATH_BIGINTEGER_MODE == self::MODE_INTERNAL) {
  283. switch (PHP_INT_SIZE) {
  284. case 8: // use 64-bit integers if int size is 8 bytes
  285. self::$base = 31;
  286. self::$baseFull = 0x80000000;
  287. self::$maxDigit = 0x7FFFFFFF;
  288. self::$msb = 0x40000000;
  289. self::$max10 = 1000000000;
  290. self::$max10Len = 9;
  291. self::$maxDigit2 = pow(2, 62);
  292. break;
  293. //case 4: // use 64-bit floats if int size is 4 bytes
  294. default:
  295. self::$base = 26;
  296. self::$baseFull = 0x4000000;
  297. self::$maxDigit = 0x3FFFFFF;
  298. self::$msb = 0x2000000;
  299. self::$max10 = 10000000;
  300. self::$max10Len = 7;
  301. self::$maxDigit2 = pow(2, 52); // pow() prevents truncation
  302. }
  303. }
  304. switch (MATH_BIGINTEGER_MODE) {
  305. case self::MODE_GMP:
  306. switch (true) {
  307. case is_resource($x) && get_resource_type($x) == 'GMP integer':
  308. // PHP 5.6 switched GMP from using resources to objects
  309. case $x instanceof \GMP:
  310. $this->value = $x;
  311. return;
  312. }
  313. $this->value = gmp_init(0);
  314. break;
  315. case self::MODE_BCMATH:
  316. $this->value = '0';
  317. break;
  318. default:
  319. $this->value = array();
  320. }
  321. // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48
  322. // '0' is the only value like this per http://php.net/empty
  323. if (empty($x) && (abs($base) != 256 || $x !== '0')) {
  324. return;
  325. }
  326. switch ($base) {
  327. case -256:
  328. if (ord($x[0]) & 0x80) {
  329. $x = ~$x;
  330. $this->is_negative = true;
  331. }
  332. case 256:
  333. switch (MATH_BIGINTEGER_MODE) {
  334. case self::MODE_GMP:
  335. $sign = $this->is_negative ? '-' : '';
  336. $this->value = gmp_init($sign . '0x' . bin2hex($x));
  337. break;
  338. case self::MODE_BCMATH:
  339. // round $len to the nearest 4 (thanks, DavidMJ!)
  340. $len = (strlen($x) + 3) & 0xFFFFFFFC;
  341. $x = str_pad($x, $len, chr(0), STR_PAD_LEFT);
  342. for ($i = 0; $i < $len; $i+= 4) {
  343. $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32
  344. $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0);
  345. }
  346. if ($this->is_negative) {
  347. $this->value = '-' . $this->value;
  348. }
  349. break;
  350. // converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb)
  351. default:
  352. while (strlen($x)) {
  353. $this->value[] = $this->_bytes2int($this->_base256_rshift($x, self::$base));
  354. }
  355. }
  356. if ($this->is_negative) {
  357. if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
  358. $this->is_negative = false;
  359. }
  360. $temp = $this->add(new static('-1'));
  361. $this->value = $temp->value;
  362. }
  363. break;
  364. case 16:
  365. case -16:
  366. if ($base > 0 && $x[0] == '-') {
  367. $this->is_negative = true;
  368. $x = substr($x, 1);
  369. }
  370. $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x);
  371. $is_negative = false;
  372. if ($base < 0 && hexdec($x[0]) >= 8) {
  373. $this->is_negative = $is_negative = true;
  374. $x = bin2hex(~pack('H*', $x));
  375. }
  376. switch (MATH_BIGINTEGER_MODE) {
  377. case self::MODE_GMP:
  378. $temp = $this->is_negative ? '-0x' . $x : '0x' . $x;
  379. $this->value = gmp_init($temp);
  380. $this->is_negative = false;
  381. break;
  382. case self::MODE_BCMATH:
  383. $x = (strlen($x) & 1) ? '0' . $x : $x;
  384. $temp = new static(pack('H*', $x), 256);
  385. $this->value = $this->is_negative ? '-' . $temp->value : $temp->value;
  386. $this->is_negative = false;
  387. break;
  388. default:
  389. $x = (strlen($x) & 1) ? '0' . $x : $x;
  390. $temp = new static(pack('H*', $x), 256);
  391. $this->value = $temp->value;
  392. }
  393. if ($is_negative) {
  394. $temp = $this->add(new static('-1'));
  395. $this->value = $temp->value;
  396. }
  397. break;
  398. case 10:
  399. case -10:
  400. // (?<!^)(?:-).*: find any -'s that aren't at the beginning and then any characters that follow that
  401. // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
  402. // [^-0-9].*: find any non-numeric characters and then any characters that follow that
  403. $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
  404. switch (MATH_BIGINTEGER_MODE) {
  405. case self::MODE_GMP:
  406. $this->value = gmp_init($x);
  407. break;
  408. case self::MODE_BCMATH:
  409. // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different
  410. // results then doing it on '-1' does (modInverse does $x[0])
  411. $this->value = $x === '-' ? '0' : (string) $x;
  412. break;
  413. default:
  414. $temp = new static();
  415. $multiplier = new static();
  416. $multiplier->value = array(self::$max10);
  417. if ($x[0] == '-') {
  418. $this->is_negative = true;
  419. $x = substr($x, 1);
  420. }
  421. $x = str_pad($x, strlen($x) + ((self::$max10Len - 1) * strlen($x)) % self::$max10Len, 0, STR_PAD_LEFT);
  422. while (strlen($x)) {
  423. $temp = $temp->multiply($multiplier);
  424. $temp = $temp->add(new static($this->_int2bytes(substr($x, 0, self::$max10Len)), 256));
  425. $x = substr($x, self::$max10Len);
  426. }
  427. $this->value = $temp->value;
  428. }
  429. break;
  430. case 2: // base-2 support originally implemented by Lluis Pamies - thanks!
  431. case -2:
  432. if ($base > 0 && $x[0] == '-') {
  433. $this->is_negative = true;
  434. $x = substr($x, 1);
  435. }
  436. $x = preg_replace('#^([01]*).*#', '$1', $x);
  437. $x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT);
  438. $str = '0x';
  439. while (strlen($x)) {
  440. $part = substr($x, 0, 4);
  441. $str.= dechex(bindec($part));
  442. $x = substr($x, 4);
  443. }
  444. if ($this->is_negative) {
  445. $str = '-' . $str;
  446. }
  447. $temp = new static($str, 8 * $base); // ie. either -16 or +16
  448. $this->value = $temp->value;
  449. $this->is_negative = $temp->is_negative;
  450. break;
  451. default:
  452. // base not supported, so we'll let $this == 0
  453. }
  454. }
  455. /**
  456. * Converts a BigInteger to a byte string (eg. base-256).
  457. *
  458. * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
  459. * saved as two's compliment.
  460. *
  461. * Here's an example:
  462. * <code>
  463. * <?php
  464. * $a = new \phpseclib\Math\BigInteger('65');
  465. *
  466. * echo $a->toBytes(); // outputs chr(65)
  467. * ?>
  468. * </code>
  469. *
  470. * @param bool $twos_compliment
  471. * @return string
  472. * @access public
  473. * @internal Converts a base-2**26 number to base-2**8
  474. */
  475. function toBytes($twos_compliment = false)
  476. {
  477. if ($twos_compliment) {
  478. $comparison = $this->compare(new static());
  479. if ($comparison == 0) {
  480. return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
  481. }
  482. $temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy();
  483. $bytes = $temp->toBytes();
  484. if (empty($bytes)) { // eg. if the number we're trying to convert is -1
  485. $bytes = chr(0);
  486. }
  487. if (ord($bytes[0]) & 0x80) {
  488. $bytes = chr(0) . $bytes;
  489. }
  490. return $comparison < 0 ? ~$bytes : $bytes;
  491. }
  492. switch (MATH_BIGINTEGER_MODE) {
  493. case self::MODE_GMP:
  494. if (gmp_cmp($this->value, gmp_init(0)) == 0) {
  495. return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
  496. }
  497. $temp = gmp_strval(gmp_abs($this->value), 16);
  498. $temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
  499. $temp = pack('H*', $temp);
  500. return $this->precision > 0 ?
  501. substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
  502. ltrim($temp, chr(0));
  503. case self::MODE_BCMATH:
  504. if ($this->value === '0') {
  505. return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
  506. }
  507. $value = '';
  508. $current = $this->value;
  509. if ($current[0] == '-') {
  510. $current = substr($current, 1);
  511. }
  512. while (bccomp($current, '0', 0) > 0) {
  513. $temp = bcmod($current, '16777216');
  514. $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value;
  515. $current = bcdiv($current, '16777216', 0);
  516. }
  517. return $this->precision > 0 ?
  518. substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
  519. ltrim($value, chr(0));
  520. }
  521. if (!count($this->value)) {
  522. return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
  523. }
  524. $result = $this->_int2bytes($this->value[count($this->value) - 1]);
  525. $temp = $this->copy();
  526. for ($i = count($temp->value) - 2; $i >= 0; --$i) {
  527. $temp->_base256_lshift($result, self::$base);
  528. $result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT);
  529. }
  530. return $this->precision > 0 ?
  531. str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) :
  532. $result;
  533. }
  534. /**
  535. * Converts a BigInteger to a hex string (eg. base-16)).
  536. *
  537. * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
  538. * saved as two's compliment.
  539. *
  540. * Here's an example:
  541. * <code>
  542. * <?php
  543. * $a = new \phpseclib\Math\BigInteger('65');
  544. *
  545. * echo $a->toHex(); // outputs '41'
  546. * ?>
  547. * </code>
  548. *
  549. * @param bool $twos_compliment
  550. * @return string
  551. * @access public
  552. * @internal Converts a base-2**26 number to base-2**8
  553. */
  554. function toHex($twos_compliment = false)
  555. {
  556. return bin2hex($this->toBytes($twos_compliment));
  557. }
  558. /**
  559. * Converts a BigInteger to a bit string (eg. base-2).
  560. *
  561. * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
  562. * saved as two's compliment.
  563. *
  564. * Here's an example:
  565. * <code>
  566. * <?php
  567. * $a = new \phpseclib\Math\BigInteger('65');
  568. *
  569. * echo $a->toBits(); // outputs '1000001'
  570. * ?>
  571. * </code>
  572. *
  573. * @param bool $twos_compliment
  574. * @return string
  575. * @access public
  576. * @internal Converts a base-2**26 number to base-2**2
  577. */
  578. function toBits($twos_compliment = false)
  579. {
  580. $hex = $this->toHex($twos_compliment);
  581. $bits = '';
  582. for ($i = strlen($hex) - 8, $start = strlen($hex) & 7; $i >= $start; $i-=8) {
  583. $bits = str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT) . $bits;
  584. }
  585. if ($start) { // hexdec('') == 0
  586. $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8, '0', STR_PAD_LEFT) . $bits;
  587. }
  588. $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0');
  589. if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) {
  590. return '0' . $result;
  591. }
  592. return $result;
  593. }
  594. /**
  595. * Converts a BigInteger to a base-10 number.
  596. *
  597. * Here's an example:
  598. * <code>
  599. * <?php
  600. * $a = new \phpseclib\Math\BigInteger('50');
  601. *
  602. * echo $a->toString(); // outputs 50
  603. * ?>
  604. * </code>
  605. *
  606. * @return string
  607. * @access public
  608. * @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10)
  609. */
  610. function toString()
  611. {
  612. switch (MATH_BIGINTEGER_MODE) {
  613. case self::MODE_GMP:
  614. return gmp_strval($this->value);
  615. case self::MODE_BCMATH:
  616. if ($this->value === '0') {
  617. return '0';
  618. }
  619. return ltrim($this->value, '0');
  620. }
  621. if (!count($this->value)) {
  622. return '0';
  623. }
  624. $temp = $this->copy();
  625. $temp->is_negative = false;
  626. $divisor = new static();
  627. $divisor->value = array(self::$max10);
  628. $result = '';
  629. while (count($temp->value)) {
  630. list($temp, $mod) = $temp->divide($divisor);
  631. $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', self::$max10Len, '0', STR_PAD_LEFT) . $result;
  632. }
  633. $result = ltrim($result, '0');
  634. if (empty($result)) {
  635. $result = '0';
  636. }
  637. if ($this->is_negative) {
  638. $result = '-' . $result;
  639. }
  640. return $result;
  641. }
  642. /**
  643. * Copy an object
  644. *
  645. * PHP5 passes objects by reference while PHP4 passes by value. As such, we need a function to guarantee
  646. * that all objects are passed by value, when appropriate. More information can be found here:
  647. *
  648. * {@link http://php.net/language.oop5.basic#51624}
  649. *
  650. * @access public
  651. * @see self::__clone()
  652. * @return \phpseclib\Math\BigInteger
  653. */
  654. function copy()
  655. {
  656. $temp = new static();
  657. $temp->value = $this->value;
  658. $temp->is_negative = $this->is_negative;
  659. $temp->precision = $this->precision;
  660. $temp->bitmask = $this->bitmask;
  661. return $temp;
  662. }
  663. /**
  664. * __toString() magic method
  665. *
  666. * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call
  667. * toString().
  668. *
  669. * @access public
  670. * @internal Implemented per a suggestion by Techie-Michael - thanks!
  671. */
  672. function __toString()
  673. {
  674. return $this->toString();
  675. }
  676. /**
  677. * __clone() magic method
  678. *
  679. * Although you can call BigInteger::__toString() directly in PHP5, you cannot call BigInteger::__clone() directly
  680. * in PHP5. You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5
  681. * only syntax of $y = clone $x. As such, if you're trying to write an application that works on both PHP4 and
  682. * PHP5, call BigInteger::copy(), instead.
  683. *
  684. * @access public
  685. * @see self::copy()
  686. * @return \phpseclib\Math\BigInteger
  687. */
  688. function __clone()
  689. {
  690. return $this->copy();
  691. }
  692. /**
  693. * __sleep() magic method
  694. *
  695. * Will be called, automatically, when serialize() is called on a BigInteger object.
  696. *
  697. * @see self::__wakeup()
  698. * @access public
  699. */
  700. function __sleep()
  701. {
  702. $this->hex = $this->toHex(true);
  703. $vars = array('hex');
  704. if ($this->precision > 0) {
  705. $vars[] = 'precision';
  706. }
  707. return $vars;
  708. }
  709. /**
  710. * __wakeup() magic method
  711. *
  712. * Will be called, automatically, when unserialize() is called on a BigInteger object.
  713. *
  714. * @see self::__sleep()
  715. * @access public
  716. */
  717. function __wakeup()
  718. {
  719. $temp = new static($this->hex, -16);
  720. $this->value = $temp->value;
  721. $this->is_negative = $temp->is_negative;
  722. if ($this->precision > 0) {
  723. // recalculate $this->bitmask
  724. $this->setPrecision($this->precision);
  725. }
  726. }
  727. /**
  728. * __debugInfo() magic method
  729. *
  730. * Will be called, automatically, when print_r() or var_dump() are called
  731. *
  732. * @access public
  733. */
  734. function __debugInfo()
  735. {
  736. $opts = array();
  737. switch (MATH_BIGINTEGER_MODE) {
  738. case self::MODE_GMP:
  739. $engine = 'gmp';
  740. break;
  741. case self::MODE_BCMATH:
  742. $engine = 'bcmath';
  743. break;
  744. case self::MODE_INTERNAL:
  745. $engine = 'internal';
  746. $opts[] = PHP_INT_SIZE == 8 ? '64-bit' : '32-bit';
  747. }
  748. if (MATH_BIGINTEGER_MODE != self::MODE_GMP && defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
  749. $opts[] = 'OpenSSL';
  750. }
  751. if (!empty($opts)) {
  752. $engine.= ' (' . implode($opts, ', ') . ')';
  753. }
  754. return array(
  755. 'value' => '0x' . $this->toHex(true),
  756. 'engine' => $engine
  757. );
  758. }
  759. /**
  760. * Adds two BigIntegers.
  761. *
  762. * Here's an example:
  763. * <code>
  764. * <?php
  765. * $a = new \phpseclib\Math\BigInteger('10');
  766. * $b = new \phpseclib\Math\BigInteger('20');
  767. *
  768. * $c = $a->add($b);
  769. *
  770. * echo $c->toString(); // outputs 30
  771. * ?>
  772. * </code>
  773. *
  774. * @param \phpseclib\Math\BigInteger $y
  775. * @return \phpseclib\Math\BigInteger
  776. * @access public
  777. * @internal Performs base-2**52 addition
  778. */
  779. function add($y)
  780. {
  781. switch (MATH_BIGINTEGER_MODE) {
  782. case self::MODE_GMP:
  783. $temp = new static();
  784. $temp->value = gmp_add($this->value, $y->value);
  785. return $this->_normalize($temp);
  786. case self::MODE_BCMATH:
  787. $temp = new static();
  788. $temp->value = bcadd($this->value, $y->value, 0);
  789. return $this->_normalize($temp);
  790. }
  791. $temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative);
  792. $result = new static();
  793. $result->value = $temp[self::VALUE];
  794. $result->is_negative = $temp[self::SIGN];
  795. return $this->_normalize($result);
  796. }
  797. /**
  798. * Performs addition.
  799. *
  800. * @param array $x_value
  801. * @param bool $x_negative
  802. * @param array $y_value
  803. * @param bool $y_negative
  804. * @return array
  805. * @access private
  806. */
  807. function _add($x_value, $x_negative, $y_value, $y_negative)
  808. {
  809. $x_size = count($x_value);
  810. $y_size = count($y_value);
  811. if ($x_size == 0) {
  812. return array(
  813. self::VALUE => $y_value,
  814. self::SIGN => $y_negative
  815. );
  816. } elseif ($y_size == 0) {
  817. return array(
  818. self::VALUE => $x_value,
  819. self::SIGN => $x_negative
  820. );
  821. }
  822. // subtract, if appropriate
  823. if ($x_negative != $y_negative) {
  824. if ($x_value == $y_value) {
  825. return array(
  826. self::VALUE => array(),
  827. self::SIGN => false
  828. );
  829. }
  830. $temp = $this->_subtract($x_value, false, $y_value, false);
  831. $temp[self::SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ?
  832. $x_negative : $y_negative;
  833. return $temp;
  834. }
  835. if ($x_size < $y_size) {
  836. $size = $x_size;
  837. $value = $y_value;
  838. } else {
  839. $size = $y_size;
  840. $value = $x_value;
  841. }
  842. $value[count($value)] = 0; // just in case the carry adds an extra digit
  843. $carry = 0;
  844. for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {
  845. $sum = $x_value[$j] * self::$baseFull + $x_value[$i] + $y_value[$j] * self::$baseFull + $y_value[$i] + $carry;
  846. $carry = $sum >= self::$maxDigit2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
  847. $sum = $carry ? $sum - self::$maxDigit2 : $sum;
  848. $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
  849. $value[$i] = (int) ($sum - self::$baseFull * $temp); // eg. a faster alternative to fmod($sum, 0x4000000)
  850. $value[$j] = $temp;
  851. }
  852. if ($j == $size) { // ie. if $y_size is odd
  853. $sum = $x_value[$i] + $y_value[$i] + $carry;
  854. $carry = $sum >= self::$baseFull;
  855. $value[$i] = $carry ? $sum - self::$baseFull : $sum;
  856. ++$i; // ie. let $i = $j since we've just done $value[$i]
  857. }
  858. if ($carry) {
  859. for (; $value[$i] == self::$maxDigit; ++$i) {
  860. $value[$i] = 0;
  861. }
  862. ++$value[$i];
  863. }
  864. return array(
  865. self::VALUE => $this->_trim($value),
  866. self::SIGN => $x_negative
  867. );
  868. }
  869. /**
  870. * Subtracts two BigIntegers.
  871. *
  872. * Here's an example:
  873. * <code>
  874. * <?php
  875. * $a = new \phpseclib\Math\BigInteger('10');
  876. * $b = new \phpseclib\Math\BigInteger('20');
  877. *
  878. * $c = $a->subtract($b);
  879. *
  880. * echo $c->toString(); // outputs -10
  881. * ?>
  882. * </code>
  883. *
  884. * @param \phpseclib\Math\BigInteger $y
  885. * @return \phpseclib\Math\BigInteger
  886. * @access public
  887. * @internal Performs base-2**52 subtraction
  888. */
  889. function subtract($y)
  890. {
  891. switch (MATH_BIGINTEGER_MODE) {
  892. case self::MODE_GMP:
  893. $temp = new static();
  894. $temp->value = gmp_sub($this->value, $y->value);
  895. return $this->_normalize($temp);
  896. case self::MODE_BCMATH:
  897. $temp = new static();
  898. $temp->value = bcsub($this->value, $y->value, 0);
  899. return $this->_normalize($temp);
  900. }
  901. $temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative);
  902. $result = new static();
  903. $result->value = $temp[self::VALUE];
  904. $result->is_negative = $temp[self::SIGN];
  905. return $this->_normalize($result);
  906. }
  907. /**
  908. * Performs subtraction.
  909. *
  910. * @param array $x_value
  911. * @param bool $x_negative
  912. * @param array $y_value
  913. * @param bool $y_negative
  914. * @return array
  915. * @access private
  916. */
  917. function _subtract($x_value, $x_negative, $y_value, $y_negative)
  918. {
  919. $x_size = count($x_value);
  920. $y_size = count($y_value);
  921. if ($x_size == 0) {
  922. return array(
  923. self::VALUE => $y_value,
  924. self::SIGN => !$y_negative
  925. );
  926. } elseif ($y_size == 0) {
  927. return array(
  928. self::VALUE => $x_value,
  929. self::SIGN => $x_negative
  930. );
  931. }
  932. // add, if appropriate (ie. -$x - +$y or +$x - -$y)
  933. if ($x_negative != $y_negative) {
  934. $temp = $this->_add($x_value, false, $y_value, false);
  935. $temp[self::SIGN] = $x_negative;
  936. return $temp;
  937. }
  938. $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative);
  939. if (!$diff) {
  940. return array(
  941. self::VALUE => array(),
  942. self::SIGN => false
  943. );
  944. }
  945. // switch $x and $y around, if appropriate.
  946. if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) {
  947. $temp = $x_value;
  948. $x_value = $y_value;
  949. $y_value = $temp;
  950. $x_negative = !$x_negative;
  951. $x_size = count($x_value);
  952. $y_size = count($y_value);
  953. }
  954. // at this point, $x_value should be at least as big as - if not bigger than - $y_value
  955. $carry = 0;
  956. for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) {
  957. $sum = $x_value[$j] * self::$baseFull + $x_value[$i] - $y_value[$j] * self::$baseFull - $y_value[$i] - $carry;
  958. $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
  959. $sum = $carry ? $sum + self::$maxDigit2 : $sum;
  960. $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
  961. $x_value[$i] = (int) ($sum - self::$baseFull * $temp);
  962. $x_value[$j] = $temp;
  963. }
  964. if ($j == $y_size) { // ie. if $y_size is odd
  965. $sum = $x_value[$i] - $y_value[$i] - $carry;
  966. $carry = $sum < 0;
  967. $x_value[$i] = $carry ? $sum + self::$baseFull : $sum;
  968. ++$i;
  969. }
  970. if ($carry) {
  971. for (; !$x_value[$i]; ++$i) {
  972. $x_value[$i] = self::$maxDigit;
  973. }
  974. --$x_value[$i];
  975. }
  976. return array(
  977. self::VALUE => $this->_trim($x_value),
  978. self::SIGN => $x_negative
  979. );
  980. }
  981. /**
  982. * Multiplies two BigIntegers
  983. *
  984. * Here's an example:
  985. * <code>
  986. * <?php
  987. * $a = new \phpseclib\Math\BigInteger('10');
  988. * $b = new \phpseclib\Math\BigInteger('20');
  989. *
  990. * $c = $a->multiply($b);
  991. *
  992. * echo $c->toString(); // outputs 200
  993. * ?>
  994. * </code>
  995. *
  996. * @param \phpseclib\Math\BigInteger $x
  997. * @return \phpseclib\Math\BigInteger
  998. * @access public
  999. */
  1000. function multiply($x)
  1001. {
  1002. switch (MATH_BIGINTEGER_MODE) {
  1003. case self::MODE_GMP:
  1004. $temp = new static();
  1005. $temp->value = gmp_mul($this->value, $x->value);
  1006. return $this->_normalize($temp);
  1007. case self::MODE_BCMATH:
  1008. $temp = new static();
  1009. $temp->value = bcmul($this->value, $x->value, 0);
  1010. return $this->_normalize($temp);
  1011. }
  1012. $temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative);
  1013. $product = new static();
  1014. $product->value = $temp[self::VALUE];
  1015. $product->is_negative = $temp[self::SIGN];
  1016. return $this->_normalize($product);
  1017. }
  1018. /**
  1019. * Performs multiplication.
  1020. *
  1021. * @param array $x_value
  1022. * @param bool $x_negative
  1023. * @param array $y_value
  1024. * @param bool $y_negative
  1025. * @return array
  1026. * @access private
  1027. */
  1028. function _multiply($x_value, $x_negative, $y_value, $y_negative)
  1029. {
  1030. //if ( $x_value == $y_value ) {
  1031. // return array(
  1032. // self::VALUE => $this->_square($x_value),
  1033. // self::SIGN => $x_sign != $y_value
  1034. // );
  1035. //}
  1036. $x_length = count($x_value);
  1037. $y_length = count($y_value);
  1038. if (!$x_length || !$y_length) { // a 0 is being multiplied
  1039. return array(
  1040. self::VALUE => array(),
  1041. self::SIGN => false
  1042. );
  1043. }
  1044. return array(
  1045. self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ?
  1046. $this->_trim($this->_regularMultiply($x_value, $y_value)) :
  1047. $this->_trim($this->_karatsuba($x_value, $y_value)),
  1048. self::SIGN => $x_negative != $y_negative
  1049. );
  1050. }
  1051. /**
  1052. * Performs long multiplication on two BigIntegers
  1053. *
  1054. * Modeled after 'multiply' in MutableBigInteger.java.
  1055. *
  1056. * @param array $x_value
  1057. * @param array $y_value
  1058. * @return array
  1059. * @access private
  1060. */
  1061. function _regularMultiply($x_value, $y_value)
  1062. {
  1063. $x_length = count($x_value);
  1064. $y_length = count($y_value);
  1065. if (!$x_length || !$y_length) { // a 0 is being multiplied
  1066. return array();
  1067. }
  1068. if ($x_length < $y_length) {
  1069. $temp = $x_value;
  1070. $x_value = $y_value;
  1071. $y_value = $temp;
  1072. $x_length = count($x_value);
  1073. $y_length = count($y_value);
  1074. }
  1075. $product_value = $this->_array_repeat(0, $x_length + $y_length);
  1076. // the following for loop could be removed if the for loop following it
  1077. // (the one with nested for loops) initially set $i to 0, but
  1078. // doing so would also make the result in one set of unnecessary adds,
  1079. // since on the outermost loops first pass, $product->value[$k] is going
  1080. // to always be 0
  1081. $carry = 0;
  1082. for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0
  1083. $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
  1084. $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
  1085. $product_value[$j] = (int) ($temp - self::$baseFull * $carry);
  1086. }
  1087. $product_value[$j] = $carry;
  1088. // the above for loop is what the previous comment was talking about. the
  1089. // following for loop is the "one with nested for loops"
  1090. for ($i = 1; $i < $y_length; ++$i) {
  1091. $carry = 0;
  1092. for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) {
  1093. $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
  1094. $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
  1095. $product_value[$k] = (int) ($temp - self::$baseFull * $carry);
  1096. }
  1097. $product_value[$k] = $carry;
  1098. }
  1099. return $product_value;
  1100. }
  1101. /**
  1102. * Performs Karatsuba multiplication on two BigIntegers
  1103. *
  1104. * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
  1105. * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}.
  1106. *
  1107. * @param array $x_value
  1108. * @param array $y_value
  1109. * @return array
  1110. * @access private
  1111. */
  1112. function _karatsuba($x_value, $y_value)
  1113. {
  1114. $m = min(count($x_value) >> 1, count($y_value) >> 1);
  1115. if ($m < self::KARATSUBA_CUTOFF) {
  1116. return $this->_regularMultiply($x_value, $y_value);
  1117. }
  1118. $x1 = array_slice($x_value, $m);
  1119. $x0 = array_slice($x_value, 0, $m);
  1120. $y1 = array_slice($y_value, $m);
  1121. $y0 = array_slice($y_value, 0, $m);
  1122. $z2 = $this->_karatsuba($x1, $y1);
  1123. $z0 = $this->_karatsuba($x0, $y0);
  1124. $z1 = $this->_add($x1, false, $x0, false);
  1125. $temp = $this->_add($y1, false, $y0, false);
  1126. $z1 = $this->_karatsuba($z1[self::VALUE], $temp[self::VALUE]);
  1127. $temp = $this->_add($z2, false, $z0, false);
  1128. $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false);
  1129. $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
  1130. $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]);
  1131. $xy = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]);
  1132. $xy = $this->_add($xy[self::VALUE], $xy[self::SIGN], $z0, false);
  1133. return $xy[self::VALUE];
  1134. }
  1135. /**
  1136. * Performs squaring
  1137. *
  1138. * @param array $x
  1139. * @return array
  1140. * @access private
  1141. */
  1142. function _square($x = false)
  1143. {
  1144. return count($x) < 2 * self::KARATSUBA_CUTOFF ?
  1145. $this->_trim($this->_baseSquare($x)) :
  1146. $this->_trim($this->_karatsubaSquare($x));
  1147. }
  1148. /**
  1149. * Performs traditional squaring on two BigIntegers
  1150. *
  1151. * Squaring can be done faster than multiplying a number by itself can be. See
  1152. * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} /
  1153. * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information.
  1154. *
  1155. * @param array $value
  1156. * @return array
  1157. * @access private
  1158. */
  1159. function _baseSquare($value)
  1160. {
  1161. if (empty($value)) {
  1162. return array();
  1163. }
  1164. $square_value = $this->_array_repeat(0, 2 * count($value));
  1165. for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) {
  1166. $i2 = $i << 1;
  1167. $temp = $square_value[$i2] + $value[$i] * $value[$i];
  1168. $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
  1169. $square_value[$i2] = (int) ($temp - self::$baseFull * $carry);
  1170. // note how we start from $i+1 instead of 0 as we do in multiplication.
  1171. for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) {
  1172. $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry;
  1173. $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
  1174. $square_value[$k] = (int) ($temp - self::$baseFull * $carry);
  1175. }
  1176. // the following line can yield values larger 2**15. at this point, PHP should switch
  1177. // over to floats.
  1178. $square_value[$i + $max_index + 1] = $carry;
  1179. }
  1180. return $square_value;
  1181. }
  1182. /**
  1183. * Performs Karatsuba "squaring" on two BigIntegers
  1184. *
  1185. * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
  1186. * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}.
  1187. *
  1188. * @param array $value
  1189. * @return array
  1190. * @access private
  1191. */
  1192. function _karatsubaSquare($value)
  1193. {
  1194. $m = count($value) >> 1;
  1195. if ($m < self::KARATSUBA_CUTOFF) {
  1196. return $this->_baseSquare($value);
  1197. }
  1198. $x1 = array_slice($value, $m);
  1199. $x0 = array_slice($value, 0, $m);
  1200. $z2 = $this->_karatsubaSquare($x1);
  1201. $z0 = $this->_karatsubaSquare($x0);
  1202. $z1 = $this->_add($x1, false, $x0, false);
  1203. $z1 = $this->_karatsubaSquare($z1[self::VALUE]);
  1204. $temp = $this->_add($z2, false, $z0, false);
  1205. $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false);
  1206. $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
  1207. $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]);
  1208. $xx = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]);
  1209. $xx = $this->_add($xx[self::VALUE], $xx[self::SIGN], $z0, false);
  1210. return $xx[self::VALUE];
  1211. }
  1212. /**
  1213. * Divides two BigIntegers.
  1214. *
  1215. * Returns an array whose first element contains the quotient and whose second element contains the
  1216. * "common residue". If the remainder would be positive, the "common residue" and the remainder are the
  1217. * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder
  1218. * and the divisor (basically, the "common residue" is the first positive modulo).
  1219. *
  1220. * Here's an example:
  1221. * <code>
  1222. * <?php
  1223. * $a = new \phpseclib\Math\BigInteger('10');
  1224. * $b = new \phpseclib\Math\BigInteger('20');
  1225. *
  1226. * list($quotient, $remainder) = $a->divide($b);
  1227. *
  1228. * echo $quotient->toString(); // outputs 0
  1229. * echo "\r\n";
  1230. * echo $remainder->toString(); // outputs 10
  1231. * ?>
  1232. * </code>
  1233. *
  1234. * @param \phpseclib\Math\BigInteger $y
  1235. * @return array
  1236. * @access public
  1237. * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}.
  1238. */
  1239. function divide($y)
  1240. {
  1241. switch (MATH_BIGINTEGER_MODE) {
  1242. case self::MODE_GMP:
  1243. $quotient = new static();
  1244. $remainder = new static();
  1245. list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);
  1246. if (gmp_sign($remainder->value) < 0) {
  1247. $remainder->value = gmp_add($remainder->value, gmp_abs($y->value));
  1248. }
  1249. return array($this->_normalize($quotient), $this->_normalize($remainder));
  1250. case self::MODE_BCMATH:
  1251. $quotient = new static();
  1252. $remainder = new static();
  1253. $quotient->value = bcdiv($this->value, $y->value, 0);
  1254. $remainder->value = bcmod($this->value, $y->value);
  1255. if ($remainder->value[0] == '-') {
  1256. $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0);
  1257. }
  1258. return array($this->_normalize($quotient), $this->_normalize($remainder));
  1259. }
  1260. if (count($y->value) == 1) {
  1261. list($q, $r) = $this->_divide_digit($this->value, $y->value[0]);
  1262. $quotient = new static();
  1263. $remainder = new static();
  1264. $quotient->value = $q;
  1265. $remainder->value = array($r);
  1266. $quotient->is_negative = $this->is_negative != $y->is_negative;
  1267. return array($this->_normalize($quotient), $this->_normalize($remainder));
  1268. }
  1269. static $zero;
  1270. if (!isset($zero)) {
  1271. $zero = new static();
  1272. }
  1273. $x = $this->copy();
  1274. $y = $y->copy();
  1275. $x_sign = $x->is_negative;
  1276. $y_sign = $y->is_negative;
  1277. $x->is_negative = $y->is_negative = false;
  1278. $diff = $x->compare($y);
  1279. if (!$diff) {
  1280. $temp = new static();
  1281. $temp->value = array(1);
  1282. $temp->is_negative = $x_sign != $y_sign;
  1283. return array($this->_normalize($temp), $this->_normalize(new static()));
  1284. }
  1285. if ($diff < 0) {
  1286. // if $x is negative, "add" $y.
  1287. if ($x_sign) {
  1288. $x = $y->subtract($x);
  1289. }
  1290. return array($this->_normalize(new static()), $this->_normalize($x));
  1291. }
  1292. // normalize $x and $y as described in HAC 14.23 / 14.24
  1293. $msb = $y->value[count($y->value) - 1];
  1294. for ($shift = 0; !($msb & self::$msb); ++$shift) {
  1295. $msb <<= 1;
  1296. }
  1297. $x->_lshift($shift);
  1298. $y->_lshift($shift);
  1299. $y_value = &$y->value;
  1300. $x_max = count($x->value) - 1;
  1301. $y_max = count($y->value) - 1;
  1302. $quotient = new static();
  1303. $quotient_value = &$quotient->value;
  1304. $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1);
  1305. static $temp, $lhs, $rhs;
  1306. if (!isset($temp)) {
  1307. $temp = new static();
  1308. $lhs = new static();
  1309. $rhs = new static();
  1310. }
  1311. $temp_value = &$temp->value;
  1312. $rhs_value = &$rhs->value;
  1313. // $temp = $y << ($x_max - $y_max-1) in base 2**26
  1314. $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
  1315. while ($x->compare($temp) >= 0) {
  1316. // calculate the "common residue"
  1317. ++$quotient_value[$x_max - $y_max];
  1318. $x = $x->subtract($temp);
  1319. $x_max = count($x->value) - 1;
  1320. }
  1321. for ($i = $x_max; $i >= $y_max + 1; --$i) {
  1322. $x_value = &$x->value;
  1323. $x_window = array(
  1324. isset($x_value[$i]) ? $x_value[$i] : 0,
  1325. isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0,
  1326. isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0
  1327. );
  1328. $y_window = array(
  1329. $y_value[$y_max],
  1330. ($y_max > 0) ? $y_value[$y_max - 1] : 0
  1331. );
  1332. $q_index = $i - $y_max - 1;
  1333. if ($x_window[0] == $y_window[0]) {
  1334. $quotient_value[$q_index] = self::$maxDigit;
  1335. } else {
  1336. $quotient_value[$q_index] = $this->_safe_divide(
  1337. $x_window[0] * self::$baseFull + $x_window[1],
  1338. $y_window[0]
  1339. );
  1340. }
  1341. $temp_value = array($y_window[1], $y_window[0]);
  1342. $lhs->value = array($quotient_value[$q_index]);
  1343. $lhs = $lhs->multiply($temp);
  1344. $rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
  1345. while ($lhs->compare($rhs) > 0) {
  1346. --$quotient_value[$q_index];
  1347. $lhs->value = array($quotient_value[$q_index]);
  1348. $lhs = $lhs->multiply($temp);
  1349. }
  1350. $adjust = $this->_array_repeat(0, $q_index);
  1351. $temp_value = array($quotient_value[$q_index]);
  1352. $temp = $temp->multiply($y);
  1353. $temp_value = &$temp->value;
  1354. $temp_value = array_merge($adjust, $temp_value);
  1355. $x = $x->subtract($temp);
  1356. if ($x->compare($zero) < 0) {
  1357. $temp_value = array_merge($adjust, $y_value);
  1358. $x = $x->add($temp);
  1359. --$quotient_value[$q_index];
  1360. }
  1361. $x_max = count($x_value) - 1;
  1362. }
  1363. // unnormalize the remainder
  1364. $x->_rshift($shift);
  1365. $quotient->is_negative = $x_sign != $y_sign;
  1366. // calculate the "common residue", if appropriate
  1367. if ($x_sign) {
  1368. $y->_rshift($shift);
  1369. $x = $y->subtract($x);
  1370. }
  1371. return array($this->_normalize($quotient), $this->_normalize($x));
  1372. }
  1373. /**
  1374. * Divides a BigInteger by a regular integer
  1375. *
  1376. * abc / x = a00 / x + b0 / x + c / x
  1377. *
  1378. * @param array $dividend
  1379. * @param array $divisor
  1380. * @return array
  1381. * @access private
  1382. */
  1383. function _divide_digit($dividend, $divisor)
  1384. {
  1385. $carry = 0;
  1386. $result = array();
  1387. for ($i = count($dividend) - 1; $i >= 0; --$i) {
  1388. $temp = self::$baseFull * $carry + $dividend[$i];
  1389. $result[$i] = $this->_safe_divide($temp, $divisor);
  1390. $carry = (int) ($temp - $divisor * $result[$i]);
  1391. }
  1392. return array($result, $carry);
  1393. }
  1394. /**
  1395. * Performs modular exponentiation.
  1396. *
  1397. * Here's an example:
  1398. * <code>
  1399. * <?php
  1400. * $a = new \phpseclib\Math\BigInteger('10');
  1401. * $b = new \phpseclib\Math\BigInteger('20');
  1402. * $c = new \phpseclib\Math\BigInteger('30');
  1403. *
  1404. * $c = $a->modPow($b, $c);
  1405. *
  1406. * echo $c->toString(); // outputs 10
  1407. * ?>
  1408. * </code>
  1409. *
  1410. * @param \phpseclib\Math\BigInteger $e
  1411. * @param \phpseclib\Math\BigInteger $n
  1412. * @return \phpseclib\Math\BigInteger
  1413. * @access public
  1414. * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and
  1415. * and although the approach involving repeated squaring does vastly better, it, too, is impractical
  1416. * for our purposes. The reason being that division - by far the most complicated and time-consuming
  1417. * of the basic operations (eg. +,-,*,/) - occurs multiple times within it.
  1418. *
  1419. * Modular reductions resolve this issue. Although an individual modular reduction takes more time
  1420. * then an individual division, when performed in succession (with the same modulo), they're a lot faster.
  1421. *
  1422. * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction,
  1423. * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the
  1424. * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because
  1425. * the product of two odd numbers is odd), but what about when RSA isn't used?
  1426. *
  1427. * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a
  1428. * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the
  1429. * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however,
  1430. * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and
  1431. * the other, a power of two - and recombine them, later. This is the method that this modPow function uses.
  1432. * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.
  1433. */
  1434. function modPow($e, $n)
  1435. {
  1436. $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs();
  1437. if ($e->compare(new static()) < 0) {
  1438. $e = $e->abs();
  1439. $temp = $this->modInverse($n);
  1440. if ($temp === false) {
  1441. return false;
  1442. }
  1443. return $this->_normalize($temp->modPow($e, $n));
  1444. }
  1445. if (MATH_BIGINTEGER_MODE == self::MODE_GMP) {
  1446. $temp = new static();
  1447. $temp->value = gmp_powm($this->value, $e->value, $n->value);
  1448. return $this->_normalize($temp);
  1449. }
  1450. if ($this->compare(new static()) < 0 || $this->compare($n) > 0) {
  1451. list(, $temp) = $this->divide($n);
  1452. return $temp->modPow($e, $n);
  1453. }
  1454. if (defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
  1455. $components = array(
  1456. 'modulus' => $n->toBytes(true),
  1457. 'publicExponent' => $e->toBytes(true)
  1458. );
  1459. $components = array(
  1460. 'modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']),
  1461. 'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent'])
  1462. );
  1463. $RSAPublicKey = pack(
  1464. 'Ca*a*a*',
  1465. 48,
  1466. $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
  1467. $components['modulus'],
  1468. $components['publicExponent']
  1469. );
  1470. $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
  1471. $RSAPublicKey = chr(0) . $RSAPublicKey;
  1472. $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey;
  1473. $encapsulated = pack(
  1474. 'Ca*a*',
  1475. 48,
  1476. $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)),
  1477. $rsaOID . $RSAPublicKey
  1478. );
  1479. $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
  1480. chunk_split(base64_encode($encapsulated)) .
  1481. '-----END PUBLIC KEY-----';
  1482. $plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT);
  1483. if (openssl_public_encrypt($plaintext, $result, $RSAPublicKey, OPENSSL_NO_PADDING)) {
  1484. return new static($result, 256);
  1485. }
  1486. }
  1487. if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
  1488. $temp = new static();
  1489. $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
  1490. return $this->_normalize($temp);
  1491. }
  1492. if (empty($e->value)) {
  1493. $temp = new static();
  1494. $temp->value = array(1);
  1495. return $this->_normalize($temp);
  1496. }
  1497. if ($e->value == array(1)) {
  1498. list(, $temp) = $this->divide($n);
  1499. return $this->_normalize($temp);
  1500. }
  1501. if ($e->value == array(2)) {
  1502. $temp = new static();
  1503. $temp->value = $this->_square($this->value);
  1504. list(, $temp) = $temp->divide($n);
  1505. return $this->_normalize($temp);
  1506. }
  1507. return $this->_normalize($this->_slidingWindow($e, $n, self::BARRETT));
  1508. // the following code, although not callable, can be run independently of the above code
  1509. // although the above code performed better in my benchmarks the following could might
  1510. // perform better under different circumstances. in lieu of deleting it it's just been
  1511. // made uncallable
  1512. // is the modulo odd?
  1513. if ($n->value[0] & 1) {
  1514. return $this->_normalize($this->_slidingWindow($e, $n, self::MONTGOMERY));
  1515. }
  1516. // if it's not, it's even
  1517. // find the lowest set bit (eg. the max pow of 2 that divides $n)
  1518. for ($i = 0; $i < count($n->value); ++$i) {
  1519. if ($n->value[$i]) {
  1520. $temp = decbin($n->value[$i]);
  1521. $j = strlen($temp) - strrpos($temp, '1') - 1;
  1522. $j+= 26 * $i;
  1523. break;
  1524. }
  1525. }
  1526. // at this point, 2^$j * $n/(2^$j) == $n
  1527. $mod1 = $n->copy();
  1528. $mod1->_rshift($j);
  1529. $mod2 = new static();
  1530. $mod2->value = array(1);
  1531. $mod2->_lshift($j);
  1532. $part1 = ($mod1->value != array(1)) ? $this->_slidingWindow($e, $mod1, self::MONTGOMERY) : new static();
  1533. $part2 = $this->_slidingWindow($e, $mod2, self::POWEROF2);
  1534. $y1 = $mod2->modInverse($mod1);
  1535. $y2 = $mod1->modInverse($mod2);
  1536. $result = $part1->multiply($mod2);
  1537. $result = $result->multiply($y1);
  1538. $temp = $part2->multiply($mod1);
  1539. $temp = $temp->multiply($y2);
  1540. $result = $result->add($temp);
  1541. list(, $result) = $result->divide($n);
  1542. return $this->_normalize($result);
  1543. }
  1544. /**
  1545. * Performs modular exponentiation.
  1546. *
  1547. * Alias for modPow().
  1548. *
  1549. * @param \phpseclib\Math\BigInteger $e
  1550. * @param \phpseclib\Math\BigInteger $n
  1551. * @return \phpseclib\Math\BigInteger
  1552. * @access public
  1553. */
  1554. function powMod($e, $n)
  1555. {
  1556. return $this->modPow($e, $n);
  1557. }
  1558. /**
  1559. * Sliding Window k-ary Modular Exponentiation
  1560. *
  1561. * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} /
  1562. * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims,
  1563. * however, this function performs a modular reduction after every multiplication and squaring operation.
  1564. * As such, this function has the same preconditions that the reductions being used do.
  1565. *
  1566. * @param \phpseclib\Math\BigInteger $e
  1567. * @param \phpseclib\Math\BigInteger $n
  1568. * @param int $mode
  1569. * @return \phpseclib\Math\BigInteger
  1570. * @access private
  1571. */
  1572. function _slidingWindow($e, $n, $mode)
  1573. {
  1574. static $window_ranges = array(7, 25, 81, 241, 673, 1793); // from BigInteger.java's oddModPow function
  1575. //static $window_ranges = array(0, 7, 36, 140, 450, 1303, 3529); // from MPM 7.3.1
  1576. $e_value = $e->value;
  1577. $e_length = count($e_value) - 1;
  1578. $e_bits = decbin($e_value[$e_length]);
  1579. for ($i = $e_length - 1; $i >= 0; --$i) {
  1580. $e_bits.= str_pad(decbin($e_value[$i]), self::$base, '0', STR_PAD_LEFT);
  1581. }
  1582. $e_length = strlen($e_bits);
  1583. // calculate the appropriate window size.
  1584. // $window_size == 3 if $window_ranges is between 25 and 81, for example.
  1585. for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) {
  1586. }
  1587. $n_value = $n->value;
  1588. // precompute $this^0 through $this^$window_size
  1589. $powers = array();
  1590. $powers[1] = $this->_prepareReduce($this->value, $n_value, $mode);
  1591. $powers[2] = $this->_squareReduce($powers[1], $n_value, $mode);
  1592. // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end
  1593. // in a 1. ie. it's supposed to be odd.
  1594. $temp = 1 << ($window_size - 1);
  1595. for ($i = 1; $i < $temp; ++$i) {
  1596. $i2 = $i << 1;
  1597. $powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode);
  1598. }
  1599. $result = array(1);
  1600. $result = $this->_prepareReduce($result, $n_value, $mode);
  1601. for ($i = 0; $i < $e_length;) {
  1602. if (!$e_bits[$i]) {
  1603. $result = $this->_squareReduce($result, $n_value, $mode);
  1604. ++$i;
  1605. } else {
  1606. for ($j = $window_size - 1; $j > 0; --$j) {
  1607. if (!empty($e_bits[$i + $j])) {
  1608. break;
  1609. }
  1610. }
  1611. // eg. the length of substr($e_bits, $i, $j + 1)
  1612. for ($k = 0; $k <= $j; ++$k) {
  1613. $result = $this->_squareReduce($result, $n_value, $mode);
  1614. }
  1615. $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode);
  1616. $i += $j + 1;
  1617. }
  1618. }
  1619. $temp = new static();
  1620. $temp->value = $this->_reduce($result, $n_value, $mode);
  1621. return $temp;
  1622. }
  1623. /**
  1624. * Modular reduction
  1625. *
  1626. * For most $modes this will return the remainder.
  1627. *
  1628. * @see self::_slidingWindow()
  1629. * @access private
  1630. * @param array $x
  1631. * @param array $n
  1632. * @param int $mode
  1633. * @return array
  1634. */
  1635. function _reduce($x, $n, $mode)
  1636. {
  1637. switch ($mode) {
  1638. case self::MONTGOMERY:
  1639. return $this->_montgomery($x, $n);
  1640. case self::BARRETT:
  1641. return $this->_barrett($x, $n);
  1642. case self::POWEROF2:
  1643. $lhs = new static();
  1644. $lhs->value = $x;
  1645. $rhs = new static();
  1646. $rhs->value = $n;
  1647. return $x->_mod2($n);
  1648. case self::CLASSIC:
  1649. $lhs = new static();
  1650. $lhs->value = $x;
  1651. $rhs = new static();
  1652. $rhs->value = $n;
  1653. list(, $temp) = $lhs->divide($rhs);
  1654. return $temp->value;
  1655. case self::NONE:
  1656. return $x;
  1657. default:
  1658. // an invalid $mode was provided
  1659. }
  1660. }
  1661. /**
  1662. * Modular reduction preperation
  1663. *
  1664. * @see self::_slidingWindow()
  1665. * @access private
  1666. * @param array $x
  1667. * @param array $n
  1668. * @param int $mode
  1669. * @return array
  1670. */
  1671. function _prepareReduce($x, $n, $mode)
  1672. {
  1673. if ($mode == self::MONTGOMERY) {
  1674. return $this->_prepMontgomery($x, $n);
  1675. }
  1676. return $this->_reduce($x, $n, $mode);
  1677. }
  1678. /**
  1679. * Modular multiply
  1680. *
  1681. * @see self::_slidingWindow()
  1682. * @access private
  1683. * @param array $x
  1684. * @param array $y
  1685. * @param array $n
  1686. * @param int $mode
  1687. * @return array
  1688. */
  1689. function _multiplyReduce($x, $y, $n, $mode)
  1690. {
  1691. if ($mode == self::MONTGOMERY) {
  1692. return $this->_montgomeryMultiply($x, $y, $n);
  1693. }
  1694. $temp = $this->_multiply($x, false, $y, false);
  1695. return $this->_reduce($temp[self::VALUE], $n, $mode);
  1696. }
  1697. /**
  1698. * Modular square
  1699. *
  1700. * @see self::_slidingWindow()
  1701. * @access private
  1702. * @param array $x
  1703. * @param array $n
  1704. * @param int $mode
  1705. * @return array
  1706. */
  1707. function _squareReduce($x, $n, $mode)
  1708. {
  1709. if ($mode == self::MONTGOMERY) {
  1710. return $this->_montgomeryMultiply($x, $x, $n);
  1711. }
  1712. return $this->_reduce($this->_square($x), $n, $mode);
  1713. }
  1714. /**
  1715. * Modulos for Powers of Two
  1716. *
  1717. * Calculates $x%$n, where $n = 2**$e, for some $e. Since this is basically the same as doing $x & ($n-1),
  1718. * we'll just use this function as a wrapper for doing that.
  1719. *
  1720. * @see self::_slidingWindow()
  1721. * @access private
  1722. * @param \phpseclib\Math\BigInteger
  1723. * @return \phpseclib\Math\BigInteger
  1724. */
  1725. function _mod2($n)
  1726. {
  1727. $temp = new static();
  1728. $temp->value = array(1);
  1729. return $this->bitwise_and($n->subtract($temp));
  1730. }
  1731. /**
  1732. * Barrett Modular Reduction
  1733. *
  1734. * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} /
  1735. * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly,
  1736. * so as not to require negative numbers (initially, this script didn't support negative numbers).
  1737. *
  1738. * Employs "folding", as described at
  1739. * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from
  1740. * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x."
  1741. *
  1742. * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that
  1743. * usable on account of (1) its not using reasonable radix points as discussed in
  1744. * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable
  1745. * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that
  1746. * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line
  1747. * comments for details.
  1748. *
  1749. * @see self::_slidingWindow()
  1750. * @access private
  1751. * @param array $n
  1752. * @param array $m
  1753. * @return array
  1754. */
  1755. function _barrett($n, $m)
  1756. {
  1757. static $cache = array(
  1758. self::VARIABLE => array(),
  1759. self::DATA => array()
  1760. );
  1761. $m_length = count($m);
  1762. // if ($this->_compare($n, $this->_square($m)) >= 0) {
  1763. if (count($n) > 2 * $m_length) {
  1764. $lhs = new static();
  1765. $rhs = new static();
  1766. $lhs->value = $n;
  1767. $rhs->value = $m;
  1768. list(, $temp) = $lhs->divide($rhs);
  1769. return $temp->value;
  1770. }
  1771. // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced
  1772. if ($m_length < 5) {
  1773. return $this->_regularBarrett($n, $m);
  1774. }
  1775. // n = 2 * m.length
  1776. if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
  1777. $key = count($cache[self::VARIABLE]);
  1778. $cache[self::VARIABLE][] = $m;
  1779. $lhs = new static();
  1780. $lhs_value = &$lhs->value;
  1781. $lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1));
  1782. $lhs_value[] = 1;
  1783. $rhs = new static();
  1784. $rhs->value = $m;
  1785. list($u, $m1) = $lhs->divide($rhs);
  1786. $u = $u->value;
  1787. $m1 = $m1->value;
  1788. $cache[self::DATA][] = array(
  1789. 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1)
  1790. 'm1'=> $m1 // m.length
  1791. );
  1792. } else {
  1793. extract($cache[self::DATA][$key]);
  1794. }
  1795. $cutoff = $m_length + ($m_length >> 1);
  1796. $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1)
  1797. $msd = array_slice($n, $cutoff); // m.length >> 1
  1798. $lsd = $this->_trim($lsd);
  1799. $temp = $this->_multiply($msd, false, $m1, false);
  1800. $n = $this->_add($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1
  1801. if ($m_length & 1) {
  1802. return $this->_regularBarrett($n[self::VALUE], $m);
  1803. }
  1804. // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2
  1805. $temp = array_slice($n[self::VALUE], $m_length - 1);
  1806. // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2
  1807. // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1
  1808. $temp = $this->_multiply($temp, false, $u, false);
  1809. // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1
  1810. // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1)
  1811. $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1);
  1812. // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1
  1813. // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1)
  1814. $temp = $this->_multiply($temp, false, $m, false);
  1815. // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit
  1816. // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop
  1817. // following this comment would loop a lot (hence our calling _regularBarrett() in that situation).
  1818. $result = $this->_subtract($n[self::VALUE], false, $temp[self::VALUE], false);
  1819. while ($this->_compare($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) {
  1820. $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $m, false);
  1821. }
  1822. return $result[self::VALUE];
  1823. }
  1824. /**
  1825. * (Regular) Barrett Modular Reduction
  1826. *
  1827. * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this
  1828. * is that this function does not fold the denominator into a smaller form.
  1829. *
  1830. * @see self::_slidingWindow()
  1831. * @access private
  1832. * @param array $x
  1833. * @param array $n
  1834. * @return array
  1835. */
  1836. function _regularBarrett($x, $n)
  1837. {
  1838. static $cache = array(
  1839. self::VARIABLE => array(),
  1840. self::DATA => array()
  1841. );
  1842. $n_length = count($n);
  1843. if (count($x) > 2 * $n_length) {
  1844. $lhs = new static();
  1845. $rhs = new static();
  1846. $lhs->value = $x;
  1847. $rhs->value = $n;
  1848. list(, $temp) = $lhs->divide($rhs);
  1849. return $temp->value;
  1850. }
  1851. if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
  1852. $key = count($cache[self::VARIABLE]);
  1853. $cache[self::VARIABLE][] = $n;
  1854. $lhs = new static();
  1855. $lhs_value = &$lhs->value;
  1856. $lhs_value = $this->_array_repeat(0, 2 * $n_length);
  1857. $lhs_value[] = 1;
  1858. $rhs = new static();
  1859. $rhs->value = $n;
  1860. list($temp, ) = $lhs->divide($rhs); // m.length
  1861. $cache[self::DATA][] = $temp->value;
  1862. }
  1863. // 2 * m.length - (m.length - 1) = m.length + 1
  1864. $temp = array_slice($x, $n_length - 1);
  1865. // (m.length + 1) + m.length = 2 * m.length + 1
  1866. $temp = $this->_multiply($temp, false, $cache[self::DATA][$key], false);
  1867. // (2 * m.length + 1) - (m.length - 1) = m.length + 2
  1868. $temp = array_slice($temp[self::VALUE], $n_length + 1);
  1869. // m.length + 1
  1870. $result = array_slice($x, 0, $n_length + 1);
  1871. // m.length + 1
  1872. $temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1);
  1873. // $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1)
  1874. if ($this->_compare($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) {
  1875. $corrector_value = $this->_array_repeat(0, $n_length + 1);
  1876. $corrector_value[count($corrector_value)] = 1;
  1877. $result = $this->_add($result, false, $corrector_value, false);
  1878. $result = $result[self::VALUE];
  1879. }
  1880. // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits
  1881. $result = $this->_subtract($result, false, $temp[self::VALUE], $temp[self::SIGN]);
  1882. while ($this->_compare($result[self::VALUE], $result[self::SIGN], $n, false) > 0) {
  1883. $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $n, false);
  1884. }
  1885. return $result[self::VALUE];
  1886. }
  1887. /**
  1888. * Performs long multiplication up to $stop digits
  1889. *
  1890. * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved.
  1891. *
  1892. * @see self::_regularBarrett()
  1893. * @param array $x_value
  1894. * @param bool $x_negative
  1895. * @param array $y_value
  1896. * @param bool $y_negative
  1897. * @param int $stop
  1898. * @return array
  1899. * @access private
  1900. */
  1901. function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop)
  1902. {
  1903. $x_length = count($x_value);
  1904. $y_length = count($y_value);
  1905. if (!$x_length || !$y_length) { // a 0 is being multiplied
  1906. return array(
  1907. self::VALUE => array(),
  1908. self::SIGN => false
  1909. );
  1910. }
  1911. if ($x_length < $y_length) {
  1912. $temp = $x_value;
  1913. $x_value = $y_value;
  1914. $y_value = $temp;
  1915. $x_length = count($x_value);
  1916. $y_length = count($y_value);
  1917. }
  1918. $product_value = $this->_array_repeat(0, $x_length + $y_length);
  1919. // the following for loop could be removed if the for loop following it
  1920. // (the one with nested for loops) initially set $i to 0, but
  1921. // doing so would also make the result in one set of unnecessary adds,
  1922. // since on the outermost loops first pass, $product->value[$k] is going
  1923. // to always be 0
  1924. $carry = 0;
  1925. for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i
  1926. $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
  1927. $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
  1928. $product_value[$j] = (int) ($temp - self::$baseFull * $carry);
  1929. }
  1930. if ($j < $stop) {
  1931. $product_value[$j] = $carry;
  1932. }
  1933. // the above for loop is what the previous comment was talking about. the
  1934. // following for loop is the "one with nested for loops"
  1935. for ($i = 1; $i < $y_length; ++$i) {
  1936. $carry = 0;
  1937. for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) {
  1938. $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
  1939. $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
  1940. $product_value[$k] = (int) ($temp - self::$baseFull * $carry);
  1941. }
  1942. if ($k < $stop) {
  1943. $product_value[$k] = $carry;
  1944. }
  1945. }
  1946. return array(
  1947. self::VALUE => $this->_trim($product_value),
  1948. self::SIGN => $x_negative != $y_negative
  1949. );
  1950. }
  1951. /**
  1952. * Montgomery Modular Reduction
  1953. *
  1954. * ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n.
  1955. * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be
  1956. * improved upon (basically, by using the comba method). gcd($n, 2) must be equal to one for this function
  1957. * to work correctly.
  1958. *
  1959. * @see self::_prepMontgomery()
  1960. * @see self::_slidingWindow()
  1961. * @access private
  1962. * @param array $x
  1963. * @param array $n
  1964. * @return array
  1965. */
  1966. function _montgomery($x, $n)
  1967. {
  1968. static $cache = array(
  1969. self::VARIABLE => array(),
  1970. self::DATA => array()
  1971. );
  1972. if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
  1973. $key = count($cache[self::VARIABLE]);
  1974. $cache[self::VARIABLE][] = $x;
  1975. $cache[self::DATA][] = $this->_modInverse67108864($n);
  1976. }
  1977. $k = count($n);
  1978. $result = array(self::VALUE => $x);
  1979. for ($i = 0; $i < $k; ++$i) {
  1980. $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key];
  1981. $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
  1982. $temp = $this->_regularMultiply(array($temp), $n);
  1983. $temp = array_merge($this->_array_repeat(0, $i), $temp);
  1984. $result = $this->_add($result[self::VALUE], false, $temp, false);
  1985. }
  1986. $result[self::VALUE] = array_slice($result[self::VALUE], $k);
  1987. if ($this->_compare($result, false, $n, false) >= 0) {
  1988. $result = $this->_subtract($result[self::VALUE], false, $n, false);
  1989. }
  1990. return $result[self::VALUE];
  1991. }
  1992. /**
  1993. * Montgomery Multiply
  1994. *
  1995. * Interleaves the montgomery reduction and long multiplication algorithms together as described in
  1996. * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36}
  1997. *
  1998. * @see self::_prepMontgomery()
  1999. * @see self::_montgomery()
  2000. * @access private
  2001. * @param array $x
  2002. * @param array $y
  2003. * @param array $m
  2004. * @return array
  2005. */
  2006. function _montgomeryMultiply($x, $y, $m)
  2007. {
  2008. $temp = $this->_multiply($x, false, $y, false);
  2009. return $this->_montgomery($temp[self::VALUE], $m);
  2010. // the following code, although not callable, can be run independently of the above code
  2011. // although the above code performed better in my benchmarks the following could might
  2012. // perform better under different circumstances. in lieu of deleting it it's just been
  2013. // made uncallable
  2014. static $cache = array(
  2015. self::VARIABLE => array(),
  2016. self::DATA => array()
  2017. );
  2018. if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
  2019. $key = count($cache[self::VARIABLE]);
  2020. $cache[self::VARIABLE][] = $m;
  2021. $cache[self::DATA][] = $this->_modInverse67108864($m);
  2022. }
  2023. $n = max(count($x), count($y), count($m));
  2024. $x = array_pad($x, $n, 0);
  2025. $y = array_pad($y, $n, 0);
  2026. $m = array_pad($m, $n, 0);
  2027. $a = array(self::VALUE => $this->_array_repeat(0, $n + 1));
  2028. for ($i = 0; $i < $n; ++$i) {
  2029. $temp = $a[self::VALUE][0] + $x[$i] * $y[0];
  2030. $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
  2031. $temp = $temp * $cache[self::DATA][$key];
  2032. $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
  2033. $temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false);
  2034. $a = $this->_add($a[self::VALUE], false, $temp[self::VALUE], false);
  2035. $a[self::VALUE] = array_slice($a[self::VALUE], 1);
  2036. }
  2037. if ($this->_compare($a[self::VALUE], false, $m, false) >= 0) {
  2038. $a = $this->_subtract($a[self::VALUE], false, $m, false);
  2039. }
  2040. return $a[self::VALUE];
  2041. }
  2042. /**
  2043. * Prepare a number for use in Montgomery Modular Reductions
  2044. *
  2045. * @see self::_montgomery()
  2046. * @see self::_slidingWindow()
  2047. * @access private
  2048. * @param array $x
  2049. * @param array $n
  2050. * @return array
  2051. */
  2052. function _prepMontgomery($x, $n)
  2053. {
  2054. $lhs = new static();
  2055. $lhs->value = array_merge($this->_array_repeat(0, count($n)), $x);
  2056. $rhs = new static();
  2057. $rhs->value = $n;
  2058. list(, $temp) = $lhs->divide($rhs);
  2059. return $temp->value;
  2060. }
  2061. /**
  2062. * Modular Inverse of a number mod 2**26 (eg. 67108864)
  2063. *
  2064. * Based off of the bnpInvDigit function implemented and justified in the following URL:
  2065. *
  2066. * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js}
  2067. *
  2068. * The following URL provides more info:
  2069. *
  2070. * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85}
  2071. *
  2072. * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For
  2073. * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields
  2074. * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't
  2075. * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that
  2076. * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the
  2077. * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to
  2078. * 40 bits, which only 64-bit floating points will support.
  2079. *
  2080. * Thanks to Pedro Gimeno Fortea for input!
  2081. *
  2082. * @see self::_montgomery()
  2083. * @access private
  2084. * @param array $x
  2085. * @return int
  2086. */
  2087. function _modInverse67108864($x) // 2**26 == 67,108,864
  2088. {
  2089. $x = -$x[0];
  2090. $result = $x & 0x3; // x**-1 mod 2**2
  2091. $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4
  2092. $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8
  2093. $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16
  2094. $result = fmod($result * (2 - fmod($x * $result, self::$baseFull)), self::$baseFull); // x**-1 mod 2**26
  2095. return $result & self::$maxDigit;
  2096. }
  2097. /**
  2098. * Calculates modular inverses.
  2099. *
  2100. * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses.
  2101. *
  2102. * Here's an example:
  2103. * <code>
  2104. * <?php
  2105. * $a = new \phpseclib\Math\BigInteger(30);
  2106. * $b = new \phpseclib\Math\BigInteger(17);
  2107. *
  2108. * $c = $a->modInverse($b);
  2109. * echo $c->toString(); // outputs 4
  2110. *
  2111. * echo "\r\n";
  2112. *
  2113. * $d = $a->multiply($c);
  2114. * list(, $d) = $d->divide($b);
  2115. * echo $d; // outputs 1 (as per the definition of modular inverse)
  2116. * ?>
  2117. * </code>
  2118. *
  2119. * @param \phpseclib\Math\BigInteger $n
  2120. * @return \phpseclib\Math\BigInteger|false
  2121. * @access public
  2122. * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.
  2123. */
  2124. function modInverse($n)
  2125. {
  2126. switch (MATH_BIGINTEGER_MODE) {
  2127. case self::MODE_GMP:
  2128. $temp = new static();
  2129. $temp->value = gmp_invert($this->value, $n->value);
  2130. return ($temp->value === false) ? false : $this->_normalize($temp);
  2131. }
  2132. static $zero, $one;
  2133. if (!isset($zero)) {
  2134. $zero = new static();
  2135. $one = new static(1);
  2136. }
  2137. // $x mod -$n == $x mod $n.
  2138. $n = $n->abs();
  2139. if ($this->compare($zero) < 0) {
  2140. $temp = $this->abs();
  2141. $temp = $temp->modInverse($n);
  2142. return $this->_normalize($n->subtract($temp));
  2143. }
  2144. extract($this->extendedGCD($n));
  2145. if (!$gcd->equals($one)) {
  2146. return false;
  2147. }
  2148. $x = $x->compare($zero) < 0 ? $x->add($n) : $x;
  2149. return $this->compare($zero) < 0 ? $this->_normalize($n->subtract($x)) : $this->_normalize($x);
  2150. }
  2151. /**
  2152. * Calculates the greatest common divisor and Bezout's identity.
  2153. *
  2154. * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that
  2155. * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which
  2156. * combination is returned is dependant upon which mode is in use. See
  2157. * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information.
  2158. *
  2159. * Here's an example:
  2160. * <code>
  2161. * <?php
  2162. * $a = new \phpseclib\Math\BigInteger(693);
  2163. * $b = new \phpseclib\Math\BigInteger(609);
  2164. *
  2165. * extract($a->extendedGCD($b));
  2166. *
  2167. * echo $gcd->toString() . "\r\n"; // outputs 21
  2168. * echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21
  2169. * ?>
  2170. * </code>
  2171. *
  2172. * @param \phpseclib\Math\BigInteger $n
  2173. * @return \phpseclib\Math\BigInteger
  2174. * @access public
  2175. * @internal Calculates the GCD using the binary xGCD algorithim described in
  2176. * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}. As the text above 14.61 notes,
  2177. * the more traditional algorithim requires "relatively costly multiple-precision divisions".
  2178. */
  2179. function extendedGCD($n)
  2180. {
  2181. switch (MATH_BIGINTEGER_MODE) {
  2182. case self::MODE_GMP:
  2183. extract(gmp_gcdext($this->value, $n->value));
  2184. return array(
  2185. 'gcd' => $this->_normalize(new static($g)),
  2186. 'x' => $this->_normalize(new static($s)),
  2187. 'y' => $this->_normalize(new static($t))
  2188. );
  2189. case self::MODE_BCMATH:
  2190. // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works
  2191. // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is,
  2192. // the basic extended euclidean algorithim is what we're using.
  2193. $u = $this->value;
  2194. $v = $n->value;
  2195. $a = '1';
  2196. $b = '0';
  2197. $c = '0';
  2198. $d = '1';
  2199. while (bccomp($v, '0', 0) != 0) {
  2200. $q = bcdiv($u, $v, 0);
  2201. $temp = $u;
  2202. $u = $v;
  2203. $v = bcsub($temp, bcmul($v, $q, 0), 0);
  2204. $temp = $a;
  2205. $a = $c;
  2206. $c = bcsub($temp, bcmul($a, $q, 0), 0);
  2207. $temp = $b;
  2208. $b = $d;
  2209. $d = bcsub($temp, bcmul($b, $q, 0), 0);
  2210. }
  2211. return array(
  2212. 'gcd' => $this->_normalize(new static($u)),
  2213. 'x' => $this->_normalize(new static($a)),
  2214. 'y' => $this->_normalize(new static($b))
  2215. );
  2216. }
  2217. $y = $n->copy();
  2218. $x = $this->copy();
  2219. $g = new static();
  2220. $g->value = array(1);
  2221. while (!(($x->value[0] & 1)|| ($y->value[0] & 1))) {
  2222. $x->_rshift(1);
  2223. $y->_rshift(1);
  2224. $g->_lshift(1);
  2225. }
  2226. $u = $x->copy();
  2227. $v = $y->copy();
  2228. $a = new static();
  2229. $b = new static();
  2230. $c = new static();
  2231. $d = new static();
  2232. $a->value = $d->value = $g->value = array(1);
  2233. $b->value = $c->value = array();
  2234. while (!empty($u->value)) {
  2235. while (!($u->value[0] & 1)) {
  2236. $u->_rshift(1);
  2237. if ((!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1))) {
  2238. $a = $a->add($y);
  2239. $b = $b->subtract($x);
  2240. }
  2241. $a->_rshift(1);
  2242. $b->_rshift(1);
  2243. }
  2244. while (!($v->value[0] & 1)) {
  2245. $v->_rshift(1);
  2246. if ((!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1))) {
  2247. $c = $c->add($y);
  2248. $d = $d->subtract($x);
  2249. }
  2250. $c->_rshift(1);
  2251. $d->_rshift(1);
  2252. }
  2253. if ($u->compare($v) >= 0) {
  2254. $u = $u->subtract($v);
  2255. $a = $a->subtract($c);
  2256. $b = $b->subtract($d);
  2257. } else {
  2258. $v = $v->subtract($u);
  2259. $c = $c->subtract($a);
  2260. $d = $d->subtract($b);
  2261. }
  2262. }
  2263. return array(
  2264. 'gcd' => $this->_normalize($g->multiply($v)),
  2265. 'x' => $this->_normalize($c),
  2266. 'y' => $this->_normalize($d)
  2267. );
  2268. }
  2269. /**
  2270. * Calculates the greatest common divisor
  2271. *
  2272. * Say you have 693 and 609. The GCD is 21.
  2273. *
  2274. * Here's an example:
  2275. * <code>
  2276. * <?php
  2277. * $a = new \phpseclib\Math\BigInteger(693);
  2278. * $b = new \phpseclib\Math\BigInteger(609);
  2279. *
  2280. * $gcd = a->extendedGCD($b);
  2281. *
  2282. * echo $gcd->toString() . "\r\n"; // outputs 21
  2283. * ?>
  2284. * </code>
  2285. *
  2286. * @param \phpseclib\Math\BigInteger $n
  2287. * @return \phpseclib\Math\BigInteger
  2288. * @access public
  2289. */
  2290. function gcd($n)
  2291. {
  2292. extract($this->extendedGCD($n));
  2293. return $gcd;
  2294. }
  2295. /**
  2296. * Absolute value.
  2297. *
  2298. * @return \phpseclib\Math\BigInteger
  2299. * @access public
  2300. */
  2301. function abs()
  2302. {
  2303. $temp = new static();
  2304. switch (MATH_BIGINTEGER_MODE) {
  2305. case self::MODE_GMP:
  2306. $temp->value = gmp_abs($this->value);
  2307. break;
  2308. case self::MODE_BCMATH:
  2309. $temp->value = (bccomp($this->value, '0', 0) < 0) ? substr($this->value, 1) : $this->value;
  2310. break;
  2311. default:
  2312. $temp->value = $this->value;
  2313. }
  2314. return $temp;
  2315. }
  2316. /**
  2317. * Compares two numbers.
  2318. *
  2319. * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is
  2320. * demonstrated thusly:
  2321. *
  2322. * $x > $y: $x->compare($y) > 0
  2323. * $x < $y: $x->compare($y) < 0
  2324. * $x == $y: $x->compare($y) == 0
  2325. *
  2326. * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y).
  2327. *
  2328. * @param \phpseclib\Math\BigInteger $y
  2329. * @return int < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
  2330. * @access public
  2331. * @see self::equals()
  2332. * @internal Could return $this->subtract($x), but that's not as fast as what we do do.
  2333. */
  2334. function compare($y)
  2335. {
  2336. switch (MATH_BIGINTEGER_MODE) {
  2337. case self::MODE_GMP:
  2338. return gmp_cmp($this->value, $y->value);
  2339. case self::MODE_BCMATH:
  2340. return bccomp($this->value, $y->value, 0);
  2341. }
  2342. return $this->_compare($this->value, $this->is_negative, $y->value, $y->is_negative);
  2343. }
  2344. /**
  2345. * Compares two numbers.
  2346. *
  2347. * @param array $x_value
  2348. * @param bool $x_negative
  2349. * @param array $y_value
  2350. * @param bool $y_negative
  2351. * @return int
  2352. * @see self::compare()
  2353. * @access private
  2354. */
  2355. function _compare($x_value, $x_negative, $y_value, $y_negative)
  2356. {
  2357. if ($x_negative != $y_negative) {
  2358. return (!$x_negative && $y_negative) ? 1 : -1;
  2359. }
  2360. $result = $x_negative ? -1 : 1;
  2361. if (count($x_value) != count($y_value)) {
  2362. return (count($x_value) > count($y_value)) ? $result : -$result;
  2363. }
  2364. $size = max(count($x_value), count($y_value));
  2365. $x_value = array_pad($x_value, $size, 0);
  2366. $y_value = array_pad($y_value, $size, 0);
  2367. for ($i = count($x_value) - 1; $i >= 0; --$i) {
  2368. if ($x_value[$i] != $y_value[$i]) {
  2369. return ($x_value[$i] > $y_value[$i]) ? $result : -$result;
  2370. }
  2371. }
  2372. return 0;
  2373. }
  2374. /**
  2375. * Tests the equality of two numbers.
  2376. *
  2377. * If you need to see if one number is greater than or less than another number, use BigInteger::compare()
  2378. *
  2379. * @param \phpseclib\Math\BigInteger $x
  2380. * @return bool
  2381. * @access public
  2382. * @see self::compare()
  2383. */
  2384. function equals($x)
  2385. {
  2386. switch (MATH_BIGINTEGER_MODE) {
  2387. case self::MODE_GMP:
  2388. return gmp_cmp($this->value, $x->value) == 0;
  2389. default:
  2390. return $this->value === $x->value && $this->is_negative == $x->is_negative;
  2391. }
  2392. }
  2393. /**
  2394. * Set Precision
  2395. *
  2396. * Some bitwise operations give different results depending on the precision being used. Examples include left
  2397. * shift, not, and rotates.
  2398. *
  2399. * @param int $bits
  2400. * @access public
  2401. */
  2402. function setPrecision($bits)
  2403. {
  2404. $this->precision = $bits;
  2405. if (MATH_BIGINTEGER_MODE != self::MODE_BCMATH) {
  2406. $this->bitmask = new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256);
  2407. } else {
  2408. $this->bitmask = new static(bcpow('2', $bits, 0));
  2409. }
  2410. $temp = $this->_normalize($this);
  2411. $this->value = $temp->value;
  2412. }
  2413. /**
  2414. * Logical And
  2415. *
  2416. * @param \phpseclib\Math\BigInteger $x
  2417. * @access public
  2418. * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
  2419. * @return \phpseclib\Math\BigInteger
  2420. */
  2421. function bitwise_and($x)
  2422. {
  2423. switch (MATH_BIGINTEGER_MODE) {
  2424. case self::MODE_GMP:
  2425. $temp = new static();
  2426. $temp->value = gmp_and($this->value, $x->value);
  2427. return $this->_normalize($temp);
  2428. case self::MODE_BCMATH:
  2429. $left = $this->toBytes();
  2430. $right = $x->toBytes();
  2431. $length = max(strlen($left), strlen($right));
  2432. $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
  2433. $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
  2434. return $this->_normalize(new static($left & $right, 256));
  2435. }
  2436. $result = $this->copy();
  2437. $length = min(count($x->value), count($this->value));
  2438. $result->value = array_slice($result->value, 0, $length);
  2439. for ($i = 0; $i < $length; ++$i) {
  2440. $result->value[$i]&= $x->value[$i];
  2441. }
  2442. return $this->_normalize($result);
  2443. }
  2444. /**
  2445. * Logical Or
  2446. *
  2447. * @param \phpseclib\Math\BigInteger $x
  2448. * @access public
  2449. * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
  2450. * @return \phpseclib\Math\BigInteger
  2451. */
  2452. function bitwise_or($x)
  2453. {
  2454. switch (MATH_BIGINTEGER_MODE) {
  2455. case self::MODE_GMP:
  2456. $temp = new static();
  2457. $temp->value = gmp_or($this->value, $x->value);
  2458. return $this->_normalize($temp);
  2459. case self::MODE_BCMATH:
  2460. $left = $this->toBytes();
  2461. $right = $x->toBytes();
  2462. $length = max(strlen($left), strlen($right));
  2463. $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
  2464. $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
  2465. return $this->_normalize(new static($left | $right, 256));
  2466. }
  2467. $length = max(count($this->value), count($x->value));
  2468. $result = $this->copy();
  2469. $result->value = array_pad($result->value, $length, 0);
  2470. $x->value = array_pad($x->value, $length, 0);
  2471. for ($i = 0; $i < $length; ++$i) {
  2472. $result->value[$i]|= $x->value[$i];
  2473. }
  2474. return $this->_normalize($result);
  2475. }
  2476. /**
  2477. * Logical Exclusive-Or
  2478. *
  2479. * @param \phpseclib\Math\BigInteger $x
  2480. * @access public
  2481. * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
  2482. * @return \phpseclib\Math\BigInteger
  2483. */
  2484. function bitwise_xor($x)
  2485. {
  2486. switch (MATH_BIGINTEGER_MODE) {
  2487. case self::MODE_GMP:
  2488. $temp = new static();
  2489. $temp->value = gmp_xor($this->value, $x->value);
  2490. return $this->_normalize($temp);
  2491. case self::MODE_BCMATH:
  2492. $left = $this->toBytes();
  2493. $right = $x->toBytes();
  2494. $length = max(strlen($left), strlen($right));
  2495. $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
  2496. $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
  2497. return $this->_normalize(new static($left ^ $right, 256));
  2498. }
  2499. $length = max(count($this->value), count($x->value));
  2500. $result = $this->copy();
  2501. $result->value = array_pad($result->value, $length, 0);
  2502. $x->value = array_pad($x->value, $length, 0);
  2503. for ($i = 0; $i < $length; ++$i) {
  2504. $result->value[$i]^= $x->value[$i];
  2505. }
  2506. return $this->_normalize($result);
  2507. }
  2508. /**
  2509. * Logical Not
  2510. *
  2511. * @access public
  2512. * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
  2513. * @return \phpseclib\Math\BigInteger
  2514. */
  2515. function bitwise_not()
  2516. {
  2517. // calculuate "not" without regard to $this->precision
  2518. // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
  2519. $temp = $this->toBytes();
  2520. if ($temp == '') {
  2521. return '';
  2522. }
  2523. $pre_msb = decbin(ord($temp[0]));
  2524. $temp = ~$temp;
  2525. $msb = decbin(ord($temp[0]));
  2526. if (strlen($msb) == 8) {
  2527. $msb = substr($msb, strpos($msb, '0'));
  2528. }
  2529. $temp[0] = chr(bindec($msb));
  2530. // see if we need to add extra leading 1's
  2531. $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8;
  2532. $new_bits = $this->precision - $current_bits;
  2533. if ($new_bits <= 0) {
  2534. return $this->_normalize(new static($temp, 256));
  2535. }
  2536. // generate as many leading 1's as we need to.
  2537. $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3);
  2538. $this->_base256_lshift($leading_ones, $current_bits);
  2539. $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT);
  2540. return $this->_normalize(new static($leading_ones | $temp, 256));
  2541. }
  2542. /**
  2543. * Logical Right Shift
  2544. *
  2545. * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift.
  2546. *
  2547. * @param int $shift
  2548. * @return \phpseclib\Math\BigInteger
  2549. * @access public
  2550. * @internal The only version that yields any speed increases is the internal version.
  2551. */
  2552. function bitwise_rightShift($shift)
  2553. {
  2554. $temp = new static();
  2555. switch (MATH_BIGINTEGER_MODE) {
  2556. case self::MODE_GMP:
  2557. static $two;
  2558. if (!isset($two)) {
  2559. $two = gmp_init('2');
  2560. }
  2561. $temp->value = gmp_div_q($this->value, gmp_pow($two, $shift));
  2562. break;
  2563. case self::MODE_BCMATH:
  2564. $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0);
  2565. break;
  2566. default: // could just replace _lshift with this, but then all _lshift() calls would need to be rewritten
  2567. // and I don't want to do that...
  2568. $temp->value = $this->value;
  2569. $temp->_rshift($shift);
  2570. }
  2571. return $this->_normalize($temp);
  2572. }
  2573. /**
  2574. * Logical Left Shift
  2575. *
  2576. * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift.
  2577. *
  2578. * @param int $shift
  2579. * @return \phpseclib\Math\BigInteger
  2580. * @access public
  2581. * @internal The only version that yields any speed increases is the internal version.
  2582. */
  2583. function bitwise_leftShift($shift)
  2584. {
  2585. $temp = new static();
  2586. switch (MATH_BIGINTEGER_MODE) {
  2587. case self::MODE_GMP:
  2588. static $two;
  2589. if (!isset($two)) {
  2590. $two = gmp_init('2');
  2591. }
  2592. $temp->value = gmp_mul($this->value, gmp_pow($two, $shift));
  2593. break;
  2594. case self::MODE_BCMATH:
  2595. $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0);
  2596. break;
  2597. default: // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten
  2598. // and I don't want to do that...
  2599. $temp->value = $this->value;
  2600. $temp->_lshift($shift);
  2601. }
  2602. return $this->_normalize($temp);
  2603. }
  2604. /**
  2605. * Logical Left Rotate
  2606. *
  2607. * Instead of the top x bits being dropped they're appended to the shifted bit string.
  2608. *
  2609. * @param int $shift
  2610. * @return \phpseclib\Math\BigInteger
  2611. * @access public
  2612. */
  2613. function bitwise_leftRotate($shift)
  2614. {
  2615. $bits = $this->toBytes();
  2616. if ($this->precision > 0) {
  2617. $precision = $this->precision;
  2618. if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
  2619. $mask = $this->bitmask->subtract(new static(1));
  2620. $mask = $mask->toBytes();
  2621. } else {
  2622. $mask = $this->bitmask->toBytes();
  2623. }
  2624. } else {
  2625. $temp = ord($bits[0]);
  2626. for ($i = 0; $temp >> $i; ++$i) {
  2627. }
  2628. $precision = 8 * strlen($bits) - 8 + $i;
  2629. $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3);
  2630. }
  2631. if ($shift < 0) {
  2632. $shift+= $precision;
  2633. }
  2634. $shift%= $precision;
  2635. if (!$shift) {
  2636. return $this->copy();
  2637. }
  2638. $left = $this->bitwise_leftShift($shift);
  2639. $left = $left->bitwise_and(new static($mask, 256));
  2640. $right = $this->bitwise_rightShift($precision - $shift);
  2641. $result = MATH_BIGINTEGER_MODE != self::MODE_BCMATH ? $left->bitwise_or($right) : $left->add($right);
  2642. return $this->_normalize($result);
  2643. }
  2644. /**
  2645. * Logical Right Rotate
  2646. *
  2647. * Instead of the bottom x bits being dropped they're prepended to the shifted bit string.
  2648. *
  2649. * @param int $shift
  2650. * @return \phpseclib\Math\BigInteger
  2651. * @access public
  2652. */
  2653. function bitwise_rightRotate($shift)
  2654. {
  2655. return $this->bitwise_leftRotate(-$shift);
  2656. }
  2657. /**
  2658. * Generates a random BigInteger
  2659. *
  2660. * Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not.
  2661. *
  2662. * @param int $length
  2663. * @return \phpseclib\Math\BigInteger
  2664. * @access private
  2665. */
  2666. function _random_number_helper($size)
  2667. {
  2668. if (class_exists('\phpseclib\Crypt\Random')) {
  2669. $random = Random::string($size);
  2670. } else {
  2671. $random = '';
  2672. if ($size & 1) {
  2673. $random.= chr(mt_rand(0, 255));
  2674. }
  2675. $blocks = $size >> 1;
  2676. for ($i = 0; $i < $blocks; ++$i) {
  2677. // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems
  2678. $random.= pack('n', mt_rand(0, 0xFFFF));
  2679. }
  2680. }
  2681. return new static($random, 256);
  2682. }
  2683. /**
  2684. * Generate a random number
  2685. *
  2686. * Returns a random number between $min and $max where $min and $max
  2687. * can be defined using one of the two methods:
  2688. *
  2689. * $min->random($max)
  2690. * $max->random($min)
  2691. *
  2692. * @param \phpseclib\Math\BigInteger $arg1
  2693. * @param \phpseclib\Math\BigInteger $arg2
  2694. * @return \phpseclib\Math\BigInteger
  2695. * @access public
  2696. * @internal The API for creating random numbers used to be $a->random($min, $max), where $a was a BigInteger object.
  2697. * That method is still supported for BC purposes.
  2698. */
  2699. function random($arg1, $arg2 = false)
  2700. {
  2701. if ($arg1 === false) {
  2702. return false;
  2703. }
  2704. if ($arg2 === false) {
  2705. $max = $arg1;
  2706. $min = $this;
  2707. } else {
  2708. $min = $arg1;
  2709. $max = $arg2;
  2710. }
  2711. $compare = $max->compare($min);
  2712. if (!$compare) {
  2713. return $this->_normalize($min);
  2714. } elseif ($compare < 0) {
  2715. // if $min is bigger then $max, swap $min and $max
  2716. $temp = $max;
  2717. $max = $min;
  2718. $min = $temp;
  2719. }
  2720. static $one;
  2721. if (!isset($one)) {
  2722. $one = new static(1);
  2723. }
  2724. $max = $max->subtract($min->subtract($one));
  2725. $size = strlen(ltrim($max->toBytes(), chr(0)));
  2726. /*
  2727. doing $random % $max doesn't work because some numbers will be more likely to occur than others.
  2728. eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145
  2729. would produce 5 whereas the only value of random that could produce 139 would be 139. ie.
  2730. not all numbers would be equally likely. some would be more likely than others.
  2731. creating a whole new random number until you find one that is within the range doesn't work
  2732. because, for sufficiently small ranges, the likelihood that you'd get a number within that range
  2733. would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability
  2734. would be pretty high that $random would be greater than $max.
  2735. phpseclib works around this using the technique described here:
  2736. http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string
  2737. */
  2738. $random_max = new static(chr(1) . str_repeat("\0", $size), 256);
  2739. $random = $this->_random_number_helper($size);
  2740. list($max_multiple) = $random_max->divide($max);
  2741. $max_multiple = $max_multiple->multiply($max);
  2742. while ($random->compare($max_multiple) >= 0) {
  2743. $random = $random->subtract($max_multiple);
  2744. $random_max = $random_max->subtract($max_multiple);
  2745. $random = $random->bitwise_leftShift(8);
  2746. $random = $random->add($this->_random_number_helper(1));
  2747. $random_max = $random_max->bitwise_leftShift(8);
  2748. list($max_multiple) = $random_max->divide($max);
  2749. $max_multiple = $max_multiple->multiply($max);
  2750. }
  2751. list(, $random) = $random->divide($max);
  2752. return $this->_normalize($random->add($min));
  2753. }
  2754. /**
  2755. * Generate a random prime number.
  2756. *
  2757. * If there's not a prime within the given range, false will be returned.
  2758. * If more than $timeout seconds have elapsed, give up and return false.
  2759. *
  2760. * @param \phpseclib\Math\BigInteger $arg1
  2761. * @param \phpseclib\Math\BigInteger $arg2
  2762. * @param int $timeout
  2763. * @return Math_BigInteger|false
  2764. * @access public
  2765. * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}.
  2766. */
  2767. function randomPrime($arg1, $arg2 = false, $timeout = false)
  2768. {
  2769. if ($arg1 === false) {
  2770. return false;
  2771. }
  2772. if ($arg2 === false) {
  2773. $max = $arg1;
  2774. $min = $this;
  2775. } else {
  2776. $min = $arg1;
  2777. $max = $arg2;
  2778. }
  2779. $compare = $max->compare($min);
  2780. if (!$compare) {
  2781. return $min->isPrime() ? $min : false;
  2782. } elseif ($compare < 0) {
  2783. // if $min is bigger then $max, swap $min and $max
  2784. $temp = $max;
  2785. $max = $min;
  2786. $min = $temp;
  2787. }
  2788. static $one, $two;
  2789. if (!isset($one)) {
  2790. $one = new static(1);
  2791. $two = new static(2);
  2792. }
  2793. $start = time();
  2794. $x = $this->random($min, $max);
  2795. // gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
  2796. if (MATH_BIGINTEGER_MODE == self::MODE_GMP && extension_loaded('gmp')) {
  2797. $p = new static();
  2798. $p->value = gmp_nextprime($x->value);
  2799. if ($p->compare($max) <= 0) {
  2800. return $p;
  2801. }
  2802. if (!$min->equals($x)) {
  2803. $x = $x->subtract($one);
  2804. }
  2805. return $x->randomPrime($min, $x);
  2806. }
  2807. if ($x->equals($two)) {
  2808. return $x;
  2809. }
  2810. $x->_make_odd();
  2811. if ($x->compare($max) > 0) {
  2812. // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range
  2813. if ($min->equals($max)) {
  2814. return false;
  2815. }
  2816. $x = $min->copy();
  2817. $x->_make_odd();
  2818. }
  2819. $initial_x = $x->copy();
  2820. while (true) {
  2821. if ($timeout !== false && time() - $start > $timeout) {
  2822. return false;
  2823. }
  2824. if ($x->isPrime()) {
  2825. return $x;
  2826. }
  2827. $x = $x->add($two);
  2828. if ($x->compare($max) > 0) {
  2829. $x = $min->copy();
  2830. if ($x->equals($two)) {
  2831. return $x;
  2832. }
  2833. $x->_make_odd();
  2834. }
  2835. if ($x->equals($initial_x)) {
  2836. return false;
  2837. }
  2838. }
  2839. }
  2840. /**
  2841. * Make the current number odd
  2842. *
  2843. * If the current number is odd it'll be unchanged. If it's even, one will be added to it.
  2844. *
  2845. * @see self::randomPrime()
  2846. * @access private
  2847. */
  2848. function _make_odd()
  2849. {
  2850. switch (MATH_BIGINTEGER_MODE) {
  2851. case self::MODE_GMP:
  2852. gmp_setbit($this->value, 0);
  2853. break;
  2854. case self::MODE_BCMATH:
  2855. if ($this->value[strlen($this->value) - 1] % 2 == 0) {
  2856. $this->value = bcadd($this->value, '1');
  2857. }
  2858. break;
  2859. default:
  2860. $this->value[0] |= 1;
  2861. }
  2862. }
  2863. /**
  2864. * Checks a numer to see if it's prime
  2865. *
  2866. * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the
  2867. * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads
  2868. * on a website instead of just one.
  2869. *
  2870. * @param \phpseclib\Math\BigInteger $t
  2871. * @return bool
  2872. * @access public
  2873. * @internal Uses the
  2874. * {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. See
  2875. * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24}.
  2876. */
  2877. function isPrime($t = false)
  2878. {
  2879. $length = strlen($this->toBytes());
  2880. if (!$t) {
  2881. // see HAC 4.49 "Note (controlling the error probability)"
  2882. // @codingStandardsIgnoreStart
  2883. if ($length >= 163) { $t = 2; } // floor(1300 / 8)
  2884. else if ($length >= 106) { $t = 3; } // floor( 850 / 8)
  2885. else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8)
  2886. else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8)
  2887. else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8)
  2888. else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8)
  2889. else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8)
  2890. else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8)
  2891. else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8)
  2892. else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8)
  2893. else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8)
  2894. else { $t = 27; }
  2895. // @codingStandardsIgnoreEnd
  2896. }
  2897. // ie. gmp_testbit($this, 0)
  2898. // ie. isEven() or !isOdd()
  2899. switch (MATH_BIGINTEGER_MODE) {
  2900. case self::MODE_GMP:
  2901. return gmp_prob_prime($this->value, $t) != 0;
  2902. case self::MODE_BCMATH:
  2903. if ($this->value === '2') {
  2904. return true;
  2905. }
  2906. if ($this->value[strlen($this->value) - 1] % 2 == 0) {
  2907. return false;
  2908. }
  2909. break;
  2910. default:
  2911. if ($this->value == array(2)) {
  2912. return true;
  2913. }
  2914. if (~$this->value[0] & 1) {
  2915. return false;
  2916. }
  2917. }
  2918. static $primes, $zero, $one, $two;
  2919. if (!isset($primes)) {
  2920. $primes = array(
  2921. 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
  2922. 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
  2923. 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
  2924. 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,
  2925. 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419,
  2926. 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509,
  2927. 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617,
  2928. 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727,
  2929. 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829,
  2930. 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947,
  2931. 953, 967, 971, 977, 983, 991, 997
  2932. );
  2933. if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
  2934. for ($i = 0; $i < count($primes); ++$i) {
  2935. $primes[$i] = new static($primes[$i]);
  2936. }
  2937. }
  2938. $zero = new static();
  2939. $one = new static(1);
  2940. $two = new static(2);
  2941. }
  2942. if ($this->equals($one)) {
  2943. return false;
  2944. }
  2945. // see HAC 4.4.1 "Random search for probable primes"
  2946. if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
  2947. foreach ($primes as $prime) {
  2948. list(, $r) = $this->divide($prime);
  2949. if ($r->equals($zero)) {
  2950. return $this->equals($prime);
  2951. }
  2952. }
  2953. } else {
  2954. $value = $this->value;
  2955. foreach ($primes as $prime) {
  2956. list(, $r) = $this->_divide_digit($value, $prime);
  2957. if (!$r) {
  2958. return count($value) == 1 && $value[0] == $prime;
  2959. }
  2960. }
  2961. }
  2962. $n = $this->copy();
  2963. $n_1 = $n->subtract($one);
  2964. $n_2 = $n->subtract($two);
  2965. $r = $n_1->copy();
  2966. $r_value = $r->value;
  2967. // ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s));
  2968. if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
  2969. $s = 0;
  2970. // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier
  2971. while ($r->value[strlen($r->value) - 1] % 2 == 0) {
  2972. $r->value = bcdiv($r->value, '2', 0);
  2973. ++$s;
  2974. }
  2975. } else {
  2976. for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) {
  2977. $temp = ~$r_value[$i] & 0xFFFFFF;
  2978. for ($j = 1; ($temp >> $j) & 1; ++$j) {
  2979. }
  2980. if ($j != 25) {
  2981. break;
  2982. }
  2983. }
  2984. $s = 26 * $i + $j - 1;
  2985. $r->_rshift($s);
  2986. }
  2987. for ($i = 0; $i < $t; ++$i) {
  2988. $a = $this->random($two, $n_2);
  2989. $y = $a->modPow($r, $n);
  2990. if (!$y->equals($one) && !$y->equals($n_1)) {
  2991. for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) {
  2992. $y = $y->modPow($two, $n);
  2993. if ($y->equals($one)) {
  2994. return false;
  2995. }
  2996. }
  2997. if (!$y->equals($n_1)) {
  2998. return false;
  2999. }
  3000. }
  3001. }
  3002. return true;
  3003. }
  3004. /**
  3005. * Logical Left Shift
  3006. *
  3007. * Shifts BigInteger's by $shift bits.
  3008. *
  3009. * @param int $shift
  3010. * @access private
  3011. */
  3012. function _lshift($shift)
  3013. {
  3014. if ($shift == 0) {
  3015. return;
  3016. }
  3017. $num_digits = (int) ($shift / self::$base);
  3018. $shift %= self::$base;
  3019. $shift = 1 << $shift;
  3020. $carry = 0;
  3021. for ($i = 0; $i < count($this->value); ++$i) {
  3022. $temp = $this->value[$i] * $shift + $carry;
  3023. $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
  3024. $this->value[$i] = (int) ($temp - $carry * self::$baseFull);
  3025. }
  3026. if ($carry) {
  3027. $this->value[count($this->value)] = $carry;
  3028. }
  3029. while ($num_digits--) {
  3030. array_unshift($this->value, 0);
  3031. }
  3032. }
  3033. /**
  3034. * Logical Right Shift
  3035. *
  3036. * Shifts BigInteger's by $shift bits.
  3037. *
  3038. * @param int $shift
  3039. * @access private
  3040. */
  3041. function _rshift($shift)
  3042. {
  3043. if ($shift == 0) {
  3044. return;
  3045. }
  3046. $num_digits = (int) ($shift / self::$base);
  3047. $shift %= self::$base;
  3048. $carry_shift = self::$base - $shift;
  3049. $carry_mask = (1 << $shift) - 1;
  3050. if ($num_digits) {
  3051. $this->value = array_slice($this->value, $num_digits);
  3052. }
  3053. $carry = 0;
  3054. for ($i = count($this->value) - 1; $i >= 0; --$i) {
  3055. $temp = $this->value[$i] >> $shift | $carry;
  3056. $carry = ($this->value[$i] & $carry_mask) << $carry_shift;
  3057. $this->value[$i] = $temp;
  3058. }
  3059. $this->value = $this->_trim($this->value);
  3060. }
  3061. /**
  3062. * Normalize
  3063. *
  3064. * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision
  3065. *
  3066. * @param \phpseclib\Math\BigInteger
  3067. * @return \phpseclib\Math\BigInteger
  3068. * @see self::_trim()
  3069. * @access private
  3070. */
  3071. function _normalize($result)
  3072. {
  3073. $result->precision = $this->precision;
  3074. $result->bitmask = $this->bitmask;
  3075. switch (MATH_BIGINTEGER_MODE) {
  3076. case self::MODE_GMP:
  3077. if ($this->bitmask !== false) {
  3078. $result->value = gmp_and($result->value, $result->bitmask->value);
  3079. }
  3080. return $result;
  3081. case self::MODE_BCMATH:
  3082. if (!empty($result->bitmask->value)) {
  3083. $result->value = bcmod($result->value, $result->bitmask->value);
  3084. }
  3085. return $result;
  3086. }
  3087. $value = &$result->value;
  3088. if (!count($value)) {
  3089. return $result;
  3090. }
  3091. $value = $this->_trim($value);
  3092. if (!empty($result->bitmask->value)) {
  3093. $length = min(count($value), count($this->bitmask->value));
  3094. $value = array_slice($value, 0, $length);
  3095. for ($i = 0; $i < $length; ++$i) {
  3096. $value[$i] = $value[$i] & $this->bitmask->value[$i];
  3097. }
  3098. }
  3099. return $result;
  3100. }
  3101. /**
  3102. * Trim
  3103. *
  3104. * Removes leading zeros
  3105. *
  3106. * @param array $value
  3107. * @return \phpseclib\Math\BigInteger
  3108. * @access private
  3109. */
  3110. function _trim($value)
  3111. {
  3112. for ($i = count($value) - 1; $i >= 0; --$i) {
  3113. if ($value[$i]) {
  3114. break;
  3115. }
  3116. unset($value[$i]);
  3117. }
  3118. return $value;
  3119. }
  3120. /**
  3121. * Array Repeat
  3122. *
  3123. * @param $input Array
  3124. * @param $multiplier mixed
  3125. * @return array
  3126. * @access private
  3127. */
  3128. function _array_repeat($input, $multiplier)
  3129. {
  3130. return ($multiplier) ? array_fill(0, $multiplier, $input) : array();
  3131. }
  3132. /**
  3133. * Logical Left Shift
  3134. *
  3135. * Shifts binary strings $shift bits, essentially multiplying by 2**$shift.
  3136. *
  3137. * @param $x String
  3138. * @param $shift Integer
  3139. * @return string
  3140. * @access private
  3141. */
  3142. function _base256_lshift(&$x, $shift)
  3143. {
  3144. if ($shift == 0) {
  3145. return;
  3146. }
  3147. $num_bytes = $shift >> 3; // eg. floor($shift/8)
  3148. $shift &= 7; // eg. $shift % 8
  3149. $carry = 0;
  3150. for ($i = strlen($x) - 1; $i >= 0; --$i) {
  3151. $temp = ord($x[$i]) << $shift | $carry;
  3152. $x[$i] = chr($temp);
  3153. $carry = $temp >> 8;
  3154. }
  3155. $carry = ($carry != 0) ? chr($carry) : '';
  3156. $x = $carry . $x . str_repeat(chr(0), $num_bytes);
  3157. }
  3158. /**
  3159. * Logical Right Shift
  3160. *
  3161. * Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder.
  3162. *
  3163. * @param $x String
  3164. * @param $shift Integer
  3165. * @return string
  3166. * @access private
  3167. */
  3168. function _base256_rshift(&$x, $shift)
  3169. {
  3170. if ($shift == 0) {
  3171. $x = ltrim($x, chr(0));
  3172. return '';
  3173. }
  3174. $num_bytes = $shift >> 3; // eg. floor($shift/8)
  3175. $shift &= 7; // eg. $shift % 8
  3176. $remainder = '';
  3177. if ($num_bytes) {
  3178. $start = $num_bytes > strlen($x) ? -strlen($x) : -$num_bytes;
  3179. $remainder = substr($x, $start);
  3180. $x = substr($x, 0, -$num_bytes);
  3181. }
  3182. $carry = 0;
  3183. $carry_shift = 8 - $shift;
  3184. for ($i = 0; $i < strlen($x); ++$i) {
  3185. $temp = (ord($x[$i]) >> $shift) | $carry;
  3186. $carry = (ord($x[$i]) << $carry_shift) & 0xFF;
  3187. $x[$i] = chr($temp);
  3188. }
  3189. $x = ltrim($x, chr(0));
  3190. $remainder = chr($carry >> $carry_shift) . $remainder;
  3191. return ltrim($remainder, chr(0));
  3192. }
  3193. // one quirk about how the following functions are implemented is that PHP defines N to be an unsigned long
  3194. // at 32-bits, while java's longs are 64-bits.
  3195. /**
  3196. * Converts 32-bit integers to bytes.
  3197. *
  3198. * @param int $x
  3199. * @return string
  3200. * @access private
  3201. */
  3202. function _int2bytes($x)
  3203. {
  3204. return ltrim(pack('N', $x), chr(0));
  3205. }
  3206. /**
  3207. * Converts bytes to 32-bit integers
  3208. *
  3209. * @param string $x
  3210. * @return int
  3211. * @access private
  3212. */
  3213. function _bytes2int($x)
  3214. {
  3215. $temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT));
  3216. return $temp['int'];
  3217. }
  3218. /**
  3219. * DER-encode an integer
  3220. *
  3221. * The ability to DER-encode integers is needed to create RSA public keys for use with OpenSSL
  3222. *
  3223. * @see self::modPow()
  3224. * @access private
  3225. * @param int $length
  3226. * @return string
  3227. */
  3228. function _encodeASN1Length($length)
  3229. {
  3230. if ($length <= 0x7F) {
  3231. return chr($length);
  3232. }
  3233. $temp = ltrim(pack('N', $length), chr(0));
  3234. return pack('Ca*', 0x80 | strlen($temp), $temp);
  3235. }
  3236. /**
  3237. * Single digit division
  3238. *
  3239. * Even if int64 is being used the division operator will return a float64 value
  3240. * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't
  3241. * have the precision of int64 this is a problem so, when int64 is being used,
  3242. * we'll guarantee that the dividend is divisible by first subtracting the remainder.
  3243. *
  3244. * @access private
  3245. * @param int $x
  3246. * @param int $y
  3247. * @return int
  3248. */
  3249. function _safe_divide($x, $y)
  3250. {
  3251. if (self::$base === 26) {
  3252. return (int) ($x / $y);
  3253. }
  3254. // self::$base === 31
  3255. return ($x - ($x % $y)) / $y;
  3256. }
  3257. }