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
39namespace phpseclib\Crypt;
40
41use 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 */
50class 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}
894