PageRenderTime 58ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/phpseclib/Crypt/Hash.php

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