[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 3 if (class_exists('ParagonIE_Sodium_Core_Poly1305_State', false)) { 4 return; 5 } 6 7 /** 8 * Class ParagonIE_Sodium_Core_Poly1305_State 9 */ 10 class ParagonIE_Sodium_Core_Poly1305_State extends ParagonIE_Sodium_Core_Util 11 { 12 /** 13 * @var array<int, int> 14 */ 15 protected $buffer = array(); 16 17 /** 18 * @var bool 19 */ 20 protected $final = false; 21 22 /** 23 * @var array<int, int> 24 */ 25 public $h; 26 27 /** 28 * @var int 29 */ 30 protected $leftover = 0; 31 32 /** 33 * @var int[] 34 */ 35 public $r; 36 37 /** 38 * @var int[] 39 */ 40 public $pad; 41 42 /** 43 * ParagonIE_Sodium_Core_Poly1305_State constructor. 44 * 45 * @internal You should not use this directly from another application 46 * 47 * @param string $key 48 * @throws InvalidArgumentException 49 * @throws TypeError 50 */ 51 public function __construct($key = '') 52 { 53 if (self::strlen($key) < 32) { 54 throw new InvalidArgumentException( 55 'Poly1305 requires a 32-byte key' 56 ); 57 } 58 /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ 59 $this->r = array( 60 (int) ((self::load_4(self::substr($key, 0, 4))) & 0x3ffffff), 61 (int) ((self::load_4(self::substr($key, 3, 4)) >> 2) & 0x3ffff03), 62 (int) ((self::load_4(self::substr($key, 6, 4)) >> 4) & 0x3ffc0ff), 63 (int) ((self::load_4(self::substr($key, 9, 4)) >> 6) & 0x3f03fff), 64 (int) ((self::load_4(self::substr($key, 12, 4)) >> 8) & 0x00fffff) 65 ); 66 67 /* h = 0 */ 68 $this->h = array(0, 0, 0, 0, 0); 69 70 /* save pad for later */ 71 $this->pad = array( 72 self::load_4(self::substr($key, 16, 4)), 73 self::load_4(self::substr($key, 20, 4)), 74 self::load_4(self::substr($key, 24, 4)), 75 self::load_4(self::substr($key, 28, 4)), 76 ); 77 78 $this->leftover = 0; 79 $this->final = false; 80 } 81 82 /** 83 * Zero internal buffer upon destruction 84 */ 85 public function __destruct() 86 { 87 $this->r[0] ^= $this->r[0]; 88 $this->r[1] ^= $this->r[1]; 89 $this->r[2] ^= $this->r[2]; 90 $this->r[3] ^= $this->r[3]; 91 $this->r[4] ^= $this->r[4]; 92 $this->h[0] ^= $this->h[0]; 93 $this->h[1] ^= $this->h[1]; 94 $this->h[2] ^= $this->h[2]; 95 $this->h[3] ^= $this->h[3]; 96 $this->h[4] ^= $this->h[4]; 97 $this->pad[0] ^= $this->pad[0]; 98 $this->pad[1] ^= $this->pad[1]; 99 $this->pad[2] ^= $this->pad[2]; 100 $this->pad[3] ^= $this->pad[3]; 101 $this->leftover = 0; 102 $this->final = true; 103 } 104 105 /** 106 * @internal You should not use this directly from another application 107 * 108 * @param string $message 109 * @return self 110 * @throws SodiumException 111 * @throws TypeError 112 */ 113 public function update($message = '') 114 { 115 $bytes = self::strlen($message); 116 if ($bytes < 1) { 117 return $this; 118 } 119 120 /* handle leftover */ 121 if ($this->leftover) { 122 $want = ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - $this->leftover; 123 if ($want > $bytes) { 124 $want = $bytes; 125 } 126 for ($i = 0; $i < $want; ++$i) { 127 $mi = self::chrToInt($message[$i]); 128 $this->buffer[$this->leftover + $i] = $mi; 129 } 130 // We snip off the leftmost bytes. 131 $message = self::substr($message, $want); 132 $bytes = self::strlen($message); 133 $this->leftover += $want; 134 if ($this->leftover < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { 135 // We still don't have enough to run $this->blocks() 136 return $this; 137 } 138 139 $this->blocks( 140 self::intArrayToString($this->buffer), 141 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE 142 ); 143 $this->leftover = 0; 144 } 145 146 /* process full blocks */ 147 if ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { 148 /** @var int $want */ 149 $want = $bytes & ~(ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - 1); 150 if ($want >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { 151 $block = self::substr($message, 0, $want); 152 if (self::strlen($block) >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { 153 $this->blocks($block, $want); 154 $message = self::substr($message, $want); 155 $bytes = self::strlen($message); 156 } 157 } 158 } 159 160 /* store leftover */ 161 if ($bytes) { 162 for ($i = 0; $i < $bytes; ++$i) { 163 $mi = self::chrToInt($message[$i]); 164 $this->buffer[$this->leftover + $i] = $mi; 165 } 166 $this->leftover = (int) $this->leftover + $bytes; 167 } 168 return $this; 169 } 170 171 /** 172 * @internal You should not use this directly from another application 173 * 174 * @param string $message 175 * @param int $bytes 176 * @return self 177 * @throws TypeError 178 */ 179 public function blocks($message, $bytes) 180 { 181 if (self::strlen($message) < 16) { 182 $message = str_pad($message, 16, "\x00", STR_PAD_RIGHT); 183 } 184 /** @var int $hibit */ 185 $hibit = $this->final ? 0 : 1 << 24; /* 1 << 128 */ 186 $r0 = (int) $this->r[0]; 187 $r1 = (int) $this->r[1]; 188 $r2 = (int) $this->r[2]; 189 $r3 = (int) $this->r[3]; 190 $r4 = (int) $this->r[4]; 191 192 $s1 = self::mul($r1, 5, 3); 193 $s2 = self::mul($r2, 5, 3); 194 $s3 = self::mul($r3, 5, 3); 195 $s4 = self::mul($r4, 5, 3); 196 197 $h0 = $this->h[0]; 198 $h1 = $this->h[1]; 199 $h2 = $this->h[2]; 200 $h3 = $this->h[3]; 201 $h4 = $this->h[4]; 202 203 while ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { 204 /* h += m[i] */ 205 $h0 += self::load_4(self::substr($message, 0, 4)) & 0x3ffffff; 206 $h1 += (self::load_4(self::substr($message, 3, 4)) >> 2) & 0x3ffffff; 207 $h2 += (self::load_4(self::substr($message, 6, 4)) >> 4) & 0x3ffffff; 208 $h3 += (self::load_4(self::substr($message, 9, 4)) >> 6) & 0x3ffffff; 209 $h4 += (self::load_4(self::substr($message, 12, 4)) >> 8) | $hibit; 210 211 /* h *= r */ 212 $d0 = ( 213 self::mul($h0, $r0, 25) + 214 self::mul($s4, $h1, 26) + 215 self::mul($s3, $h2, 26) + 216 self::mul($s2, $h3, 26) + 217 self::mul($s1, $h4, 26) 218 ); 219 220 $d1 = ( 221 self::mul($h0, $r1, 25) + 222 self::mul($h1, $r0, 25) + 223 self::mul($s4, $h2, 26) + 224 self::mul($s3, $h3, 26) + 225 self::mul($s2, $h4, 26) 226 ); 227 228 $d2 = ( 229 self::mul($h0, $r2, 25) + 230 self::mul($h1, $r1, 25) + 231 self::mul($h2, $r0, 25) + 232 self::mul($s4, $h3, 26) + 233 self::mul($s3, $h4, 26) 234 ); 235 236 $d3 = ( 237 self::mul($h0, $r3, 25) + 238 self::mul($h1, $r2, 25) + 239 self::mul($h2, $r1, 25) + 240 self::mul($h3, $r0, 25) + 241 self::mul($s4, $h4, 26) 242 ); 243 244 $d4 = ( 245 self::mul($h0, $r4, 25) + 246 self::mul($h1, $r3, 25) + 247 self::mul($h2, $r2, 25) + 248 self::mul($h3, $r1, 25) + 249 self::mul($h4, $r0, 25) 250 ); 251 252 /* (partial) h %= p */ 253 /** @var int $c */ 254 $c = $d0 >> 26; 255 /** @var int $h0 */ 256 $h0 = $d0 & 0x3ffffff; 257 $d1 += $c; 258 259 /** @var int $c */ 260 $c = $d1 >> 26; 261 /** @var int $h1 */ 262 $h1 = $d1 & 0x3ffffff; 263 $d2 += $c; 264 265 /** @var int $c */ 266 $c = $d2 >> 26; 267 /** @var int $h2 */ 268 $h2 = $d2 & 0x3ffffff; 269 $d3 += $c; 270 271 /** @var int $c */ 272 $c = $d3 >> 26; 273 /** @var int $h3 */ 274 $h3 = $d3 & 0x3ffffff; 275 $d4 += $c; 276 277 /** @var int $c */ 278 $c = $d4 >> 26; 279 /** @var int $h4 */ 280 $h4 = $d4 & 0x3ffffff; 281 $h0 += (int) self::mul($c, 5, 3); 282 283 /** @var int $c */ 284 $c = $h0 >> 26; 285 /** @var int $h0 */ 286 $h0 &= 0x3ffffff; 287 $h1 += $c; 288 289 // Chop off the left 32 bytes. 290 $message = self::substr( 291 $message, 292 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE 293 ); 294 $bytes -= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE; 295 } 296 297 $this->h = array( 298 (int) ($h0 & 0xffffffff), 299 (int) ($h1 & 0xffffffff), 300 (int) ($h2 & 0xffffffff), 301 (int) ($h3 & 0xffffffff), 302 (int) ($h4 & 0xffffffff) 303 ); 304 return $this; 305 } 306 307 /** 308 * @internal You should not use this directly from another application 309 * 310 * @return string 311 * @throws TypeError 312 */ 313 public function finish() 314 { 315 /* process the remaining block */ 316 if ($this->leftover) { 317 $i = $this->leftover; 318 $this->buffer[$i++] = 1; 319 for (; $i < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE; ++$i) { 320 $this->buffer[$i] = 0; 321 } 322 $this->final = true; 323 $this->blocks( 324 self::substr( 325 self::intArrayToString($this->buffer), 326 0, 327 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE 328 ), 329 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE 330 ); 331 } 332 333 $h0 = (int) $this->h[0]; 334 $h1 = (int) $this->h[1]; 335 $h2 = (int) $this->h[2]; 336 $h3 = (int) $this->h[3]; 337 $h4 = (int) $this->h[4]; 338 339 /** @var int $c */ 340 $c = $h1 >> 26; 341 /** @var int $h1 */ 342 $h1 &= 0x3ffffff; 343 /** @var int $h2 */ 344 $h2 += $c; 345 /** @var int $c */ 346 $c = $h2 >> 26; 347 /** @var int $h2 */ 348 $h2 &= 0x3ffffff; 349 $h3 += $c; 350 /** @var int $c */ 351 $c = $h3 >> 26; 352 $h3 &= 0x3ffffff; 353 $h4 += $c; 354 /** @var int $c */ 355 $c = $h4 >> 26; 356 $h4 &= 0x3ffffff; 357 /** @var int $h0 */ 358 $h0 += self::mul($c, 5, 3); 359 /** @var int $c */ 360 $c = $h0 >> 26; 361 /** @var int $h0 */ 362 $h0 &= 0x3ffffff; 363 /** @var int $h1 */ 364 $h1 += $c; 365 366 /* compute h + -p */ 367 /** @var int $g0 */ 368 $g0 = $h0 + 5; 369 /** @var int $c */ 370 $c = $g0 >> 26; 371 /** @var int $g0 */ 372 $g0 &= 0x3ffffff; 373 374 /** @var int $g1 */ 375 $g1 = $h1 + $c; 376 /** @var int $c */ 377 $c = $g1 >> 26; 378 $g1 &= 0x3ffffff; 379 380 /** @var int $g2 */ 381 $g2 = $h2 + $c; 382 /** @var int $c */ 383 $c = $g2 >> 26; 384 /** @var int $g2 */ 385 $g2 &= 0x3ffffff; 386 387 /** @var int $g3 */ 388 $g3 = $h3 + $c; 389 /** @var int $c */ 390 $c = $g3 >> 26; 391 /** @var int $g3 */ 392 $g3 &= 0x3ffffff; 393 394 /** @var int $g4 */ 395 $g4 = ($h4 + $c - (1 << 26)) & 0xffffffff; 396 397 /* select h if h < p, or h + -p if h >= p */ 398 /** @var int $mask */ 399 $mask = ($g4 >> 31) - 1; 400 401 $g0 &= $mask; 402 $g1 &= $mask; 403 $g2 &= $mask; 404 $g3 &= $mask; 405 $g4 &= $mask; 406 407 /** @var int $mask */ 408 $mask = ~$mask & 0xffffffff; 409 /** @var int $h0 */ 410 $h0 = ($h0 & $mask) | $g0; 411 /** @var int $h1 */ 412 $h1 = ($h1 & $mask) | $g1; 413 /** @var int $h2 */ 414 $h2 = ($h2 & $mask) | $g2; 415 /** @var int $h3 */ 416 $h3 = ($h3 & $mask) | $g3; 417 /** @var int $h4 */ 418 $h4 = ($h4 & $mask) | $g4; 419 420 /* h = h % (2^128) */ 421 /** @var int $h0 */ 422 $h0 = (($h0) | ($h1 << 26)) & 0xffffffff; 423 /** @var int $h1 */ 424 $h1 = (($h1 >> 6) | ($h2 << 20)) & 0xffffffff; 425 /** @var int $h2 */ 426 $h2 = (($h2 >> 12) | ($h3 << 14)) & 0xffffffff; 427 /** @var int $h3 */ 428 $h3 = (($h3 >> 18) | ($h4 << 8)) & 0xffffffff; 429 430 /* mac = (h + pad) % (2^128) */ 431 $f = (int) ($h0 + $this->pad[0]); 432 $h0 = (int) $f; 433 $f = (int) ($h1 + $this->pad[1] + ($f >> 32)); 434 $h1 = (int) $f; 435 $f = (int) ($h2 + $this->pad[2] + ($f >> 32)); 436 $h2 = (int) $f; 437 $f = (int) ($h3 + $this->pad[3] + ($f >> 32)); 438 $h3 = (int) $f; 439 440 return self::store32_le($h0 & 0xffffffff) . 441 self::store32_le($h1 & 0xffffffff) . 442 self::store32_le($h2 & 0xffffffff) . 443 self::store32_le($h3 & 0xffffffff); 444 } 445 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:03 2024 | Cross-referenced by PHPXref 0.7.1 |