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