function is_prime($n, $k)
{
    if ($n == 2) {
        return true;
    }
    if ($n < 2 || $n % 2 == 0) {
        return false;
    }
    $d = $n - 1;
    $s = 0;
    while ($d % 2 == 0) {
        $d /= 2;
        $s++;
    }
    for ($i = 0; $i < $k; $i++) {
        $a = rand(2, $n - 1);
        $x = bcpowmod($a, $d, $n);
        if ($x == 1 || $x == $n - 1) {
            continue;
        }
        for ($j = 1; $j < $s; $j++) {
            $x = bcmod(bcmul($x, $x), $n);
            if ($x == 1) {
                return false;
            }
            if ($x == $n - 1) {
                continue 2;
            }
        }
        return false;
    }
    return true;
}
Example #2
0
function powmod($base, $exponent, $modulus)
{
    if (function_exists('gmp_powm')) {
        // fast
        return gmp_strval(gmp_powm($base, $exponent, $modulus));
    }
    if (function_exists('bi_powmod')) {
        // not tested
        return bi_sto_str(bi_powmod($base, $exponent, $modulus));
    }
    if (function_exists('bcpowmod')) {
        // slow
        return bcpowmod($base, $exponent, $modulus);
    }
    // emulation, slow
    $square = bcmod($base, $modulus);
    $result = 1;
    while (bccomp($exponent, 0) > 0) {
        if (bcmod($exponent, 2)) {
            $result = bcmod(bcmul($result, $square), $modulus);
        }
        $square = bcmod(bcmul($square, $square), $modulus);
        $exponent = bcdiv($exponent, 2);
    }
    return $result;
}
Example #3
0
 public static function encryptPortion($portion, $n, $e)
 {
     $plain = '0';
     foreach (array_reverse($portion) as $k => $v) {
         $plain = bcadd($plain, bcmul($v, bcpowmod(256, $k, $n)));
     }
     $t = self::dec2hex(bcpowmod($plain, $e, $n));
     return $t;
 }
Example #4
0
 protected function expmod($b, $e, $m)
 {
     //if($e==0){return 1;}
     $t = bcpowmod($b, $e, $m);
     if ($t[0] === '-') {
         $t = bcadd($t, $m);
     }
     return $t;
 }
 public static function encrypt($text)
 {
     $text = self::bchexdec(bin2hex($text));
     $n = bcpowmod($text, self::$rsa_exp, self::$rsa_mod);
     $ret = '';
     while ($n > 0) {
         $ret = chr(bcmod($n, 256)) . $ret;
         $n = bcdiv($n, 256, 0);
     }
     return $ret;
 }
Example #6
0
/**
 * powmod
 * Raise a number to a power mod n
 * This could probably be made faster with some Montgomery trickery, but it's just fallback for now
 * @param string Decimal string to be raised
 * @param string Decimal string of the power to raise to
 * @param string Decimal string the modulus
 * @return string Decimal string
 */
function powmod($num, $pow, $mod)
{
    if (function_exists('bcpowmod')) {
        return bcpowmod($num, $pow, $mod);
    }
    // Emulate bcpowmod
    $result = '1';
    do {
        if (!bccomp(bcmod($pow, '2'), '1')) {
            $result = bcmod(bcmul($result, $num), $mod);
        }
        $num = bcmod(bcpow($num, '2'), $mod);
        $pow = bcdiv($pow, '2');
    } while (bccomp($pow, '0'));
    return $result;
}
Example #7
0
 function biDecryptedString($s, $utf8_decoded = FALSE)
 {
     $blocks = split(",", $s);
     $result = "";
     for ($i = 0; $i < count($blocks); $i++) {
         $block = bcpowmod(self::biFromHex($blocks[$i]), $this->d, $this->m);
         for ($j = 0; $block !== "0"; $j++) {
             $curchar = bcmod($block, 256);
             $result .= chr($curchar);
             $block = bcdiv($block, 256, 0);
         }
     }
     $result = str_replace(chr(255), chr(0), $result);
     $result = substr($result, 0, strpos($result, chr(254)));
     return $utf8_decoded ? utf8_decode($result) : $result;
 }
Example #8
0
 private function _computeK()
 {
     $hash_input = str_pad($this->_Ahex, strlen($this->_srp->Nhex()), "0", STR_PAD_LEFT) . str_pad($this->_Bhex, strlen($this->_srp->Nhex()), "0", STR_PAD_LEFT);
     $hash_input = pack("H*", $hash_input);
     $this->_uhex = $this->_srp->hash($hash_input);
     $this->_udec = hex2dec($this->_uhex);
     $Stmp = bcpowmod($this->_vdec, $this->_udec, $this->_srp->Ndec());
     // v^u (mod N)
     $Stmp = bcmod(bcmul($Stmp, $this->_Adec), $this->_srp->Ndec());
     //v^u*A (mod N)
     $Stmp = bcpowmod($Stmp, $this->_bdec, $this->_srp->Ndec());
     // (v^u*A)^b (mod N)
     $this->_Sdec = $Stmp;
     $this->_Shex = dec2hex($this->_Sdec);
     $this->_Shex = str_pad($this->_Shex, strlen($this->_srp->Nhex()), "0", STR_PAD_LEFT);
     $this->_Khex = $this->_srp->keyHash(pack("H*", $this->_Shex));
 }
Example #9
0
 public static function modular_exp($base, $exponent, $modulus)
 {
     if (extension_loaded('gmp') && USE_EXT == 'GMP') {
         if ($exponent < 0) {
             return new ErrorException("Negative exponents (" . $exponent . ") not allowed");
         } else {
             $p = gmp_strval(gmp_powm($base, $exponent, $modulus));
             return $p;
         }
     } elseif (extension_loaded('bcmath') && USE_EXT == 'BCMATH') {
         if ($exponent < 0) {
             return new ErrorException("Negative exponents (" . $exponent . ") not allowed");
         } else {
             $p = bcpowmod($base, $exponent, $modulus);
             return $p;
         }
     } else {
         throw new ErrorException("Please install BCMATH or GMP");
     }
 }
