Example #1
0
 public function toString($base = 10)
 {
     if ($base == 10) {
         return $this->str;
     } else {
         if ($base == 16) {
             return BigInteger::bcdechex($this->str);
         }
     }
 }
Example #2
0
 /**
  * Adds leading zeros if necessary to the unscaled value to represent the full decimal number.
  *
  * @return string
  */
 private function getUnscaledValueWithLeadingZeros()
 {
     $value = (string) $this->intVal;
     $targetLength = $this->scale + 1;
     $negative = $this->intVal->isNegative();
     $length = strlen($value);
     if ($negative) {
         --$length;
     }
     if ($length >= $targetLength) {
         return $value;
     }
     if ($negative) {
         $value = substr($value, 1);
     }
     $value = str_pad($value, $targetLength, '0', STR_PAD_LEFT);
     if ($negative) {
         $value = '-' . $value;
     }
     return $value;
 }
Example #3
0
 /**
  * Pure-PHP implementation of SHA384 and SHA512
  *
  * @access private
  * @param String $m
  */
 function _sha512($m)
 {
     if (!class_exists('Math_BigInteger')) {
         require_once 'Math/BigInteger.php';
     }
     static $init384, $init512, $k;
     if (!isset($k)) {
         // Initialize variables
         $init384 = array('cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939', '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4');
         $init512 = array('6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1', '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179');
         for ($i = 0; $i < 8; $i++) {
             $init384[$i] = new BigInteger($init384[$i], 16);
             $init384[$i]->setPrecision(64);
             $init512[$i] = new BigInteger($init512[$i], 16);
             $init512[$i]->setPrecision(64);
         }
         // Initialize table of round constants
         // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
         $k = array('428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817');
         for ($i = 0; $i < 80; $i++) {
             $k[$i] = new BigInteger($k[$i], 16);
         }
     }
     $hash = $this->l == 48 ? $init384 : $init512;
     // Pre-processing
     $length = strlen($m);
     // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
     $m .= str_repeat(chr(0), 128 - ($length + 16 & 0x7f));
     $m[$length] = chr(0x80);
     // we don't support hashing strings 512MB long
     $m .= pack('N4', 0, 0, 0, $length << 3);
     // Process the message in successive 1024-bit chunks
     $chunks = str_split($m, 128);
     foreach ($chunks as $chunk) {
         $w = array();
         for ($i = 0; $i < 16; $i++) {
             $temp = new BigInteger($this->_string_shift($chunk, 8), 256);
             $temp->setPrecision(64);
             $w[] = $temp;
         }
         // Extend the sixteen 32-bit words into eighty 32-bit words
         for ($i = 16; $i < 80; $i++) {
             $temp = array($w[$i - 15]->bitwise_rightRotate(1), $w[$i - 15]->bitwise_rightRotate(8), $w[$i - 15]->bitwise_rightShift(7));
             $s0 = $temp[0]->bitwise_xor($temp[1]);
             $s0 = $s0->bitwise_xor($temp[2]);
             $temp = array($w[$i - 2]->bitwise_rightRotate(19), $w[$i - 2]->bitwise_rightRotate(61), $w[$i - 2]->bitwise_rightShift(6));
             $s1 = $temp[0]->bitwise_xor($temp[1]);
             $s1 = $s1->bitwise_xor($temp[2]);
             $w[$i] = $w[$i - 16]->copy();
             $w[$i] = $w[$i]->add($s0);
             $w[$i] = $w[$i]->add($w[$i - 7]);
             $w[$i] = $w[$i]->add($s1);
         }
         // Initialize hash value for this chunk
         $a = $hash[0]->copy();
         $b = $hash[1]->copy();
         $c = $hash[2]->copy();
         $d = $hash[3]->copy();
         $e = $hash[4]->copy();
         $f = $hash[5]->copy();
         $g = $hash[6]->copy();
         $h = $hash[7]->copy();
         // Main loop
         for ($i = 0; $i < 80; $i++) {
             $temp = array($a->bitwise_rightRotate(28), $a->bitwise_rightRotate(34), $a->bitwise_rightRotate(39));
             $s0 = $temp[0]->bitwise_xor($temp[1]);
             $s0 = $s0->bitwise_xor($temp[2]);
             $temp = array($a->bitwise_and($b), $a->bitwise_and($c), $b->bitwise_and($c));
             $maj = $temp[0]->bitwise_xor($temp[1]);
             $maj = $maj->bitwise_xor($temp[2]);
             $t2 = $s0->add($maj);
             $temp = array($e->bitwise_rightRotate(14), $e->bitwise_rightRotate(18), $e->bitwise_rightRotate(41));
             $s1 = $temp[0]->bitwise_xor($temp[1]);
             $s1 = $s1->bitwise_xor($temp[2]);
             $temp = array($e->bitwise_and($f), $g->bitwise_and($e->bitwise_not()));
             $ch = $temp[0]->bitwise_xor($temp[1]);
             $t1 = $h->add($s1);
             $t1 = $t1->add($ch);
             $t1 = $t1->add($k[$i]);
             $t1 = $t1->add($w[$i]);
             $h = $g->copy();
             $g = $f->copy();
             $f = $e->copy();
             $e = $d->add($t1);
             $d = $c->copy();
             $c = $b->copy();
             $b = $a->copy();
             $a = $t1->add($t2);
         }
         // Add this chunk's hash to result so far
         $hash = array($hash[0]->add($a), $hash[1]->add($b), $hash[2]->add($c), $hash[3]->add($d), $hash[4]->add($e), $hash[5]->add($f), $hash[6]->add($g), $hash[7]->add($h));
     }
     // Produce the final hash value (big-endian)
     // (Crypt_Hash::hash() trims the output for hashes but not for HMACs.  as such, we trim the output here)
     $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . $hash[4]->toBytes() . $hash[5]->toBytes();
     if ($this->l != 48) {
         $temp .= $hash[6]->toBytes() . $hash[7]->toBytes();
     }
     return $temp;
 }
