# HG changeset patch # User Dan # Date 1204415797 18000 # Node ID e4bbd6fb8df3a2825684cd60e92bdb1eee45ab85 # Parent 1cc8a038ad205fc4106998762ab51e0da4eb8349 Modifed EnanoMath layer by segregating it into its own file; got support for big_int PHP extension backend working diff -r 1cc8a038ad20 -r e4bbd6fb8df3 includes/diffiehellman.php --- a/includes/diffiehellman.php Sat Mar 01 18:55:54 2008 -0500 +++ b/includes/diffiehellman.php Sat Mar 01 18:56:37 2008 -0500 @@ -14,206 +14,10 @@ */ /** - * Class to handle math operations that require the use of >32-bit integers. - */ - -class EnanoMath -{ - - var $api = 'gmp'; - var $limb = 16; - - function __construct() - { - /* - // big_int support is untested. - if ( extension_loaded('big_int') ) - { - $this->api = 'bigint'; - } - else - */ - if ( function_exists('gmp_init') ) - { - $this->api = 'gmp'; - } - else if ( function_exists('bcpow') ) - { - $this->api = 'bcmath'; - } - else - { - throw new Exception('dh_err_not_supported'); - } - } - - function powmod($base, $pow, $mod) - { - switch($this->api) - { - case 'bigint': - return ( pow($base, $pow) % $mod ); - break; - case 'gmp': - return ( function_exists('gmp_powm') ) ? gmp_powm($base, $pow, $mod) : gmp_mod(gmp_pow($base, $pow), $mod); - break; - case 'bcmath': - return ( function_exists('bcpowmod') ) ? bcpowmod($base, $pow, $mod) : bcmod( bcpow($base, $pow), $mod ); - break; - } - } - - function random($len) - { - switch($this->api) - { - case 'gmp': - return gmp_random($len); - break; - case 'bcmath': - return $this->_bcmath_random($len); - break; - case 'bigint': - return $this->_bigint_random($len); - break; - } - } - - function _bcmath_random($len) - { - $len = ( $this->limb / 2 ) * $len; - $chars = '0123456789abcdef'; - $ret = ''; - for ( $i = 0; $i < $len; $i++ ) - { - $chid = mt_rand ( 0, strlen($chars) - 1 ); - $chr = $chars{$chid}; - $ret .= $chr; - } - return $this->basecon($ret, 16, 10); - } - - function _bigint_random($len) - { - $len = ( $this->limb / 2 ) * $len; - $chars = '0123456789abcdef'; - $ret = ''; - for ( $i = 0; $i < $len; $i++ ) - { - $chid = mt_rand ( 0, strlen($chars) - 1 ); - $chr = $chars{$chid}; - $ret .= $chr; - } - return $this->basecon($ret, 16, 10); - } - - function basecon($int, $from, $to) - { - switch($this->api) - { - case 'gmp': - return gmp_strval(gmp_init($int, $from), $to); - break; - case 'bcmath': - return $this->_bcmath_baseconv($int, $from, $to); - break; - case 'bigint': - return base_convert($int, $from, $to); - break; - } - } - - function str($res, $base = 10) - { - switch($this->api) - { - case 'bigint': - case 'bcmath': - return strval($this->basecon($res, 10, $base)); - break; - case 'gmp': - return gmp_strval($res, $base); - break; - } - } - - function compare($v1, $v2) - { - switch($this->api) - { - case 'bigint': - return ( $v1 === $v2 ); - break; - case 'bcmath': - return ( bccomp($v1, $v2) === 0 ); - break; - case 'gmp': - return ( gmp_cmp($v1, $v2) === 0 ); - break; - } - } - - function _bcmath_baseconv($int, $from, $to) - { - if ( $from != 10 ) - $int = $this->_bcmath_base2dec($int, $from); - if ( $to != 10 ) - $int = $this->_bcmath_dec2base($int, $to); - return $int; - } - - // from us.php.net/bc: - // convert a decimal value to any other base value - function _bcmath_dec2base($dec,$base,$digits=FALSE) { - if($base<2 or $base>256) die("Invalid Base: ".$base); - bcscale(0); - $value=""; - if(!$digits) $digits=$this->_bcmath_digits($base); - while($dec>$base-1) { - $rest=bcmod($dec,$base); - $dec=bcdiv($dec,$base); - $value=$digits[$rest].$value; - } - $value=$digits[intval($dec)].$value; - return (string) $value; - } - - // convert another base value to its decimal value - function _bcmath_base2dec($value,$base,$digits=FALSE) { - if($base<2 or $base>256) die("Invalid Base: ".$base); - bcscale(0); - if($base<37) $value=strtolower($value); - if(!$digits) $digits=$this->_bcmath_digits($base); - $size=strlen($value); - $dec="0"; - for($loop=0;$loop<$size;$loop++) { - $element=strpos($digits,$value[$loop]); - $power=bcpow($base,$size-$loop-1); - $dec=bcadd($dec,bcmul($element,$power)); - } - return (string) $dec; - } - - function _bcmath_digits($base) { - if($base>64) { - $digits=""; - for($loop=0;$loop<256;$loop++) { - $digits.=chr($loop); - } - } else { - $digits ="0123456789abcdefghijklmnopqrstuvwxyz"; - $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; - } - $digits=substr($digits,0,$base); - return (string) $digits; - } -} - -/** * The Diffie-Hellman key exchange protocol */ -$GLOBALS['_math'] = new EnanoMath(); +$GLOBALS['_math'] = enanomath_create(); // Our prime number as a base for operations. $GLOBALS['dh_prime'] = '82818079787776757473727170696867666564636261605958575655545352515049484746454443424140393837363534333231302928272625242322212019181716151413121110987654321'; diff -r 1cc8a038ad20 -r e4bbd6fb8df3 includes/math.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/math.php Sat Mar 01 18:56:37 2008 -0500 @@ -0,0 +1,308 @@ +init(gmp_strval(gmp_init($this->str($int), $from), $to)); + } + + /** + * Generates a random integer. + * @param int Length + * @return resource + */ + + function random($len) + { + return gmp_random($len); + } + + /** + * Powmod operation (calculates (a ^ b) mod m) + * @param resource a + * @param resource b + * @param resource m + * @return resource + */ + + function powmod($a, $b, $m) + { + $a = $this->init($a); + $b = $this->init($b); + $m = $this->init($m); + return ( function_exists('gmp_powm') ) ? gmp_powm($a, $b, $m) : gmp_mod(gmp_pow($a, $b), $m); + } +} + +/** + * EnanoMath big_int backend + */ + +class EnanoMath_BigInt +{ + var $api = 'big_int'; + + /** + * Initializes a number to a BigInt integer. + * @param string String representation of the number + * @param int Base the number is in, defaults to 10 + * @return resource + */ + + function init($int, $base = 10) + { + return (is_resource($int)) ? $int : bi_from_str($int, $base); + } + + /** + * Converts a number from a BigInt integer to a string + * @param resource + * @param int Base, default is 10 + * @return string + */ + + function str($int, $base = 10) + { + return ( is_string($int) ) ? $int : bi_to_str($int, $base); + } + + /** + * Generates a random integer + * @param int Length (bits) + * @return resource + */ + + function random($len) + { + return bi_rand($len); + } + + /** + * Converts a number between bases. + * @param resource BigInt to convert + * @param int Base to convert from + * @param int Base to convert to + */ + + function basecon($int, $from, $to) + { + return bi_base_convert($this->str($int, $from), $from, $to); + } + + /** + * Powmod operation (calculates (a ^ b) mod m) + * @param resource a + * @param resource b + * @param resource m + * @return resource + */ + + function powmod($a, $b, $m) + { + $a = $this->init($a); + $b = $this->init($b); + $m = $this->init($m); + return bi_powmod($a, $b, $m); + } +} + +/** + * EnanoMath BCMath backend + */ + +class EnanoMath_BCMath +{ + var $api = 'BCMath'; + + /** + * Initializes a number to a BCMath integer. + * @param string String representation of the number + * @param int Base the number is in, defaults to 10 + * @return resource + */ + + function init($int, $base = 10) + { + return $this->basecon($int, $base, 10); + } + + /** + * Converts a number from a BCMath integer to a string + * @param resource + * @param int Base, default is 10 + * @return string + */ + + function str($res) + { + return ( is_string($res) ) ? $res : strval($this->basecon($res, 10, $base)); + } + + /** + * Generates a random integer + * @param int Length in bits + * @return resource + */ + + function random($len) + { + $len = 4 * $len; + $chars = '0123456789abcdef'; + $ret = ''; + for ( $i = 0; $i < $len; $i++ ) + { + $chid = mt_rand ( 0, strlen($chars) - 1 ); + $chr = $chars{$chid}; + $ret .= $chr; + } + return $this->basecon($this->init($ret), 16, 10); + } + + /** + * Converts a number between bases. + * @param resource BigInt to convert + * @param int Base to convert from + * @param int Base to convert to + */ + + function basecon($int, $from, $to) + { + if ( $from != 10 ) + $int = $this->_bcmath_base2dec($int, $from); + if ( $to != 10 ) + $int = $this->_bcmath_dec2base($int, $to); + return $int; + } + + /** + * Powmod operation (calculates (a ^ b) mod m) + * @param resource a + * @param resource b + * @param resource m + * @return resource + */ + + function powmod($a, $b, $m) + { + $a = $this->init($a); + $b = $this->init($b); + $m = $this->init($m); + return ( function_exists('bcpowmod') ) ? bcpowmod($a, $b, $m) : bcmod( bcpow($a, $b), $m ); + } + + // from us.php.net/bc: + // convert a decimal value to any other base value + function _bcmath_dec2base($dec,$base,$digits=FALSE) { + if($base<2 or $base>256) die("Invalid Base: ".$base); + bcscale(0); + $value=""; + if(!$digits) $digits=$this->_bcmath_digits($base); + while($dec>$base-1) { + $rest=bcmod($dec,$base); + $dec=bcdiv($dec,$base); + $value=$digits[$rest].$value; + } + $value=$digits[intval($dec)].$value; + return (string) $value; + } + + // convert another base value to its decimal value + function _bcmath_base2dec($value,$base,$digits=FALSE) { + if($base<2 or $base>256) die("Invalid Base: ".$base); + bcscale(0); + if($base<37) $value=strtolower($value); + if(!$digits) $digits=$this->_bcmath_digits($base); + $size=strlen($value); + $dec="0"; + for($loop=0;$loop<$size;$loop++) { + $element=strpos($digits,$value[$loop]); + $power=bcpow($base,$size-$loop-1); + $dec=bcadd($dec,bcmul($element,$power)); + } + return (string) $dec; + } + + function _bcmath_digits($base) { + if($base>64) { + $digits=""; + for($loop=0;$loop<256;$loop++) { + $digits.=chr($loop); + } + } else { + $digits ="0123456789abcdefghijklmnopqrstuvwxyz"; + $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; + } + $digits=substr($digits,0,$base); + return (string) $digits; + } +} + +/** + * Creates a new math object based on what libraries are available. + * @return object + */ + +function enanomath_create() +{ + if ( function_exists('gmp_init') ) + return new EnanoMath_GMP(); + else if ( function_exists('bi_from_str') ) + return new EnanoMath_BigInt(); + else if ( function_exists('bcadd') ) + return new EnanoMath_BCMath(); + else + throw new Exception('dh_err_not_supported'); +} + +?>