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