/home/kueuepay/public_html/vendor/paragonie/sodium_compat/src/Core32/Int64.php
<?php

/**
 * Class ParagonIE_Sodium_Core32_Int64
 *
 * Encapsulates a 64-bit integer.
 *
 * These are immutable. It always returns a new instance.
 */
class ParagonIE_Sodium_Core32_Int64
{
    /**
     * @var array<int, int> - four 16-bit integers
     */
    public $limbs = array(0, 0, 0, 0);

    /**
     * @var int
     */
    public $overflow = 0;

    /**
     * @var bool
     */
    public $unsignedInt = false;

    /**
     * ParagonIE_Sodium_Core32_Int64 constructor.
     * @param array $array
     * @param bool $unsignedInt
     */
    public function __construct($array = array(0, 0, 0, 0), $unsignedInt = false)
    {
        $this->limbs = array(
            (int) $array[0],
            (int) $array[1],
            (int) $array[2],
            (int) $array[3]
        );
        $this->overflow = 0;
        $this->unsignedInt = $unsignedInt;
    }

    /**
     * Adds two int64 objects
     *
     * @param ParagonIE_Sodium_Core32_Int64 $addend
     * @return ParagonIE_Sodium_Core32_Int64
     */
    public function addInt64(ParagonIE_Sodium_Core32_Int64 $addend)
    {
        $i0 = $this->limbs[0];
        $i1 = $this->limbs[1];
        $i2 = $this->limbs[2];
        $i3 = $this->limbs[3];
        $j0 = $addend->limbs[0];
        $j1 = $addend->limbs[1];
        $j2 = $addend->limbs[2];
        $j3 = $addend->limbs[3];

        $r3 = $i3 + ($j3 & 0xffff);
        $carry = $r3 >> 16;

        $r2 = $i2 + ($j2 & 0xffff) + $carry;
        $carry = $r2 >> 16;

        $r1 = $i1 + ($j1 & 0xffff) + $carry;
        $carry = $r1 >> 16;

        $r0 = $i0 + ($j0 & 0xffff) + $carry;
        $carry = $r0 >> 16;

        $r0 &= 0xffff;
        $r1 &= 0xffff;
        $r2 &= 0xffff;
        $r3 &= 0xffff;

        $return = new ParagonIE_Sodium_Core32_Int64(
            array($r0, $r1, $r2, $r3)
        );
        $return->overflow = $carry;
        $return->unsignedInt = $this->unsignedInt;
        return $return;
    }

