openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Hash.class.php (29328B)


      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      * @param int $...
    853      * @return int
    854      * @see self::_sha256()
    855      * @access private
    856      */
    857     function _add()
    858     {
    859         static $mod;
    860         if (!isset($mod)) {
    861             $mod = pow(2, 32);
    862         }
    863 
    864         $result = 0;
    865         $arguments = func_get_args();
    866         foreach ($arguments as $argument) {
    867             $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
    868         }
    869 
    870         if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') {
    871             return fmod($result, $mod);
    872         }
    873 
    874         return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
    875             ((fmod(floor($result / 0x80000000), 2) & 1) << 31);
    876     }
    877 
    878     /**
    879      * String Shift
    880      *
    881      * Inspired by array_shift
    882      *
    883      * @param string $string
    884      * @param int $index
    885      * @return string
    886      * @access private
    887      */
    888     function _string_shift(&$string, $index = 1)
    889     {
    890         $substr = substr($string, 0, $index);
    891         $string = substr($string, $index);
    892         return $substr;
    893     }
    894 }