includes/diffiehellman.php
changeset 1227 bdac73ed481e
parent 1081 745200a9cc2a
child 1261 beb0da036222
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
    18 
    18 
    19 global $dh_supported;
    19 global $dh_supported;
    20 $dh_supported = true;
    20 $dh_supported = true;
    21 try
    21 try
    22 {
    22 {
    23   $GLOBALS['_math'] = enanomath_create();
    23 	$GLOBALS['_math'] = enanomath_create();
    24 }
    24 }
    25 catch ( Exception $e )
    25 catch ( Exception $e )
    26 {
    26 {
    27   $dh_supported = false;
    27 	$dh_supported = false;
    28 }
    28 }
    29 // Our prime number as a base for operations.
    29 // Our prime number as a base for operations.
    30 $GLOBALS['dh_prime'] = '7916586051748534588306961133067968196965257961415756656521818848750723547477673457670019632882524164647651492025728980571833579341743988603191694784406703';
    30 $GLOBALS['dh_prime'] = '7916586051748534588306961133067968196965257961415756656521818848750723547477673457670019632882524164647651492025728980571833579341743988603191694784406703';
    31 
    31 
    32 // g, a primitive root used as an exponent
    32 // g, a primitive root used as an exponent
    38  * @return string(BigInt)
    38  * @return string(BigInt)
    39  */
    39  */
    40 
    40 
    41 function dh_gen_private()
    41 function dh_gen_private()
    42 {
    42 {
    43   global $_math;
    43 	global $_math;
    44   return $_math->random(256);
    44 	return $_math->random(256);
    45 }
    45 }
    46 
    46 
    47 /**
    47 /**
    48  * Calculates the public key from the private key
    48  * Calculates the public key from the private key
    49  * @param string(BigInt)
    49  * @param string(BigInt)
    50  * @return string(BigInt)
    50  * @return string(BigInt)
    51  */
    51  */
    52 
    52 
    53 function dh_gen_public($b)
    53 function dh_gen_public($b)
    54 {
    54 {
    55   global $_math, $dh_g, $dh_prime;
    55 	global $_math, $dh_g, $dh_prime;
    56   return $_math->powmod($dh_g, $b, $dh_prime);
    56 	return $_math->powmod($dh_g, $b, $dh_prime);
    57 }
    57 }
    58 
    58 
    59 /**
    59 /**
    60  * Calculates the shared secret.
    60  * Calculates the shared secret.
    61  * @param string(BigInt) Our private key
    61  * @param string(BigInt) Our private key
    63  * @return string(BigInt)
    63  * @return string(BigInt)
    64  */
    64  */
    65 
    65 
    66 function dh_gen_shared_secret($a, $B)
    66 function dh_gen_shared_secret($a, $B)
    67 {
    67 {
    68   global $_math, $dh_g, $dh_prime;
    68 	global $_math, $dh_g, $dh_prime;
    69   return $_math->powmod($B, $a, $dh_prime);
    69 	return $_math->powmod($B, $a, $dh_prime);
    70 }
    70 }
    71 
    71 
    72 /*
    72 /*
    73 SHA-256 algorithm - ported from Javascript
    73 SHA-256 algorithm - ported from Javascript
    74 
    74 
    78 
    78 
    79 Redistribution and use in source and binary forms, with or without modification,
    79 Redistribution and use in source and binary forms, with or without modification,
    80 are permitted provided that the following conditions are met:
    80 are permitted provided that the following conditions are met:
    81 
    81 
    82  * Redistributions of source code must retain the above copyright notice, this
    82  * Redistributions of source code must retain the above copyright notice, this
    83    list of conditions and the following disclaimer.
    83  	list of conditions and the following disclaimer.
    84  * Redistributions in binary form must reproduce the above copyright notice,
    84  * Redistributions in binary form must reproduce the above copyright notice,
    85    this list of conditions and the following disclaimer in the documentation
    85  	this list of conditions and the following disclaimer in the documentation
    86    and/or other materials provided with the distribution.
    86  	and/or other materials provided with the distribution.
    87  * Neither the name of the <ORGANIZATION> nor the names of its contributors may
    87  * Neither the name of the <ORGANIZATION> nor the names of its contributors may
    88    be used to endorse or promote products derived from this software without
    88  	be used to endorse or promote products derived from this software without
    89    specific prior written permission.
    89  	specific prior written permission.
    90 
    90 
    91 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    91 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    92 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    92 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    93 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    93 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    94 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    94 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    99 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    99 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   100 OF THE POSSIBILITY OF SUCH DAMAGE.
   100 OF THE POSSIBILITY OF SUCH DAMAGE.
   101 */
   101 */
   102 class SHA256
   102 class SHA256
   103 {
   103 {
   104   var $chrsz = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode  */
   104 	var $chrsz = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode  */
   105   
   105 	
   106   function safe_add ($x, $y) {
   106 	function safe_add ($x, $y) {
   107     $lsw = ($x & 0xFFFF) + ($y & 0xFFFF);
   107 		$lsw = ($x & 0xFFFF) + ($y & 0xFFFF);
   108     $msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);
   108 		$msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);
   109     // 2009-07-02 Added & 0xFFFFFFFF here to fix problem on PHP w/ native 64-bit integer support (rev. 1030)
   109 		// 2009-07-02 Added & 0xFFFFFFFF here to fix problem on PHP w/ native 64-bit integer support (rev. 1030)
   110     return (($msw << 16) | ($lsw & 0xFFFF)) & 0xFFFFFFFF;
   110 		return (($msw << 16) | ($lsw & 0xFFFF)) & 0xFFFFFFFF;
   111   }
   111 	}
   112   function rshz($X, $n)
   112 	function rshz($X, $n)
   113   {
   113 	{
   114     // equivalent to $X >>> $n in javascript
   114 		// equivalent to $X >>> $n in javascript
   115     // pulled from http://www.tapouillo.com/firefox_extension/sourcecode.txt, public domain
   115 		// pulled from http://www.tapouillo.com/firefox_extension/sourcecode.txt, public domain
   116     $z = hexdec(80000000); 
   116 		$z = hexdec(80000000); 
   117     if ($z & $X) 
   117 		if ($z & $X) 
   118     { 
   118 		{ 
   119         $X = ($X>>1); 
   119 				$X = ($X>>1); 
   120         $X &= (~$z); 
   120 				$X &= (~$z); 
   121         $X |= 0x40000000; 
   121 				$X |= 0x40000000; 
   122         $X = ($X>>($n-1)); 
   122 				$X = ($X>>($n-1)); 
   123     } 
   123 		} 
   124     else 
   124 		else 
   125     { 
   125 		{ 
   126         $X = ($X>>$n); 
   126 				$X = ($X>>$n); 
   127     } 
   127 		} 
   128     return $X; 
   128 		return $X; 
   129   }
   129 	}
   130   function S ($X, $n) {return ( $this->rshz($X, $n) ) | ($X << (32 - $n));}
   130 	function S ($X, $n) {return ( $this->rshz($X, $n) ) | ($X << (32 - $n));}
   131   function R ($X, $n) {return ( $this->rshz($X, $n) );}
   131 	function R ($X, $n) {return ( $this->rshz($X, $n) );}
   132   function Ch($x, $y, $z)  {return (($x & $y) ^ ((~$x) & $z));}
   132 	function Ch($x, $y, $z)  {return (($x & $y) ^ ((~$x) & $z));}
   133   function Maj($x, $y, $z) {return (($x & $y) ^ ($x & $z) ^ ($y & $z));}
   133 	function Maj($x, $y, $z) {return (($x & $y) ^ ($x & $z) ^ ($y & $z));}
   134   function Sigma0256($x) {return ($this->S($x, 2)  ^ $this->S($x, 13) ^ $this->S($x, 22));}
   134 	function Sigma0256($x) {return ($this->S($x, 2)  ^ $this->S($x, 13) ^ $this->S($x, 22));}
   135   function Sigma1256($x) {return ($this->S($x, 6)  ^ $this->S($x, 11) ^ $this->S($x, 25));}
   135 	function Sigma1256($x) {return ($this->S($x, 6)  ^ $this->S($x, 11) ^ $this->S($x, 25));}
   136   function Gamma0256($x) {return ($this->S($x, 7)  ^ $this->S($x, 18) ^ $this->R($x, 3));}
   136 	function Gamma0256($x) {return ($this->S($x, 7)  ^ $this->S($x, 18) ^ $this->R($x, 3));}
   137   function Gamma1256($x) {return ($this->S($x, 17) ^ $this->S($x, 19) ^ $this->R($x, 10));}
   137 	function Gamma1256($x) {return ($this->S($x, 17) ^ $this->S($x, 19) ^ $this->R($x, 10));}
   138   function core_sha256 ($m, $l) {
   138 	function core_sha256 ($m, $l) {
   139       $K = Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2);
   139 			$K = Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2);
   140       $HASH = Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
   140 			$HASH = Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
   141       $W = Array(64);
   141 			$W = Array(64);
   142       /* append padding */
   142 			/* append padding */
   143       if ( !isset($m[$l >> 5]) )
   143 			if ( !isset($m[$l >> 5]) )
   144         $m[$l >> 5] = 0;
   144 				$m[$l >> 5] = 0;
   145       $m[$l >> 5] |= 0x80 << (24 - $l % 32);
   145 			$m[$l >> 5] |= 0x80 << (24 - $l % 32);
   146       $m[(($l + 64 >> 9) << 4) + 15] = $l;
   146 			$m[(($l + 64 >> 9) << 4) + 15] = $l;
   147       for ( $i = 0; $i<count($m); $i+=16 ) {
   147 			for ( $i = 0; $i<count($m); $i+=16 ) {
   148           $a = $HASH[0];
   148 					$a = $HASH[0];
   149           $b = $HASH[1];
   149 					$b = $HASH[1];
   150           $c = $HASH[2];
   150 					$c = $HASH[2];
   151           $d = $HASH[3];
   151 					$d = $HASH[3];
   152           $e = $HASH[4];
   152 					$e = $HASH[4];
   153           $f = $HASH[5];
   153 					$f = $HASH[5];
   154           $g = $HASH[6];
   154 					$g = $HASH[6];
   155           $h = $HASH[7];
   155 					$h = $HASH[7];
   156           for ( $j = 0; $j<64; $j++)
   156 					for ( $j = 0; $j<64; $j++)
   157           {
   157 					{
   158               if ( $j < 16 )
   158 							if ( $j < 16 )
   159               {
   159 							{
   160                 $W[$j] = ( isset($m[$j + $i]) ) ? $m[$j + $i] : 0;
   160 								$W[$j] = ( isset($m[$j + $i]) ) ? $m[$j + $i] : 0;
   161               }
   161 							}
   162               else
   162 							else
   163               {
   163 							{
   164                 $W[$j] = $this->safe_add(
   164 								$W[$j] = $this->safe_add(
   165                   $this->safe_add(
   165 									$this->safe_add(
   166                     $this->safe_add(
   166 										$this->safe_add(
   167                       $this->Gamma1256($W[$j - 2]), $W[$j - 7]),
   167 											$this->Gamma1256($W[$j - 2]), $W[$j - 7]),
   168                     $this->Gamma0256($W[$j - 15])),
   168 										$this->Gamma0256($W[$j - 15])),
   169                   $W[$j - 16]);
   169 									$W[$j - 16]);
   170               }
   170 							}
   171               $T1 = $this->safe_add(
   171 							$T1 = $this->safe_add(
   172                 $this->safe_add(
   172 								$this->safe_add(
   173                   $this->safe_add(
   173 									$this->safe_add(
   174                     $this->safe_add($h, $this->Sigma1256($e)
   174 										$this->safe_add($h, $this->Sigma1256($e)
   175                       ),
   175 											),
   176                     $this->Ch($e, $f, $g)),
   176 										$this->Ch($e, $f, $g)),
   177                   $K[$j]),
   177 									$K[$j]),
   178                 $W[$j]);
   178 								$W[$j]);
   179               $T2 = $this->safe_add($this->Sigma0256($a), $this->Maj($a, $b, $c));
   179 							$T2 = $this->safe_add($this->Sigma0256($a), $this->Maj($a, $b, $c));
   180               $h = $g;
   180 							$h = $g;
   181               $g = $f;
   181 							$g = $f;
   182               $f = $e;
   182 							$f = $e;
   183               $e = $this->safe_add($d, $T1);
   183 							$e = $this->safe_add($d, $T1);
   184               $d = $c;
   184 							$d = $c;
   185               $c = $b;
   185 							$c = $b;
   186               $b = $a;
   186 							$b = $a;
   187               $a = $this->safe_add($T1, $T2);
   187 							$a = $this->safe_add($T1, $T2);
   188           }
   188 					}
   189           $HASH[0] = $this->safe_add($a, $HASH[0]);
   189 					$HASH[0] = $this->safe_add($a, $HASH[0]);
   190           $HASH[1] = $this->safe_add($b, $HASH[1]);
   190 					$HASH[1] = $this->safe_add($b, $HASH[1]);
   191           $HASH[2] = $this->safe_add($c, $HASH[2]);
   191 					$HASH[2] = $this->safe_add($c, $HASH[2]);
   192           $HASH[3] = $this->safe_add($d, $HASH[3]);
   192 					$HASH[3] = $this->safe_add($d, $HASH[3]);
   193           $HASH[4] = $this->safe_add($e, $HASH[4]);
   193 					$HASH[4] = $this->safe_add($e, $HASH[4]);
   194           $HASH[5] = $this->safe_add($f, $HASH[5]);
   194 					$HASH[5] = $this->safe_add($f, $HASH[5]);
   195           $HASH[6] = $this->safe_add($g, $HASH[6]);
   195 					$HASH[6] = $this->safe_add($g, $HASH[6]);
   196           $HASH[7] = $this->safe_add($h, $HASH[7]);
   196 					$HASH[7] = $this->safe_add($h, $HASH[7]);
   197       }
   197 			}
   198       return $HASH;
   198 			return $HASH;
   199   }
   199 	}
   200   function str2binb ($str) {
   200 	function str2binb ($str) {
   201     $bin = Array();
   201 		$bin = Array();
   202     for ( $i = 0; $i < strlen($str); $i++ )
   202 		for ( $i = 0; $i < strlen($str); $i++ )
   203     {
   203 		{
   204       $byte = ord($str{$i});
   204 			$byte = ord($str{$i});
   205       $block = floor($i / 4);
   205 			$block = floor($i / 4);
   206       $stage = $i % 4;
   206 			$stage = $i % 4;
   207       if ( $stage == 0 )
   207 			if ( $stage == 0 )
   208       {
   208 			{
   209         $bin[$block] = $byte;
   209 				$bin[$block] = $byte;
   210       }
   210 			}
   211       else
   211 			else
   212       {
   212 			{
   213         $bin[$block] <<= 8;
   213 				$bin[$block] <<= 8;
   214         $bin[$block] |= $byte;
   214 				$bin[$block] |= $byte;
   215       }
   215 			}
   216     }
   216 		}
   217     while ( $stage < 3 )
   217 		while ( $stage < 3 )
   218     {
   218 		{
   219       $stage++;
   219 			$stage++;
   220       $bin[$block] <<= 8;
   220 			$bin[$block] <<= 8;
   221     }
   221 		}
   222     return $bin;
   222 		return $bin;
   223   }
   223 	}
   224   function byte2hex($byte)
   224 	function byte2hex($byte)
   225   {
   225 	{
   226     $b = dechex(ord($byte));
   226 		$b = dechex(ord($byte));
   227     return ( strlen($b) < 2 ) ? "0$b" : $b;
   227 		return ( strlen($b) < 2 ) ? "0$b" : $b;
   228   }
   228 	}
   229   function binb2hex ($binarray) {
   229 	function binb2hex ($binarray) {
   230     $hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
   230 		$hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
   231     $hex_tab = $hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
   231 		$hex_tab = $hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
   232     $str = "";
   232 		$str = "";
   233     foreach ( $binarray as $bytes )
   233 		foreach ( $binarray as $bytes )
   234     {
   234 		{
   235       $str .= implode('', array(
   235 			$str .= implode('', array(
   236           $this->byte2hex(chr(( $bytes >> 24 ) & 0xFF)),
   236 					$this->byte2hex(chr(( $bytes >> 24 ) & 0xFF)),
   237           $this->byte2hex(chr(( $bytes >> 16 ) & 0xFF)),
   237 					$this->byte2hex(chr(( $bytes >> 16 ) & 0xFF)),
   238           $this->byte2hex(chr(( $bytes >> 8 ) & 0xFF)),
   238 					$this->byte2hex(chr(( $bytes >> 8 ) & 0xFF)),
   239           $this->byte2hex(chr($bytes & 0xFF))
   239 					$this->byte2hex(chr($bytes & 0xFF))
   240         ));
   240 				));
   241     }
   241 		}
   242     return $str;
   242 		return $str;
   243   }
   243 	}
   244   function hex_sha256 ( $s )
   244 	function hex_sha256 ( $s )
   245   {
   245 	{
   246     return $this->binb2hex(
   246 		return $this->binb2hex(
   247       $this->core_sha256(
   247 			$this->core_sha256(
   248         $this->str2binb($s),
   248 				$this->str2binb($s),
   249         strlen($s) * $this->chrsz)
   249 				strlen($s) * $this->chrsz)
   250       );
   250 			);
   251   }
   251 	}
   252 }
   252 }
   253 
   253 
   254 if ( !function_exists('sha256') )
   254 if ( !function_exists('sha256') )
   255 {
   255 {
   256   function sha256($text)
   256 	function sha256($text)
   257   {
   257 	{
   258     static $sha_obj = false;
   258 		static $sha_obj = false;
   259     if ( !is_object($sha_obj) )
   259 		if ( !is_object($sha_obj) )
   260       $sha_obj = new SHA256();
   260 			$sha_obj = new SHA256();
   261     return $sha_obj->hex_sha256($text);
   261 		return $sha_obj->hex_sha256($text);
   262   }
   262 	}
   263 }
   263 }
   264 
   264 
   265 ?>
   265 ?>