Example #4
0
 /**
  * Generate a random prime number.
  *
  * If there's not a prime within the given range, false will be returned.  If more than $timeout seconds have elapsed,
  * give up and return false.
  *
  * @param optional Integer $min
  * @param optional Integer $max
  * @param optional Integer $timeout
  * @return BigInteger
  * @access public
  * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}.
  */
 function randomPrime($min = false, $max = false, $timeout = false)
 {
     if ($min === false) {
         $min = new BigInteger(0);
     }
     if ($max === false) {
         $max = new BigInteger(0x7fffffff);
     }
     $compare = $max->compare($min);
     if (!$compare) {
         return $min->isPrime() ? $min : false;
     } else {
         if ($compare < 0) {
             // if $min is bigger then $max, swap $min and $max
             $temp = $max;
             $max = $min;
             $min = $temp;
         }
     }
     static $one, $two;
     if (!isset($one)) {
         $one = new BigInteger(1);
         $two = new BigInteger(2);
     }
     $start = time();
     $x = $this->random($min, $max);
     // gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
     if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP && function_exists('gmp_nextprime')) {
         $p = new BigInteger();
         $p->value = gmp_nextprime($x->value);
         if ($p->compare($max) <= 0) {
             return $p;
         }
         if (!$min->equals($x)) {
             $x = $x->subtract($one);
         }
         return $x->randomPrime($min, $x);
     }
     if ($x->equals($two)) {
         return $x;
     }
     $x->_make_odd();
     if ($x->compare($max) > 0) {
         // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range
         if ($min->equals($max)) {
             return false;
         }
         $x = $min->copy();
         $x->_make_odd();
     }
     $initial_x = $x->copy();
     while (true) {
         if ($timeout !== false && time() - $start > $timeout) {
             return false;
         }
         if ($x->isPrime()) {
             return $x;
         }
         $x = $x->add($two);
         if ($x->compare($max) > 0) {
             $x = $min->copy();
             if ($x->equals($two)) {
                 return $x;
             }
             $x->_make_odd();
         }
         if ($x->equals($initial_x)) {
             return false;
         }
     }
 }