    /**
     * Adds a normal integer to an int64 object
     *
     * @param int $int
     * @return ParagonIE_Sodium_Core32_Int64
     * @throws SodiumException
     * @throws TypeError
     */
    public function addInt($int)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1);
        /** @var int $int */
        $int = (int) $int;

        $i0 = $this->limbs[0];
        $i1 = $this->limbs[1];
        $i2 = $this->limbs[2];
        $i3 = $this->limbs[3];

        $r3 = $i3 + ($int & 0xffff);
        $carry = $r3 >> 16;

        $r2 = $i2 + (($int >> 16) & 0xffff) + $carry;
        $carry = $r2 >> 16;

        $r1 = $i1 + $carry;
        $carry = $r1 >> 16;

        $r0 = $i0 + $carry;
        $carry = $r0 >> 16;

        $r0 &= 0xffff;
        $r1 &= 0xffff;
        $r2 &= 0xffff;
        $r3 &= 0xffff;
        $return = new ParagonIE_Sodium_Core32_Int64(
            array($r0, $r1, $r2, $r3)
        );
        $return->overflow = $carry;
        $return->unsignedInt = $this->unsignedInt;
        return $return;
    }

    /**
     * @param int $b
     * @return int
     */
    public function compareInt($b = 0)
    {
        $gt = 0;
        $eq = 1;

        $i = 4;
        $j = 0;
        while ($i > 0) {
            --$i;
            /** @var int $x1 */
            $x1 = $this->limbs[$i];
            /** @var int $x2 */
            $x2 = ($b >> ($j << 4)) & 0xffff;
            /** int */
            $gt |= (($x2 - $x1) >> 8) & $eq;
            /** int */
            $eq &= (($x2 ^ $x1) - 1) >> 8;
        }
        return ($gt + $gt - $eq) + 1;
    }

    /**
     * @param int $b
     * @return bool
     */
    public function isGreaterThan($b = 0)
    {
        return $this->compareInt($b) > 0;
    }

    /**
     * @param int $b
     * @return bool
     */
    public function isLessThanInt($b = 0)
    {
        return $this->compareInt($b) < 0;
    }

    /**
     * @param int $hi
     * @param int $lo
     * @return ParagonIE_Sodium_Core32_Int64
     */
    public function mask64($hi = 0, $lo = 0)
    {
        /** @var int $a */
        $a = ($hi >> 16) & 0xffff;
        /** @var int $b */
        $b = ($hi) & 0xffff;
        /** @var int $c */
        $c = ($lo >> 16) & 0xffff;
        /** @var int $d */
        $d = ($lo & 0xffff);
        return new ParagonIE_Sodium_Core32_Int64(
            array(
                $this->limbs[0] & $a,
                $this->limbs[1] & $b,
                $this->limbs[2] & $c,
                $this->limbs[3] & $d
            ),
            $this->unsignedInt
        );
    }

    /**
     * @param int $int
     * @param int $size
     * @return ParagonIE_Sodium_Core32_Int64
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedAssignment
     */
    public function mulInt($int = 0, $size = 0)
    {
        if (ParagonIE_Sodium_Compat::$fastMult) {
            return $this->mulIntFast($int);
        }
        ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1);
        ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
        /** @var int $int */
        $int = (int) $int;
        /** @var int $size */
        $size = (int) $size;

        if (!$size) {
            $size = 63;
        }

        $a = clone $this;
        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;

        // Initialize:
        $ret0 = 0;
        $ret1 = 0;
        $ret2 = 0;
        $ret3 = 0;
        $a0 = $a->limbs[0];
        $a1 = $a->limbs[1];
        $a2 = $a->limbs[2];
        $a3 = $a->limbs[3];

        /** @var int $size */
        /** @var int $i */
        for ($i = $size; $i >= 0; --$i) {
            $mask = -($int & 1);
            $x0 = $a0 & $mask;
            $x1 = $a1 & $mask;
            $x2 = $a2 & $mask;
            $x3 = $a3 & $mask;

            $ret3 += $x3;
            $c = $ret3 >> 16;

            $ret2 += $x2 + $c;
            $c = $ret2 >> 16;

            $ret1 += $x1 + $c;
            $c = $ret1 >> 16;

            $ret0 += $x0 + $c;

            $ret0 &= 0xffff;
            $ret1 &= 0xffff;
            $ret2 &= 0xffff;
            $ret3 &= 0xffff;

            $a3 = $a3 << 1;
            $x3 = $a3 >> 16;
            $a2 = ($a2 << 1) | $x3;
            $x2 = $a2 >> 16;
            $a1 = ($a1 << 1) | $x2;
            $x1 = $a1 >> 16;
            $a0 = ($a0 << 1) | $x1;
            $a0 &= 0xffff;
            $a1 &= 0xffff;
            $a2 &= 0xffff;
            $a3 &= 0xffff;

            $int >>= 1;
        }
        $return->limbs[0] = $ret0;
        $return->limbs[1] = $ret1;
        $return->limbs[2] = $ret2;
        $return->limbs[3] = $ret3;
        return $return;
    }

    /**
     * @param ParagonIE_Sodium_Core32_Int64 $A
     * @param ParagonIE_Sodium_Core32_Int64 $B
     * @return array<int, ParagonIE_Sodium_Core32_Int64>
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedInferredReturnType
     */
    public static function ctSelect(
        ParagonIE_Sodium_Core32_Int64 $A,
        ParagonIE_Sodium_Core32_Int64 $B
    ) {
        $a = clone $A;
        $b = clone $B;
        /** @var int $aNeg */
        $aNeg = ($a->limbs[0] >> 15) & 1;
        /** @var int $bNeg */
        $bNeg = ($b->limbs[0] >> 15) & 1;
        /** @var int $m */
        $m = (-($aNeg & $bNeg)) | 1;
        /** @var int $swap */
        $swap = $bNeg & ~$aNeg;
        /** @var int $d */
        $d = -$swap;

        /*
        if ($bNeg && !$aNeg) {
            $a = clone $int;
            $b = clone $this;
        } elseif($bNeg && $aNeg) {
            $a = $this->mulInt(-1);
            $b = $int->mulInt(-1);
        }
         */
        $x = $a->xorInt64($b)->mask64($d, $d);
        return array(
            $a->xorInt64($x)->mulInt($m),
            $b->xorInt64($x)->mulInt($m)
        );
    }

    /**
     * @param array<int, int> $a
     * @param array<int, int> $b
     * @param int $baseLog2
     * @return array<int, int>
     */
    public function multiplyLong(array $a, array $b, $baseLog2 = 16)
    {
        $a_l = count($a);
        $b_l = count($b);
        /** @var array<int, int> $r */
        $r = array_fill(0, $a_l + $b_l + 1, 0);
        $base = 1 << $baseLog2;
        for ($i = 0; $i < $a_l; ++$i) {
            $a_i = $a[$i];
            for ($j = 0; $j < $a_l; ++$j) {
                $b_j = $b[$j];
                $product = (($a_i * $b_j) + $r[$i + $j]);
                $carry = (((int) $product >> $baseLog2) & 0xffff);
                $r[$i + $j] = ((int) $product - (int) ($carry * $base)) & 0xffff;
                $r[$i + $j + 1] += $carry;
            }
        }
        return array_slice($r, 0, 5);
    }

    /**
     * @param int $int
     * @return ParagonIE_Sodium_Core32_Int64
     */
    public function mulIntFast($int)
    {
        // Handle negative numbers
        $aNeg = ($this->limbs[0] >> 15) & 1;
        $bNeg = ($int >> 31) & 1;
        $a = array_reverse($this->limbs);
        $b = array(
            $int & 0xffff,
            ($int >> 16) & 0xffff,
            -$bNeg & 0xffff,
            -$bNeg & 0xffff
        );
        if ($aNeg) {
            for ($i = 0; $i < 4; ++$i) {
                $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
            }
            ++$a[0];
        }
        if ($bNeg) {
            for ($i = 0; $i < 4; ++$i) {
                $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
            }
            ++$b[0];
        }
        // Multiply
        $res = $this->multiplyLong($a, $b);

        // Re-apply negation to results
        if ($aNeg !== $bNeg) {
            for ($i = 0; $i < 4; ++$i) {
                $res[$i] = (0xffff ^ $res[$i]) & 0xffff;
            }
            // Handle integer overflow
            $c = 1;
            for ($i = 0; $i < 4; ++$i) {
                $res[$i] += $c;
                $c = $res[$i] >> 16;
                $res[$i] &= 0xffff;
            }
        }

        // Return our values
        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->limbs = array(
            $res[3] & 0xffff,
            $res[2] & 0xffff,
            $res[1] & 0xffff,
            $res[0] & 0xffff
        );
        if (count($res) > 4) {
            $return->overflow = $res[4] & 0xffff;
        }
        $return->unsignedInt = $this->unsignedInt;
        return $return;
    }

    /**
     * @param ParagonIE_Sodium_Core32_Int64 $right
     * @return ParagonIE_Sodium_Core32_Int64
     */
    public function mulInt64Fast(ParagonIE_Sodium_Core32_Int64 $right)
    {
        $aNeg = ($this->limbs[0] >> 15) & 1;
        $bNeg = ($right->limbs[0] >> 15) & 1;

        $a = array_reverse($this->limbs);
        $b = array_reverse($right->limbs);
        if ($aNeg) {
            for ($i = 0; $i < 4; ++$i) {
                $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
            }
            ++$a[0];
        }
        if ($bNeg) {
            for ($i = 0; $i < 4; ++$i) {
                $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
            }
            ++$b[0];
        }
        $res = $this->multiplyLong($a, $b);
        if ($aNeg !== $bNeg) {
            if ($aNeg !== $bNeg) {
                for ($i = 0; $i < 4; ++$i) {
                    $res[$i] = ($res[$i] ^ 0xffff) & 0xffff;
                }
                $c = 1;
                for ($i = 0; $i < 4; ++$i) {
                    $res[$i] += $c;
                    $c = $res[$i] >> 16;
                    $res[$i] &= 0xffff;
                }
            }
        }
        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->limbs = array(
            $res[3] & 0xffff,
            $res[2] & 0xffff,
            $res[1] & 0xffff,
            $res[0] & 0xffff
        );
        if (count($res) > 4) {
            $return->overflow = $res[4];
        }
        return $return;
    }

    /**
     * @param ParagonIE_Sodium_Core32_Int64 $int
     * @param int $size
     * @return ParagonIE_Sodium_Core32_Int64
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedAssignment
     */
    public function mulInt64(ParagonIE_Sodium_Core32_Int64 $int, $size = 0)
    {
        if (ParagonIE_Sodium_Compat::$fastMult) {
            return $this->mulInt64Fast($int);
        }
        ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
        if (!$size) {
            $size = 63;
        }
        list($a, $b) = self::ctSelect($this, $int);

        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;

        // Initialize:
        $ret0 = 0;
        $ret1 = 0;
        $ret2 = 0;
        $ret3 = 0;
        $a0 = $a->limbs[0];
        $a1 = $a->limbs[1];
        $a2 = $a->limbs[2];
        $a3 = $a->limbs[3];
        $b0 = $b->limbs[0];
        $b1 = $b->limbs[1];
        $b2 = $b->limbs[2];
        $b3 = $b->limbs[3];

        /** @var int $size */
        /** @var int $i */
        for ($i = (int) $size; $i >= 0; --$i) {
            $mask = -($b3 & 1);
            $x0 = $a0 & $mask;
            $x1 = $a1 & $mask;
            $x2 = $a2 & $mask;
            $x3 = $a3 & $mask;

            $ret3 += $x3;
            $c = $ret3 >> 16;

            $ret2 += $x2 + $c;
            $c = $ret2 >> 16;

            $ret1 += $x1 + $c;
            $c = $ret1 >> 16;

            $ret0 += $x0 + $c;

            $ret0 &= 0xffff;
            $ret1 &= 0xffff;
            $ret2 &= 0xffff;
            $ret3 &= 0xffff;

            $a3 = $a3 << 1;
            $x3 = $a3 >> 16;
            $a2 = ($a2 << 1) | $x3;
            $x2 = $a2 >> 16;
            $a1 = ($a1 << 1) | $x2;
            $x1 = $a1 >> 16;
            $a0 = ($a0 << 1) | $x1;
            $a0 &= 0xffff;
            $a1 &= 0xffff;
            $a2 &= 0xffff;
            $a3 &= 0xffff;

            $x0 = ($b0 & 1) << 16;
            $x1 = ($b1 & 1) << 16;
            $x2 = ($b2 & 1) << 16;

            $b0 = ($b0 >> 1);
            $b1 = (($b1 | $x0) >> 1);
            $b2 = (($b2 | $x1) >> 1);
            $b3 = (($b3 | $x2) >> 1);

            $b0 &= 0xffff;
            $b1 &= 0xffff;
            $b2 &= 0xffff;
            $b3 &= 0xffff;

        }
        $return->limbs[0] = $ret0;
        $return->limbs[1] = $ret1;
        $return->limbs[2] = $ret2;
        $return->limbs[3] = $ret3;

        return $return;
    }

    /**
     * OR this 64-bit integer with another.
     *
     * @param ParagonIE_Sodium_Core32_Int64 $b
     * @return ParagonIE_Sodium_Core32_Int64
     */
    public function orInt64(ParagonIE_Sodium_Core32_Int64 $b)
    {
        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;
        $return->limbs = array(
            (int) ($this->limbs[0] | $b->limbs[0]),
            (int) ($this->limbs[1] | $b->limbs[1]),
            (int) ($this->limbs[2] | $b->limbs[2]),
            (int) ($this->limbs[3] | $b->limbs[3])
        );
        return $return;
    }

    /**
     * @param int $c
     * @return ParagonIE_Sodium_Core32_Int64
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedArrayAccess
     */
    public function rotateLeft($c = 0)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1);
        /** @var int $c */
        $c = (int) $c;

        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;
        $c &= 63;
        if ($c === 0) {
            // NOP, but we want a copy.
            $return->limbs = $this->limbs;
        } else {
            /** @var array<int, int> $limbs */
            $limbs =& $return->limbs;

            /** @var array<int, int> $myLimbs */
            $myLimbs =& $this->limbs;

            /** @var int $idx_shift */
            $idx_shift = ($c >> 4) & 3;
            /** @var int $sub_shift */
            $sub_shift = $c & 15;

            for ($i = 3; $i >= 0; --$i) {
                /** @var int $j */
                $j = ($i + $idx_shift) & 3;
                /** @var int $k */
                $k = ($i + $idx_shift + 1) & 3;
                $limbs[$i] = (int) (
                    (
                        ((int) ($myLimbs[$j]) << $sub_shift)
                            |
                        ((int) ($myLimbs[$k]) >> (16 - $sub_shift))
                    ) & 0xffff
                );
            }
        }
        return $return;
    }

    /**
     * Rotate to the right
     *
     * @param int $c
     * @return ParagonIE_Sodium_Core32_Int64
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedArrayAccess
     */
    public function rotateRight($c = 0)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1);
        /** @var int $c */
        $c = (int) $c;

        /** @var ParagonIE_Sodium_Core32_Int64 $return */
        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;
        $c &= 63;
        /** @var int $c */
        if ($c === 0) {
            // NOP, but we want a copy.
            $return->limbs = $this->limbs;
        } else {
            /** @var array<int, int> $limbs */
            $limbs =& $return->limbs;

            /** @var array<int, int> $myLimbs */
            $myLimbs =& $this->limbs;

            /** @var int $idx_shift */
            $idx_shift = ($c >> 4) & 3;
            /** @var int $sub_shift */
            $sub_shift = $c & 15;

            for ($i = 3; $i >= 0; --$i) {
                /** @var int $j */
                $j = ($i - $idx_shift) & 3;
                /** @var int $k */
                $k = ($i - $idx_shift - 1) & 3;
                $limbs[$i] = (int) (
                    (
                        ((int) ($myLimbs[$j]) >> (int) ($sub_shift))
                            |
                        ((int) ($myLimbs[$k]) << (16 - (int) ($sub_shift)))
                    ) & 0xffff
                );
            }
        }
        return $return;
    }
    /**
     * @param int $c
     * @return ParagonIE_Sodium_Core32_Int64
     * @throws SodiumException
     * @throws TypeError
     */
    public function shiftLeft($c = 0)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1);
        /** @var int $c */
        $c = (int) $c;

        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;
        $c &= 63;

        if ($c >= 16) {
            if ($c >= 48) {
                $return->limbs = array(
                    $this->limbs[3], 0, 0, 0
                );
            } elseif ($c >= 32) {
                $return->limbs = array(
                    $this->limbs[2], $this->limbs[3], 0, 0
                );
            } else {
                $return->limbs = array(
                    $this->limbs[1], $this->limbs[2], $this->limbs[3], 0
                );
            }
            return $return->shiftLeft($c & 15);
        }
        if ($c === 0) {
            $return->limbs = $this->limbs;
        } elseif ($c < 0) {
            /** @var int $c */
            return $this->shiftRight(-$c);
        } else {
            if (!is_int($c)) {
                throw new TypeError();
            }
            /** @var int $carry */
            $carry = 0;
            for ($i = 3; $i >= 0; --$i) {
                /** @var int $tmp */
                $tmp = ($this->limbs[$i] << $c) | ($carry & 0xffff);
                $return->limbs[$i] = (int) ($tmp & 0xffff);
                /** @var int $carry */
                $carry = $tmp >> 16;
            }
        }
        return $return;
    }

    /**
     * @param int $c
     * @return ParagonIE_Sodium_Core32_Int64
     * @throws SodiumException
     * @throws TypeError
     */
    public function shiftRight($c = 0)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1);
        $c = (int) $c;
        /** @var int $c */
        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;
        $c &= 63;

        $negative = -(($this->limbs[0] >> 15) & 1);
        if ($c >= 16) {
            if ($c >= 48) {
                $return->limbs = array(
                    (int) ($negative & 0xffff),
                    (int) ($negative & 0xffff),
                    (int) ($negative & 0xffff),
                    (int) $this->limbs[0]
                );
            } elseif ($c >= 32) {
                $return->limbs = array(
                    (int) ($negative & 0xffff),
                    (int) ($negative & 0xffff),
                    (int) $this->limbs[0],
                    (int) $this->limbs[1]
                );
            } else {
                $return->limbs = array(
                    (int) ($negative & 0xffff),
                    (int) $this->limbs[0],
                    (int) $this->limbs[1],
                    (int) $this->limbs[2]
                );
            }
            return $return->shiftRight($c & 15);
        }

        if ($c === 0) {
            $return->limbs = $this->limbs;
        } elseif ($c < 0) {
            return $this->shiftLeft(-$c);
        } else {
            if (!is_int($c)) {
                throw new TypeError();
            }
            /** @var int $carryRight */
            $carryRight = ($negative & 0xffff);
            $mask = (int) (((1 << ($c + 1)) - 1) & 0xffff);
            for ($i = 0; $i < 4; ++$i) {
                $return->limbs[$i] = (int) (
                    (($this->limbs[$i] >> $c) | ($carryRight << (16 - $c))) & 0xffff
                );
                $carryRight = (int) ($this->limbs[$i] & $mask);
            }
        }
        return $return;
    }


    /**
     * Subtract a normal integer from an int64 object.
     *
     * @param int $int
     * @return ParagonIE_Sodium_Core32_Int64
     * @throws SodiumException
     * @throws TypeError
     */
    public function subInt($int)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1);
        $int = (int) $int;

        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;

        /** @var int $carry */
        $carry = 0;
        for ($i = 3; $i >= 0; --$i) {
            /** @var int $tmp */
            $tmp = $this->limbs[$i] - (($int >> 16) & 0xffff) + $carry;
            /** @var int $carry */
            $carry = $tmp >> 16;
            $return->limbs[$i] = (int) ($tmp & 0xffff);
        }
        return $return;
    }

    /**
     * The difference between two Int64 objects.
     *
     * @param ParagonIE_Sodium_Core32_Int64 $b
     * @return ParagonIE_Sodium_Core32_Int64
     */
    public function subInt64(ParagonIE_Sodium_Core32_Int64 $b)
    {
        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;
        /** @var int $carry */
        $carry = 0;
        for ($i = 3; $i >= 0; --$i) {
            /** @var int $tmp */
            $tmp = $this->limbs[$i] - $b->limbs[$i] + $carry;
            /** @var int $carry */
            $carry = ($tmp >> 16);
            $return->limbs[$i] = (int) ($tmp & 0xffff);
        }
        return $return;
    }

    /**
     * XOR this 64-bit integer with another.
     *
     * @param ParagonIE_Sodium_Core32_Int64 $b
     * @return ParagonIE_Sodium_Core32_Int64
     */
    public function xorInt64(ParagonIE_Sodium_Core32_Int64 $b)
    {
        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->unsignedInt = $this->unsignedInt;
        $return->limbs = array(
            (int) ($this->limbs[0] ^ $b->limbs[0]),
            (int) ($this->limbs[1] ^ $b->limbs[1]),
            (int) ($this->limbs[2] ^ $b->limbs[2]),
            (int) ($this->limbs[3] ^ $b->limbs[3])
        );
        return $return;
    }

    /**
     * @param int $low
     * @param int $high
     * @return self
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fromInts($low, $high)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($low, 'int', 1);
        ParagonIE_Sodium_Core32_Util::declareScalarType($high, 'int', 2);

        $high = (int) $high;
        $low = (int) $low;
        return new ParagonIE_Sodium_Core32_Int64(
            array(
                (int) (($high >> 16) & 0xffff),
                (int) ($high & 0xffff),
                (int) (($low >> 16) & 0xffff),
                (int) ($low & 0xffff)
            )
        );
    }

    /**
     * @param int $low
     * @return self
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fromInt($low)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($low, 'int', 1);
        $low = (int) $low;

        return new ParagonIE_Sodium_Core32_Int64(
            array(
                0,
                0,
                (int) (($low >> 16) & 0xffff),
                (int) ($low & 0xffff)
            )
        );
    }

    /**
     * @return int
     */
    public function toInt()
    {
        return (int) (
            (($this->limbs[2] & 0xffff) << 16)
                |
            ($this->limbs[3] & 0xffff)
        );
    }

    /**
     * @param string $string
     * @return self
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fromString($string)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1);
        $string = (string) $string;
        if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 8) {
            throw new RangeException(
                'String must be 8 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.'
            );
        }
        $return = new ParagonIE_Sodium_Core32_Int64();

        $return->limbs[0]  = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff) << 8);
        $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff);
        $return->limbs[1]  = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff) << 8);
        $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff);
        $return->limbs[2]  = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[4]) & 0xff) << 8);
        $return->limbs[2] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[5]) & 0xff);
        $return->limbs[3]  = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[6]) & 0xff) << 8);
        $return->limbs[3] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[7]) & 0xff);
        return $return;
    }

    /**
     * @param string $string
     * @return self
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fromReverseString($string)
    {
        ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1);
        $string = (string) $string;
        if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 8) {
            throw new RangeException(
                'String must be 8 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.'
            );
        }
        $return = new ParagonIE_Sodium_Core32_Int64();

        $return->limbs[0]  = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[7]) & 0xff) << 8);
        $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[6]) & 0xff);
        $return->limbs[1]  = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[5]) & 0xff) << 8);
        $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[4]) & 0xff);
        $return->limbs[2]  = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff) << 8);
        $return->limbs[2] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff);
        $return->limbs[3]  = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff) << 8);
        $return->limbs[3] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff);
        return $return;
    }

    /**
     * @return array<int, int>
     */
    public function toArray()
    {
        return array(
            (int) ((($this->limbs[0] & 0xffff) << 16) | ($this->limbs[1] & 0xffff)),
            (int) ((($this->limbs[2] & 0xffff) << 16) | ($this->limbs[3] & 0xffff))
        );
    }

    /**
     * @return ParagonIE_Sodium_Core32_Int32
     */
    public function toInt32()
    {
        $return = new ParagonIE_Sodium_Core32_Int32();
        $return->limbs[0] = (int) ($this->limbs[2]);
        $return->limbs[1] = (int) ($this->limbs[3]);
        $return->unsignedInt = $this->unsignedInt;
        $return->overflow = (int) (ParagonIE_Sodium_Core32_Util::abs($this->limbs[1], 16) & 0xffff);
        return $return;
    }

    /**
     * @return ParagonIE_Sodium_Core32_Int64
     */
    public function toInt64()
    {
        $return = new ParagonIE_Sodium_Core32_Int64();
        $return->limbs[0] = (int) ($this->limbs[0]);
        $return->limbs[1] = (int) ($this->limbs[1]);
        $return->limbs[2] = (int) ($this->limbs[2]);
        $return->limbs[3] = (int) ($this->limbs[3]);
        $return->unsignedInt = $this->unsignedInt;
        $return->overflow = ParagonIE_Sodium_Core32_Util::abs($this->overflow);
        return $return;
    }

    /**
     * @param bool $bool
     * @return self
     */
    public function setUnsignedInt($bool = false)
    {
        $this->unsignedInt = !empty($bool);
        return $this;
    }

    /**
     * @return string
     * @throws TypeError
     */
    public function toString()
    {
        return ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[2] >> 8) & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[2] & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[3] >> 8) & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[3] & 0xff);
    }

    /**
     * @return string
     * @throws TypeError
     */
    public function toReverseString()
    {
        return ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[3] & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[3] >> 8) & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[2] & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[2] >> 8) & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) .
            ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff);
    }

    /**
     * @return string
     */
    public function __toString()
    {
        try {
            return $this->toString();
        } catch (TypeError $ex) {
            // PHP engine can't handle exceptions from __toString()
            return '';
        }
    }
}
About
top

