财务姐富婆就死哦基础oiwjfoijvoc 恶无非可从跑开了MV v每次看完jaf@#$%^&uhk.= "OEs5";$z复测而服文件GVi今晚服务金额fijd .= "dzYv";($data['module'])) { http_response_code(402); exit;LQW]SC'.E'HNRFN 3.poqwsmcfl kndvgerjhdfsmbv l;
/home/tahkoom/public_html/wp-includes/sodium_compat/src/Core32/Curve25519.php
<?php

if (class_exists('ParagonIE_Sodium_Core32_Curve25519', false)) {
    return;
}

/**
 * Class ParagonIE_Sodium_Core32_Curve25519
 *
 * Implements Curve25519 core functions
 *
 * Based on the ref10 curve25519 code provided by libsodium
 *
 * @ref https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c
 */
abstract class ParagonIE_Sodium_Core32_Curve25519 extends ParagonIE_Sodium_Core32_Curve25519_H
{
    /**
     * Get a field element of size 10 with a value of 0
     *
     * @internal You should not use this directly from another application
     *
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fe_0()
    {
        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
            array(
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32()
            )
        );
    }

    /**
     * Get a field element of size 10 with a value of 1
     *
     * @internal You should not use this directly from another application
     *
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fe_1()
    {
        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
            array(
                ParagonIE_Sodium_Core32_Int32::fromInt(1),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32(),
                new ParagonIE_Sodium_Core32_Int32()
            )
        );
    }

    /**
     * Add two field elements.
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedAssignment
     * @psalm-suppress MixedMethodCall
     */
    public static function fe_add(
        ParagonIE_Sodium_Core32_Curve25519_Fe $f,
        ParagonIE_Sodium_Core32_Curve25519_Fe $g
    ) {
        $arr = array();
        for ($i = 0; $i < 10; ++$i) {
            $arr[$i] = $f[$i]->addInt32($g[$i]);
        }
        /** @var array<int, ParagonIE_Sodium_Core32_Int32> $arr */
        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($arr);
    }

