PageRenderTime 34ms CodeModel.GetById 2ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php

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