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 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 $oldHash = $this->hashParam; 289 $this->hashParam = $hash = strtolower($hash); 290 switch ($hash) { 291 case 'umac-32': 292 case 'umac-64': 293 case 'umac-96': 294 case 'umac-128': 295 if ($oldHash != $this->hashParam) { 296 $this->recomputeAESKey = true; 297 } 298 $this->blockSize = 128; 299 $this->length = abs(substr($hash, -3)) >> 3; 300 $this->algo = 'umac'; 301 return; 302 case 'md2-96': 303 case 'md5-96': 304 case 'sha1-96': 305 case 'sha224-96': 306 case 'sha256-96': 307 case 'sha384-96': 308 case 'sha512-96': 309 case 'sha512/224-96': 310 case 'sha512/256-96': 311 $hash = substr($hash, 0, -3); 312 $this->length = 12; // 96 / 8 = 12 313 break; 314 case 'md2': 315 case 'md5': 316 $this->length = 16; 317 break; 318 case 'sha1': 319 $this->length = 20; 320 break; 321 case 'sha224': 322 case 'sha512/224': 323 case 'sha3-224': 324 $this->length = 28; 325 break; 326 case 'keccak256': 327 $this->paddingType = self::PADDING_KECCAK; 328 // fall-through 329 case 'sha256': 330 case 'sha512/256': 331 case 'sha3-256': 332 $this->length = 32; 333 break; 334 case 'sha384': 335 case 'sha3-384': 336 $this->length = 48; 337 break; 338 case 'sha512': 339 case 'sha3-512': 340 $this->length = 64; 341 break; 342 default: 343 if (preg_match('#^(shake(?:128|256))-(\d+)$#', $hash, $matches)) { 344 $this->paddingType = self::PADDING_SHAKE; 345 $hash = $matches[1]; 346 $this->length = $matches[2] >> 3; 347 } else { 348 throw new UnsupportedAlgorithmException( 349 "$hash is not a supported algorithm" 350 ); 351 } 352 } 353 354 switch ($hash) { 355 case 'md2': 356 case 'md2-96': 357 $this->blockSize = 128; 358 break; 359 case 'md5-96': 360 case 'sha1-96': 361 case 'sha224-96': 362 case 'sha256-96': 363 case 'md5': 364 case 'sha1': 365 case 'sha224': 366 case 'sha256': 367 $this->blockSize = 512; 368 break; 369 case 'sha3-224': 370 $this->blockSize = 1152; // 1600 - 2*224 371 break; 372 case 'sha3-256': 373 case 'shake256': 374 case 'keccak256': 375 $this->blockSize = 1088; // 1600 - 2*256 376 break; 377 case 'sha3-384': 378 $this->blockSize = 832; // 1600 - 2*384 379 break; 380 case 'sha3-512': 381 $this->blockSize = 576; // 1600 - 2*512 382 break; 383 case 'shake128': 384 $this->blockSize = 1344; // 1600 - 2*128 385 break; 386 default: 387 $this->blockSize = 1024; 388 } 389 390 if (in_array(substr($hash, 0, 5), ['sha3-', 'shake', 'kecca'])) { 391 // PHP 7.1.0 introduced support for "SHA3 fixed mode algorithms": 392 // http://php.net/ChangeLog-7.php#7.1.0 393 if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0, 5) != 'sha3-') { 394 //preg_match('#(\d+)$#', $hash, $matches); 395 //$this->parameters['capacity'] = 2 * $matches[1]; // 1600 - $this->blockSize 396 //$this->parameters['rate'] = 1600 - $this->parameters['capacity']; // == $this->blockSize 397 if (!$this->paddingType) { 398 $this->paddingType = self::PADDING_SHA3; 399 } 400 $this->parameters = [ 401 'capacity' => 1600 - $this->blockSize, 402 'rate' => $this->blockSize, 403 'length' => $this->length, 404 'padding' => $this->paddingType 405 ]; 406 $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha3_64' : 'sha3_32']; 407 } 408 } 409 410 if ($hash == 'sha512/224' || $hash == 'sha512/256') { 411 // PHP 7.1.0 introduced sha512/224 and sha512/256 support: 412 // http://php.net/ChangeLog-7.php#7.1.0 413 if (version_compare(PHP_VERSION, '7.1.0') < 0) { 414 // from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24 415 $initial = $hash == 'sha512/256' ? 416 [ 417 '22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD', 418 '96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2' 419 ] : 420 [ 421 '8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF', 422 '0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1' 423 ]; 424 for ($i = 0; $i < 8; $i++) { 425 if (PHP_INT_SIZE == 8) { 426 list(, $initial[$i]) = unpack('J', pack('H*', $initial[$i])); 427 } else { 428 $initial[$i] = new BigInteger($initial[$i], 16); 429 $initial[$i]->setPrecision(64); 430 } 431 } 432 433 $this->parameters = compact('initial'); 434 435 $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha512_64' : 'sha512']; 436 } 437 } 438 439 if (is_array($hash)) { 440 $b = $this->blockSize >> 3; 441 $this->ipad = str_repeat(chr(0x36), $b); 442 $this->opad = str_repeat(chr(0x5C), $b); 443 } 444 445 $this->algo = $hash; 446 447 $this->computeKey(); 448 } 449 450 /** 451 * KDF: Key-Derivation Function 452 * 453 * The key-derivation function generates pseudorandom bits used to key the hash functions. 454 * 455 * @param int $index a non-negative integer less than 2^64 456 * @param int $numbytes a non-negative integer less than 2^64 457 * @return string string of length numbytes bytes 458 */ 459 private function kdf($index, $numbytes) 460 { 461 $this->c->setIV(pack('N4', 0, $index, 0, 1)); 462 463 return $this->c->encrypt(str_repeat("\0", $numbytes)); 464 } 465 466 /** 467 * PDF Algorithm 468 * 469 * @return string string of length taglen bytes. 470 */ 471 private function pdf() 472 { 473 $k = $this->key; 474 $nonce = $this->nonce; 475 $taglen = $this->length; 476 477 // 478 // Extract and zero low bit(s) of Nonce if needed 479 // 480 if ($taglen <= 8) { 481 $last = strlen($nonce) - 1; 482 $mask = $taglen == 4 ? "\3" : "\1"; 483 $index = $nonce[$last] & $mask; 484 $nonce[$last] = $nonce[$last] ^ $index; 485 } 486 487 // 488 // Make Nonce BLOCKLEN bytes by appending zeroes if needed 489 // 490 $nonce = str_pad($nonce, 16, "\0"); 491 492 // 493 // Generate subkey, encipher and extract indexed substring 494 // 495 $kp = $this->kdf(0, 16); 496 $c = new AES('ctr'); 497 $c->disablePadding(); 498 $c->setKey($kp); 499 $c->setIV($nonce); 500 $t = $c->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); 501 502 // we could use ord() but per https://paragonie.com/blog/2016/06/constant-time-encoding-boring-cryptography-rfc-4648-and-you 503 // unpack() doesn't leak timing info 504 return $taglen <= 8 ? 505 substr($t, unpack('C', $index)[1] * $taglen, $taglen) : 506 substr($t, 0, $taglen); 507 } 508 509 /** 510 * UHASH Algorithm 511 * 512 * @param string $m string of length less than 2^67 bits. 513 * @param int $taglen the integer 4, 8, 12 or 16. 514 * @return string string of length taglen bytes. 515 */ 516 private function uhash($m, $taglen) 517 { 518 // 519 // One internal iteration per 4 bytes of output 520 // 521 $iters = $taglen >> 2; 522 523 // 524 // Define total key needed for all iterations using KDF. 525 // L1Key reuses most key material between iterations. 526 // 527 //$L1Key = $this->kdf(1, 1024 + ($iters - 1) * 16); 528 $L1Key = $this->kdf(1, (1024 + ($iters - 1)) * 16); 529 $L2Key = $this->kdf(2, $iters * 24); 530 $L3Key1 = $this->kdf(3, $iters * 64); 531 $L3Key2 = $this->kdf(4, $iters * 4); 532 533 // 534 // For each iteration, extract key and do three-layer hash. 535 // If bytelength(M) <= 1024, then skip L2-HASH. 536 // 537 $y = ''; 538 for ($i = 0; $i < $iters; $i++) { 539 $L1Key_i = substr($L1Key, $i * 16, 1024); 540 $L2Key_i = substr($L2Key, $i * 24, 24); 541 $L3Key1_i = substr($L3Key1, $i * 64, 64); 542 $L3Key2_i = substr($L3Key2, $i * 4, 4); 543 544 $a = self::L1Hash($L1Key_i, $m); 545 $b = strlen($m) <= 1024 ? "\0\0\0\0\0\0\0\0$a" : self::L2Hash($L2Key_i, $a); 546 $c = self::L3Hash($L3Key1_i, $L3Key2_i, $b); 547 $y .= $c; 548 } 549 550 return $y; 551 } 552 553 /** 554 * L1-HASH Algorithm 555 * 556 * The first-layer hash breaks the message into 1024-byte chunks and 557 * hashes each with a function called NH. Concatenating the results 558 * forms a string, which is up to 128 times shorter than the original. 559 * 560 * @param string $k string of length 1024 bytes. 561 * @param string $m string of length less than 2^67 bits. 562 * @return string string of length (8 * ceil(bitlength(M)/8192)) bytes. 563 */ 564 private static function L1Hash($k, $m) 565 { 566 // 567 // Break M into 1024 byte chunks (final chunk may be shorter) 568 // 569 $m = str_split($m, 1024); 570 571 // 572 // For each chunk, except the last: endian-adjust, NH hash 573 // and add bit-length. Use results to build Y. 574 // 575 $length = 1024 * 8; 576 $y = ''; 577 578 for ($i = 0; $i < count($m) - 1; $i++) { 579 $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP 580 $y .= PHP_INT_SIZE == 8 ? 581 static::nh64($k, $m[$i], $length) : 582 static::nh32($k, $m[$i], $length); 583 } 584 585 // 586 // For the last chunk: pad to 32-byte boundary, endian-adjust, 587 // NH hash and add bit-length. Concatenate the result to Y. 588 // 589 $length = count($m) ? strlen($m[$i]) : 0; 590 $pad = 32 - ($length % 32); 591 $pad = max(32, $length + $pad % 32); 592 $m[$i] = str_pad(isset($m[$i]) ? $m[$i] : '', $pad, "\0"); // zeropad 593 $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP 594 595 $y .= PHP_INT_SIZE == 8 ? 596 static::nh64($k, $m[$i], $length * 8) : 597 static::nh32($k, $m[$i], $length * 8); 598 599 return $y; 600 } 601 602 /** 603 * 32-bit safe 64-bit Multiply with 2x 32-bit ints 604 * 605 * @param int $x 606 * @param int $y 607 * @return string $x * $y 608 */ 609 private static function mul32_64($x, $y) 610 { 611 // see mul64() for a more detailed explanation of how this works 612 613 $x1 = ($x >> 16) & 0xFFFF; 614 $x0 = $x & 0xFFFF; 615 616 $y1 = ($y >> 16) & 0xFFFF; 617 $y0 = $y & 0xFFFF; 618 619 // the following 3x lines will possibly yield floats 620 $z2 = $x1 * $y1; 621 $z0 = $x0 * $y0; 622 $z1 = $x1 * $y0 + $x0 * $y1; 623 624 $a = intval(fmod($z0, 65536)); 625 $b = intval($z0 / 65536) + intval(fmod($z1, 65536)); 626 $c = intval($z1 / 65536) + intval(fmod($z2, 65536)) + intval($b / 65536); 627 $b = intval(fmod($b, 65536)); 628 $d = intval($z2 / 65536) + intval($c / 65536); 629 $c = intval(fmod($c, 65536)); 630 $d = intval(fmod($d, 65536)); 631 632 return pack('n4', $d, $c, $b, $a); 633 } 634 635 /** 636 * 32-bit safe 64-bit Addition with 2x 64-bit strings 637 * 638 * @param int $x 639 * @param int $y 640 * @return int $x * $y 641 */ 642 private static function add32_64($x, $y) 643 { 644 list(, $x1, $x2, $x3, $x4) = unpack('n4', $x); 645 list(, $y1, $y2, $y3, $y4) = unpack('n4', $y); 646 $a = $x4 + $y4; 647 $b = $x3 + $y3 + ($a >> 16); 648 $c = $x2 + $y2 + ($b >> 16); 649 $d = $x1 + $y1 + ($c >> 16); 650 return pack('n4', $d, $c, $b, $a); 651 } 652 653 /** 654 * 32-bit safe 32-bit Addition with 2x 32-bit strings 655 * 656 * @param int $x 657 * @param int $y 658 * @return int $x * $y 659 */ 660 private static function add32($x, $y) 661 { 662 // see add64() for a more detailed explanation of how this works 663 664 $x1 = $x & 0xFFFF; 665 $x2 = ($x >> 16) & 0xFFFF; 666 $y1 = $y & 0xFFFF; 667 $y2 = ($y >> 16) & 0xFFFF; 668 669 $a = $x1 + $y1; 670 $b = ($x2 + $y2 + ($a >> 16)) << 16; 671 $a &= 0xFFFF; 672 673 return $a | $b; 674 } 675 676 /** 677 * NH Algorithm / 32-bit safe 678 * 679 * @param string $k string of length 1024 bytes. 680 * @param string $m string with length divisible by 32 bytes. 681 * @return string string of length 8 bytes. 682 */ 683 private static function nh32($k, $m, $length) 684 { 685 // 686 // Break M and K into 4-byte chunks 687 // 688 $k = unpack('N*', $k); 689 $m = unpack('N*', $m); 690 $t = count($m); 691 692 // 693 // Perform NH hash on the chunks, pairing words for multiplication 694 // which are 4 apart to accommodate vector-parallelism. 695 // 696 $i = 1; 697 $y = "\0\0\0\0\0\0\0\0"; 698 while ($i <= $t) { 699 $temp = self::add32($m[$i], $k[$i]); 700 $temp2 = self::add32($m[$i + 4], $k[$i + 4]); 701 $y = self::add32_64($y, self::mul32_64($temp, $temp2)); 702 703 $temp = self::add32($m[$i + 1], $k[$i + 1]); 704 $temp2 = self::add32($m[$i + 5], $k[$i + 5]); 705 $y = self::add32_64($y, self::mul32_64($temp, $temp2)); 706 707 $temp = self::add32($m[$i + 2], $k[$i + 2]); 708 $temp2 = self::add32($m[$i + 6], $k[$i + 6]); 709 $y = self::add32_64($y, self::mul32_64($temp, $temp2)); 710 711 $temp = self::add32($m[$i + 3], $k[$i + 3]); 712 $temp2 = self::add32($m[$i + 7], $k[$i + 7]); 713 $y = self::add32_64($y, self::mul32_64($temp, $temp2)); 714 715 $i += 8; 716 } 717 718 return self::add32_64($y, pack('N2', 0, $length)); 719 } 720 721 /** 722 * 64-bit Multiply with 2x 32-bit ints 723 * 724 * @param int $x 725 * @param int $y 726 * @return int $x * $y 727 */ 728 private static function mul64($x, $y) 729 { 730 // since PHP doesn't implement unsigned integers we'll implement them with signed integers 731 // to do this we'll use karatsuba multiplication 732 733 $x1 = $x >> 16; 734 $x0 = $x & 0xFFFF; 735 736 $y1 = $y >> 16; 737 $y0 = $y & 0xFFFF; 738 739 $z2 = $x1 * $y1; // up to 32 bits long 740 $z0 = $x0 * $y0; // up to 32 bits long 741 $z1 = $x1 * $y0 + $x0 * $y1; // up to 33 bit long 742 // normally karatsuba multiplication calculates $z1 thusly: 743 //$z1 = ($x1 + $x0) * ($y0 + $y1) - $z2 - $z0; 744 // the idea being to eliminate one extra multiplication. for arbitrary precision math that makes sense 745 // but not for this purpose 746 747 // at this point karatsuba would normally return this: 748 //return ($z2 << 64) + ($z1 << 32) + $z0; 749 // the problem is that the output could be out of range for signed 64-bit ints, 750 // which would cause PHP to switch to floats, which would risk losing the lower few bits 751 // as such we'll OR 4x 16-bit blocks together like so: 752 /* 753 ........ | ........ | ........ | ........ 754 upper $z2 | lower $z2 | lower $z1 | lower $z0 755 | +upper $z1 | +upper $z0 | 756 + $carry | + $carry | | 757 */ 758 // technically upper $z1 is 17 bit - not 16 - but the most significant digit of that will 759 // just get added to $carry 760 761 $a = $z0 & 0xFFFF; 762 $b = ($z0 >> 16) + ($z1 & 0xFFFF); 763 $c = ($z1 >> 16) + ($z2 & 0xFFFF) + ($b >> 16); 764 $b = ($b & 0xFFFF) << 16; 765 $d = ($z2 >> 16) + ($c >> 16); 766 $c = ($c & 0xFFFF) << 32; 767 $d = ($d & 0xFFFF) << 48; 768 769 return $a | $b | $c | $d; 770 } 771 772 /** 773 * 64-bit Addition with 2x 64-bit ints 774 * 775 * @param int $x 776 * @param int $y 777 * @return int $x + $y 778 */ 779 private static function add64($x, $y) 780 { 781 // doing $x + $y risks returning a result that's out of range for signed 64-bit ints 782 // in that event PHP would convert the result to a float and precision would be lost 783 // so we'll just add 2x 32-bit ints together like so: 784 /* 785 ........ | ........ 786 upper $x | lower $x 787 +upper $y |+lower $y 788 + $carry | 789 */ 790 $x1 = $x & 0xFFFFFFFF; 791 $x2 = ($x >> 32) & 0xFFFFFFFF; 792 $y1 = $y & 0xFFFFFFFF; 793 $y2 = ($y >> 32) & 0xFFFFFFFF; 794 795 $a = $x1 + $y1; 796 $b = ($x2 + $y2 + ($a >> 32)) << 32; 797 $a &= 0xFFFFFFFF; 798 799 return $a | $b; 800 } 801 802 /** 803 * NH Algorithm / 64-bit safe 804 * 805 * @param string $k string of length 1024 bytes. 806 * @param string $m string with length divisible by 32 bytes. 807 * @return string string of length 8 bytes. 808 */ 809 private static function nh64($k, $m, $length) 810 { 811 // 812 // Break M and K into 4-byte chunks 813 // 814 $k = unpack('N*', $k); 815 $m = unpack('N*', $m); 816 $t = count($m); 817 818 // 819 // Perform NH hash on the chunks, pairing words for multiplication 820 // which are 4 apart to accommodate vector-parallelism. 821 // 822 $i = 1; 823 $y = 0; 824 while ($i <= $t) { 825 $temp = ($m[$i] + $k[$i]) & 0xFFFFFFFF; 826 $temp2 = ($m[$i + 4] + $k[$i + 4]) & 0xFFFFFFFF; 827 $y = self::add64($y, self::mul64($temp, $temp2)); 828 829 $temp = ($m[$i + 1] + $k[$i + 1]) & 0xFFFFFFFF; 830 $temp2 = ($m[$i + 5] + $k[$i + 5]) & 0xFFFFFFFF; 831 $y = self::add64($y, self::mul64($temp, $temp2)); 832 833 $temp = ($m[$i + 2] + $k[$i + 2]) & 0xFFFFFFFF; 834 $temp2 = ($m[$i + 6] + $k[$i + 6]) & 0xFFFFFFFF; 835 $y = self::add64($y, self::mul64($temp, $temp2)); 836 837 $temp = ($m[$i + 3] + $k[$i + 3]) & 0xFFFFFFFF; 838 $temp2 = ($m[$i + 7] + $k[$i + 7]) & 0xFFFFFFFF; 839 $y = self::add64($y, self::mul64($temp, $temp2)); 840 841 $i += 8; 842 } 843 844 return pack('J', self::add64($y, $length)); 845 } 846 847 /** 848 * L2-HASH: Second-Layer Hash 849 * 850 * The second-layer rehashes the L1-HASH output using a polynomial hash 851 * called POLY. If the L1-HASH output is long, then POLY is called once 852 * on a prefix of the L1-HASH output and called using different settings 853 * on the remainder. (This two-step hashing of the L1-HASH output is 854 * needed only if the message length is greater than 16 megabytes.) 855 * Careful implementation of POLY is necessary to avoid a possible 856 * timing attack (see Section 6.6 for more information). 857 * 858 * @param string $k string of length 24 bytes. 859 * @param string $m string of length less than 2^64 bytes. 860 * @return string string of length 16 bytes. 861 */ 862 private static function L2Hash($k, $m) 863 { 864 // 865 // Extract keys and restrict to special key-sets 866 // 867 $k64 = $k & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; 868 $k64 = new BigInteger($k64, 256); 869 $k128 = substr($k, 8) & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; 870 $k128 = new BigInteger($k128, 256); 871 872 // 873 // If M is no more than 2^17 bytes, hash under 64-bit prime, 874 // otherwise, hash first 2^17 bytes under 64-bit prime and 875 // remainder under 128-bit prime. 876 // 877 if (strlen($m) <= 0x20000) { // 2^14 64-bit words 878 $y = self::poly(64, self::$maxwordrange64, $k64, $m); 879 } else { 880 $m_1 = substr($m, 0, 0x20000); // 1 << 17 881 $m_2 = substr($m, 0x20000) . "\x80"; 882 $length = strlen($m_2); 883 $pad = 16 - ($length % 16); 884 $pad %= 16; 885 $m_2 = str_pad($m_2, $length + $pad, "\0"); // zeropad 886 $y = self::poly(64, self::$maxwordrange64, $k64, $m_1); 887 $y = str_pad($y, 16, "\0", STR_PAD_LEFT); 888 $y = self::poly(128, self::$maxwordrange128, $k128, $y . $m_2); 889 } 890 891 return str_pad($y, 16, "\0", STR_PAD_LEFT); 892 } 893 894 /** 895 * POLY Algorithm 896 * 897 * @param int $wordbits the integer 64 or 128. 898 * @param BigInteger $maxwordrange positive integer less than 2^wordbits. 899 * @param BigInteger $k integer in the range 0 ... prime(wordbits) - 1. 900 * @param string $m string with length divisible by (wordbits / 8) bytes. 901 * @return integer in the range 0 ... prime(wordbits) - 1. 902 */ 903 private static function poly($wordbits, $maxwordrange, $k, $m) 904 { 905 // 906 // Define constants used for fixing out-of-range words 907 // 908 $wordbytes = $wordbits >> 3; 909 if ($wordbits == 128) { 910 $factory = self::$factory128; 911 $offset = self::$offset128; 912 $marker = self::$marker128; 913 } else { 914 $factory = self::$factory64; 915 $offset = self::$offset64; 916 $marker = self::$marker64; 917 } 918 919 $k = $factory->newInteger($k); 920 921 // 922 // Break M into chunks of length wordbytes bytes 923 // 924 $m_i = str_split($m, $wordbytes); 925 926 // 927 // Each input word m is compared with maxwordrange. If not smaller 928 // then 'marker' and (m - offset), both in range, are hashed. 929 // 930 $y = $factory->newInteger(new BigInteger(1)); 931 foreach ($m_i as $m) { 932 $m = $factory->newInteger(new BigInteger($m, 256)); 933 if ($m->compare($maxwordrange) >= 0) { 934 $y = $k->multiply($y)->add($marker); 935 $y = $k->multiply($y)->add($m->subtract($offset)); 936 } else { 937 $y = $k->multiply($y)->add($m); 938 } 939 } 940 941 return $y->toBytes(); 942 } 943 944 /** 945 * L3-HASH: Third-Layer Hash 946 * 947 * The output from L2-HASH is 16 bytes long. This final hash function 948 * hashes the 16-byte string to a fixed length of 4 bytes. 949 * 950 * @param string $k1 string of length 64 bytes. 951 * @param string $k2 string of length 4 bytes. 952 * @param string $m string of length 16 bytes. 953 * @return string string of length 4 bytes. 954 */ 955 private static function L3Hash($k1, $k2, $m) 956 { 957 $factory = self::$factory36; 958 959 $y = $factory->newInteger(new BigInteger()); 960 for ($i = 0; $i < 8; $i++) { 961 $m_i = $factory->newInteger(new BigInteger(substr($m, 2 * $i, 2), 256)); 962 $k_i = $factory->newInteger(new BigInteger(substr($k1, 8 * $i, 8), 256)); 963 $y = $y->add($m_i->multiply($k_i)); 964 } 965 $y = str_pad(substr($y->toBytes(), -4), 4, "\0", STR_PAD_LEFT); 966 $y = $y ^ $k2; 967 968 return $y; 969 } 970 971 /** 972 * Compute the Hash / HMAC / UMAC. 973 * 974 * @param string $text 975 * @return string 976 */ 977 public function hash($text) 978 { 979 $algo = $this->algo; 980 if ($algo == 'umac') { 981 if ($this->recomputeAESKey) { 982 if (!is_string($this->nonce)) { 983 throw new InsufficientSetupException('No nonce has been set'); 984 } 985 if (!is_string($this->key)) { 986 throw new InsufficientSetupException('No key has been set'); 987 } 988 if (strlen($this->key) != 16) { 989 throw new \LengthException('Key must be 16 bytes long'); 990 } 991 992 if (!isset(self::$maxwordrange64)) { 993 $one = new BigInteger(1); 994 995 $prime36 = new BigInteger("\x00\x00\x00\x0F\xFF\xFF\xFF\xFB", 256); 996 self::$factory36 = new PrimeField($prime36); 997 998 $prime64 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC5", 256); 999 self::$factory64 = new PrimeField($prime64); 1000 1001 $prime128 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x61", 256); 1002 self::$factory128 = new PrimeField($prime128); 1003 1004 self::$offset64 = new BigInteger("\1\0\0\0\0\0\0\0\0", 256); 1005 self::$offset64 = self::$factory64->newInteger(self::$offset64->subtract($prime64)); 1006 self::$offset128 = new BigInteger("\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 256); 1007 self::$offset128 = self::$factory128->newInteger(self::$offset128->subtract($prime128)); 1008 1009 self::$marker64 = self::$factory64->newInteger($prime64->subtract($one)); 1010 self::$marker128 = self::$factory128->newInteger($prime128->subtract($one)); 1011 1012 $maxwordrange64 = $one->bitwise_leftShift(64)->subtract($one->bitwise_leftShift(32)); 1013 self::$maxwordrange64 = self::$factory64->newInteger($maxwordrange64); 1014 1015 $maxwordrange128 = $one->bitwise_leftShift(128)->subtract($one->bitwise_leftShift(96)); 1016 self::$maxwordrange128 = self::$factory128->newInteger($maxwordrange128); 1017 } 1018 1019 $this->c = new AES('ctr'); 1020 $this->c->disablePadding(); 1021 $this->c->setKey($this->key); 1022 1023 $this->pad = $this->pdf(); 1024 1025 $this->recomputeAESKey = false; 1026 } 1027 1028 $hashedmessage = $this->uhash($text, $this->length); 1029 return $hashedmessage ^ $this->pad; 1030 } 1031 1032 if (is_array($algo)) { 1033 if (empty($this->key) || !is_string($this->key)) { 1034 return substr($algo($text, ...array_values($this->parameters)), 0, $this->length); 1035 } 1036 1037 // SHA3 HMACs are discussed at https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=30 1038 1039 $key = str_pad($this->computedKey, $b, chr(0)); 1040 $temp = $this->ipad ^ $key; 1041 $temp .= $text; 1042 $temp = substr($algo($temp, ...array_values($this->parameters)), 0, $this->length); 1043 $output = $this->opad ^ $key; 1044 $output .= $temp; 1045 $output = $algo($output, ...array_values($this->parameters)); 1046 1047 return substr($output, 0, $this->length); 1048 } 1049 1050 $output = !empty($this->key) || is_string($this->key) ? 1051 hash_hmac($algo, $text, $this->computedKey, true) : 1052 hash($algo, $text, true); 1053 1054 return strlen($output) > $this->length 1055 ? substr($output, 0, $this->length) 1056 : $output; 1057 } 1058 1059 /** 1060 * Returns the hash length (in bits) 1061 * 1062 * @return int 1063 */ 1064 public function getLength() 1065 { 1066 return $this->length << 3; 1067 } 1068 1069 /** 1070 * Returns the hash length (in bytes) 1071 * 1072 * @return int 1073 */ 1074 public function getLengthInBytes() 1075 { 1076 return $this->length; 1077 } 1078 1079 /** 1080 * Returns the block length (in bits) 1081 * 1082 * @return int 1083 */ 1084 public function getBlockLength() 1085 { 1086 return $this->blockSize; 1087 } 1088 1089 /** 1090 * Returns the block length (in bytes) 1091 * 1092 * @return int 1093 */ 1094 public function getBlockLengthInBytes() 1095 { 1096 return $this->blockSize >> 3; 1097 } 1098 1099 /** 1100 * Pads SHA3 based on the mode 1101 * 1102 * @param int $padLength 1103 * @param int $padType 1104 * @return string 1105 */ 1106 private static function sha3_pad($padLength, $padType) 1107 { 1108 switch ($padType) { 1109 case self::PADDING_KECCAK: 1110 $temp = chr(0x01) . str_repeat("\0", $padLength - 1); 1111 $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); 1112 return $temp; 1113 case self::PADDING_SHAKE: 1114 $temp = chr(0x1F) . str_repeat("\0", $padLength - 1); 1115 $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); 1116 return $temp; 1117 //case self::PADDING_SHA3: 1118 default: 1119 // from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=36 1120 return $padLength == 1 ? chr(0x86) : chr(0x06) . str_repeat("\0", $padLength - 2) . chr(0x80); 1121 } 1122 } 1123 1124 /** 1125 * Pure-PHP 32-bit implementation of SHA3 1126 * 1127 * Whereas BigInteger.php's 32-bit engine works on PHP 64-bit this 32-bit implementation 1128 * of SHA3 will *not* work on PHP 64-bit. This is because this implementation 1129 * employees bitwise NOTs and bitwise left shifts. And the round constants only work 1130 * on 32-bit PHP. eg. dechex(-2147483648) returns 80000000 on 32-bit PHP and 1131 * FFFFFFFF80000000 on 64-bit PHP. Sure, we could do bitwise ANDs but that would slow 1132 * things down. 1133 * 1134 * SHA512 requires BigInteger to simulate 64-bit unsigned integers because SHA2 employees 1135 * addition whereas SHA3 just employees bitwise operators. PHP64 only supports signed 1136 * 64-bit integers, which complicates addition, whereas that limitation isn't an issue 1137 * for SHA3. 1138 * 1139 * In https://ws680.nist.gov/publication/get_pdf.cfm?pub_id=919061#page=16 KECCAK[C] is 1140 * defined as "the KECCAK instance with KECCAK-f[1600] as the underlying permutation and 1141 * capacity c". This is relevant because, altho the KECCAK standard defines a mode 1142 * (KECCAK-f[800]) designed for 32-bit machines that mode is incompatible with SHA3 1143 * 1144 * @param string $p 1145 * @param int $c 1146 * @param int $r 1147 * @param int $d 1148 * @param int $padType 1149 */ 1150 private static function sha3_32($p, $c, $r, $d, $padType) 1151 { 1152 $block_size = $r >> 3; 1153 $padLength = $block_size - (strlen($p) % $block_size); 1154 $num_ints = $block_size >> 2; 1155 1156 $p .= static::sha3_pad($padLength, $padType); 1157 1158 $n = strlen($p) / $r; // number of blocks 1159 1160 $s = [ 1161 [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], 1162 [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], 1163 [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], 1164 [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], 1165 [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] 1166 ]; 1167 1168 $p = str_split($p, $block_size); 1169 1170 foreach ($p as $pi) { 1171 $pi = unpack('V*', $pi); 1172 $x = $y = 0; 1173 for ($i = 1; $i <= $num_ints; $i += 2) { 1174 $s[$x][$y][0] ^= $pi[$i + 1]; 1175 $s[$x][$y][1] ^= $pi[$i]; 1176 if (++$y == 5) { 1177 $y = 0; 1178 $x++; 1179 } 1180 } 1181 static::processSHA3Block32($s); 1182 } 1183 1184 $z = ''; 1185 $i = $j = 0; 1186 while (strlen($z) < $d) { 1187 $z .= pack('V2', $s[$i][$j][1], $s[$i][$j++][0]); 1188 if ($j == 5) { 1189 $j = 0; 1190 $i++; 1191 if ($i == 5) { 1192 $i = 0; 1193 static::processSHA3Block32($s); 1194 } 1195 } 1196 } 1197 1198 return $z; 1199 } 1200 1201 /** 1202 * 32-bit block processing method for SHA3 1203 * 1204 * @param array $s 1205 */ 1206 private static function processSHA3Block32(&$s) 1207 { 1208 static $rotationOffsets = [ 1209 [ 0, 1, 62, 28, 27], 1210 [36, 44, 6, 55, 20], 1211 [ 3, 10, 43, 25, 39], 1212 [41, 45, 15, 21, 8], 1213 [18, 2, 61, 56, 14] 1214 ]; 1215 1216 // the standards give these constants in hexadecimal notation. it's tempting to want to use 1217 // that same notation, here, however, we can't, because 0x80000000, on PHP32, is a positive 1218 // float - not the negative int that we need to be in PHP32. so we use -2147483648 instead 1219 static $roundConstants = [ 1220 [0, 1], 1221 [0, 32898], 1222 [-2147483648, 32906], 1223 [-2147483648, -2147450880], 1224 [0, 32907], 1225 [0, -2147483647], 1226 [-2147483648, -2147450751], 1227 [-2147483648, 32777], 1228 [0, 138], 1229 [0, 136], 1230 [0, -2147450871], 1231 [0, -2147483638], 1232 [0, -2147450741], 1233 [-2147483648, 139], 1234 [-2147483648, 32905], 1235 [-2147483648, 32771], 1236 [-2147483648, 32770], 1237 [-2147483648, 128], 1238 [0, 32778], 1239 [-2147483648, -2147483638], 1240 [-2147483648, -2147450751], 1241 [-2147483648, 32896], 1242 [0, -2147483647], 1243 [-2147483648, -2147450872] 1244 ]; 1245 1246 for ($round = 0; $round < 24; $round++) { 1247 // theta step 1248 $parity = $rotated = []; 1249 for ($i = 0; $i < 5; $i++) { 1250 $parity[] = [ 1251 $s[0][$i][0] ^ $s[1][$i][0] ^ $s[2][$i][0] ^ $s[3][$i][0] ^ $s[4][$i][0], 1252 $s[0][$i][1] ^ $s[1][$i][1] ^ $s[2][$i][1] ^ $s[3][$i][1] ^ $s[4][$i][1] 1253 ]; 1254 $rotated[] = static::rotateLeft32($parity[$i], 1); 1255 } 1256 1257 $temp = [ 1258 [$parity[4][0] ^ $rotated[1][0], $parity[4][1] ^ $rotated[1][1]], 1259 [$parity[0][0] ^ $rotated[2][0], $parity[0][1] ^ $rotated[2][1]], 1260 [$parity[1][0] ^ $rotated[3][0], $parity[1][1] ^ $rotated[3][1]], 1261 [$parity[2][0] ^ $rotated[4][0], $parity[2][1] ^ $rotated[4][1]], 1262 [$parity[3][0] ^ $rotated[0][0], $parity[3][1] ^ $rotated[0][1]] 1263 ]; 1264 for ($i = 0; $i < 5; $i++) { 1265 for ($j = 0; $j < 5; $j++) { 1266 $s[$i][$j][0] ^= $temp[$j][0]; 1267 $s[$i][$j][1] ^= $temp[$j][1]; 1268 } 1269 } 1270 1271 $st = $s; 1272 1273 // rho and pi steps 1274 for ($i = 0; $i < 5; $i++) { 1275 for ($j = 0; $j < 5; $j++) { 1276 $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft32($s[$j][$i], $rotationOffsets[$j][$i]); 1277 } 1278 } 1279 1280 // chi step 1281 for ($i = 0; $i < 5; $i++) { 1282 $s[$i][0] = [ 1283 $st[$i][0][0] ^ (~$st[$i][1][0] & $st[$i][2][0]), 1284 $st[$i][0][1] ^ (~$st[$i][1][1] & $st[$i][2][1]) 1285 ]; 1286 $s[$i][1] = [ 1287 $st[$i][1][0] ^ (~$st[$i][2][0] & $st[$i][3][0]), 1288 $st[$i][1][1] ^ (~$st[$i][2][1] & $st[$i][3][1]) 1289 ]; 1290 $s[$i][2] = [ 1291 $st[$i][2][0] ^ (~$st[$i][3][0] & $st[$i][4][0]), 1292 $st[$i][2][1] ^ (~$st[$i][3][1] & $st[$i][4][1]) 1293 ]; 1294 $s[$i][3] = [ 1295 $st[$i][3][0] ^ (~$st[$i][4][0] & $st[$i][0][0]), 1296 $st[$i][3][1] ^ (~$st[$i][4][1] & $st[$i][0][1]) 1297 ]; 1298 $s[$i][4] = [ 1299 $st[$i][4][0] ^ (~$st[$i][0][0] & $st[$i][1][0]), 1300 $st[$i][4][1] ^ (~$st[$i][0][1] & $st[$i][1][1]) 1301 ]; 1302 } 1303 1304 // iota step 1305 $s[0][0][0] ^= $roundConstants[$round][0]; 1306 $s[0][0][1] ^= $roundConstants[$round][1]; 1307 } 1308 } 1309 1310 /** 1311 * Rotate 32-bit int 1312 * 1313 * @param array $x 1314 * @param int $shift 1315 */ 1316 private static function rotateLeft32($x, $shift) 1317 { 1318 if ($shift < 32) { 1319 list($hi, $lo) = $x; 1320 } else { 1321 $shift -= 32; 1322 list($lo, $hi) = $x; 1323 } 1324 1325 $mask = -1 ^ (-1 << $shift); 1326 return [ 1327 ($hi << $shift) | (($lo >> (32 - $shift)) & $mask), 1328 ($lo << $shift) | (($hi >> (32 - $shift)) & $mask) 1329 ]; 1330 } 1331 1332 /** 1333 * Pure-PHP 64-bit implementation of SHA3 1334 * 1335 * @param string $p 1336 * @param int $c 1337 * @param int $r 1338 * @param int $d 1339 * @param int $padType 1340 */ 1341 private static function sha3_64($p, $c, $r, $d, $padType) 1342 { 1343 $block_size = $r >> 3; 1344 $padLength = $block_size - (strlen($p) % $block_size); 1345 $num_ints = $block_size >> 2; 1346 1347 $p .= static::sha3_pad($padLength, $padType); 1348 1349 $n = strlen($p) / $r; // number of blocks 1350 1351 $s = [ 1352 [0, 0, 0, 0, 0], 1353 [0, 0, 0, 0, 0], 1354 [0, 0, 0, 0, 0], 1355 [0, 0, 0, 0, 0], 1356 [0, 0, 0, 0, 0] 1357 ]; 1358 1359 $p = str_split($p, $block_size); 1360 1361 foreach ($p as $pi) { 1362 $pi = unpack('P*', $pi); 1363 $x = $y = 0; 1364 foreach ($pi as $subpi) { 1365 $s[$x][$y++] ^= $subpi; 1366 if ($y == 5) { 1367 $y = 0; 1368 $x++; 1369 } 1370 } 1371 static::processSHA3Block64($s); 1372 } 1373 1374 $z = ''; 1375 $i = $j = 0; 1376 while (strlen($z) < $d) { 1377 $z .= pack('P', $s[$i][$j++]); 1378 if ($j == 5) { 1379 $j = 0; 1380 $i++; 1381 if ($i == 5) { 1382 $i = 0; 1383 static::processSHA3Block64($s); 1384 } 1385 } 1386 } 1387 1388 return $z; 1389 } 1390 1391 /** 1392 * 64-bit block processing method for SHA3 1393 * 1394 * @param array $s 1395 */ 1396 private static function processSHA3Block64(&$s) 1397 { 1398 static $rotationOffsets = [ 1399 [ 0, 1, 62, 28, 27], 1400 [36, 44, 6, 55, 20], 1401 [ 3, 10, 43, 25, 39], 1402 [41, 45, 15, 21, 8], 1403 [18, 2, 61, 56, 14] 1404 ]; 1405 1406 static $roundConstants = [ 1407 1, 1408 32898, 1409 -9223372036854742902, 1410 -9223372034707259392, 1411 32907, 1412 2147483649, 1413 -9223372034707259263, 1414 -9223372036854743031, 1415 138, 1416 136, 1417 2147516425, 1418 2147483658, 1419 2147516555, 1420 -9223372036854775669, 1421 -9223372036854742903, 1422 -9223372036854743037, 1423 -9223372036854743038, 1424 -9223372036854775680, 1425 32778, 1426 -9223372034707292150, 1427 -9223372034707259263, 1428 -9223372036854742912, 1429 2147483649, 1430 -9223372034707259384 1431 ]; 1432 1433 for ($round = 0; $round < 24; $round++) { 1434 // theta step 1435 $parity = []; 1436 for ($i = 0; $i < 5; $i++) { 1437 $parity[] = $s[0][$i] ^ $s[1][$i] ^ $s[2][$i] ^ $s[3][$i] ^ $s[4][$i]; 1438 } 1439 $temp = [ 1440 $parity[4] ^ static::rotateLeft64($parity[1], 1), 1441 $parity[0] ^ static::rotateLeft64($parity[2], 1), 1442 $parity[1] ^ static::rotateLeft64($parity[3], 1), 1443 $parity[2] ^ static::rotateLeft64($parity[4], 1), 1444 $parity[3] ^ static::rotateLeft64($parity[0], 1) 1445 ]; 1446 for ($i = 0; $i < 5; $i++) { 1447 for ($j = 0; $j < 5; $j++) { 1448 $s[$i][$j] ^= $temp[$j]; 1449 } 1450 } 1451 1452 $st = $s; 1453 1454 // rho and pi steps 1455 for ($i = 0; $i < 5; $i++) { 1456 for ($j = 0; $j < 5; $j++) { 1457 $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft64($s[$j][$i], $rotationOffsets[$j][$i]); 1458 } 1459 } 1460 1461 // chi step 1462 for ($i = 0; $i < 5; $i++) { 1463 $s[$i] = [ 1464 $st[$i][0] ^ (~$st[$i][1] & $st[$i][2]), 1465 $st[$i][1] ^ (~$st[$i][2] & $st[$i][3]), 1466 $st[$i][2] ^ (~$st[$i][3] & $st[$i][4]), 1467 $st[$i][3] ^ (~$st[$i][4] & $st[$i][0]), 1468 $st[$i][4] ^ (~$st[$i][0] & $st[$i][1]) 1469 ]; 1470 } 1471 1472 // iota step 1473 $s[0][0] ^= $roundConstants[$round]; 1474 } 1475 } 1476 1477 /** 1478 * Left rotate 64-bit int 1479 * 1480 * @param int $x 1481 * @param int $shift 1482 */ 1483 private static function rotateLeft64($x, $shift) 1484 { 1485 $mask = -1 ^ (-1 << $shift); 1486 return ($x << $shift) | (($x >> (64 - $shift)) & $mask); 1487 } 1488 1489 /** 1490 * Right rotate 64-bit int 1491 * 1492 * @param int $x 1493 * @param int $shift 1494 */ 1495 private static function rotateRight64($x, $shift) 1496 { 1497 $mask = -1 ^ (-1 << (64 - $shift)); 1498 return (($x >> $shift) & $mask) | ($x << (64 - $shift)); 1499 } 1500 1501 /** 1502 * Pure-PHP implementation of SHA512 1503 * 1504 * @param string $m 1505 * @param array $hash 1506 * @return string 1507 */ 1508 private static function sha512($m, $hash) 1509 { 1510 static $k; 1511 1512 if (!isset($k)) { 1513 // Initialize table of round constants 1514 // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) 1515 $k = [ 1516 '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', 1517 '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', 1518 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', 1519 '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', 1520 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', 1521 '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', 1522 '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', 1523 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', 1524 '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', 1525 '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', 1526 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', 1527 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', 1528 '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', 1529 '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', 1530 '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', 1531 '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', 1532 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', 1533 '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', 1534 '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', 1535 '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' 1536 ]; 1537 1538 for ($i = 0; $i < 80; $i++) { 1539 $k[$i] = new BigInteger($k[$i], 16); 1540 } 1541 } 1542 1543 // Pre-processing 1544 $length = strlen($m); 1545 // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 1546 $m .= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); 1547 $m[$length] = chr(0x80); 1548 // we don't support hashing strings 512MB long 1549 $m .= pack('N4', 0, 0, 0, $length << 3); 1550 1551 // Process the message in successive 1024-bit chunks 1552 $chunks = str_split($m, 128); 1553 foreach ($chunks as $chunk) { 1554 $w = []; 1555 for ($i = 0; $i < 16; $i++) { 1556 $temp = new BigInteger(Strings::shift($chunk, 8), 256); 1557 $temp->setPrecision(64); 1558 $w[] = $temp; 1559 } 1560 1561 // Extend the sixteen 32-bit words into eighty 32-bit words 1562 for ($i = 16; $i < 80; $i++) { 1563 $temp = [ 1564 $w[$i - 15]->bitwise_rightRotate(1), 1565 $w[$i - 15]->bitwise_rightRotate(8), 1566 $w[$i - 15]->bitwise_rightShift(7) 1567 ]; 1568 $s0 = $temp[0]->bitwise_xor($temp[1]); 1569 $s0 = $s0->bitwise_xor($temp[2]); 1570 $temp = [ 1571 $w[$i - 2]->bitwise_rightRotate(19), 1572 $w[$i - 2]->bitwise_rightRotate(61), 1573 $w[$i - 2]->bitwise_rightShift(6) 1574 ]; 1575 $s1 = $temp[0]->bitwise_xor($temp[1]); 1576 $s1 = $s1->bitwise_xor($temp[2]); 1577 $w[$i] = clone $w[$i - 16]; 1578 $w[$i] = $w[$i]->add($s0); 1579 $w[$i] = $w[$i]->add($w[$i - 7]); 1580 $w[$i] = $w[$i]->add($s1); 1581 } 1582 1583 // Initialize hash value for this chunk 1584 $a = clone $hash[0]; 1585 $b = clone $hash[1]; 1586 $c = clone $hash[2]; 1587 $d = clone $hash[3]; 1588 $e = clone $hash[4]; 1589 $f = clone $hash[5]; 1590 $g = clone $hash[6]; 1591 $h = clone $hash[7]; 1592 1593 // Main loop 1594 for ($i = 0; $i < 80; $i++) { 1595 $temp = [ 1596 $a->bitwise_rightRotate(28), 1597 $a->bitwise_rightRotate(34), 1598 $a->bitwise_rightRotate(39) 1599 ]; 1600 $s0 = $temp[0]->bitwise_xor($temp[1]); 1601 $s0 = $s0->bitwise_xor($temp[2]); 1602 $temp = [ 1603 $a->bitwise_and($b), 1604 $a->bitwise_and($c), 1605 $b->bitwise_and($c) 1606 ]; 1607 $maj = $temp[0]->bitwise_xor($temp[1]); 1608 $maj = $maj->bitwise_xor($temp[2]); 1609 $t2 = $s0->add($maj); 1610 1611 $temp = [ 1612 $e->bitwise_rightRotate(14), 1613 $e->bitwise_rightRotate(18), 1614 $e->bitwise_rightRotate(41) 1615 ]; 1616 $s1 = $temp[0]->bitwise_xor($temp[1]); 1617 $s1 = $s1->bitwise_xor($temp[2]); 1618 $temp = [ 1619 $e->bitwise_and($f), 1620 $g->bitwise_and($e->bitwise_not()) 1621 ]; 1622 $ch = $temp[0]->bitwise_xor($temp[1]); 1623 $t1 = $h->add($s1); 1624 $t1 = $t1->add($ch); 1625 $t1 = $t1->add($k[$i]); 1626 $t1 = $t1->add($w[$i]); 1627 1628 $h = clone $g; 1629 $g = clone $f; 1630 $f = clone $e; 1631 $e = $d->add($t1); 1632 $d = clone $c; 1633 $c = clone $b; 1634 $b = clone $a; 1635 $a = $t1->add($t2); 1636 } 1637 1638 // Add this chunk's hash to result so far 1639 $hash = [ 1640 $hash[0]->add($a), 1641 $hash[1]->add($b), 1642 $hash[2]->add($c), 1643 $hash[3]->add($d), 1644 $hash[4]->add($e), 1645 $hash[5]->add($f), 1646 $hash[6]->add($g), 1647 $hash[7]->add($h) 1648 ]; 1649 } 1650 1651 // Produce the final hash value (big-endian) 1652 // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) 1653 $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . 1654 $hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes(); 1655 1656 return $temp; 1657 } 1658 1659 /** 1660 * Pure-PHP implementation of SHA512 1661 * 1662 * @param string $m 1663 * @param array $hash 1664 * @return string 1665 */ 1666 private static function sha512_64($m, $hash) 1667 { 1668 static $k; 1669 1670 if (!isset($k)) { 1671 // Initialize table of round constants 1672 // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) 1673 $k = [ 1674 '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', 1675 '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', 1676 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', 1677 '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', 1678 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', 1679 '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', 1680 '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', 1681 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', 1682 '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', 1683 '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', 1684 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', 1685 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', 1686 '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', 1687 '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', 1688 '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', 1689 '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', 1690 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', 1691 '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', 1692 '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', 1693 '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' 1694 ]; 1695 1696 for ($i = 0; $i < 80; $i++) { 1697 list(, $k[$i]) = unpack('J', pack('H*', $k[$i])); 1698 } 1699 } 1700 1701 // Pre-processing 1702 $length = strlen($m); 1703 // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 1704 $m .= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); 1705 $m[$length] = chr(0x80); 1706 // we don't support hashing strings 512MB long 1707 $m .= pack('N4', 0, 0, 0, $length << 3); 1708 1709 // Process the message in successive 1024-bit chunks 1710 $chunks = str_split($m, 128); 1711 foreach ($chunks as $chunk) { 1712 $w = []; 1713 for ($i = 0; $i < 16; $i++) { 1714 list(, $w[]) = unpack('J', Strings::shift($chunk, 8)); 1715 } 1716 1717 // Extend the sixteen 32-bit words into eighty 32-bit words 1718 for ($i = 16; $i < 80; $i++) { 1719 $temp = [ 1720 self::rotateRight64($w[$i - 15], 1), 1721 self::rotateRight64($w[$i - 15], 8), 1722 ($w[$i - 15] >> 7) & 0x01FFFFFFFFFFFFFF, 1723 ]; 1724 $s0 = $temp[0] ^ $temp[1] ^ $temp[2]; 1725 $temp = [ 1726 self::rotateRight64($w[$i - 2], 19), 1727 self::rotateRight64($w[$i - 2], 61), 1728 ($w[$i - 2] >> 6) & 0x03FFFFFFFFFFFFFF, 1729 ]; 1730 $s1 = $temp[0] ^ $temp[1] ^ $temp[2]; 1731 1732 $w[$i] = $w[$i - 16]; 1733 $w[$i] = self::add64($w[$i], $s0); 1734 $w[$i] = self::add64($w[$i], $w[$i - 7]); 1735 $w[$i] = self::add64($w[$i], $s1); 1736 } 1737 1738 // Initialize hash value for this chunk 1739 list($a, $b, $c, $d, $e, $f, $g, $h) = $hash; 1740 1741 // Main loop 1742 for ($i = 0; $i < 80; $i++) { 1743 $temp = [ 1744 self::rotateRight64($a, 28), 1745 self::rotateRight64($a, 34), 1746 self::rotateRight64($a, 39), 1747 ]; 1748 $s0 = $temp[0] ^ $temp[1] ^ $temp[2]; 1749 $temp = [$a & $b, $a & $c, $b & $c]; 1750 $maj = $temp[0] ^ $temp[1] ^ $temp[2]; 1751 $t2 = self::add64($s0, $maj); 1752 1753 $temp = [ 1754 self::rotateRight64($e, 14), 1755 self::rotateRight64($e, 18), 1756 self::rotateRight64($e, 41), 1757 ]; 1758 $s1 = $temp[0] ^ $temp[1] ^ $temp[2]; 1759 $ch = ($e & $f) ^ ($g & ~$e); 1760 $t1 = self::add64($h, $s1); 1761 $t1 = self::add64($t1, $ch); 1762 $t1 = self::add64($t1, $k[$i]); 1763 $t1 = self::add64($t1, $w[$i]); 1764 1765 $h = $g; 1766 $g = $f; 1767 $f = $e; 1768 $e = self::add64($d, $t1); 1769 $d = $c; 1770 $c = $b; 1771 $b = $a; 1772 $a = self::add64($t1, $t2); 1773 } 1774 1775 // Add this chunk's hash to result so far 1776 $hash = [ 1777 self::add64($hash[0], $a), 1778 self::add64($hash[1], $b), 1779 self::add64($hash[2], $c), 1780 self::add64($hash[3], $d), 1781 self::add64($hash[4], $e), 1782 self::add64($hash[5], $f), 1783 self::add64($hash[6], $g), 1784 self::add64($hash[7], $h), 1785 ]; 1786 } 1787 1788 // Produce the final hash value (big-endian) 1789 // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) 1790 return pack('J*', ...$hash); 1791 } 1792 1793 /** 1794 * __toString() magic method 1795 */ 1796 public function __toString() 1797 { 1798 return $this->getHash(); 1799 } 1800} 1801