Example #10
0
 /**
  * Create signature for given data
  *
  * @param string $data
  *
  * @return string
  */
 public function sign($data)
 {
     // Make data hash (16 bytes)
     $base = hash('md4', $data, true);
     // Add 40 random bytes
     for ($i = 0; $i < 10; ++$i) {
         $base .= pack('V', mt_rand());
     }
     // Add length of the base as first 2 bytes
     $base = pack('v', strlen($base)) . $base;
     // Modular exponentiation
     $dec = bcpowmod($this->reverseToDecimal($base), $this->power, $this->modulus);
     // Convert result to hexadecimal
     $hex = gmp_strval($dec, 16);
     // Fill empty bytes with zeros
     $hex = str_repeat('0', 132 - strlen($hex)) . $hex;
     // Reverse byte order
     $hexReversed = '';
     for ($i = 0; $i < strlen($hex) / 4; ++$i) {
         $hexReversed = substr($hex, $i * 4, 4) . $hexReversed;
     }
     return strtolower($hexReversed);
 }
Example #11
0
 /**
  * Create a signature for the given data
  *
  * @param string $data
  *
  * @return string
  */
 public function sign($data)
 {
     // Make data hash (16 bytes)
     $base = hash('md4', $data, true);
     // Add 40 random bytes
     for ($i = 0; $i < 10; ++$i) {
         $base .= pack('V', mt_rand());
     }
     // Add the length of the base (56 = 16 + 40) as the first 2 bytes
     $base = pack('v', mb_strlen($base, self::MB_ENCODING)) . $base;
     // Modular exponentiation
     $dec = bcpowmod(self::reverseToDecimal($base), $this->power, $this->modulus, 0);
     // Convert to hexadecimal
     $hex = self::dec2hex($dec);
     // Fill empty bytes with zeros
     $hex = str_repeat('0', 132 - mb_strlen($hex, self::MB_ENCODING)) . $hex;
     // Reverse byte order
     $hexReversed = '';
     for ($i = 0; $i < mb_strlen($hex, self::MB_ENCODING) / 4; ++$i) {
         $hexReversed = mb_substr($hex, $i * 4, 4, self::MB_ENCODING) . $hexReversed;
     }
     return mb_strtolower($hexReversed, self::MB_ENCODING);
 }
Example #12
0
 /**
  * Performs modular exponentiation.
  *
  * Here's a quick 'n dirty example:
  * <code>
  * <?php
  *    include('Math/BigInteger.php');
  *
  *    $a = new Math_BigInteger('10');
  *    $b = new Math_BigInteger('20');
  *    $c = new Math_BigInteger('30');
  *
  *    $c = $a->modPow($b, $c);
  *
  *    echo $c->toString(); // outputs 10
  * ?>
  * </code>
  *
  * @param Math_BigInteger $e
  * @param Math_BigInteger $n
  * @return Math_BigInteger
  * @access public
  * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and
  *    and although the approach involving repeated squaring does vastly better, it, too, is impractical
  *    for our purposes.  The reason being that division - by far the most complicated and time-consuming
  *    of the basic operations (eg. +,-,*,/) - occurs multiple times within it.
  *
  *    Modular reductions resolve this issue.  Although an individual modular reduction takes more time
  *    then an individual division, when performed in succession (with the same modulo), they're a lot faster.
  *
  *    The two most commonly used modular reductions are Barrett and Montgomery reduction.  Montgomery reduction,
  *    although faster, only works when the gcd of the modulo and of the base being used is 1.  In RSA, when the
  *    base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because
  *    the product of two odd numbers is odd), but what about when RSA isn't used?
  *
  *    In contrast, Barrett reduction has no such constraint.  As such, some bigint implementations perform a
  *    Barrett reduction after every operation in the modpow function.  Others perform Barrett reductions when the
  *    modulo is even and Montgomery reductions when the modulo is odd.  BigInteger.java's modPow method, however,
  *    uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and
  *    the other, a power of two - and recombine them, later.  This is the method that this modPow function uses.
  *    {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.
  */
 function modPow($e, $n)
 {
     $n = $n->abs();
     if ($e->compare(new Math_BigInteger()) < 0) {
         $e = $e->abs();
         $temp = $this->modInverse($n);
         if ($temp === false) {
             return false;
         }
         return $temp->modPow($e, $n);
     }
     switch (MATH_BIGINTEGER_MODE) {
         case MATH_BIGINTEGER_MODE_GMP:
             $temp = new Math_BigInteger();
             $temp->value = gmp_powm($this->value, $e->value, $n->value);
             return $temp;
         case MATH_BIGINTEGER_MODE_BCMATH:
             // even though the last parameter is optional, according to php.net, it's not optional in
             // PHP_Compat 1.5.0 when running PHP 4.
             $temp = new Math_BigInteger();
             $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
             return $temp;
     }
     if (empty($e->value)) {
         $temp = new Math_BigInteger();
         $temp->value = array(1);
         return $temp;
     }
     if ($e->value == array(1)) {
         list(, $temp) = $this->divide($n);
         return $temp;
     }
     if ($e->value == array(2)) {
         $temp = $this->_square();
         list(, $temp) = $temp->divide($n);
         return $temp;
     }
     // is the modulo odd?
     if ($n->value[0] & 1) {
         return $this->_slidingWindow($e, $n, MATH_BIGINTEGER_MONTGOMERY);
     }
     // if it's not, it's even
     // find the lowest set bit (eg. the max pow of 2 that divides $n)
     for ($i = 0; $i < count($n->value); $i++) {
         if ($n->value[$i]) {
             $temp = decbin($n->value[$i]);
             $j = strlen($temp) - strrpos($temp, '1') - 1;
             $j += 26 * $i;
             break;
         }
     }
     // at this point, 2^$j * $n/(2^$j) == $n
     $mod1 = $n->_copy();
     $mod1->_rshift($j);
     $mod2 = new Math_BigInteger();
     $mod2->value = array(1);
     $mod2->_lshift($j);
     $part1 = $mod1->value != array(1) ? $this->_slidingWindow($e, $mod1, MATH_BIGINTEGER_MONTGOMERY) : new Math_BigInteger();
     $part2 = $this->_slidingWindow($e, $mod2, MATH_BIGINTEGER_POWEROF2);
     $y1 = $mod2->modInverse($mod1);
     $y2 = $mod1->modInverse($mod2);
     $result = $part1->multiply($mod2);
     $result = $result->multiply($y1);
     $temp = $part2->multiply($mod1);
     $temp = $temp->multiply($y2);
     $result = $result->add($temp);
     list(, $result) = $result->divide($n);
     return $result;
 }
