includes/diffiehellman.php
changeset 467 e4bbd6fb8df3
parent 436 242353360e37
child 507 586fd7d3202d
equal deleted inserted replaced
466:1cc8a038ad20 467:e4bbd6fb8df3
    12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    13  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
    13  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
    14  */
    14  */
    15 
    15 
    16 /**
    16 /**
    17  * Class to handle math operations that require the use of >32-bit integers.
       
    18  */
       
    19 
       
    20 class EnanoMath
       
    21 {
       
    22   
       
    23   var $api = 'gmp';
       
    24   var $limb = 16;
       
    25   
       
    26   function __construct()
       
    27   {
       
    28     /*
       
    29     // big_int support is untested.
       
    30     if ( extension_loaded('big_int') )
       
    31     {
       
    32       $this->api = 'bigint';
       
    33     }
       
    34     else
       
    35     */
       
    36     if ( function_exists('gmp_init') )
       
    37     {
       
    38       $this->api = 'gmp';
       
    39     }
       
    40     else if ( function_exists('bcpow') )
       
    41     {
       
    42       $this->api = 'bcmath';
       
    43     }
       
    44     else
       
    45     {
       
    46       throw new Exception('dh_err_not_supported');
       
    47     }
       
    48   }
       
    49   
       
    50   function powmod($base, $pow, $mod)
       
    51   {
       
    52     switch($this->api)
       
    53     {
       
    54       case 'bigint':
       
    55         return ( pow($base, $pow) % $mod );
       
    56         break;
       
    57       case 'gmp':
       
    58         return ( function_exists('gmp_powm') ) ? gmp_powm($base, $pow, $mod) : gmp_mod(gmp_pow($base, $pow), $mod);
       
    59         break;
       
    60       case 'bcmath':
       
    61         return ( function_exists('bcpowmod') ) ? bcpowmod($base, $pow, $mod) : bcmod( bcpow($base, $pow), $mod );
       
    62         break;
       
    63     }
       
    64   }
       
    65   
       
    66   function random($len)
       
    67   {
       
    68     switch($this->api)
       
    69     {
       
    70       case 'gmp':
       
    71         return gmp_random($len);
       
    72         break;
       
    73       case 'bcmath':
       
    74         return $this->_bcmath_random($len);
       
    75         break;
       
    76       case 'bigint':
       
    77         return $this->_bigint_random($len);
       
    78         break;
       
    79     }
       
    80   }
       
    81   
       
    82   function _bcmath_random($len)
       
    83   {
       
    84     $len = ( $this->limb / 2 ) * $len;
       
    85     $chars = '0123456789abcdef';
       
    86     $ret = '';
       
    87     for ( $i = 0; $i < $len; $i++ )
       
    88     {
       
    89       $chid = mt_rand ( 0, strlen($chars) - 1 );
       
    90       $chr = $chars{$chid};
       
    91       $ret .= $chr;
       
    92     }
       
    93     return $this->basecon($ret, 16, 10);
       
    94   }
       
    95   
       
    96   function _bigint_random($len)
       
    97   {
       
    98     $len = ( $this->limb / 2 ) * $len;
       
    99     $chars = '0123456789abcdef';
       
   100     $ret = '';
       
   101     for ( $i = 0; $i < $len; $i++ )
       
   102     {
       
   103       $chid = mt_rand ( 0, strlen($chars) - 1 );
       
   104       $chr = $chars{$chid};
       
   105       $ret .= $chr;
       
   106     }
       
   107     return $this->basecon($ret, 16, 10);
       
   108   }
       
   109   
       
   110   function basecon($int, $from, $to)
       
   111   {
       
   112     switch($this->api)
       
   113     {
       
   114       case 'gmp':
       
   115         return gmp_strval(gmp_init($int, $from), $to);
       
   116         break;
       
   117       case 'bcmath':
       
   118         return $this->_bcmath_baseconv($int, $from, $to);
       
   119         break;
       
   120       case 'bigint':
       
   121         return base_convert($int, $from, $to);
       
   122         break;
       
   123     }
       
   124   }
       
   125   
       
   126   function str($res, $base = 10)
       
   127   {
       
   128     switch($this->api)
       
   129     {
       
   130       case 'bigint':
       
   131       case 'bcmath':
       
   132         return strval($this->basecon($res, 10, $base));
       
   133         break;
       
   134       case 'gmp':
       
   135         return gmp_strval($res, $base);
       
   136         break;
       
   137     }
       
   138   }
       
   139   
       
   140   function compare($v1, $v2)
       
   141   {
       
   142     switch($this->api)
       
   143     {
       
   144       case 'bigint':
       
   145         return ( $v1 === $v2 );
       
   146         break;
       
   147       case 'bcmath':
       
   148         return ( bccomp($v1, $v2) === 0 );
       
   149         break;
       
   150       case 'gmp':
       
   151         return ( gmp_cmp($v1, $v2) === 0 );
       
   152         break;
       
   153     }
       
   154   }
       
   155   
       
   156   function _bcmath_baseconv($int, $from, $to)
       
   157   {
       
   158     if ( $from != 10 )
       
   159       $int = $this->_bcmath_base2dec($int, $from);
       
   160     if ( $to != 10 )
       
   161       $int = $this->_bcmath_dec2base($int, $to);
       
   162     return $int;
       
   163   }
       
   164   
       
   165   // from us.php.net/bc:
       
   166   // convert a decimal value to any other base value
       
   167   function _bcmath_dec2base($dec,$base,$digits=FALSE) {
       
   168       if($base<2 or $base>256) die("Invalid Base: ".$base);
       
   169       bcscale(0);
       
   170       $value="";
       
   171       if(!$digits) $digits=$this->_bcmath_digits($base);
       
   172       while($dec>$base-1) {
       
   173           $rest=bcmod($dec,$base);
       
   174           $dec=bcdiv($dec,$base);
       
   175           $value=$digits[$rest].$value;
       
   176       }
       
   177       $value=$digits[intval($dec)].$value;
       
   178       return (string) $value;
       
   179   }
       
   180   
       
   181   // convert another base value to its decimal value
       
   182   function _bcmath_base2dec($value,$base,$digits=FALSE) {
       
   183       if($base<2 or $base>256) die("Invalid Base: ".$base);
       
   184       bcscale(0);
       
   185       if($base<37) $value=strtolower($value);
       
   186       if(!$digits) $digits=$this->_bcmath_digits($base);
       
   187       $size=strlen($value);
       
   188       $dec="0";
       
   189       for($loop=0;$loop<$size;$loop++) {
       
   190           $element=strpos($digits,$value[$loop]);
       
   191           $power=bcpow($base,$size-$loop-1);
       
   192           $dec=bcadd($dec,bcmul($element,$power));
       
   193       }
       
   194       return (string) $dec;
       
   195   }
       
   196   
       
   197   function _bcmath_digits($base) {
       
   198       if($base>64) {
       
   199           $digits="";
       
   200           for($loop=0;$loop<256;$loop++) {
       
   201               $digits.=chr($loop);
       
   202           }
       
   203       } else {
       
   204           $digits ="0123456789abcdefghijklmnopqrstuvwxyz";
       
   205           $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
       
   206       }
       
   207       $digits=substr($digits,0,$base);
       
   208       return (string) $digits;
       
   209   }
       
   210 }
       
   211 
       
   212 /**
       
   213  * The Diffie-Hellman key exchange protocol
    17  * The Diffie-Hellman key exchange protocol
   214  */
    18  */
   215 
    19 
   216 $GLOBALS['_math'] = new EnanoMath();
    20 $GLOBALS['_math'] = enanomath_create();
   217 // Our prime number as a base for operations.
    21 // Our prime number as a base for operations.
   218 $GLOBALS['dh_prime'] = '82818079787776757473727170696867666564636261605958575655545352515049484746454443424140393837363534333231302928272625242322212019181716151413121110987654321';
    22 $GLOBALS['dh_prime'] = '82818079787776757473727170696867666564636261605958575655545352515049484746454443424140393837363534333231302928272625242322212019181716151413121110987654321';
   219 
    23 
   220 // g, a primitive root used as an exponent
    24 // g, a primitive root used as an exponent
   221 // (2 and 5 are acceptable, but BigInt is faster with odd numbers)
    25 // (2 and 5 are acceptable, but BigInt is faster with odd numbers)