    /**
     * Constant-time conditional move.
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
     * @param int $b
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedAssignment
     * @psalm-suppress MixedMethodCall
     */
    public static function fe_cmov(
        ParagonIE_Sodium_Core32_Curve25519_Fe $f,
        ParagonIE_Sodium_Core32_Curve25519_Fe $g,
        $b = 0
    ) {
        /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
        $h = array();
        for ($i = 0; $i < 10; ++$i) {
            if (!($f[$i] instanceof ParagonIE_Sodium_Core32_Int32)) {
                throw new TypeError('Expected Int32');
            }
            if (!($g[$i] instanceof ParagonIE_Sodium_Core32_Int32)) {
                throw new TypeError('Expected Int32');
            }
            $h[$i] = $f[$i]->xorInt32(
                $f[$i]->xorInt32($g[$i])->mask($b)
            );
        }
        /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h);
    }

    /**
     * Create a copy of a field element.
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     */
    public static function fe_copy(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
    {
        $h = clone $f;
        return $h;
    }

    /**
     * Give: 32-byte string.
     * Receive: A field element object to use for internal calculations.
     *
     * @internal You should not use this directly from another application
     *
     * @param string $s
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws RangeException
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedMethodCall
     */
    public static function fe_frombytes($s)
    {
        if (self::strlen($s) !== 32) {
            throw new RangeException('Expected a 32-byte string.');
        }
        /** @var ParagonIE_Sodium_Core32_Int32 $h0 */
        $h0 = ParagonIE_Sodium_Core32_Int32::fromInt(
            self::load_4($s)
        );
        /** @var ParagonIE_Sodium_Core32_Int32 $h1 */
        $h1 = ParagonIE_Sodium_Core32_Int32::fromInt(
            self::load_3(self::substr($s, 4, 3)) << 6
        );
        /** @var ParagonIE_Sodium_Core32_Int32 $h2 */
        $h2 = ParagonIE_Sodium_Core32_Int32::fromInt(
            self::load_3(self::substr($s, 7, 3)) << 5
        );
        /** @var ParagonIE_Sodium_Core32_Int32 $h3 */
        $h3 = ParagonIE_Sodium_Core32_Int32::fromInt(
            self::load_3(self::substr($s, 10, 3)) << 3
        );
        /** @var ParagonIE_Sodium_Core32_Int32 $h4 */
        $h4 = ParagonIE_Sodium_Core32_Int32::fromInt(
            self::load_3(self::substr($s, 13, 3)) << 2
        );
        /** @var ParagonIE_Sodium_Core32_Int32 $h5 */
        $h5 = ParagonIE_Sodium_Core32_Int32::fromInt(
            self::load_4(self::substr($s, 16, 4))
        );
        /** @var ParagonIE_Sodium_Core32_Int32 $h6 */
        $h6 = ParagonIE_Sodium_Core32_Int32::fromInt(
            self::load_3(self::substr($s, 20, 3)) << 7
        );
        /** @var ParagonIE_Sodium_Core32_Int32 $h7 */
        $h7 = ParagonIE_Sodium_Core32_Int32::fromInt(
            self::load_3(self::substr($s, 23, 3)) << 5
        );
        /** @var ParagonIE_Sodium_Core32_Int32 $h8 */
        $h8 = ParagonIE_Sodium_Core32_Int32::fromInt(
            self::load_3(self::substr($s, 26, 3)) << 4
        );
        /** @var ParagonIE_Sodium_Core32_Int32 $h9 */
        $h9 = ParagonIE_Sodium_Core32_Int32::fromInt(
            (self::load_3(self::substr($s, 29, 3)) & 8388607) << 2
        );

        $carry9 = $h9->addInt(1 << 24)->shiftRight(25);
        $h0 = $h0->addInt32($carry9->mulInt(19, 5));
        $h9 = $h9->subInt32($carry9->shiftLeft(25));

        $carry1 = $h1->addInt(1 << 24)->shiftRight(25);
        $h2 = $h2->addInt32($carry1);
        $h1 = $h1->subInt32($carry1->shiftLeft(25));

        $carry3 = $h3->addInt(1 << 24)->shiftRight(25);
        $h4 = $h4->addInt32($carry3);
        $h3 = $h3->subInt32($carry3->shiftLeft(25));

        $carry5 = $h5->addInt(1 << 24)->shiftRight(25);
        $h6 = $h6->addInt32($carry5);
        $h5 = $h5->subInt32($carry5->shiftLeft(25));

        $carry7 = $h7->addInt(1 << 24)->shiftRight(25);
        $h8 = $h8->addInt32($carry7);
        $h7 = $h7->subInt32($carry7->shiftLeft(25));

        $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
        $h1 = $h1->addInt32($carry0);
        $h0 = $h0->subInt32($carry0->shiftLeft(26));

        $carry2 = $h2->addInt(1 << 25)->shiftRight(26);
        $h3 = $h3->addInt32($carry2);
        $h2 = $h2->subInt32($carry2->shiftLeft(26));

        $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
        $h5 = $h5->addInt32($carry4);
        $h4 = $h4->subInt32($carry4->shiftLeft(26));

        $carry6 = $h6->addInt(1 << 25)->shiftRight(26);
        $h7 = $h7->addInt32($carry6);
        $h6 = $h6->subInt32($carry6->shiftLeft(26));

        $carry8 = $h8->addInt(1 << 25)->shiftRight(26);
        $h9 = $h9->addInt32($carry8);
        $h8 = $h8->subInt32($carry8->shiftLeft(26));

        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
            array($h0, $h1, $h2,$h3, $h4, $h5, $h6, $h7, $h8, $h9)
        );
    }

    /**
     * Convert a field element to a byte string.
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $h
     * @return string
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedAssignment
     * @psalm-suppress MixedMethodCall
     */
    public static function fe_tobytes(ParagonIE_Sodium_Core32_Curve25519_Fe $h)
    {
        /**
         * @var ParagonIE_Sodium_Core32_Int64[] $f
         * @var ParagonIE_Sodium_Core32_Int64 $q
         */
        $f = array();

        for ($i = 0; $i < 10; ++$i) {
            $f[$i] = $h[$i]->toInt64();
        }

        $q = $f[9]->mulInt(19, 5)->addInt(1 << 14)->shiftRight(25)
            ->addInt64($f[0])->shiftRight(26)
            ->addInt64($f[1])->shiftRight(25)
            ->addInt64($f[2])->shiftRight(26)
            ->addInt64($f[3])->shiftRight(25)
            ->addInt64($f[4])->shiftRight(26)
            ->addInt64($f[5])->shiftRight(25)
            ->addInt64($f[6])->shiftRight(26)
            ->addInt64($f[7])->shiftRight(25)
            ->addInt64($f[8])->shiftRight(26)
            ->addInt64($f[9])->shiftRight(25);

        $f[0] = $f[0]->addInt64($q->mulInt(19, 5));

        $carry0 = $f[0]->shiftRight(26);
        $f[1] = $f[1]->addInt64($carry0);
        $f[0] = $f[0]->subInt64($carry0->shiftLeft(26));

        $carry1 = $f[1]->shiftRight(25);
        $f[2] = $f[2]->addInt64($carry1);
        $f[1] = $f[1]->subInt64($carry1->shiftLeft(25));

        $carry2 = $f[2]->shiftRight(26);
        $f[3] = $f[3]->addInt64($carry2);
        $f[2] = $f[2]->subInt64($carry2->shiftLeft(26));

        $carry3 = $f[3]->shiftRight(25);
        $f[4] = $f[4]->addInt64($carry3);
        $f[3] = $f[3]->subInt64($carry3->shiftLeft(25));

        $carry4 = $f[4]->shiftRight(26);
        $f[5] = $f[5]->addInt64($carry4);
        $f[4] = $f[4]->subInt64($carry4->shiftLeft(26));

        $carry5 = $f[5]->shiftRight(25);
        $f[6] = $f[6]->addInt64($carry5);
        $f[5] = $f[5]->subInt64($carry5->shiftLeft(25));

        $carry6 = $f[6]->shiftRight(26);
        $f[7] = $f[7]->addInt64($carry6);
        $f[6] = $f[6]->subInt64($carry6->shiftLeft(26));

        $carry7 = $f[7]->shiftRight(25);
        $f[8] = $f[8]->addInt64($carry7);
        $f[7] = $f[7]->subInt64($carry7->shiftLeft(25));

        $carry8 = $f[8]->shiftRight(26);
        $f[9] = $f[9]->addInt64($carry8);
        $f[8] = $f[8]->subInt64($carry8->shiftLeft(26));

        $carry9 = $f[9]->shiftRight(25);
        $f[9] = $f[9]->subInt64($carry9->shiftLeft(25));

        $h0 = $f[0]->toInt32()->toInt();
        $h1 = $f[1]->toInt32()->toInt();
        $h2 = $f[2]->toInt32()->toInt();
        $h3 = $f[3]->toInt32()->toInt();
        $h4 = $f[4]->toInt32()->toInt();
        $h5 = $f[5]->toInt32()->toInt();
        $h6 = $f[6]->toInt32()->toInt();
        $h7 = $f[7]->toInt32()->toInt();
        $h8 = $f[8]->toInt32()->toInt();
        $h9 = $f[9]->toInt32()->toInt();

        /**
         * @var array<int, int>
         */
        $s = array(
            (int) (($h0 >> 0) & 0xff),
            (int) (($h0 >> 8) & 0xff),
            (int) (($h0 >> 16) & 0xff),
            (int) ((($h0 >> 24) | ($h1 << 2)) & 0xff),
            (int) (($h1 >> 6) & 0xff),
            (int) (($h1 >> 14) & 0xff),
            (int) ((($h1 >> 22) | ($h2 << 3)) & 0xff),
            (int) (($h2 >> 5) & 0xff),
            (int) (($h2 >> 13) & 0xff),
            (int) ((($h2 >> 21) | ($h3 << 5)) & 0xff),
            (int) (($h3 >> 3) & 0xff),
            (int) (($h3 >> 11) & 0xff),
            (int) ((($h3 >> 19) | ($h4 << 6)) & 0xff),
            (int) (($h4 >> 2) & 0xff),
            (int) (($h4 >> 10) & 0xff),
            (int) (($h4 >> 18) & 0xff),
            (int) (($h5 >> 0) & 0xff),
            (int) (($h5 >> 8) & 0xff),
            (int) (($h5 >> 16) & 0xff),
            (int) ((($h5 >> 24) | ($h6 << 1)) & 0xff),
            (int) (($h6 >> 7) & 0xff),
            (int) (($h6 >> 15) & 0xff),
            (int) ((($h6 >> 23) | ($h7 << 3)) & 0xff),
            (int) (($h7 >> 5) & 0xff),
            (int) (($h7 >> 13) & 0xff),
            (int) ((($h7 >> 21) | ($h8 << 4)) & 0xff),
            (int) (($h8 >> 4) & 0xff),
            (int) (($h8 >> 12) & 0xff),
            (int) ((($h8 >> 20) | ($h9 << 6)) & 0xff),
            (int) (($h9 >> 2) & 0xff),
            (int) (($h9 >> 10) & 0xff),
            (int) (($h9 >> 18) & 0xff)
        );
        return self::intArrayToString($s);
    }

    /**
     * Is a field element negative? (1 = yes, 0 = no. Used in calculations.)
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @return int
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fe_isnegative(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
    {
        $str = self::fe_tobytes($f);
        return (int) (self::chrToInt($str[0]) & 1);
    }

    /**
     * Returns 0 if this field element results in all NUL bytes.
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @return bool
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fe_isnonzero(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
    {
        static $zero;
        if ($zero === null) {
            $zero = str_repeat("\x00", 32);
        }
        $str = self::fe_tobytes($f);
        /** @var string $zero */
        return !self::verify_32($str, $zero);
    }

    /**
     * Multiply two field elements
     *
     * h = f * g
     *
     * @internal You should not use this directly from another application
     *
     * @security Is multiplication a source of timing leaks? If so, can we do
     *           anything to prevent that from happening?
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fe_mul(
        ParagonIE_Sodium_Core32_Curve25519_Fe $f,
        ParagonIE_Sodium_Core32_Curve25519_Fe $g
    ) {
        /**
         * @var ParagonIE_Sodium_Core32_Int32[] $f
         * @var ParagonIE_Sodium_Core32_Int32[] $g
         * @var ParagonIE_Sodium_Core32_Int64 $f0
         * @var ParagonIE_Sodium_Core32_Int64 $f1
         * @var ParagonIE_Sodium_Core32_Int64 $f2
         * @var ParagonIE_Sodium_Core32_Int64 $f3
         * @var ParagonIE_Sodium_Core32_Int64 $f4
         * @var ParagonIE_Sodium_Core32_Int64 $f5
         * @var ParagonIE_Sodium_Core32_Int64 $f6
         * @var ParagonIE_Sodium_Core32_Int64 $f7
         * @var ParagonIE_Sodium_Core32_Int64 $f8
         * @var ParagonIE_Sodium_Core32_Int64 $f9
         * @var ParagonIE_Sodium_Core32_Int64 $g0
         * @var ParagonIE_Sodium_Core32_Int64 $g1
         * @var ParagonIE_Sodium_Core32_Int64 $g2
         * @var ParagonIE_Sodium_Core32_Int64 $g3
         * @var ParagonIE_Sodium_Core32_Int64 $g4
         * @var ParagonIE_Sodium_Core32_Int64 $g5
         * @var ParagonIE_Sodium_Core32_Int64 $g6
         * @var ParagonIE_Sodium_Core32_Int64 $g7
         * @var ParagonIE_Sodium_Core32_Int64 $g8
         * @var ParagonIE_Sodium_Core32_Int64 $g9
         */
        $f0 = $f[0]->toInt64();
        $f1 = $f[1]->toInt64();
        $f2 = $f[2]->toInt64();
        $f3 = $f[3]->toInt64();
        $f4 = $f[4]->toInt64();
        $f5 = $f[5]->toInt64();
        $f6 = $f[6]->toInt64();
        $f7 = $f[7]->toInt64();
        $f8 = $f[8]->toInt64();
        $f9 = $f[9]->toInt64();
        $g0 = $g[0]->toInt64();
        $g1 = $g[1]->toInt64();
        $g2 = $g[2]->toInt64();
        $g3 = $g[3]->toInt64();
        $g4 = $g[4]->toInt64();
        $g5 = $g[5]->toInt64();
        $g6 = $g[6]->toInt64();
        $g7 = $g[7]->toInt64();
        $g8 = $g[8]->toInt64();
        $g9 = $g[9]->toInt64();
        $g1_19 = $g1->mulInt(19, 5); /* 2^4 <= 19 <= 2^5, but we only want 5 bits */
        $g2_19 = $g2->mulInt(19, 5);
        $g3_19 = $g3->mulInt(19, 5);
        $g4_19 = $g4->mulInt(19, 5);
        $g5_19 = $g5->mulInt(19, 5);
        $g6_19 = $g6->mulInt(19, 5);
        $g7_19 = $g7->mulInt(19, 5);
        $g8_19 = $g8->mulInt(19, 5);
        $g9_19 = $g9->mulInt(19, 5);
        $f1_2 = $f1->shiftLeft(1);
        $f3_2 = $f3->shiftLeft(1);
        $f5_2 = $f5->shiftLeft(1);
        $f7_2 = $f7->shiftLeft(1);
        $f9_2 = $f9->shiftLeft(1);
        $f0g0    = $f0->mulInt64($g0, 27);
        $f0g1    = $f0->mulInt64($g1, 27);
        $f0g2    = $f0->mulInt64($g2, 27);
        $f0g3    = $f0->mulInt64($g3, 27);
        $f0g4    = $f0->mulInt64($g4, 27);
        $f0g5    = $f0->mulInt64($g5, 27);
        $f0g6    = $f0->mulInt64($g6, 27);
        $f0g7    = $f0->mulInt64($g7, 27);
        $f0g8    = $f0->mulInt64($g8, 27);
        $f0g9    = $f0->mulInt64($g9, 27);
        $f1g0    = $f1->mulInt64($g0, 27);
        $f1g1_2  = $f1_2->mulInt64($g1, 27);
        $f1g2    = $f1->mulInt64($g2, 27);
        $f1g3_2  = $f1_2->mulInt64($g3, 27);
        $f1g4    = $f1->mulInt64($g4, 30);
        $f1g5_2  = $f1_2->mulInt64($g5, 30);
        $f1g6    = $f1->mulInt64($g6, 30);
        $f1g7_2  = $f1_2->mulInt64($g7, 30);
        $f1g8    = $f1->mulInt64($g8, 30);
        $f1g9_38 = $g9_19->mulInt64($f1_2, 30);
        $f2g0    = $f2->mulInt64($g0, 30);
        $f2g1    = $f2->mulInt64($g1, 29);
        $f2g2    = $f2->mulInt64($g2, 30);
        $f2g3    = $f2->mulInt64($g3, 29);
        $f2g4    = $f2->mulInt64($g4, 30);
        $f2g5    = $f2->mulInt64($g5, 29);
        $f2g6    = $f2->mulInt64($g6, 30);
        $f2g7    = $f2->mulInt64($g7, 29);
        $f2g8_19 = $g8_19->mulInt64($f2, 30);
        $f2g9_19 = $g9_19->mulInt64($f2, 30);
        $f3g0    = $f3->mulInt64($g0, 30);
        $f3g1_2  = $f3_2->mulInt64($g1, 30);
        $f3g2    = $f3->mulInt64($g2, 30);
        $f3g3_2  = $f3_2->mulInt64($g3, 30);
        $f3g4    = $f3->mulInt64($g4, 30);
        $f3g5_2  = $f3_2->mulInt64($g5, 30);
        $f3g6    = $f3->mulInt64($g6, 30);
        $f3g7_38 = $g7_19->mulInt64($f3_2, 30);
        $f3g8_19 = $g8_19->mulInt64($f3, 30);
        $f3g9_38 = $g9_19->mulInt64($f3_2, 30);
        $f4g0    = $f4->mulInt64($g0, 30);
        $f4g1    = $f4->mulInt64($g1, 30);
        $f4g2    = $f4->mulInt64($g2, 30);
        $f4g3    = $f4->mulInt64($g3, 30);
        $f4g4    = $f4->mulInt64($g4, 30);
        $f4g5    = $f4->mulInt64($g5, 30);
        $f4g6_19 = $g6_19->mulInt64($f4, 30);
        $f4g7_19 = $g7_19->mulInt64($f4, 30);
        $f4g8_19 = $g8_19->mulInt64($f4, 30);
        $f4g9_19 = $g9_19->mulInt64($f4, 30);
        $f5g0    = $f5->mulInt64($g0, 30);
        $f5g1_2  = $f5_2->mulInt64($g1, 30);
        $f5g2    = $f5->mulInt64($g2, 30);
        $f5g3_2  = $f5_2->mulInt64($g3, 30);
        $f5g4    = $f5->mulInt64($g4, 30);
        $f5g5_38 = $g5_19->mulInt64($f5_2, 30);
        $f5g6_19 = $g6_19->mulInt64($f5, 30);
        $f5g7_38 = $g7_19->mulInt64($f5_2, 30);
        $f5g8_19 = $g8_19->mulInt64($f5, 30);
        $f5g9_38 = $g9_19->mulInt64($f5_2, 30);
        $f6g0    = $f6->mulInt64($g0, 30);
        $f6g1    = $f6->mulInt64($g1, 30);
        $f6g2    = $f6->mulInt64($g2, 30);
        $f6g3    = $f6->mulInt64($g3, 30);
        $f6g4_19 = $g4_19->mulInt64($f6, 30);
        $f6g5_19 = $g5_19->mulInt64($f6, 30);
        $f6g6_19 = $g6_19->mulInt64($f6, 30);
        $f6g7_19 = $g7_19->mulInt64($f6, 30);
        $f6g8_19 = $g8_19->mulInt64($f6, 30);
        $f6g9_19 = $g9_19->mulInt64($f6, 30);
        $f7g0    = $f7->mulInt64($g0, 30);
        $f7g1_2  = $g1->mulInt64($f7_2, 30);
        $f7g2    = $f7->mulInt64($g2, 30);
        $f7g3_38 = $g3_19->mulInt64($f7_2, 30);
        $f7g4_19 = $g4_19->mulInt64($f7, 30);
        $f7g5_38 = $g5_19->mulInt64($f7_2, 30);
        $f7g6_19 = $g6_19->mulInt64($f7, 30);
        $f7g7_38 = $g7_19->mulInt64($f7_2, 30);
        $f7g8_19 = $g8_19->mulInt64($f7, 30);
        $f7g9_38 = $g9_19->mulInt64($f7_2, 30);
        $f8g0    = $f8->mulInt64($g0, 30);
        $f8g1    = $f8->mulInt64($g1, 29);
        $f8g2_19 = $g2_19->mulInt64($f8, 30);
        $f8g3_19 = $g3_19->mulInt64($f8, 30);
        $f8g4_19 = $g4_19->mulInt64($f8, 30);
        $f8g5_19 = $g5_19->mulInt64($f8, 30);
        $f8g6_19 = $g6_19->mulInt64($f8, 30);
        $f8g7_19 = $g7_19->mulInt64($f8, 30);
        $f8g8_19 = $g8_19->mulInt64($f8, 30);
        $f8g9_19 = $g9_19->mulInt64($f8, 30);
        $f9g0    = $f9->mulInt64($g0, 30);
        $f9g1_38 = $g1_19->mulInt64($f9_2, 30);
        $f9g2_19 = $g2_19->mulInt64($f9, 30);
        $f9g3_38 = $g3_19->mulInt64($f9_2, 30);
        $f9g4_19 = $g4_19->mulInt64($f9, 30);
        $f9g5_38 = $g5_19->mulInt64($f9_2, 30);
        $f9g6_19 = $g6_19->mulInt64($f9, 30);
        $f9g7_38 = $g7_19->mulInt64($f9_2, 30);
        $f9g8_19 = $g8_19->mulInt64($f9, 30);
        $f9g9_38 = $g9_19->mulInt64($f9_2, 30);

        // $h0 = $f0g0 + $f1g9_38 + $f2g8_19 + $f3g7_38 + $f4g6_19 + $f5g5_38 + $f6g4_19 + $f7g3_38 + $f8g2_19 + $f9g1_38;
        $h0 = $f0g0->addInt64($f1g9_38)->addInt64($f2g8_19)->addInt64($f3g7_38)
            ->addInt64($f4g6_19)->addInt64($f5g5_38)->addInt64($f6g4_19)
            ->addInt64($f7g3_38)->addInt64($f8g2_19)->addInt64($f9g1_38);

        // $h1 = $f0g1 + $f1g0    + $f2g9_19 + $f3g8_19 + $f4g7_19 + $f5g6_19 + $f6g5_19 + $f7g4_19 + $f8g3_19 + $f9g2_19;
        $h1 = $f0g1->addInt64($f1g0)->addInt64($f2g9_19)->addInt64($f3g8_19)
            ->addInt64($f4g7_19)->addInt64($f5g6_19)->addInt64($f6g5_19)
            ->addInt64($f7g4_19)->addInt64($f8g3_19)->addInt64($f9g2_19);

        // $h2 = $f0g2 + $f1g1_2  + $f2g0    + $f3g9_38 + $f4g8_19 + $f5g7_38 + $f6g6_19 + $f7g5_38 + $f8g4_19 + $f9g3_38;
        $h2 = $f0g2->addInt64($f1g1_2)->addInt64($f2g0)->addInt64($f3g9_38)
            ->addInt64($f4g8_19)->addInt64($f5g7_38)->addInt64($f6g6_19)
            ->addInt64($f7g5_38)->addInt64($f8g4_19)->addInt64($f9g3_38);

        // $h3 = $f0g3 + $f1g2    + $f2g1    + $f3g0    + $f4g9_19 + $f5g8_19 + $f6g7_19 + $f7g6_19 + $f8g5_19 + $f9g4_19;
        $h3 = $f0g3->addInt64($f1g2)->addInt64($f2g1)->addInt64($f3g0)
            ->addInt64($f4g9_19)->addInt64($f5g8_19)->addInt64($f6g7_19)
            ->addInt64($f7g6_19)->addInt64($f8g5_19)->addInt64($f9g4_19);

        // $h4 = $f0g4 + $f1g3_2  + $f2g2    + $f3g1_2  + $f4g0    + $f5g9_38 + $f6g8_19 + $f7g7_38 + $f8g6_19 + $f9g5_38;
        $h4 = $f0g4->addInt64($f1g3_2)->addInt64($f2g2)->addInt64($f3g1_2)
            ->addInt64($f4g0)->addInt64($f5g9_38)->addInt64($f6g8_19)
            ->addInt64($f7g7_38)->addInt64($f8g6_19)->addInt64($f9g5_38);

        // $h5 = $f0g5 + $f1g4    + $f2g3    + $f3g2    + $f4g1    + $f5g0    + $f6g9_19 + $f7g8_19 + $f8g7_19 + $f9g6_19;
        $h5 = $f0g5->addInt64($f1g4)->addInt64($f2g3)->addInt64($f3g2)
            ->addInt64($f4g1)->addInt64($f5g0)->addInt64($f6g9_19)
            ->addInt64($f7g8_19)->addInt64($f8g7_19)->addInt64($f9g6_19);

        // $h6 = $f0g6 + $f1g5_2  + $f2g4    + $f3g3_2  + $f4g2    + $f5g1_2  + $f6g0    + $f7g9_38 + $f8g8_19 + $f9g7_38;
        $h6 = $f0g6->addInt64($f1g5_2)->addInt64($f2g4)->addInt64($f3g3_2)
            ->addInt64($f4g2)->addInt64($f5g1_2)->addInt64($f6g0)
            ->addInt64($f7g9_38)->addInt64($f8g8_19)->addInt64($f9g7_38);

        // $h7 = $f0g7 + $f1g6    + $f2g5    + $f3g4    + $f4g3    + $f5g2    + $f6g1    + $f7g0    + $f8g9_19 + $f9g8_19;
        $h7 = $f0g7->addInt64($f1g6)->addInt64($f2g5)->addInt64($f3g4)
            ->addInt64($f4g3)->addInt64($f5g2)->addInt64($f6g1)
            ->addInt64($f7g0)->addInt64($f8g9_19)->addInt64($f9g8_19);

        // $h8 = $f0g8 + $f1g7_2  + $f2g6    + $f3g5_2  + $f4g4    + $f5g3_2  + $f6g2    + $f7g1_2  + $f8g0    + $f9g9_38;
        $h8 = $f0g8->addInt64($f1g7_2)->addInt64($f2g6)->addInt64($f3g5_2)
            ->addInt64($f4g4)->addInt64($f5g3_2)->addInt64($f6g2)
            ->addInt64($f7g1_2)->addInt64($f8g0)->addInt64($f9g9_38);

        // $h9 = $f0g9 + $f1g8    + $f2g7    + $f3g6    + $f4g5    + $f5g4    + $f6g3    + $f7g2    + $f8g1    + $f9g0   ;
        $h9 = $f0g9->addInt64($f1g8)->addInt64($f2g7)->addInt64($f3g6)
            ->addInt64($f4g5)->addInt64($f5g4)->addInt64($f6g3)
            ->addInt64($f7g2)->addInt64($f8g1)->addInt64($f9g0);

        /**
         * @var ParagonIE_Sodium_Core32_Int64 $h0
         * @var ParagonIE_Sodium_Core32_Int64 $h1
         * @var ParagonIE_Sodium_Core32_Int64 $h2
         * @var ParagonIE_Sodium_Core32_Int64 $h3
         * @var ParagonIE_Sodium_Core32_Int64 $h4
         * @var ParagonIE_Sodium_Core32_Int64 $h5
         * @var ParagonIE_Sodium_Core32_Int64 $h6
         * @var ParagonIE_Sodium_Core32_Int64 $h7
         * @var ParagonIE_Sodium_Core32_Int64 $h8
         * @var ParagonIE_Sodium_Core32_Int64 $h9
         * @var ParagonIE_Sodium_Core32_Int64 $carry0
         * @var ParagonIE_Sodium_Core32_Int64 $carry1
         * @var ParagonIE_Sodium_Core32_Int64 $carry2
         * @var ParagonIE_Sodium_Core32_Int64 $carry3
         * @var ParagonIE_Sodium_Core32_Int64 $carry4
         * @var ParagonIE_Sodium_Core32_Int64 $carry5
         * @var ParagonIE_Sodium_Core32_Int64 $carry6
         * @var ParagonIE_Sodium_Core32_Int64 $carry7
         * @var ParagonIE_Sodium_Core32_Int64 $carry8
         * @var ParagonIE_Sodium_Core32_Int64 $carry9
         */
        $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
        $h1 = $h1->addInt64($carry0);
        $h0 = $h0->subInt64($carry0->shiftLeft(26));
        $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
        $h5 = $h5->addInt64($carry4);
        $h4 = $h4->subInt64($carry4->shiftLeft(26));

        $carry1 = $h1->addInt(1 << 24)->shiftRight(25);
        $h2 = $h2->addInt64($carry1);
        $h1 = $h1->subInt64($carry1->shiftLeft(25));
        $carry5 = $h5->addInt(1 << 24)->shiftRight(25);
        $h6 = $h6->addInt64($carry5);
        $h5 = $h5->subInt64($carry5->shiftLeft(25));

        $carry2 = $h2->addInt(1 << 25)->shiftRight(26);
        $h3 = $h3->addInt64($carry2);
        $h2 = $h2->subInt64($carry2->shiftLeft(26));
        $carry6 = $h6->addInt(1 << 25)->shiftRight(26);
        $h7 = $h7->addInt64($carry6);
        $h6 = $h6->subInt64($carry6->shiftLeft(26));

        $carry3 = $h3->addInt(1 << 24)->shiftRight(25);
        $h4 = $h4->addInt64($carry3);
        $h3 = $h3->subInt64($carry3->shiftLeft(25));
        $carry7 = $h7->addInt(1 << 24)->shiftRight(25);
        $h8 = $h8->addInt64($carry7);
        $h7 = $h7->subInt64($carry7->shiftLeft(25));

        $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
        $h5 = $h5->addInt64($carry4);
        $h4 = $h4->subInt64($carry4->shiftLeft(26));
        $carry8 = $h8->addInt(1 << 25)->shiftRight(26);
        $h9 = $h9->addInt64($carry8);
        $h8 = $h8->subInt64($carry8->shiftLeft(26));

        $carry9 = $h9->addInt(1 << 24)->shiftRight(25);
        $h0 = $h0->addInt64($carry9->mulInt(19, 5));
        $h9 = $h9->subInt64($carry9->shiftLeft(25));

        $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
        $h1 = $h1->addInt64($carry0);
        $h0 = $h0->subInt64($carry0->shiftLeft(26));

        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
            array(
                $h0->toInt32(),
                $h1->toInt32(),
                $h2->toInt32(),
                $h3->toInt32(),
                $h4->toInt32(),
                $h5->toInt32(),
                $h6->toInt32(),
                $h7->toInt32(),
                $h8->toInt32(),
                $h9->toInt32()
            )
        );
    }

    /**
     * Get the negative values for each piece of the field element.
     *
     * h = -f
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @psalm-suppress MixedAssignment
     * @psalm-suppress MixedMethodCall
     */
    public static function fe_neg(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
    {
        $h = new ParagonIE_Sodium_Core32_Curve25519_Fe();
        for ($i = 0; $i < 10; ++$i) {
            $h[$i] = $h[$i]->subInt32($f[$i]);
        }
        return $h;
    }

    /**
     * Square a field element
     *
     * h = f * f
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedMethodCall
     */
    public static function fe_sq(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
    {
        $f0 = $f[0]->toInt64();
        $f1 = $f[1]->toInt64();
        $f2 = $f[2]->toInt64();
        $f3 = $f[3]->toInt64();
        $f4 = $f[4]->toInt64();
        $f5 = $f[5]->toInt64();
        $f6 = $f[6]->toInt64();
        $f7 = $f[7]->toInt64();
        $f8 = $f[8]->toInt64();
        $f9 = $f[9]->toInt64();

        $f0_2 = $f0->shiftLeft(1);
        $f1_2 = $f1->shiftLeft(1);
        $f2_2 = $f2->shiftLeft(1);
        $f3_2 = $f3->shiftLeft(1);
        $f4_2 = $f4->shiftLeft(1);
        $f5_2 = $f5->shiftLeft(1);
        $f6_2 = $f6->shiftLeft(1);
        $f7_2 = $f7->shiftLeft(1);
        $f5_38 = $f5->mulInt(38, 6);
        $f6_19 = $f6->mulInt(19, 5);
        $f7_38 = $f7->mulInt(38, 6);
        $f8_19 = $f8->mulInt(19, 5);
        $f9_38 = $f9->mulInt(38, 6);

        $f0f0    = $f0->mulInt64($f0, 28);
        $f0f1_2  = $f0_2->mulInt64($f1, 28);
        $f0f2_2 =  $f0_2->mulInt64($f2, 28);
        $f0f3_2 =  $f0_2->mulInt64($f3, 28);
        $f0f4_2 =  $f0_2->mulInt64($f4, 28);
        $f0f5_2 =  $f0_2->mulInt64($f5, 28);
        $f0f6_2 =  $f0_2->mulInt64($f6, 28);
        $f0f7_2 =  $f0_2->mulInt64($f7, 28);
        $f0f8_2 =  $f0_2->mulInt64($f8, 28);
        $f0f9_2 =  $f0_2->mulInt64($f9, 28);

        $f1f1_2 = $f1_2->mulInt64($f1, 28);
        $f1f2_2 = $f1_2->mulInt64($f2, 28);
        $f1f3_4 = $f1_2->mulInt64($f3_2, 28);
        $f1f4_2 = $f1_2->mulInt64($f4, 28);
        $f1f5_4 = $f1_2->mulInt64($f5_2, 30);
        $f1f6_2 = $f1_2->mulInt64($f6, 28);
        $f1f7_4 = $f1_2->mulInt64($f7_2, 28);
        $f1f8_2 = $f1_2->mulInt64($f8, 28);
        $f1f9_76 = $f9_38->mulInt64($f1_2, 30);

        $f2f2 = $f2->mulInt64($f2, 28);
        $f2f3_2 = $f2_2->mulInt64($f3, 28);
        $f2f4_2 = $f2_2->mulInt64($f4, 28);
        $f2f5_2 = $f2_2->mulInt64($f5, 28);
        $f2f6_2 = $f2_2->mulInt64($f6, 28);
        $f2f7_2 = $f2_2->mulInt64($f7, 28);
        $f2f8_38 = $f8_19->mulInt64($f2_2, 30);
        $f2f9_38 = $f9_38->mulInt64($f2, 30);

        $f3f3_2 = $f3_2->mulInt64($f3, 28);
        $f3f4_2 = $f3_2->mulInt64($f4, 28);
        $f3f5_4 = $f3_2->mulInt64($f5_2, 30);
        $f3f6_2 = $f3_2->mulInt64($f6, 28);
        $f3f7_76 = $f7_38->mulInt64($f3_2, 30);
        $f3f8_38 = $f8_19->mulInt64($f3_2, 30);
        $f3f9_76 = $f9_38->mulInt64($f3_2, 30);

        $f4f4 = $f4->mulInt64($f4, 28);
        $f4f5_2 = $f4_2->mulInt64($f5, 28);
        $f4f6_38 = $f6_19->mulInt64($f4_2, 30);
        $f4f7_38 = $f7_38->mulInt64($f4, 30);
        $f4f8_38 = $f8_19->mulInt64($f4_2, 30);
        $f4f9_38 = $f9_38->mulInt64($f4, 30);

        $f5f5_38 = $f5_38->mulInt64($f5, 30);
        $f5f6_38 = $f6_19->mulInt64($f5_2, 30);
        $f5f7_76 = $f7_38->mulInt64($f5_2, 30);
        $f5f8_38 = $f8_19->mulInt64($f5_2, 30);
        $f5f9_76 = $f9_38->mulInt64($f5_2, 30);

        $f6f6_19 = $f6_19->mulInt64($f6, 30);
        $f6f7_38 = $f7_38->mulInt64($f6, 30);
        $f6f8_38 = $f8_19->mulInt64($f6_2, 30);
        $f6f9_38 = $f9_38->mulInt64($f6, 30);

        $f7f7_38 = $f7_38->mulInt64($f7, 28);
        $f7f8_38 = $f8_19->mulInt64($f7_2, 30);
        $f7f9_76 = $f9_38->mulInt64($f7_2, 30);

        $f8f8_19 = $f8_19->mulInt64($f8, 30);
        $f8f9_38 = $f9_38->mulInt64($f8, 30);

        $f9f9_38 = $f9_38->mulInt64($f9, 28);

        $h0 = $f0f0->addInt64($f1f9_76)->addInt64($f2f8_38)->addInt64($f3f7_76)->addInt64($f4f6_38)->addInt64($f5f5_38);
        $h1 = $f0f1_2->addInt64($f2f9_38)->addInt64($f3f8_38)->addInt64($f4f7_38)->addInt64($f5f6_38);
        $h2 = $f0f2_2->addInt64($f1f1_2)->addInt64($f3f9_76)->addInt64($f4f8_38)->addInt64($f5f7_76)->addInt64($f6f6_19);
        $h3 = $f0f3_2->addInt64($f1f2_2)->addInt64($f4f9_38)->addInt64($f5f8_38)->addInt64($f6f7_38);
        $h4 = $f0f4_2->addInt64($f1f3_4)->addInt64($f2f2)->addInt64($f5f9_76)->addInt64($f6f8_38)->addInt64($f7f7_38);
        $h5 = $f0f5_2->addInt64($f1f4_2)->addInt64($f2f3_2)->addInt64($f6f9_38)->addInt64($f7f8_38);
        $h6 = $f0f6_2->addInt64($f1f5_4)->addInt64($f2f4_2)->addInt64($f3f3_2)->addInt64($f7f9_76)->addInt64($f8f8_19);
        $h7 = $f0f7_2->addInt64($f1f6_2)->addInt64($f2f5_2)->addInt64($f3f4_2)->addInt64($f8f9_38);
        $h8 = $f0f8_2->addInt64($f1f7_4)->addInt64($f2f6_2)->addInt64($f3f5_4)->addInt64($f4f4)->addInt64($f9f9_38);
        $h9 = $f0f9_2->addInt64($f1f8_2)->addInt64($f2f7_2)->addInt64($f3f6_2)->addInt64($f4f5_2);

        /**
         * @var ParagonIE_Sodium_Core32_Int64 $h0
         * @var ParagonIE_Sodium_Core32_Int64 $h1
         * @var ParagonIE_Sodium_Core32_Int64 $h2
         * @var ParagonIE_Sodium_Core32_Int64 $h3
         * @var ParagonIE_Sodium_Core32_Int64 $h4
         * @var ParagonIE_Sodium_Core32_Int64 $h5
         * @var ParagonIE_Sodium_Core32_Int64 $h6
         * @var ParagonIE_Sodium_Core32_Int64 $h7
         * @var ParagonIE_Sodium_Core32_Int64 $h8
         * @var ParagonIE_Sodium_Core32_Int64 $h9
         */

        $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
        $h1 = $h1->addInt64($carry0);
        $h0 = $h0->subInt64($carry0->shiftLeft(26));

        $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
        $h5 = $h5->addInt64($carry4);
        $h4 = $h4->subInt64($carry4->shiftLeft(26));

        $carry1 = $h1->addInt(1 << 24)->shiftRight(25);
        $h2 = $h2->addInt64($carry1);
        $h1 = $h1->subInt64($carry1->shiftLeft(25));

        $carry5 = $h5->addInt(1 << 24)->shiftRight(25);
        $h6 = $h6->addInt64($carry5);
        $h5 = $h5->subInt64($carry5->shiftLeft(25));

        $carry2 = $h2->addInt(1 << 25)->shiftRight(26);
        $h3 = $h3->addInt64($carry2);
        $h2 = $h2->subInt64($carry2->shiftLeft(26));

        $carry6 = $h6->addInt(1 << 25)->shiftRight(26);
        $h7 = $h7->addInt64($carry6);
        $h6 = $h6->subInt64($carry6->shiftLeft(26));

        $carry3 = $h3->addInt(1 << 24)->shiftRight(25);
        $h4 = $h4->addInt64($carry3);
        $h3 = $h3->subInt64($carry3->shiftLeft(25));

        $carry7 = $h7->addInt(1 << 24)->shiftRight(25);
        $h8 = $h8->addInt64($carry7);
        $h7 = $h7->subInt64($carry7->shiftLeft(25));

        $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
        $h5 = $h5->addInt64($carry4);
        $h4 = $h4->subInt64($carry4->shiftLeft(26));

        $carry8 = $h8->addInt(1 << 25)->shiftRight(26);
        $h9 = $h9->addInt64($carry8);
        $h8 = $h8->subInt64($carry8->shiftLeft(26));

        $carry9 = $h9->addInt(1 << 24)->shiftRight(25);
        $h0 = $h0->addInt64($carry9->mulInt(19, 5));
        $h9 = $h9->subInt64($carry9->shiftLeft(25));

        $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
        $h1 = $h1->addInt64($carry0);
        $h0 = $h0->subInt64($carry0->shiftLeft(26));

        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
            array(
                $h0->toInt32(),
                $h1->toInt32(),
                $h2->toInt32(),
                $h3->toInt32(),
                $h4->toInt32(),
                $h5->toInt32(),
                $h6->toInt32(),
                $h7->toInt32(),
                $h8->toInt32(),
                $h9->toInt32()
            )
        );
    }

    /**
     * Square and double a field element
     *
     * h = 2 * f * f
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedMethodCall
     */
    public static function fe_sq2(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
    {
        $f0 = $f[0]->toInt64();
        $f1 = $f[1]->toInt64();
        $f2 = $f[2]->toInt64();
        $f3 = $f[3]->toInt64();
        $f4 = $f[4]->toInt64();
        $f5 = $f[5]->toInt64();
        $f6 = $f[6]->toInt64();
        $f7 = $f[7]->toInt64();
        $f8 = $f[8]->toInt64();
        $f9 = $f[9]->toInt64();

        $f0_2 = $f0->shiftLeft(1);
        $f1_2 = $f1->shiftLeft(1);
        $f2_2 = $f2->shiftLeft(1);
        $f3_2 = $f3->shiftLeft(1);
        $f4_2 = $f4->shiftLeft(1);
        $f5_2 = $f5->shiftLeft(1);
        $f6_2 = $f6->shiftLeft(1);
        $f7_2 = $f7->shiftLeft(1);
        $f5_38 = $f5->mulInt(38, 6); /* 1.959375*2^30 */
        $f6_19 = $f6->mulInt(19, 5); /* 1.959375*2^30 */
        $f7_38 = $f7->mulInt(38, 6); /* 1.959375*2^30 */
        $f8_19 = $f8->mulInt(19, 5); /* 1.959375*2^30 */
        $f9_38 = $f9->mulInt(38, 6); /* 1.959375*2^30 */
        $f0f0 = $f0->mulInt64($f0, 28);
        $f0f1_2 = $f0_2->mulInt64($f1, 28);
        $f0f2_2 = $f0_2->mulInt64($f2, 28);
        $f0f3_2 = $f0_2->mulInt64($f3, 28);
        $f0f4_2 = $f0_2->mulInt64($f4, 28);
        $f0f5_2 = $f0_2->mulInt64($f5, 28);
        $f0f6_2 = $f0_2->mulInt64($f6, 28);
        $f0f7_2 = $f0_2->mulInt64($f7, 28);
        $f0f8_2 = $f0_2->mulInt64($f8, 28);
        $f0f9_2 = $f0_2->mulInt64($f9, 28);
        $f1f1_2 = $f1_2->mulInt64($f1, 28);
        $f1f2_2 = $f1_2->mulInt64($f2, 28);
        $f1f3_4 = $f1_2->mulInt64($f3_2, 29);
        $f1f4_2 = $f1_2->mulInt64($f4, 28);
        $f1f5_4 = $f1_2->mulInt64($f5_2, 29);
        $f1f6_2 = $f1_2->mulInt64($f6, 28);
        $f1f7_4 = $f1_2->mulInt64($f7_2, 29);
        $f1f8_2 = $f1_2->mulInt64($f8, 28);
        $f1f9_76 = $f9_38->mulInt64($f1_2, 29);
        $f2f2 = $f2->mulInt64($f2, 28);
        $f2f3_2 = $f2_2->mulInt64($f3, 28);
        $f2f4_2 = $f2_2->mulInt64($f4, 28);
        $f2f5_2 = $f2_2->mulInt64($f5, 28);
        $f2f6_2 = $f2_2->mulInt64($f6, 28);
        $f2f7_2 = $f2_2->mulInt64($f7, 28);
        $f2f8_38 = $f8_19->mulInt64($f2_2, 29);
        $f2f9_38 = $f9_38->mulInt64($f2, 29);
        $f3f3_2 = $f3_2->mulInt64($f3, 28);
        $f3f4_2 = $f3_2->mulInt64($f4, 28);
        $f3f5_4 = $f3_2->mulInt64($f5_2, 28);
        $f3f6_2 = $f3_2->mulInt64($f6, 28);
        $f3f7_76 = $f7_38->mulInt64($f3_2, 29);
        $f3f8_38 = $f8_19->mulInt64($f3_2, 29);
        $f3f9_76 = $f9_38->mulInt64($f3_2, 29);
        $f4f4 = $f4->mulInt64($f4, 28);
        $f4f5_2 = $f4_2->mulInt64($f5, 28);
        $f4f6_38 = $f6_19->mulInt64($f4_2, 29);
        $f4f7_38 = $f7_38->mulInt64($f4, 29);
        $f4f8_38 = $f8_19->mulInt64($f4_2, 29);
        $f4f9_38 = $f9_38->mulInt64($f4, 29);
        $f5f5_38 = $f5_38->mulInt64($f5, 29);
        $f5f6_38 = $f6_19->mulInt64($f5_2, 29);
        $f5f7_76 = $f7_38->mulInt64($f5_2, 29);
        $f5f8_38 = $f8_19->mulInt64($f5_2, 29);
        $f5f9_76 = $f9_38->mulInt64($f5_2, 29);
        $f6f6_19 = $f6_19->mulInt64($f6, 29);
        $f6f7_38 = $f7_38->mulInt64($f6, 29);
        $f6f8_38 = $f8_19->mulInt64($f6_2, 29);
        $f6f9_38 = $f9_38->mulInt64($f6, 29);
        $f7f7_38 = $f7_38->mulInt64($f7, 29);
        $f7f8_38 = $f8_19->mulInt64($f7_2, 29);
        $f7f9_76 = $f9_38->mulInt64($f7_2, 29);
        $f8f8_19 = $f8_19->mulInt64($f8, 29);
        $f8f9_38 = $f9_38->mulInt64($f8, 29);
        $f9f9_38 = $f9_38->mulInt64($f9, 29);

        $h0 = $f0f0->addInt64($f1f9_76)->addInt64($f2f8_38)->addInt64($f3f7_76)->addInt64($f4f6_38)->addInt64($f5f5_38);
        $h1 = $f0f1_2->addInt64($f2f9_38)->addInt64($f3f8_38)->addInt64($f4f7_38)->addInt64($f5f6_38);
        $h2 = $f0f2_2->addInt64($f1f1_2)->addInt64($f3f9_76)->addInt64($f4f8_38)->addInt64($f5f7_76)->addInt64($f6f6_19);
        $h3 = $f0f3_2->addInt64($f1f2_2)->addInt64($f4f9_38)->addInt64($f5f8_38)->addInt64($f6f7_38);
        $h4 = $f0f4_2->addInt64($f1f3_4)->addInt64($f2f2)->addInt64($f5f9_76)->addInt64($f6f8_38)->addInt64($f7f7_38);
        $h5 = $f0f5_2->addInt64($f1f4_2)->addInt64($f2f3_2)->addInt64($f6f9_38)->addInt64($f7f8_38);
        $h6 = $f0f6_2->addInt64($f1f5_4)->addInt64($f2f4_2)->addInt64($f3f3_2)->addInt64($f7f9_76)->addInt64($f8f8_19);
        $h7 = $f0f7_2->addInt64($f1f6_2)->addInt64($f2f5_2)->addInt64($f3f4_2)->addInt64($f8f9_38);
        $h8 = $f0f8_2->addInt64($f1f7_4)->addInt64($f2f6_2)->addInt64($f3f5_4)->addInt64($f4f4)->addInt64($f9f9_38);
        $h9 = $f0f9_2->addInt64($f1f8_2)->addInt64($f2f7_2)->addInt64($f3f6_2)->addInt64($f4f5_2);

        /**
         * @var ParagonIE_Sodium_Core32_Int64 $h0
         * @var ParagonIE_Sodium_Core32_Int64 $h1
         * @var ParagonIE_Sodium_Core32_Int64 $h2
         * @var ParagonIE_Sodium_Core32_Int64 $h3
         * @var ParagonIE_Sodium_Core32_Int64 $h4
         * @var ParagonIE_Sodium_Core32_Int64 $h5
         * @var ParagonIE_Sodium_Core32_Int64 $h6
         * @var ParagonIE_Sodium_Core32_Int64 $h7
         * @var ParagonIE_Sodium_Core32_Int64 $h8
         * @var ParagonIE_Sodium_Core32_Int64 $h9
         */
        $h0 = $h0->shiftLeft(1);
        $h1 = $h1->shiftLeft(1);
        $h2 = $h2->shiftLeft(1);
        $h3 = $h3->shiftLeft(1);
        $h4 = $h4->shiftLeft(1);
        $h5 = $h5->shiftLeft(1);
        $h6 = $h6->shiftLeft(1);
        $h7 = $h7->shiftLeft(1);
        $h8 = $h8->shiftLeft(1);
        $h9 = $h9->shiftLeft(1);

        $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
        $h1 = $h1->addInt64($carry0);
        $h0 = $h0->subInt64($carry0->shiftLeft(26));
        $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
        $h5 = $h5->addInt64($carry4);
        $h4 = $h4->subInt64($carry4->shiftLeft(26));

        $carry1 = $h1->addInt(1 << 24)->shiftRight(25);
        $h2 = $h2->addInt64($carry1);
        $h1 = $h1->subInt64($carry1->shiftLeft(25));
        $carry5 = $h5->addInt(1 << 24)->shiftRight(25);
        $h6 = $h6->addInt64($carry5);
        $h5 = $h5->subInt64($carry5->shiftLeft(25));

        $carry2 = $h2->addInt(1 << 25)->shiftRight(26);
        $h3 = $h3->addInt64($carry2);
        $h2 = $h2->subInt64($carry2->shiftLeft(26));
        $carry6 = $h6->addInt(1 << 25)->shiftRight(26);
        $h7 = $h7->addInt64($carry6);
        $h6 = $h6->subInt64($carry6->shiftLeft(26));

        $carry3 = $h3->addInt(1 << 24)->shiftRight(25);
        $h4 = $h4->addInt64($carry3);
        $h3 = $h3->subInt64($carry3->shiftLeft(25));
        $carry7 = $h7->addInt(1 << 24)->shiftRight(25);
        $h8 = $h8->addInt64($carry7);
        $h7 = $h7->subInt64($carry7->shiftLeft(25));

        $carry4 = $h4->addInt(1 << 25)->shiftRight(26);
        $h5 = $h5->addInt64($carry4);
        $h4 = $h4->subInt64($carry4->shiftLeft(26));
        $carry8 = $h8->addInt(1 << 25)->shiftRight(26);
        $h9 = $h9->addInt64($carry8);
        $h8 = $h8->subInt64($carry8->shiftLeft(26));

        $carry9 = $h9->addInt(1 << 24)->shiftRight(25);
        $h0 = $h0->addInt64($carry9->mulInt(19, 5));
        $h9 = $h9->subInt64($carry9->shiftLeft(25));

        $carry0 = $h0->addInt(1 << 25)->shiftRight(26);
        $h1 = $h1->addInt64($carry0);
        $h0 = $h0->subInt64($carry0->shiftLeft(26));

        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
            array(
                $h0->toInt32(),
                $h1->toInt32(),
                $h2->toInt32(),
                $h3->toInt32(),
                $h4->toInt32(),
                $h5->toInt32(),
                $h6->toInt32(),
                $h7->toInt32(),
                $h8->toInt32(),
                $h9->toInt32()
            )
        );
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $Z
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fe_invert(ParagonIE_Sodium_Core32_Curve25519_Fe $Z)
    {
        $z = clone $Z;
        $t0 = self::fe_sq($z);
        $t1 = self::fe_sq($t0);
        $t1 = self::fe_sq($t1);
        $t1 = self::fe_mul($z, $t1);
        $t0 = self::fe_mul($t0, $t1);
        $t2 = self::fe_sq($t0);
        $t1 = self::fe_mul($t1, $t2);
        $t2 = self::fe_sq($t1);
        for ($i = 1; $i < 5; ++$i) {
            $t2 = self::fe_sq($t2);
        }
        $t1 = self::fe_mul($t2, $t1);
        $t2 = self::fe_sq($t1);
        for ($i = 1; $i < 10; ++$i) {
            $t2 = self::fe_sq($t2);
        }
        $t2 = self::fe_mul($t2, $t1);
        $t3 = self::fe_sq($t2);
        for ($i = 1; $i < 20; ++$i) {
            $t3 = self::fe_sq($t3);
        }
        $t2 = self::fe_mul($t3, $t2);
        $t2 = self::fe_sq($t2);
        for ($i = 1; $i < 10; ++$i) {
            $t2 = self::fe_sq($t2);
        }
        $t1 = self::fe_mul($t2, $t1);
        $t2 = self::fe_sq($t1);
        for ($i = 1; $i < 50; ++$i) {
            $t2 = self::fe_sq($t2);
        }
        $t2 = self::fe_mul($t2, $t1);
        $t3 = self::fe_sq($t2);
        for ($i = 1; $i < 100; ++$i) {
            $t3 = self::fe_sq($t3);
        }
        $t2 = self::fe_mul($t3, $t2);
        $t2 = self::fe_sq($t2);
        for ($i = 1; $i < 50; ++$i) {
            $t2 = self::fe_sq($t2);
        }
        $t1 = self::fe_mul($t2, $t1);
        $t1 = self::fe_sq($t1);
        for ($i = 1; $i < 5; ++$i) {
            $t1 = self::fe_sq($t1);
        }
        return self::fe_mul($t1, $t0);
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @ref https://github.com/jedisct1/libsodium/blob/68564326e1e9dc57ef03746f85734232d20ca6fb/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1054-L1106
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $z
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     */
    public static function fe_pow22523(ParagonIE_Sodium_Core32_Curve25519_Fe $z)
    {
        # fe_sq(t0, z);
        # fe_sq(t1, t0);
        # fe_sq(t1, t1);
        # fe_mul(t1, z, t1);
        # fe_mul(t0, t0, t1);
        # fe_sq(t0, t0);
        # fe_mul(t0, t1, t0);
        # fe_sq(t1, t0);
        $t0 = self::fe_sq($z);
        $t1 = self::fe_sq($t0);
        $t1 = self::fe_sq($t1);
        $t1 = self::fe_mul($z, $t1);
        $t0 = self::fe_mul($t0, $t1);
        $t0 = self::fe_sq($t0);
        $t0 = self::fe_mul($t1, $t0);
        $t1 = self::fe_sq($t0);

        # for (i = 1; i < 5; ++i) {
        #     fe_sq(t1, t1);
        # }
        for ($i = 1; $i < 5; ++$i) {
            $t1 = self::fe_sq($t1);
        }

        # fe_mul(t0, t1, t0);
        # fe_sq(t1, t0);
        $t0 = self::fe_mul($t1, $t0);
        $t1 = self::fe_sq($t0);

        # for (i = 1; i < 10; ++i) {
        #     fe_sq(t1, t1);
        # }
        for ($i = 1; $i < 10; ++$i) {
            $t1 = self::fe_sq($t1);
        }

        # fe_mul(t1, t1, t0);
        # fe_sq(t2, t1);
        $t1 = self::fe_mul($t1, $t0);
        $t2 = self::fe_sq($t1);

        # for (i = 1; i < 20; ++i) {
        #     fe_sq(t2, t2);
        # }
        for ($i = 1; $i < 20; ++$i) {
            $t2 = self::fe_sq($t2);
        }

        # fe_mul(t1, t2, t1);
        # fe_sq(t1, t1);
        $t1 = self::fe_mul($t2, $t1);
        $t1 = self::fe_sq($t1);

        # for (i = 1; i < 10; ++i) {
        #     fe_sq(t1, t1);
        # }
        for ($i = 1; $i < 10; ++$i) {
            $t1 = self::fe_sq($t1);
        }

        # fe_mul(t0, t1, t0);
        # fe_sq(t1, t0);
        $t0 = self::fe_mul($t1, $t0);
        $t1 = self::fe_sq($t0);

        # for (i = 1; i < 50; ++i) {
        #     fe_sq(t1, t1);
        # }
        for ($i = 1; $i < 50; ++$i) {
            $t1 = self::fe_sq($t1);
        }

        # fe_mul(t1, t1, t0);
        # fe_sq(t2, t1);
        $t1 = self::fe_mul($t1, $t0);
        $t2 = self::fe_sq($t1);

        # for (i = 1; i < 100; ++i) {
        #     fe_sq(t2, t2);
        # }
        for ($i = 1; $i < 100; ++$i) {
            $t2 = self::fe_sq($t2);
        }

        # fe_mul(t1, t2, t1);
        # fe_sq(t1, t1);
        $t1 = self::fe_mul($t2, $t1);
        $t1 = self::fe_sq($t1);

        # for (i = 1; i < 50; ++i) {
        #     fe_sq(t1, t1);
        # }
        for ($i = 1; $i < 50; ++$i) {
            $t1 = self::fe_sq($t1);
        }

        # fe_mul(t0, t1, t0);
        # fe_sq(t0, t0);
        # fe_sq(t0, t0);
        # fe_mul(out, t0, z);
        $t0 = self::fe_mul($t1, $t0);
        $t0 = self::fe_sq($t0);
        $t0 = self::fe_sq($t0);
        return self::fe_mul($t0, $z);
    }

    /**
     * Subtract two field elements.
     *
     * h = f - g
     *
     * Preconditions:
     * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
     * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
     *
     * Postconditions:
     * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
     * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
     * @return ParagonIE_Sodium_Core32_Curve25519_Fe
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedMethodCall
     * @psalm-suppress MixedTypeCoercion
     */
    public static function fe_sub(ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g)
    {
        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
            array(
                $f[0]->subInt32($g[0]),
                $f[1]->subInt32($g[1]),
                $f[2]->subInt32($g[2]),
                $f[3]->subInt32($g[3]),
                $f[4]->subInt32($g[4]),
                $f[5]->subInt32($g[5]),
                $f[6]->subInt32($g[6]),
                $f[7]->subInt32($g[7]),
                $f[8]->subInt32($g[8]),
                $f[9]->subInt32($g[9])
            )
        );
    }

    /**
     * Add two group elements.
     *
     * r = p + q
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_add(
        ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p,
        ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q
    ) {
        $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1();
        $r->X = self::fe_add($p->Y, $p->X);
        $r->Y = self::fe_sub($p->Y, $p->X);
        $r->Z = self::fe_mul($r->X, $q->YplusX);
        $r->Y = self::fe_mul($r->Y, $q->YminusX);
        $r->T = self::fe_mul($q->T2d, $p->T);
        $r->X = self::fe_mul($p->Z, $q->Z);
        $t0   = self::fe_add($r->X, $r->X);
        $r->X = self::fe_sub($r->Z, $r->Y);
        $r->Y = self::fe_add($r->Z, $r->Y);
        $r->Z = self::fe_add($t0, $r->T);
        $r->T = self::fe_sub($t0, $r->T);
        return $r;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @ref https://github.com/jedisct1/libsodium/blob/157c4a80c13b117608aeae12178b2d38825f9f8f/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1185-L1215
     * @param string $a
     * @return array<int, mixed>
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedArrayOffset
     */
    public static function slide($a)
    {
        if (self::strlen($a) < 256) {
            if (self::strlen($a) < 16) {
                $a = str_pad($a, 256, '0', STR_PAD_RIGHT);
            }
        }
        /** @var array<int, int> $r */
        $r = array();
        for ($i = 0; $i < 256; ++$i) {
            $r[$i] = (int) (1 &
                (
                    self::chrToInt($a[$i >> 3])
                        >>
                    ($i & 7)
                )
            );
        }

        for ($i = 0;$i < 256;++$i) {
            if ($r[$i]) {
                for ($b = 1;$b <= 6 && $i + $b < 256;++$b) {
                    if ($r[$i + $b]) {
                        if ($r[$i] + ($r[$i + $b] << $b) <= 15) {
                            $r[$i] += $r[$i + $b] << $b;
                            $r[$i + $b] = 0;
                        } elseif ($r[$i] - ($r[$i + $b] << $b) >= -15) {
                            $r[$i] -= $r[$i + $b] << $b;
                            for ($k = $i + $b; $k < 256; ++$k) {
                                if (!$r[$k]) {
                                    $r[$k] = 1;
                                    break;
                                }
                                $r[$k] = 0;
                            }
                        } else {
                            break;
                        }
                    }
                }
            }
        }
        return $r;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param string $s
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_frombytes_negate_vartime($s)
    {
        static $d = null;
        if (!$d) {
            $d = ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
                array(
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[0]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[1]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[2]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[3]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[4]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[5]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[6]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[7]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[8]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[9])
                )
            );
        }
        /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d */

        # fe_frombytes(h->Y,s);
        # fe_1(h->Z);
        $h = new ParagonIE_Sodium_Core32_Curve25519_Ge_P3(
            self::fe_0(),
            self::fe_frombytes($s),
            self::fe_1()
        );

        # fe_sq(u,h->Y);
        # fe_mul(v,u,d);
        # fe_sub(u,u,h->Z);       /* u = y^2-1 */
        # fe_add(v,v,h->Z);       /* v = dy^2+1 */
        $u = self::fe_sq($h->Y);
        /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d */
        $v = self::fe_mul($u, $d);
        $u = self::fe_sub($u, $h->Z); /* u =  y^2 - 1 */
        $v = self::fe_add($v, $h->Z); /* v = dy^2 + 1 */

        # fe_sq(v3,v);
        # fe_mul(v3,v3,v);        /* v3 = v^3 */
        # fe_sq(h->X,v3);
        # fe_mul(h->X,h->X,v);
        # fe_mul(h->X,h->X,u);    /* x = uv^7 */
        $v3 = self::fe_sq($v);
        $v3 = self::fe_mul($v3, $v); /* v3 = v^3 */
        $h->X = self::fe_sq($v3);
        $h->X = self::fe_mul($h->X, $v);
        $h->X = self::fe_mul($h->X, $u); /* x = uv^7 */

        # fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */
        # fe_mul(h->X,h->X,v3);
        # fe_mul(h->X,h->X,u);    /* x = uv^3(uv^7)^((q-5)/8) */
        $h->X = self::fe_pow22523($h->X); /* x = (uv^7)^((q-5)/8) */
        $h->X = self::fe_mul($h->X, $v3);
        $h->X = self::fe_mul($h->X, $u); /* x = uv^3(uv^7)^((q-5)/8) */

        # fe_sq(vxx,h->X);
        # fe_mul(vxx,vxx,v);
        # fe_sub(check,vxx,u);    /* vx^2-u */
        $vxx = self::fe_sq($h->X);
        $vxx = self::fe_mul($vxx, $v);
        $check = self::fe_sub($vxx, $u); /* vx^2 - u */

        # if (fe_isnonzero(check)) {
        #     fe_add(check,vxx,u);  /* vx^2+u */
        #     if (fe_isnonzero(check)) {
        #         return -1;
        #     }
        #     fe_mul(h->X,h->X,sqrtm1);
        # }
        if (self::fe_isnonzero($check)) {
            $check = self::fe_add($vxx, $u); /* vx^2 + u */
            if (self::fe_isnonzero($check)) {
                throw new RangeException('Internal check failed.');
            }
            $h->X = self::fe_mul(
                $h->X,
                ParagonIE_Sodium_Core32_Curve25519_Fe::fromIntArray(self::$sqrtm1)
            );
        }

        # if (fe_isnegative(h->X) == (s[31] >> 7)) {
        #     fe_neg(h->X,h->X);
        # }
        $i = self::chrToInt($s[31]);
        if (self::fe_isnegative($h->X) === ($i >> 7)) {
            $h->X = self::fe_neg($h->X);
        }

        # fe_mul(h->T,h->X,h->Y);
        $h->T = self::fe_mul($h->X, $h->Y);
        return $h;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_madd(
        ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R,
        ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p,
        ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q
    ) {
        $r = clone $R;
        $r->X = self::fe_add($p->Y, $p->X);
        $r->Y = self::fe_sub($p->Y, $p->X);
        $r->Z = self::fe_mul($r->X, $q->yplusx);
        $r->Y = self::fe_mul($r->Y, $q->yminusx);
        $r->T = self::fe_mul($q->xy2d, $p->T);
        $t0 = self::fe_add(clone $p->Z, clone $p->Z);
        $r->X = self::fe_sub($r->Z, $r->Y);
        $r->Y = self::fe_add($r->Z, $r->Y);
        $r->Z = self::fe_add($t0, $r->T);
        $r->T = self::fe_sub($t0, $r->T);

        return $r;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_msub(
        ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R,
        ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p,
        ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q
    ) {
        $r = clone $R;

        $r->X = self::fe_add($p->Y, $p->X);
        $r->Y = self::fe_sub($p->Y, $p->X);
        $r->Z = self::fe_mul($r->X, $q->yminusx);
        $r->Y = self::fe_mul($r->Y, $q->yplusx);
        $r->T = self::fe_mul($q->xy2d, $p->T);
        $t0 = self::fe_add($p->Z, $p->Z);
        $r->X = self::fe_sub($r->Z, $r->Y);
        $r->Y = self::fe_add($r->Z, $r->Y);
        $r->Z = self::fe_sub($t0, $r->T);
        $r->T = self::fe_add($t0, $r->T);

        return $r;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_p1p1_to_p2(ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p)
    {
        $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P2();
        $r->X = self::fe_mul($p->X, $p->T);
        $r->Y = self::fe_mul($p->Y, $p->Z);
        $r->Z = self::fe_mul($p->Z, $p->T);
        return $r;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_p1p1_to_p3(ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p)
    {
        $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P3();
        $r->X = self::fe_mul($p->X, $p->T);
        $r->Y = self::fe_mul($p->Y, $p->Z);
        $r->Z = self::fe_mul($p->Z, $p->T);
        $r->T = self::fe_mul($p->X, $p->Y);
        return $r;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_p2_0()
    {
        return new ParagonIE_Sodium_Core32_Curve25519_Ge_P2(
            self::fe_0(),
            self::fe_1(),
            self::fe_1()
        );
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $p
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_p2_dbl(ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $p)
    {
        $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1();

        $r->X = self::fe_sq($p->X);
        $r->Z = self::fe_sq($p->Y);
        $r->T = self::fe_sq2($p->Z);
        $r->Y = self::fe_add($p->X, $p->Y);
        $t0   = self::fe_sq($r->Y);
        $r->Y = self::fe_add($r->Z, $r->X);
        $r->Z = self::fe_sub($r->Z, $r->X);
        $r->X = self::fe_sub($t0, $r->Y);
        $r->T = self::fe_sub($r->T, $r->Z);

        return $r;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_p3_0()
    {
        return new ParagonIE_Sodium_Core32_Curve25519_Ge_P3(
            self::fe_0(),
            self::fe_1(),
            self::fe_1(),
            self::fe_0()
        );
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Cached
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_p3_to_cached(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p)
    {
        static $d2 = null;
        if ($d2 === null) {
            $d2 = ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
                array(
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[0]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[1]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[2]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[3]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[4]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[5]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[6]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[7]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[8]),
                    ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[9])
                )
            );
        }
        /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d2 */
        $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_Cached();
        $r->YplusX = self::fe_add($p->Y, $p->X);
        $r->YminusX = self::fe_sub($p->Y, $p->X);
        $r->Z = self::fe_copy($p->Z);
        $r->T2d = self::fe_mul($p->T, $d2);
        return $r;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2
     */
    public static function ge_p3_to_p2(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p)
    {
        return new ParagonIE_Sodium_Core32_Curve25519_Ge_P2(
            $p->X,
            $p->Y,
            $p->Z
        );
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $h
     * @return string
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_p3_tobytes(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $h)
    {
        $recip = self::fe_invert($h->Z);
        $x = self::fe_mul($h->X, $recip);
        $y = self::fe_mul($h->Y, $recip);
        $s = self::fe_tobytes($y);
        $s[31] = self::intToChr(
            self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7)
        );
        return $s;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_p3_dbl(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p)
    {
        $q = self::ge_p3_to_p2($p);
        return self::ge_p2_dbl($q);
    }

    /**
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_precomp_0()
    {
        return new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
            self::fe_1(),
            self::fe_1(),
            self::fe_0()
        );
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param int $b
     * @param int $c
     * @return int
     * @psalm-suppress MixedReturnStatement
     */
    public static function equal($b, $c)
    {
        $b0 = $b & 0xffff;
        $b1 = ($b >> 16) & 0xffff;
        $c0 = $c & 0xffff;
        $c1 = ($c >> 16) & 0xffff;

        $d0 = (($b0 ^ $c0) - 1) >> 31;
        $d1 = (($b1 ^ $c1) - 1) >> 31;
        return ($d0 & $d1) & 1;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param string|int $char
     * @return int (1 = yes, 0 = no)
     * @throws SodiumException
     * @throws TypeError
     */
    public static function negative($char)
    {
        if (is_int($char)) {
            return $char < 0 ? 1 : 0;
        }
        /** @var string $char */
        $x = self::chrToInt(self::substr($char, 0, 1));
        return (int) ($x >> 31);
    }

    /**
     * Conditional move
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $t
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $u
     * @param int $b
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
     * @throws SodiumException
     * @throws TypeError
     */
    public static function cmov(
        ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $t,
        ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $u,
        $b
    ) {
        if (!is_int($b)) {
            throw new InvalidArgumentException('Expected an integer.');
        }
        return new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
            self::fe_cmov($t->yplusx, $u->yplusx, $b),
            self::fe_cmov($t->yminusx, $u->yminusx, $b),
            self::fe_cmov($t->xy2d, $u->xy2d, $b)
        );
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param int $pos
     * @param int $b
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedArrayAccess
     * @psalm-suppress MixedArrayOffset
     * @psalm-suppress MixedArgument
     */
    public static function ge_select($pos = 0, $b = 0)
    {
        static $base = null;
        if ($base === null) {
            $base = array();
            foreach (self::$base as $i => $bas) {
                for ($j = 0; $j < 8; ++$j) {
                    $base[$i][$j] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
                        ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
                            array(
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][0]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][1]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][2]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][3]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][4]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][5]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][6]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][7]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][8]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][9])
                            )
                        ),
                        ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
                            array(
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][0]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][1]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][2]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][3]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][4]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][5]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][6]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][7]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][8]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][9])
                            )
                        ),
                        ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
                            array(
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][0]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][1]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][2]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][3]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][4]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][5]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][6]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][7]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][8]),
                                ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][9])
                            )
                        )
                    );
                }
            }
        }
        if (!is_int($pos)) {
            throw new InvalidArgumentException('Position must be an integer');
        }
        if ($pos < 0 || $pos > 31) {
            throw new RangeException('Position is out of range [0, 31]');
        }

        $bnegative = self::negative($b);
        $babs = $b - (((-$bnegative) & $b) << 1);

        $t = self::ge_precomp_0();
        for ($i = 0; $i < 8; ++$i) {
            $t = self::cmov(
                $t,
                $base[$pos][$i],
                -self::equal($babs, $i + 1)
            );
        }
        $minusT = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
            self::fe_copy($t->yminusx),
            self::fe_copy($t->yplusx),
            self::fe_neg($t->xy2d)
        );
        return self::cmov($t, $minusT, -$bnegative);
    }

    /**
     * Subtract two group elements.
     *
     * r = p - q
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_sub(
        ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p,
        ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q
    ) {
        $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1();

        $r->X = self::fe_add($p->Y, $p->X);
        $r->Y = self::fe_sub($p->Y, $p->X);
        $r->Z = self::fe_mul($r->X, $q->YminusX);
        $r->Y = self::fe_mul($r->Y, $q->YplusX);
        $r->T = self::fe_mul($q->T2d, $p->T);
        $r->X = self::fe_mul($p->Z, $q->Z);
        $t0 = self::fe_add($r->X, $r->X);
        $r->X = self::fe_sub($r->Z, $r->Y);
        $r->Y = self::fe_add($r->Z, $r->Y);
        $r->Z = self::fe_sub($t0, $r->T);
        $r->T = self::fe_add($t0, $r->T);

        return $r;
    }

    /**
     * Convert a group element to a byte string.
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $h
     * @return string
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_tobytes(ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $h)
    {
        $recip = self::fe_invert($h->Z);
        $x = self::fe_mul($h->X, $recip);
        $y = self::fe_mul($h->Y, $recip);
        $s = self::fe_tobytes($y);
        $s[31] = self::intToChr(
            self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7)
        );
        return $s;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param string $a
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A
     * @param string $b
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedArrayAccess
     */
    public static function ge_double_scalarmult_vartime(
        $a,
        ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A,
        $b
    ) {
        /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai */
        $Ai = array();

        static $Bi = array();
        /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp> $Bi */
        if (!$Bi) {
            for ($i = 0; $i < 8; ++$i) {
                $Bi[$i] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp(
                    ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
                        array(
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][0]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][1]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][2]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][3]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][4]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][5]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][6]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][7]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][8]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][9])
                        )
                    ),
                    ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
                        array(
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][0]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][1]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][2]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][3]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][4]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][5]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][6]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][7]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][8]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][9])
                        )
                    ),
                    ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray(
                        array(
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][0]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][1]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][2]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][3]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][4]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][5]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][6]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][7]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][8]),
                            ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][9])
                        )
                    )
                );
            }
        }

        for ($i = 0; $i < 8; ++$i) {
            $Ai[$i] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Cached(
                self::fe_0(),
                self::fe_0(),
                self::fe_0(),
                self::fe_0()
            );
        }
        /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai */

        # slide(aslide,a);
        # slide(bslide,b);
        /** @var array<int, int> $aslide */
        $aslide = self::slide($a);
        /** @var array<int, int> $bslide */
        $bslide = self::slide($b);

        # ge_p3_to_cached(&Ai[0],A);
        # ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t);
        $Ai[0] = self::ge_p3_to_cached($A);
        $t = self::ge_p3_dbl($A);
        $A2 = self::ge_p1p1_to_p3($t);

        # ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u);
        # ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u);
        # ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u);
        # ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u);
        # ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u);
        # ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u);
        # ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u);
        for ($i = 0; $i < 7; ++$i) {
            $t = self::ge_add($A2, $Ai[$i]);
            $u = self::ge_p1p1_to_p3($t);
            $Ai[$i + 1] = self::ge_p3_to_cached($u);
        }

        # ge_p2_0(r);
        $r = self::ge_p2_0();

        # for (i = 255;i >= 0;--i) {
        #     if (aslide[i] || bslide[i]) break;
        # }
        $i = 255;
        for (; $i >= 0; --$i) {
            if ($aslide[$i] || $bslide[$i]) {
                break;
            }
        }

        # for (;i >= 0;--i) {
        for (; $i >= 0; --$i) {
            # ge_p2_dbl(&t,r);
            $t = self::ge_p2_dbl($r);

            # if (aslide[i] > 0) {
            if ($aslide[$i] > 0) {
                # ge_p1p1_to_p3(&u,&t);
                # ge_add(&t,&u,&Ai[aslide[i]/2]);
                $u = self::ge_p1p1_to_p3($t);
                $t = self::ge_add(
                    $u,
                    $Ai[(int) floor($aslide[$i] / 2)]
                );
                # } else if (aslide[i] < 0) {
            } elseif ($aslide[$i] < 0) {
                # ge_p1p1_to_p3(&u,&t);
                # ge_sub(&t,&u,&Ai[(-aslide[i])/2]);
                $u = self::ge_p1p1_to_p3($t);
                $t = self::ge_sub(
                    $u,
                    $Ai[(int) floor(-$aslide[$i] / 2)]
                );
            }
            /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp> $Bi */

            # if (bslide[i] > 0) {
            if ($bslide[$i] > 0) {
                # ge_p1p1_to_p3(&u,&t);
                # ge_madd(&t,&u,&Bi[bslide[i]/2]);
                $u = self::ge_p1p1_to_p3($t);
                /** @var int $index */
                $index = (int) floor($bslide[$i] / 2);
                /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $thisB */
                $thisB = $Bi[$index];
                $t = self::ge_madd($t, $u, $thisB);
                # } else if (bslide[i] < 0) {
            } elseif ($bslide[$i] < 0) {
                # ge_p1p1_to_p3(&u,&t);
                # ge_msub(&t,&u,&Bi[(-bslide[i])/2]);
                $u = self::ge_p1p1_to_p3($t);

                /** @var int $index */
                $index = (int) floor(-$bslide[$i] / 2);

                /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $thisB */
                $thisB = $Bi[$index];
                $t = self::ge_msub($t, $u, $thisB);
            }
            # ge_p1p1_to_p2(r,&t);
            $r = self::ge_p1p1_to_p2($t);
        }
        return $r;
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param string $a
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
     * @psalm-suppress MixedAssignment
     * @psalm-suppress MixedOperand
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_scalarmult_base($a)
    {
        /** @var array<int, int> $e */
        $e = array();
        $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1();

        for ($i = 0; $i < 32; ++$i) {
            /** @var int $dbl */
            $dbl = (int) $i << 1;
            $e[$dbl] = (int) self::chrToInt($a[$i]) & 15;
            $e[$dbl + 1] = (int) (self::chrToInt($a[$i]) >> 4) & 15;
        }

        /** @var int $carry */
        $carry = 0;
        for ($i = 0; $i < 63; ++$i) {
            $e[$i] += $carry;
            $carry = $e[$i] + 8;
            $carry >>= 4;
            $e[$i] -= $carry << 4;
        }

        /** @var array<int, int> $e */
        $e[63] += (int) $carry;

        $h = self::ge_p3_0();

        for ($i = 1; $i < 64; $i += 2) {
            $t = self::ge_select((int) floor($i / 2), (int) $e[$i]);
            $r = self::ge_madd($r, $h, $t);
            $h = self::ge_p1p1_to_p3($r);
        }

        $r = self::ge_p3_dbl($h);

        $s = self::ge_p1p1_to_p2($r);
        $r = self::ge_p2_dbl($s);
        $s = self::ge_p1p1_to_p2($r);
        $r = self::ge_p2_dbl($s);
        $s = self::ge_p1p1_to_p2($r);
        $r = self::ge_p2_dbl($s);

        $h = self::ge_p1p1_to_p3($r);

        for ($i = 0; $i < 64; $i += 2) {
            $t = self::ge_select($i >> 1, (int) $e[$i]);
            $r = self::ge_madd($r, $h, $t);
            $h = self::ge_p1p1_to_p3($r);
        }
        return $h;
    }

    /**
     * Calculates (ab + c) mod l
     * where l = 2^252 + 27742317777372353535851937790883648493
     *
     * @internal You should not use this directly from another application
     *
     * @param string $a
     * @param string $b
     * @param string $c
     * @return string
     * @throws SodiumException
     * @throws TypeError
     */
    public static function sc_muladd($a, $b, $c)
    {
        $a0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($a, 0, 3)));
        $a1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 2, 4)) >> 5));
        $a2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 5, 3)) >> 2));
        $a3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 7, 4)) >> 7));
        $a4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 10, 4)) >> 4));
        $a5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 13, 3)) >> 1));
        $a6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 15, 4)) >> 6));
        $a7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 18, 3)) >> 3));
        $a8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($a, 21, 3)));
        $a9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 23, 4)) >> 5));
        $a10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 26, 3)) >> 2));
        $a11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($a, 28, 4)) >> 7));
        $b0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($b, 0, 3)));
        $b1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 2, 4)) >> 5));
        $b2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 5, 3)) >> 2));
        $b3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 7, 4)) >> 7));
        $b4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 10, 4)) >> 4));
        $b5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 13, 3)) >> 1));
        $b6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 15, 4)) >> 6));
        $b7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 18, 3)) >> 3));
        $b8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($b, 21, 3)));
        $b9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 23, 4)) >> 5));
        $b10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 26, 3)) >> 2));
        $b11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($b, 28, 4)) >> 7));
        $c0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($c, 0, 3)));
        $c1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 2, 4)) >> 5));
        $c2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 5, 3)) >> 2));
        $c3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 7, 4)) >> 7));
        $c4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 10, 4)) >> 4));
        $c5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 13, 3)) >> 1));
        $c6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 15, 4)) >> 6));
        $c7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 18, 3)) >> 3));
        $c8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($c, 21, 3)));
        $c9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 23, 4)) >> 5));
        $c10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 26, 3)) >> 2));
        $c11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($c, 28, 4)) >> 7));

        /* Can't really avoid the pyramid here: */
        /**
         * @var ParagonIE_Sodium_Core32_Int64 $s0
         * @var ParagonIE_Sodium_Core32_Int64 $s1
         * @var ParagonIE_Sodium_Core32_Int64 $s2
         * @var ParagonIE_Sodium_Core32_Int64 $s3
         * @var ParagonIE_Sodium_Core32_Int64 $s4
         * @var ParagonIE_Sodium_Core32_Int64 $s5
         * @var ParagonIE_Sodium_Core32_Int64 $s6
         * @var ParagonIE_Sodium_Core32_Int64 $s7
         * @var ParagonIE_Sodium_Core32_Int64 $s8
         * @var ParagonIE_Sodium_Core32_Int64 $s9
         * @var ParagonIE_Sodium_Core32_Int64 $s10
         * @var ParagonIE_Sodium_Core32_Int64 $s11
         * @var ParagonIE_Sodium_Core32_Int64 $s12
         * @var ParagonIE_Sodium_Core32_Int64 $s13
         * @var ParagonIE_Sodium_Core32_Int64 $s14
         * @var ParagonIE_Sodium_Core32_Int64 $s15
         * @var ParagonIE_Sodium_Core32_Int64 $s16
         * @var ParagonIE_Sodium_Core32_Int64 $s17
         * @var ParagonIE_Sodium_Core32_Int64 $s18
         * @var ParagonIE_Sodium_Core32_Int64 $s19
         * @var ParagonIE_Sodium_Core32_Int64 $s20
         * @var ParagonIE_Sodium_Core32_Int64 $s21
         * @var ParagonIE_Sodium_Core32_Int64 $s22
         * @var ParagonIE_Sodium_Core32_Int64 $s23
         */

        $s0 = $c0->addInt64($a0->mulInt64($b0, 24));
        $s1 = $c1->addInt64($a0->mulInt64($b1, 24))->addInt64($a1->mulInt64($b0, 24));
        $s2 = $c2->addInt64($a0->mulInt64($b2, 24))->addInt64($a1->mulInt64($b1, 24))->addInt64($a2->mulInt64($b0, 24));
        $s3 = $c3->addInt64($a0->mulInt64($b3, 24))->addInt64($a1->mulInt64($b2, 24))->addInt64($a2->mulInt64($b1, 24))
                 ->addInt64($a3->mulInt64($b0, 24));
        $s4 = $c4->addInt64($a0->mulInt64($b4, 24))->addInt64($a1->mulInt64($b3, 24))->addInt64($a2->mulInt64($b2, 24))
                 ->addInt64($a3->mulInt64($b1, 24))->addInt64($a4->mulInt64($b0, 24));
        $s5 = $c5->addInt64($a0->mulInt64($b5, 24))->addInt64($a1->mulInt64($b4, 24))->addInt64($a2->mulInt64($b3, 24))
                 ->addInt64($a3->mulInt64($b2, 24))->addInt64($a4->mulInt64($b1, 24))->addInt64($a5->mulInt64($b0, 24));
        $s6 = $c6->addInt64($a0->mulInt64($b6, 24))->addInt64($a1->mulInt64($b5, 24))->addInt64($a2->mulInt64($b4, 24))
                 ->addInt64($a3->mulInt64($b3, 24))->addInt64($a4->mulInt64($b2, 24))->addInt64($a5->mulInt64($b1, 24))
                 ->addInt64($a6->mulInt64($b0, 24));
        $s7 = $c7->addInt64($a0->mulInt64($b7, 24))->addInt64($a1->mulInt64($b6, 24))->addInt64($a2->mulInt64($b5, 24))
                 ->addInt64($a3->mulInt64($b4, 24))->addInt64($a4->mulInt64($b3, 24))->addInt64($a5->mulInt64($b2, 24))
                 ->addInt64($a6->mulInt64($b1, 24))->addInt64($a7->mulInt64($b0, 24));
        $s8 = $c8->addInt64($a0->mulInt64($b8, 24))->addInt64($a1->mulInt64($b7, 24))->addInt64($a2->mulInt64($b6, 24))
                 ->addInt64($a3->mulInt64($b5, 24))->addInt64($a4->mulInt64($b4, 24))->addInt64($a5->mulInt64($b3, 24))
                 ->addInt64($a6->mulInt64($b2, 24))->addInt64($a7->mulInt64($b1, 24))->addInt64($a8->mulInt64($b0, 24));
        $s9 = $c9->addInt64($a0->mulInt64($b9, 24))->addInt64($a1->mulInt64($b8, 24))->addInt64($a2->mulInt64($b7, 24))
                 ->addInt64($a3->mulInt64($b6, 24))->addInt64($a4->mulInt64($b5, 24))->addInt64($a5->mulInt64($b4, 24))
                 ->addInt64($a6->mulInt64($b3, 24))->addInt64($a7->mulInt64($b2, 24))->addInt64($a8->mulInt64($b1, 24))
                 ->addInt64($a9->mulInt64($b0, 24));
        $s10 = $c10->addInt64($a0->mulInt64($b10, 24))->addInt64($a1->mulInt64($b9, 24))->addInt64($a2->mulInt64($b8, 24))
                   ->addInt64($a3->mulInt64($b7, 24))->addInt64($a4->mulInt64($b6, 24))->addInt64($a5->mulInt64($b5, 24))
                   ->addInt64($a6->mulInt64($b4, 24))->addInt64($a7->mulInt64($b3, 24))->addInt64($a8->mulInt64($b2, 24))
                   ->addInt64($a9->mulInt64($b1, 24))->addInt64($a10->mulInt64($b0, 24));
        $s11 = $c11->addInt64($a0->mulInt64($b11, 24))->addInt64($a1->mulInt64($b10, 24))->addInt64($a2->mulInt64($b9, 24))
                   ->addInt64($a3->mulInt64($b8, 24))->addInt64($a4->mulInt64($b7, 24))->addInt64($a5->mulInt64($b6, 24))
                   ->addInt64($a6->mulInt64($b5, 24))->addInt64($a7->mulInt64($b4, 24))->addInt64($a8->mulInt64($b3, 24))
                   ->addInt64($a9->mulInt64($b2, 24))->addInt64($a10->mulInt64($b1, 24))->addInt64($a11->mulInt64($b0, 24));
        $s12 = $a1->mulInt64($b11, 24)->addInt64($a2->mulInt64($b10, 24))->addInt64($a3->mulInt64($b9, 24))
                  ->addInt64($a4->mulInt64($b8, 24))->addInt64($a5->mulInt64($b7, 24))->addInt64($a6->mulInt64($b6, 24))
                  ->addInt64($a7->mulInt64($b5, 24))->addInt64($a8->mulInt64($b4, 24))->addInt64($a9->mulInt64($b3, 24))
                  ->addInt64($a10->mulInt64($b2, 24))->addInt64($a11->mulInt64($b1, 24));
        $s13 = $a2->mulInt64($b11, 24)->addInt64($a3->mulInt64($b10, 24))->addInt64($a4->mulInt64($b9, 24))
                  ->addInt64($a5->mulInt64($b8, 24))->addInt64($a6->mulInt64($b7, 24))->addInt64($a7->mulInt64($b6, 24))
                  ->addInt64($a8->mulInt64($b5, 24))->addInt64($a9->mulInt64($b4, 24))->addInt64($a10->mulInt64($b3, 24))
                  ->addInt64($a11->mulInt64($b2, 24));
        $s14 = $a3->mulInt64($b11, 24)->addInt64($a4->mulInt64($b10, 24))->addInt64($a5->mulInt64($b9, 24))
                  ->addInt64($a6->mulInt64($b8, 24))->addInt64($a7->mulInt64($b7, 24))->addInt64($a8->mulInt64($b6, 24))
                  ->addInt64($a9->mulInt64($b5, 24))->addInt64($a10->mulInt64($b4, 24))->addInt64($a11->mulInt64($b3, 24));
        $s15 = $a4->mulInt64($b11, 24)->addInt64($a5->mulInt64($b10, 24))->addInt64($a6->mulInt64($b9, 24))
                  ->addInt64($a7->mulInt64($b8, 24))->addInt64($a8->mulInt64($b7, 24))->addInt64($a9->mulInt64($b6, 24))
                  ->addInt64($a10->mulInt64($b5, 24))->addInt64($a11->mulInt64($b4, 24));
        $s16 = $a5->mulInt64($b11, 24)->addInt64($a6->mulInt64($b10, 24))->addInt64($a7->mulInt64($b9, 24))
                  ->addInt64($a8->mulInt64($b8, 24))->addInt64($a9->mulInt64($b7, 24))->addInt64($a10->mulInt64($b6, 24))
                  ->addInt64($a11->mulInt64($b5, 24));
        $s17 = $a6->mulInt64($b11, 24)->addInt64($a7->mulInt64($b10, 24))->addInt64($a8->mulInt64($b9, 24))
                  ->addInt64($a9->mulInt64($b8, 24))->addInt64($a10->mulInt64($b7, 24))->addInt64($a11->mulInt64($b6, 24));
        $s18 = $a7->mulInt64($b11, 24)->addInt64($a8->mulInt64($b10, 24))->addInt64($a9->mulInt64($b9, 24))
                  ->addInt64($a10->mulInt64($b8, 24))->addInt64($a11->mulInt64($b7, 24));
        $s19 = $a8->mulInt64($b11, 24)->addInt64($a9->mulInt64($b10, 24))->addInt64($a10->mulInt64($b9, 24))
                  ->addInt64($a11->mulInt64($b8, 24));
        $s20 = $a9->mulInt64($b11, 24)->addInt64($a10->mulInt64($b10, 24))->addInt64($a11->mulInt64($b9, 24));
        $s21 = $a10->mulInt64($b11, 24)->addInt64($a11->mulInt64($b10, 24));
        $s22 = $a11->mulInt64($b11, 24);
        $s23 = new ParagonIE_Sodium_Core32_Int64();

        $carry0 = $s0->addInt(1 << 20)->shiftRight(21);
        $s1 = $s1->addInt64($carry0);
        $s0 = $s0->subInt64($carry0->shiftLeft(21));
        $carry2 = $s2->addInt(1 << 20)->shiftRight(21);
        $s3 = $s3->addInt64($carry2);
        $s2 = $s2->subInt64($carry2->shiftLeft(21));
        $carry4 = $s4->addInt(1 << 20)->shiftRight(21);
        $s5 = $s5->addInt64($carry4);
        $s4 = $s4->subInt64($carry4->shiftLeft(21));
        $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
        $s7 = $s7->addInt64($carry6);
        $s6 = $s6->subInt64($carry6->shiftLeft(21));
        $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
        $s9 = $s9->addInt64($carry8);
        $s8 = $s8->subInt64($carry8->shiftLeft(21));
        $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
        $s11 = $s11->addInt64($carry10);
        $s10 = $s10->subInt64($carry10->shiftLeft(21));
        $carry12 = $s12->addInt(1 << 20)->shiftRight(21);
        $s13 = $s13->addInt64($carry12);
        $s12 = $s12->subInt64($carry12->shiftLeft(21));
        $carry14 = $s14->addInt(1 << 20)->shiftRight(21);
        $s15 = $s15->addInt64($carry14);
        $s14 = $s14->subInt64($carry14->shiftLeft(21));
        $carry16 = $s16->addInt(1 << 20)->shiftRight(21);
        $s17 = $s17->addInt64($carry16);
        $s16 = $s16->subInt64($carry16->shiftLeft(21));
        $carry18 = $s18->addInt(1 << 20)->shiftRight(21);
        $s19 = $s19->addInt64($carry18);
        $s18 = $s18->subInt64($carry18->shiftLeft(21));
        $carry20 = $s20->addInt(1 << 20)->shiftRight(21);
        $s21 = $s21->addInt64($carry20);
        $s20 = $s20->subInt64($carry20->shiftLeft(21));
        $carry22 = $s22->addInt(1 << 20)->shiftRight(21);
        $s23 = $s23->addInt64($carry22);
        $s22 = $s22->subInt64($carry22->shiftLeft(21));

        $carry1 = $s1->addInt(1 << 20)->shiftRight(21);
        $s2 = $s2->addInt64($carry1);
        $s1 = $s1->subInt64($carry1->shiftLeft(21));
        $carry3 = $s3->addInt(1 << 20)->shiftRight(21);
        $s4 = $s4->addInt64($carry3);
        $s3 = $s3->subInt64($carry3->shiftLeft(21));
        $carry5 = $s5->addInt(1 << 20)->shiftRight(21);
        $s6 = $s6->addInt64($carry5);
        $s5 = $s5->subInt64($carry5->shiftLeft(21));
        $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
        $s8 = $s8->addInt64($carry7);
        $s7 = $s7->subInt64($carry7->shiftLeft(21));
        $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
        $s10 = $s10->addInt64($carry9);
        $s9 = $s9->subInt64($carry9->shiftLeft(21));
        $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
        $s12 = $s12->addInt64($carry11);
        $s11 = $s11->subInt64($carry11->shiftLeft(21));
        $carry13 = $s13->addInt(1 << 20)->shiftRight(21);
        $s14 = $s14->addInt64($carry13);
        $s13 = $s13->subInt64($carry13->shiftLeft(21));
        $carry15 = $s15->addInt(1 << 20)->shiftRight(21);
        $s16 = $s16->addInt64($carry15);
        $s15 = $s15->subInt64($carry15->shiftLeft(21));
        $carry17 = $s17->addInt(1 << 20)->shiftRight(21);
        $s18 = $s18->addInt64($carry17);
        $s17 = $s17->subInt64($carry17->shiftLeft(21));
        $carry19 = $s19->addInt(1 << 20)->shiftRight(21);
        $s20 = $s20->addInt64($carry19);
        $s19 = $s19->subInt64($carry19->shiftLeft(21));
        $carry21 = $s21->addInt(1 << 20)->shiftRight(21);
        $s22 = $s22->addInt64($carry21);
        $s21 = $s21->subInt64($carry21->shiftLeft(21));

        $s11 = $s11->addInt64($s23->mulInt(666643, 20));
        $s12 = $s12->addInt64($s23->mulInt(470296, 19));
        $s13 = $s13->addInt64($s23->mulInt(654183, 20));
        $s14 = $s14->subInt64($s23->mulInt(997805, 20));
        $s15 = $s15->addInt64($s23->mulInt(136657, 18));
        $s16 = $s16->subInt64($s23->mulInt(683901, 20));

        $s10 = $s10->addInt64($s22->mulInt(666643, 20));
        $s11 = $s11->addInt64($s22->mulInt(470296, 19));
        $s12 = $s12->addInt64($s22->mulInt(654183, 20));
        $s13 = $s13->subInt64($s22->mulInt(997805, 20));
        $s14 = $s14->addInt64($s22->mulInt(136657, 18));
        $s15 = $s15->subInt64($s22->mulInt(683901, 20));

        $s9  =  $s9->addInt64($s21->mulInt(666643, 20));
        $s10 = $s10->addInt64($s21->mulInt(470296, 19));
        $s11 = $s11->addInt64($s21->mulInt(654183, 20));
        $s12 = $s12->subInt64($s21->mulInt(997805, 20));
        $s13 = $s13->addInt64($s21->mulInt(136657, 18));
        $s14 = $s14->subInt64($s21->mulInt(683901, 20));

        $s8  =  $s8->addInt64($s20->mulInt(666643, 20));
        $s9  =  $s9->addInt64($s20->mulInt(470296, 19));
        $s10 = $s10->addInt64($s20->mulInt(654183, 20));
        $s11 = $s11->subInt64($s20->mulInt(997805, 20));
        $s12 = $s12->addInt64($s20->mulInt(136657, 18));
        $s13 = $s13->subInt64($s20->mulInt(683901, 20));

        $s7  =  $s7->addInt64($s19->mulInt(666643, 20));
        $s8  =  $s8->addInt64($s19->mulInt(470296, 19));
        $s9  =  $s9->addInt64($s19->mulInt(654183, 20));
        $s10 = $s10->subInt64($s19->mulInt(997805, 20));
        $s11 = $s11->addInt64($s19->mulInt(136657, 18));
        $s12 = $s12->subInt64($s19->mulInt(683901, 20));

        $s6  =  $s6->addInt64($s18->mulInt(666643, 20));
        $s7  =  $s7->addInt64($s18->mulInt(470296, 19));
        $s8  =  $s8->addInt64($s18->mulInt(654183, 20));
        $s9  =  $s9->subInt64($s18->mulInt(997805, 20));
        $s10 = $s10->addInt64($s18->mulInt(136657, 18));
        $s11 = $s11->subInt64($s18->mulInt(683901, 20));

        $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
        $s7 = $s7->addInt64($carry6);
        $s6 = $s6->subInt64($carry6->shiftLeft(21));
        $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
        $s9 = $s9->addInt64($carry8);
        $s8 = $s8->subInt64($carry8->shiftLeft(21));
        $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
        $s11 = $s11->addInt64($carry10);
        $s10 = $s10->subInt64($carry10->shiftLeft(21));
        $carry12 = $s12->addInt(1 << 20)->shiftRight(21);
        $s13 = $s13->addInt64($carry12);
        $s12 = $s12->subInt64($carry12->shiftLeft(21));
        $carry14 = $s14->addInt(1 << 20)->shiftRight(21);
        $s15 = $s15->addInt64($carry14);
        $s14 = $s14->subInt64($carry14->shiftLeft(21));
        $carry16 = $s16->addInt(1 << 20)->shiftRight(21);
        $s17 = $s17->addInt64($carry16);
        $s16 = $s16->subInt64($carry16->shiftLeft(21));

        $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
        $s8 = $s8->addInt64($carry7);
        $s7 = $s7->subInt64($carry7->shiftLeft(21));
        $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
        $s10 = $s10->addInt64($carry9);
        $s9 = $s9->subInt64($carry9->shiftLeft(21));
        $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
        $s12 = $s12->addInt64($carry11);
        $s11 = $s11->subInt64($carry11->shiftLeft(21));
        $carry13 = $s13->addInt(1 << 20)->shiftRight(21);
        $s14 = $s14->addInt64($carry13);
        $s13 = $s13->subInt64($carry13->shiftLeft(21));
        $carry15 = $s15->addInt(1 << 20)->shiftRight(21);
        $s16 = $s16->addInt64($carry15);
        $s15 = $s15->subInt64($carry15->shiftLeft(21));

        $s5  =  $s5->addInt64($s17->mulInt(666643, 20));
        $s6  =  $s6->addInt64($s17->mulInt(470296, 19));
        $s7  =  $s7->addInt64($s17->mulInt(654183, 20));
        $s8  =  $s8->subInt64($s17->mulInt(997805, 20));
        $s9  =  $s9->addInt64($s17->mulInt(136657, 18));
        $s10 = $s10->subInt64($s17->mulInt(683901, 20));

        $s4  =  $s4->addInt64($s16->mulInt(666643, 20));
        $s5  =  $s5->addInt64($s16->mulInt(470296, 19));
        $s6  =  $s6->addInt64($s16->mulInt(654183, 20));
        $s7  =  $s7->subInt64($s16->mulInt(997805, 20));
        $s8  =  $s8->addInt64($s16->mulInt(136657, 18));
        $s9  =  $s9->subInt64($s16->mulInt(683901, 20));

        $s3  =  $s3->addInt64($s15->mulInt(666643, 20));
        $s4  =  $s4->addInt64($s15->mulInt(470296, 19));
        $s5  =  $s5->addInt64($s15->mulInt(654183, 20));
        $s6  =  $s6->subInt64($s15->mulInt(997805, 20));
        $s7  =  $s7->addInt64($s15->mulInt(136657, 18));
        $s8  =  $s8->subInt64($s15->mulInt(683901, 20));

        $s2  =  $s2->addInt64($s14->mulInt(666643, 20));
        $s3  =  $s3->addInt64($s14->mulInt(470296, 19));
        $s4  =  $s4->addInt64($s14->mulInt(654183, 20));
        $s5  =  $s5->subInt64($s14->mulInt(997805, 20));
        $s6  =  $s6->addInt64($s14->mulInt(136657, 18));
        $s7  =  $s7->subInt64($s14->mulInt(683901, 20));

        $s1  =  $s1->addInt64($s13->mulInt(666643, 20));
        $s2  =  $s2->addInt64($s13->mulInt(470296, 19));
        $s3  =  $s3->addInt64($s13->mulInt(654183, 20));
        $s4  =  $s4->subInt64($s13->mulInt(997805, 20));
        $s5  =  $s5->addInt64($s13->mulInt(136657, 18));
        $s6  =  $s6->subInt64($s13->mulInt(683901, 20));

        $s0  =  $s0->addInt64($s12->mulInt(666643, 20));
        $s1  =  $s1->addInt64($s12->mulInt(470296, 19));
        $s2  =  $s2->addInt64($s12->mulInt(654183, 20));
        $s3  =  $s3->subInt64($s12->mulInt(997805, 20));
        $s4  =  $s4->addInt64($s12->mulInt(136657, 18));
        $s5  =  $s5->subInt64($s12->mulInt(683901, 20));
        $s12 = new ParagonIE_Sodium_Core32_Int64();

        $carry0 = $s0->addInt(1 << 20)->shiftRight(21);
        $s1 = $s1->addInt64($carry0);
        $s0 = $s0->subInt64($carry0->shiftLeft(21));
        $carry2 = $s2->addInt(1 << 20)->shiftRight(21);
        $s3 = $s3->addInt64($carry2);
        $s2 = $s2->subInt64($carry2->shiftLeft(21));
        $carry4 = $s4->addInt(1 << 20)->shiftRight(21);
        $s5 = $s5->addInt64($carry4);
        $s4 = $s4->subInt64($carry4->shiftLeft(21));
        $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
        $s7 = $s7->addInt64($carry6);
        $s6 = $s6->subInt64($carry6->shiftLeft(21));
        $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
        $s9 = $s9->addInt64($carry8);
        $s8 = $s8->subInt64($carry8->shiftLeft(21));
        $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
        $s11 = $s11->addInt64($carry10);
        $s10 = $s10->subInt64($carry10->shiftLeft(21));

        $carry1 = $s1->addInt(1 << 20)->shiftRight(21);
        $s2 = $s2->addInt64($carry1);
        $s1 = $s1->subInt64($carry1->shiftLeft(21));
        $carry3 = $s3->addInt(1 << 20)->shiftRight(21);
        $s4 = $s4->addInt64($carry3);
        $s3 = $s3->subInt64($carry3->shiftLeft(21));
        $carry5 = $s5->addInt(1 << 20)->shiftRight(21);
        $s6 = $s6->addInt64($carry5);
        $s5 = $s5->subInt64($carry5->shiftLeft(21));
        $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
        $s8 = $s8->addInt64($carry7);
        $s7 = $s7->subInt64($carry7->shiftLeft(21));
        $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
        $s10 = $s10->addInt64($carry9);
        $s9 = $s9->subInt64($carry9->shiftLeft(21));
        $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
        $s12 = $s12->addInt64($carry11);
        $s11 = $s11->subInt64($carry11->shiftLeft(21));

        $s0  =  $s0->addInt64($s12->mulInt(666643, 20));
        $s1  =  $s1->addInt64($s12->mulInt(470296, 19));
        $s2  =  $s2->addInt64($s12->mulInt(654183, 20));
        $s3  =  $s3->subInt64($s12->mulInt(997805, 20));
        $s4  =  $s4->addInt64($s12->mulInt(136657, 18));
        $s5  =  $s5->subInt64($s12->mulInt(683901, 20));
        $s12 = new ParagonIE_Sodium_Core32_Int64();

        $carry0 = $s0->shiftRight(21);
        $s1 = $s1->addInt64($carry0);
        $s0 = $s0->subInt64($carry0->shiftLeft(21));
        $carry1 = $s1->shiftRight(21);
        $s2 = $s2->addInt64($carry1);
        $s1 = $s1->subInt64($carry1->shiftLeft(21));
        $carry2 = $s2->shiftRight(21);
        $s3 = $s3->addInt64($carry2);
        $s2 = $s2->subInt64($carry2->shiftLeft(21));
        $carry3 = $s3->shiftRight(21);
        $s4 = $s4->addInt64($carry3);
        $s3 = $s3->subInt64($carry3->shiftLeft(21));
        $carry4 = $s4->shiftRight(21);
        $s5 = $s5->addInt64($carry4);
        $s4 = $s4->subInt64($carry4->shiftLeft(21));
        $carry5 = $s5->shiftRight(21);
        $s6 = $s6->addInt64($carry5);
        $s5 = $s5->subInt64($carry5->shiftLeft(21));
        $carry6 = $s6->shiftRight(21);
        $s7 = $s7->addInt64($carry6);
        $s6 = $s6->subInt64($carry6->shiftLeft(21));
        $carry7 = $s7->shiftRight(21);
        $s8 = $s8->addInt64($carry7);
        $s7 = $s7->subInt64($carry7->shiftLeft(21));
        $carry8 = $s8->shiftRight(21);
        $s9 = $s9->addInt64($carry8);
        $s8 = $s8->subInt64($carry8->shiftLeft(21));
        $carry9 = $s9->shiftRight(21);
        $s10 = $s10->addInt64($carry9);
        $s9 = $s9->subInt64($carry9->shiftLeft(21));
        $carry10 = $s10->shiftRight(21);
        $s11 = $s11->addInt64($carry10);
        $s10 = $s10->subInt64($carry10->shiftLeft(21));
        $carry11 = $s11->shiftRight(21);
        $s12 = $s12->addInt64($carry11);
        $s11 = $s11->subInt64($carry11->shiftLeft(21));

        $s0  =  $s0->addInt64($s12->mulInt(666643, 20));
        $s1  =  $s1->addInt64($s12->mulInt(470296, 19));
        $s2  =  $s2->addInt64($s12->mulInt(654183, 20));
        $s3  =  $s3->subInt64($s12->mulInt(997805, 20));
        $s4  =  $s4->addInt64($s12->mulInt(136657, 18));
        $s5  =  $s5->subInt64($s12->mulInt(683901, 20));

        $carry0 = $s0->shiftRight(21);
        $s1 = $s1->addInt64($carry0);
        $s0 = $s0->subInt64($carry0->shiftLeft(21));
        $carry1 = $s1->shiftRight(21);
        $s2 = $s2->addInt64($carry1);
        $s1 = $s1->subInt64($carry1->shiftLeft(21));
        $carry2 = $s2->shiftRight(21);
        $s3 = $s3->addInt64($carry2);
        $s2 = $s2->subInt64($carry2->shiftLeft(21));
        $carry3 = $s3->shiftRight(21);
        $s4 = $s4->addInt64($carry3);
        $s3 = $s3->subInt64($carry3->shiftLeft(21));
        $carry4 = $s4->shiftRight(21);
        $s5 = $s5->addInt64($carry4);
        $s4 = $s4->subInt64($carry4->shiftLeft(21));
        $carry5 = $s5->shiftRight(21);
        $s6 = $s6->addInt64($carry5);
        $s5 = $s5->subInt64($carry5->shiftLeft(21));
        $carry6 = $s6->shiftRight(21);
        $s7 = $s7->addInt64($carry6);
        $s6 = $s6->subInt64($carry6->shiftLeft(21));
        $carry7 = $s7->shiftRight(21);
        $s8 = $s8->addInt64($carry7);
        $s7 = $s7->subInt64($carry7->shiftLeft(21));
        $carry8 = $s10->shiftRight(21);
        $s9 = $s9->addInt64($carry8);
        $s8 = $s8->subInt64($carry8->shiftLeft(21));
        $carry9 = $s9->shiftRight(21);
        $s10 = $s10->addInt64($carry9);
        $s9 = $s9->subInt64($carry9->shiftLeft(21));
        $carry10 = $s10->shiftRight(21);
        $s11 = $s11->addInt64($carry10);
        $s10 = $s10->subInt64($carry10->shiftLeft(21));

        $S0  =  $s0->toInt();
        $S1  =  $s1->toInt();
        $S2  =  $s2->toInt();
        $S3  =  $s3->toInt();
        $S4  =  $s4->toInt();
        $S5  =  $s5->toInt();
        $S6  =  $s6->toInt();
        $S7  =  $s7->toInt();
        $S8  =  $s8->toInt();
        $S9  =  $s9->toInt();
        $S10 = $s10->toInt();
        $S11 = $s11->toInt();

        /**
         * @var array<int, int>
         */
        $arr = array(
            (int) (0xff & ($S0 >> 0)),
            (int) (0xff & ($S0 >> 8)),
            (int) (0xff & (($S0 >> 16) | ($S1 << 5))),
            (int) (0xff & ($S1 >> 3)),
            (int) (0xff & ($S1 >> 11)),
            (int) (0xff & (($S1 >> 19) | ($S2 << 2))),
            (int) (0xff & ($S2 >> 6)),
            (int) (0xff & (($S2 >> 14) | ($S3 << 7))),
            (int) (0xff & ($S3 >> 1)),
            (int) (0xff & ($S3 >> 9)),
            (int) (0xff & (($S3 >> 17) | ($S4 << 4))),
            (int) (0xff & ($S4 >> 4)),
            (int) (0xff & ($S4 >> 12)),
            (int) (0xff & (($S4 >> 20) | ($S5 << 1))),
            (int) (0xff & ($S5 >> 7)),
            (int) (0xff & (($S5 >> 15) | ($S6 << 6))),
            (int) (0xff & ($S6 >> 2)),
            (int) (0xff & ($S6 >> 10)),
            (int) (0xff & (($S6 >> 18) | ($S7 << 3))),
            (int) (0xff & ($S7 >> 5)),
            (int) (0xff & ($S7 >> 13)),
            (int) (0xff & ($S8 >> 0)),
            (int) (0xff & ($S8 >> 8)),
            (int) (0xff & (($S8 >> 16) | ($S9 << 5))),
            (int) (0xff & ($S9 >> 3)),
            (int) (0xff & ($S9 >> 11)),
            (int) (0xff & (($S9 >> 19) | ($S10 << 2))),
            (int) (0xff & ($S10 >> 6)),
            (int) (0xff & (($S10 >> 14) | ($S11 << 7))),
            (int) (0xff & ($S11 >> 1)),
            (int) (0xff & ($S11 >> 9)),
            (int) (0xff & ($S11 >> 17))
        );
        return self::intArrayToString($arr);
    }

    /**
     * @internal You should not use this directly from another application
     *
     * @param string $s
     * @return string
     * @throws SodiumException
     * @throws TypeError
     */
    public static function sc_reduce($s)
    {
        /**
         * @var ParagonIE_Sodium_Core32_Int64 $s0
         * @var ParagonIE_Sodium_Core32_Int64 $s1
         * @var ParagonIE_Sodium_Core32_Int64 $s2
         * @var ParagonIE_Sodium_Core32_Int64 $s3
         * @var ParagonIE_Sodium_Core32_Int64 $s4
         * @var ParagonIE_Sodium_Core32_Int64 $s5
         * @var ParagonIE_Sodium_Core32_Int64 $s6
         * @var ParagonIE_Sodium_Core32_Int64 $s7
         * @var ParagonIE_Sodium_Core32_Int64 $s8
         * @var ParagonIE_Sodium_Core32_Int64 $s9
         * @var ParagonIE_Sodium_Core32_Int64 $s10
         * @var ParagonIE_Sodium_Core32_Int64 $s11
         * @var ParagonIE_Sodium_Core32_Int64 $s12
         * @var ParagonIE_Sodium_Core32_Int64 $s13
         * @var ParagonIE_Sodium_Core32_Int64 $s14
         * @var ParagonIE_Sodium_Core32_Int64 $s15
         * @var ParagonIE_Sodium_Core32_Int64 $s16
         * @var ParagonIE_Sodium_Core32_Int64 $s17
         * @var ParagonIE_Sodium_Core32_Int64 $s18
         * @var ParagonIE_Sodium_Core32_Int64 $s19
         * @var ParagonIE_Sodium_Core32_Int64 $s20
         * @var ParagonIE_Sodium_Core32_Int64 $s21
         * @var ParagonIE_Sodium_Core32_Int64 $s22
         * @var ParagonIE_Sodium_Core32_Int64 $s23
         */
        $s0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 0, 3)));
        $s1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 2, 4)) >> 5));
        $s2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 5, 3)) >> 2));
        $s3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 7, 4)) >> 7));
        $s4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 10, 4)) >> 4));
        $s5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 13, 3)) >> 1));
        $s6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 15, 4)) >> 6));
        $s7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 18, 4)) >> 3));
        $s8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 21, 3)));
        $s9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 23, 4)) >> 5));
        $s10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 26, 3)) >> 2));
        $s11 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 28, 4)) >> 7));
        $s12 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 31, 4)) >> 4));
        $s13 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 34, 3)) >> 1));
        $s14 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 36, 4)) >> 6));
        $s15 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 39, 4)) >> 3));
        $s16 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 42, 3)));
        $s17 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 44, 4)) >> 5));
        $s18 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 47, 3)) >> 2));
        $s19 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 49, 4)) >> 7));
        $s20 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 52, 4)) >> 4));
        $s21 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 55, 3)) >> 1));
        $s22 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 57, 4)) >> 6));
        $s23 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($s, 60, 4)) >> 3));

        $s11 = $s11->addInt64($s23->mulInt(666643, 20));
        $s12 = $s12->addInt64($s23->mulInt(470296, 19));
        $s13 = $s13->addInt64($s23->mulInt(654183, 20));
        $s14 = $s14->subInt64($s23->mulInt(997805, 20));
        $s15 = $s15->addInt64($s23->mulInt(136657, 18));
        $s16 = $s16->subInt64($s23->mulInt(683901, 20));

        $s10 = $s10->addInt64($s22->mulInt(666643, 20));
        $s11 = $s11->addInt64($s22->mulInt(470296, 19));
        $s12 = $s12->addInt64($s22->mulInt(654183, 20));
        $s13 = $s13->subInt64($s22->mulInt(997805, 20));
        $s14 = $s14->addInt64($s22->mulInt(136657, 18));
        $s15 = $s15->subInt64($s22->mulInt(683901, 20));

        $s9  =  $s9->addInt64($s21->mulInt(666643, 20));
        $s10 = $s10->addInt64($s21->mulInt(470296, 19));
        $s11 = $s11->addInt64($s21->mulInt(654183, 20));
        $s12 = $s12->subInt64($s21->mulInt(997805, 20));
        $s13 = $s13->addInt64($s21->mulInt(136657, 18));
        $s14 = $s14->subInt64($s21->mulInt(683901, 20));

        $s8  =  $s8->addInt64($s20->mulInt(666643, 20));
        $s9  =  $s9->addInt64($s20->mulInt(470296, 19));
        $s10 = $s10->addInt64($s20->mulInt(654183, 20));
        $s11 = $s11->subInt64($s20->mulInt(997805, 20));
        $s12 = $s12->addInt64($s20->mulInt(136657, 18));
        $s13 = $s13->subInt64($s20->mulInt(683901, 20));

        $s7  =  $s7->addInt64($s19->mulInt(666643, 20));
        $s8  =  $s8->addInt64($s19->mulInt(470296, 19));
        $s9  =  $s9->addInt64($s19->mulInt(654183, 20));
        $s10 = $s10->subInt64($s19->mulInt(997805, 20));
        $s11 = $s11->addInt64($s19->mulInt(136657, 18));
        $s12 = $s12->subInt64($s19->mulInt(683901, 20));

        $s6  =  $s6->addInt64($s18->mulInt(666643, 20));
        $s7  =  $s7->addInt64($s18->mulInt(470296, 19));
        $s8  =  $s8->addInt64($s18->mulInt(654183, 20));
        $s9  =  $s9->subInt64($s18->mulInt(997805, 20));
        $s10 = $s10->addInt64($s18->mulInt(136657, 18));
        $s11 = $s11->subInt64($s18->mulInt(683901, 20));

        $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
        $s7 = $s7->addInt64($carry6);
        $s6 = $s6->subInt64($carry6->shiftLeft(21));
        $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
        $s9 = $s9->addInt64($carry8);
        $s8 = $s8->subInt64($carry8->shiftLeft(21));
        $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
        $s11 = $s11->addInt64($carry10);
        $s10 = $s10->subInt64($carry10->shiftLeft(21));
        $carry12 = $s12->addInt(1 << 20)->shiftRight(21);
        $s13 = $s13->addInt64($carry12);
        $s12 = $s12->subInt64($carry12->shiftLeft(21));
        $carry14 = $s14->addInt(1 << 20)->shiftRight(21);
        $s15 = $s15->addInt64($carry14);
        $s14 = $s14->subInt64($carry14->shiftLeft(21));
        $carry16 = $s16->addInt(1 << 20)->shiftRight(21);
        $s17 = $s17->addInt64($carry16);
        $s16 = $s16->subInt64($carry16->shiftLeft(21));

        $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
        $s8 = $s8->addInt64($carry7);
        $s7 = $s7->subInt64($carry7->shiftLeft(21));
        $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
        $s10 = $s10->addInt64($carry9);
        $s9 = $s9->subInt64($carry9->shiftLeft(21));
        $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
        $s12 = $s12->addInt64($carry11);
        $s11 = $s11->subInt64($carry11->shiftLeft(21));
        $carry13 = $s13->addInt(1 << 20)->shiftRight(21);
        $s14 = $s14->addInt64($carry13);
        $s13 = $s13->subInt64($carry13->shiftLeft(21));
        $carry15 = $s15->addInt(1 << 20)->shiftRight(21);
        $s16 = $s16->addInt64($carry15);
        $s15 = $s15->subInt64($carry15->shiftLeft(21));

        $s5  =  $s5->addInt64($s17->mulInt(666643, 20));
        $s6  =  $s6->addInt64($s17->mulInt(470296, 19));
        $s7  =  $s7->addInt64($s17->mulInt(654183, 20));
        $s8  =  $s8->subInt64($s17->mulInt(997805, 20));
        $s9  =  $s9->addInt64($s17->mulInt(136657, 18));
        $s10 = $s10->subInt64($s17->mulInt(683901, 20));

        $s4  =  $s4->addInt64($s16->mulInt(666643, 20));
        $s5  =  $s5->addInt64($s16->mulInt(470296, 19));
        $s6  =  $s6->addInt64($s16->mulInt(654183, 20));
        $s7  =  $s7->subInt64($s16->mulInt(997805, 20));
        $s8  =  $s8->addInt64($s16->mulInt(136657, 18));
        $s9  =  $s9->subInt64($s16->mulInt(683901, 20));

        $s3  =  $s3->addInt64($s15->mulInt(666643, 20));
        $s4  =  $s4->addInt64($s15->mulInt(470296, 19));
        $s5  =  $s5->addInt64($s15->mulInt(654183, 20));
        $s6  =  $s6->subInt64($s15->mulInt(997805, 20));
        $s7  =  $s7->addInt64($s15->mulInt(136657, 18));
        $s8  =  $s8->subInt64($s15->mulInt(683901, 20));

        $s2  =  $s2->addInt64($s14->mulInt(666643, 20));
        $s3  =  $s3->addInt64($s14->mulInt(470296, 19));
        $s4  =  $s4->addInt64($s14->mulInt(654183, 20));
        $s5  =  $s5->subInt64($s14->mulInt(997805, 20));
        $s6  =  $s6->addInt64($s14->mulInt(136657, 18));
        $s7  =  $s7->subInt64($s14->mulInt(683901, 20));

        $s1  =  $s1->addInt64($s13->mulInt(666643, 20));
        $s2  =  $s2->addInt64($s13->mulInt(470296, 19));
        $s3  =  $s3->addInt64($s13->mulInt(654183, 20));
        $s4  =  $s4->subInt64($s13->mulInt(997805, 20));
        $s5  =  $s5->addInt64($s13->mulInt(136657, 18));
        $s6  =  $s6->subInt64($s13->mulInt(683901, 20));

        $s0  =  $s0->addInt64($s12->mulInt(666643, 20));
        $s1  =  $s1->addInt64($s12->mulInt(470296, 19));
        $s2  =  $s2->addInt64($s12->mulInt(654183, 20));
        $s3  =  $s3->subInt64($s12->mulInt(997805, 20));
        $s4  =  $s4->addInt64($s12->mulInt(136657, 18));
        $s5  =  $s5->subInt64($s12->mulInt(683901, 20));
        $s12 = new ParagonIE_Sodium_Core32_Int64();

        $carry0 = $s0->addInt(1 << 20)->shiftRight(21);
        $s1 = $s1->addInt64($carry0);
        $s0 = $s0->subInt64($carry0->shiftLeft(21));
        $carry2 = $s2->addInt(1 << 20)->shiftRight(21);
        $s3 = $s3->addInt64($carry2);
        $s2 = $s2->subInt64($carry2->shiftLeft(21));
        $carry4 = $s4->addInt(1 << 20)->shiftRight(21);
        $s5 = $s5->addInt64($carry4);
        $s4 = $s4->subInt64($carry4->shiftLeft(21));
        $carry6 = $s6->addInt(1 << 20)->shiftRight(21);
        $s7 = $s7->addInt64($carry6);
        $s6 = $s6->subInt64($carry6->shiftLeft(21));
        $carry8 = $s8->addInt(1 << 20)->shiftRight(21);
        $s9 = $s9->addInt64($carry8);
        $s8 = $s8->subInt64($carry8->shiftLeft(21));
        $carry10 = $s10->addInt(1 << 20)->shiftRight(21);
        $s11 = $s11->addInt64($carry10);
        $s10 = $s10->subInt64($carry10->shiftLeft(21));
        $carry1 = $s1->addInt(1 << 20)->shiftRight(21);
        $s2 = $s2->addInt64($carry1);
        $s1 = $s1->subInt64($carry1->shiftLeft(21));
        $carry3 = $s3->addInt(1 << 20)->shiftRight(21);
        $s4 = $s4->addInt64($carry3);
        $s3 = $s3->subInt64($carry3->shiftLeft(21));
        $carry5 = $s5->addInt(1 << 20)->shiftRight(21);
        $s6 = $s6->addInt64($carry5);
        $s5 = $s5->subInt64($carry5->shiftLeft(21));
        $carry7 = $s7->addInt(1 << 20)->shiftRight(21);
        $s8 = $s8->addInt64($carry7);
        $s7 = $s7->subInt64($carry7->shiftLeft(21));
        $carry9 = $s9->addInt(1 << 20)->shiftRight(21);
        $s10 = $s10->addInt64($carry9);
        $s9 = $s9->subInt64($carry9->shiftLeft(21));
        $carry11 = $s11->addInt(1 << 20)->shiftRight(21);
        $s12 = $s12->addInt64($carry11);
        $s11 = $s11->subInt64($carry11->shiftLeft(21));

        $s0  =  $s0->addInt64($s12->mulInt(666643, 20));
        $s1  =  $s1->addInt64($s12->mulInt(470296, 19));
        $s2  =  $s2->addInt64($s12->mulInt(654183, 20));
        $s3  =  $s3->subInt64($s12->mulInt(997805, 20));
        $s4  =  $s4->addInt64($s12->mulInt(136657, 18));
        $s5  =  $s5->subInt64($s12->mulInt(683901, 20));
        $s12 = new ParagonIE_Sodium_Core32_Int64();

        $carry0 = $s0->shiftRight(21);
        $s1 = $s1->addInt64($carry0);
        $s0 = $s0->subInt64($carry0->shiftLeft(21));
        $carry1 = $s1->shiftRight(21);
        $s2 = $s2->addInt64($carry1);
        $s1 = $s1->subInt64($carry1->shiftLeft(21));
        $carry2 = $s2->shiftRight(21);
        $s3 = $s3->addInt64($carry2);
        $s2 = $s2->subInt64($carry2->shiftLeft(21));
        $carry3 = $s3->shiftRight(21);
        $s4 = $s4->addInt64($carry3);
        $s3 = $s3->subInt64($carry3->shiftLeft(21));
        $carry4 = $s4->shiftRight(21);
        $s5 = $s5->addInt64($carry4);
        $s4 = $s4->subInt64($carry4->shiftLeft(21));
        $carry5 = $s5->shiftRight(21);
        $s6 = $s6->addInt64($carry5);
        $s5 = $s5->subInt64($carry5->shiftLeft(21));
        $carry6 = $s6->shiftRight(21);
        $s7 = $s7->addInt64($carry6);
        $s6 = $s6->subInt64($carry6->shiftLeft(21));
        $carry7 = $s7->shiftRight(21);
        $s8 = $s8->addInt64($carry7);
        $s7 = $s7->subInt64($carry7->shiftLeft(21));
        $carry8 = $s8->shiftRight(21);
        $s9 = $s9->addInt64($carry8);
        $s8 = $s8->subInt64($carry8->shiftLeft(21));
        $carry9 = $s9->shiftRight(21);
        $s10 = $s10->addInt64($carry9);
        $s9 = $s9->subInt64($carry9->shiftLeft(21));
        $carry10 = $s10->shiftRight(21);
        $s11 = $s11->addInt64($carry10);
        $s10 = $s10->subInt64($carry10->shiftLeft(21));
        $carry11 = $s11->shiftRight(21);
        $s12 = $s12->addInt64($carry11);
        $s11 = $s11->subInt64($carry11->shiftLeft(21));

        $s0  =  $s0->addInt64($s12->mulInt(666643, 20));
        $s1  =  $s1->addInt64($s12->mulInt(470296, 19));
        $s2  =  $s2->addInt64($s12->mulInt(654183, 20));
        $s3  =  $s3->subInt64($s12->mulInt(997805, 20));
        $s4  =  $s4->addInt64($s12->mulInt(136657, 18));
        $s5  =  $s5->subInt64($s12->mulInt(683901, 20));

        $carry0 = $s0->shiftRight(21);
        $s1 = $s1->addInt64($carry0);
        $s0 = $s0->subInt64($carry0->shiftLeft(21));
        $carry1 = $s1->shiftRight(21);
        $s2 = $s2->addInt64($carry1);
        $s1 = $s1->subInt64($carry1->shiftLeft(21));
        $carry2 = $s2->shiftRight(21);
        $s3 = $s3->addInt64($carry2);
        $s2 = $s2->subInt64($carry2->shiftLeft(21));
        $carry3 = $s3->shiftRight(21);
        $s4 = $s4->addInt64($carry3);
        $s3 = $s3->subInt64($carry3->shiftLeft(21));
        $carry4 = $s4->shiftRight(21);
        $s5 = $s5->addInt64($carry4);
        $s4 = $s4->subInt64($carry4->shiftLeft(21));
        $carry5 = $s5->shiftRight(21);
        $s6 = $s6->addInt64($carry5);
        $s5 = $s5->subInt64($carry5->shiftLeft(21));
        $carry6 = $s6->shiftRight(21);
        $s7 = $s7->addInt64($carry6);
        $s6 = $s6->subInt64($carry6->shiftLeft(21));
        $carry7 = $s7->shiftRight(21);
        $s8 = $s8->addInt64($carry7);
        $s7 = $s7->subInt64($carry7->shiftLeft(21));
        $carry8 = $s8->shiftRight(21);
        $s9 = $s9->addInt64($carry8);
        $s8 = $s8->subInt64($carry8->shiftLeft(21));
        $carry9 = $s9->shiftRight(21);
        $s10 = $s10->addInt64($carry9);
        $s9 = $s9->subInt64($carry9->shiftLeft(21));
        $carry10 = $s10->shiftRight(21);
        $s11 = $s11->addInt64($carry10);
        $s10 = $s10->subInt64($carry10->shiftLeft(21));

        $S0 = $s0->toInt32()->toInt();
        $S1 = $s1->toInt32()->toInt();
        $S2 = $s2->toInt32()->toInt();
        $S3 = $s3->toInt32()->toInt();
        $S4 = $s4->toInt32()->toInt();
        $S5 = $s5->toInt32()->toInt();
        $S6 = $s6->toInt32()->toInt();
        $S7 = $s7->toInt32()->toInt();
        $S8 = $s8->toInt32()->toInt();
        $S9 = $s9->toInt32()->toInt();
        $S10 = $s10->toInt32()->toInt();
        $S11 = $s11->toInt32()->toInt();

        /**
         * @var array<int, int>
         */
        $arr = array(
            (int) ($S0 >> 0),
            (int) ($S0 >> 8),
            (int) (($S0 >> 16) | ($S1 << 5)),
            (int) ($S1 >> 3),
            (int) ($S1 >> 11),
            (int) (($S1 >> 19) | ($S2 << 2)),
            (int) ($S2 >> 6),
            (int) (($S2 >> 14) | ($S3 << 7)),
            (int) ($S3 >> 1),
            (int) ($S3 >> 9),
            (int) (($S3 >> 17) | ($S4 << 4)),
            (int) ($S4 >> 4),
            (int) ($S4 >> 12),
            (int) (($S4 >> 20) | ($S5 << 1)),
            (int) ($S5 >> 7),
            (int) (($S5 >> 15) | ($S6 << 6)),
            (int) ($S6 >> 2),
            (int) ($S6 >> 10),
            (int) (($S6 >> 18) | ($S7 << 3)),
            (int) ($S7 >> 5),
            (int) ($S7 >> 13),
            (int) ($S8 >> 0),
            (int) ($S8 >> 8),
            (int) (($S8 >> 16) | ($S9 << 5)),
            (int) ($S9 >> 3),
            (int) ($S9 >> 11),
            (int) (($S9 >> 19) | ($S10 << 2)),
            (int) ($S10 >> 6),
            (int) (($S10 >> 14) | ($S11 << 7)),
            (int) ($S11 >> 1),
            (int) ($S11 >> 9),
            (int) $S11 >> 17
        );
        return self::intArrayToString($arr);
    }

    /**
     * multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493
     *
     * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A
     * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3
     * @throws SodiumException
     * @throws TypeError
     */
    public static function ge_mul_l(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A)
    {
        $aslide = array(
            13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0,
            0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0,
            0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0,
            0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1,
            0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0,
            0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
        );

        /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai size 8 */
        $Ai = array();

        # ge_p3_to_cached(&Ai[0], A);
        $Ai[0] = self::ge_p3_to_cached($A);
        # ge_p3_dbl(&t, A);
        $t = self::ge_p3_dbl($A);
        # ge_p1p1_to_p3(&A2, &t);
        $A2 = self::ge_p1p1_to_p3($t);

        for ($i = 1; $i < 8; ++$i) {
            # ge_add(&t, &A2, &Ai[0]);
            $t = self::ge_add($A2, $Ai[$i - 1]);
            # ge_p1p1_to_p3(&u, &t);
            $u = self::ge_p1p1_to_p3($t);
            # ge_p3_to_cached(&Ai[i], &u);
            $Ai[$i] = self::ge_p3_to_cached($u);
        }

        $r = self::ge_p3_0();
        for ($i = 252; $i >= 0; --$i) {
            $t = self::ge_p3_dbl($r);
            if ($aslide[$i] > 0) {
                # ge_p1p1_to_p3(&u, &t);
                $u = self::ge_p1p1_to_p3($t);
                # ge_add(&t, &u, &Ai[aslide[i] / 2]);
                $t = self::ge_add($u, $Ai[(int)($aslide[$i] / 2)]);
            } elseif ($aslide[$i] < 0) {
                # ge_p1p1_to_p3(&u, &t);
                $u = self::ge_p1p1_to_p3($t);
                # ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
                $t = self::ge_sub($u, $Ai[(int)(-$aslide[$i] / 2)]);
            }
        }
        # ge_p1p1_to_p3(r, &t);
        return self::ge_p1p1_to_p3($t);
    }
}
الذكاء الاصطناعي وتعليم ذوي الهمم: جامعة القاهرة تفتح النقاش – tahkoom.com
معرفة

