[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

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