[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Class ParagonIE_Sodium_Core32_Int64 5 * 6 * Encapsulates a 64-bit integer. 7 * 8 * These are immutable. It always returns a new instance. 9 */ 10 class ParagonIE_Sodium_Core32_Int64 11 { 12 /** 13 * @var array<int, int> - four 16-bit integers 14 */ 15 public $limbs = array(0, 0, 0, 0); 16 17 /** 18 * @var int 19 */ 20 public $overflow = 0; 21 22 /** 23 * @var bool 24 */ 25 public $unsignedInt = false; 26 27 /** 28 * ParagonIE_Sodium_Core32_Int64 constructor. 29 * @param array $array 30 * @param bool $unsignedInt 31 */ 32 public function __construct($array = array(0, 0, 0, 0), $unsignedInt = false) 33 { 34 $this->limbs = array( 35 (int) $array[0], 36 (int) $array[1], 37 (int) $array[2], 38 (int) $array[3] 39 ); 40 $this->overflow = 0; 41 $this->unsignedInt = $unsignedInt; 42 } 43 44 /** 45 * Adds two int64 objects 46 * 47 * @param ParagonIE_Sodium_Core32_Int64 $addend 48 * @return ParagonIE_Sodium_Core32_Int64 49 */ 50 public function addInt64(ParagonIE_Sodium_Core32_Int64 $addend) 51 { 52 $i0 = $this->limbs[0]; 53 $i1 = $this->limbs[1]; 54 $i2 = $this->limbs[2]; 55 $i3 = $this->limbs[3]; 56 $j0 = $addend->limbs[0]; 57 $j1 = $addend->limbs[1]; 58 $j2 = $addend->limbs[2]; 59 $j3 = $addend->limbs[3]; 60 61 $r3 = $i3 + ($j3 & 0xffff); 62 $carry = $r3 >> 16; 63 64 $r2 = $i2 + ($j2 & 0xffff) + $carry; 65 $carry = $r2 >> 16; 66 67 $r1 = $i1 + ($j1 & 0xffff) + $carry; 68 $carry = $r1 >> 16; 69 70 $r0 = $i0 + ($j0 & 0xffff) + $carry; 71 $carry = $r0 >> 16; 72 73 $r0 &= 0xffff; 74 $r1 &= 0xffff; 75 $r2 &= 0xffff; 76 $r3 &= 0xffff; 77 78 $return = new ParagonIE_Sodium_Core32_Int64( 79 array($r0, $r1, $r2, $r3) 80 ); 81 $return->overflow = $carry; 82 $return->unsignedInt = $this->unsignedInt; 83 return $return; 84 } 85 86 /** 87 * Adds a normal integer to an int64 object 88 * 89 * @param int $int 90 * @return ParagonIE_Sodium_Core32_Int64 91 * @throws SodiumException 92 * @throws TypeError 93 */ 94 public function addInt($int) 95 { 96 ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); 97 /** @var int $int */ 98 $int = (int) $int; 99 100 $i0 = $this->limbs[0]; 101 $i1 = $this->limbs[1]; 102 $i2 = $this->limbs[2]; 103 $i3 = $this->limbs[3]; 104 105 $r3 = $i3 + ($int & 0xffff); 106 $carry = $r3 >> 16; 107 108 $r2 = $i2 + (($int >> 16) & 0xffff) + $carry; 109 $carry = $r2 >> 16; 110 111 $r1 = $i1 + $carry; 112 $carry = $r1 >> 16; 113 114 $r0 = $i0 + $carry; 115 $carry = $r0 >> 16; 116 117 $r0 &= 0xffff; 118 $r1 &= 0xffff; 119 $r2 &= 0xffff; 120 $r3 &= 0xffff; 121 $return = new ParagonIE_Sodium_Core32_Int64( 122 array($r0, $r1, $r2, $r3) 123 ); 124 $return->overflow = $carry; 125 $return->unsignedInt = $this->unsignedInt; 126 return $return; 127 } 128 129 /** 130 * @param int $b 131 * @return int 132 */ 133 public function compareInt($b = 0) 134 { 135 $gt = 0; 136 $eq = 1; 137 138 $i = 4; 139 $j = 0; 140 while ($i > 0) { 141 --$i; 142 /** @var int $x1 */ 143 $x1 = $this->limbs[$i]; 144 /** @var int $x2 */ 145 $x2 = ($b >> ($j << 4)) & 0xffff; 146 /** int */ 147 $gt |= (($x2 - $x1) >> 8) & $eq; 148 /** int */ 149 $eq &= (($x2 ^ $x1) - 1) >> 8; 150 } 151 return ($gt + $gt - $eq) + 1; 152 } 153 154 /** 155 * @param int $b 156 * @return bool 157 */ 158 public function isGreaterThan($b = 0) 159 { 160 return $this->compareInt($b) > 0; 161 } 162 163 /** 164 * @param int $b 165 * @return bool 166 */ 167 public function isLessThanInt($b = 0) 168 { 169 return $this->compareInt($b) < 0; 170 } 171 172 /** 173 * @param int $hi 174 * @param int $lo 175 * @return ParagonIE_Sodium_Core32_Int64 176 */ 177 public function mask64($hi = 0, $lo = 0) 178 { 179 /** @var int $a */ 180 $a = ($hi >> 16) & 0xffff; 181 /** @var int $b */ 182 $b = ($hi) & 0xffff; 183 /** @var int $c */ 184 $c = ($lo >> 16) & 0xffff; 185 /** @var int $d */ 186 $d = ($lo & 0xffff); 187 return new ParagonIE_Sodium_Core32_Int64( 188 array( 189 $this->limbs[0] & $a, 190 $this->limbs[1] & $b, 191 $this->limbs[2] & $c, 192 $this->limbs[3] & $d 193 ), 194 $this->unsignedInt 195 ); 196 } 197 198 /** 199 * @param int $int 200 * @param int $size 201 * @return ParagonIE_Sodium_Core32_Int64 202 * @throws SodiumException 203 * @throws TypeError 204 * @psalm-suppress MixedAssignment 205 */ 206 public function mulInt($int = 0, $size = 0) 207 { 208 if (ParagonIE_Sodium_Compat::$fastMult) { 209 return $this->mulIntFast($int); 210 } 211 ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); 212 ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); 213 /** @var int $int */ 214 $int = (int) $int; 215 /** @var int $size */ 216 $size = (int) $size; 217 218 if (!$size) { 219 $size = 63; 220 } 221 222 $a = clone $this; 223 $return = new ParagonIE_Sodium_Core32_Int64(); 224 $return->unsignedInt = $this->unsignedInt; 225 226 // Initialize: 227 $ret0 = 0; 228 $ret1 = 0; 229 $ret2 = 0; 230 $ret3 = 0; 231 $a0 = $a->limbs[0]; 232 $a1 = $a->limbs[1]; 233 $a2 = $a->limbs[2]; 234 $a3 = $a->limbs[3]; 235 236 /** @var int $size */ 237 /** @var int $i */ 238 for ($i = $size; $i >= 0; --$i) { 239 $mask = -($int & 1); 240 $x0 = $a0 & $mask; 241 $x1 = $a1 & $mask; 242 $x2 = $a2 & $mask; 243 $x3 = $a3 & $mask; 244 245 $ret3 += $x3; 246 $c = $ret3 >> 16; 247 248 $ret2 += $x2 + $c; 249 $c = $ret2 >> 16; 250 251 $ret1 += $x1 + $c; 252 $c = $ret1 >> 16; 253 254 $ret0 += $x0 + $c; 255 256 $ret0 &= 0xffff; 257 $ret1 &= 0xffff; 258 $ret2 &= 0xffff; 259 $ret3 &= 0xffff; 260 261 $a3 = $a3 << 1; 262 $x3 = $a3 >> 16; 263 $a2 = ($a2 << 1) | $x3; 264 $x2 = $a2 >> 16; 265 $a1 = ($a1 << 1) | $x2; 266 $x1 = $a1 >> 16; 267 $a0 = ($a0 << 1) | $x1; 268 $a0 &= 0xffff; 269 $a1 &= 0xffff; 270 $a2 &= 0xffff; 271 $a3 &= 0xffff; 272 273 $int >>= 1; 274 } 275 $return->limbs[0] = $ret0; 276 $return->limbs[1] = $ret1; 277 $return->limbs[2] = $ret2; 278 $return->limbs[3] = $ret3; 279 return $return; 280 } 281 282 /** 283 * @param ParagonIE_Sodium_Core32_Int64 $A 284 * @param ParagonIE_Sodium_Core32_Int64 $B 285 * @return array<int, ParagonIE_Sodium_Core32_Int64> 286 * @throws SodiumException 287 * @throws TypeError 288 * @psalm-suppress MixedInferredReturnType 289 */ 290 public static function ctSelect( 291 ParagonIE_Sodium_Core32_Int64 $A, 292 ParagonIE_Sodium_Core32_Int64 $B 293 ) { 294 $a = clone $A; 295 $b = clone $B; 296 /** @var int $aNeg */ 297 $aNeg = ($a->limbs[0] >> 15) & 1; 298 /** @var int $bNeg */ 299 $bNeg = ($b->limbs[0] >> 15) & 1; 300 /** @var int $m */ 301 $m = (-($aNeg & $bNeg)) | 1; 302 /** @var int $swap */ 303 $swap = $bNeg & ~$aNeg; 304 /** @var int $d */ 305 $d = -$swap; 306 307 /* 308 if ($bNeg && !$aNeg) { 309 $a = clone $int; 310 $b = clone $this; 311 } elseif($bNeg && $aNeg) { 312 $a = $this->mulInt(-1); 313 $b = $int->mulInt(-1); 314 } 315 */ 316 $x = $a->xorInt64($b)->mask64($d, $d); 317 return array( 318 $a->xorInt64($x)->mulInt($m), 319 $b->xorInt64($x)->mulInt($m) 320 ); 321 } 322 323 /** 324 * @param array<int, int> $a 325 * @param array<int, int> $b 326 * @param int $baseLog2 327 * @return array<int, int> 328 */ 329 public function multiplyLong(array $a, array $b, $baseLog2 = 16) 330 { 331 $a_l = count($a); 332 $b_l = count($b); 333 /** @var array<int, int> $r */ 334 $r = array_fill(0, $a_l + $b_l + 1, 0); 335 $base = 1 << $baseLog2; 336 for ($i = 0; $i < $a_l; ++$i) { 337 $a_i = $a[$i]; 338 for ($j = 0; $j < $a_l; ++$j) { 339 $b_j = $b[$j]; 340 $product = (($a_i * $b_j) + $r[$i + $j]); 341 $carry = (((int) $product >> $baseLog2) & 0xffff); 342 $r[$i + $j] = ((int) $product - (int) ($carry * $base)) & 0xffff; 343 $r[$i + $j + 1] += $carry; 344 } 345 } 346 return array_slice($r, 0, 5); 347 } 348 349 /** 350 * @param int $int 351 * @return ParagonIE_Sodium_Core32_Int64 352 */ 353 public function mulIntFast($int) 354 { 355 // Handle negative numbers 356 $aNeg = ($this->limbs[0] >> 15) & 1; 357 $bNeg = ($int >> 31) & 1; 358 $a = array_reverse($this->limbs); 359 $b = array( 360 $int & 0xffff, 361 ($int >> 16) & 0xffff, 362 -$bNeg & 0xffff, 363 -$bNeg & 0xffff 364 ); 365 if ($aNeg) { 366 for ($i = 0; $i < 4; ++$i) { 367 $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; 368 } 369 ++$a[0]; 370 } 371 if ($bNeg) { 372 for ($i = 0; $i < 4; ++$i) { 373 $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; 374 } 375 ++$b[0]; 376 } 377 // Multiply 378 $res = $this->multiplyLong($a, $b); 379 380 // Re-apply negation to results 381 if ($aNeg !== $bNeg) { 382 for ($i = 0; $i < 4; ++$i) { 383 $res[$i] = (0xffff ^ $res[$i]) & 0xffff; 384 } 385 // Handle integer overflow 386 $c = 1; 387 for ($i = 0; $i < 4; ++$i) { 388 $res[$i] += $c; 389 $c = $res[$i] >> 16; 390 $res[$i] &= 0xffff; 391 } 392 } 393 394 // Return our values 395 $return = new ParagonIE_Sodium_Core32_Int64(); 396 $return->limbs = array( 397 $res[3] & 0xffff, 398 $res[2] & 0xffff, 399 $res[1] & 0xffff, 400 $res[0] & 0xffff 401 ); 402 if (count($res) > 4) { 403 $return->overflow = $res[4] & 0xffff; 404 } 405 $return->unsignedInt = $this->unsignedInt; 406 return $return; 407 } 408 409 /** 410 * @param ParagonIE_Sodium_Core32_Int64 $right 411 * @return ParagonIE_Sodium_Core32_Int64 412 */ 413 public function mulInt64Fast(ParagonIE_Sodium_Core32_Int64 $right) 414 { 415 $aNeg = ($this->limbs[0] >> 15) & 1; 416 $bNeg = ($right->limbs[0] >> 15) & 1; 417 418 $a = array_reverse($this->limbs); 419 $b = array_reverse($right->limbs); 420 if ($aNeg) { 421 for ($i = 0; $i < 4; ++$i) { 422 $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; 423 } 424 ++$a[0]; 425 } 426 if ($bNeg) { 427 for ($i = 0; $i < 4; ++$i) { 428 $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; 429 } 430 ++$b[0]; 431 } 432 $res = $this->multiplyLong($a, $b); 433 if ($aNeg !== $bNeg) { 434 if ($aNeg !== $bNeg) { 435 for ($i = 0; $i < 4; ++$i) { 436 $res[$i] = ($res[$i] ^ 0xffff) & 0xffff; 437 } 438 $c = 1; 439 for ($i = 0; $i < 4; ++$i) { 440 $res[$i] += $c; 441 $c = $res[$i] >> 16; 442 $res[$i] &= 0xffff; 443 } 444 } 445 } 446 $return = new ParagonIE_Sodium_Core32_Int64(); 447 $return->limbs = array( 448 $res[3] & 0xffff, 449 $res[2] & 0xffff, 450 $res[1] & 0xffff, 451 $res[0] & 0xffff 452 ); 453 if (count($res) > 4) { 454 $return->overflow = $res[4]; 455 } 456 return $return; 457 } 458 459 /** 460 * @param ParagonIE_Sodium_Core32_Int64 $int 461 * @param int $size 462 * @return ParagonIE_Sodium_Core32_Int64 463 * @throws SodiumException 464 * @throws TypeError 465 * @psalm-suppress MixedAssignment 466 */ 467 public function mulInt64(ParagonIE_Sodium_Core32_Int64 $int, $size = 0) 468 { 469 if (ParagonIE_Sodium_Compat::$fastMult) { 470 return $this->mulInt64Fast($int); 471 } 472 ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); 473 if (!$size) { 474 $size = 63; 475 } 476 list($a, $b) = self::ctSelect($this, $int); 477 478 $return = new ParagonIE_Sodium_Core32_Int64(); 479 $return->unsignedInt = $this->unsignedInt; 480 481 // Initialize: 482 $ret0 = 0; 483 $ret1 = 0; 484 $ret2 = 0; 485 $ret3 = 0; 486 $a0 = $a->limbs[0]; 487 $a1 = $a->limbs[1]; 488 $a2 = $a->limbs[2]; 489 $a3 = $a->limbs[3]; 490 $b0 = $b->limbs[0]; 491 $b1 = $b->limbs[1]; 492 $b2 = $b->limbs[2]; 493 $b3 = $b->limbs[3]; 494 495 /** @var int $size */ 496 /** @var int $i */ 497 for ($i = (int) $size; $i >= 0; --$i) { 498 $mask = -($b3 & 1); 499 $x0 = $a0 & $mask; 500 $x1 = $a1 & $mask; 501 $x2 = $a2 & $mask; 502 $x3 = $a3 & $mask; 503 504 $ret3 += $x3; 505 $c = $ret3 >> 16; 506 507 $ret2 += $x2 + $c; 508 $c = $ret2 >> 16; 509 510 $ret1 += $x1 + $c; 511 $c = $ret1 >> 16; 512 513 $ret0 += $x0 + $c; 514 515 $ret0 &= 0xffff; 516 $ret1 &= 0xffff; 517 $ret2 &= 0xffff; 518 $ret3 &= 0xffff; 519 520 $a3 = $a3 << 1; 521 $x3 = $a3 >> 16; 522 $a2 = ($a2 << 1) | $x3; 523 $x2 = $a2 >> 16; 524 $a1 = ($a1 << 1) | $x2; 525 $x1 = $a1 >> 16; 526 $a0 = ($a0 << 1) | $x1; 527 $a0 &= 0xffff; 528 $a1 &= 0xffff; 529 $a2 &= 0xffff; 530 $a3 &= 0xffff; 531 532 $x0 = ($b0 & 1) << 16; 533 $x1 = ($b1 & 1) << 16; 534 $x2 = ($b2 & 1) << 16; 535 536 $b0 = ($b0 >> 1); 537 $b1 = (($b1 | $x0) >> 1); 538 $b2 = (($b2 | $x1) >> 1); 539 $b3 = (($b3 | $x2) >> 1); 540 541 $b0 &= 0xffff; 542 $b1 &= 0xffff; 543 $b2 &= 0xffff; 544 $b3 &= 0xffff; 545 546 } 547 $return->limbs[0] = $ret0; 548 $return->limbs[1] = $ret1; 549 $return->limbs[2] = $ret2; 550 $return->limbs[3] = $ret3; 551 552 return $return; 553 } 554 555 /** 556 * OR this 64-bit integer with another. 557 * 558 * @param ParagonIE_Sodium_Core32_Int64 $b 559 * @return ParagonIE_Sodium_Core32_Int64 560 */ 561 public function orInt64(ParagonIE_Sodium_Core32_Int64 $b) 562 { 563 $return = new ParagonIE_Sodium_Core32_Int64(); 564 $return->unsignedInt = $this->unsignedInt; 565 $return->limbs = array( 566 (int) ($this->limbs[0] | $b->limbs[0]), 567 (int) ($this->limbs[1] | $b->limbs[1]), 568 (int) ($this->limbs[2] | $b->limbs[2]), 569 (int) ($this->limbs[3] | $b->limbs[3]) 570 ); 571 return $return; 572 } 573 574 /** 575 * @param int $c 576 * @return ParagonIE_Sodium_Core32_Int64 577 * @throws SodiumException 578 * @throws TypeError 579 * @psalm-suppress MixedArrayAccess 580 */ 581 public function rotateLeft($c = 0) 582 { 583 ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); 584 /** @var int $c */ 585 $c = (int) $c; 586 587 $return = new ParagonIE_Sodium_Core32_Int64(); 588 $return->unsignedInt = $this->unsignedInt; 589 $c &= 63; 590 if ($c === 0) { 591 // NOP, but we want a copy. 592 $return->limbs = $this->limbs; 593 } else { 594 /** @var array<int, int> $limbs */ 595 $limbs =& $return->limbs; 596 597 /** @var array<int, int> $myLimbs */ 598 $myLimbs =& $this->limbs; 599 600 /** @var int $idx_shift */ 601 $idx_shift = ($c >> 4) & 3; 602 /** @var int $sub_shift */ 603 $sub_shift = $c & 15; 604 605 for ($i = 3; $i >= 0; --$i) { 606 /** @var int $j */ 607 $j = ($i + $idx_shift) & 3; 608 /** @var int $k */ 609 $k = ($i + $idx_shift + 1) & 3; 610 $limbs[$i] = (int) ( 611 ( 612 ((int) ($myLimbs[$j]) << $sub_shift) 613 | 614 ((int) ($myLimbs[$k]) >> (16 - $sub_shift)) 615 ) & 0xffff 616 ); 617 } 618 } 619 return $return; 620 } 621 622 /** 623 * Rotate to the right 624 * 625 * @param int $c 626 * @return ParagonIE_Sodium_Core32_Int64 627 * @throws SodiumException 628 * @throws TypeError 629 * @psalm-suppress MixedArrayAccess 630 */ 631 public function rotateRight($c = 0) 632 { 633 ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); 634 /** @var int $c */ 635 $c = (int) $c; 636 637 /** @var ParagonIE_Sodium_Core32_Int64 $return */ 638 $return = new ParagonIE_Sodium_Core32_Int64(); 639 $return->unsignedInt = $this->unsignedInt; 640 $c &= 63; 641 /** @var int $c */ 642 if ($c === 0) { 643 // NOP, but we want a copy. 644 $return->limbs = $this->limbs; 645 } else { 646 /** @var array<int, int> $limbs */ 647 $limbs =& $return->limbs; 648 649 /** @var array<int, int> $myLimbs */ 650 $myLimbs =& $this->limbs; 651 652 /** @var int $idx_shift */ 653 $idx_shift = ($c >> 4) & 3; 654 /** @var int $sub_shift */ 655 $sub_shift = $c & 15; 656 657 for ($i = 3; $i >= 0; --$i) { 658 /** @var int $j */ 659 $j = ($i - $idx_shift) & 3; 660 /** @var int $k */ 661 $k = ($i - $idx_shift - 1) & 3; 662 $limbs[$i] = (int) ( 663 ( 664 ((int) ($myLimbs[$j]) >> (int) ($sub_shift)) 665 | 666 ((int) ($myLimbs[$k]) << (16 - (int) ($sub_shift))) 667 ) & 0xffff 668 ); 669 } 670 } 671 return $return; 672 } 673 /** 674 * @param int $c 675 * @return ParagonIE_Sodium_Core32_Int64 676 * @throws SodiumException 677 * @throws TypeError 678 */ 679 public function shiftLeft($c = 0) 680 { 681 ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); 682 /** @var int $c */ 683 $c = (int) $c; 684 685 $return = new ParagonIE_Sodium_Core32_Int64(); 686 $return->unsignedInt = $this->unsignedInt; 687 $c &= 63; 688 689 if ($c >= 16) { 690 if ($c >= 48) { 691 $return->limbs = array( 692 $this->limbs[3], 0, 0, 0 693 ); 694 } elseif ($c >= 32) { 695 $return->limbs = array( 696 $this->limbs[2], $this->limbs[3], 0, 0 697 ); 698 } else { 699 $return->limbs = array( 700 $this->limbs[1], $this->limbs[2], $this->limbs[3], 0 701 ); 702 } 703 return $return->shiftLeft($c & 15); 704 } 705 if ($c === 0) { 706 $return->limbs = $this->limbs; 707 } elseif ($c < 0) { 708 /** @var int $c */ 709 return $this->shiftRight(-$c); 710 } else { 711 if (!is_int($c)) { 712 throw new TypeError(); 713 } 714 /** @var int $carry */ 715 $carry = 0; 716 for ($i = 3; $i >= 0; --$i) { 717 /** @var int $tmp */ 718 $tmp = ($this->limbs[$i] << $c) | ($carry & 0xffff); 719 $return->limbs[$i] = (int) ($tmp & 0xffff); 720 /** @var int $carry */ 721 $carry = $tmp >> 16; 722 } 723 } 724 return $return; 725 } 726 727 /** 728 * @param int $c 729 * @return ParagonIE_Sodium_Core32_Int64 730 * @throws SodiumException 731 * @throws TypeError 732 */ 733 public function shiftRight($c = 0) 734 { 735 ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); 736 $c = (int) $c; 737 /** @var int $c */ 738 $return = new ParagonIE_Sodium_Core32_Int64(); 739 $return->unsignedInt = $this->unsignedInt; 740 $c &= 63; 741 742 $negative = -(($this->limbs[0] >> 15) & 1); 743 if ($c >= 16) { 744 if ($c >= 48) { 745 $return->limbs = array( 746 (int) ($negative & 0xffff), 747 (int) ($negative & 0xffff), 748 (int) ($negative & 0xffff), 749 (int) $this->limbs[0] 750 ); 751 } elseif ($c >= 32) { 752 $return->limbs = array( 753 (int) ($negative & 0xffff), 754 (int) ($negative & 0xffff), 755 (int) $this->limbs[0], 756 (int) $this->limbs[1] 757 ); 758 } else { 759 $return->limbs = array( 760 (int) ($negative & 0xffff), 761 (int) $this->limbs[0], 762 (int) $this->limbs[1], 763 (int) $this->limbs[2] 764 ); 765 } 766 return $return->shiftRight($c & 15); 767 } 768 769 if ($c === 0) { 770 $return->limbs = $this->limbs; 771 } elseif ($c < 0) { 772 return $this->shiftLeft(-$c); 773 } else { 774 if (!is_int($c)) { 775 throw new TypeError(); 776 } 777 /** @var int $carryRight */ 778 $carryRight = ($negative & 0xffff); 779 $mask = (int) (((1 << ($c + 1)) - 1) & 0xffff); 780 for ($i = 0; $i < 4; ++$i) { 781 $return->limbs[$i] = (int) ( 782 (($this->limbs[$i] >> $c) | ($carryRight << (16 - $c))) & 0xffff 783 ); 784 $carryRight = (int) ($this->limbs[$i] & $mask); 785 } 786 } 787 return $return; 788 } 789 790 791 /** 792 * Subtract a normal integer from an int64 object. 793 * 794 * @param int $int 795 * @return ParagonIE_Sodium_Core32_Int64 796 * @throws SodiumException 797 * @throws TypeError 798 */ 799 public function subInt($int) 800 { 801 ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); 802 $int = (int) $int; 803 804 $return = new ParagonIE_Sodium_Core32_Int64(); 805 $return->unsignedInt = $this->unsignedInt; 806 807 /** @var int $carry */ 808 $carry = 0; 809 for ($i = 3; $i >= 0; --$i) { 810 /** @var int $tmp */ 811 $tmp = $this->limbs[$i] - (($int >> 16) & 0xffff) + $carry; 812 /** @var int $carry */ 813 $carry = $tmp >> 16; 814 $return->limbs[$i] = (int) ($tmp & 0xffff); 815 } 816 return $return; 817 } 818 819 /** 820 * The difference between two Int64 objects. 821 * 822 * @param ParagonIE_Sodium_Core32_Int64 $b 823 * @return ParagonIE_Sodium_Core32_Int64 824 */ 825 public function subInt64(ParagonIE_Sodium_Core32_Int64 $b) 826 { 827 $return = new ParagonIE_Sodium_Core32_Int64(); 828 $return->unsignedInt = $this->unsignedInt; 829 /** @var int $carry */ 830 $carry = 0; 831 for ($i = 3; $i >= 0; --$i) { 832 /** @var int $tmp */ 833 $tmp = $this->limbs[$i] - $b->limbs[$i] + $carry; 834 /** @var int $carry */ 835 $carry = ($tmp >> 16); 836 $return->limbs[$i] = (int) ($tmp & 0xffff); 837 } 838 return $return; 839 } 840 841 /** 842 * XOR this 64-bit integer with another. 843 * 844 * @param ParagonIE_Sodium_Core32_Int64 $b 845 * @return ParagonIE_Sodium_Core32_Int64 846 */ 847 public function xorInt64(ParagonIE_Sodium_Core32_Int64 $b) 848 { 849 $return = new ParagonIE_Sodium_Core32_Int64(); 850 $return->unsignedInt = $this->unsignedInt; 851 $return->limbs = array( 852 (int) ($this->limbs[0] ^ $b->limbs[0]), 853 (int) ($this->limbs[1] ^ $b->limbs[1]), 854 (int) ($this->limbs[2] ^ $b->limbs[2]), 855 (int) ($this->limbs[3] ^ $b->limbs[3]) 856 ); 857 return $return; 858 } 859 860 /** 861 * @param int $low 862 * @param int $high 863 * @return self 864 * @throws SodiumException 865 * @throws TypeError 866 */ 867 public static function fromInts($low, $high) 868 { 869 ParagonIE_Sodium_Core32_Util::declareScalarType($low, 'int', 1); 870 ParagonIE_Sodium_Core32_Util::declareScalarType($high, 'int', 2); 871 872 $high = (int) $high; 873 $low = (int) $low; 874 return new ParagonIE_Sodium_Core32_Int64( 875 array( 876 (int) (($high >> 16) & 0xffff), 877 (int) ($high & 0xffff), 878 (int) (($low >> 16) & 0xffff), 879 (int) ($low & 0xffff) 880 ) 881 ); 882 } 883 884 /** 885 * @param int $low 886 * @return self 887 * @throws SodiumException 888 * @throws TypeError 889 */ 890 public static function fromInt($low) 891 { 892 ParagonIE_Sodium_Core32_Util::declareScalarType($low, 'int', 1); 893 $low = (int) $low; 894 895 return new ParagonIE_Sodium_Core32_Int64( 896 array( 897 0, 898 0, 899 (int) (($low >> 16) & 0xffff), 900 (int) ($low & 0xffff) 901 ) 902 ); 903 } 904 905 /** 906 * @return int 907 */ 908 public function toInt() 909 { 910 return (int) ( 911 (($this->limbs[2] & 0xffff) << 16) 912 | 913 ($this->limbs[3] & 0xffff) 914 ); 915 } 916 917 /** 918 * @param string $string 919 * @return self 920 * @throws SodiumException 921 * @throws TypeError 922 */ 923 public static function fromString($string) 924 { 925 ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1); 926 $string = (string) $string; 927 if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 8) { 928 throw new RangeException( 929 'String must be 8 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.' 930 ); 931 } 932 $return = new ParagonIE_Sodium_Core32_Int64(); 933 934 $return->limbs[0] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff) << 8); 935 $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff); 936 $return->limbs[1] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff) << 8); 937 $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff); 938 $return->limbs[2] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[4]) & 0xff) << 8); 939 $return->limbs[2] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[5]) & 0xff); 940 $return->limbs[3] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[6]) & 0xff) << 8); 941 $return->limbs[3] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[7]) & 0xff); 942 return $return; 943 } 944 945 /** 946 * @param string $string 947 * @return self 948 * @throws SodiumException 949 * @throws TypeError 950 */ 951 public static function fromReverseString($string) 952 { 953 ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1); 954 $string = (string) $string; 955 if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 8) { 956 throw new RangeException( 957 'String must be 8 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.' 958 ); 959 } 960 $return = new ParagonIE_Sodium_Core32_Int64(); 961 962 $return->limbs[0] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[7]) & 0xff) << 8); 963 $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[6]) & 0xff); 964 $return->limbs[1] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[5]) & 0xff) << 8); 965 $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[4]) & 0xff); 966 $return->limbs[2] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff) << 8); 967 $return->limbs[2] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff); 968 $return->limbs[3] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff) << 8); 969 $return->limbs[3] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff); 970 return $return; 971 } 972 973 /** 974 * @return array<int, int> 975 */ 976 public function toArray() 977 { 978 return array( 979 (int) ((($this->limbs[0] & 0xffff) << 16) | ($this->limbs[1] & 0xffff)), 980 (int) ((($this->limbs[2] & 0xffff) << 16) | ($this->limbs[3] & 0xffff)) 981 ); 982 } 983 984 /** 985 * @return ParagonIE_Sodium_Core32_Int32 986 */ 987 public function toInt32() 988 { 989 $return = new ParagonIE_Sodium_Core32_Int32(); 990 $return->limbs[0] = (int) ($this->limbs[2]); 991 $return->limbs[1] = (int) ($this->limbs[3]); 992 $return->unsignedInt = $this->unsignedInt; 993 $return->overflow = (int) (ParagonIE_Sodium_Core32_Util::abs($this->limbs[1], 16) & 0xffff); 994 return $return; 995 } 996 997 /** 998 * @return ParagonIE_Sodium_Core32_Int64 999 */ 1000 public function toInt64() 1001 { 1002 $return = new ParagonIE_Sodium_Core32_Int64(); 1003 $return->limbs[0] = (int) ($this->limbs[0]); 1004 $return->limbs[1] = (int) ($this->limbs[1]); 1005 $return->limbs[2] = (int) ($this->limbs[2]); 1006 $return->limbs[3] = (int) ($this->limbs[3]); 1007 $return->unsignedInt = $this->unsignedInt; 1008 $return->overflow = ParagonIE_Sodium_Core32_Util::abs($this->overflow); 1009 return $return; 1010 } 1011 1012 /** 1013 * @param bool $bool 1014 * @return self 1015 */ 1016 public function setUnsignedInt($bool = false) 1017 { 1018 $this->unsignedInt = !empty($bool); 1019 return $this; 1020 } 1021 1022 /** 1023 * @return string 1024 * @throws TypeError 1025 */ 1026 public function toString() 1027 { 1028 return ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff) . 1029 ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) . 1030 ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) . 1031 ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff) . 1032 ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[2] >> 8) & 0xff) . 1033 ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[2] & 0xff) . 1034 ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[3] >> 8) & 0xff) . 1035 ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[3] & 0xff); 1036 } 1037 1038 /** 1039 * @return string 1040 * @throws TypeError 1041 */ 1042 public function toReverseString() 1043 { 1044 return ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[3] & 0xff) . 1045 ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[3] >> 8) & 0xff) . 1046 ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[2] & 0xff) . 1047 ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[2] >> 8) & 0xff) . 1048 ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff) . 1049 ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) . 1050 ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) . 1051 ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff); 1052 } 1053 1054 /** 1055 * @return string 1056 */ 1057 public function __toString() 1058 { 1059 try { 1060 return $this->toString(); 1061 } catch (TypeError $ex) { 1062 // PHP engine can't handle exceptions from __toString() 1063 return ''; 1064 } 1065 } 1066 }
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 |