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