Subversion Repositories cheapmusic

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
103 - 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
     * 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
}