Example #5
0
 /**
  * Generate a random number
  *
  * @param optional Integer $min
  * @param optional Integer $max
  * @return BigInteger
  * @access public
  */
 function random($min = false, $max = false)
 {
     if ($min === false) {
         $min = new BigInteger(0);
     }
     if ($max === false) {
         $max = new BigInteger(0x7fffffff);
     }
     $compare = $max->compare($min);
     if (!$compare) {
         return $this->_normalize($min);
     } else {
         if ($compare < 0) {
             // if $min is bigger then $max, swap $min and $max
             $temp = $max;
             $max = $min;
             $min = $temp;
         }
     }
     $generator = $this->generator;
     $max = $max->subtract($min);
     $max = ltrim($max->toBytes(), chr(0));
     $size = strlen($max) - 1;
     $random = '';
     $bytes = $size & 1;
     for ($i = 0; $i < $bytes; ++$i) {
         $random .= chr($generator(0, 255));
     }
     $blocks = $size >> 1;
     for ($i = 0; $i < $blocks; ++$i) {
         // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems
         $random .= pack('n', $generator(0, 0xffff));
     }
     $temp = new BigInteger($random, 256);
     if ($temp->compare(new BigInteger(substr($max, 1), 256)) > 0) {
         $random = chr($generator(0, ord($max[0]) - 1)) . $random;
     } else {
         $random = chr($generator(0, ord($max[0]))) . $random;
     }
     $random = new BigInteger($random, 256);
     return $this->_normalize($random->add($min));
 }
Example #6
0
 /**
  * Get the index of a revoked certificate.
  *
  * @param array $rclist
  * @param String $serial
  * @param Boolean $create optional
  * @access private
  * @return Integer or false
  */
 function _revokedCertificate(&$rclist, $serial, $create = false)
 {
     $serial = new BigInteger($serial);
     foreach ($rclist as $i => $rc) {
         if (!$serial->compare($rc['userCertificate'])) {
             return $i;
         }
     }
     if (!$create) {
         return false;
     }
     $i = count($rclist);
     $rclist[] = array('userCertificate' => $serial, 'revocationDate' => $this->_timeField(@date('D, d M Y H:i:s O')));
     return $i;
 }
Example #7
0
 /**
  * Exponentiate with or without Chinese Remainder Theorem
  *
  * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}.
  *
  * @access private
  * @param Math_BigInteger $x
  * @return Math_BigInteger
  */
 function _exponentiate($x)
 {
     if (empty($this->primes) || empty($this->coefficients) || empty($this->exponents)) {
         return $x->modPow($this->exponent, $this->modulus);
     }
     $num_primes = count($this->primes);
     if (defined('CRYPT_RSA_DISABLE_BLINDING')) {
         $m_i = array(1 => $x->modPow($this->exponents[1], $this->primes[1]), 2 => $x->modPow($this->exponents[2], $this->primes[2]));
         $h = $m_i[1]->subtract($m_i[2]);
         $h = $h->multiply($this->coefficients[2]);
         list(, $h) = $h->divide($this->primes[1]);
         $m = $m_i[2]->add($h->multiply($this->primes[2]));
         $r = $this->primes[1];
         for ($i = 3; $i <= $num_primes; $i++) {
             $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]);
             $r = $r->multiply($this->primes[$i - 1]);
             $h = $m_i->subtract($m);
             $h = $h->multiply($this->coefficients[$i]);
             list(, $h) = $h->divide($this->primes[$i]);
             $m = $m->add($r->multiply($h));
         }
     } else {
         $smallest = $this->primes[1];
         for ($i = 2; $i <= $num_primes; $i++) {
             if ($smallest->compare($this->primes[$i]) > 0) {
                 $smallest = $this->primes[$i];
             }
         }
         $one = new BigInteger(1);
         $r = $one->random($one, $smallest->subtract($one));
         $m_i = array(1 => $this->_blind($x, $r, 1), 2 => $this->_blind($x, $r, 2));
         $h = $m_i[1]->subtract($m_i[2]);
         $h = $h->multiply($this->coefficients[2]);
         list(, $h) = $h->divide($this->primes[1]);
         $m = $m_i[2]->add($h->multiply($this->primes[2]));
         $r = $this->primes[1];
         for ($i = 3; $i <= $num_primes; $i++) {
             $m_i = $this->_blind($x, $r, $i);
             $r = $r->multiply($this->primes[$i - 1]);
             $h = $m_i->subtract($m);
             $h = $h->multiply($this->coefficients[$i]);
             list(, $h) = $h->divide($this->primes[$i]);
             $m = $m->add($r->multiply($h));
         }
     }
     return $m;
 }
 /**
  * @return GmpBigInteger
  **/
 public function pow(BigInteger $exp)
 {
     $result = new self();
     $result->resource = gmp_pow($this->resource, $exp->intValue());
     return $result;
 }