Diff: STRATO-apps/wordpress_03/app/wp-includes/sodium_compat/src/Core32/Int32.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 +
3 + /**
4 + * Class ParagonIE_Sodium_Core32_Int32
5 + *
6 + * Encapsulates a 32-bit integer.
7 + *
8 + * These are immutable. It always returns a new instance.
9 + */
10 + class ParagonIE_Sodium_Core32_Int32
11 + {
12 + /**
13 + * @var array<int, int> - two 16-bit integers
14 + *
15 + * 0 is the higher 16 bits
16 + * 1 is the lower 16 bits
17 + */
18 + public $limbs = array(0, 0);
19 +
20 + /**
21 + * @var int
22 + */
23 + public $overflow = 0;
24 +
25 + /**
26 + * @var bool
27 + */
28 + public $unsignedInt = false;
29 +
30 + /**
31 + * ParagonIE_Sodium_Core32_Int32 constructor.
32 + * @param array $array
33 + * @param bool $unsignedInt
34 + */
35 + public function __construct($array = array(0, 0), $unsignedInt = false)
36 + {
37 + $this->limbs = array(
38 + (int) $array[0],
39 + (int) $array[1]
40 + );
41 + $this->overflow = 0;
42 + $this->unsignedInt = $unsignedInt;
43 + }
44 +
45 + /**
46 + * Adds two int32 objects
47 + *
48 + * @param ParagonIE_Sodium_Core32_Int32 $addend
49 + * @return ParagonIE_Sodium_Core32_Int32
50 + */
51 + public function addInt32(ParagonIE_Sodium_Core32_Int32 $addend)
52 + {
53 + $i0 = $this->limbs[0];
54 + $i1 = $this->limbs[1];
55 + $j0 = $addend->limbs[0];
56 + $j1 = $addend->limbs[1];
57 +
58 + $r1 = $i1 + ($j1 & 0xffff);
59 + $carry = $r1 >> 16;
60 +
61 + $r0 = $i0 + ($j0 & 0xffff) + $carry;
62 + $carry = $r0 >> 16;
63 +
64 + $r0 &= 0xffff;
65 + $r1 &= 0xffff;
66 +
67 + $return = new ParagonIE_Sodium_Core32_Int32(
68 + array($r0, $r1)
69 + );
70 + $return->overflow = $carry;
71 + $return->unsignedInt = $this->unsignedInt;
72 + return $return;
73 + }
74 +
75 + /**
76 + * Adds a normal integer to an int32 object
77 + *
78 + * @param int $int
79 + * @return ParagonIE_Sodium_Core32_Int32
80 + * @throws SodiumException
81 + * @throws TypeError
82 + */
83 + public function addInt($int)
84 + {
85 + ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1);
86 + /** @var int $int */
87 + $int = (int) $int;
88 +
89 + $int = (int) $int;
90 +
91 + $i0 = $this->limbs[0];
92 + $i1 = $this->limbs[1];
93 +
94 + $r1 = $i1 + ($int & 0xffff);
95 + $carry = $r1 >> 16;
96 +
97 + $r0 = $i0 + (($int >> 16) & 0xffff) + $carry;
98 + $carry = $r0 >> 16;
99 + $r0 &= 0xffff;
100 + $r1 &= 0xffff;
101 + $return = new ParagonIE_Sodium_Core32_Int32(
102 + array($r0, $r1)
103 + );
104 + $return->overflow = $carry;
105 + $return->unsignedInt = $this->unsignedInt;
106 + return $return;
107 + }
108 +
109 + /**
110 + * @param int $b
111 + * @return int
112 + */
113 + public function compareInt($b = 0)
114 + {
115 + $gt = 0;
116 + $eq = 1;
117 +
118 + $i = 2;
119 + $j = 0;
120 + while ($i > 0) {
121 + --$i;
122 + /** @var int $x1 */
123 + $x1 = $this->limbs[$i];
124 + /** @var int $x2 */
125 + $x2 = ($b >> ($j << 4)) & 0xffff;
126 + /** @var int $gt */
127 + $gt |= (($x2 - $x1) >> 8) & $eq;
128 + /** @var int $eq */
129 + $eq &= (($x2 ^ $x1) - 1) >> 8;
130 + }
131 + return ($gt + $gt - $eq) + 1;
132 + }
133 +
134 + /**
135 + * @param int $m
136 + * @return ParagonIE_Sodium_Core32_Int32
137 + */
138 + public function mask($m = 0)
139 + {
140 + /** @var int $hi */
141 + $hi = ((int) $m >> 16);
142 + $hi &= 0xffff;
143 + /** @var int $lo */
144 + $lo = ((int) $m) & 0xffff;
145 + return new ParagonIE_Sodium_Core32_Int32(
146 + array(
147 + (int) ($this->limbs[0] & $hi),
148 + (int) ($this->limbs[1] & $lo)
149 + ),
150 + $this->unsignedInt
151 + );
152 + }
153 +
154 + /**
155 + * @param array<int, int> $a
156 + * @param array<int, int> $b
157 + * @param int $baseLog2
158 + * @return array<int, int>
159 + */
160 + public function multiplyLong(array $a, array $b, $baseLog2 = 16)
161 + {
162 + $a_l = count($a);
163 + $b_l = count($b);
164 + /** @var array<int, int> $r */
165 + $r = array_fill(0, $a_l + $b_l + 1, 0);
166 + $base = 1 << $baseLog2;
167 + for ($i = 0; $i < $a_l; ++$i) {
168 + $a_i = $a[$i];
169 + for ($j = 0; $j < $a_l; ++$j) {
170 + $b_j = $b[$j];
171 + $product = ($a_i * $b_j) + $r[$i + $j];
172 + $carry = ((int) $product >> $baseLog2 & 0xffff);
173 + $r[$i + $j] = ((int) $product - (int) ($carry * $base)) & 0xffff;
174 + $r[$i + $j + 1] += $carry;
175 + }
176 + }
177 + return array_slice($r, 0, 5);
178 + }
179 +
180 + /**
181 + * @param int $int
182 + * @return ParagonIE_Sodium_Core32_Int32
183 + */
184 + public function mulIntFast($int)
185 + {
186 + // Handle negative numbers
187 + $aNeg = ($this->limbs[0] >> 15) & 1;
188 + $bNeg = ($int >> 31) & 1;
189 + $a = array_reverse($this->limbs);
190 + $b = array(
191 + $int & 0xffff,
192 + ($int >> 16) & 0xffff
193 + );
194 + if ($aNeg) {
195 + for ($i = 0; $i < 2; ++$i) {
196 + $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
197 + }
198 + ++$a[0];
199 + }
200 + if ($bNeg) {
201 + for ($i = 0; $i < 2; ++$i) {
202 + $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
203 + }
204 + ++$b[0];
205 + }
206 + // Multiply
207 + $res = $this->multiplyLong($a, $b);
208 +
209 + // Re-apply negation to results
210 + if ($aNeg !== $bNeg) {
211 + for ($i = 0; $i < 2; ++$i) {
212 + $res[$i] = (0xffff ^ $res[$i]) & 0xffff;
213 + }
214 + // Handle integer overflow
215 + $c = 1;
216 + for ($i = 0; $i < 2; ++$i) {
217 + $res[$i] += $c;
218 + $c = $res[$i] >> 16;
219 + $res[$i] &= 0xffff;
220 + }
221 + }
222 +
223 + // Return our values
224 + $return = new ParagonIE_Sodium_Core32_Int32();
225 + $return->limbs = array(
226 + $res[1] & 0xffff,
227 + $res[0] & 0xffff
228 + );
229 + if (count($res) > 2) {
230 + $return->overflow = $res[2] & 0xffff;
231 + }
232 + $return->unsignedInt = $this->unsignedInt;
233 + return $return;
234 + }
235 +
236 + /**
237 + * @param ParagonIE_Sodium_Core32_Int32 $right
238 + * @return ParagonIE_Sodium_Core32_Int32
239 + */
240 + public function mulInt32Fast(ParagonIE_Sodium_Core32_Int32 $right)
241 + {
242 + $aNeg = ($this->limbs[0] >> 15) & 1;
243 + $bNeg = ($right->limbs[0] >> 15) & 1;
244 +
245 + $a = array_reverse($this->limbs);
246 + $b = array_reverse($right->limbs);
247 + if ($aNeg) {
248 + for ($i = 0; $i < 2; ++$i) {
249 + $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
250 + }
251 + ++$a[0];
252 + }
253 + if ($bNeg) {
254 + for ($i = 0; $i < 2; ++$i) {
255 + $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
256 + }
257 + ++$b[0];
258 + }
259 + $res = $this->multiplyLong($a, $b);
260 + if ($aNeg !== $bNeg) {
261 + if ($aNeg !== $bNeg) {
262 + for ($i = 0; $i < 2; ++$i) {
263 + $res[$i] = ($res[$i] ^ 0xffff) & 0xffff;
264 + }
265 + $c = 1;
266 + for ($i = 0; $i < 2; ++$i) {
267 + $res[$i] += $c;
268 + $c = $res[$i] >> 16;
269 + $res[$i] &= 0xffff;
270 + }
271 + }
272 + }
273 + $return = new ParagonIE_Sodium_Core32_Int32();
274 + $return->limbs = array(
275 + $res[1] & 0xffff,
276 + $res[0] & 0xffff
277 + );
278 + if (count($res) > 2) {
279 + $return->overflow = $res[2];
280 + }
281 + return $return;
282 + }
283 +
284 + /**
285 + * @param int $int
286 + * @param int $size
287 + * @return ParagonIE_Sodium_Core32_Int32
288 + * @throws SodiumException
289 + * @throws TypeError
290 + */
291 + public function mulInt($int = 0, $size = 0)
292 + {
293 + ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1);
294 + ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
295 + if (ParagonIE_Sodium_Compat::$fastMult) {
296 + return $this->mulIntFast((int) $int);
297 + }
298 + /** @var int $int */
299 + $int = (int) $int;
300 + /** @var int $size */
301 + $size = (int) $size;
302 +
303 + if (!$size) {
304 + $size = 31;
305 + }
306 + /** @var int $size */
307 +
308 + $a = clone $this;
309 + $return = new ParagonIE_Sodium_Core32_Int32();
310 + $return->unsignedInt = $this->unsignedInt;
311 +
312 + // Initialize:
313 + $ret0 = 0;
314 + $ret1 = 0;
315 + $a0 = $a->limbs[0];
316 + $a1 = $a->limbs[1];
317 +
318 + /** @var int $size */
319 + /** @var int $i */
320 + for ($i = $size; $i >= 0; --$i) {
321 + $m = (int) (-($int & 1));
322 + $x0 = $a0 & $m;
323 + $x1 = $a1 & $m;
324 +
325 + $ret1 += $x1;
326 + $c = $ret1 >> 16;
327 +
328 + $ret0 += $x0 + $c;
329 +
330 + $ret0 &= 0xffff;
331 + $ret1 &= 0xffff;
332 +
333 + $a1 = ($a1 << 1);
334 + $x1 = $a1 >> 16;
335 + $a0 = ($a0 << 1) | $x1;
336 + $a0 &= 0xffff;
337 + $a1 &= 0xffff;
338 + $int >>= 1;
339 + }
340 + $return->limbs[0] = $ret0;
341 + $return->limbs[1] = $ret1;
342 + return $return;
343 + }
344 +
345 + /**
346 + * @param ParagonIE_Sodium_Core32_Int32 $int
347 + * @param int $size
348 + * @return ParagonIE_Sodium_Core32_Int32
349 + * @throws SodiumException
350 + * @throws TypeError
351 + */
352 + public function mulInt32(ParagonIE_Sodium_Core32_Int32 $int, $size = 0)
353 + {
354 + ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
355 + if (ParagonIE_Sodium_Compat::$fastMult) {
356 + return $this->mulInt32Fast($int);
357 + }
358 + if (!$size) {
359 + $size = 31;
360 + }
361 + /** @var int $size */
362 +
363 + $a = clone $this;
364 + $b = clone $int;
365 + $return = new ParagonIE_Sodium_Core32_Int32();
366 + $return->unsignedInt = $this->unsignedInt;
367 +
368 + // Initialize:
369 + $ret0 = 0;
370 + $ret1 = 0;
371 + $a0 = $a->limbs[0];
372 + $a1 = $a->limbs[1];
373 + $b0 = $b->limbs[0];
374 + $b1 = $b->limbs[1];
375 +
376 + /** @var int $size */
377 + /** @var int $i */
378 + for ($i = $size; $i >= 0; --$i) {
379 + $m = (int) (-($b1 & 1));
380 + $x0 = $a0 & $m;
381 + $x1 = $a1 & $m;
382 +
383 + $ret1 += $x1;
384 + $c = $ret1 >> 16;
385 +
386 + $ret0 += $x0 + $c;
387 +
388 + $ret0 &= 0xffff;
389 + $ret1 &= 0xffff;
390 +
391 + $a1 = ($a1 << 1);
392 + $x1 = $a1 >> 16;
393 + $a0 = ($a0 << 1) | $x1;
394 + $a0 &= 0xffff;
395 + $a1 &= 0xffff;
396 +
397 + $x0 = ($b0 & 1) << 16;
398 + $b0 = ($b0 >> 1);
399 + $b1 = (($b1 | $x0) >> 1);
400 +
401 + $b0 &= 0xffff;
402 + $b1 &= 0xffff;
403 +
404 + }
405 + $return->limbs[0] = $ret0;
406 + $return->limbs[1] = $ret1;
407 +
408 + return $return;
409 + }
410 +
411 + /**
412 + * OR this 32-bit integer with another.
413 + *
414 + * @param ParagonIE_Sodium_Core32_Int32 $b
415 + * @return ParagonIE_Sodium_Core32_Int32
416 + */
417 + public function orInt32(ParagonIE_Sodium_Core32_Int32 $b)
418 + {
419 + $return = new ParagonIE_Sodium_Core32_Int32();
420 + $return->unsignedInt = $this->unsignedInt;
421 + $return->limbs = array(
422 + (int) ($this->limbs[0] | $b->limbs[0]),
423 + (int) ($this->limbs[1] | $b->limbs[1])
424 + );
425 + /** @var int overflow */
426 + $return->overflow = $this->overflow | $b->overflow;
427 + return $return;
428 + }
429 +
430 + /**
431 + * @param int $b
432 + * @return bool
433 + */
434 + public function isGreaterThan($b = 0)
435 + {
436 + return $this->compareInt($b) > 0;
437 + }
438 +
439 + /**
440 + * @param int $b
441 + * @return bool
442 + */
443 + public function isLessThanInt($b = 0)
444 + {
445 + return $this->compareInt($b) < 0;
446 + }
447 +
448 + /**
449 + * @param int $c
450 + * @return ParagonIE_Sodium_Core32_Int32
451 + * @throws SodiumException
452 + * @throws TypeError
453 + * @psalm-suppress MixedArrayAccess
454 + */
455 + public function rotateLeft($c = 0)
456 + {
457 + ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1);
458 + /** @var int $c */
459 + $c = (int) $c;
460 +
461 + $return = new ParagonIE_Sodium_Core32_Int32();
462 + $return->unsignedInt = $this->unsignedInt;
463 + $c &= 31;
464 + if ($c === 0) {
465 + // NOP, but we want a copy.
466 + $return->limbs = $this->limbs;
467 + } else {
468 + /** @var int $c */
469 +
470 + /** @var int $idx_shift */
471 + $idx_shift = ($c >> 4) & 1;
472 +
473 + /** @var int $sub_shift */
474 + $sub_shift = $c & 15;
475 +
476 + /** @var array<int, int> $limbs */
477 + $limbs =& $return->limbs;
478 +
479 + /** @var array<int, int> $myLimbs */
480 + $myLimbs =& $this->limbs;
481 +
482 + for ($i = 1; $i >= 0; --$i) {
483 + /** @var int $j */
484 + $j = ($i + $idx_shift) & 1;
485 + /** @var int $k */
486 + $k = ($i + $idx_shift + 1) & 1;
487 + $limbs[$i] = (int) (
488 + (
489 + ((int) ($myLimbs[$j]) << $sub_shift)
490 + |
491 + ((int) ($myLimbs[$k]) >> (16 - $sub_shift))
492 + ) & 0xffff
493 + );
494 + }
495 + }
496 + return $return;
497 + }
498 +
499 + /**
500 + * Rotate to the right
501 + *
502 + * @param int $c
503 + * @return ParagonIE_Sodium_Core32_Int32
504 + * @throws SodiumException
505 + * @throws TypeError
506 + * @psalm-suppress MixedArrayAccess
507 + */
508 + public function rotateRight($c = 0)
509 + {
510 + ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1);
511 + /** @var int $c */
512 + $c = (int) $c;
513 +
514 + $return = new ParagonIE_Sodium_Core32_Int32();
515 + $return->unsignedInt = $this->unsignedInt;
516 + $c &= 31;
517 + /** @var int $c */
518 + if ($c === 0) {
519 + // NOP, but we want a copy.
520 + $return->limbs = $this->limbs;
521 + } else {
522 + /** @var int $c */
523 +
524 + /** @var int $idx_shift */
525 + $idx_shift = ($c >> 4) & 1;
526 +
527 + /** @var int $sub_shift */
528 + $sub_shift = $c & 15;
529 +
530 + /** @var array<int, int> $limbs */
531 + $limbs =& $return->limbs;
532 +
533 + /** @var array<int, int> $myLimbs */
534 + $myLimbs =& $this->limbs;
535 +
536 + for ($i = 1; $i >= 0; --$i) {
537 + /** @var int $j */
538 + $j = ($i - $idx_shift) & 1;
539 + /** @var int $k */
540 + $k = ($i - $idx_shift - 1) & 1;
541 + $limbs[$i] = (int) (
542 + (
543 + ((int) ($myLimbs[$j]) >> (int) ($sub_shift))
544 + |
545 + ((int) ($myLimbs[$k]) << (16 - (int) ($sub_shift)))
546 + ) & 0xffff
547 + );
548 + }
549 + }
550 + return $return;
551 + }
552 +
553 + /**
554 + * @param bool $bool
555 + * @return self
556 + */
557 + public function setUnsignedInt($bool = false)
558 + {
559 + $this->unsignedInt = !empty($bool);
560 + return $this;
561 + }
562 +
563 + /**
564 + * @param int $c
565 + * @return ParagonIE_Sodium_Core32_Int32
566 + * @throws SodiumException
567 + * @throws TypeError
568 + */
569 + public function shiftLeft($c = 0)
570 + {
571 + ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1);
572 + /** @var int $c */
573 + $c = (int) $c;
574 +
575 + $return = new ParagonIE_Sodium_Core32_Int32();
576 + $return->unsignedInt = $this->unsignedInt;
577 + $c &= 63;
578 + /** @var int $c */
579 + if ($c === 0) {
580 + $return->limbs = $this->limbs;
581 + } elseif ($c < 0) {
582 + /** @var int $c */
583 + return $this->shiftRight(-$c);
584 + } else {
585 + /** @var int $c */
586 + /** @var int $tmp */
587 + $tmp = $this->limbs[1] << $c;
588 + $return->limbs[1] = (int)($tmp & 0xffff);
589 + /** @var int $carry */
590 + $carry = $tmp >> 16;
591 +
592 + /** @var int $tmp */
593 + $tmp = ($this->limbs[0] << $c) | ($carry & 0xffff);
594 + $return->limbs[0] = (int) ($tmp & 0xffff);
595 + }
596 + return $return;
597 + }
598 +
599 + /**
600 + * @param int $c
601 + * @return ParagonIE_Sodium_Core32_Int32
602 + * @throws SodiumException
603 + * @throws TypeError
604 + * @psalm-suppress MixedAssignment
605 + * @psalm-suppress MixedOperand
606 + */
607 + public function shiftRight($c = 0)
608 + {
609 + ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1);
610 + /** @var int $c */
611 + $c = (int) $c;
612 +
613 + $return = new ParagonIE_Sodium_Core32_Int32();
614 + $return->unsignedInt = $this->unsignedInt;
615 + $c &= 63;
616 + /** @var int $c */
617 + if ($c >= 16) {
618 + $return->limbs = array(
619 + (int) ($this->overflow & 0xffff),
620 + (int) ($this->limbs[0])
621 + );
622 + $return->overflow = $this->overflow >> 16;
623 + return $return->shiftRight($c & 15);
624 + }
625 + if ($c === 0) {
626 + $return->limbs = $this->limbs;
627 + } elseif ($c < 0) {
628 + /** @var int $c */
629 + return $this->shiftLeft(-$c);
630 + } else {
631 + if (!is_int($c)) {
632 + throw new TypeError();
633 + }
634 + /** @var int $c */
635 + // $return->limbs[0] = (int) (($this->limbs[0] >> $c) & 0xffff);
636 + $carryLeft = (int) ($this->overflow & ((1 << ($c + 1)) - 1));
637 + $return->limbs[0] = (int) ((($this->limbs[0] >> $c) | ($carryLeft << (16 - $c))) & 0xffff);
638 + $carryRight = (int) ($this->limbs[0] & ((1 << ($c + 1)) - 1));
639 + $return->limbs[1] = (int) ((($this->limbs[1] >> $c) | ($carryRight << (16 - $c))) & 0xffff);
640 + $return->overflow >>= $c;
641 + }
642 + return $return;
643 + }
644 +
645 + /**
646 + * Subtract a normal integer from an int32 object.
647 + *
648 + * @param int $int
649 + * @return ParagonIE_Sodium_Core32_Int32
650 + * @throws SodiumException
651 + * @throws TypeError
652 + */
653 + public function subInt($int)
654 + {
655 + ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1);
656 + /** @var int $int */
657 + $int = (int) $int;
658 +
659 + $return = new ParagonIE_Sodium_Core32_Int32();
660 + $return->unsignedInt = $this->unsignedInt;
661 +
662 + /** @var int $tmp */
663 + $tmp = $this->limbs[1] - ($int & 0xffff);
664 + /** @var int $carry */
665 + $carry = $tmp >> 16;
666 + $return->limbs[1] = (int) ($tmp & 0xffff);
667 +
668 + /** @var int $tmp */
669 + $tmp = $this->limbs[0] - (($int >> 16) & 0xffff) + $carry;
670 + $return->limbs[0] = (int) ($tmp & 0xffff);
671 + return $return;
672 + }
673 +
674 + /**
675 + * Subtract two int32 objects from each other
676 + *
677 + * @param ParagonIE_Sodium_Core32_Int32 $b
678 + * @return ParagonIE_Sodium_Core32_Int32
679 + */
680 + public function subInt32(ParagonIE_Sodium_Core32_Int32 $b)
681 + {
682 + $return = new ParagonIE_Sodium_Core32_Int32();
683 + $return->unsignedInt = $this->unsignedInt;
684 +
685 + /** @var int $tmp */
686 + $tmp = $this->limbs[1] - ($b->limbs[1] & 0xffff);
687 + /** @var int $carry */
688 + $carry = $tmp >> 16;
689 + $return->limbs[1] = (int) ($tmp & 0xffff);
690 +
691 + /** @var int $tmp */
692 + $tmp = $this->limbs[0] - ($b->limbs[0] & 0xffff) + $carry;
693 + $return->limbs[0] = (int) ($tmp & 0xffff);
694 + return $return;
695 + }
696 +
697 + /**
698 + * XOR this 32-bit integer with another.
699 + *
700 + * @param ParagonIE_Sodium_Core32_Int32 $b
701 + * @return ParagonIE_Sodium_Core32_Int32
702 + */
703 + public function xorInt32(ParagonIE_Sodium_Core32_Int32 $b)
704 + {
705 + $return = new ParagonIE_Sodium_Core32_Int32();
706 + $return->unsignedInt = $this->unsignedInt;
707 + $return->limbs = array(
708 + (int) ($this->limbs[0] ^ $b->limbs[0]),
709 + (int) ($this->limbs[1] ^ $b->limbs[1])
710 + );
711 + return $return;
712 + }
713 +
714 + /**
715 + * @param int $signed
716 + * @return self
717 + * @throws SodiumException
718 + * @throws TypeError
719 + */
720 + public static function fromInt($signed)
721 + {
722 + ParagonIE_Sodium_Core32_Util::declareScalarType($signed, 'int', 1);;
723 + /** @var int $signed */
724 + $signed = (int) $signed;
725 +
726 + return new ParagonIE_Sodium_Core32_Int32(
727 + array(
728 + (int) (($signed >> 16) & 0xffff),
729 + (int) ($signed & 0xffff)
730 + )
731 + );
732 + }
733 +
734 + /**
735 + * @param string $string
736 + * @return self
737 + * @throws SodiumException
738 + * @throws TypeError
739 + */
740 + public static function fromString($string)
741 + {
742 + ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1);
743 + $string = (string) $string;
744 + if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 4) {
745 + throw new RangeException(
746 + 'String must be 4 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.'
747 + );
748 + }
749 + $return = new ParagonIE_Sodium_Core32_Int32();
750 +
751 + $return->limbs[0] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff) << 8);
752 + $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff);
753 + $return->limbs[1] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff) << 8);
754 + $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff);
755 + return $return;
756 + }
757 +
758 + /**
759 + * @param string $string
760 + * @return self
761 + * @throws SodiumException
762 + * @throws TypeError
763 + */
764 + public static function fromReverseString($string)
765 + {
766 + ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1);
767 + $string = (string) $string;
768 + if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 4) {
769 + throw new RangeException(
770 + 'String must be 4 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.'
771 + );
772 + }
773 + $return = new ParagonIE_Sodium_Core32_Int32();
774 +
775 + $return->limbs[0] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff) << 8);
776 + $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff);
777 + $return->limbs[1] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff) << 8);
778 + $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff);
779 + return $return;
780 + }
781 +
782 + /**
783 + * @return array<int, int>
784 + */
785 + public function toArray()
786 + {
787 + return array((int) ($this->limbs[0] << 16 | $this->limbs[1]));
788 + }
789 +
790 + /**
791 + * @return string
792 + * @throws TypeError
793 + */
794 + public function toString()
795 + {
796 + return
797 + ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff) .
798 + ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) .
799 + ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) .
800 + ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff);
801 + }
802 +
803 + /**
804 + * @return int
805 + */
806 + public function toInt()
807 + {
808 + return (int) (
809 + (($this->limbs[0] & 0xffff) << 16)
810 + |
811 + ($this->limbs[1] & 0xffff)
812 + );
813 + }
814 +
815 + /**
816 + * @return ParagonIE_Sodium_Core32_Int32
817 + */
818 + public function toInt32()
819 + {
820 + $return = new ParagonIE_Sodium_Core32_Int32();
821 + $return->limbs[0] = (int) ($this->limbs[0] & 0xffff);
822 + $return->limbs[1] = (int) ($this->limbs[1] & 0xffff);
823 + $return->unsignedInt = $this->unsignedInt;
824 + $return->overflow = (int) ($this->overflow & 0x7fffffff);
825 + return $return;
826 + }
827 +
828 + /**
829 + * @return ParagonIE_Sodium_Core32_Int64
830 + */
831 + public function toInt64()
832 + {
833 + $return = new ParagonIE_Sodium_Core32_Int64();
834 + $return->unsignedInt = $this->unsignedInt;
835 + if ($this->unsignedInt) {
836 + $return->limbs[0] += (($this->overflow >> 16) & 0xffff);
837 + $return->limbs[1] += (($this->overflow) & 0xffff);
838 + } else {
839 + $neg = -(($this->limbs[0] >> 15) & 1);
840 + $return->limbs[0] = (int)($neg & 0xffff);
841 + $return->limbs[1] = (int)($neg & 0xffff);
842 + }
843 + $return->limbs[2] = (int) ($this->limbs[0] & 0xffff);
844 + $return->limbs[3] = (int) ($this->limbs[1] & 0xffff);
845 + return $return;
846 + }
847 +
848 + /**
849 + * @return string
850 + * @throws TypeError
851 + */
852 + public function toReverseString()
853 + {
854 + return ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff) .
855 + ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) .
856 + ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) .
857 + ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff);
858 + }
859 +
860 + /**
861 + * @return string
862 + */
863 + public function __toString()
864 + {
865 + try {
866 + return $this->toString();
867 + } catch (TypeError $ex) {
868 + // PHP engine can't handle exceptions from __toString()
869 + return '';
870 + }
871 + }
872 + }
873 +