Example #13
0
 function powmod($base, $exponent, $modulus)
 {
     if (function_exists('bcpowmod')) {
         return bcpowmod($base, $exponent, $modulus);
     } else {
         return $this->_powmod($base, $exponent, $modulus);
     }
 }
 /**
  * Gets the remainder of this integer number raised to the integer `$exponent`, divided by the integer `$modulus`
  *
  * This method is faster than doing `$num->pow($exponent)->mod($modulus)`
  * and is primarily useful for cryptographic functionality.
  *
  * @throws fValidationException  When `$exponent` or `$modulus` is not a valid number
  *
  * @param  fNumber|string $exponent  The power to raise to - all non integer values will be truncated to integers
  * @param  fNumber|string $modulus   The value to divide by - all non integer values will be truncated to integers
  * @return fNumber  The remainder
  */
 public function powmod($exponent, $modulus)
 {
     $exp = self::parse($exponent, 'array');
     $mod = self::parse($modulus, 'array');
     if ($this->value[0] == '-') {
         throw new fProgrammerException('The method %s can only be called for positive number, however this number is negative', 'powmod()');
     }
     if ($exp['integer'][0] == '-') {
         throw new fProgrammerException('The exponent specified, %s, must be a positive integer, however it is negative', $exponent);
     }
     if ($mod['integer'][0] == '-') {
         throw new fProgrammerException('The modulus specified, %s, must be a positive integer, however it is negative', $modulus);
     }
     // All numbers involved in this need to be integers
     $exponent = $exp['integer'];
     $modulus = $mod['integer'];
     $len = strpos($this->value, '.') !== FALSE ? strpos($this->value, '.') : strlen($this->value);
     $value = substr($this->value, 0, $len);
     if (function_exists('bcpowmod')) {
         $result = bcpowmod($value, $exponent, $modulus, 0);
     } else {
         $exponent = self::baseConvert($exponent, 10, 2);
         $result = '+1';
         self::performDiv($value, $modulus, $first_modulus);
         for ($i = 0; $i < strlen($exponent); $i++) {
             self::performDiv(self::performMul($result, $result), $modulus, $result);
             if ($exponent[$i] == '1') {
                 self::performDiv(self::performMul($result, $first_modulus), $modulus, $result);
             }
         }
     }
     return new fNumber($result);
 }
Example #15
0
File: BC.php Project: ionux/phactor
 /**
  * Raises an arbitrary precision number to another,
  * reduced by a specified modulus.
  *
  * @param  string  $a        The first number.
  * @param  string  $b        The exponent.
  * @param  string  $c        The modulus.
  * @return string            The result of the operation.
  */
 public function powmod($a, $b, $c)
 {
     return bcpowmod($this->bcNormalize($a), $this->bcNormalize($b), $this->bcNormalize($c));
 }
Example #16
0
 /**
  * Decrypts a given string with the $dec_key and the $enc_mod
  *
  * @param string $encrypted
  * @param int $dec_key
  * @param int $enc_mod
  * @return string
  */
 public function decrypt($encrypted, $dec_key, $enc_mod)
 {
     //replaced split with explode
     $blocks = explode(' ', $encrypted);
     $result = "";
     $max = count($blocks);
     for ($i = 0; $i < $max; $i++) {
         $dec = $this->_hex2bint($blocks[$i]);
         $dec = bcpowmod($dec, $dec_key, $enc_mod);
         $ascii = $this->_bint2char($dec);
         $result .= $ascii;
     }
     return $this->_redundacyCheck($result);
 }
Example #17
0
 /**
  * powmod using bcmath extension
  */
 function _powmodBcmath($x, $y, $mod)
 {
     if (function_exists('bcpowmod')) {
         return bcpowmod($x, $y, $mod);
     } else {
         if (bccomp($y, 1) == 0) {
             return bcmod($x, $mod);
         } else {
             if (bcmod($y, 2) == 0) {
                 return bcmod(bcpow(Security_DSA::_powmodBcmath($x, bcdiv($y, 2), $mod), 2), $mod);
             } else {
                 return bcmod(bcmul($x, Security_DSA::_powmodBcmath($x, bcsub($y, 1), $mod)), $mod);
             }
         }
     }
 }
Example #18
0
/**
 * Attempt to create a shared secret with the OpenID Provider.
 *
 * @param $op_endpoint URL of the OpenID Provider endpoint.
 *
 * @return $assoc_handle The association handle.
 */
