[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/phpseclib/phpseclib/phpseclib/Crypt/ -> ChaCha20.php (source)

   1  <?php
   2  
   3  /**
   4   * Pure-PHP implementation of ChaCha20.
   5   *
   6   * PHP version 5
   7   *
   8   * @category  Crypt
   9   * @package   ChaCha20
  10   * @author    Jim Wigginton <[email protected]>
  11   * @copyright 2019 Jim Wigginton
  12   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  13   * @link      http://phpseclib.sourceforge.net
  14   */
  15  
  16  namespace phpseclib3\Crypt;
  17  
  18  use phpseclib3\Exception\BadDecryptionException;
  19  use phpseclib3\Exception\InsufficientSetupException;
  20  
  21  /**
  22   * Pure-PHP implementation of ChaCha20.
  23   *
  24   * @package ChaCha20
  25   * @author  Jim Wigginton <[email protected]>
  26   * @access  public
  27   */
  28  class ChaCha20 extends Salsa20
  29  {
  30      /**
  31       * The OpenSSL specific name of the cipher
  32       *
  33       * @var string
  34       */
  35      protected $cipher_name_openssl = 'chacha20';
  36  
  37      /**
  38       * Test for engine validity
  39       *
  40       * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine()
  41       *
  42       * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct()
  43       * @param int $engine
  44       * @access protected
  45       * @return bool
  46       */
  47      protected function isValidEngineHelper($engine)
  48      {
  49          switch ($engine) {
  50              case self::ENGINE_LIBSODIUM:
  51                  // PHP 7.2.0 (30 Nov 2017) added support for libsodium
  52  
  53                  // we could probably make it so that if $this->counter == 0 then the first block would be done with either OpenSSL
  54                  // or PHP and then subsequent blocks would then be done with libsodium but idk - it's not a high priority atm
  55  
  56                  // we could also make it so that if $this->counter == 0 and $this->continuousBuffer then do the first string
  57                  // with libsodium and subsequent strings with openssl or pure-PHP but again not a high priority
  58                  return function_exists('sodium_crypto_aead_chacha20poly1305_ietf_encrypt') &&
  59                         $this->key_length == 32 &&
  60                         (($this->usePoly1305 && !isset($this->poly1305Key) && $this->counter == 0) || $this->counter == 1) &&
  61                         !$this->continuousBuffer;
  62              case self::ENGINE_OPENSSL:
  63                  // OpenSSL 1.1.0 (released 25 Aug 2016) added support for chacha20.
  64                  // PHP didn't support OpenSSL 1.1.0 until 7.0.19 (11 May 2017)
  65  
  66                  // if you attempt to provide openssl with a 128 bit key (as opposed to a 256 bit key) openssl will null
  67                  // pad the key to 256 bits and still use the expansion constant for 256-bit keys. the fact that
  68                  // openssl treats the IV as both the counter and nonce, however, let's us use openssl in continuous mode
  69                  // whereas libsodium does not
  70                  if ($this->key_length != 32) {
  71                      return false;
  72                  }
  73          }
  74  
  75          return parent::isValidEngineHelper($engine);
  76      }
  77  
  78      /**
  79       * Encrypts a message.
  80       *
  81       * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt()
  82       * @see self::crypt()
  83       * @param string $plaintext
  84       * @return string $ciphertext
  85       */
  86      public function encrypt($plaintext)
  87      {
  88          $this->setup();
  89  
  90          if ($this->engine == self::ENGINE_LIBSODIUM) {
  91              return $this->encrypt_with_libsodium($plaintext);
  92          }
  93  
  94          return parent::encrypt($plaintext);
  95      }
  96  
  97      /**
  98       * Decrypts a message.
  99       *
 100       * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
 101       * At least if the continuous buffer is disabled.
 102       *
 103       * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt()
 104       * @see self::crypt()
 105       * @param string $ciphertext
 106       * @return string $plaintext
 107       */
 108      public function decrypt($ciphertext)
 109      {
 110          $this->setup();
 111  
 112          if ($this->engine == self::ENGINE_LIBSODIUM) {
 113              return $this->decrypt_with_libsodium($ciphertext);
 114          }
 115  
 116          return parent::decrypt($ciphertext);
 117      }
 118  
 119      /**
 120       * Encrypts a message with libsodium
 121       *
 122       * @see self::encrypt()
 123       * @param string $plaintext
 124       * @return string $text
 125       */
 126      private function encrypt_with_libsodium($plaintext)
 127      {
 128          $params = [$plaintext, $this->aad, $this->nonce, $this->key];
 129          $ciphertext = strlen($this->nonce) == 8 ?
 130              sodium_crypto_aead_chacha20poly1305_encrypt(...$params) :
 131              sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params);
 132          if (!$this->usePoly1305) {
 133              return substr($ciphertext, 0, strlen($plaintext));
 134          }
 135  
 136          $newciphertext = substr($ciphertext, 0, strlen($plaintext));
 137  
 138          $this->newtag = $this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12 ?
 139              substr($ciphertext, strlen($plaintext)) :
 140              $this->poly1305($newciphertext);
 141  
 142          return $newciphertext;
 143      }
 144  
 145      /**
 146       * Decrypts a message with libsodium
 147       *
 148       * @see self::decrypt()
 149       * @param string $ciphertext
 150       * @return string $text
 151       */
 152      private function decrypt_with_libsodium($ciphertext)
 153      {
 154          $params = [$ciphertext, $this->aad, $this->nonce, $this->key];
 155  
 156          if (isset($this->poly1305Key)) {
 157              if ($this->oldtag === false) {
 158                  throw new InsufficientSetupException('Authentication Tag has not been set');
 159              }
 160              if ($this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12) {
 161                  $plaintext = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(...$params);
 162                  $this->oldtag = false;
 163                  if ($plaintext === false) {
 164                      throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match');
 165                  }
 166                  return $plaintext;
 167              }
 168              $newtag = $this->poly1305($ciphertext);
 169              if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) {
 170                  $this->oldtag = false;
 171                  throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match');
 172              }
 173              $this->oldtag = false;
 174          }
 175  
 176          $plaintext = strlen($this->nonce) == 8 ?
 177              sodium_crypto_aead_chacha20poly1305_encrypt(...$params) :
 178              sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params);
 179  
 180          return substr($plaintext, 0, strlen($ciphertext));
 181      }
 182  
 183      /**
 184       * Sets the nonce.
 185       *
 186       * @param string $nonce
 187       */
 188      public function setNonce($nonce)
 189      {
 190          if (!is_string($nonce)) {
 191              throw new \UnexpectedValueException('The nonce should be a string');
 192          }
 193  
 194          /*
 195            from https://tools.ietf.org/html/rfc7539#page-7
 196  
 197            "Note also that the original ChaCha had a 64-bit nonce and 64-bit
 198             block count.  We have modified this here to be more consistent with
 199             recommendations in Section 3.2 of [RFC5116]."
 200           */
 201          switch (strlen($nonce)) {
 202              case 8:  // 64 bits
 203              case 12: // 96 bits
 204                  break;
 205              default:
 206                  throw new \LengthException('Nonce of size ' . strlen($nonce) . ' not supported by this algorithm. Only 64-bit nonces or 96-bit nonces are supported');
 207          }
 208  
 209          $this->nonce = $nonce;
 210          $this->changed = true;
 211          $this->setEngine();
 212      }
 213  
 214      /**
 215       * Setup the self::ENGINE_INTERNAL $engine
 216       *
 217       * (re)init, if necessary, the internal cipher $engine
 218       *
 219       * _setup() will be called each time if $changed === true
 220       * typically this happens when using one or more of following public methods:
 221       *
 222       * - setKey()
 223       *
 224       * - setNonce()
 225       *
 226       * - First run of encrypt() / decrypt() with no init-settings
 227       *
 228       * @see self::setKey()
 229       * @see self::setNonce()
 230       * @see self::disableContinuousBuffer()
 231       */
 232      protected function setup()
 233      {
 234          if (!$this->changed) {
 235              return;
 236          }
 237  
 238          $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter];
 239  
 240          $this->changed = $this->nonIVChanged = false;
 241  
 242          if ($this->nonce === false) {
 243              throw new InsufficientSetupException('No nonce has been defined');
 244          }
 245  
 246          if ($this->key === false) {
 247              throw new InsufficientSetupException('No key has been defined');
 248          }
 249  
 250          if ($this->usePoly1305 && !isset($this->poly1305Key)) {
 251              $this->usingGeneratedPoly1305Key = true;
 252              if ($this->engine == self::ENGINE_LIBSODIUM) {
 253                  return;
 254              }
 255              $this->createPoly1305Key();
 256          }
 257  
 258          $key = $this->key;
 259          if (strlen($key) == 16) {
 260              $constant = 'expand 16-byte k';
 261              $key .= $key;
 262          } else {
 263              $constant = 'expand 32-byte k';
 264          }
 265  
 266          $this->p1 = $constant . $key;
 267          $this->p2 = $this->nonce;
 268          if (strlen($this->nonce) == 8) {
 269              $this->p2 = "\0\0\0\0" . $this->p2;
 270          }
 271      }
 272  
 273      /**
 274       * The quarterround function
 275       *
 276       * @param int $a
 277       * @param int $b
 278       * @param int $c
 279       * @param int $d
 280       */
 281      protected static function quarterRound(&$a, &$b, &$c, &$d)
 282      {
 283          // in https://datatracker.ietf.org/doc/html/rfc7539#section-2.1 the addition,
 284          // xor'ing and rotation are all on the same line so i'm keeping it on the same
 285          // line here as well
 286          // @codingStandardsIgnoreStart
 287          $a+= $b; $d = self::leftRotate($d ^ $a, 16);
 288          $c+= $d; $b = self::leftRotate($b ^ $c, 12);
 289          $a+= $b; $d = self::leftRotate($d ^ $a, 8);
 290          $c+= $d; $b = self::leftRotate($b ^ $c, 7);
 291          // @codingStandardsIgnoreEnd
 292      }
 293  
 294      /**
 295       * The doubleround function
 296       *
 297       * @param int $x0 (by reference)
 298       * @param int $x1 (by reference)
 299       * @param int $x2 (by reference)
 300       * @param int $x3 (by reference)
 301       * @param int $x4 (by reference)
 302       * @param int $x5 (by reference)
 303       * @param int $x6 (by reference)
 304       * @param int $x7 (by reference)
 305       * @param int $x8 (by reference)
 306       * @param int $x9 (by reference)
 307       * @param int $x10 (by reference)
 308       * @param int $x11 (by reference)
 309       * @param int $x12 (by reference)
 310       * @param int $x13 (by reference)
 311       * @param int $x14 (by reference)
 312       * @param int $x15 (by reference)
 313       */
 314      protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15)
 315      {
 316          // columnRound
 317          static::quarterRound($x0, $x4, $x8, $x12);
 318          static::quarterRound($x1, $x5, $x9, $x13);
 319          static::quarterRound($x2, $x6, $x10, $x14);
 320          static::quarterRound($x3, $x7, $x11, $x15);
 321          // rowRound
 322          static::quarterRound($x0, $x5, $x10, $x15);
 323          static::quarterRound($x1, $x6, $x11, $x12);
 324          static::quarterRound($x2, $x7, $x8, $x13);
 325          static::quarterRound($x3, $x4, $x9, $x14);
 326      }
 327  
 328      /**
 329       * The Salsa20 hash function function
 330       *
 331       * On my laptop this loop unrolled / function dereferenced version of parent::salsa20 encrypts 1mb of text in
 332       * 0.65s vs the 0.85s that it takes with the parent method.
 333       *
 334       * If we were free to assume that the host OS would always be 64-bits then the if condition in leftRotate could
 335       * be eliminated and we could knock this done to 0.60s.
 336       *
 337       * For comparison purposes, RC4 takes 0.16s and AES in CTR mode with the Eval engine takes 0.48s.
 338       * AES in CTR mode with the PHP engine takes 1.19s. Salsa20 / ChaCha20 do not benefit as much from the Eval
 339       * approach due to the fact that there are a lot less variables to de-reference, fewer loops to unroll, etc
 340       *
 341       * @param string $x
 342       */
 343      protected static function salsa20($x)
 344      {
 345          list(, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15) = unpack('V*', $x);
 346          $z0 = $x0;
 347          $z1 = $x1;
 348          $z2 = $x2;
 349          $z3 = $x3;
 350          $z4 = $x4;
 351          $z5 = $x5;
 352          $z6 = $x6;
 353          $z7 = $x7;
 354          $z8 = $x8;
 355          $z9 = $x9;
 356          $z10 = $x10;
 357          $z11 = $x11;
 358          $z12 = $x12;
 359          $z13 = $x13;
 360          $z14 = $x14;
 361          $z15 = $x15;
 362  
 363          // @codingStandardsIgnoreStart
 364          // columnRound
 365          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 366          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 367          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 368          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 369  
 370          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 371          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 372          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 373          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 374  
 375          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 376          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 377          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 378          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 379  
 380          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 381          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 382          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 383          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 384  
 385          // rowRound
 386          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 387          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 388          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 389          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 390  
 391          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 392          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 393          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 394          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 395  
 396          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 397          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 398          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 399          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 400  
 401          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 402          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 403          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 404          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 405  
 406          // columnRound
 407          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 408          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 409          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 410          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 411  
 412          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 413          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 414          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 415          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 416  
 417          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 418          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 419          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 420          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 421  
 422          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 423          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 424          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 425          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 426  
 427          // rowRound
 428          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 429          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 430          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 431          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 432  
 433          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 434          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 435          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 436          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 437  
 438          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 439          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 440          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 441          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 442  
 443          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 444          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 445          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 446          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 447  
 448          // columnRound
 449          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 450          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 451          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 452          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 453  
 454          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 455          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 456          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 457          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 458  
 459          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 460          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 461          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 462          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 463  
 464          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 465          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 466          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 467          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 468  
 469          // rowRound
 470          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 471          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 472          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 473          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 474  
 475          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 476          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 477          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 478          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 479  
 480          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 481          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 482          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 483          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 484  
 485          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 486          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 487          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 488          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 489  
 490          // columnRound
 491          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 492          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 493          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 494          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 495  
 496          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 497          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 498          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 499          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 500  
 501          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 502          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 503          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 504          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 505  
 506          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 507          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 508          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 509          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 510  
 511          // rowRound
 512          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 513          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 514          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 515          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 516  
 517          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 518          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 519          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 520          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 521  
 522          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 523          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 524          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 525          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 526  
 527          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 528          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 529          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 530          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 531  
 532          // columnRound
 533          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 534          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 535          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 536          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 537  
 538          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 539          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 540          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 541          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 542  
 543          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 544          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 545          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 546          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 547  
 548          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 549          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 550          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 551          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 552  
 553          // rowRound
 554          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 555          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 556          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 557          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 558  
 559          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 560          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 561          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 562          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 563  
 564          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 565          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 566          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 567          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 568  
 569          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 570          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 571          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 572          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 573  
 574          // columnRound
 575          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 576          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 577          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 578          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 579  
 580          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 581          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 582          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 583          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 584  
 585          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 586          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 587          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 588          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 589  
 590          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 591          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 592          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 593          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 594  
 595          // rowRound
 596          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 597          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 598          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 599          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 600  
 601          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 602          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 603          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 604          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 605  
 606          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 607          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 608          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 609          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 610  
 611          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 612          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 613          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 614          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 615  
 616          // columnRound
 617          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 618          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 619          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 620          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 621  
 622          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 623          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 624          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 625          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 626  
 627          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 628          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 629          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 630          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 631  
 632          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 633          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 634          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 635          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 636  
 637          // rowRound
 638          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 639          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 640          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 641          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 642  
 643          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 644          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 645          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 646          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 647  
 648          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 649          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 650          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 651          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 652  
 653          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 654          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 655          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 656          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 657  
 658          // columnRound
 659          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 660          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 661          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 662          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 663  
 664          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 665          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 666          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 667          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 668  
 669          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 670          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 671          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 672          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 673  
 674          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 675          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 676          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 677          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 678  
 679          // rowRound
 680          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 681          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 682          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 683          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 684  
 685          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 686          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 687          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 688          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 689  
 690          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 691          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 692          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 693          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 694  
 695          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 696          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 697          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 698          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 699  
 700          // columnRound
 701          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 702          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 703          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 704          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 705  
 706          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 707          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 708          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 709          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 710  
 711          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 712          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 713          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 714          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 715  
 716          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 717          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 718          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 719          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 720  
 721          // rowRound
 722          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 723          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 724          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 725          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 726  
 727          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 728          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 729          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 730          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 731  
 732          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 733          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 734          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 735          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 736  
 737          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 738          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 739          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 740          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 741  
 742          // columnRound
 743          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 16);
 744          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 12);
 745          $x0+= $x4; $x12 = self::leftRotate($x12 ^ $x0, 8);
 746          $x8+= $x12; $x4 = self::leftRotate($x4 ^ $x8, 7);
 747  
 748          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 16);
 749          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 12);
 750          $x1+= $x5; $x13 = self::leftRotate($x13 ^ $x1, 8);
 751          $x9+= $x13; $x5 = self::leftRotate($x5 ^ $x9, 7);
 752  
 753          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 16);
 754          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 12);
 755          $x2+= $x6; $x14 = self::leftRotate($x14 ^ $x2, 8);
 756          $x10+= $x14; $x6 = self::leftRotate($x6 ^ $x10, 7);
 757  
 758          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 16);
 759          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 12);
 760          $x3+= $x7; $x15 = self::leftRotate($x15 ^ $x3, 8);
 761          $x11+= $x15; $x7 = self::leftRotate($x7 ^ $x11, 7);
 762  
 763          // rowRound
 764          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 16);
 765          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 12);
 766          $x0+= $x5; $x15 = self::leftRotate($x15 ^ $x0, 8);
 767          $x10+= $x15; $x5 = self::leftRotate($x5 ^ $x10, 7);
 768  
 769          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 16);
 770          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 12);
 771          $x1+= $x6; $x12 = self::leftRotate($x12 ^ $x1, 8);
 772          $x11+= $x12; $x6 = self::leftRotate($x6 ^ $x11, 7);
 773  
 774          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 16);
 775          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 12);
 776          $x2+= $x7; $x13 = self::leftRotate($x13 ^ $x2, 8);
 777          $x8+= $x13; $x7 = self::leftRotate($x7 ^ $x8, 7);
 778  
 779          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 16);
 780          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 12);
 781          $x3+= $x4; $x14 = self::leftRotate($x14 ^ $x3, 8);
 782          $x9+= $x14; $x4 = self::leftRotate($x4 ^ $x9, 7);
 783          // @codingStandardsIgnoreEnd
 784  
 785          $x0 += $z0;
 786          $x1 += $z1;
 787          $x2 += $z2;
 788          $x3 += $z3;
 789          $x4 += $z4;
 790          $x5 += $z5;
 791          $x6 += $z6;
 792          $x7 += $z7;
 793          $x8 += $z8;
 794          $x9 += $z9;
 795          $x10 += $z10;
 796          $x11 += $z11;
 797          $x12 += $z12;
 798          $x13 += $z13;
 799          $x14 += $z14;
 800          $x15 += $z15;
 801  
 802          return pack('V*', $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15);
 803      }
 804  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer