BigIntegerGmp.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. /*
  3. * This file is part of the PHPASN1 library.
  4. *
  5. * For the full copyright and license information, please view the LICENSE
  6. * file that was distributed with this source code.
  7. */
  8. namespace FG\Utility;
  9. /**
  10. * Class BigIntegerGmp
  11. * Integer representation of big numbers using the GMP extension to perform operations.
  12. * @package FG\Utility
  13. * @internal
  14. */
  15. class BigIntegerGmp extends BigInteger
  16. {
  17. /**
  18. * Resource handle.
  19. * @var \GMP
  20. */
  21. protected $_rh;
  22. public function __clone()
  23. {
  24. $this->_rh = gmp_add($this->_rh, 0);
  25. }
  26. protected function _fromString($str)
  27. {
  28. $this->_rh = gmp_init($str, 10);
  29. }
  30. protected function _fromInteger($integer)
  31. {
  32. $this->_rh = gmp_init($integer, 10);
  33. }
  34. public function __toString()
  35. {
  36. return gmp_strval($this->_rh, 10);
  37. }
  38. public function toInteger()
  39. {
  40. if ($this->compare(PHP_INT_MAX) > 0 || $this->compare(PHP_INT_MIN) < 0) {
  41. throw new \OverflowException(sprintf('Can not represent %s as integer.', $this));
  42. }
  43. return gmp_intval($this->_rh);
  44. }
  45. public function isNegative()
  46. {
  47. return gmp_sign($this->_rh) === -1;
  48. }
  49. protected function _unwrap($number)
  50. {
  51. if ($number instanceof self) {
  52. return $number->_rh;
  53. }
  54. return $number;
  55. }
  56. public function compare($number)
  57. {
  58. return gmp_cmp($this->_rh, $this->_unwrap($number));
  59. }
  60. public function add($b)
  61. {
  62. $ret = new self();
  63. $ret->_rh = gmp_add($this->_rh, $this->_unwrap($b));
  64. return $ret;
  65. }
  66. public function subtract($b)
  67. {
  68. $ret = new self();
  69. $ret->_rh = gmp_sub($this->_rh, $this->_unwrap($b));
  70. return $ret;
  71. }
  72. public function multiply($b)
  73. {
  74. $ret = new self();
  75. $ret->_rh = gmp_mul($this->_rh, $this->_unwrap($b));
  76. return $ret;
  77. }
  78. public function modulus($b)
  79. {
  80. $ret = new self();
  81. $ret->_rh = gmp_mod($this->_rh, $this->_unwrap($b));
  82. return $ret;
  83. }
  84. public function toPower($b)
  85. {
  86. if ($b instanceof self) {
  87. // gmp_pow accepts just an integer
  88. if ($b->compare(PHP_INT_MAX) > 0) {
  89. throw new \UnexpectedValueException('Unable to raise to power greater than PHP_INT_MAX.');
  90. }
  91. $b = gmp_intval($b->_rh);
  92. }
  93. $ret = new self();
  94. $ret->_rh = gmp_pow($this->_rh, $b);
  95. return $ret;
  96. }
  97. public function shiftRight($bits=8)
  98. {
  99. $ret = new self();
  100. $ret->_rh = gmp_div($this->_rh, gmp_pow(2, $bits));
  101. return $ret;
  102. }
  103. public function shiftLeft($bits=8)
  104. {
  105. $ret = new self();
  106. $ret->_rh = gmp_mul($this->_rh, gmp_pow(2, $bits));
  107. return $ret;
  108. }
  109. public function absoluteValue()
  110. {
  111. $ret = new self();
  112. $ret->_rh = gmp_abs($this->_rh);
  113. return $ret;
  114. }
  115. }