function openid_association($op_endpoint)
{
    //@todo Remove Old Associations:
    $openid_association = Database::get_main_table(TABLE_MAIN_OPENID_ASSOCIATION);
    $sql = "DELETE FROM {$openid_association}\n            WHERE created + expires_in < '" . api_get_utc_datetime() . "'";
    Database::query($sql);
    // Check to see if we have an association for this IdP already
    $op_endpoint = Database::escape_string($op_endpoint);
    $sql = "SELECT assoc_handle\n            FROM {$openid_association}\n            WHERE idp_endpoint_uri = '{$op_endpoint}'";
    $assoc_handle = Database::query($sql);
    if (Database::num_rows($assoc_handle) <= 1) {
        $mod = OPENID_DH_DEFAULT_MOD;
        $gen = OPENID_DH_DEFAULT_GEN;
        $r = _openid_dh_rand($mod);
        $private = bcadd($r, 1);
        $public = bcpowmod($gen, $private, $mod);
        // If there is no existing association, then request one
        $assoc_request = openid_association_request($public);
        $assoc_message = _openid_encode_message(_openid_create_message($assoc_request));
        $assoc_headers = array('Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8');
        //TODO
        $assoc_result = openid_http_request($op_endpoint, $assoc_headers, 'POST', $assoc_message);
        if (isset($assoc_result->error)) {
            return FALSE;
        }
        $assoc_response = _openid_parse_message($assoc_result->data);
        if (isset($assoc_response['mode']) && $assoc_response['mode'] == 'error') {
            return FALSE;
        }
        if ($assoc_response['session_type'] == 'DH-SHA1') {
            $spub = _openid_dh_base64_to_long($assoc_response['dh_server_public']);
            $enc_mac_key = base64_decode($assoc_response['enc_mac_key']);
            $shared = bcpowmod($spub, $private, $mod);
            $assoc_response['mac_key'] = base64_encode(_openid_dh_xorsecret($shared, $enc_mac_key));
        }
        //TODO
        $openid_association = Database::get_main_table(TABLE_MAIN_OPENID_ASSOCIATION);
        Database::query(sprintf("INSERT INTO {$openid_association} (idp_endpoint_uri, session_type, assoc_handle, assoc_type, expires_in, mac_key, created) VALUES('%s', '%s', '%s', '%s', %d, '%s', %d)", $op_endpoint, $assoc_response['session_type'], $assoc_response['assoc_handle'], $assoc_response['assoc_type'], $assoc_response['expires_in'], $assoc_response['mac_key'], api_get_utc_datetime()));
        $assoc_handle = $assoc_response['assoc_handle'];
    }
    return $assoc_handle;
}
Example #19
0
 /**
  * Computes the shared secret from the private DH value $dh and the other
  * party's public value in $pub_key
  *
  * @param string $pub_key other party's public value
  * @param mixed $dh Diffie-Hellman key
  * @return string
  * @throws Zend\OpenId\Exception
  */
 public static function computeDhSecret($pub_key, $dh)
 {
     if (function_exists('openssl_dh_compute_key')) {
         $ret = openssl_dh_compute_key($pub_key, $dh);
         if (ord($ret[0]) > 127) {
             $ret = "" . $ret;
         }
         return $ret;
     } else {
         if (extension_loaded('gmp')) {
             $bn_pub_key = self::binToBigNum($pub_key);
             $bn_secret = gmp_powm($bn_pub_key, $dh['priv_key'], $dh['p']);
             return self::bigNumToBin($bn_secret);
         } else {
             if (extension_loaded('bcmath')) {
                 $bn_pub_key = self::binToBigNum($pub_key);
                 $bn_secret = bcpowmod($bn_pub_key, $dh['priv_key'], $dh['p']);
                 return self::bigNumToBin($bn_secret);
             }
         }
     }
     throw new Exception('The system doesn\'t have proper big integer extension', Exception::UNSUPPORTED_LONG_MATH);
 }
