1<?php
2
3/**
4 * Wrapper around hash() and hash_hmac() functions supporting truncated hashes
5 * such as sha256-96.  Any hash algorithm returned by hash_algos() (and
6 * truncated versions thereof) are supported.
7 *
8 * If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will
9 * return the HMAC as opposed to the hash.
10 *
11 * Here's a short example of how to use this library:
12 * <code>
13 * <?php
14 *    include 'vendor/autoload.php';
15 *
16 *    $hash = new \phpseclib3\Crypt\Hash('sha512');
17 *
18 *    $hash->setKey('abcdefg');
19 *
20 *    echo base64_encode($hash->hash('abcdefg'));
21 * ?>
22 * </code>
23 *
24 * @author    Jim Wigginton <terrafrost@php.net>
25 * @copyright 2015 Jim Wigginton
26 * @author    Andreas Fischer <bantu@phpbb.com>
27 * @copyright 2015 Andreas Fischer
28 * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
29 * @link      http://phpseclib.sourceforge.net
30 */
31
32namespace phpseclib3\Crypt;
33
34use phpseclib3\Common\Functions\Strings;
35use phpseclib3\Exception\InsufficientSetupException;
36use phpseclib3\Exception\UnsupportedAlgorithmException;
37use phpseclib3\Math\BigInteger;
38use phpseclib3\Math\PrimeField;
39
40/**
41 * @author  Jim Wigginton <terrafrost@php.net>
42 * @author  Andreas Fischer <bantu@phpbb.com>
43 */
44class Hash
45{
46    /**
47     * Padding Types
48     *
49     */
50    const PADDING_KECCAK = 1;
51
52    /**
53     * Padding Types
54     *
55     */
56    const PADDING_SHA3 = 2;
57
58    /**
59     * Padding Types
60     *
61     */
62    const PADDING_SHAKE = 3;
63
64    /**
65     * Padding Type
66     *
67     * Only used by SHA3
68     *
69     * @var int
70     */
71    private $paddingType = 0;
72
73    /**
74     * Hash Parameter
75     *
76     * @see self::setHash()
77     * @var int
78     */
79    private $hashParam;
80
81    /**
82     * Byte-length of hash output (Internal HMAC)
83     *
84     * @see self::setHash()
85     * @var int
86     */
87    private $length;
88
89    /**
90     * Hash Algorithm
91     *
92     * @see self::setHash()
93     * @var string
94     */
95    private $algo;
96
97    /**
98     * Key
99     *
100     * @see self::setKey()
101     * @var string
102     */
103    private $key = false;
104
105    /**
106     * Nonce
107     *
108     * @see self::setNonce()
109     * @var string
110     */
111    private $nonce = false;
112
113    /**
114     * Hash Parameters
115     *
116     * @var array
117     */
118    private $parameters = [];
119
120    /**
121     * Computed Key
122     *
123     * @see self::_computeKey()
124     * @var string
125     */
126    private $computedKey = false;
127
128    /**
129     * Outer XOR (Internal HMAC)
130     *
131     * Used only for sha512/*
132     *
133     * @see self::hash()
134     * @var string
135     */
136    private $opad;
137
138    /**
139     * Inner XOR (Internal HMAC)
140     *
141     * Used only for sha512/*
142     *
143     * @see self::hash()
144     * @var string
145     */
146    private $ipad;
147
148    /**
149     * Recompute AES Key
150     *
151     * Used only for umac
152     *
153     * @see self::hash()
154     * @var boolean
155     */
156    private $recomputeAESKey;
157
158    /**
159     * umac cipher object
160     *
161     * @see self::hash()
162     * @var \phpseclib3\Crypt\AES
163     */
164    private $c;
165
166    /**
167     * umac pad
168     *
169     * @see self::hash()
170     * @var string
171     */
172    private $pad;
173
174    /**
175     * Block Size
176     *
177     * @var int
178     */
179    private $blockSize;
180
181    /**#@+
182     * UMAC variables
183     *
184     * @var PrimeField
185     */
186    private static $factory36;
187    private static $factory64;
188    private static $factory128;
189    private static $offset64;
190    private static $offset128;
191    private static $marker64;
192    private static $marker128;
193    private static $maxwordrange64;
194    private static $maxwordrange128;
195    /**#@-*/
196
197    /**
198     * Default Constructor.
199     *
200     * @param string $hash
201     */
202    public function __construct($hash = 'sha256')
203    {
204        $this->setHash($hash);
205    }
206
207    /**
208     * Sets the key for HMACs
209     *
210     * Keys can be of any length.
211     *
212     * @param string $key
213     */
214    public function setKey($key = false)
215    {
216        $this->key = $key;
217        $this->computeKey();
218        $this->recomputeAESKey = true;
219    }
220
221    /**
222     * Sets the nonce for UMACs
223     *
224     * Keys can be of any length.
225     *
226     * @param string $nonce
227     */
228    public function setNonce($nonce = false)
229    {
230        switch (true) {
231            case !is_string($nonce):
232            case strlen($nonce) > 0 && strlen($nonce) <= 16:
233                $this->recomputeAESKey = true;
234                $this->nonce = $nonce;
235                return;
236        }
237
238        throw new \LengthException('The nonce length must be between 1 and 16 bytes, inclusive');
239    }
240
241    /**
242     * Pre-compute the key used by the HMAC
243     *
244     * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
245     * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
246     *
247     * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
248     * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
249     * every call
250     *
251     */
252    private function computeKey()
253    {
254        if ($this->key === false) {
255            $this->computedKey = false;
256            return;
257        }
258
259        if (strlen($this->key) <= $this->getBlockLengthInBytes()) {
260            $this->computedKey = $this->key;
261            return;
262        }
263
264        $this->computedKey = is_array($this->algo) ?
265            call_user_func($this->algo, $this->key) :
266            hash($this->algo, $this->key, true);
267    }
268
269    /**
270     * Gets the hash function.
271     *
272     * As set by the constructor or by the setHash() method.
273     *
274     * @return string
275     */
276    public function getHash()
277    {
278        return $this->hashParam;
279    }
280
281    /**
282     * Sets the hash function.
283     *
284     * @param string $hash
285     */
286    public function setHash($hash)
287    {
288        $this->hashParam = $hash = strtolower($hash);
289        switch ($hash) {
290            case 'umac-32':
291            case 'umac-64':
292            case 'umac-96':
293            case 'umac-128':
294                $this->blockSize = 128;
295                $this->length = abs(substr($hash, -3)) >> 3;
296                $this->algo = 'umac';
297                return;
298            case 'md2-96':
299            case 'md5-96':
300            case 'sha1-96':
301            case 'sha224-96':
302            case 'sha256-96':
303            case 'sha384-96':
304            case 'sha512-96':
305            case 'sha512/224-96':
306            case 'sha512/256-96':
307                $hash = substr($hash, 0, -3);
308                $this->length = 12; // 96 / 8 = 12
309                break;
310            case 'md2':
311            case 'md5':
312                $this->length = 16;
313                break;
314            case 'sha1':
315                $this->length = 20;
316                break;
317            case 'sha224':
318            case 'sha512/224':
319            case 'sha3-224':
320                $this->length = 28;
321                break;
322            case 'keccak256':
323                $this->paddingType = self::PADDING_KECCAK;
324                // fall-through
325            case 'sha256':
326            case 'sha512/256':
327            case 'sha3-256':
328                $this->length = 32;
329                break;
330            case 'sha384':
331            case 'sha3-384':
332                $this->length = 48;
333                break;
334            case 'sha512':
335            case 'sha3-512':
336                $this->length = 64;
337                break;
338            default:
339                if (preg_match('#^(shake(?:128|256))-(\d+)$#', $hash, $matches)) {
340                    $this->paddingType = self::PADDING_SHAKE;
341                    $hash = $matches[1];
342                    $this->length = $matches[2] >> 3;
343                } else {
344                    throw new UnsupportedAlgorithmException(
345                        "$hash is not a supported algorithm"
346                    );
347                }
348        }
349
350        switch ($hash) {
351            case 'md2':
352            case 'md2-96':
353                $this->blockSize = 128;
354                break;
355            case 'md5-96':
356            case 'sha1-96':
357            case 'sha224-96':
358            case 'sha256-96':
359            case 'md5':
360            case 'sha1':
361            case 'sha224':
362            case 'sha256':
363                $this->blockSize = 512;
364                break;
365            case 'sha3-224':
366                $this->blockSize = 1152; // 1600 - 2*224
367                break;
368            case 'sha3-256':
369            case 'shake256':
370            case 'keccak256':
371                $this->blockSize = 1088; // 1600 - 2*256
372                break;
373            case 'sha3-384':
374                $this->blockSize = 832; // 1600 - 2*384
375                break;
376            case 'sha3-512':
377                $this->blockSize = 576; // 1600 - 2*512
378                break;
379            case 'shake128':
380                $this->blockSize = 1344; // 1600 - 2*128
381                break;
382            default:
383                $this->blockSize = 1024;
384        }
385
386        if (in_array(substr($hash, 0, 5), ['sha3-', 'shake', 'kecca'])) {
387            // PHP 7.1.0 introduced support for "SHA3 fixed mode algorithms":
388            // http://php.net/ChangeLog-7.php#7.1.0
389            if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0, 5) != 'sha3-') {
390                //preg_match('#(\d+)$#', $hash, $matches);
391                //$this->parameters['capacity'] = 2 * $matches[1]; // 1600 - $this->blockSize
392                //$this->parameters['rate'] = 1600 - $this->parameters['capacity']; // == $this->blockSize
393                if (!$this->paddingType) {
394                    $this->paddingType = self::PADDING_SHA3;
395                }
396                $this->parameters = [
397                    'capacity' => 1600 - $this->blockSize,
398                    'rate' => $this->blockSize,
399                    'length' => $this->length,
400                    'padding' => $this->paddingType
401                ];
402                $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha3_64' : 'sha3_32'];
403            }
404        }
405
406        if ($hash == 'sha512/224' || $hash == 'sha512/256') {
407            // PHP 7.1.0 introduced sha512/224 and sha512/256 support:
408            // http://php.net/ChangeLog-7.php#7.1.0
409            if (version_compare(PHP_VERSION, '7.1.0') < 0) {
410                // from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24
411                $initial = $hash == 'sha512/256' ?
412                    [
413                        '22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD',
414                        '96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2'
415                    ] :
416                    [
417                        '8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF',
418                        '0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1'
419                    ];
420                for ($i = 0; $i < 8; $i++) {
421                    $initial[$i] = new BigInteger($initial[$i], 16);
422                    $initial[$i]->setPrecision(64);
423                }
424
425                $this->parameters = compact('initial');
426
427                $hash = ['phpseclib3\Crypt\Hash', 'sha512'];
428            }
429        }
430
431        if (is_array($hash)) {
432            $b = $this->blockSize >> 3;
433            $this->ipad = str_repeat(chr(0x36), $b);
434            $this->opad = str_repeat(chr(0x5C), $b);
435        }
436
437        $this->algo = $hash;
438
439        $this->computeKey();
440    }
441
442    /**
443     * KDF: Key-Derivation Function
444     *
445     * The key-derivation function generates pseudorandom bits used to key the hash functions.
446     *
447     * @param int $index a non-negative integer less than 2^64
448     * @param int $numbytes a non-negative integer less than 2^64
449     * @return string string of length numbytes bytes
450     */
451    private function kdf($index, $numbytes)
452    {
453        $this->c->setIV(pack('N4', 0, $index, 0, 1));
454
455        return $this->c->encrypt(str_repeat("\0", $numbytes));
456    }
457
458    /**
459     * PDF Algorithm
460     *
461     * @return string string of length taglen bytes.
462     */
463    private function pdf()
464    {
465        $k = $this->key;
466        $nonce = $this->nonce;
467        $taglen = $this->length;
468
469        //
470        // Extract and zero low bit(s) of Nonce if needed
471        //
472        if ($taglen <= 8) {
473            $last = strlen($nonce) - 1;
474            $mask = $taglen == 4 ? "\3" : "\1";
475            $index = $nonce[$last] & $mask;
476            $nonce[$last] = $nonce[$last] ^ $index;
477        }
478
479        //
480        // Make Nonce BLOCKLEN bytes by appending zeroes if needed
481        //
482        $nonce = str_pad($nonce, 16, "\0");
483
484        //
485        // Generate subkey, encipher and extract indexed substring
486        //
487        $kp = $this->kdf(0, 16);
488        $c = new AES('ctr');
489        $c->disablePadding();
490        $c->setKey($kp);
491        $c->setIV($nonce);
492        $t = $c->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
493
494        // we could use ord() but per https://paragonie.com/blog/2016/06/constant-time-encoding-boring-cryptography-rfc-4648-and-you
495        // unpack() doesn't leak timing info
496        return $taglen <= 8 ?
497            substr($t, unpack('C', $index)[1] * $taglen, $taglen) :
498            substr($t, 0, $taglen);
499    }
500
501    /**
502     * UHASH Algorithm
503     *
504     * @param string $m string of length less than 2^67 bits.
505     * @param int $taglen the integer 4, 8, 12 or 16.
506     * @return string string of length taglen bytes.
507     */
508    private function uhash($m, $taglen)
509    {
510        //
511        // One internal iteration per 4 bytes of output
512        //
513        $iters = $taglen >> 2;
514
515        //
516        // Define total key needed for all iterations using KDF.
517        // L1Key reuses most key material between iterations.
518        //
519        //$L1Key  = $this->kdf(1, 1024 + ($iters - 1) * 16);
520        $L1Key  = $this->kdf(1, (1024 + ($iters - 1)) * 16);
521        $L2Key  = $this->kdf(2, $iters * 24);
522        $L3Key1 = $this->kdf(3, $iters * 64);
523        $L3Key2 = $this->kdf(4, $iters * 4);
524
525        //
526        // For each iteration, extract key and do three-layer hash.
527        // If bytelength(M) <= 1024, then skip L2-HASH.
528        //
529        $y = '';
530        for ($i = 0; $i < $iters; $i++) {
531            $L1Key_i  = substr($L1Key, $i * 16, 1024);
532            $L2Key_i  = substr($L2Key, $i * 24, 24);
533            $L3Key1_i = substr($L3Key1, $i * 64, 64);
534            $L3Key2_i = substr($L3Key2, $i * 4, 4);
535
536            $a = self::L1Hash($L1Key_i, $m);
537            $b = strlen($m) <= 1024 ? "\0\0\0\0\0\0\0\0$a" : self::L2Hash($L2Key_i, $a);
538            $c = self::L3Hash($L3Key1_i, $L3Key2_i, $b);
539            $y .= $c;
540        }
541
542        return $y;
543    }
544
545    /**
546     * L1-HASH Algorithm
547     *
548     * The first-layer hash breaks the message into 1024-byte chunks and
549     * hashes each with a function called NH.  Concatenating the results
550     * forms a string, which is up to 128 times shorter than the original.
551     *
552     * @param string $k string of length 1024 bytes.
553     * @param string $m string of length less than 2^67 bits.
554     * @return string string of length (8 * ceil(bitlength(M)/8192)) bytes.
555     */
556    private static function L1Hash($k, $m)
557    {
558        //
559        // Break M into 1024 byte chunks (final chunk may be shorter)
560        //
561        $m = str_split($m, 1024);
562
563        //
564        // For each chunk, except the last: endian-adjust, NH hash
565        // and add bit-length.  Use results to build Y.
566        //
567        $length = new BigInteger(1024 * 8);
568        $y = '';
569        for ($i = 0; $i < count($m) - 1; $i++) {
570            $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP
571            $y .= static::nh($k, $m[$i], $length);
572        }
573
574        //
575        // For the last chunk: pad to 32-byte boundary, endian-adjust,
576        // NH hash and add bit-length.  Concatenate the result to Y.
577        //
578        $length = count($m) ? strlen($m[$i]) : 0;
579        $pad = 32 - ($length % 32);
580        $pad = max(32, $length + $pad % 32);
581        $m[$i] = str_pad(isset($m[$i]) ? $m[$i] : '', $pad, "\0"); // zeropad
582        $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP
583
584        $y .= static::nh($k, $m[$i], new BigInteger($length * 8));
585
586        return $y;
587    }
588
589    /**
590     * NH Algorithm
591     *
592     * @param string $k string of length 1024 bytes.
593     * @param string $m string with length divisible by 32 bytes.
594     * @return string string of length 8 bytes.
595     */
596    private static function nh($k, $m, $length)
597    {
598        $toUInt32 = function ($x) {
599            $x = new BigInteger($x, 256);
600            $x->setPrecision(32);
601            return $x;
602        };
603
604        //
605        // Break M and K into 4-byte chunks
606        //
607        //$t = strlen($m) >> 2;
608        $m = str_split($m, 4);
609        $t = count($m);
610        $k = str_split($k, 4);
611        $k = array_pad(array_slice($k, 0, $t), $t, 0);
612
613        $m = array_map($toUInt32, $m);
614        $k = array_map($toUInt32, $k);
615
616        //
617        // Perform NH hash on the chunks, pairing words for multiplication
618        // which are 4 apart to accommodate vector-parallelism.
619        //
620        $y = new BigInteger();
621        $y->setPrecision(64);
622        $i = 0;
623        while ($i < $t) {
624            $temp = $m[$i]->add($k[$i]);
625            $temp->setPrecision(64);
626            $temp = $temp->multiply($m[$i + 4]->add($k[$i + 4]));
627            $y = $y->add($temp);
628
629            $temp = $m[$i + 1]->add($k[$i + 1]);
630            $temp->setPrecision(64);
631            $temp = $temp->multiply($m[$i + 5]->add($k[$i + 5]));
632            $y = $y->add($temp);
633
634            $temp = $m[$i + 2]->add($k[$i + 2]);
635            $temp->setPrecision(64);
636            $temp = $temp->multiply($m[$i + 6]->add($k[$i + 6]));
637            $y = $y->add($temp);
638
639            $temp = $m[$i + 3]->add($k[$i + 3]);
640            $temp->setPrecision(64);
641            $temp = $temp->multiply($m[$i + 7]->add($k[$i + 7]));
642            $y = $y->add($temp);
643
644            $i += 8;
645        }
646
647        return $y->add($length)->toBytes();
648    }
649
650    /**
651     * L2-HASH: Second-Layer Hash
652     *
653     * The second-layer rehashes the L1-HASH output using a polynomial hash
654     * called POLY.  If the L1-HASH output is long, then POLY is called once
655     * on a prefix of the L1-HASH output and called using different settings
656     * on the remainder.  (This two-step hashing of the L1-HASH output is
657     * needed only if the message length is greater than 16 megabytes.)
658     * Careful implementation of POLY is necessary to avoid a possible
659     * timing attack (see Section 6.6 for more information).
660     *
661     * @param string $k string of length 24 bytes.
662     * @param string $m string of length less than 2^64 bytes.
663     * @return string string of length 16 bytes.
664     */
665    private static function L2Hash($k, $m)
666    {
667        //
668        //  Extract keys and restrict to special key-sets
669        //
670        $k64 = $k & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF";
671        $k64 = new BigInteger($k64, 256);
672        $k128 = substr($k, 8) & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF";
673        $k128 = new BigInteger($k128, 256);
674
675        //
676        // If M is no more than 2^17 bytes, hash under 64-bit prime,
677        // otherwise, hash first 2^17 bytes under 64-bit prime and
678        // remainder under 128-bit prime.
679        //
680        if (strlen($m) <= 0x20000) { // 2^14 64-bit words
681            $y = self::poly(64, self::$maxwordrange64, $k64, $m);
682        } else {
683            $m_1 = substr($m, 0, 0x20000); // 1 << 17
684            $m_2 = substr($m, 0x20000) . "\x80";
685            $length = strlen($m_2);
686            $pad = 16 - ($length % 16);
687            $pad %= 16;
688            $m_2 = str_pad($m_2, $length + $pad, "\0"); // zeropad
689            $y = self::poly(64, self::$maxwordrange64, $k64, $m_1);
690            $y = str_pad($y, 16, "\0", STR_PAD_LEFT);
691            $y = self::poly(128, self::$maxwordrange128, $k128, $y . $m_2);
692        }
693
694        return str_pad($y, 16, "\0", STR_PAD_LEFT);
695    }
696
697    /**
698     * POLY Algorithm
699     *
700     * @param int $wordbits the integer 64 or 128.
701     * @param BigInteger $maxwordrange positive integer less than 2^wordbits.
702     * @param BigInteger $k integer in the range 0 ... prime(wordbits) - 1.
703     * @param string $m string with length divisible by (wordbits / 8) bytes.
704     * @return integer in the range 0 ... prime(wordbits) - 1.
705     */
706    private static function poly($wordbits, $maxwordrange, $k, $m)
707    {
708        //
709        // Define constants used for fixing out-of-range words
710        //
711        $wordbytes = $wordbits >> 3;
712        if ($wordbits == 128) {
713            $factory = self::$factory128;
714            $offset = self::$offset128;
715            $marker = self::$marker128;
716        } else {
717            $factory = self::$factory64;
718            $offset = self::$offset64;
719            $marker = self::$marker64;
720        }
721
722        $k = $factory->newInteger($k);
723
724        //
725        // Break M into chunks of length wordbytes bytes
726        //
727        $m_i = str_split($m, $wordbytes);
728
729        //
730        // Each input word m is compared with maxwordrange.  If not smaller
731        // then 'marker' and (m - offset), both in range, are hashed.
732        //
733        $y = $factory->newInteger(new BigInteger(1));
734        foreach ($m_i as $m) {
735            $m = $factory->newInteger(new BigInteger($m, 256));
736            if ($m->compare($maxwordrange) >= 0) {
737                $y = $k->multiply($y)->add($marker);
738                $y = $k->multiply($y)->add($m->subtract($offset));
739            } else {
740                $y = $k->multiply($y)->add($m);
741            }
742        }
743
744        return $y->toBytes();
745    }
746
747    /**
748     * L3-HASH: Third-Layer Hash
749     *
750     * The output from L2-HASH is 16 bytes long.  This final hash function
751     * hashes the 16-byte string to a fixed length of 4 bytes.
752     *
753     * @param string $k1 string of length 64 bytes.
754     * @param string $k2 string of length 4 bytes.
755     * @param string $m string of length 16 bytes.
756     * @return string string of length 4 bytes.
757     */
758    private static function L3Hash($k1, $k2, $m)
759    {
760        $factory = self::$factory36;
761
762        $y = $factory->newInteger(new BigInteger());
763        for ($i = 0; $i < 8; $i++) {
764            $m_i = $factory->newInteger(new BigInteger(substr($m, 2 * $i, 2), 256));
765            $k_i = $factory->newInteger(new BigInteger(substr($k1, 8 * $i, 8), 256));
766            $y = $y->add($m_i->multiply($k_i));
767        }
768        $y = str_pad(substr($y->toBytes(), -4), 4, "\0", STR_PAD_LEFT);
769        $y = $y ^ $k2;
770
771        return $y;
772    }
773
774    /**
775     * Compute the Hash / HMAC / UMAC.
776     *
777     * @param string $text
778     * @return string
779     */
780    public function hash($text)
781    {
782        $algo = $this->algo;
783        if ($algo == 'umac') {
784            if ($this->recomputeAESKey) {
785                if (!is_string($this->nonce)) {
786                    throw new InsufficientSetupException('No nonce has been set');
787                }
788                if (!is_string($this->key)) {
789                    throw new InsufficientSetupException('No key has been set');
790                }
791                if (strlen($this->key) != 16) {
792                    throw new \LengthException('Key must be 16 bytes long');
793                }
794
795                if (!isset(self::$maxwordrange64)) {
796                    $one = new BigInteger(1);
797
798                    $prime36 = new BigInteger("\x00\x00\x00\x0F\xFF\xFF\xFF\xFB", 256);
799                    self::$factory36 = new PrimeField($prime36);
800
801                    $prime64 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC5", 256);
802                    self::$factory64 = new PrimeField($prime64);
803
804                    $prime128 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x61", 256);
805                    self::$factory128 = new PrimeField($prime128);
806
807                    self::$offset64 = new BigInteger("\1\0\0\0\0\0\0\0\0", 256);
808                    self::$offset64 = self::$factory64->newInteger(self::$offset64->subtract($prime64));
809                    self::$offset128 = new BigInteger("\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 256);
810                    self::$offset128 = self::$factory128->newInteger(self::$offset128->subtract($prime128));
811
812                    self::$marker64 = self::$factory64->newInteger($prime64->subtract($one));
813                    self::$marker128 = self::$factory128->newInteger($prime128->subtract($one));
814
815                    $maxwordrange64 = $one->bitwise_leftShift(64)->subtract($one->bitwise_leftShift(32));
816                    self::$maxwordrange64 = self::$factory64->newInteger($maxwordrange64);
817
818                    $maxwordrange128 = $one->bitwise_leftShift(128)->subtract($one->bitwise_leftShift(96));
819                    self::$maxwordrange128 = self::$factory128->newInteger($maxwordrange128);
820                }
821
822                $this->c = new AES('ctr');
823                $this->c->disablePadding();
824                $this->c->setKey($this->key);
825
826                $this->pad = $this->pdf();
827
828                $this->recomputeAESKey = false;
829            }
830
831            $hashedmessage = $this->uhash($text, $this->length);
832            return $hashedmessage ^ $this->pad;
833        }
834
835        if (is_array($algo)) {
836            if (empty($this->key) || !is_string($this->key)) {
837                return substr($algo($text, ...array_values($this->parameters)), 0, $this->length);
838            }
839
840            // SHA3 HMACs are discussed at https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=30
841
842            $key    = str_pad($this->computedKey, $b, chr(0));
843            $temp   = $this->ipad ^ $key;
844            $temp  .= $text;
845            $temp   = substr($algo($temp, ...array_values($this->parameters)), 0, $this->length);
846            $output = $this->opad ^ $key;
847            $output .= $temp;
848            $output = $algo($output, ...array_values($this->parameters));
849
850            return substr($output, 0, $this->length);
851        }
852
853        $output = !empty($this->key) || is_string($this->key) ?
854            hash_hmac($algo, $text, $this->computedKey, true) :
855            hash($algo, $text, true);
856
857        return strlen($output) > $this->length
858            ? substr($output, 0, $this->length)
859            : $output;
860    }
861
862    /**
863     * Returns the hash length (in bits)
864     *
865     * @return int
866     */
867    public function getLength()
868    {
869        return $this->length << 3;
870    }
871
872    /**
873     * Returns the hash length (in bytes)
874     *
875     * @return int
876     */
877    public function getLengthInBytes()
878    {
879        return $this->length;
880    }
881
882    /**
883     * Returns the block length (in bits)
884     *
885     * @return int
886     */
887    public function getBlockLength()
888    {
889        return $this->blockSize;
890    }
891
892    /**
893     * Returns the block length (in bytes)
894     *
895     * @return int
896     */
897    public function getBlockLengthInBytes()
898    {
899        return $this->blockSize >> 3;
900    }
901
902    /**
903     * Pads SHA3 based on the mode
904     *
905     * @param int $padLength
906     * @param int $padType
907     * @return string
908     */
909    private static function sha3_pad($padLength, $padType)
910    {
911        switch ($padType) {
912            case self::PADDING_KECCAK:
913                $temp = chr(0x01) . str_repeat("\0", $padLength - 1);
914                $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80);
915                return $temp;
916            case self::PADDING_SHAKE:
917                $temp = chr(0x1F) . str_repeat("\0", $padLength - 1);
918                $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80);
919                return $temp;
920            //case self::PADDING_SHA3:
921            default:
922                // from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=36
923                return $padLength == 1 ? chr(0x86) : chr(0x06) . str_repeat("\0", $padLength - 2) . chr(0x80);
924        }
925    }
926
927    /**
928     * Pure-PHP 32-bit implementation of SHA3
929     *
930     * Whereas BigInteger.php's 32-bit engine works on PHP 64-bit this 32-bit implementation
931     * of SHA3 will *not* work on PHP 64-bit. This is because this implementation
932     * employees bitwise NOTs and bitwise left shifts. And the round constants only work
933     * on 32-bit PHP. eg. dechex(-2147483648) returns 80000000 on 32-bit PHP and
934     * FFFFFFFF80000000 on 64-bit PHP. Sure, we could do bitwise ANDs but that would slow
935     * things down.
936     *
937     * SHA512 requires BigInteger to simulate 64-bit unsigned integers because SHA2 employees
938     * addition whereas SHA3 just employees bitwise operators. PHP64 only supports signed
939     * 64-bit integers, which complicates addition, whereas that limitation isn't an issue
940     * for SHA3.
941     *
942     * In https://ws680.nist.gov/publication/get_pdf.cfm?pub_id=919061#page=16 KECCAK[C] is
943     * defined as "the KECCAK instance with KECCAK-f[1600] as the underlying permutation and
944     * capacity c". This is relevant because, altho the KECCAK standard defines a mode
945     * (KECCAK-f[800]) designed for 32-bit machines that mode is incompatible with SHA3
946     *
947     * @param string $p
948     * @param int $c
949     * @param int $r
950     * @param int $d
951     * @param int $padType
952     */
953    private static function sha3_32($p, $c, $r, $d, $padType)
954    {
955        $block_size = $r >> 3;
956        $padLength = $block_size - (strlen($p) % $block_size);
957        $num_ints = $block_size >> 2;
958
959        $p .= static::sha3_pad($padLength, $padType);
960
961        $n = strlen($p) / $r; // number of blocks
962
963        $s = [
964            [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
965            [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
966            [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
967            [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
968            [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]
969        ];
970
971        $p = str_split($p, $block_size);
972
973        foreach ($p as $pi) {
974            $pi = unpack('V*', $pi);
975            $x = $y = 0;
976            for ($i = 1; $i <= $num_ints; $i += 2) {
977                $s[$x][$y][0] ^= $pi[$i + 1];
978                $s[$x][$y][1] ^= $pi[$i];
979                if (++$y == 5) {
980                    $y = 0;
981                    $x++;
982                }
983            }
984            static::processSHA3Block32($s);
985        }
986
987        $z = '';
988        $i = $j = 0;
989        while (strlen($z) < $d) {
990            $z .= pack('V2', $s[$i][$j][1], $s[$i][$j++][0]);
991            if ($j == 5) {
992                $j = 0;
993                $i++;
994                if ($i == 5) {
995                    $i = 0;
996                    static::processSHA3Block32($s);
997                }
998            }
999        }
1000
1001        return $z;
1002    }
1003
1004    /**
1005     * 32-bit block processing method for SHA3
1006     *
1007     * @param array $s
1008     */
1009    private static function processSHA3Block32(&$s)
1010    {
1011        static $rotationOffsets = [
1012            [ 0,  1, 62, 28, 27],
1013            [36, 44,  6, 55, 20],
1014            [ 3, 10, 43, 25, 39],
1015            [41, 45, 15, 21,  8],
1016            [18,  2, 61, 56, 14]
1017        ];
1018
1019        // the standards give these constants in hexadecimal notation. it's tempting to want to use
1020        // that same notation, here, however, we can't, because 0x80000000, on PHP32, is a positive
1021        // float - not the negative int that we need to be in PHP32. so we use -2147483648 instead
1022        static $roundConstants = [
1023            [0, 1],
1024            [0, 32898],
1025            [-2147483648, 32906],
1026            [-2147483648, -2147450880],
1027            [0, 32907],
1028            [0, -2147483647],
1029            [-2147483648, -2147450751],
1030            [-2147483648, 32777],
1031            [0, 138],
1032            [0, 136],
1033            [0, -2147450871],
1034            [0, -2147483638],
1035            [0, -2147450741],
1036            [-2147483648, 139],
1037            [-2147483648, 32905],
1038            [-2147483648, 32771],
1039            [-2147483648, 32770],
1040            [-2147483648, 128],
1041            [0, 32778],
1042            [-2147483648, -2147483638],
1043            [-2147483648, -2147450751],
1044            [-2147483648, 32896],
1045            [0, -2147483647],
1046            [-2147483648, -2147450872]
1047        ];
1048
1049        for ($round = 0; $round < 24; $round++) {
1050            // theta step
1051            $parity = $rotated = [];
1052            for ($i = 0; $i < 5; $i++) {
1053                $parity[] = [
1054                    $s[0][$i][0] ^ $s[1][$i][0] ^ $s[2][$i][0] ^ $s[3][$i][0] ^ $s[4][$i][0],
1055                    $s[0][$i][1] ^ $s[1][$i][1] ^ $s[2][$i][1] ^ $s[3][$i][1] ^ $s[4][$i][1]
1056                ];
1057                $rotated[] = static::rotateLeft32($parity[$i], 1);
1058            }
1059
1060            $temp = [
1061                [$parity[4][0] ^ $rotated[1][0], $parity[4][1] ^ $rotated[1][1]],
1062                [$parity[0][0] ^ $rotated[2][0], $parity[0][1] ^ $rotated[2][1]],
1063                [$parity[1][0] ^ $rotated[3][0], $parity[1][1] ^ $rotated[3][1]],
1064                [$parity[2][0] ^ $rotated[4][0], $parity[2][1] ^ $rotated[4][1]],
1065                [$parity[3][0] ^ $rotated[0][0], $parity[3][1] ^ $rotated[0][1]]
1066            ];
1067            for ($i = 0; $i < 5; $i++) {
1068                for ($j = 0; $j < 5; $j++) {
1069                    $s[$i][$j][0] ^= $temp[$j][0];
1070                    $s[$i][$j][1] ^= $temp[$j][1];
1071                }
1072            }
1073
1074            $st = $s;
1075
1076            // rho and pi steps
1077            for ($i = 0; $i < 5; $i++) {
1078                for ($j = 0; $j < 5; $j++) {
1079                    $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft32($s[$j][$i], $rotationOffsets[$j][$i]);
1080                }
1081            }
1082
1083            // chi step
1084            for ($i = 0; $i < 5; $i++) {
1085                $s[$i][0] = [
1086                    $st[$i][0][0] ^ (~$st[$i][1][0] & $st[$i][2][0]),
1087                    $st[$i][0][1] ^ (~$st[$i][1][1] & $st[$i][2][1])
1088                ];
1089                $s[$i][1] = [
1090                    $st[$i][1][0] ^ (~$st[$i][2][0] & $st[$i][3][0]),
1091                    $st[$i][1][1] ^ (~$st[$i][2][1] & $st[$i][3][1])
1092                ];
1093                $s[$i][2] = [
1094                    $st[$i][2][0] ^ (~$st[$i][3][0] & $st[$i][4][0]),
1095                    $st[$i][2][1] ^ (~$st[$i][3][1] & $st[$i][4][1])
1096                ];
1097                $s[$i][3] = [
1098                    $st[$i][3][0] ^ (~$st[$i][4][0] & $st[$i][0][0]),
1099                    $st[$i][3][1] ^ (~$st[$i][4][1] & $st[$i][0][1])
1100                ];
1101                $s[$i][4] = [
1102                    $st[$i][4][0] ^ (~$st[$i][0][0] & $st[$i][1][0]),
1103                    $st[$i][4][1] ^ (~$st[$i][0][1] & $st[$i][1][1])
1104                ];
1105            }
1106
1107            // iota step
1108            $s[0][0][0] ^= $roundConstants[$round][0];
1109            $s[0][0][1] ^= $roundConstants[$round][1];
1110        }
1111    }
1112
1113    /**
1114     * Rotate 32-bit int
1115     *
1116     * @param array $x
1117     * @param int $shift
1118     */
1119    private static function rotateLeft32($x, $shift)
1120    {
1121        if ($shift < 32) {
1122            list($hi, $lo) = $x;
1123        } else {
1124            $shift -= 32;
1125            list($lo, $hi) = $x;
1126        }
1127
1128        return [
1129            ($hi << $shift) | (($lo >> (32 - $shift)) & (1 << $shift) - 1),
1130            ($lo << $shift) | (($hi >> (32 - $shift)) & (1 << $shift) - 1)
1131        ];
1132    }
1133
1134    /**
1135     * Pure-PHP 64-bit implementation of SHA3
1136     *
1137     * @param string $p
1138     * @param int $c
1139     * @param int $r
1140     * @param int $d
1141     * @param int $padType
1142     */
1143    private static function sha3_64($p, $c, $r, $d, $padType)
1144    {
1145        $block_size = $r >> 3;
1146        $padLength = $block_size - (strlen($p) % $block_size);
1147        $num_ints = $block_size >> 2;
1148
1149        $p .= static::sha3_pad($padLength, $padType);
1150
1151        $n = strlen($p) / $r; // number of blocks
1152
1153        $s = [
1154            [0, 0, 0, 0, 0],
1155            [0, 0, 0, 0, 0],
1156            [0, 0, 0, 0, 0],
1157            [0, 0, 0, 0, 0],
1158            [0, 0, 0, 0, 0]
1159        ];
1160
1161        $p = str_split($p, $block_size);
1162
1163        foreach ($p as $pi) {
1164            $pi = unpack('P*', $pi);
1165            $x = $y = 0;
1166            foreach ($pi as $subpi) {
1167                $s[$x][$y++] ^= $subpi;
1168                if ($y == 5) {
1169                    $y = 0;
1170                    $x++;
1171                }
1172            }
1173            static::processSHA3Block64($s);
1174        }
1175
1176        $z = '';
1177        $i = $j = 0;
1178        while (strlen($z) < $d) {
1179            $z .= pack('P', $s[$i][$j++]);
1180            if ($j == 5) {
1181                $j = 0;
1182                $i++;
1183                if ($i == 5) {
1184                    $i = 0;
1185                    static::processSHA3Block64($s);
1186                }
1187            }
1188        }
1189
1190        return $z;
1191    }
1192
1193    /**
1194     * 64-bit block processing method for SHA3
1195     *
1196     * @param array $s
1197     */
1198    private static function processSHA3Block64(&$s)
1199    {
1200        static $rotationOffsets = [
1201            [ 0,  1, 62, 28, 27],
1202            [36, 44,  6, 55, 20],
1203            [ 3, 10, 43, 25, 39],
1204            [41, 45, 15, 21,  8],
1205            [18,  2, 61, 56, 14]
1206        ];
1207
1208        static $roundConstants = [
1209            1,
1210            32898,
1211            -9223372036854742902,
1212            -9223372034707259392,
1213            32907,
1214            2147483649,
1215            -9223372034707259263,
1216            -9223372036854743031,
1217            138,
1218            136,
1219            2147516425,
1220            2147483658,
1221            2147516555,
1222            -9223372036854775669,
1223            -9223372036854742903,
1224            -9223372036854743037,
1225            -9223372036854743038,
1226            -9223372036854775680,
1227            32778,
1228            -9223372034707292150,
1229            -9223372034707259263,
1230            -9223372036854742912,
1231            2147483649,
1232            -9223372034707259384
1233        ];
1234
1235        for ($round = 0; $round < 24; $round++) {
1236            // theta step
1237            $parity = [];
1238            for ($i = 0; $i < 5; $i++) {
1239                $parity[] = $s[0][$i] ^ $s[1][$i] ^ $s[2][$i] ^ $s[3][$i] ^ $s[4][$i];
1240            }
1241            $temp = [
1242                $parity[4] ^ static::rotateLeft64($parity[1], 1),
1243                $parity[0] ^ static::rotateLeft64($parity[2], 1),
1244                $parity[1] ^ static::rotateLeft64($parity[3], 1),
1245                $parity[2] ^ static::rotateLeft64($parity[4], 1),
1246                $parity[3] ^ static::rotateLeft64($parity[0], 1)
1247            ];
1248            for ($i = 0; $i < 5; $i++) {
1249                for ($j = 0; $j < 5; $j++) {
1250                    $s[$i][$j] ^= $temp[$j];
1251                }
1252            }
1253
1254            $st = $s;
1255
1256            // rho and pi steps
1257            for ($i = 0; $i < 5; $i++) {
1258                for ($j = 0; $j < 5; $j++) {
1259                    $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft64($s[$j][$i], $rotationOffsets[$j][$i]);
1260                }
1261            }
1262
1263            // chi step
1264            for ($i = 0; $i < 5; $i++) {
1265                $s[$i] = [
1266                    $st[$i][0] ^ (~$st[$i][1] & $st[$i][2]),
1267                    $st[$i][1] ^ (~$st[$i][2] & $st[$i][3]),
1268                    $st[$i][2] ^ (~$st[$i][3] & $st[$i][4]),
1269                    $st[$i][3] ^ (~$st[$i][4] & $st[$i][0]),
1270                    $st[$i][4] ^ (~$st[$i][0] & $st[$i][1])
1271                ];
1272            }
1273
1274            // iota step
1275            $s[0][0] ^= $roundConstants[$round];
1276        }
1277    }
1278
1279    /**
1280     * Rotate 64-bit int
1281     *
1282     * @param int $x
1283     * @param int $shift
1284     */
1285    private static function rotateLeft64($x, $shift)
1286    {
1287        return ($x << $shift) | (($x >> (64 - $shift)) & ((1 << $shift) - 1));
1288    }
1289
1290    /**
1291     * Pure-PHP implementation of SHA512
1292     *
1293     * @param string $m
1294     * @param array $hash
1295     * @return string
1296     */
1297    private static function sha512($m, $hash)
1298    {
1299        static $k;
1300
1301        if (!isset($k)) {
1302            // Initialize table of round constants
1303            // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
1304            $k = [
1305                '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
1306                '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
1307                'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
1308                '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
1309                'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
1310                '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
1311                '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
1312                'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
1313                '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
1314                '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
1315                'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
1316                'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
1317                '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
1318                '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
1319                '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
1320                '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
1321                'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
1322                '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
1323                '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
1324                '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
1325            ];
1326
1327            for ($i = 0; $i < 80; $i++) {
1328                $k[$i] = new BigInteger($k[$i], 16);
1329            }
1330        }
1331
1332        // Pre-processing
1333        $length = strlen($m);
1334        // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
1335        $m .= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
1336        $m[$length] = chr(0x80);
1337        // we don't support hashing strings 512MB long
1338        $m .= pack('N4', 0, 0, 0, $length << 3);
1339
1340        // Process the message in successive 1024-bit chunks
1341        $chunks = str_split($m, 128);
1342        foreach ($chunks as $chunk) {
1343            $w = [];
1344            for ($i = 0; $i < 16; $i++) {
1345                $temp = new BigInteger(Strings::shift($chunk, 8), 256);
1346                $temp->setPrecision(64);
1347                $w[] = $temp;
1348            }
1349
1350            // Extend the sixteen 32-bit words into eighty 32-bit words
1351            for ($i = 16; $i < 80; $i++) {
1352                $temp = [
1353                          $w[$i - 15]->bitwise_rightRotate(1),
1354                          $w[$i - 15]->bitwise_rightRotate(8),
1355                          $w[$i - 15]->bitwise_rightShift(7)
1356                ];
1357                $s0 = $temp[0]->bitwise_xor($temp[1]);
1358                $s0 = $s0->bitwise_xor($temp[2]);
1359                $temp = [
1360                          $w[$i - 2]->bitwise_rightRotate(19),
1361                          $w[$i - 2]->bitwise_rightRotate(61),
1362                          $w[$i - 2]->bitwise_rightShift(6)
1363                ];
1364                $s1 = $temp[0]->bitwise_xor($temp[1]);
1365                $s1 = $s1->bitwise_xor($temp[2]);
1366                $w[$i] = clone $w[$i - 16];
1367                $w[$i] = $w[$i]->add($s0);
1368                $w[$i] = $w[$i]->add($w[$i - 7]);
1369                $w[$i] = $w[$i]->add($s1);
1370            }
1371
1372            // Initialize hash value for this chunk
1373            $a = clone $hash[0];
1374            $b = clone $hash[1];
1375            $c = clone $hash[2];
1376            $d = clone $hash[3];
1377            $e = clone $hash[4];
1378            $f = clone $hash[5];
1379            $g = clone $hash[6];
1380            $h = clone $hash[7];
1381
1382            // Main loop
1383            for ($i = 0; $i < 80; $i++) {
1384                $temp = [
1385                    $a->bitwise_rightRotate(28),
1386                    $a->bitwise_rightRotate(34),
1387                    $a->bitwise_rightRotate(39)
1388                ];
1389                $s0 = $temp[0]->bitwise_xor($temp[1]);
1390                $s0 = $s0->bitwise_xor($temp[2]);
1391                $temp = [
1392                    $a->bitwise_and($b),
1393                    $a->bitwise_and($c),
1394                    $b->bitwise_and($c)
1395                ];
1396                $maj = $temp[0]->bitwise_xor($temp[1]);
1397                $maj = $maj->bitwise_xor($temp[2]);
1398                $t2 = $s0->add($maj);
1399
1400                $temp = [
1401                    $e->bitwise_rightRotate(14),
1402                    $e->bitwise_rightRotate(18),
1403                    $e->bitwise_rightRotate(41)
1404                ];
1405                $s1 = $temp[0]->bitwise_xor($temp[1]);
1406                $s1 = $s1->bitwise_xor($temp[2]);
1407                $temp = [
1408                    $e->bitwise_and($f),
1409                    $g->bitwise_and($e->bitwise_not())
1410                ];
1411                $ch = $temp[0]->bitwise_xor($temp[1]);
1412                $t1 = $h->add($s1);
1413                $t1 = $t1->add($ch);
1414                $t1 = $t1->add($k[$i]);
1415                $t1 = $t1->add($w[$i]);
1416
1417                $h = clone $g;
1418                $g = clone $f;
1419                $f = clone $e;
1420                $e = $d->add($t1);
1421                $d = clone $c;
1422                $c = clone $b;
1423                $b = clone $a;
1424                $a = $t1->add($t2);
1425            }
1426
1427            // Add this chunk's hash to result so far
1428            $hash = [
1429                $hash[0]->add($a),
1430                $hash[1]->add($b),
1431                $hash[2]->add($c),
1432                $hash[3]->add($d),
1433                $hash[4]->add($e),
1434                $hash[5]->add($f),
1435                $hash[6]->add($g),
1436                $hash[7]->add($h)
1437            ];
1438        }
1439
1440        // Produce the final hash value (big-endian)
1441        // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs.  as such, we trim the output here)
1442        $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
1443                $hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes();
1444
1445        return $temp;
1446    }
1447
1448    /**
1449     *  __toString() magic method
1450     */
1451    public function __toString()
1452    {
1453        return $this->getHash();
1454    }
1455}
1456