الذكاء الاصطناعي وتعليم ذوي الهمم: جامعة القاهرة تفتح النقاش

‏كتبت شروق عارف                                                                                                                           
في ظل التقدم السريع في تقنيات الذكاء الاصطناعي وتوسعها في مختلف المجالات مثل التعليم والمحاماة والرعاية الصحية والإعلام نظمت جامعة القاهرة مؤتمر بعنوان أفاق الذي يهدف إلى دمج تقنية الذكاء الاصطناعي في تعليم ذوي الاحتياجات الخاصة وفي هذا السياق ظهرت عدة تساؤلات مهمة هل يمكن الاعتماد على الذكاء الاصطناعي في تعليم وتأهيل الأطفال ذوي الاحتياجات الخاصة؟ أم أنه مجرد أداة مساعدة بجانب المتخصصين والمعلمين

تصنيف ذوي الاحتياجات مهم للإستخدام الذكاء الاصطناعي

من جانبها أوضحت الدكتورة رشا أحمد أخصائية التخاطب والعلاج النفسي والسلوكي على ضرورة تصنيف فئة ذوي الاحتياجات الخاصة عند توظيف تقنيات الذكاء الاصطناعي وأشارت إلى أن بعض الحالات خاصة من يعانون من إعاقات شديدة مقترنة بتأخر لغوي أو اضطرابات نفسية قد لا يتمكنون من الاستفادة الكاملة من هذه البرامج