Example #20
0
         $_SESSION["userId"] = $currentUser->userId;
     } else {
         $_SESSION["s"] = "112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00";
         $_SESSION["v"] = "112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00";
     }
     $_SESSION["b"] = clipperz_randomSeed();
     //				$_SESSION["b"] = "5761e6c84d22ea3c5649de01702d60f674ccfe79238540eb34c61cd020230c53";
     $_SESSION["B"] = dec2base(bcadd(base2dec($_SESSION["v"], 16), bcpowmod($srp_g, base2dec($_SESSION["b"], 16), $srp_n)), 16);
     $result["s"] = $_SESSION["s"];
     $result["B"] = $_SESSION["B"];
     //=============================================================
 } else {
     if ($message == "credentialCheck") {
         $u = clipperz_hash(base2dec($_SESSION["B"], 16));
         $A = base2dec($_SESSION["A"], 16);
         $S = bcpowmod(bcmul($A, bcpowmod(base2dec($_SESSION["v"], 16), base2dec($u, 16), $srp_n)), base2dec($_SESSION["b"], 16), $srp_n);
         $K = clipperz_hash($S);
         $M1 = clipperz_hash($A . base2dec($_SESSION["B"], 16) . $K);
         //$result["B"] = $_SESSION["B"];
         //$result["u"] = $u;
         //$result["A"] = $A;
         //$result["S"] = $S;
         //$result["K"] = $K;
         //$result["M1"] = $M1;
         //$result["_M1"] = $parameters["parameters"]["M1"];
         if ($M1 == $parameters["parameters"]["M1"]) {
             $_SESSION["K"] = $K;
             $M2 = clipperz_hash($A . $M1 . $K);
             $result["M2"] = $M2;
             $result["connectionId"] = "";
             $result["loginInfo"] = array();
 /**
  * Raise an arbitrary precision number to another, reduced by a specified modulus
  *
  * @param string $base The left operand, as a string.
  * @param string $exp The right operand, as a string.
  * @param string $mod The modulus, as a string.
  * @access public
  * @return string|null Returns the result as a string, or <b>NULL</b> if modulus is 0.
  * @link http://us3.php.net/manual/en/function.bcpowmod.php
  */
 public function powmod($base, $exp, $mod)
 {
     return bcpowmod($base, $exp, $mod);
 }
Example #22
0
 static function decryptBlock($value, $key)
 {
     return bcpowmod($value, $key['private']['d'], $key['private']['n']);
 }
Example #23
0
 /**
  * Shortcut for $this->power($power)->modulus($modulus)
  *
  * @param mixed $power   the power to raise to
  * @param mixed $modulus the modulus to apply
  *
  * @return Money
  *
  * @throws \InvalidArgumentException if the $power is not numeric
  * @throws \InvalidArgumentException if the $modulus is not numeric
  */
 public function powerModulus($power, $modulus)
 {
     if (!is_numeric($power)) {
         throw new \InvalidArgumentException('Power must be numeric');
     }
     if (!is_numeric($modulus)) {
         throw new \InvalidArgumentException('Modulus must be numeric');
     }
     // bcscale leads to strange results with modulus operations (which is
     // why bcmod doesn't even have the parameter...)
     $amount = bcpowmod($this->amount, strval($power), strval($modulus), 0);
     return self::valueOf($amount, $this->currency);
 }
Example #24
0
/**
 * @param ssh\PacketProtocol
 * @param Side
 * @param Side
 * @param mixed array of Key-s if local side is SERVER, string with expected public 
 * key if local side is CLIENT
 */
function kex(ssh\PacketProtocol $protocol, Side $local, Side $remote, $keys)
{
    $send = $local->type . '_to_' . $remote->type;
    $receive = $remote->type . '_to_' . $local->type;
    if ($local->type === Side::CLIENT) {
        $local_pk_algorithms = array('ssh-dss', 'ssh-rsa');
    } else {
        $local_pk_algorithms = array_keys($keys);
    }
    $local->kexinit_packet = ssh\format('brnnnnnnnnnnbu', ssh\SSH_MSG_KEXINIT, ssh\random(16), $local_kex_algorithms = array('diffie-hellman-group1-sha1', 'diffie-hellman-group14-sha1'), $local_pk_algorithms = array('ssh-dss', 'ssh-rsa'), $protocol->getEncryptionAlgorithms(), $protocol->getEncryptionAlgorithms(), $protocol->getMacAlgorithms(), $protocol->getMacAlgorithms(), $protocol->getCompressionAlgorithms(), $protocol->getCompressionAlgorithms(), array(), array(), 0, 0);
    $protocol->send('r', $local->kexinit_packet);
    $remote->kexinit_packet = $remote_kexinit = $protocol->receive();
    $remote_kexinit = substr($remote_kexinit, 17);
    list($remote_kex_algorithms, $remote_pk_algorithms, $encryption_algorithms_client_to_server, $encryption_algorithms_server_to_client, $mac_algorithms_client_to_server, $mac_algorithms_server_to_client, $compression_algorithms_client_to_server, $compression_algorithms_server_to_client, $languages_client_to_server, $languages_server_to_client, $first_kex_packet_follows, $reserved) = ssh\parse('nnnnnnnnnnbu', $remote_kexinit);
    $mistakes = 0;
    $mistakes += select_algorithm($kex_algorithm, $local_kex_algorithms, $remote_kex_algorithms, $local, $remote, 'kex');
    $mistakes += select_algorithm($pk_algorithm, $local_pk_algorithms, $remote_pk_algorithms, $local, $remote, 'public key');
    select_algorithm($decryption_algorithm, $protocol->getEncryptionAlgorithms(), ${'encryption_algorithms_' . $remote->type . '_to_' . $local->type}, $local, $remote, 'decryption');
    select_algorithm($encryption_algorithm, $protocol->getEncryptionAlgorithms(), ${'encryption_algorithms_' . $local->type . '_to_' . $remote->type}, $local, $remote, 'encryption');
    select_algorithm($receive_mac_algorithm, $protocol->getMacAlgorithms(), ${'mac_algorithms_' . $remote->type . '_to_' . $local->type}, $local, $remote, 'receive mac');
    select_algorithm($send_mac_algorithm, $protocol->getMacAlgorithms(), ${'mac_algorithms_' . $local->type . '_to_' . $remote->type}, $local, $remote, 'send mac');
    select_algorithm($uncompression_algorithm, $protocol->getCompressionAlgorithms(), ${'compression_algorithms_' . $remote->type . '_to_' . $local->type}, $local, $remote, 'uncompression');
    select_algorithm($compression_algorithm, $protocol->getCompressionAlgorithms(), ${'compression_algorithms_' . $local->type . '_to_' . $remote->type}, $local, $remote, 'compression');
    if ($mistakes > 0 && $first_kex_packet_follows) {
        for (;;) {
            $packet = $protocol->receive();
            list($packet_type) = ssh\parse('b', $packet);
            if ($packet_type === ssh\SSH_MSG_DISCONNECT) {
                list($reason, $description) = ssh\parse('us');
                throw new Disconnected($description, $reason);
            }
            if ($packet_type === ssh\SSH_MSG_KEXDH_INIT) {
                break;
            }
        }
    }
    switch ($kex_algorithm) {
        // http://tools.ietf.org/html/rfc2409#section-6.2
        // http://tools.ietf.org/html/rfc2412#appendix-E.2
        case 'diffie-hellman-group1-sha1':
            $pbin = pack('H*', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF');
            $random_length = 64;
            break;
            // http://tools.ietf.org/html/rfc3526#section-3
        // http://tools.ietf.org/html/rfc3526#section-3
        case 'diffie-hellman-group14-sha1':
            $pbin = pack('H*', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF');
            $random_length = 128;
            break;
    }
    if (!extension_loaded('gmp') && !extension_loaded('bcmath')) {
        throw new ssh\Error('No extension for mpint calculations.');
    }
    if (extension_loaded('gmp')) {
        $p = gmp_init(bin2hex($pbin), 16);
    } else {
        if (extension_loaded('bcmath')) {
            $p = bcdebin($pbin);
        }
    }
    if ($local->type === Side::SERVER) {
        $ybin = ssh\random($random_length);
        list($packet_type, $ebin) = ssh\parse('bm', $protocol->receive());
        if ($packet_type !== ssh\SSH_MSG_KEXDH_INIT) {
            throw new ssh\Error('Expected SSH_MSG_KEXDH_INIT, got #' . $packet_type . '.');
        }
        if (extension_loaded('gmp')) {
            $y = gmp_init(bin2hex($ybin), 16);
            $e = gmp_init(bin2hex($ebin), 16);
            $f = gmp_powm(2, $y, $p);
            $K = gmp_powm($e, $y, $p);
            $fbin = gmp_binval($f);
            $Kbin = gmp_binval($K);
        } else {
            if (extension_loaded('bcmath')) {
                $y = bcdebin($ybin);
                $e = bcdebin($ebin);
                $f = bcpowmod(2, $y, $p);
                $K = bcpowmod($e, $y, $p);
                $fbin = bcbin($f);
                $Kbin = bcbin($K);
            }
        }
        if (!isset($keys[$pk_algorithm])) {
            throw new ssh\Error('I do not have needed ' . $pk_algorithm . ' key.');
        }
        $key = $keys[$pk_algorithm];
        $H = sha1(ssh\format('sssssmmm', $remote->identification_string, $local->identification_string, $remote->kexinit_packet, $local->kexinit_packet, $key->public, $ebin, $fbin, $Kbin), TRUE);
        if ($protocol->getSessionId() === NULL) {
            $protocol->setSessionId($H);
        }
        $signature = ssh\sign($key->private, $H);
        $protocol->send('bsms', ssh\SSH_MSG_KEXDH_REPLY, $key->public, $fbin, $signature);
    } else {
        asset($local->type === Side::CLIENT);
        for (;;) {
            $xbin = ssh\random($random_length);
            if (extension_loaded('gmp')) {
                $x = gmp_init(bin2hex($xbin), 16);
                $cmp = gmp_cmp($x, 0);
            } else {
                if (extension_loaded('bcmath')) {
                    $x = bcdebin($xbin);
                    $cmp = bccomp($x, 0);
                }
            }
            if ($cmp > 0) {
                // if is x > 0
                break;
            }
        }
        if (extension_loaded('gmp')) {
            $e = gmp_powm(2, $x, $p);
            $ebin = gmp_binval($e);
        } else {
            if (extension_loaded('bcmath')) {
                $e = bcpowmod(2, $x, $p);
                $ebin = bcbin($e);
            }
        }
        $protocol->send('bm', ssh\SSH_MSG_KEXDH_INIT, $e);
        list($packet_type) = ssh\parse('b', $packet = $protocol->receive());
        if ($packet_type !== ssh\SSH_MSG_KEXDH_REPLY) {
            throw new ssh\Error('Expected SSH_MSG_KEXDH_REPLY, got #' . $packet_type . '.');
        }
        list($server_key, $fbin, $signature) = ssh\parse('sms', $packet);
        if ($server_key !== $keys) {
            throw new ssh\Error('Server keys do not match.');
        }
        if (extension_loaded('gmp')) {
            $f = gmp_init(bin2hex($fbin), 16);
            $K = gmp_powm($f, $x, $p);
            $Kbin = gmp_binval($K);
        } else {
            if (extension_loaded('bcmath')) {
                $f = bcdebin($fbin);
                $K = bcpowmod($f, $x, $p);
                $Kbin = bcbin($K);
            }
        }
        $H = sha1(ssh\format('sssssmmm', $local->identification_string, $remote->identification_string, $local->kexinit_packet, $remote->kexinit_packet, $server_key, $ebin, $fbin, $Kbin), TRUE);
        if (!ssh\verify($server_key, $H, $signature)) {
            throw new ssh\Error('Server reply cannot be verified.');
        }
        if ($protocol->getSessionId() === NULL) {
            $protocol->setSessionId($H);
        }
    }
    $iv_client_to_server = sha1(ssh\format('mrbr', $Kbin, $H, ord('A'), $protocol->getSessionId()), TRUE);
    $iv_server_to_client = sha1(ssh\format('mrbr', $Kbin, $H, ord('B'), $protocol->getSessionId()), TRUE);
    $key_client_to_server = sha1(ssh\format('mrbr', $Kbin, $H, ord('C'), $protocol->getSessionId()), TRUE);
    $key_server_to_client = sha1(ssh\format('mrbr', $Kbin, $H, ord('D'), $protocol->getSessionId()), TRUE);
    $mac_key_client_to_server = sha1(ssh\format('mrbr', $Kbin, $H, ord('E'), $protocol->getSessionId()), TRUE);
    $mac_key_server_to_client = sha1(ssh\format('mrbr', $Kbin, $H, ord('F'), $protocol->getSessionId()), TRUE);
    lengthen(${'iv_' . $send}, $protocol->getEncryptionIVLength($encryption_algorithm), $Kbin, $H);
    lengthen(${'iv_' . $receive}, $protocol->getEncryptionIVLength($decryption_algorithm), $Kbin, $H);
    lengthen(${'key_' . $send}, $protocol->getEncryptionKeyLength($encryption_algorithm), $Kbin, $H);
    lengthen(${'key_' . $receive}, $protocol->getEncryptionKeyLength($decryption_algorithm), $Kbin, $H);
    lengthen(${'mac_key' . $send}, $protocol->getMacKeyLength($send_mac_algorithm), $Kbin, $H);
    lengthen(${'mac_key' . $receive}, $protocol->getMacKeyLength($receive_mac_algorithm), $Kbin, $H);
    if ($local->type === Side::SERVER) {
        list($packet_type) = ssh\parse('b', $protocol->receive());
        if ($packet_type !== ssh\SSH_MSG_NEWKEYS) {
            throw new ssh\Error('Expected SSH_MSG_NEWKEYS, got #' . $packet_type . '.');
        }
        $protocol->initDecryption($decryption_algorithm, ${'key_' . $receive}, ${'iv_' . $receive});
        $protocol->initUncompression($uncompression_algorithm);
        $protocol->initReceiveMac($receive_mac_algorithm, ${'mac_key_' . $receive});
        $protocol->send('b', ssh\SSH_MSG_NEWKEYS);
        $protocol->initEncryption($encryption_algorithm, ${'key_' . $send}, ${'iv_' . $send});
        $protocol->initCompression($compression_algorithm);
        $protocol->initSendMac($send_mac_algorithm, ${'mac_key_' . $send});
    } else {
        asset($local->type === Side::CLIENT);
        $protocol->send('b', ssh\SSH_MSG_NEWKEYS);
        $protocol->initEncryption($encryption_algorithm, ${'key_' . $send}, ${'iv_' . $send});
        $protocol->initCompression($compression_algorithm);
        $protocol->initSendMac($send_mac_algorithm, ${'mac_key_' . $send});
        list($packet_type) = ssh\parse('b', $protocol->receive());
        if ($packet_type !== ssh\SSH_MSG_NEWKEYS) {
            throw new ssh\Error('Expected SSH_MSG_NEWKEYS, got #' . $packet_type . '.');
        }
        $protocol->initDecryption($decryption_algorithm, ${'key_' . $receive}, ${'iv_' . $receive});
        $protocol->initUncompression($uncompression_algorithm);
        $protocol->initReceiveMac($receive_mac_algorithm, ${'mac_key_' . $receive});
    }
}
Example #25
0
 /**
  * @param string $left_operand
  * @param string $right_operand
  * @return string
  */
 public function powmod($left_operand, $right_operand, $modulus)
 {
     return bcpowmod($left_operand, $right_operand, $modulus);
 }
Example #26
0
 /**
  * Generates the secret key using the private key and prime
  *
  * @param	string	Public key passed in by the request
  *
  * @return	string String containing the shared secret
  */
 function fetch_shared_secret($foreignpubkey)
 {
     if (function_exists('bcpowmod')) {
         $this->secret = bcpowmod($foreignpubkey, $this->privatekey, $this->prime);
     } else {
         $this->secret = bcmod(bcpow($foreignpubkey, $this->privatekey), $this->prime);
     }
     return $this->secret;
 }
Example #27
0
 /**
  * Performs modular exponentiation.
  *
  * Here's an example:
  * <code>
  * <?php
  *    include 'Math/BigInteger.php';
  *
  *    $a = new Math_BigInteger('10');
  *    $b = new Math_BigInteger('20');
  *    $c = new Math_BigInteger('30');
  *
  *    $c = $a->modPow($b, $c);
  *
  *    echo $c->toString(); // outputs 10
  * ?>
  * </code>
  *
  * @param Math_BigInteger $e
  * @param Math_BigInteger $n
  * @return Math_BigInteger
  * @access public
  * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and
  *    and although the approach involving repeated squaring does vastly better, it, too, is impractical
  *    for our purposes.  The reason being that division - by far the most complicated and time-consuming
  *    of the basic operations (eg. +,-,*,/) - occurs multiple times within it.
  *
  *    Modular reductions resolve this issue.  Although an individual modular reduction takes more time
  *    then an individual division, when performed in succession (with the same modulo), they're a lot faster.
  *
  *    The two most commonly used modular reductions are Barrett and Montgomery reduction.  Montgomery reduction,
  *    although faster, only works when the gcd of the modulo and of the base being used is 1.  In RSA, when the
  *    base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because
  *    the product of two odd numbers is odd), but what about when RSA isn't used?
  *
  *    In contrast, Barrett reduction has no such constraint.  As such, some bigint implementations perform a
  *    Barrett reduction after every operation in the modpow function.  Others perform Barrett reductions when the
  *    modulo is even and Montgomery reductions when the modulo is odd.  BigInteger.java's modPow method, however,
  *    uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and
  *    the other, a power of two - and recombine them, later.  This is the method that this modPow function uses.
  *    {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.
  */
 function modPow($e, $n)
 {
     $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs();
     if ($e->compare(new Math_BigInteger()) < 0) {
         $e = $e->abs();
         $temp = $this->modInverse($n);
         if ($temp === false) {
             return false;
         }
         return $this->_normalize($temp->modPow($e, $n));
     }
     if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP) {
         $temp = new Math_BigInteger();
         $temp->value = gmp_powm($this->value, $e->value, $n->value);
         return $this->_normalize($temp);
     }
     if ($this->compare(new Math_BigInteger()) < 0 || $this->compare($n) > 0) {
         list(, $temp) = $this->divide($n);
         return $temp->modPow($e, $n);
     }
     if (defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
         $components = array('modulus' => $n->toBytes(true), 'publicExponent' => $e->toBytes(true));
         $components = array('modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']), 'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent']));
         $RSAPublicKey = pack('Ca*a*a*', 48, $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])), $components['modulus'], $components['publicExponent']);
         $rsaOID = pack('H*', '300d06092a864886f70d0101010500');
         // hex version of MA0GCSqGSIb3DQEBAQUA
         $RSAPublicKey = chr(0) . $RSAPublicKey;
         $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey;
         $encapsulated = pack('Ca*a*', 48, $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey);
         $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . chunk_split(base64_encode($encapsulated)) . '-----END PUBLIC KEY-----';
         $plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "", STR_PAD_LEFT);
         if (openssl_public_encrypt($plaintext, $result, $RSAPublicKey, OPENSSL_NO_PADDING)) {
             return new Math_BigInteger($result, 256);
         }
     }
     if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH) {
         $temp = new Math_BigInteger();
         $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
         return $this->_normalize($temp);
     }
     if (empty($e->value)) {
         $temp = new Math_BigInteger();
         $temp->value = array(1);
         return $this->_normalize($temp);
     }
     if ($e->value == array(1)) {
         list(, $temp) = $this->divide($n);
         return $this->_normalize($temp);
     }
     if ($e->value == array(2)) {
         $temp = new Math_BigInteger();
         $temp->value = $this->_square($this->value);
         list(, $temp) = $temp->divide($n);
         return $this->_normalize($temp);
     }
     return $this->_normalize($this->_slidingWindow($e, $n, MATH_BIGINTEGER_BARRETT));
     // the following code, although not callable, can be run independently of the above code
     // although the above code performed better in my benchmarks the following could might
     // perform better under different circumstances. in lieu of deleting it it's just been
     // made uncallable
     // is the modulo odd?
     if ($n->value[0] & 1) {
         return $this->_normalize($this->_slidingWindow($e, $n, MATH_BIGINTEGER_MONTGOMERY));
     }
     // if it's not, it's even
     // find the lowest set bit (eg. the max pow of 2 that divides $n)
     for ($i = 0; $i < count($n->value); ++$i) {
         if ($n->value[$i]) {
             $temp = decbin($n->value[$i]);
             $j = strlen($temp) - strrpos($temp, '1') - 1;
             $j += 26 * $i;
             break;
         }
     }
     // at this point, 2^$j * $n/(2^$j) == $n
     $mod1 = $n->copy();
     $mod1->_rshift($j);
     $mod2 = new Math_BigInteger();
     $mod2->value = array(1);
     $mod2->_lshift($j);
     $part1 = $mod1->value != array(1) ? $this->_slidingWindow($e, $mod1, MATH_BIGINTEGER_MONTGOMERY) : new Math_BigInteger();
     $part2 = $this->_slidingWindow($e, $mod2, MATH_BIGINTEGER_POWEROF2);
     $y1 = $mod2->modInverse($mod1);
     $y2 = $mod1->modInverse($mod2);
     $result = $part1->multiply($mod2);
     $result = $result->multiply($y1);
     $temp = $part2->multiply($mod1);
     $temp = $temp->multiply($y2);
     $result = $result->add($temp);
     list(, $result) = $result->divide($n);
     return $this->_normalize($result);
 }
