includes/math.php
changeset 467 e4bbd6fb8df3
child 507 586fd7d3202d
equal deleted inserted replaced
466:1cc8a038ad20 467:e4bbd6fb8df3
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
       
     5  * Version 1.1.2 (Caoineag alpha 2)
       
     6  * Copyright (C) 2006-2007 Dan Fuhry
       
     7  * diffiehellman.php - Diffie Hellman key exchange and supporting functions
       
     8  *
       
     9  * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
       
    10  * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
       
    11  *
       
    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.
       
    14  */
       
    15 
       
    16 /**
       
    17  * EnanoMath GMP backend
       
    18  */
       
    19 
       
    20 class EnanoMath_GMP
       
    21 {
       
    22   var $api = 'GMP';
       
    23   
       
    24   /**
       
    25    * Initializes a number to a GMP integer.
       
    26    * @param string String representation of the number
       
    27    * @param int Base the number is currently in, defaults to 10
       
    28    * @return resource
       
    29    */
       
    30   
       
    31   function init($int, $base = 10)
       
    32   {
       
    33     return ( is_resource($int) ) ? $int : gmp_init($int, $base);
       
    34   }
       
    35   
       
    36   /**
       
    37    * Converts a number from a GMP integer to a string
       
    38    * @param resource
       
    39    * @param int Base, default is 10
       
    40    * @return string
       
    41    */
       
    42   
       
    43   function str($int, $base = 10)
       
    44   {
       
    45     return ( is_string($int) ) ? $int : gmp_strval($int, $base);
       
    46   }
       
    47   
       
    48   /**
       
    49    * Converts a number between bases.
       
    50    * @param resource BigInt to convert
       
    51    * @param int Base to convert from
       
    52    * @param int Base to convert to
       
    53    */
       
    54    
       
    55   function basecon($int, $from, $to)
       
    56   {
       
    57     return $this->init(gmp_strval(gmp_init($this->str($int), $from), $to));
       
    58   }
       
    59   
       
    60   /**
       
    61    * Generates a random integer.
       
    62    * @param int Length
       
    63    * @return resource
       
    64    */
       
    65   
       
    66   function random($len)
       
    67   {
       
    68     return gmp_random($len);
       
    69   }
       
    70   
       
    71   /**
       
    72    * Powmod operation (calculates (a ^ b) mod m)
       
    73    * @param resource a
       
    74    * @param resource b
       
    75    * @param resource m
       
    76    * @return resource
       
    77    */
       
    78   
       
    79   function powmod($a, $b, $m)
       
    80   {
       
    81     $a = $this->init($a);
       
    82     $b = $this->init($b);
       
    83     $m = $this->init($m);
       
    84     return ( function_exists('gmp_powm') ) ? gmp_powm($a, $b, $m) : gmp_mod(gmp_pow($a, $b), $m);
       
    85   }
       
    86 }
       
    87 
       
    88 /**
       
    89  * EnanoMath big_int backend
       
    90  */
       
    91 
       
    92 class EnanoMath_BigInt
       
    93 {
       
    94   var $api = 'big_int';
       
    95   
       
    96   /**
       
    97    * Initializes a number to a BigInt integer.
       
    98    * @param string String representation of the number
       
    99    * @param int Base the number is in, defaults to 10
       
   100    * @return resource
       
   101    */
       
   102   
       
   103   function init($int, $base = 10)
       
   104   {
       
   105     return (is_resource($int)) ? $int : bi_from_str($int, $base);
       
   106   }
       
   107   
       
   108   /**
       
   109    * Converts a number from a BigInt integer to a string
       
   110    * @param resource
       
   111    * @param int Base, default is 10
       
   112    * @return string
       
   113    */
       
   114   
       
   115   function str($int, $base = 10)
       
   116   {
       
   117     return ( is_string($int) ) ? $int : bi_to_str($int, $base);
       
   118   }
       
   119   
       
   120   /**
       
   121    * Generates a random integer
       
   122    * @param int Length (bits)
       
   123    * @return resource
       
   124    */
       
   125   
       
   126   function random($len)
       
   127   {
       
   128     return bi_rand($len);
       
   129   }
       
   130   
       
   131   /**
       
   132    * Converts a number between bases.
       
   133    * @param resource BigInt to convert
       
   134    * @param int Base to convert from
       
   135    * @param int Base to convert to
       
   136    */
       
   137   
       
   138   function basecon($int, $from, $to)
       
   139   {
       
   140     return bi_base_convert($this->str($int, $from), $from, $to);
       
   141   }
       
   142   
       
   143   /**
       
   144    * Powmod operation (calculates (a ^ b) mod m)
       
   145    * @param resource a
       
   146    * @param resource b
       
   147    * @param resource m
       
   148    * @return resource
       
   149    */
       
   150   
       
   151   function powmod($a, $b, $m)
       
   152   {
       
   153     $a = $this->init($a);
       
   154     $b = $this->init($b);
       
   155     $m = $this->init($m);
       
   156     return bi_powmod($a, $b, $m);
       
   157   }
       
   158 }
       
   159 
       
   160 /**
       
   161  * EnanoMath BCMath backend
       
   162  */
       
   163 
       
   164 class EnanoMath_BCMath
       
   165 {
       
   166   var $api = 'BCMath';
       
   167   
       
   168   /**
       
   169    * Initializes a number to a BCMath integer.
       
   170    * @param string String representation of the number
       
   171    * @param int Base the number is in, defaults to 10
       
   172    * @return resource
       
   173    */
       
   174   
       
   175   function init($int, $base = 10)
       
   176   {
       
   177     return $this->basecon($int, $base, 10);
       
   178   }
       
   179   
       
   180   /**
       
   181    * Converts a number from a BCMath integer to a string
       
   182    * @param resource
       
   183    * @param int Base, default is 10
       
   184    * @return string
       
   185    */
       
   186    
       
   187   function str($res)
       
   188   {
       
   189     return ( is_string($res) ) ? $res : strval($this->basecon($res, 10, $base));
       
   190   }
       
   191   
       
   192   /**
       
   193    * Generates a random integer
       
   194    * @param int Length in bits
       
   195    * @return resource
       
   196    */
       
   197   
       
   198   function random($len)
       
   199   {
       
   200     $len = 4 * $len;
       
   201     $chars = '0123456789abcdef';
       
   202     $ret = '';
       
   203     for ( $i = 0; $i < $len; $i++ )
       
   204     {
       
   205       $chid = mt_rand ( 0, strlen($chars) - 1 );
       
   206       $chr = $chars{$chid};
       
   207       $ret .= $chr;
       
   208     }
       
   209     return $this->basecon($this->init($ret), 16, 10);
       
   210   }
       
   211   
       
   212   /**
       
   213    * Converts a number between bases.
       
   214    * @param resource BigInt to convert
       
   215    * @param int Base to convert from
       
   216    * @param int Base to convert to
       
   217    */
       
   218   
       
   219   function basecon($int, $from, $to)
       
   220   {
       
   221     if ( $from != 10 )
       
   222       $int = $this->_bcmath_base2dec($int, $from);
       
   223     if ( $to != 10 )
       
   224       $int = $this->_bcmath_dec2base($int, $to);
       
   225     return $int;
       
   226   }
       
   227   
       
   228   /**
       
   229    * Powmod operation (calculates (a ^ b) mod m)
       
   230    * @param resource a
       
   231    * @param resource b
       
   232    * @param resource m
       
   233    * @return resource
       
   234    */
       
   235   
       
   236   function powmod($a, $b, $m)
       
   237   {
       
   238     $a = $this->init($a);
       
   239     $b = $this->init($b);
       
   240     $m = $this->init($m);
       
   241     return ( function_exists('bcpowmod') ) ? bcpowmod($a, $b, $m) : bcmod( bcpow($a, $b), $m );
       
   242   }
       
   243   
       
   244   // from us.php.net/bc:
       
   245   // convert a decimal value to any other base value
       
   246   function _bcmath_dec2base($dec,$base,$digits=FALSE) {
       
   247       if($base<2 or $base>256) die("Invalid Base: ".$base);
       
   248       bcscale(0);
       
   249       $value="";
       
   250       if(!$digits) $digits=$this->_bcmath_digits($base);
       
   251       while($dec>$base-1) {
       
   252           $rest=bcmod($dec,$base);
       
   253           $dec=bcdiv($dec,$base);
       
   254           $value=$digits[$rest].$value;
       
   255       }
       
   256       $value=$digits[intval($dec)].$value;
       
   257       return (string) $value;
       
   258   }
       
   259   
       
   260   // convert another base value to its decimal value
       
   261   function _bcmath_base2dec($value,$base,$digits=FALSE) {
       
   262       if($base<2 or $base>256) die("Invalid Base: ".$base);
       
   263       bcscale(0);
       
   264       if($base<37) $value=strtolower($value);
       
   265       if(!$digits) $digits=$this->_bcmath_digits($base);
       
   266       $size=strlen($value);
       
   267       $dec="0";
       
   268       for($loop=0;$loop<$size;$loop++) {
       
   269           $element=strpos($digits,$value[$loop]);
       
   270           $power=bcpow($base,$size-$loop-1);
       
   271           $dec=bcadd($dec,bcmul($element,$power));
       
   272       }
       
   273       return (string) $dec;
       
   274   }
       
   275   
       
   276   function _bcmath_digits($base) {
       
   277       if($base>64) {
       
   278           $digits="";
       
   279           for($loop=0;$loop<256;$loop++) {
       
   280               $digits.=chr($loop);
       
   281           }
       
   282       } else {
       
   283           $digits ="0123456789abcdefghijklmnopqrstuvwxyz";
       
   284           $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
       
   285       }
       
   286       $digits=substr($digits,0,$base);
       
   287       return (string) $digits;
       
   288   }
       
   289 }
       
   290 
       
   291 /**
       
   292  * Creates a new math object based on what libraries are available.
       
   293  * @return object
       
   294  */
       
   295 
       
   296 function enanomath_create()
       
   297 {
       
   298   if ( function_exists('gmp_init') )
       
   299     return new EnanoMath_GMP();
       
   300   else if ( function_exists('bi_from_str') )
       
   301     return new EnanoMath_BigInt();
       
   302   else if ( function_exists('bcadd') )
       
   303     return new EnanoMath_BCMath();
       
   304   else
       
   305     throw new Exception('dh_err_not_supported');
       
   306 }
       
   307 
       
   308 ?>