[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/phpseclib/phpseclib/phpseclib/Crypt/ -> Hash.php (source)

   1  <?php
   2  
   3  /**
   4   * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
   5   *
   6   * Uses hash() or mhash() if available and an internal implementation, otherwise.  Currently supports the following:
   7   *
   8   * md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
   9   *
  10   * If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to
  11   * the hash.  If no valid algorithm is provided, sha1 will be used.
  12   *
  13   * PHP version 5
  14   *
  15   * {@internal The variable names are the same as those in
  16   * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
  17   *
  18   * Here's a short example of how to use this library:
  19   * <code>
  20   * <?php
  21   *    include 'vendor/autoload.php';
  22   *
  23   *    $hash = new \phpseclib\Crypt\Hash('sha1');
  24   *
  25   *    $hash->setKey('abcdefg');
  26   *
  27   *    echo base64_encode($hash->hash('abcdefg'));
  28   * ?>
  29   * </code>
  30   *
  31   * @category  Crypt
  32   * @package   Hash
  33   * @author    Jim Wigginton <terrafrost@php.net>
  34   * @copyright 2007 Jim Wigginton
  35   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  36   * @link      http://phpseclib.sourceforge.net
  37   */
  38  
  39  namespace phpseclib\Crypt;
  40  
  41  use phpseclib\Math\BigInteger;
  42  
  43  /**
  44   * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
  45   *
  46   * @package Hash
  47   * @author  Jim Wigginton <terrafrost@php.net>
  48   * @access  public
  49   */
  50  class Hash
  51  {
  52      /**#@+
  53       * @access private
  54       * @see \phpseclib\Crypt\Hash::__construct()
  55       */
  56      /**
  57       * Toggles the internal implementation
  58       */
  59      const MODE_INTERNAL = 1;
  60      /**
  61       * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
  62       */
  63      const MODE_MHASH = 2;
  64      /**
  65       * Toggles the hash() implementation, which works on PHP 5.1.2+.
  66       */
  67      const MODE_HASH = 3;
  68      /**#@-*/
  69  
  70      /**
  71       * Hash Parameter
  72       *
  73       * @see self::setHash()
  74       * @var int
  75       * @access private
  76       */
  77      var $hashParam;
  78  
  79      /**
  80       * Byte-length of compression blocks / key (Internal HMAC)
  81       *
  82       * @see self::setAlgorithm()
  83       * @var int
  84       * @access private
  85       */
  86      var $b;
  87  
  88      /**
  89       * Byte-length of hash output (Internal HMAC)
  90       *
  91       * @see self::setHash()
  92       * @var int
  93       * @access private
  94       */
  95      var $l = false;
  96  
  97      /**
  98       * Hash Algorithm
  99       *
 100       * @see self::setHash()
 101       * @var string
 102       * @access private
 103       */
 104      var $hash;
 105  
 106      /**
 107       * Key
 108       *
 109       * @see self::setKey()
 110       * @var string
 111       * @access private
 112       */
 113      var $key = false;
 114  
 115      /**
 116       * Computed Key
 117       *
 118       * @see self::_computeKey()
 119       * @var string
 120       * @access private
 121       */
 122      var $computedKey = false;
 123  
 124      /**
 125       * Outer XOR (Internal HMAC)
 126       *
 127       * @see self::setKey()
 128       * @var string
 129       * @access private
 130       */
 131      var $opad;
 132  
 133      /**
 134       * Inner XOR (Internal HMAC)
 135       *
 136       * @see self::setKey()
 137       * @var string
 138       * @access private
 139       */
 140      var $ipad;
 141  
 142      /**
 143       * Engine
 144       *
 145       * @see self::setHash()
 146       * @var string
 147       * @access private
 148       */
 149      var $engine;
 150  
 151      /**
 152       * Default Constructor.
 153       *
 154       * @param string $hash
 155       * @return \phpseclib\Crypt\Hash
 156       * @access public
 157       */
 158      function __construct($hash = 'sha1')
 159      {
 160          if (!defined('CRYPT_HASH_MODE')) {
 161              switch (true) {
 162                  case extension_loaded('hash'):
 163                      define('CRYPT_HASH_MODE', self::MODE_HASH);
 164                      break;
 165                  case extension_loaded('mhash'):
 166                      define('CRYPT_HASH_MODE', self::MODE_MHASH);
 167                      break;
 168                  default:
 169                      define('CRYPT_HASH_MODE', self::MODE_INTERNAL);
 170              }
 171          }
 172  
 173          $this->setHash($hash);
 174      }
 175  
 176      /**
 177       * Sets the key for HMACs
 178       *
 179       * Keys can be of any length.
 180       *
 181       * @access public
 182       * @param string $key
 183       */
 184      function setKey($key = false)
 185      {
 186          $this->key = $key;
 187          $this->_computeKey();
 188      }
 189  
 190      /**
 191       * Pre-compute the key used by the HMAC
 192       *
 193       * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
 194       * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
 195       *
 196       * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
 197       * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
 198       * every call
 199       *
 200       * @access private
 201       */
 202      function _computeKey()
 203      {
 204          if ($this->key === false) {
 205              $this->computedKey = false;
 206              return;
 207          }
 208  
 209          if (strlen($this->key) <= $this->b) {
 210              $this->computedKey = $this->key;
 211              return;
 212          }
 213  
 214          switch ($this->engine) {
 215              case self::MODE_MHASH:
 216                  $this->computedKey = mhash($this->hash, $this->key);
 217                  break;
 218              case self::MODE_HASH:
 219                  $this->computedKey = hash($this->hash, $this->key, true);
 220                  break;
 221              case self::MODE_INTERNAL:
 222                  $this->computedKey = call_user_func($this->hash, $this->key);
 223          }
 224      }
 225  
 226      /**
 227       * Gets the hash function.
 228       *
 229       * As set by the constructor or by the setHash() method.
 230       *
 231       * @access public
 232       * @return string
 233       */
 234      function getHash()
 235      {
 236          return $this->hashParam;
 237      }
 238  
 239      /**
 240       * Sets the hash function.
 241       *
 242       * @access public
 243       * @param string $hash
 244       */
 245      function setHash($hash)
 246      {
 247          $this->hashParam = $hash = strtolower($hash);
 248          switch ($hash) {
 249              case 'md5-96':
 250              case 'sha1-96':
 251              case 'sha256-96':
 252              case 'sha512-96':
 253                  $hash = substr($hash, 0, -3);
 254                  $this->l = 12; // 96 / 8 = 12
 255                  break;
 256              case 'md2':
 257              case 'md5':
 258                  $this->l = 16;
 259                  break;
 260              case 'sha1':
 261                  $this->l = 20;
 262                  break;
 263              case 'sha256':
 264                  $this->l = 32;
 265                  break;
 266              case 'sha384':
 267                  $this->l = 48;
 268                  break;
 269              case 'sha512':
 270                  $this->l = 64;
 271          }
 272  
 273          switch ($hash) {
 274              case 'md2-96':
 275              case 'md2':
 276                  $this->b = 16;
 277              case 'md5-96':
 278              case 'sha1-96':
 279              case 'sha224-96':
 280              case 'sha256-96':
 281              case 'md2':
 282              case 'md5':
 283              case 'sha1':
 284              case 'sha224':
 285              case 'sha256':
 286                  $this->b = 64;
 287                  break;
 288              default:
 289                  $this->b = 128;
 290          }
 291  
 292          switch ($hash) {
 293              case 'md2':
 294                  $this->engine = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ?
 295                      self::MODE_HASH : self::MODE_INTERNAL;
 296                  break;
 297              case 'sha384':
 298              case 'sha512':
 299                  $this->engine = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
 300                  break;
 301              default:
 302                  $this->engine = CRYPT_HASH_MODE;
 303          }
 304  
 305          switch ($this->engine) {
 306              case self::MODE_MHASH:
 307                  switch ($hash) {
 308                      case 'md5':
 309                          $this->hash = MHASH_MD5;
 310                          break;
 311                      case 'sha256':
 312                          $this->hash = MHASH_SHA256;
 313                          break;
 314                      case 'sha1':
 315                      default:
 316                          $this->hash = MHASH_SHA1;
 317                  }
 318                  $this->_computeKey(self::MODE_MHASH);
 319                  return;
 320              case self::MODE_HASH:
 321                  switch ($hash) {
 322                      case 'md5':
 323                          $this->hash = 'md5';
 324                          return;
 325                      case 'md2':
 326                      case 'sha256':
 327                      case 'sha384':
 328                      case 'sha512':
 329                          $this->hash = $hash;
 330                          return;
 331                      case 'sha1':
 332                      default:
 333                          $this->hash = 'sha1';
 334                  }
 335                  $this->_computeKey(self::MODE_HASH);
 336                  return;
 337          }
 338  
 339          switch ($hash) {
 340              case 'md2':
 341                  $this->hash = array($this, '_md2');
 342                  break;
 343              case 'md5':
 344                  $this->hash = array($this, '_md5');
 345                  break;
 346              case 'sha256':
 347                  $this->hash = array($this, '_sha256');
 348                  break;
 349              case 'sha384':
 350              case 'sha512':
 351                  $this->hash = array($this, '_sha512');
 352                  break;
 353              case 'sha1':
 354              default:
 355                  $this->hash = array($this, '_sha1');
 356          }
 357  
 358          $this->ipad = str_repeat(chr(0x36), $this->b);
 359          $this->opad = str_repeat(chr(0x5C), $this->b);
 360  
 361          $this->_computeKey(self::MODE_INTERNAL);
 362      }
 363  
 364      /**
 365       * Compute the HMAC.
 366       *
 367       * @access public
 368       * @param string $text
 369       * @return string
 370       */
 371      function hash($text)
 372      {
 373          if (!empty($this->key) || is_string($this->key)) {
 374              switch ($this->engine) {
 375                  case self::MODE_MHASH:
 376                      $output = mhash($this->hash, $text, $this->computedKey);
 377                      break;
 378                  case self::MODE_HASH:
 379                      $output = hash_hmac($this->hash, $text, $this->computedKey, true);
 380                      break;
 381                  case self::MODE_INTERNAL:
 382                      $key    = str_pad($this->computedKey, $this->b, chr(0)); // step 1
 383                      $temp   = $this->ipad ^ $key;                            // step 2
 384                      $temp  .= $text;                                         // step 3
 385                      $temp   = call_user_func($this->hash, $temp);            // step 4
 386                      $output = $this->opad ^ $key;                            // step 5
 387                      $output.= $temp;                                         // step 6
 388                      $output = call_user_func($this->hash, $output);          // step 7
 389              }
 390          } else {
 391              switch ($this->engine) {
 392                  case self::MODE_MHASH:
 393                      $output = mhash($this->hash, $text);
 394                      break;
 395                  case self::MODE_HASH:
 396                      $output = hash($this->hash, $text, true);
 397                      break;
 398                  case self::MODE_INTERNAL:
 399                      $output = call_user_func($this->hash, $text);
 400              }
 401          }
 402  
 403          return substr($output, 0, $this->l);
 404      }
 405  
 406      /**
 407       * Returns the hash length (in bytes)
 408       *
 409       * @access public
 410       * @return int
 411       */
 412      function getLength()
 413      {
 414          return $this->l;
 415      }
 416  
 417      /**
 418       * Wrapper for MD5
 419       *
 420       * @access private
 421       * @param string $m
 422       */
 423      function _md5($m)
 424      {
 425          return pack('H*', md5($m));
 426      }
 427  
 428      /**
 429       * Wrapper for SHA1
 430       *
 431       * @access private
 432       * @param string $m
 433       */
 434      function _sha1($m)
 435      {
 436          return pack('H*', sha1($m));
 437      }
 438  
 439      /**
 440       * Pure-PHP implementation of MD2
 441       *
 442       * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
 443       *
 444       * @access private
 445       * @param string $m
 446       */
 447      function _md2($m)
 448      {
 449          static $s = array(
 450               41,  46,  67, 201, 162, 216, 124,   1,  61,  54,  84, 161, 236, 240, 6,
 451               19,  98, 167,   5, 243, 192, 199, 115, 140, 152, 147,  43, 217, 188,
 452               76, 130, 202,  30, 155,  87,  60, 253, 212, 224,  22, 103,  66, 111, 24,
 453              138,  23, 229,  18, 190,  78, 196, 214, 218, 158, 222,  73, 160, 251,
 454              245, 142, 187,  47, 238, 122, 169, 104, 121, 145,  21, 178,   7,  63,
 455              148, 194,  16, 137,  11,  34,  95,  33, 128, 127,  93, 154,  90, 144, 50,
 456               39,  53,  62, 204, 231, 191, 247, 151,   3, 255,  25,  48, 179,  72, 165,
 457              181, 209, 215,  94, 146,  42, 172,  86, 170, 198,  79, 184,  56, 210,
 458              150, 164, 125, 182, 118, 252, 107, 226, 156, 116,   4, 241,  69, 157,
 459              112,  89, 100, 113, 135,  32, 134,  91, 207, 101, 230,  45, 168,   2, 27,
 460               96,  37, 173, 174, 176, 185, 246,  28,  70,  97, 105,  52,  64, 126, 15,
 461               85,  71, 163,  35, 221,  81, 175,  58, 195,  92, 249, 206, 186, 197,
 462              234,  38,  44,  83,  13, 110, 133,  40, 132,   9, 211, 223, 205, 244, 65,
 463              129,  77,  82, 106, 220,  55, 200, 108, 193, 171, 250,  36, 225, 123,
 464                8,  12, 189, 177,  74, 120, 136, 149, 139, 227,  99, 232, 109, 233,
 465              203, 213, 254,  59,   0,  29,  57, 242, 239, 183,  14, 102,  88, 208, 228,
 466              166, 119, 114, 248, 235, 117,  75,  10,  49,  68,  80, 180, 143, 237,
 467               31,  26, 219, 153, 141,  51, 159,  17, 131, 20
 468          );
 469  
 470          // Step 1. Append Padding Bytes
 471          $pad = 16 - (strlen($m) & 0xF);
 472          $m.= str_repeat(chr($pad), $pad);
 473  
 474          $length = strlen($m);
 475  
 476          // Step 2. Append Checksum
 477          $c = str_repeat(chr(0), 16);
 478          $l = chr(0);
 479          for ($i = 0; $i < $length; $i+= 16) {
 480              for ($j = 0; $j < 16; $j++) {
 481                  // RFC1319 incorrectly states that C[j] should be set to S[c xor L]
 482                  //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
 483                  // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
 484                  $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
 485                  $l = $c[$j];
 486              }
 487          }
 488          $m.= $c;
 489  
 490          $length+= 16;
 491  
 492          // Step 3. Initialize MD Buffer
 493          $x = str_repeat(chr(0), 48);
 494  
 495          // Step 4. Process Message in 16-Byte Blocks
 496          for ($i = 0; $i < $length; $i+= 16) {
 497              for ($j = 0; $j < 16; $j++) {
 498                  $x[$j + 16] = $m[$i + $j];
 499                  $x[$j + 32] = $x[$j + 16] ^ $x[$j];
 500              }
 501              $t = chr(0);
 502              for ($j = 0; $j < 18; $j++) {
 503                  for ($k = 0; $k < 48; $k++) {
 504                      $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
 505                      //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
 506                  }
 507                  $t = chr(ord($t) + $j);
 508              }
 509          }
 510  
 511          // Step 5. Output
 512          return substr($x, 0, 16);
 513      }
 514  
 515      /**
 516       * Pure-PHP implementation of SHA256
 517       *
 518       * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
 519       *
 520       * @access private
 521       * @param string $m
 522       */
 523      function _sha256($m)
 524      {
 525          if (extension_loaded('suhosin')) {
 526              return pack('H*', sha256($m));
 527          }
 528  
 529          // Initialize variables
 530          $hash = array(
 531              0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
 532          );
 533          // Initialize table of round constants
 534          // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
 535          static $k = array(
 536              0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
 537              0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
 538              0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
 539              0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
 540              0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
 541              0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
 542              0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
 543              0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
 544          );
 545  
 546          // Pre-processing
 547          $length = strlen($m);
 548          // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
 549          $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
 550          $m[$length] = chr(0x80);
 551          // we don't support hashing strings 512MB long
 552          $m.= pack('N2', 0, $length << 3);
 553  
 554          // Process the message in successive 512-bit chunks
 555          $chunks = str_split($m, 64);
 556          foreach ($chunks as $chunk) {
 557              $w = array();
 558              for ($i = 0; $i < 16; $i++) {
 559                  extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
 560                  $w[] = $temp;
 561              }
 562  
 563              // Extend the sixteen 32-bit words into sixty-four 32-bit words
 564              for ($i = 16; $i < 64; $i++) {
 565                  // @codingStandardsIgnoreStart
 566                  $s0 = $this->_rightRotate($w[$i - 15],  7) ^
 567                        $this->_rightRotate($w[$i - 15], 18) ^
 568                        $this->_rightShift( $w[$i - 15],  3);
 569                  $s1 = $this->_rightRotate($w[$i - 2], 17) ^
 570                        $this->_rightRotate($w[$i - 2], 19) ^
 571                        $this->_rightShift( $w[$i - 2], 10);
 572                  // @codingStandardsIgnoreEnd
 573                  $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
 574              }
 575  
 576              // Initialize hash value for this chunk
 577              list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
 578  
 579              // Main loop
 580              for ($i = 0; $i < 64; $i++) {
 581                  $s0 = $this->_rightRotate($a,  2) ^
 582                        $this->_rightRotate($a, 13) ^
 583                        $this->_rightRotate($a, 22);
 584                  $maj = ($a & $b) ^
 585                         ($a & $c) ^
 586                         ($b & $c);
 587                  $t2 = $this->_add($s0, $maj);
 588  
 589                  $s1 = $this->_rightRotate($e,  6) ^
 590                        $this->_rightRotate($e, 11) ^
 591                        $this->_rightRotate($e, 25);
 592                  $ch = ($e & $f) ^
 593                        ($this->_not($e) & $g);
 594                  $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
 595  
 596                  $h = $g;
 597                  $g = $f;
 598                  $f = $e;
 599                  $e = $this->_add($d, $t1);
 600                  $d = $c;
 601                  $c = $b;
 602                  $b = $a;
 603                  $a = $this->_add($t1, $t2);
 604              }
 605  
 606              // Add this chunk's hash to result so far
 607              $hash = array(
 608                  $this->_add($hash[0], $a),
 609                  $this->_add($hash[1], $b),
 610                  $this->_add($hash[2], $c),
 611                  $this->_add($hash[3], $d),
 612                  $this->_add($hash[4], $e),
 613                  $this->_add($hash[5], $f),
 614                  $this->_add($hash[6], $g),
 615                  $this->_add($hash[7], $h)
 616              );
 617          }
 618  
 619          // Produce the final hash value (big-endian)
 620          return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
 621      }
 622  
 623      /**
 624       * Pure-PHP implementation of SHA384 and SHA512
 625       *
 626       * @access private
 627       * @param string $m
 628       */
 629      function _sha512($m)
 630      {
 631          static $init384, $init512, $k;
 632  
 633          if (!isset($k)) {
 634              // Initialize variables
 635              $init384 = array( // initial values for SHA384
 636                  'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
 637                  '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
 638              );
 639              $init512 = array( // initial values for SHA512
 640                  '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
 641                  '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
 642              );
 643  
 644              for ($i = 0; $i < 8; $i++) {
 645                  $init384[$i] = new BigInteger($init384[$i], 16);
 646                  $init384[$i]->setPrecision(64);
 647                  $init512[$i] = new BigInteger($init512[$i], 16);
 648                  $init512[$i]->setPrecision(64);
 649              }
 650  
 651              // Initialize table of round constants
 652              // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
 653              $k = array(
 654                  '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
 655                  '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
 656                  'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
 657                  '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
 658                  'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
 659                  '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
 660                  '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
 661                  'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
 662                  '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
 663                  '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
 664                  'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
 665                  'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
 666                  '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
 667                  '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
 668                  '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
 669                  '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
 670                  'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
 671                  '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
 672                  '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
 673                  '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
 674              );
 675  
 676              for ($i = 0; $i < 80; $i++) {
 677                  $k[$i] = new BigInteger($k[$i], 16);
 678              }
 679          }
 680  
 681          $hash = $this->l == 48 ? $init384 : $init512;
 682  
 683          // Pre-processing
 684          $length = strlen($m);
 685          // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
 686          $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
 687          $m[$length] = chr(0x80);
 688          // we don't support hashing strings 512MB long
 689          $m.= pack('N4', 0, 0, 0, $length << 3);
 690  
 691          // Process the message in successive 1024-bit chunks
 692          $chunks = str_split($m, 128);
 693          foreach ($chunks as $chunk) {
 694              $w = array();
 695              for ($i = 0; $i < 16; $i++) {
 696                  $temp = new BigInteger($this->_string_shift($chunk, 8), 256);
 697                  $temp->setPrecision(64);
 698                  $w[] = $temp;
 699              }
 700  
 701              // Extend the sixteen 32-bit words into eighty 32-bit words
 702              for ($i = 16; $i < 80; $i++) {
 703                  $temp = array(
 704                            $w[$i - 15]->bitwise_rightRotate(1),
 705                            $w[$i - 15]->bitwise_rightRotate(8),
 706                            $w[$i - 15]->bitwise_rightShift(7)
 707                  );
 708                  $s0 = $temp[0]->bitwise_xor($temp[1]);
 709                  $s0 = $s0->bitwise_xor($temp[2]);
 710                  $temp = array(
 711                            $w[$i - 2]->bitwise_rightRotate(19),
 712                            $w[$i - 2]->bitwise_rightRotate(61),
 713                            $w[$i - 2]->bitwise_rightShift(6)
 714                  );
 715                  $s1 = $temp[0]->bitwise_xor($temp[1]);
 716                  $s1 = $s1->bitwise_xor($temp[2]);
 717                  $w[$i] = $w[$i - 16]->copy();
 718                  $w[$i] = $w[$i]->add($s0);
 719                  $w[$i] = $w[$i]->add($w[$i - 7]);
 720                  $w[$i] = $w[$i]->add($s1);
 721              }
 722  
 723              // Initialize hash value for this chunk
 724              $a = $hash[0]->copy();
 725              $b = $hash[1]->copy();
 726              $c = $hash[2]->copy();
 727              $d = $hash[3]->copy();
 728              $e = $hash[4]->copy();
 729              $f = $hash[5]->copy();
 730              $g = $hash[6]->copy();
 731              $h = $hash[7]->copy();
 732  
 733              // Main loop
 734              for ($i = 0; $i < 80; $i++) {
 735                  $temp = array(
 736                      $a->bitwise_rightRotate(28),
 737                      $a->bitwise_rightRotate(34),
 738                      $a->bitwise_rightRotate(39)
 739                  );
 740                  $s0 = $temp[0]->bitwise_xor($temp[1]);
 741                  $s0 = $s0->bitwise_xor($temp[2]);
 742                  $temp = array(
 743                      $a->bitwise_and($b),
 744                      $a->bitwise_and($c),
 745                      $b->bitwise_and($c)
 746                  );
 747                  $maj = $temp[0]->bitwise_xor($temp[1]);
 748                  $maj = $maj->bitwise_xor($temp[2]);
 749                  $t2 = $s0->add($maj);
 750  
 751                  $temp = array(
 752                      $e->bitwise_rightRotate(14),
 753                      $e->bitwise_rightRotate(18),
 754                      $e->bitwise_rightRotate(41)
 755                  );
 756                  $s1 = $temp[0]->bitwise_xor($temp[1]);
 757                  $s1 = $s1->bitwise_xor($temp[2]);
 758                  $temp = array(
 759                      $e->bitwise_and($f),
 760                      $g->bitwise_and($e->bitwise_not())
 761                  );
 762                  $ch = $temp[0]->bitwise_xor($temp[1]);
 763                  $t1 = $h->add($s1);
 764                  $t1 = $t1->add($ch);
 765                  $t1 = $t1->add($k[$i]);
 766                  $t1 = $t1->add($w[$i]);
 767  
 768                  $h = $g->copy();
 769                  $g = $f->copy();
 770                  $f = $e->copy();
 771                  $e = $d->add($t1);
 772                  $d = $c->copy();
 773                  $c = $b->copy();
 774                  $b = $a->copy();
 775                  $a = $t1->add($t2);
 776              }
 777  
 778              // Add this chunk's hash to result so far
 779              $hash = array(
 780                  $hash[0]->add($a),
 781                  $hash[1]->add($b),
 782                  $hash[2]->add($c),
 783                  $hash[3]->add($d),
 784                  $hash[4]->add($e),
 785                  $hash[5]->add($f),
 786                  $hash[6]->add($g),
 787                  $hash[7]->add($h)
 788              );
 789          }
 790  
 791          // Produce the final hash value (big-endian)
 792          // (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs.  as such, we trim the output here)
 793          $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
 794                  $hash[4]->toBytes() . $hash[5]->toBytes();
 795          if ($this->l != 48) {
 796              $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
 797          }
 798  
 799          return $temp;
 800      }
 801  
 802      /**
 803       * Right Rotate
 804       *
 805       * @access private
 806       * @param int $int
 807       * @param int $amt
 808       * @see self::_sha256()
 809       * @return int
 810       */
 811      function _rightRotate($int, $amt)
 812      {
 813          $invamt = 32 - $amt;
 814          $mask = (1 << $invamt) - 1;
 815          return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
 816      }
 817  
 818      /**
 819       * Right Shift
 820       *
 821       * @access private
 822       * @param int $int
 823       * @param int $amt
 824       * @see self::_sha256()
 825       * @return int
 826       */
 827      function _rightShift($int, $amt)
 828      {
 829          $mask = (1 << (32 - $amt)) - 1;
 830          return ($int >> $amt) & $mask;
 831      }
 832  
 833      /**
 834       * Not
 835       *
 836       * @access private
 837       * @param int $int
 838       * @see self::_sha256()
 839       * @return int
 840       */
 841      function _not($int)
 842      {
 843          return ~$int & 0xFFFFFFFF;
 844      }
 845  
 846      /**
 847       * Add
 848       *
 849       * _sha256() adds multiple unsigned 32-bit integers.  Since PHP doesn't support unsigned integers and since the
 850       * possibility of overflow exists, care has to be taken.  BigInteger could be used but this should be faster.
 851       *
 852       * @return int
 853       * @see self::_sha256()
 854       * @access private
 855       */
 856      function _add()
 857      {
 858          static $mod;
 859          if (!isset($mod)) {
 860              $mod = pow(2, 32);
 861          }
 862  
 863          $result = 0;
 864          $arguments = func_get_args();
 865          foreach ($arguments as $argument) {
 866              $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
 867          }
 868  
 869          if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') {
 870              return fmod($result, $mod);
 871          }
 872  
 873          return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
 874              ((fmod(floor($result / 0x80000000), 2) & 1) << 31);
 875      }
 876  
 877      /**
 878       * String Shift
 879       *
 880       * Inspired by array_shift
 881       *
 882       * @param string $string
 883       * @param int $index
 884       * @return string
 885       * @access private
 886       */
 887      function _string_shift(&$string, $index = 1)
 888      {
 889          $substr = substr($string, 0, $index);
 890          $string = substr($string, $index);
 891          return $substr;
 892      }
 893  }