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