[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body