function bcpowmod($gen, $private, $mod) is used in openid.module, which makes the code php5-exclusive.
Info in the php-manual: http://be2.php.net/function.bcpowmod

We might consider making it php4-compatible, by adding some extra code, copied from the comment of 'ewilde aht bsmdevelopment dawt com' in the manual:

function PowModSim($Value, $Exponent, $Modulus)
  {
  // Check if simulation is even necessary.
  if (function_exists("bcpowmod"))
   return (bcpowmod($Value, $Exponent, $Modulus));

  // Loop until the exponent is reduced to zero.
  $Result = "1";

  while (TRUE)
   {
   if (bcmod($Exponent, 2) == "1")
     $Result = bcmod(bcmul($Result, $Value), $Modulus);

   if (($Exponent = bcdiv($Exponent, 2)) == "0") break;

   $Value = bcmod(bcmul($Value, $Value), $Modulus);
   }

  return ($Result);
  }

(I got some division by zero errors, when adding this code, so maybe it is not a perfect solution)

Comments

Jo Wouters’s picture

Title: openid.module uses function that is not available in php4 » openid.module uses php5 function
Category: bug » feature

(better title, and making it a feature request)

aaron’s picture

from http://us2.php.net/function.bcpowmod --

laysoft at gmail dot com
30-Jan-2007 05:34
I found a better way to emulate bcpowmod on PHP 4, which works with very big numbers too:

function powmod($m,$e,$n) {
if (intval(PHP_VERSION)>4) {
return(bcpowmod($m,$e,$n));
} else {
$r="";
while ($e!="0") {
$t=bcmod($e,"4096");
$r=substr("000000000000".decbin(intval($t)),-12).$r;
$e=bcdiv($e,"4096");
}
$r=preg_replace("!^0+!","",$r);
if ($r=="") $r="0";
$m=bcmod($m,$n);
$erb=strrev($r);
$q="1";
$a[0]=$m;
for ($i=1;$i $a[$i]=bcmod(bcmul($a[$i-1],$a[$i-1]),$n);
}
for ($i=0;$i if ($erb[$i]=="1") {
$q=bcmod(bcmul($q,$a[$i]),$n);
}
}
return($q);
}
}

aaron’s picture

oops. here it is encoded:


function powmod($m,$e,$n) {
   if (intval(PHP_VERSION)>4) {
       return(bcpowmod($m,$e,$n));
   } else {
       $r="";
       while ($e!="0") {
           $t=bcmod($e,"4096");
           $r=substr("000000000000".decbin(intval($t)),-12).$r;
           $e=bcdiv($e,"4096");
       }
       $r=preg_replace("!^0+!","",$r);
       if ($r=="") $r="0";
       $m=bcmod($m,$n);
       $erb=strrev($r);
       $q="1";
       $a[0]=$m;
       for ($i=1;$i<strlen($erb);$i++) {
           $a[$i]=bcmod(bcmul($a[$i-1],$a[$i-1]),$n);
       }
       for ($i=0;$i<strlen($erb);$i++) {
           if ($erb[$i]=="1") {
               $q=bcmod(bcmul($q,$a[$i]),$n);
           }
       }
       return($q);
   }
}

Jo Wouters’s picture

Thank you Aaron!

Unfortunately I still get division by zero errors:

# warning: bcmod(): Division by zero in /home/planetca/public_html/openid/modules/openid/openid.module on line 21.
# warning: bcmod(): Division by zero in /home/planetca/public_html/openid/modules/openid/openid.module on line 26.
# warning: bcmod(): Division by zero in /home/planetca/public_html/openid/modules/openid/openid.module on line 26.
... (a lot of repetition)
# warning: bcmod(): Division by zero in /home/planetca/public_html/openid/modules/openid/openid.module on line 30.
# OpenID Association failed

walkah’s picture

Status: Active » Fixed

committed a fix for this. thanks.

Anonymous’s picture

Status: Fixed » Closed (fixed)