Subversion Repositories oidplus

Rev

Rev 846 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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