Example #1
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 #2
0
 function powm($base, $exponent, $modulus)
 {
     if (function_exists('gmp_powm')) {
         return gmp_strval(gmp_powm($base, $exponent, $modulus));
     } else {
         if (function_exists('bi_powmod')) {
             return bi_sto_str(bi_powmod($base, $exponent, $modulus));
         } else {
             if (function_exists('bcpowmod')) {
                 return bcpowmod($base, $exponent, $modulus);
             } else {
                 if (preg_match("/^\\d+,\\d+,\\d+\$/", "{$base},{$exponent},{$modulus}")) {
                     //@FIX: this is insecure - a bi-directional proc_open() is required
                     if (is_executable("/usr/bin/python")) {
                         $r = trim(`python -c "print pow({$base}, {$exponent}, {$modulus})"`);
                     } else {
                         $r = trim(`perl -e "use Math::BigInt; print Math::BigInt->new('{$base}')->bmodpow('{$exponent}', '{$modulus}')->bstr();"`);
                     }
                     if (preg_match("/^\\d+\$/", $r)) {
                         return $r;
                     }
                 }
             }
         }
     }
     trigger_error("powmod: unsupported or non-integer argument", E_USER_ERROR);
 }