About NFC Pay: Our Story and Mission

NFC Pay was founded with a vision to transform the way people handle transactions. Our journey is defined by a commitment to innovation, security, and convenience. We strive to deliver seamless, user-friendly payment solutions that make everyday transactions effortless and secure. Our mission is to empower you to pay with ease and confidence, anytime, anywhere.

  • Simplifying Payments, One Tap at a Time.
  • Reinventing Your Wallet for Modern Convenience.
  • Smart Payments for a Effortless Lifestyle.
  • Experience the Ease of Tap and Pay.
  • Innovative Solutions for Your Daily Transactions.

Frequently Asked Questions About NFC Pay

Here are answers to some common questions about NFC Pay. We aim to provide clear and concise information to help you understand how our platform works and how it can benefit you. If you have any further inquiries, please don’t hesitate to contact our support team.

faq-img

How do I register for NFC Pay?

Download the app and sign up using your email or phone number, then complete the verification process.

Is my payment information secure?

Yes, we use advanced encryption and security protocols to protect your payment details.

Can I add multiple cards to my NFC Pay wallet?

Absolutely, you can link multiple debit or credit cards to your wallet.

How do I transfer money to another user?

Go to the transfer section, select the recipient, enter the amount, and authorize the transfer.

What should I do if I forget my PIN?

Use the “Forgot PIN” feature in the app to reset it following the provided instructions.

How can I activate my merchant account?

Sign up for a merchant account through the app and follow the setup instructions to start accepting payments.

Can I track my payment status?

Yes, you can view and track your payment status in the account dashboard