Example #28
0
 /**
  * Performs modular exponentiation.
  *
  * Here's an example:
  * <code>
  * <?php
  *    include('Math/BigInteger.php');
  *
  *    $a = new BigInteger('10');
  *    $b = new BigInteger('20');
  *    $c = new BigInteger('30');
  *
  *    $c = $a->modPow($b, $c);
  *
  *    echo $c->toString(); // outputs 10
  * ?>
  * </code>
  *
  * @param BigInteger $e
  * @param BigInteger $n
  * @return BigInteger
  * @access public
  * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and
  *    and although the approach involving repeated squaring does vastly better, it, too, is impractical
  *    for our purposes.  The reason being that division - by far the most complicated and time-consuming
  *    of the basic operations (eg. +,-,*,/) - occurs multiple times within it.
  *
  *    Modular reductions resolve this issue.  Although an individual modular reduction takes more time
  *    then an individual division, when performed in succession (with the same modulo), they're a lot faster.
  *
  *    The two most commonly used modular reductions are Barrett and Montgomery reduction.  Montgomery reduction,
  *    although faster, only works when the gcd of the modulo and of the base being used is 1.  In RSA, when the
  *    base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because
  *    the product of two odd numbers is odd), but what about when RSA isn't used?
  *
  *    In contrast, Barrett reduction has no such constraint.  As such, some bigint implementations perform a
  *    Barrett reduction after every operation in the modpow function.  Others perform Barrett reductions when the
  *    modulo is even and Montgomery reductions when the modulo is odd.  BigInteger.java's modPow method, however,
  *    uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and
  *    the other, a power of two - and recombine them, later.  This is the method that this modPow function uses.
  *    {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.
  */
 function modPow($e, $n)
 {
     $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs();
     if ($e->compare(new BigInteger()) < 0) {
         $e = $e->abs();
         $temp = $this->modInverse($n);
         if ($temp === false) {
             return false;
         }
         return $this->_normalize($temp->modPow($e, $n));
     }
     switch (BigInteger_MODE) {
         case BigInteger_MODE_GMP:
             $temp = new BigInteger();
             $temp->value = gmp_powm($this->value, $e->value, $n->value);
             return $this->_normalize($temp);
         case BigInteger_MODE_BCMATH:
             $temp = new BigInteger();
             $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
             return $this->_normalize($temp);
     }
     if (empty($e->value)) {
         $temp = new BigInteger();
         $temp->value = array(1);
         return $this->_normalize($temp);
     }
     if ($e->value == array(1)) {
         list(, $temp) = $this->divide($n);
         return $this->_normalize($temp);
     }
     if ($e->value == array(2)) {
         $temp = new BigInteger();
         $temp->value = $this->_square($this->value);
         list(, $temp) = $temp->divide($n);
         return $this->_normalize($temp);
     }
     return $this->_normalize($this->_slidingWindow($e, $n, BigInteger_BARRETT));
     // is the modulo odd?
     if ($n->value[0] & 1) {
         return $this->_normalize($this->_slidingWindow($e, $n, BigInteger_MONTGOMERY));
     }
     // if it's not, it's even
     // find the lowest set bit (eg. the max pow of 2 that divides $n)
     for ($i = 0; $i < count($n->value); ++$i) {
         if ($n->value[$i]) {
             $temp = decbin($n->value[$i]);
             $j = strlen($temp) - strrpos($temp, '1') - 1;
             $j += 26 * $i;
             break;
         }
     }
     // at this point, 2^$j * $n/(2^$j) == $n
     $mod1 = $n->copy();
     $mod1->_rshift($j);
     $mod2 = new BigInteger();
     $mod2->value = array(1);
     $mod2->_lshift($j);
     $part1 = $mod1->value != array(1) ? $this->_slidingWindow($e, $mod1, BigInteger_MONTGOMERY) : new BigInteger();
     $part2 = $this->_slidingWindow($e, $mod2, BigInteger_POWEROF2);
     $y1 = $mod2->modInverse($mod1);
     $y2 = $mod1->modInverse($mod2);
     $result = $part1->multiply($mod2);
     $result = $result->multiply($y1);
     $temp = $part2->multiply($mod1);
     $temp = $temp->multiply($y2);
     $result = $result->add($temp);
     list(, $result) = $result->divide($n);
     return $this->_normalize($result);
 }
 /**
  * Computes $base to the power of $exponent and then applies modulo $modulus.
  *
  * @param string $base The number to be exponentiated
  * @param string $exponent The exponent to apply to $base
  * @param string $modulus The modulo value to be applied to the result
  * @return string
  */
 public function powmod($base, $exponent, $modulus)
 {
     return bcpowmod($base, $exponent, $modulus);
 }
Example #30
0
 public static function powmod($x, $y, $m)
 {
     switch (BigInt::support()) {
         case 'gmp':
             return gmp_powm($x, $y, $m);
         case 'big_int':
             return bi_powmod($x, $y, $m);
         case 'bcmath':
             return bcpowmod($x, $y, $m);
         case '':
         default:
             return BigInt::_powmod($x, $y, $m);
     }
 }