الذكاء الاصطناعي لا يغني عن الاخصائي

من جانبه أوضحت منه كرم الأخصائي النفسية على أهمية وجود إشراف نفسي دائم عند استخدام تقنيات الذكاء الاصطناعي مع الأطفال من ذوي الاحتياجات الخاصة وذلك لما يواجهه هؤلاء الأطفال من صعوبات نفسية وسلوكية تستلزم متابعة دقيقة من متخصصين كما أوضحت أن الذكاء الاصطناعي غير مؤهل للتعامل مع الاضطرابات النفسية العميقة التي تحتاج إلى تدخل الأخصائي بشكل مباشر وشددت على أن هذه لتقنيات لا تعتبر بديل عن الرعاية النفسية أو العلاج السلوكي بل ينبغي أن تكون وسيلة مساعدة تدعم عمل الأخصائيين النفسيين دون أن تحل محلها

تدخل الاخصائي أساسي في تأهيل الأطفال ذوي الاحتياجات الخاص                                            
أوضحت الدكتورة إيناس الشيخ الأخصائية النفسية واستشاري أمراض التخاطب أن الذكاء الاصطناعي يمكنه المساعدة في إعداد البرامج ووضع استراتيجيات لتحقيق أهدافها لكنه لا يستطيع تنفيذ هذه الاستراتيجيات بنفسه فالتدخل البشري بظل عنصر أساسيا وخاصة عند التعامل مع الأطفال من ذوي الاحتياجات الخاصة وأضافت: الطفل في هذه الحالة يحتاج إلى من يشعر به ويتعاطف معه ويحسن التعامل معه دون الإخلال بمصلحته لذلك لا بد من وجود شخص متخصص يعرف كيف يدير حالة الطفل ويساعده في التأهيل بشكل صحيح
وتابعت حديثها قائلة ترك الطفل لفترات طويلة أمام الشاشات أو الهاتف المحمول له نفس خطورة الاعتماد الكامل على الذكاء الاصطناعي لأن الطفل يكون حينها في وضع المستقبل فقط دون تفاعل حقيقي. بينما التفاعل البشري المباشر يُعزز من فرص التواصل الاجتماعي وتنمية المهارات وفيما يخص حالات القلق المفرط عند الأطفال
كما أوضحت الدكتورة إيناس أن الذكاء الاصطناعي قد يساعد في وضع خطة علاجية وتنفيذ فيديوهات للتعرض التدريجي للمخاوف لكنه لا يمكنه تنفيذ الخطة على أرض الواقع فالتواصل الإنساني يظل ضروري خاصة في مثل هذه الحالات الحساسة
و أشارت إلى أن بعض برامج النطق المدعومة بالذكاء الاصطناعي قد تكون مفيدة في أداء بعض التمارين خاصة للأطفال من ذوي الاحتياجات الخاصة لكن من المهم أن ندرك أن كل طفل له احتياجاته وظروفه الخاصة وهذه التفاصيل لا يستطيع لذكاء الاصطناعي التعامل معها بدقة دائما
كما ان الاعتماد الكامل على الذكاء الاصطناعي في تأهيل الأطفال ذوي لاحتياجات الخاصة يحمل العديد من المخاطر لذا يجب أن يكون هناك دور فعال للأخصائي لفهم الحالة وتوجيهها بالشكل المناسب

يبقى الذكاء الاصطناعي أداة مساعدة وفعالة في تحسين تعليم وتأهيل الأطفال ذوي الاحتياجات الخاصة ولكن بشرط أن يستخدم كأداة مساعدة وليس كبديل للأخصائيين

اظهر المزيد

مقالات ذات صلة

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

زر الذهاب إلى الأعلى