!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache. PHP/8.1.30 

uname -a: Linux server1.tuhinhossain.com 5.15.0-151-generic #161-Ubuntu SMP Tue Jul 22 14:25:40 UTC
2025 x86_64
 

uid=1002(picotech) gid=1003(picotech) groups=1003(picotech),0(root)  

Safe-mode: OFF (not secure)

/home/picotech/public_html/phpmyadmin/vendor/paragonie/sodium_compat/src/Core/   drwxr-xr-x
Free 28.43 GB of 117.98 GB (24.1%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     Curve25519.php (139.29 KB)      -rwxr-x---
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php

if (class_exists('ParagonIE_Sodium_Core_Curve25519'false)) {
    return;
}

/**
 * Class ParagonIE_Sodium_Core_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_Core_Curve25519 extends ParagonIE_Sodium_Core_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_Core_Curve25519_Fe
     */
    
public static function fe_0()
    {
        return 
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
            array(
0000000000)
        );
    }

    
/**
     * 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_Core_Curve25519_Fe
     */
    
public static function fe_1()
    {
        return 
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
            array(
1000000000)
        );
    }

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

    
/**
     * Constant-time conditional move.
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $g
     * @param int $b
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     * @psalm-suppress MixedAssignment
     */
    
public static function fe_cmov(
        
ParagonIE_Sodium_Core_Curve25519_Fe $f,
        
ParagonIE_Sodium_Core_Curve25519_Fe $g,
        
$b 0
    
) {
        
/** @var array<int, int> $h */
        
$h = array();
        
$b *= -1;
        for (
$i 0$i 10; ++$i) {
            
$x = (($f[$i] ^ $g[$i]) & $b);
            
$h[$i] = ($f[$i]) ^ $x;
        }
        return 
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h);
    }

    
/**
     * Create a copy of a field element.
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     */
    
public static function fe_copy(ParagonIE_Sodium_Core_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_Core_Curve25519_Fe
     * @throws RangeException
     * @throws TypeError
     */
    
public static function fe_frombytes($s)
    {
        if (
self::strlen($s) !== 32) {
            throw new 
RangeException('Expected a 32-byte string.');
        }
        
$h0 self::load_4($s);
        
$h1 self::load_3(self::substr($s43)) << 6;
        
$h2 self::load_3(self::substr($s73)) << 5;
        
$h3 self::load_3(self::substr($s103)) << 3;
        
$h4 self::load_3(self::substr($s133)) << 2;
        
$h5 self::load_4(self::substr($s164));
        
$h6 self::load_3(self::substr($s203)) << 7;
        
$h7 self::load_3(self::substr($s233)) << 5;
        
$h8 self::load_3(self::substr($s263)) << 4;
        
$h9 = (self::load_3(self::substr($s293)) & 8388607) << 2;

        
$carry9 = ($h9 + (<< 24)) >> 25;
        
$h0 += self::mul($carry9195);
        
$h9 -= $carry9 << 25;
        
$carry1 = ($h1 + (<< 24)) >> 25;
        
$h2 += $carry1;
        
$h1 -= $carry1 << 25;
        
$carry3 = ($h3 + (<< 24)) >> 25;
        
$h4 += $carry3;
        
$h3 -= $carry3 << 25;
        
$carry5 = ($h5 + (<< 24)) >> 25;
        
$h6 += $carry5;
        
$h5 -= $carry5 << 25;
        
$carry7 = ($h7 + (<< 24)) >> 25;
        
$h8 += $carry7;
        
$h7 -= $carry7 << 25;

        
$carry0 = ($h0 + (<< 25)) >> 26;
        
$h1 += $carry0;
        
$h0 -= $carry0 << 26;
        
$carry2 = ($h2 + (<< 25)) >> 26;
        
$h3 += $carry2;
        
$h2 -= $carry2 << 26;
        
$carry4 = ($h4 + (<< 25)) >> 26;
        
$h5 += $carry4;
        
$h4 -= $carry4 << 26;
        
$carry6 = ($h6 + (<< 25)) >> 26;
        
$h7 += $carry6;
        
$h6 -= $carry6 << 26;
        
$carry8 = ($h8 + (<< 25)) >> 26;
        
$h9 += $carry8;
        
$h8 -= $carry8 << 26;

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

    
/**
     * Convert a field element to a byte string.
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $h
     * @return string
     */
    
public static function fe_tobytes(ParagonIE_Sodium_Core_Curve25519_Fe $h)
    {
        
$h0 = (int) $h[0];
        
$h1 = (int) $h[1];
        
$h2 = (int) $h[2];
        
$h3 = (int) $h[3];
        
$h4 = (int) $h[4];
        
$h5 = (int) $h[5];
        
$h6 = (int) $h[6];
        
$h7 = (int) $h[7];
        
$h8 = (int) $h[8];
        
$h9 = (int) $h[9];

        
$q = (self::mul($h9195) + (<< 24)) >> 25;
        
$q = ($h0 $q) >> 26;
        
$q = ($h1 $q) >> 25;
        
$q = ($h2 $q) >> 26;
        
$q = ($h3 $q) >> 25;
        
$q = ($h4 $q) >> 26;
        
$q = ($h5 $q) >> 25;
        
$q = ($h6 $q) >> 26;
        
$q = ($h7 $q) >> 25;
        
$q = ($h8 $q) >> 26;
        
$q = ($h9 $q) >> 25;

        
$h0 += self::mul($q195);

        
$carry0 $h0 >> 26;
        
$h1 += $carry0;
        
$h0 -= $carry0 << 26;
        
$carry1 $h1 >> 25;
        
$h2 += $carry1;
        
$h1 -= $carry1 << 25;
        
$carry2 $h2 >> 26;
        
$h3 += $carry2;
        
$h2 -= $carry2 << 26;
        
$carry3 $h3 >> 25;
        
$h4 += $carry3;
        
$h3 -= $carry3 << 25;
        
$carry4 $h4 >> 26;
        
$h5 += $carry4;
        
$h4 -= $carry4 << 26;
        
$carry5 $h5 >> 25;
        
$h6 += $carry5;
        
$h5 -= $carry5 << 25;
        
$carry6 $h6 >> 26;
        
$h7 += $carry6;
        
$h6 -= $carry6 << 26;
        
$carry7 $h7 >> 25;
        
$h8 += $carry7;
        
$h7 -= $carry7 << 25;
        
$carry8 $h8 >> 26;
        
$h9 += $carry8;
        
$h8 -= $carry8 << 26;
        
$carry9 $h9 >> 25;
        
$h9 -= $carry9 << 25;

        
/**
         * @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_Core_Curve25519_Fe $f
     * @return int
     * @throws SodiumException
     * @throws TypeError
     */
    
public static function fe_isnegative(ParagonIE_Sodium_Core_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_Core_Curve25519_Fe $f
     * @return bool
     * @throws SodiumException
     * @throws TypeError
     */
    
public static function fe_isnonzero(ParagonIE_Sodium_Core_Curve25519_Fe $f)
    {
        static 
$zero;
        if (
$zero === null) {
            
$zero str_repeat("\x00"32);
        }
        
/** @var string $zero */
        /** @var string $str */
        
$str self::fe_tobytes($f);
        return !
self::verify_32($str, (string) $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_Core_Curve25519_Fe $f
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $g
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     */
    
public static function fe_mul(
        
ParagonIE_Sodium_Core_Curve25519_Fe $f,
        
ParagonIE_Sodium_Core_Curve25519_Fe $g
    
) {
        
// Ensure limbs aren't oversized.
        
$f self::fe_normalize($f);
        
$g self::fe_normalize($g);
        
$f0 $f[0];
        
$f1 $f[1];
        
$f2 $f[2];
        
$f3 $f[3];
        
$f4 $f[4];
        
$f5 $f[5];
        
$f6 $f[6];
        
$f7 $f[7];
        
$f8 $f[8];
        
$f9 $f[9];
        
$g0 $g[0];
        
$g1 $g[1];
        
$g2 $g[2];
        
$g3 $g[3];
        
$g4 $g[4];
        
$g5 $g[5];
        
$g6 $g[6];
        
$g7 $g[7];
        
$g8 $g[8];
        
$g9 $g[9];
        
$g1_19 self::mul($g1195);
        
$g2_19 self::mul($g2195);
        
$g3_19 self::mul($g3195);
        
$g4_19 self::mul($g4195);
        
$g5_19 self::mul($g5195);
        
$g6_19 self::mul($g6195);
        
$g7_19 self::mul($g7195);
        
$g8_19 self::mul($g8195);
        
$g9_19 self::mul($g9195);
        
$f1_2 $f1 << 1;
        
$f3_2 $f3 << 1;
        
$f5_2 $f5 << 1;
        
$f7_2 $f7 << 1;
        
$f9_2 $f9 << 1;
        
$f0g0    self::mul($f0,    $g026);
        
$f0g1    self::mul($f0,    $g125);
        
$f0g2    self::mul($f0,    $g226);
        
$f0g3    self::mul($f0,    $g325);
        
$f0g4    self::mul($f0,    $g426);
        
$f0g5    self::mul($f0,    $g525);
        
$f0g6    self::mul($f0,    $g626);
        
$f0g7    self::mul($f0,    $g725);
        
$f0g8    self::mul($f0,    $g826);
        
$f0g9    self::mul($f0,    $g926);
        
$f1g0    self::mul($f1,    $g026);
        
$f1g1_2  self::mul($f1_2,  $g125);
        
$f1g2    self::mul($f1,    $g226);
        
$f1g3_2  self::mul($f1_2,  $g325);
        
$f1g4    self::mul($f1,    $g426);
        
$f1g5_2  self::mul($f1_2,  $g525);
        
$f1g6    self::mul($f1,    $g626);
        
$f1g7_2  self::mul($f1_2,  $g725);
        
$f1g8    self::mul($f1,    $g826);
        
$f1g9_38 self::mul($g9_19$f1_226);
        
$f2g0    self::mul($f2,    $g026);
        
$f2g1    self::mul($f2,    $g125);
        
$f2g2    self::mul($f2,    $g226);
        
$f2g3    self::mul($f2,    $g325);
        
$f2g4    self::mul($f2,    $g426);
        
$f2g5    self::mul($f2,    $g525);
        
$f2g6    self::mul($f2,    $g626);
        
$f2g7    self::mul($f2,    $g725);
        
$f2g8_19 self::mul($g8_19$f226);
        
$f2g9_19 self::mul($g9_19$f226);
        
$f3g0    self::mul($f3,    $g026);
        
$f3g1_2  self::mul($f3_2,  $g125);
        
$f3g2    self::mul($f3,    $g226);
        
$f3g3_2  self::mul($f3_2,  $g325);
        
$f3g4    self::mul($f3,    $g426);
        
$f3g5_2  self::mul($f3_2,  $g525);
        
$f3g6    self::mul($f3,    $g626);
        
$f3g7_38 self::mul($g7_19$f3_226);
        
$f3g8_19 self::mul($g8_19$f325);
        
$f3g9_38 self::mul($g9_19$f3_226);
        
$f4g0    self::mul($f4,    $g026);
        
$f4g1    self::mul($f4,    $g125);
        
$f4g2    self::mul($f4,    $g226);
        
$f4g3    self::mul($f4,    $g325);
        
$f4g4    self::mul($f4,    $g426);
        
$f4g5    self::mul($f4,    $g525);
        
$f4g6_19 self::mul($g6_19$f426);
        
$f4g7_19 self::mul($g7_19$f426);
        
$f4g8_19 self::mul($g8_19$f426);
        
$f4g9_19 self::mul($g9_19$f426);
        
$f5g0    self::mul($f5,    $g026);
        
$f5g1_2  self::mul($f5_2,  $g125);
        
$f5g2    self::mul($f5,    $g226);
        
$f5g3_2  self::mul($f5_2,  $g325);
        
$f5g4    self::mul($f5,    $g426);
        
$f5g5_38 self::mul($g5_19$f5_226);
        
$f5g6_19 self::mul($g6_19$f525);
        
$f5g7_38 self::mul($g7_19$f5_226);
        
$f5g8_19 self::mul($g8_19$f525);
        
$f5g9_38 self::mul($g9_19$f5_226);
        
$f6g0    self::mul($f6,    $g026);
        
$f6g1    self::mul($f6,    $g125);
        
$f6g2    self::mul($f6,    $g226);
        
$f6g3    self::mul($f6,    $g325);
        
$f6g4_19 self::mul($g4_19$f626);
        
$f6g5_19 self::mul($g5_19$f626);
        
$f6g6_19 self::mul($g6_19$f626);
        
$f6g7_19 self::mul($g7_19$f626);
        
$f6g8_19 self::mul($g8_19$f626);
        
$f6g9_19 self::mul($g9_19$f626);
        
$f7g0    self::mul($f7,    $g026);
        
$f7g1_2  self::mul($f7_2,  $g125);
        
$f7g2    self::mul($f7,    $g226);
        
$f7g3_38 self::mul($g3_19$f7_226);
        
$f7g4_19 self::mul($g4_19$f726);
        
$f7g5_38 self::mul($g5_19$f7_226);
        
$f7g6_19 self::mul($g6_19$f725);
        
$f7g7_38 self::mul($g7_19$f7_226);
        
$f7g8_19 self::mul($g8_19$f725);
        
$f7g9_38 self::mul($g9_19,$f7_226);
        
$f8g0    self::mul($f8,    $g026);
        
$f8g1    self::mul($f8,    $g125);
        
$f8g2_19 self::mul($g2_19$f826);
        
$f8g3_19 self::mul($g3_19$f826);
        
$f8g4_19 self::mul($g4_19$f826);
        
$f8g5_19 self::mul($g5_19$f826);
        
$f8g6_19 self::mul($g6_19$f826);
        
$f8g7_19 self::mul($g7_19$f826);
        
$f8g8_19 self::mul($g8_19$f826);
        
$f8g9_19 self::mul($g9_19$f826);
        
$f9g0    self::mul($f9,    $g026);
        
$f9g1_38 self::mul($g1_19$f9_226);
        
$f9g2_19 self::mul($g2_19$f925);
        
$f9g3_38 self::mul($g3_19$f9_226);
        
$f9g4_19 self::mul($g4_19$f925);
        
$f9g5_38 self::mul($g5_19$f9_226);
        
$f9g6_19 self::mul($g6_19$f925);
        
$f9g7_38 self::mul($g7_19$f9_226);
        
$f9g8_19 self::mul($g8_19$f925);
        
$f9g9_38 self::mul($g9_19$f9_226);

        
$h0 $f0g0 $f1g9_38 $f2g8_19 $f3g7_38 $f4g6_19 $f5g5_38 $f6g4_19 $f7g3_38 $f8g2_19 $f9g1_38;
        
$h1 $f0g1 $f1g0    $f2g9_19 $f3g8_19 $f4g7_19 $f5g6_19 $f6g5_19 $f7g4_19 $f8g3_19 $f9g2_19;
        
$h2 $f0g2 $f1g1_2  $f2g0    $f3g9_38 $f4g8_19 $f5g7_38 $f6g6_19 $f7g5_38 $f8g4_19 $f9g3_38;
        
$h3 $f0g3 $f1g2    $f2g1    $f3g0    $f4g9_19 $f5g8_19 $f6g7_19 $f7g6_19 $f8g5_19 $f9g4_19;
        
$h4 $f0g4 $f1g3_2  $f2g2    $f3g1_2  $f4g0    $f5g9_38 $f6g8_19 $f7g7_38 $f8g6_19 $f9g5_38;
        
$h5 $f0g5 $f1g4    $f2g3    $f3g2    $f4g1    $f5g0    $f6g9_19 $f7g8_19 $f8g7_19 $f9g6_19;
        
$h6 $f0g6 $f1g5_2  $f2g4    $f3g3_2  $f4g2    $f5g1_2  $f6g0    $f7g9_38 $f8g8_19 $f9g7_38;
        
$h7 $f0g7 $f1g6    $f2g5    $f3g4    $f4g3    $f5g2    $f6g1    $f7g0    $f8g9_19 $f9g8_19;
        
$h8 $f0g8 $f1g7_2  $f2g6    $f3g5_2  $f4g4    $f5g3_2  $f6g2    $f7g1_2  $f8g0    $f9g9_38;
        
$h9 $f0g9 $f1g8    $f2g7    $f3g6    $f4g5    $f5g4    $f6g3    $f7g2    $f8g1    $f9g0   ;

        
$carry0 = ($h0 + (<< 25)) >> 26;
        
$h1 += $carry0;
        
$h0 -= $carry0 << 26;
        
$carry4 = ($h4 + (<< 25)) >> 26;
        
$h5 += $carry4;
        
$h4 -= $carry4 << 26;

        
$carry1 = ($h1 + (<< 24)) >> 25;
        
$h2 += $carry1;
        
$h1 -= $carry1 << 25;
        
$carry5 = ($h5 + (<< 24)) >> 25;
        
$h6 += $carry5;
        
$h5 -= $carry5 << 25;

        
$carry2 = ($h2 + (<< 25)) >> 26;
        
$h3 += $carry2;
        
$h2 -= $carry2 << 26;
        
$carry6 = ($h6 + (<< 25)) >> 26;
        
$h7 += $carry6;
        
$h6 -= $carry6 << 26;

        
$carry3 = ($h3 + (<< 24)) >> 25;
        
$h4 += $carry3;
        
$h3 -= $carry3 << 25;
        
$carry7 = ($h7 + (<< 24)) >> 25;
        
$h8 += $carry7;
        
$h7 -= $carry7 << 25;

        
$carry4 = ($h4 + (<< 25)) >> 26;
        
$h5 += $carry4;
        
$h4 -= $carry4 << 26;
        
$carry8 = ($h8 + (<< 25)) >> 26;
        
$h9 += $carry8;
        
$h8 -= $carry8 << 26;

        
$carry9 = ($h9 + (<< 24)) >> 25;
        
$h0 += self::mul($carry9195);
        
$h9 -= $carry9 << 25;

        
$carry0 = ($h0 + (<< 25)) >> 26;
        
$h1 += $carry0;
        
$h0 -= $carry0 << 26;

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

    
/**
     * 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_Core_Curve25519_Fe $f
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     * @psalm-suppress MixedAssignment
     */
    
public static function fe_neg(ParagonIE_Sodium_Core_Curve25519_Fe $f)
    {
        
$h = new ParagonIE_Sodium_Core_Curve25519_Fe();
        for (
$i 0$i 10; ++$i) {
            
$h[$i] = -$f[$i];
        }
        return 
self::fe_normalize($h);
    }

    
/**
     * Square a field element
     *
     * h = f * f
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     */
    
public static function fe_sq(ParagonIE_Sodium_Core_Curve25519_Fe $f)
    {
        
$f self::fe_normalize($f);
        
$f0 = (int) $f[0];
        
$f1 = (int) $f[1];
        
$f2 = (int) $f[2];
        
$f3 = (int) $f[3];
        
$f4 = (int) $f[4];
        
$f5 = (int) $f[5];
        
$f6 = (int) $f[6];
        
$f7 = (int) $f[7];
        
$f8 = (int) $f[8];
        
$f9 = (int) $f[9];

        
$f0_2 $f0 << 1;
        
$f1_2 $f1 << 1;
        
$f2_2 $f2 << 1;
        
$f3_2 $f3 << 1;
        
$f4_2 $f4 << 1;
        
$f5_2 $f5 << 1;
        
$f6_2 $f6 << 1;
        
$f7_2 $f7 << 1;
        
$f5_38 self::mul($f5386);
        
$f6_19 self::mul($f6195);
        
$f7_38 self::mul($f7386);
        
$f8_19 self::mul($f8195);
        
$f9_38 self::mul($f9386);
        
$f0f0    self::mul($f0,    $f0,    26);
        
$f0f1_2  self::mul($f0_2,  $f1,    26);
        
$f0f2_2  self::mul($f0_2,  $f2,    26);
        
$f0f3_2  self::mul($f0_2,  $f3,    26);
        
$f0f4_2  self::mul($f0_2,  $f4,    26);
        
$f0f5_2  self::mul($f0_2,  $f5,    26);
        
$f0f6_2  self::mul($f0_2,  $f6,    26);
        
$f0f7_2  self::mul($f0_2,  $f7,    26);
        
$f0f8_2  self::mul($f0_2,  $f8,    26);
        
$f0f9_2  self::mul($f0_2,  $f9,    26);
        
$f1f1_2  self::mul($f1_2,  $f1,    26);
        
$f1f2_2  self::mul($f1_2,  $f2,    26);
        
$f1f3_4  self::mul($f1_2,  $f3_2,  26);
        
$f1f4_2  self::mul($f1_2,  $f4,    26);
        
$f1f5_4  self::mul($f1_2,  $f5_2,  26);
        
$f1f6_2  self::mul($f1_2,  $f6,    26);
        
$f1f7_4  self::mul($f1_2,  $f7_2,  26);
        
$f1f8_2  self::mul($f1_2,  $f8,    26);
        
$f1f9_76 self::mul($f9_38$f1_2,  27);
        
$f2f2    self::mul($f2,    $f2,    27);
        
$f2f3_2  self::mul($f2_2,  $f3,    27);
        
$f2f4_2  self::mul($f2_2,  $f4,    27);
        
$f2f5_2  self::mul($f2_2,  $f5,    27);
        
$f2f6_2  self::mul($f2_2,  $f6,    27);
        
$f2f7_2  self::mul($f2_2,  $f7,    27);
        
$f2f8_38 self::mul($f8_19$f2_2,  27);
        
$f2f9_38 self::mul($f9_38$f2,    26);
        
$f3f3_2  self::mul($f3_2,  $f3,    26);
        
$f3f4_2  self::mul($f3_2,  $f4,    26);
        
$f3f5_4  self::mul($f3_2,  $f5_2,  26);
        
$f3f6_2  self::mul($f3_2,  $f6,    26);
        
$f3f7_76 self::mul($f7_38$f3_2,  26);
        
$f3f8_38 self::mul($f8_19$f3_2,  26);
        
$f3f9_76 self::mul($f9_38$f3_2,  26);
        
$f4f4    self::mul($f4,    $f4,    26);
        
$f4f5_2  self::mul($f4_2,  $f5,    26);
        
$f4f6_38 self::mul($f6_19$f4_2,  27);
        
$f4f7_38 self::mul($f7_38$f4,    26);
        
$f4f8_38 self::mul($f8_19$f4_2,  27);
        
$f4f9_38 self::mul($f9_38$f4,    26);
        
$f5f5_38 self::mul($f5_38$f5,    26);
        
$f5f6_38 self::mul($f6_19$f5_2,  26);
        
$f5f7_76 self::mul($f7_38$f5_2,  26);
        
$f5f8_38 self::mul($f8_19$f5_2,  26);
        
$f5f9_76 self::mul($f9_38$f5_2,  26);
        
$f6f6_19 self::mul($f6_19$f6,    26);
        
$f6f7_38 self::mul($f7_38$f6,    26);
        
$f6f8_38 self::mul($f8_19$f6_2,  27);
        
$f6f9_38 self::mul($f9_38$f6,    26);
        
$f7f7_38 self::mul($f7_38$f7,    26);
        
$f7f8_38 self::mul($f8_19$f7_2,  26);
        
$f7f9_76 self::mul($f9_38$f7_2,  26);
        
$f8f8_19 self::mul($f8_19$f8,    26);
        
$f8f9_38 self::mul($f9_38$f8,    26);
        
$f9f9_38 self::mul($f9_38$f9,    26);
        
$h0 $f0f0   $f1f9_76 $f2f8_38 $f3f7_76 $f4f6_38 $f5f5_38;
        
$h1 $f0f1_2 $f2f9_38 $f3f8_38 $f4f7_38 $f5f6_38;
        
$h2 $f0f2_2 $f1f1_2  $f3f9_76 $f4f8_38 $f5f7_76 $f6f6_19;
        
$h3 $f0f3_2 $f1f2_2  $f4f9_38 $f5f8_38 $f6f7_38;
        
$h4 $f0f4_2 $f1f3_4  $f2f2    $f5f9_76 $f6f8_38 $f7f7_38;
        
$h5 $f0f5_2 $f1f4_2  $f2f3_2  $f6f9_38 $f7f8_38;
        
$h6 $f0f6_2 $f1f5_4  $f2f4_2  $f3f3_2  $f7f9_76 $f8f8_19;
        
$h7 $f0f7_2 $f1f6_2  $f2f5_2  $f3f4_2  $f8f9_38;
        
$h8 $f0f8_2 $f1f7_4  $f2f6_2  $f3f5_4  $f4f4    $f9f9_38;
        
$h9 $f0f9_2 $f1f8_2  $f2f7_2  $f3f6_2  $f4f5_2;

        
$carry0 = ($h0 + (<< 25)) >> 26;
        
$h1 += $carry0;
        
$h0 -= $carry0 << 26;
        
$carry4 = ($h4 + (<< 25)) >> 26;
        
$h5 += $carry4;
        
$h4 -= $carry4 << 26;

        
$carry1 = ($h1 + (<< 24)) >> 25;
        
$h2 += $carry1;
        
$h1 -= $carry1 << 25;
        
$carry5 = ($h5 + (<< 24)) >> 25;
        
$h6 += $carry5;
        
$h5 -= $carry5 << 25;

        
$carry2 = ($h2 + (<< 25)) >> 26;
        
$h3 += $carry2;
        
$h2 -= $carry2 << 26;
        
$carry6 = ($h6 + (<< 25)) >> 26;
        
$h7 += $carry6;
        
$h6 -= $carry6 << 26;

        
$carry3 = ($h3 + (<< 24)) >> 25;
        
$h4 += $carry3;
        
$h3 -= $carry3 << 25;
        
$carry7 = ($h7 + (<< 24)) >> 25;
        
$h8 += $carry7;
        
$h7 -= $carry7 << 25;

        
$carry4 = ($h4 + (<< 25)) >> 26;
        
$h5 += $carry4;
        
$h4 -= $carry4 << 26;
        
$carry8 = ($h8 + (<< 25)) >> 26;
        
$h9 += $carry8;
        
$h8 -= $carry8 << 26;

        
$carry9 = ($h9 + (<< 24)) >> 25;
        
$h0 += self::mul($carry9195);
        
$h9 -= $carry9 << 25;

        
$carry0 = ($h0 + (<< 25)) >> 26;
        
$h1 += $carry0;
        
$h0 -= $carry0 << 26;

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


    
/**
     * Square and double a field element
     *
     * h = 2 * f * f
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     */
    
public static function fe_sq2(ParagonIE_Sodium_Core_Curve25519_Fe $f)
    {
        
$f self::fe_normalize($f);
        
$f0 = (int) $f[0];
        
$f1 = (int) $f[1];
        
$f2 = (int) $f[2];
        
$f3 = (int) $f[3];
        
$f4 = (int) $f[4];
        
$f5 = (int) $f[5];
        
$f6 = (int) $f[6];
        
$f7 = (int) $f[7];
        
$f8 = (int) $f[8];
        
$f9 = (int) $f[9];

        
$f0_2 $f0 << 1;
        
$f1_2 $f1 << 1;
        
$f2_2 $f2 << 1;
        
$f3_2 $f3 << 1;
        
$f4_2 $f4 << 1;
        
$f5_2 $f5 << 1;
        
$f6_2 $f6 << 1;
        
$f7_2 $f7 << 1;
        
$f5_38 self::mul($f5386); /* 1.959375*2^30 */
        
$f6_19 self::mul($f6195); /* 1.959375*2^30 */
        
$f7_38 self::mul($f7386); /* 1.959375*2^30 */
        
$f8_19 self::mul($f8195); /* 1.959375*2^30 */
        
$f9_38 self::mul($f9386); /* 1.959375*2^30 */
        
$f0f0 self::mul($f0$f024);
        
$f0f1_2 self::mul($f0_2$f124);
        
$f0f2_2 self::mul($f0_2$f224);
        
$f0f3_2 self::mul($f0_2$f324);
        
$f0f4_2 self::mul($f0_2$f424);
        
$f0f5_2 self::mul($f0_2$f524);
        
$f0f6_2 self::mul($f0_2$f624);
        
$f0f7_2 self::mul($f0_2$f724);
        
$f0f8_2 self::mul($f0_2$f824);
        
$f0f9_2 self::mul($f0_2$f924);
        
$f1f1_2 self::mul($f1_2,  $f124);
        
$f1f2_2 self::mul($f1_2,  $f224);
        
$f1f3_4 self::mul($f1_2,  $f3_224);
        
$f1f4_2 self::mul($f1_2,  $f424);
        
$f1f5_4 self::mul($f1_2,  $f5_224);
        
$f1f6_2 self::mul($f1_2,  $f624);
        
$f1f7_4 self::mul($f1_2,  $f7_224);
        
$f1f8_2 self::mul($f1_2,  $f824);
        
$f1f9_76 self::mul($f9_38$f1_224);
        
$f2f2 self::mul($f2,  $f224);
        
$f2f3_2 self::mul($f2_2,  $f324);
        
$f2f4_2 self::mul($f2_2,  $f424);
        
$f2f5_2 self::mul($f2_2,  $f524);
        
$f2f6_2 self::mul($f2_2,  $f624);
        
$f2f7_2 self::mul($f2_2,  $f724);
        
$f2f8_38 self::mul($f8_19$f2_225);
        
$f2f9_38 self::mul($f9_38$f224);
        
$f3f3_2 self::mul($f3_2,  $f324);
        
$f3f4_2 self::mul($f3_2,  $f424);
        
$f3f5_4 self::mul($f3_2,  $f5_224);
        
$f3f6_2 self::mul($f3_2,  $f624);
        
$f3f7_76 self::mul($f7_38$f3_224);
        
$f3f8_38 self::mul($f8_19$f3_224);
        
$f3f9_76 self::mul($f9_38$f3_224);
        
$f4f4 self::mul($f4,  $f424);
        
$f4f5_2 self::mul($f4_2,  $f524);
        
$f4f6_38 self::mul($f6_19$f4_225);
        
$f4f7_38 self::mul($f7_38$f424);
        
$f4f8_38 self::mul($f8_19$f4_225);
        
$f4f9_38 self::mul($f9_38$f424);
        
$f5f5_38 self::mul($f5_38$f524);
        
$f5f6_38 self::mul($f6_19$f5_224);
        
$f5f7_76 self::mul($f7_38$f5_224);
        
$f5f8_38 self::mul($f8_19$f5_224);
        
$f5f9_76 self::mul($f9_38$f5_224);
        
$f6f6_19 self::mul($f6_19$f624);
        
$f6f7_38 self::mul($f7_38$f624);
        
$f6f8_38 self::mul($f8_19$f6_225);
        
$f6f9_38 self::mul($f9_38$f624);
        
$f7f7_38 self::mul($f7_38$f724);
        
$f7f8_38 self::mul($f8_19$f7_224);
        
$f7f9_76 self::mul($f9_38$f7_224);
        
$f8f8_19 self::mul($f8_19$f824);
        
$f8f9_38 self::mul($f9_38$f824);
        
$f9f9_38 self::mul($f9_38$f924);

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

        
$carry0 = ($h0 + (<< 25)) >> 26;
        
$h1 += $carry0;
        
$h0 -= $carry0 << 26;
        
$carry4 = ($h4 + (<< 25)) >> 26;
        
$h5 += $carry4;
        
$h4 -= $carry4 << 26;

        
$carry1 = ($h1 + (<< 24)) >> 25;
        
$h2 += $carry1;
        
$h1 -= $carry1 << 25;
        
$carry5 = ($h5 + (<< 24)) >> 25;
        
$h6 += $carry5;
        
$h5 -= $carry5 << 25;

        
$carry2 = ($h2 + (<< 25)) >> 26;
        
$h3 += $carry2;
        
$h2 -= $carry2 << 26;
        
$carry6 = ($h6 + (<< 25)) >> 26;
        
$h7 += $carry6;
        
$h6 -= $carry6 << 26;

        
$carry3 = ($h3 + (<< 24)) >> 25;
        
$h4 += $carry3;
        
$h3 -= $carry3 << 25;
        
$carry7 = ($h7 + (<< 24)) >> 25;
        
$h8 += $carry7;
        
$h7 -= $carry7 << 25;

        
$carry4 = ($h4 + (<< 25)) >> 26;
        
$h5 += $carry4;
        
$h4 -= $carry4 << 26;
        
$carry8 = ($h8 + (<< 25)) >> 26;
        
$h9 += $carry8;
        
$h8 -= $carry8 << 26;

        
$carry9 = ($h9 + (<< 24)) >> 25;
        
$h0 += self::mul($carry9195);
        
$h9 -= $carry9 << 25;

        
$carry0 = ($h0 + (<< 25)) >> 26;
        
$h1 += $carry0;
        
$h0 -= $carry0 << 26;

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

    
/**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $Z
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     */
    
public static function fe_invert(ParagonIE_Sodium_Core_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_Core_Curve25519_Fe $z
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     */
    
public static function fe_pow22523(ParagonIE_Sodium_Core_Curve25519_Fe $z)
    {
        
$z self::fe_normalize($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_Core_Curve25519_Fe $f
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $g
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     * @psalm-suppress MixedOperand
     */
    
public static function fe_sub(ParagonIE_Sodium_Core_Curve25519_Fe $fParagonIE_Sodium_Core_Curve25519_Fe $g)
    {
        return 
self::fe_normalize(
            
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
                array(
                    (int) (
$f[0] - $g[0]),
                    (int) (
$f[1] - $g[1]),
                    (int) (
$f[2] - $g[2]),
                    (int) (
$f[3] - $g[3]),
                    (int) (
$f[4] - $g[4]),
                    (int) (
$f[5] - $g[5]),
                    (int) (
$f[6] - $g[6]),
                    (int) (
$f[7] - $g[7]),
                    (int) (
$f[8] - $g[8]),
                    (int) (
$f[9] - $g[9])
                )
            )
        );
    }

    
/**
     * Add two group elements.
     *
     * r = p + q
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     */
    
public static function ge_add(
        
ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p,
        
ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q
    
) {
        
$r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();
        
$r->self::fe_add($p->Y$p->X);
        
$r->self::fe_sub($p->Y$p->X);
        
$r->self::fe_mul($r->X$q->YplusX);
        
$r->self::fe_mul($r->Y$q->YminusX);
        
$r->self::fe_mul($q->T2d$p->T);
        
$r->self::fe_mul($p->Z$q->Z);
        
$t0   self::fe_add($r->X$r->X);
        
$r->self::fe_sub($r->Z$r->Y);
        
$r->self::fe_add($r->Z$r->Y);
        
$r->self::fe_add($t0$r->T);
        
$r->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
     */
    
public static function slide($a)
    {
        if (
self::strlen($a) < 256) {
            if (
self::strlen($a) < 16) {
                
$a str_pad($a256'0'STR_PAD_RIGHT);
            }
        }
        
/** @var array<int, int> $r */
        
$r = array();

        
/** @var int $i */
        
for ($i 0$i 256; ++$i) {
            
$r[$i] = (int) (
                
& (
                    
self::chrToInt($a[(int) ($i >> 3)])
                        >>
                    (
$i 7)
                )
            );
        }

        for (
$i 0;$i 256;++$i) {
            if (
$r[$i]) {
                for (
$b 1;$b <= && $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_Core_Curve25519_Ge_P3
     * @throws SodiumException
     * @throws TypeError
     */
    
public static function ge_frombytes_negate_vartime($s)
    {
        static 
$d null;
        if (!
$d) {
            
$d ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d);
        }

        
# fe_frombytes(h->Y,s);
        # fe_1(h->Z);
        
$h = new ParagonIE_Sodium_Core_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_Core_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->self::fe_sq($v3);
        
$h->self::fe_mul($h->X$v);
        
$h->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->self::fe_pow22523($h->X); /* x = (uv^7)^((q-5)/8) */
        
$h->self::fe_mul($h->X$v3);
        
$h->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->self::fe_mul(
                
$h->X,
                
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(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->self::fe_neg($h->X);
        }

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

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

        return 
$r;
    }

    
/**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     */
    
public static function ge_msub(
        
ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R,
        
ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p,
        
ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q
    
) {
        
$r = clone $R;

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

        return 
$r;
    }

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

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

    
/**
     * @internal You should not use this directly from another application
     *
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2
     */
    
public static function ge_p2_0()
    {
        return new 
ParagonIE_Sodium_Core_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_Core_Curve25519_Ge_P2 $p
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     */
    
public static function ge_p2_dbl(ParagonIE_Sodium_Core_Curve25519_Ge_P2 $p)
    {
        
$r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();

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

        return 
$r;
    }

    
/**
     * @internal You should not use this directly from another application
     *
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3
     */
    
public static function ge_p3_0()
    {
        return new 
ParagonIE_Sodium_Core_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_Core_Curve25519_Ge_P3 $p
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached
     */
    
public static function ge_p3_to_cached(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p)
    {
        static 
$d2 null;
        if (
$d2 === null) {
            
$d2 ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d2);
        }
        
/** @var ParagonIE_Sodium_Core_Curve25519_Fe $d2 */
        
$r = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached();
        
$r->YplusX self::fe_add($p->Y$p->X);
        
$r->YminusX self::fe_sub($p->Y$p->X);
        
$r->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_Core_Curve25519_Ge_P3 $p
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2
     */
    
public static function ge_p3_to_p2(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p)
    {
        return new 
ParagonIE_Sodium_Core_Curve25519_Ge_P2(
            
self::fe_copy($p->X),
            
self::fe_copy($p->Y),
            
self::fe_copy($p->Z)
        );
    }

    
/**
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h
     * @return string
     * @throws SodiumException
     * @throws TypeError
     */
    
public static function ge_p3_tobytes(ParagonIE_Sodium_Core_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_Core_Curve25519_Ge_P3 $p
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     */
    
public static function ge_p3_dbl(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p)
    {
        
$q self::ge_p3_to_p2($p);
        return 
self::ge_p2_dbl($q);
    }

    
/**
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
     */
    
public static function ge_precomp_0()
    {
        return new 
ParagonIE_Sodium_Core_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
     */
    
public static function equal($b$c)
    {
        return (int) (((
$b $c) - 1) >> 31) & 1;
    }

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

    
/**
     * Conditional move
     *
     * @internal You should not use this directly from another application
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $t
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $u
     * @param int $b
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
     */
    
public static function cmov(
        
ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $t,
        
ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $u,
        
$b
    
) {
        if (!
is_int($b)) {
            throw new 
InvalidArgumentException('Expected an integer.');
        }
        return new 
ParagonIE_Sodium_Core_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)
        );
    }

    
/**
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $t
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $u
     * @param int $b
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached
     */
    
public static function ge_cmov_cached(
        
ParagonIE_Sodium_Core_Curve25519_Ge_Cached $t,
        
ParagonIE_Sodium_Core_Curve25519_Ge_Cached $u,
        
$b
    
) {
        
$b &= 1;
        
$ret = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached();
        
$ret->YplusX  self::fe_cmov($t->YplusX,  $u->YplusX,  $b);
        
$ret->YminusX self::fe_cmov($t->YminusX$u->YminusX$b);
        
$ret->Z       self::fe_cmov($t->Z,       $u->Z,       $b);
        
$ret->T2d     self::fe_cmov($t->T2d,     $u->T2d,     $b);
        return 
$ret;
    }

    
/**
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached[] $cached
     * @param int $b
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached
     * @throws SodiumException
     */
    
public static function ge_cmov8_cached(array $cached$b)
    {
        
// const unsigned char bnegative = negative(b);
        // const unsigned char babs      = b - (((-bnegative) & b) * ((signed char) 1 << 1));
        
$bnegative self::negative($b);
        
$babs $b - (((-$bnegative) & $b) << 1);

        
// ge25519_cached_0(t);
        
$t = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached(
            
self::fe_1(),
            
self::fe_1(),
            
self::fe_1(),
            
self::fe_0()
        );

        
// ge25519_cmov_cached(t, &cached[0], equal(babs, 1));
        // ge25519_cmov_cached(t, &cached[1], equal(babs, 2));
        // ge25519_cmov_cached(t, &cached[2], equal(babs, 3));
        // ge25519_cmov_cached(t, &cached[3], equal(babs, 4));
        // ge25519_cmov_cached(t, &cached[4], equal(babs, 5));
        // ge25519_cmov_cached(t, &cached[5], equal(babs, 6));
        // ge25519_cmov_cached(t, &cached[6], equal(babs, 7));
        // ge25519_cmov_cached(t, &cached[7], equal(babs, 8));
        
for ($x 0$x 8; ++$x) {
            
$t self::ge_cmov_cached($t$cached[$x], self::equal($babs$x 1));
        }

        
// fe25519_copy(minust.YplusX, t->YminusX);
        // fe25519_copy(minust.YminusX, t->YplusX);
        // fe25519_copy(minust.Z, t->Z);
        // fe25519_neg(minust.T2d, t->T2d);
        
$minust = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached(
            
self::fe_copy($t->YminusX),
            
self::fe_copy($t->YplusX),
            
self::fe_copy($t->Z),
            
self::fe_neg($t->T2d)
        );
        return 
self::ge_cmov_cached($t$minust$bnegative);
    }

    
/**
     * @internal You should not use this directly from another application
     *
     * @param int $pos
     * @param int $b
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedArgument
     * @psalm-suppress MixedArrayAccess
     * @psalm-suppress MixedArrayOffset
     */
    
public static function ge_select($pos 0$b 0)
    {
        static 
$base null;
        if (
$base === null) {
            
$base = array();
            
/** @var int $i */
            
foreach (self::$base as $i => $bas) {
                for (
$j 0$j 8; ++$j) {
                    
$base[$i][$j] = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
                        
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][0]),
                        
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][1]),
                        
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][2])
                    );
                }
            }
        }
        
/** @var array<int, array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp>> $base */
        
if (!is_int($pos)) {
            throw new 
InvalidArgumentException('Position must be an integer');
        }
        if (
$pos || $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_Core_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_Core_Curve25519_Ge_P3 $p
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     */
    
public static function ge_sub(
        
ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p,
        
ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q
    
) {
        
$r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();

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

        return 
$r;
    }

    
/**
     * Convert a group element to a byte string.
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P2 $h
     * @return string
     * @throws SodiumException
     * @throws TypeError
     */
    
public static function ge_tobytes(ParagonIE_Sodium_Core_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_Core_Curve25519_Ge_P3 $A
     * @param string $b
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedArgument
     * @psalm-suppress MixedArrayAccess
     */
    
public static function ge_double_scalarmult_vartime(
        
$a,
        
ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A,
        
$b
    
) {
        
/** @var array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Cached> $Ai */
        
$Ai = array();

        
/** @var array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp> $Bi */
        
static $Bi = array();
        if (!
$Bi) {
            for (
$i 0$i 8; ++$i) {
                
$Bi[$i] = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
                    
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][0]),
                    
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][1]),
                    
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][2])
                );
            }
        }
        for (
$i 0$i 8; ++$i) {
            
$Ai[$i] = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached(
                
self::fe_0(),
                
self::fe_0(),
                
self::fe_0(),
                
self::fe_0()
            );
        }

        
# 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)]
                );
            }

            
# if (bslide[i] > 0) {
            
if ($bslide[$i] > 0) {
                
/** @var int $index */
                
$index = (int) floor($bslide[$i] / 2);
                
# ge_p1p1_to_p3(&u,&t);
                # ge_madd(&t,&u,&Bi[bslide[i]/2]);
                
$u self::ge_p1p1_to_p3($t);
                
$t self::ge_madd($t$u$Bi[$index]);
            
# } else if (bslide[i] < 0) {
            
} elseif ($bslide[$i] < 0) {
                
/** @var int $index */
                
$index = (int) floor(-$bslide[$i] / 2);
                
# ge_p1p1_to_p3(&u,&t);
                # ge_msub(&t,&u,&Bi[(-bslide[i])/2]);
                
$u self::ge_p1p1_to_p3($t);
                
$t self::ge_msub($t$u$Bi[$index]);
            }
            
# 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
     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3
     * @throws SodiumException
     * @throws TypeError
     * @psalm-suppress MixedAssignment
     * @psalm-suppress MixedOperand
     */
    
public static function ge_scalarmult($a$p)
    {
        
$e array_fill(0640);

        
/** @var ParagonIE_Sodium_Core_Curve25519_Ge_Cached[] $pi */
        
$pi = array();

        
//        ge25519_p3_to_cached(&pi[1 - 1], p);   /* p */
        
$pi[0] = self::ge_p3_to_cached($p);

        
//        ge25519_p3_dbl(&t2, p);
        //        ge25519_p1p1_to_p3(&p2, &t2);
        //        ge25519_p3_to_cached(&pi[2 - 1], &p2); /* 2p = 2*p */
        
$t2 self::ge_p3_dbl($p);
        
$p2 self::ge_p1p1_to_p3($t2);
        
$pi[1] = self::ge_p3_to_cached($p2);

        
//        ge25519_add_cached(&t3, p, &pi[2 - 1]);
        //        ge25519_p1p1_to_p3(&p3, &t3);
        //        ge25519_p3_to_cached(&pi[3 - 1], &p3); /* 3p = 2p+p */
        
$t3 self::ge_add($p$pi[1]);
        
$p3 self::ge_p1p1_to_p3($t3);
        
$pi[2] = self::ge_p3_to_cached($p3);

        
//        ge25519_p3_dbl(&t4, &p2);
        //        ge25519_p1p1_to_p3(&p4, &t4);
        //        ge25519_p3_to_cached(&pi[4 - 1], &p4); /* 4p = 2*2p */
        
$t4 self::ge_p3_dbl($p2);
        
$p4 self::ge_p1p1_to_p3($t4);
        
$pi[3] = self::ge_p3_to_cached($p4);

        
//        ge25519_add_cached(&t5, p, &pi[4 - 1]);
        //        ge25519_p1p1_to_p3(&p5, &t5);
        //        ge25519_p3_to_cached(&pi[5 - 1], &p5); /* 5p = 4p+p */
        
$t5 self::ge_add($p$pi[3]);
        
$p5 self::ge_p1p1_to_p3($t5);
        
$pi[4] = self::ge_p3_to_cached($p5);

        
//        ge25519_p3_dbl(&t6, &p3);
        //        ge25519_p1p1_to_p3(&p6, &t6);
        //        ge25519_p3_to_cached(&pi[6 - 1], &p6); /* 6p = 2*3p */
        
$t6 self::ge_p3_dbl($p3);
        
$p6 self::ge_p1p1_to_p3($t6);
        
$pi[5] = self::ge_p3_to_cached($p6);

        
//        ge25519_add_cached(&t7, p, &pi[6 - 1]);
        //        ge25519_p1p1_to_p3(&p7, &t7);
        //        ge25519_p3_to_cached(&pi[7 - 1], &p7); /* 7p = 6p+p */
        
$t7 self::ge_add($p$pi[5]);
        
$p7 self::ge_p1p1_to_p3($t7);
        
$pi[6] = self::ge_p3_to_cached($p7);

        
//        ge25519_p3_dbl(&t8, &p4);
        //        ge25519_p1p1_to_p3(&p8, &t8);
        //        ge25519_p3_to_cached(&pi[8 - 1], &p8); /* 8p = 2*4p */
        
$t8 self::ge_p3_dbl($p4);
        
$p8 self::ge_p1p1_to_p3($t8);
        
$pi[7] = self::ge_p3_to_cached($p8);


        
//        for (i = 0; i < 32; ++i) {
        //            e[2 * i + 0] = (a[i] >> 0) & 15;
        //            e[2 * i + 1] = (a[i] >> 4) & 15;
        //        }
        
for ($i 0$i 32; ++$i) {
            
$e[($i << 1)    ] =  self::chrToInt($a[$i]) & 15;
            
$e[($i << 1) + 1] = (self::chrToInt($a[$i]) >> 4) & 15;
        }
        
//        /* each e[i] is between 0 and 15 */
        //        /* e[63] is between 0 and 7 */

        //        carry = 0;
        //        for (i = 0; i < 63; ++i) {
        //            e[i] += carry;
        //            carry = e[i] + 8;
        //            carry >>= 4;
        //            e[i] -= carry * ((signed char) 1 << 4);
        //        }
        
$carry 0;
        for (
$i 0$i 63; ++$i) {
            
$e[$i] += $carry;
            
$carry $e[$i] + 8;
            
$carry >>= 4;
            
$e[$i] -= $carry << 4;
        }
        
//        e[63] += carry;
        //        /* each e[i] is between -8 and 8 */
        
$e[63] += $carry;

        
//        ge25519_p3_0(h);
        
$h self::ge_p3_0();

        
//        for (i = 63; i != 0; i--) {
        
for ($i 63$i != 0; --$i) {
            
// ge25519_cmov8_cached(&t, pi, e[i]);
            
$t self::ge_cmov8_cached($pi$e[$i]);
            
// ge25519_add_cached(&r, h, &t);
            
$r self::ge_add($h$t);

            
// ge25519_p1p1_to_p2(&s, &r);
            // ge25519_p2_dbl(&r, &s);
            // ge25519_p1p1_to_p2(&s, &r);
            // ge25519_p2_dbl(&r, &s);
            // ge25519_p1p1_to_p2(&s, &r);
            // ge25519_p2_dbl(&r, &s);
            // ge25519_p1p1_to_p2(&s, &r);
            // ge25519_p2_dbl(&r, &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);
            
$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);

            
// ge25519_p1p1_to_p3(h, &r);  /* *16 */
            
$h self::ge_p1p1_to_p3($r); /* *16 */
        
}

        
//        ge25519_cmov8_cached(&t, pi, e[i]);
        //        ge25519_add_cached(&r, h, &t);
        //        ge25519_p1p1_to_p3(h, &r);
        
$t self::ge_cmov8_cached($pi$e[0]);
        
$r self::ge_add($h$t);
        return 
self::ge_p1p1_to_p3($r);
    }

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

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

        
$carry 0;
        for (
$i 0$i 63; ++$i) {
            
$e[$i] += $carry;
            
$carry $e[$i] + 8;
            
$carry >>= 4;
            
$e[$i] -= $carry << 4;
        }
        
$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 TypeError
     */
    
public static function sc_muladd($a$b$c)
    {
        
$a0 2097151 self::load_3(self::substr($a03));
        
$a1 2097151 & (self::load_4(self::substr($a24)) >> 5);
        
$a2 2097151 & (self::load_3(self::substr($a53)) >> 2);
        
$a3 2097151 & (self::load_4(self::substr($a74)) >> 7);
        
$a4 2097151 & (self::load_4(self::substr($a104)) >> 4);
        
$a5 2097151 & (self::load_3(self::substr($a133)) >> 1);
        
$a6 2097151 & (self::load_4(self::substr($a154)) >> 6);
        
$a7 2097151 & (self::load_3(self::substr($a183)) >> 3);
        
$a8 2097151 self::load_3(self::substr($a213));
        
$a9 2097151 & (self::load_4(self::substr($a234)) >> 5);
        
$a10 2097151 & (self::load_3(self::substr($a263)) >> 2);
        
$a11 = (self::load_4(self::substr($a284)) >> 7);

        
$b0 2097151 self::load_3(self::substr($b03));
        
$b1 2097151 & (self::load_4(self::substr($b24)) >> 5);
        
$b2 2097151 & (self::load_3(self::substr($b53)) >> 2);
        
$b3 2097151 & (self::load_4(self::substr($b74)) >> 7);
        
$b4 2097151 & (self::load_4(self::substr($b104)) >> 4);
        
$b5 2097151 & (self::load_3(self::substr($b133)) >> 1);
        
$b6 2097151 & (self::load_4(self::substr($b154)) >> 6);
        
$b7 2097151 & (self::load_3(self::substr($b183)) >> 3);
        
$b8 2097151 self::load_3(self::substr($b213));
        
$b9 2097151 & (self::load_4(self::substr($b234)) >> 5);
        
$b10 2097151 & (self::load_3(self::substr($b263)) >> 2);
        
$b11 = (self::load_4(self::substr($b284)) >> 7);

        
$c0 2097151 self::load_3(self::substr($c03));
        
$c1 2097151 & (self::load_4(self::substr($c24)) >> 5);
        
$c2 2097151 & (self::load_3(self::substr($c53)) >> 2);
        
$c3 2097151 & (self::load_4(self::substr($c74)) >> 7);
        
$c4 2097151 & (self::load_4(self::substr($c104)) >> 4);
        
$c5 2097151 & (self::load_3(self::substr($c133)) >> 1);
        
$c6 2097151 & (self::load_4(self::substr($c154)) >> 6);
        
$c7 2097151 & (self::load_3(self::substr($c183)) >> 3);
        
$c8 2097151 self::load_3(self::substr($c213));
        
$c9 2097151 & (self::load_4(self::substr($c234)) >> 5);
        
$c10 2097151 & (self::load_3(self::substr($c263)) >> 2);
        
$c11 = (self::load_4(self::substr($c284)) >> 7);

        
/* Can't really avoid the pyramid here: */
        
$s0 $c0 self::mul($a0$b024);
        
$s1 $c1 self::mul($a0$b124) + self::mul($a1$b024);
        
$s2 $c2 self::mul($a0$b224) + self::mul($a1$b124) + self::mul($a2$b024);
        
$s3 $c3 self::mul($a0$b324) + self::mul($a1$b224) + self::mul($a2$b124) + self::mul($a3$b024);
        
$s4 $c4 self::mul($a0$b424) + self::mul($a1$b324) + self::mul($a2$b224) + self::mul($a3$b124) +
               
self::mul($a4$b024);
        
$s5 $c5 self::mul($a0$b524) + self::mul($a1$b424) + self::mul($a2$b324) + self::mul($a3$b224) +
               
self::mul($a4$b124) + self::mul($a5$b024);
        
$s6 $c6 self::mul($a0$b624) + self::mul($a1$b524) + self::mul($a2$b424) + self::mul($a3$b324) +
               
self::mul($a4$b224) + self::mul($a5$b124) + self::mul($a6$b024);
        
$s7 $c7 self::mul($a0$b724) + self::mul($a1$b624) + self::mul($a2$b524) + self::mul($a3$b424) +
               
self::mul($a4$b324) + self::mul($a5$b224) + self::mul($a6$b124) + self::mul($a7$b024);
        
$s8 $c8 self::mul($a0$b824) + self::mul($a1$b724) + self::mul($a2$b624) + self::mul($a3$b524) +
               
self::mul($a4$b424) + self::mul($a5$b324) + self::mul($a6$b224) + self::mul($a7$b124) +
               
self::mul($a8$b024);
        
$s9 $c9 self::mul($a0$b924) + self::mul($a1$b824) + self::mul($a2$b724) + self::mul($a3$b624) +
               
self::mul($a4$b524) + self::mul($a5$b424) + self::mul($a6$b324) + self::mul($a7$b224) +
               
self::mul($a8$b124) + self::mul($a9$b024);
        
$s10 $c10 self::mul($a0$b1024) + self::mul($a1$b924) + self::mul($a2$b824) + self::mul($a3$b724) +
               
self::mul($a4$b624) + self::mul($a5$b524) + self::mul($a6$b424) + self::mul($a7$b324) +
               
self::mul($a8$b224) + self::mul($a9$b124) + self::mul($a10$b024);
        
$s11 $c11 self::mul($a0$b1124) + self::mul($a1$b1024) + self::mul($a2$b924) + self::mul($a3$b824) +
               
self::mul($a4$b724) + self::mul($a5$b624) + self::mul($a6$b524) + self::mul($a7$b424) +
               
self::mul($a8$b324) + self::mul($a9$b224) + self::mul($a10$b124) + self::mul($a11$b024);
        
$s12 self::mul($a1$b1124) + self::mul($a2$b1024) + self::mul($a3$b924) + self::mul($a4$b824) +
               
self::mul($a5$b724) + self::mul($a6$b624) + self::mul($a7$b524) + self::mul($a8$b424) +
               
self::mul($a9$b324) + self::mul($a10$b224) + self::mul($a11$b124);
        
$s13 self::mul($a2$b1124) + self::mul($a3$b1024) + self::mul($a4$b924) + self::mul($a5$b824) +
               
self::mul($a6$b724) + self::mul($a7$b624) + self::mul($a8$b524) + self::mul($a9$b424) +
               
self::mul($a10$b324) + self::mul($a11$b224);
        
$s14 self::mul($a3$b1124) + self::mul($a4$b1024) + self::mul($a5$b924) + self::mul($a6$b824) +
               
self::mul($a7$b724) + self::mul($a8$b624) + self::mul($a9$b524) + self::mul($a10$b424) +
               
self::mul($a11$b324);
        
$s15 self::mul($a4$b1124) + self::mul($a5$b1024) + self::mul($a6$b924) + self::mul($a7$b824) +
               
self::mul($a8$b724) + self::mul($a9$b624) + self::mul($a10$b524) + self::mul($a11$b424);
        
$s16 self::mul($a5$b1124) + self::mul($a6$b1024) + self::mul($a7$b924) + self::mul($a8$b824) +
               
self::mul($a9$b724) + self::mul($a10$b624) + self::mul($a11$b524);
        
$s17 self::mul($a6$b1124) + self::mul($a7$b1024) + self::mul($a8$b924) + self::mul($a9$b824) +
               
self::mul($a10$b724) + self::mul($a11$b624);
        
$s18 self::mul($a7$b1124) + self::mul($a8$b1024) + self::mul($a9$b924) + self::mul($a10$b824) +
               
self::mul($a11$b724);
        
$s19 self::mul($a8$b1124) + self::mul($a9$b1024) + self::mul($a10$b924) + self::mul($a11$b824);
        
$s20 self::mul($a9$b1124) + self::mul($a10$b1024) + self::mul($a11$b924);
        
$s21 self::mul($a10$b1124) + self::mul($a11$b1024);
        
$s22 self::mul($a11$b1124);
        
$s23 0;

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

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

        
$s11 += self::mul($s2366664320);
        
$s12 += self::mul($s2347029619);
        
$s13 += self::mul($s2365418320);
        
$s14 -= self::mul($s2399780520);
        
$s15 += self::mul($s2313665718);
        
$s16 -= self::mul($s2368390120);

        
$s10 += self::mul($s2266664320);
        
$s11 += self::mul($s2247029619);
        
$s12 += self::mul($s2265418320);
        
$s13 -= self::mul($s2299780520);
        
$s14 += self::mul($s2213665718);
        
$s15 -= self::mul($s2268390120);

        
$s9  += self::mul($s21,  66664320);
        
$s10 += self::mul($s21,  47029619);
        
$s11 += self::mul($s21,  65418320);
        
$s12 -= self::mul($s21,  99780520);
        
$s13 += self::mul($s21,  13665718);
        
$s14 -= self::mul($s21,  68390120);

        
$s8  += self::mul($s20,  66664320);
        
$s9  += self::mul($s20,  47029619);
        
$s10 += self::mul($s20,  65418320);
        
$s11 -= self::mul($s20,  99780520);
        
$s12 += self::mul($s20,  13665718);
        
$s13 -= self::mul($s20,  68390120);

        
$s7  += self::mul($s19,  66664320);
        
$s8  += self::mul($s19,  47029619);
        
$s9  += self::mul($s19,  65418320);
        
$s10 -= self::mul($s19,  99780520);
        
$s11 += self::mul($s19,  13665718);
        
$s12 -= self::mul($s19,  68390120);

        
$s6  += self::mul($s18,  66664320);
        
$s7  += self::mul($s18,  47029619);
        
$s8  += self::mul($s18,  65418320);
        
$s9  -= self::mul($s18,  99780520);
        
$s10 += self::mul($s18,  13665718);
        
$s11 -= self::mul($s18,  68390120);

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

        
$carry7 = ($s7 + (<< 20)) >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
$carry9 = ($s9 + (<< 20)) >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
$carry11 = ($s11 + (<< 20)) >> 21;
        
$s12 += $carry11;
        
$s11 -= $carry11 << 21;
        
$carry13 = ($s13 + (<< 20)) >> 21;
        
$s14 += $carry13;
        
$s13 -= $carry13 << 21;
        
$carry15 = ($s15 + (<< 20)) >> 21;
        
$s16 += $carry15;
        
$s15 -= $carry15 << 21;

        
$s5  += self::mul($s17,  66664320);
        
$s6  += self::mul($s17,  47029619);
        
$s7  += self::mul($s17,  65418320);
        
$s8  -= self::mul($s17,  99780520);
        
$s9  += self::mul($s17,  13665718);
        
$s10 -= self::mul($s17,  68390120);

        
$s4 += self::mul($s16,  66664320);
        
$s5 += self::mul($s16,  47029619);
        
$s6 += self::mul($s16,  65418320);
        
$s7 -= self::mul($s16,  99780520);
        
$s8 += self::mul($s16,  13665718);
        
$s9 -= self::mul($s16,  68390120);

        
$s3 += self::mul($s15,  66664320);
        
$s4 += self::mul($s15,  47029619);
        
$s5 += self::mul($s15,  65418320);
        
$s6 -= self::mul($s15,  99780520);
        
$s7 += self::mul($s15,  13665718);
        
$s8 -= self::mul($s15,  68390120);

        
$s2 += self::mul($s14,  66664320);
        
$s3 += self::mul($s14,  47029619);
        
$s4 += self::mul($s14,  65418320);
        
$s5 -= self::mul($s14,  99780520);
        
$s6 += self::mul($s14,  13665718);
        
$s7 -= self::mul($s14,  68390120);

        
$s1 += self::mul($s13,  66664320);
        
$s2 += self::mul($s13,  47029619);
        
$s3 += self::mul($s13,  65418320);
        
$s4 -= self::mul($s13,  99780520);
        
$s5 += self::mul($s13,  13665718);
        
$s6 -= self::mul($s13,  68390120);

        
$s0 += self::mul($s12,  66664320);
        
$s1 += self::mul($s12,  47029619);
        
$s2 += self::mul($s12,  65418320);
        
$s3 -= self::mul($s12,  99780520);
        
$s4 += self::mul($s12,  13665718);
        
$s5 -= self::mul($s12,  68390120);
        
$s12 0;

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

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

        
$s0 += self::mul($s12,  66664320);
        
$s1 += self::mul($s12,  47029619);
        
$s2 += self::mul($s12,  65418320);
        
$s3 -= self::mul($s12,  99780520);
        
$s4 += self::mul($s12,  13665718);
        
$s5 -= self::mul($s12,  68390120);
        
$s12 0;

        
$carry0 $s0 >> 21;
        
$s1 += $carry0;
        
$s0 -= $carry0 << 21;
        
$carry1 $s1 >> 21;
        
$s2 += $carry1;
        
$s1 -= $carry1 << 21;
        
$carry2 $s2 >> 21;
        
$s3 += $carry2;
        
$s2 -= $carry2 << 21;
        
$carry3 $s3 >> 21;
        
$s4 += $carry3;
        
$s3 -= $carry3 << 21;
        
$carry4 $s4 >> 21;
        
$s5 += $carry4;
        
$s4 -= $carry4 << 21;
        
$carry5 $s5 >> 21;
        
$s6 += $carry5;
        
$s5 -= $carry5 << 21;
        
$carry6 $s6 >> 21;
        
$s7 += $carry6;
        
$s6 -= $carry6 << 21;
        
$carry7 $s7 >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
$carry8 $s8 >> 21;
        
$s9 += $carry8;
        
$s8 -= $carry8 << 21;
        
$carry9 $s9 >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
$carry10 $s10 >> 21;
        
$s11 += $carry10;
        
$s10 -= $carry10 << 21;
        
$carry11 $s11 >> 21;
        
$s12 += $carry11;
        
$s11 -= $carry11 << 21;

        
$s0 += self::mul($s12,  66664320);
        
$s1 += self::mul($s12,  47029619);
        
$s2 += self::mul($s12,  65418320);
        
$s3 -= self::mul($s12,  99780520);
        
$s4 += self::mul($s12,  13665718);
        
$s5 -= self::mul($s12,  68390120);

        
$carry0 $s0 >> 21;
        
$s1 += $carry0;
        
$s0 -= $carry0 << 21;
        
$carry1 $s1 >> 21;
        
$s2 += $carry1;
        
$s1 -= $carry1 << 21;
        
$carry2 $s2 >> 21;
        
$s3 += $carry2;
        
$s2 -= $carry2 << 21;
        
$carry3 $s3 >> 21;
        
$s4 += $carry3;
        
$s3 -= $carry3 << 21;
        
$carry4 $s4 >> 21;
        
$s5 += $carry4;
        
$s4 -= $carry4 << 21;
        
$carry5 $s5 >> 21;
        
$s6 += $carry5;
        
$s5 -= $carry5 << 21;
        
$carry6 $s6 >> 21;
        
$s7 += $carry6;
        
$s6 -= $carry6 << 21;
        
$carry7 $s7 >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
$carry8 $s8 >> 21;
        
$s9 += $carry8;
        
$s8 -= $carry8 << 21;
        
$carry9 $s9 >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
$carry10 $s10 >> 21;
        
$s11 += $carry10;
        
$s10 -= $carry10 << 21;

        
/**
         * @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)),
            
0xff & ($s11 >> 17)
        );
        return 
self::intArrayToString($arr);
    }

    
/**
     * @internal You should not use this directly from another application
     *
     * @param string $s
     * @return string
     * @throws TypeError
     */
    
public static function sc_reduce($s)
    {
        
$s0 2097151 self::load_3(self::substr($s03));
        
$s1 2097151 & (self::load_4(self::substr($s24)) >> 5);
        
$s2 2097151 & (self::load_3(self::substr($s53)) >> 2);
        
$s3 2097151 & (self::load_4(self::substr($s74)) >> 7);
        
$s4 2097151 & (self::load_4(self::substr($s104)) >> 4);
        
$s5 2097151 & (self::load_3(self::substr($s133)) >> 1);
        
$s6 2097151 & (self::load_4(self::substr($s154)) >> 6);
        
$s7 2097151 & (self::load_3(self::substr($s184)) >> 3);
        
$s8 2097151 self::load_3(self::substr($s213));
        
$s9 2097151 & (self::load_4(self::substr($s234)) >> 5);
        
$s10 2097151 & (self::load_3(self::substr($s263)) >> 2);
        
$s11 2097151 & (self::load_4(self::substr($s284)) >> 7);
        
$s12 2097151 & (self::load_4(self::substr($s314)) >> 4);
        
$s13 2097151 & (self::load_3(self::substr($s343)) >> 1);
        
$s14 2097151 & (self::load_4(self::substr($s364)) >> 6);
        
$s15 2097151 & (self::load_3(self::substr($s394)) >> 3);
        
$s16 2097151 self::load_3(self::substr($s423));
        
$s17 2097151 & (self::load_4(self::substr($s444)) >> 5);
        
$s18 2097151 & (self::load_3(self::substr($s473)) >> 2);
        
$s19 2097151 & (self::load_4(self::substr($s494)) >> 7);
        
$s20 2097151 & (self::load_4(self::substr($s524)) >> 4);
        
$s21 2097151 & (self::load_3(self::substr($s553)) >> 1);
        
$s22 2097151 & (self::load_4(self::substr($s574)) >> 6);
        
$s23 0x1fffffff & (self::load_4(self::substr($s604)) >> 3);

        
$s11 += self::mul($s23,  66664320);
        
$s12 += self::mul($s23,  47029619);
        
$s13 += self::mul($s23,  65418320);
        
$s14 -= self::mul($s23,  99780520);
        
$s15 += self::mul($s23,  13665718);
        
$s16 -= self::mul($s23,  68390120);

        
$s10 += self::mul($s22,  66664320);
        
$s11 += self::mul($s22,  47029619);
        
$s12 += self::mul($s22,  65418320);
        
$s13 -= self::mul($s22,  99780520);
        
$s14 += self::mul($s22,  13665718);
        
$s15 -= self::mul($s22,  68390120);

        
$s9  += self::mul($s21,  66664320);
        
$s10 += self::mul($s21,  47029619);
        
$s11 += self::mul($s21,  65418320);
        
$s12 -= self::mul($s21,  99780520);
        
$s13 += self::mul($s21,  13665718);
        
$s14 -= self::mul($s21,  68390120);

        
$s8  += self::mul($s20,  66664320);
        
$s9  += self::mul($s20,  47029619);
        
$s10 += self::mul($s20,  65418320);
        
$s11 -= self::mul($s20,  99780520);
        
$s12 += self::mul($s20,  13665718);
        
$s13 -= self::mul($s20,  68390120);

        
$s7  += self::mul($s19,  66664320);
        
$s8  += self::mul($s19,  47029619);
        
$s9  += self::mul($s19,  65418320);
        
$s10 -= self::mul($s19,  99780520);
        
$s11 += self::mul($s19,  13665718);
        
$s12 -= self::mul($s19,  68390120);

        
$s6  += self::mul($s18,  66664320);
        
$s7  += self::mul($s18,  47029619);
        
$s8  += self::mul($s18,  65418320);
        
$s9  -= self::mul($s18,  99780520);
        
$s10 += self::mul($s18,  13665718);
        
$s11 -= self::mul($s18,  68390120);

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

        
$carry7 = ($s7 + (<< 20)) >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
$carry9 = ($s9 + (<< 20)) >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
$carry11 = ($s11 + (<< 20)) >> 21;
        
$s12 += $carry11;
        
$s11 -= $carry11 << 21;
        
$carry13 = ($s13 + (<< 20)) >> 21;
        
$s14 += $carry13;
        
$s13 -= $carry13 << 21;
        
$carry15 = ($s15 + (<< 20)) >> 21;
        
$s16 += $carry15;
        
$s15 -= $carry15 << 21;

        
$s5  += self::mul($s17,  66664320);
        
$s6  += self::mul($s17,  47029619);
        
$s7  += self::mul($s17,  65418320);
        
$s8  -= self::mul($s17,  99780520);
        
$s9  += self::mul($s17,  13665718);
        
$s10 -= self::mul($s17,  68390120);

        
$s4 += self::mul($s16,  66664320);
        
$s5 += self::mul($s16,  47029619);
        
$s6 += self::mul($s16,  65418320);
        
$s7 -= self::mul($s16,  99780520);
        
$s8 += self::mul($s16,  13665718);
        
$s9 -= self::mul($s16,  68390120);

        
$s3 += self::mul($s15,  66664320);
        
$s4 += self::mul($s15,  47029619);
        
$s5 += self::mul($s15,  65418320);
        
$s6 -= self::mul($s15,  99780520);
        
$s7 += self::mul($s15,  13665718);
        
$s8 -= self::mul($s15,  68390120);

        
$s2 += self::mul($s14,  66664320);
        
$s3 += self::mul($s14,  47029619);
        
$s4 += self::mul($s14,  65418320);
        
$s5 -= self::mul($s14,  99780520);
        
$s6 += self::mul($s14,  13665718);
        
$s7 -= self::mul($s14,  68390120);

        
$s1 += self::mul($s13,  66664320);
        
$s2 += self::mul($s13,  47029619);
        
$s3 += self::mul($s13,  65418320);
        
$s4 -= self::mul($s13,  99780520);
        
$s5 += self::mul($s13,  13665718);
        
$s6 -= self::mul($s13,  68390120);

        
$s0 += self::mul($s12,  66664320);
        
$s1 += self::mul($s12,  47029619);
        
$s2 += self::mul($s12,  65418320);
        
$s3 -= self::mul($s12,  99780520);
        
$s4 += self::mul($s12,  13665718);
        
$s5 -= self::mul($s12,  68390120);
        
$s12 0;

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

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

        
$s0 += self::mul($s12,  66664320);
        
$s1 += self::mul($s12,  47029619);
        
$s2 += self::mul($s12,  65418320);
        
$s3 -= self::mul($s12,  99780520);
        
$s4 += self::mul($s12,  13665718);
        
$s5 -= self::mul($s12,  68390120);
        
$s12 0;

        
$carry0 $s0 >> 21;
        
$s1 += $carry0;
        
$s0 -= $carry0 << 21;
        
$carry1 $s1 >> 21;
        
$s2 += $carry1;
        
$s1 -= $carry1 << 21;
        
$carry2 $s2 >> 21;
        
$s3 += $carry2;
        
$s2 -= $carry2 << 21;
        
$carry3 $s3 >> 21;
        
$s4 += $carry3;
        
$s3 -= $carry3 << 21;
        
$carry4 $s4 >> 21;
        
$s5 += $carry4;
        
$s4 -= $carry4 << 21;
        
$carry5 $s5 >> 21;
        
$s6 += $carry5;
        
$s5 -= $carry5 << 21;
        
$carry6 $s6 >> 21;
        
$s7 += $carry6;
        
$s6 -= $carry6 << 21;
        
$carry7 $s7 >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
$carry8 $s8 >> 21;
        
$s9 += $carry8;
        
$s8 -= $carry8 << 21;
        
$carry9 $s9 >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
$carry10 $s10 >> 21;
        
$s11 += $carry10;
        
$s10 -= $carry10 << 21;
        
$carry11 $s11 >> 21;
        
$s12 += $carry11;
        
$s11 -= $carry11 << 21;

        
$s0 += self::mul($s12,  66664320);
        
$s1 += self::mul($s12,  47029619);
        
$s2 += self::mul($s12,  65418320);
        
$s3 -= self::mul($s12,  99780520);
        
$s4 += self::mul($s12,  13665718);
        
$s5 -= self::mul($s12,  68390120);

        
$carry0 $s0 >> 21;
        
$s1 += $carry0;
        
$s0 -= $carry0 << 21;
        
$carry1 $s1 >> 21;
        
$s2 += $carry1;
        
$s1 -= $carry1 << 21;
        
$carry2 $s2 >> 21;
        
$s3 += $carry2;
        
$s2 -= $carry2 << 21;
        
$carry3 $s3 >> 21;
        
$s4 += $carry3;
        
$s3 -= $carry3 << 21;
        
$carry4 $s4 >> 21;
        
$s5 += $carry4;
        
$s4 -= $carry4 << 21;
        
$carry5 $s5 >> 21;
        
$s6 += $carry5;
        
$s5 -= $carry5 << 21;
        
$carry6 $s6 >> 21;
        
$s7 += $carry6;
        
$s6 -= $carry6 << 21;
        
$carry7 $s7 >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
$carry8 $s8 >> 21;
        
$s9 += $carry8;
        
$s8 -= $carry8 << 21;
        
$carry9 $s9 >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
$carry10 $s10 >> 21;
        
$s11 += $carry10;
        
$s10 -= $carry10 << 21;

        
/**
         * @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_Core_Curve25519_Ge_P3 $A
     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3
     */
    
public static function ge_mul_l(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A)
    {
        
$aslide = array(
            
130000, -10000, -11000000, -5000,
            
000, -30000, -13000070000030,
            
000, -13000050000000011000,
            
00110000, -13000000, -300000, -1,
            
000030000, -11000000015000,
            
00, -10000, -100007000050000,
            
00000000000000000000000,
            
00000000000000000000000,
            
00000000000000000000000,
            
00000000000000000000000,
            
00000000000000000000000,
            
00000000001
        
);

        
/** @var array<int, ParagonIE_Sodium_Core_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);
    }

    
/**
     * @param string $a
     * @param string $b
     * @return string
     */
    
public static function sc25519_mul($a$b)
    {
        
//    int64_t a0  = 2097151 & load_3(a);
        //    int64_t a1  = 2097151 & (load_4(a + 2) >> 5);
        //    int64_t a2  = 2097151 & (load_3(a + 5) >> 2);
        //    int64_t a3  = 2097151 & (load_4(a + 7) >> 7);
        //    int64_t a4  = 2097151 & (load_4(a + 10) >> 4);
        //    int64_t a5  = 2097151 & (load_3(a + 13) >> 1);
        //    int64_t a6  = 2097151 & (load_4(a + 15) >> 6);
        //    int64_t a7  = 2097151 & (load_3(a + 18) >> 3);
        //    int64_t a8  = 2097151 & load_3(a + 21);
        //    int64_t a9  = 2097151 & (load_4(a + 23) >> 5);
        //    int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
        //    int64_t a11 = (load_4(a + 28) >> 7);
        
$a0  2097151 &  self::load_3(self::substr($a03));
        
$a1  2097151 & (self::load_4(self::substr($a24)) >> 5);
        
$a2  2097151 & (self::load_3(self::substr($a53)) >> 2);
        
$a3  2097151 & (self::load_4(self::substr($a74)) >> 7);
        
$a4  2097151 & (self::load_4(self::substr($a104)) >> 4);
        
$a5  2097151 & (self::load_3(self::substr($a133)) >> 1);
        
$a6  2097151 & (self::load_4(self::substr($a154)) >> 6);
        
$a7  2097151 & (self::load_3(self::substr($a183)) >> 3);
        
$a8  2097151 &  self::load_3(self::substr($a213));
        
$a9  2097151 & (self::load_4(self::substr($a234)) >> 5);
        
$a10 2097151 & (self::load_3(self::substr($a263)) >> 2);
        
$a11 = (self::load_4(self::substr($a284)) >> 7);

        
//    int64_t b0  = 2097151 & load_3(b);
        //    int64_t b1  = 2097151 & (load_4(b + 2) >> 5);
        //    int64_t b2  = 2097151 & (load_3(b + 5) >> 2);
        //    int64_t b3  = 2097151 & (load_4(b + 7) >> 7);
        //    int64_t b4  = 2097151 & (load_4(b + 10) >> 4);
        //    int64_t b5  = 2097151 & (load_3(b + 13) >> 1);
        //    int64_t b6  = 2097151 & (load_4(b + 15) >> 6);
        //    int64_t b7  = 2097151 & (load_3(b + 18) >> 3);
        //    int64_t b8  = 2097151 & load_3(b + 21);
        //    int64_t b9  = 2097151 & (load_4(b + 23) >> 5);
        //    int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
        //    int64_t b11 = (load_4(b + 28) >> 7);
        
$b0  2097151 &  self::load_3(self::substr($b03));
        
$b1  2097151 & (self::load_4(self::substr($b24)) >> 5);
        
$b2  2097151 & (self::load_3(self::substr($b53)) >> 2);
        
$b3  2097151 & (self::load_4(self::substr($b74)) >> 7);
        
$b4  2097151 & (self::load_4(self::substr($b104)) >> 4);
        
$b5  2097151 & (self::load_3(self::substr($b133)) >> 1);
        
$b6  2097151 & (self::load_4(self::substr($b154)) >> 6);
        
$b7  2097151 & (self::load_3(self::substr($b183)) >> 3);
        
$b8  2097151 &  self::load_3(self::substr($b213));
        
$b9  2097151 & (self::load_4(self::substr($b234)) >> 5);
        
$b10 2097151 & (self::load_3(self::substr($b263)) >> 2);
        
$b11 = (self::load_4(self::substr($b284)) >> 7);

        
//    s0 = a0 * b0;
        //    s1 = a0 * b1 + a1 * b0;
        //    s2 = a0 * b2 + a1 * b1 + a2 * b0;
        //    s3 = a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
        //    s4 = a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
        //    s5 = a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
        //    s6 = a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
        //    s7 = a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 +
        //        a6 * b1 + a7 * b0;
        //    s8 = a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 +
        //        a6 * b2 + a7 * b1 + a8 * b0;
        //    s9 = a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 +
        //        a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
        //    s10 = a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 +
        //        a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
        //    s11 = a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 +
        //        a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
        //    s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 +
        //        a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
        //    s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 +
        //        a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2;
        //    s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 +
        //        a9 * b5 + a10 * b4 + a11 * b3;
        //    s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 +
        //        a10 * b5 + a11 * b4;
        //    s16 =
        //        a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
        //    s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
        //    s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
        //    s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
        //    s20 = a9 * b11 + a10 * b10 + a11 * b9;
        //    s21 = a10 * b11 + a11 * b10;
        //    s22 = a11 * b11;
        //    s23 = 0;
        
$s0 self::mul($a0$b022);
        
$s1 self::mul($a0$b122) + self::mul($a1$b022);
        
$s2 self::mul($a0$b222) + self::mul($a1$b122) + self::mul($a2$b022);
        
$s3 self::mul($a0$b322) + self::mul($a1$b222) + self::mul($a2$b122) + self::mul($a3$b022);
        
$s4 self::mul($a0$b422) + self::mul($a1$b322) + self::mul($a2$b222) + self::mul($a3$b122) +
            
self::mul($a4$b022);
        
$s5 self::mul($a0$b522) + self::mul($a1$b422) + self::mul($a2$b322) + self::mul($a3$b222) +
            
self::mul($a4$b122) + self::mul($a5$b022);
        
$s6 self::mul($a0$b622) + self::mul($a1$b522) + self::mul($a2$b422) + self::mul($a3$b322) +
            
self::mul($a4$b222) + self::mul($a5$b122) + self::mul($a6$b022);
        
$s7 self::mul($a0$b722) + self::mul($a1$b622) + self::mul($a2$b522) + self::mul($a3$b422) +
            
self::mul($a4$b322) + self::mul($a5$b222) + self::mul($a6$b122) + self::mul($a7$b022);
        
$s8 self::mul($a0$b822) + self::mul($a1$b722) + self::mul($a2$b622) + self::mul($a3$b522) +
            
self::mul($a4$b422) + self::mul($a5$b322) + self::mul($a6$b222) + self::mul($a7$b122) +
            
self::mul($a8$b022);
        
$s9 self::mul($a0$b922) + self::mul($a1$b822) + self::mul($a2$b722) + self::mul($a3$b622) +
            
self::mul($a4$b522) + self::mul($a5$b422) + self::mul($a6$b322) + self::mul($a7$b222) +
            
self::mul($a8$b122) + self::mul($a9$b022);
        
$s10 self::mul($a0$b1022) + self::mul($a1$b922) + self::mul($a2$b822) + self::mul($a3$b722) +
            
self::mul($a4$b622) + self::mul($a5$b522) + self::mul($a6$b422) + self::mul($a7$b322) +
            
self::mul($a8$b222) + self::mul($a9$b122) + self::mul($a10$b022);
        
$s11 self::mul($a0$b1122) + self::mul($a1$b1022) + self::mul($a2$b922) + self::mul($a3$b822) +
            
self::mul($a4$b722) + self::mul($a5$b622) + self::mul($a6$b522) + self::mul($a7$b422) +
            
self::mul($a8$b322) + self::mul($a9$b222) + self::mul($a10$b122) + self::mul($a11$b022);
        
$s12 self::mul($a1$b1122) + self::mul($a2$b1022) + self::mul($a3$b922) + self::mul($a4$b822) +
            
self::mul($a5$b722) + self::mul($a6$b622) + self::mul($a7$b522) + self::mul($a8$b422) +
            
self::mul($a9$b322) + self::mul($a10$b222) + self::mul($a11$b122);
        
$s13 self::mul($a2$b1122) + self::mul($a3$b1022) + self::mul($a4$b922) + self::mul($a5$b822) +
            
self::mul($a6$b722) + self::mul($a7$b622) + self::mul($a8$b522) + self::mul($a9$b422) +
            
self::mul($a10$b322) + self::mul($a11$b222);
        
$s14 self::mul($a3$b1122) + self::mul($a4$b1022) + self::mul($a5$b922) + self::mul($a6$b822) +
            
self::mul($a7$b722) + self::mul($a8$b622) + self::mul($a9$b522) + self::mul($a10$b422) +
            
self::mul($a11$b322);
        
$s15 self::mul($a4$b1122) + self::mul($a5$b1022) + self::mul($a6$b922) + self::mul($a7$b822) +
            
self::mul($a8$b722) + self::mul($a9$b622) + self::mul($a10$b522) + self::mul($a11$b422);
        
$s16 =
            
self::mul($a5$b1122) + self::mul($a6$b1022) + self::mul($a7$b922) + self::mul($a8$b822) +
            
self::mul($a9$b722) + self::mul($a10$b622) + self::mul($a11$b522);
        
$s17 self::mul($a6$b1122) + self::mul($a7$b1022) + self::mul($a8$b922) + self::mul($a9$b822) +
            
self::mul($a10$b722) + self::mul($a11$b622);
        
$s18 self::mul($a7$b1122) + self::mul($a8$b1022) + self::mul($a9$b922) + self::mul($a10$b822)
            + 
self::mul($a11$b722);
        
$s19 self::mul($a8$b1122) + self::mul($a9$b1022) + self::mul($a10$b922) +
            
self::mul($a11$b822);
        
$s20 self::mul($a9$b1122) + self::mul($a10$b1022) + self::mul($a11$b922);
        
$s21 self::mul($a10$b1122) + self::mul($a11$b1022);
        
$s22 self::mul($a11$b1122);
        
$s23 0;

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

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

        
//    s11 += s23 * 666643;
        //    s12 += s23 * 470296;
        //    s13 += s23 * 654183;
        //    s14 -= s23 * 997805;
        //    s15 += s23 * 136657;
        //    s16 -= s23 * 683901;
        
$s11 += self::mul($s2366664320);
        
$s12 += self::mul($s2347029619);
        
$s13 += self::mul($s2365418320);
        
$s14 -= self::mul($s2399780520);
        
$s15 += self::mul($s2313665718);
        
$s16 -= self::mul($s2368390120);

        
//    s10 += s22 * 666643;
        //    s11 += s22 * 470296;
        //    s12 += s22 * 654183;
        //    s13 -= s22 * 997805;
        //    s14 += s22 * 136657;
        //    s15 -= s22 * 683901;
        
$s10 += self::mul($s2266664320);
        
$s11 += self::mul($s2247029619);
        
$s12 += self::mul($s2265418320);
        
$s13 -= self::mul($s2299780520);
        
$s14 += self::mul($s2213665718);
        
$s15 -= self::mul($s2268390120);

        
//    s9 += s21 * 666643;
        //    s10 += s21 * 470296;
        //    s11 += s21 * 654183;
        //    s12 -= s21 * 997805;
        //    s13 += s21 * 136657;
        //    s14 -= s21 * 683901;
        
$s9 += self::mul($s2166664320);
        
$s10 += self::mul($s2147029619);
        
$s11 += self::mul($s2165418320);
        
$s12 -= self::mul($s2199780520);
        
$s13 += self::mul($s2113665718);
        
$s14 -= self::mul($s2168390120);

        
//    s8 += s20 * 666643;
        //    s9 += s20 * 470296;
        //    s10 += s20 * 654183;
        //    s11 -= s20 * 997805;
        //    s12 += s20 * 136657;
        //    s13 -= s20 * 683901;
        
$s8 += self::mul($s2066664320);
        
$s9 += self::mul($s2047029619);
        
$s10 += self::mul($s2065418320);
        
$s11 -= self::mul($s2099780520);
        
$s12 += self::mul($s2013665718);
        
$s13 -= self::mul($s2068390120);

        
//    s7 += s19 * 666643;
        //    s8 += s19 * 470296;
        //    s9 += s19 * 654183;
        //    s10 -= s19 * 997805;
        //    s11 += s19 * 136657;
        //    s12 -= s19 * 683901;
        
$s7 += self::mul($s1966664320);
        
$s8 += self::mul($s1947029619);
        
$s9 += self::mul($s1965418320);
        
$s10 -= self::mul($s1999780520);
        
$s11 += self::mul($s1913665718);
        
$s12 -= self::mul($s1968390120);

        
//    s6 += s18 * 666643;
        //    s7 += s18 * 470296;
        //    s8 += s18 * 654183;
        //    s9 -= s18 * 997805;
        //    s10 += s18 * 136657;
        //    s11 -= s18 * 683901;
        
$s6 += self::mul($s1866664320);
        
$s7 += self::mul($s1847029619);
        
$s8 += self::mul($s1865418320);
        
$s9 -= self::mul($s1899780520);
        
$s10 += self::mul($s1813665718);
        
$s11 -= self::mul($s1868390120);

        
//    carry6 = (s6 + (int64_t) (1L << 20)) >> 21;
        //    s7 += carry6;
        //    s6 -= carry6 * ((uint64_t) 1L << 21);
        
$carry6 = ($s6 + (<< 20)) >> 21;
        
$s7 += $carry6;
        
$s6 -= $carry6 << 21;
        
//    carry8 = (s8 + (int64_t) (1L << 20)) >> 21;
        //    s9 += carry8;
        //    s8 -= carry8 * ((uint64_t) 1L << 21);
        
$carry8 = ($s8 + (<< 20)) >> 21;
        
$s9 += $carry8;
        
$s8 -= $carry8 << 21;
        
//    carry10 = (s10 + (int64_t) (1L << 20)) >> 21;
        //    s11 += carry10;
        //    s10 -= carry10 * ((uint64_t) 1L << 21);
        
$carry10 = ($s10 + (<< 20)) >> 21;
        
$s11 += $carry10;
        
$s10 -= $carry10 << 21;
        
//    carry12 = (s12 + (int64_t) (1L << 20)) >> 21;
        //    s13 += carry12;
        //    s12 -= carry12 * ((uint64_t) 1L << 21);
        
$carry12 = ($s12 + (<< 20)) >> 21;
        
$s13 += $carry12;
        
$s12 -= $carry12 << 21;
        
//    carry14 = (s14 + (int64_t) (1L << 20)) >> 21;
        //    s15 += carry14;
        //    s14 -= carry14 * ((uint64_t) 1L << 21);
        
$carry14 = ($s14 + (<< 20)) >> 21;
        
$s15 += $carry14;
        
$s14 -= $carry14 << 21;
        
//    carry16 = (s16 + (int64_t) (1L << 20)) >> 21;
        //    s17 += carry16;
        //    s16 -= carry16 * ((uint64_t) 1L << 21);
        
$carry16 = ($s16 + (<< 20)) >> 21;
        
$s17 += $carry16;
        
$s16 -= $carry16 << 21;

        
//    carry7 = (s7 + (int64_t) (1L << 20)) >> 21;
        //    s8 += carry7;
        //    s7 -= carry7 * ((uint64_t) 1L << 21);
        
$carry7 = ($s7 + (<< 20)) >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
//    carry9 = (s9 + (int64_t) (1L << 20)) >> 21;
        //    s10 += carry9;
        //    s9 -= carry9 * ((uint64_t) 1L << 21);
        
$carry9 = ($s9 + (<< 20)) >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
//    carry11 = (s11 + (int64_t) (1L << 20)) >> 21;
        //    s12 += carry11;
        //    s11 -= carry11 * ((uint64_t) 1L << 21);
        
$carry11 = ($s11 + (<< 20)) >> 21;
        
$s12 += $carry11;
        
$s11 -= $carry11 << 21;
        
//    carry13 = (s13 + (int64_t) (1L << 20)) >> 21;
        //    s14 += carry13;
        //    s13 -= carry13 * ((uint64_t) 1L << 21);
        
$carry13 = ($s13 + (<< 20)) >> 21;
        
$s14 += $carry13;
        
$s13 -= $carry13 << 21;
        
//    carry15 = (s15 + (int64_t) (1L << 20)) >> 21;
        //    s16 += carry15;
        //    s15 -= carry15 * ((uint64_t) 1L << 21);
        
$carry15 = ($s15 + (<< 20)) >> 21;
        
$s16 += $carry15;
        
$s15 -= $carry15 << 21;

        
//    s5 += s17 * 666643;
        //    s6 += s17 * 470296;
        //    s7 += s17 * 654183;
        //    s8 -= s17 * 997805;
        //    s9 += s17 * 136657;
        //    s10 -= s17 * 683901;
        
$s5 += self::mul($s1766664320);
        
$s6 += self::mul($s1747029619);
        
$s7 += self::mul($s1765418320);
        
$s8 -= self::mul($s1799780520);
        
$s9 += self::mul($s1713665718);
        
$s10 -= self::mul($s1768390120);

        
//    s4 += s16 * 666643;
        //    s5 += s16 * 470296;
        //    s6 += s16 * 654183;
        //    s7 -= s16 * 997805;
        //    s8 += s16 * 136657;
        //    s9 -= s16 * 683901;
        
$s4 += self::mul($s1666664320);
        
$s5 += self::mul($s1647029619);
        
$s6 += self::mul($s1665418320);
        
$s7 -= self::mul($s1699780520);
        
$s8 += self::mul($s1613665718);
        
$s9 -= self::mul($s1668390120);

        
//    s3 += s15 * 666643;
        //    s4 += s15 * 470296;
        //    s5 += s15 * 654183;
        //    s6 -= s15 * 997805;
        //    s7 += s15 * 136657;
        //    s8 -= s15 * 683901;
        
$s3 += self::mul($s1566664320);
        
$s4 += self::mul($s1547029619);
        
$s5 += self::mul($s1565418320);
        
$s6 -= self::mul($s1599780520);
        
$s7 += self::mul($s1513665718);
        
$s8 -= self::mul($s1568390120);

        
//    s2 += s14 * 666643;
        //    s3 += s14 * 470296;
        //    s4 += s14 * 654183;
        //    s5 -= s14 * 997805;
        //    s6 += s14 * 136657;
        //    s7 -= s14 * 683901;
        
$s2 += self::mul($s1466664320);
        
$s3 += self::mul($s1447029619);
        
$s4 += self::mul($s1465418320);
        
$s5 -= self::mul($s1499780520);
        
$s6 += self::mul($s1413665718);
        
$s7 -= self::mul($s1468390120);

        
//    s1 += s13 * 666643;
        //    s2 += s13 * 470296;
        //    s3 += s13 * 654183;
        //    s4 -= s13 * 997805;
        //    s5 += s13 * 136657;
        //    s6 -= s13 * 683901;
        
$s1 += self::mul($s1366664320);
        
$s2 += self::mul($s1347029619);
        
$s3 += self::mul($s1365418320);
        
$s4 -= self::mul($s1399780520);
        
$s5 += self::mul($s1313665718);
        
$s6 -= self::mul($s1368390120);

        
//    s0 += s12 * 666643;
        //    s1 += s12 * 470296;
        //    s2 += s12 * 654183;
        //    s3 -= s12 * 997805;
        //    s4 += s12 * 136657;
        //    s5 -= s12 * 683901;
        //    s12 = 0;
        
$s0 += self::mul($s1266664320);
        
$s1 += self::mul($s1247029619);
        
$s2 += self::mul($s1265418320);
        
$s3 -= self::mul($s1299780520);
        
$s4 += self::mul($s1213665718);
        
$s5 -= self::mul($s1268390120);
        
$s12 0;

        
//    carry0 = (s0 + (int64_t) (1L << 20)) >> 21;
        //    s1 += carry0;
        //    s0 -= carry0 * ((uint64_t) 1L << 21);
        
$carry0 = ($s0 + (<< 20)) >> 21;
        
$s1 += $carry0;
        
$s0 -= $carry0 << 21;
        
//    carry2 = (s2 + (int64_t) (1L << 20)) >> 21;
        //    s3 += carry2;
        //    s2 -= carry2 * ((uint64_t) 1L << 21);
        
$carry2 = ($s2 + (<< 20)) >> 21;
        
$s3 += $carry2;
        
$s2 -= $carry2 << 21;
        
//    carry4 = (s4 + (int64_t) (1L << 20)) >> 21;
        //    s5 += carry4;
        //    s4 -= carry4 * ((uint64_t) 1L << 21);
        
$carry4 = ($s4 + (<< 20)) >> 21;
        
$s5 += $carry4;
        
$s4 -= $carry4 << 21;
        
//    carry6 = (s6 + (int64_t) (1L << 20)) >> 21;
        //    s7 += carry6;
        //    s6 -= carry6 * ((uint64_t) 1L << 21);
        
$carry6 = ($s6 + (<< 20)) >> 21;
        
$s7 += $carry6;
        
$s6 -= $carry6 << 21;
        
//    carry8 = (s8 + (int64_t) (1L << 20)) >> 21;
        //    s9 += carry8;
        //    s8 -= carry8 * ((uint64_t) 1L << 21);
        
$carry8 = ($s8 + (<< 20)) >> 21;
        
$s9 += $carry8;
        
$s8 -= $carry8 << 21;
        
//    carry10 = (s10 + (int64_t) (1L << 20)) >> 21;
        //    s11 += carry10;
        //    s10 -= carry10 * ((uint64_t) 1L << 21);
        
$carry10 = ($s10 + (<< 20)) >> 21;
        
$s11 += $carry10;
        
$s10 -= $carry10 << 21;

        
//    carry1 = (s1 + (int64_t) (1L << 20)) >> 21;
        //    s2 += carry1;
        //    s1 -= carry1 * ((uint64_t) 1L << 21);
        
$carry1 = ($s1 + (<< 20)) >> 21;
        
$s2 += $carry1;
        
$s1 -= $carry1 << 21;
        
//    carry3 = (s3 + (int64_t) (1L << 20)) >> 21;
        //    s4 += carry3;
        //    s3 -= carry3 * ((uint64_t) 1L << 21);
        
$carry3 = ($s3 + (<< 20)) >> 21;
        
$s4 += $carry3;
        
$s3 -= $carry3 << 21;
        
//    carry5 = (s5 + (int64_t) (1L << 20)) >> 21;
        //    s6 += carry5;
        //    s5 -= carry5 * ((uint64_t) 1L << 21);
        
$carry5 = ($s5 + (<< 20)) >> 21;
        
$s6 += $carry5;
        
$s5 -= $carry5 << 21;
        
//    carry7 = (s7 + (int64_t) (1L << 20)) >> 21;
        //    s8 += carry7;
        //    s7 -= carry7 * ((uint64_t) 1L << 21);
        
$carry7 = ($s7 + (<< 20)) >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
//    carry9 = (s9 + (int64_t) (1L << 20)) >> 21;
        //    s10 += carry9;
        //    s9 -= carry9 * ((uint64_t) 1L << 21);
        
$carry9 = ($s9 + (<< 20)) >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
//    carry11 = (s11 + (int64_t) (1L << 20)) >> 21;
        //    s12 += carry11;
        //    s11 -= carry11 * ((uint64_t) 1L << 21);
        
$carry11 = ($s11 + (<< 20)) >> 21;
        
$s12 += $carry11;
        
$s11 -= $carry11 << 21;

        
//    s0 += s12 * 666643;
        //    s1 += s12 * 470296;
        //    s2 += s12 * 654183;
        //    s3 -= s12 * 997805;
        //    s4 += s12 * 136657;
        //    s5 -= s12 * 683901;
        //    s12 = 0;
        
$s0 += self::mul($s1266664320);
        
$s1 += self::mul($s1247029619);
        
$s2 += self::mul($s1265418320);
        
$s3 -= self::mul($s1299780520);
        
$s4 += self::mul($s1213665718);
        
$s5 -= self::mul($s1268390120);
        
$s12 0;

        
//    carry0 = s0 >> 21;
        //    s1 += carry0;
        //    s0 -= carry0 * ((uint64_t) 1L << 21);
        
$carry0 $s0 >> 21;
        
$s1 += $carry0;
        
$s0 -= $carry0 << 21;
        
//    carry1 = s1 >> 21;
        //    s2 += carry1;
        //    s1 -= carry1 * ((uint64_t) 1L << 21);
        
$carry1 $s1 >> 21;
        
$s2 += $carry1;
        
$s1 -= $carry1 << 21;
        
//    carry2 = s2 >> 21;
        //    s3 += carry2;
        //    s2 -= carry2 * ((uint64_t) 1L << 21);
        
$carry2 $s2 >> 21;
        
$s3 += $carry2;
        
$s2 -= $carry2 << 21;
        
//    carry3 = s3 >> 21;
        //    s4 += carry3;
        //    s3 -= carry3 * ((uint64_t) 1L << 21);
        
$carry3 $s3 >> 21;
        
$s4 += $carry3;
        
$s3 -= $carry3 << 21;
        
//    carry4 = s4 >> 21;
        //    s5 += carry4;
        //    s4 -= carry4 * ((uint64_t) 1L << 21);
        
$carry4 $s4 >> 21;
        
$s5 += $carry4;
        
$s4 -= $carry4 << 21;
        
//    carry5 = s5 >> 21;
        //    s6 += carry5;
        //    s5 -= carry5 * ((uint64_t) 1L << 21);
        
$carry5 $s5 >> 21;
        
$s6 += $carry5;
        
$s5 -= $carry5 << 21;
        
//    carry6 = s6 >> 21;
        //    s7 += carry6;
        //    s6 -= carry6 * ((uint64_t) 1L << 21);
        
$carry6 $s6 >> 21;
        
$s7 += $carry6;
        
$s6 -= $carry6 << 21;
        
//    carry7 = s7 >> 21;
        //    s8 += carry7;
        //    s7 -= carry7 * ((uint64_t) 1L << 21);
        
$carry7 $s7 >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
//    carry8 = s8 >> 21;
        //    s9 += carry8;
        //    s8 -= carry8 * ((uint64_t) 1L << 21);
        
$carry8 $s8 >> 21;
        
$s9 += $carry8;
        
$s8 -= $carry8 << 21;
        
//    carry9 = s9 >> 21;
        //    s10 += carry9;
        //    s9 -= carry9 * ((uint64_t) 1L << 21);
        
$carry9 $s9 >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
//    carry10 = s10 >> 21;
        //    s11 += carry10;
        //    s10 -= carry10 * ((uint64_t) 1L << 21);
        
$carry10 $s10 >> 21;
        
$s11 += $carry10;
        
$s10 -= $carry10 << 21;
        
//    carry11 = s11 >> 21;
        //    s12 += carry11;
        //    s11 -= carry11 * ((uint64_t) 1L << 21);
        
$carry11 $s11 >> 21;
        
$s12 += $carry11;
        
$s11 -= $carry11 << 21;

        
//    s0 += s12 * 666643;
        //    s1 += s12 * 470296;
        //    s2 += s12 * 654183;
        //    s3 -= s12 * 997805;
        //    s4 += s12 * 136657;
        //    s5 -= s12 * 683901;
        
$s0 += self::mul($s1266664320);
        
$s1 += self::mul($s1247029619);
        
$s2 += self::mul($s1265418320);
        
$s3 -= self::mul($s1299780520);
        
$s4 += self::mul($s1213665718);
        
$s5 -= self::mul($s1268390120);

        
//    carry0 = s0 >> 21;
        //    s1 += carry0;
        //    s0 -= carry0 * ((uint64_t) 1L << 21);
        
$carry0 $s0 >> 21;
        
$s1 += $carry0;
        
$s0 -= $carry0 << 21;
        
//    carry1 = s1 >> 21;
        //    s2 += carry1;
        //    s1 -= carry1 * ((uint64_t) 1L << 21);
        
$carry1 $s1 >> 21;
        
$s2 += $carry1;
        
$s1 -= $carry1 << 21;
        
//    carry2 = s2 >> 21;
        //    s3 += carry2;
        //    s2 -= carry2 * ((uint64_t) 1L << 21);
        
$carry2 $s2 >> 21;
        
$s3 += $carry2;
        
$s2 -= $carry2 << 21;
        
//    carry3 = s3 >> 21;
        //    s4 += carry3;
        //    s3 -= carry3 * ((uint64_t) 1L << 21);
        
$carry3 $s3 >> 21;
        
$s4 += $carry3;
        
$s3 -= $carry3 << 21;
        
//    carry4 = s4 >> 21;
        //    s5 += carry4;
        //    s4 -= carry4 * ((uint64_t) 1L << 21);
        
$carry4 $s4 >> 21;
        
$s5 += $carry4;
        
$s4 -= $carry4 << 21;
        
//    carry5 = s5 >> 21;
        //    s6 += carry5;
        //    s5 -= carry5 * ((uint64_t) 1L << 21);
        
$carry5 $s5 >> 21;
        
$s6 += $carry5;
        
$s5 -= $carry5 << 21;
        
//    carry6 = s6 >> 21;
        //    s7 += carry6;
        //    s6 -= carry6 * ((uint64_t) 1L << 21);
        
$carry6 $s6 >> 21;
        
$s7 += $carry6;
        
$s6 -= $carry6 << 21;
        
//    carry7 = s7 >> 21;
        //    s8 += carry7;
        //    s7 -= carry7 * ((uint64_t) 1L << 21);
        
$carry7 $s7 >> 21;
        
$s8 += $carry7;
        
$s7 -= $carry7 << 21;
        
//    carry8 = s8 >> 21;
        //    s9 += carry8;
        //    s8 -= carry8 * ((uint64_t) 1L << 21);
        
$carry8 $s8 >> 21;
        
$s9 += $carry8;
        
$s8 -= $carry8 << 21;
        
//    carry9 = s9 >> 21;
        //    s10 += carry9;
        //    s9 -= carry9 * ((uint64_t) 1L << 21);
        
$carry9 $s9 >> 21;
        
$s10 += $carry9;
        
$s9 -= $carry9 << 21;
        
//    carry10 = s10 >> 21;
        //    s11 += carry10;
        //    s10 -= carry10 * ((uint64_t) 1L << 21);
        
$carry10 $s10 >> 21;
        
$s11 += $carry10;
        
$s10 -= $carry10 << 21;

        
$s array_fill(0320);
        
// s[0]  = s0 >> 0;
        
$s[0]  = $s0 >> 0;
        
// s[1]  = s0 >> 8;
        
$s[1]  = $s0 >> 8;
        
// s[2]  = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5));
        
$s[2]  = ($s0 >> 16) | ($s1 << 5);
        
// s[3]  = s1 >> 3;
        
$s[3]  = $s1 >> 3;
        
// s[4]  = s1 >> 11;
        
$s[4]  = $s1 >> 11;
        
// s[5]  = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2));
        
$s[5]  = ($s1 >> 19) | ($s2 << 2);
        
// s[6]  = s2 >> 6;
        
$s[6]  = $s2 >> 6;
        
// s[7]  = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7));
        
$s[7]  = ($s2 >> 14) | ($s3 << 7);
        
// s[8]  = s3 >> 1;
        
$s[8]  = $s3 >> 1;
        
// s[9]  = s3 >> 9;
        
$s[9]  = $s3 >> 9;
        
// s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4));
        
$s[10] = ($s3 >> 17) | ($s4 << 4);
        
// s[11] = s4 >> 4;
        
$s[11] = $s4 >> 4;
        
// s[12] = s4 >> 12;
        
$s[12] = $s4 >> 12;
        
// s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1));
        
$s[13] = ($s4 >> 20) | ($s5 << 1);
        
// s[14] = s5 >> 7;
        
$s[14] = $s5 >> 7;
        
// s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6));
        
$s[15] = ($s5 >> 15) | ($s6 << 6);
        
// s[16] = s6 >> 2;
        
$s[16] = $s6 >> 2;
        
// s[17] = s6 >> 10;
        
$s[17] = $s6 >> 10;
        
// s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3));
        
$s[18] = ($s6 >> 18) | ($s7 << 3);
        
// s[19] = s7 >> 5;
        
$s[19] = $s7 >> 5;
        
// s[20] = s7 >> 13;
        
$s[20] = $s7 >> 13;
        
// s[21] = s8 >> 0;
        
$s[21] = $s8 >> 0;
        
// s[22] = s8 >> 8;
        
$s[22] = $s8 >> 8;
        
// s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5));
        
$s[23] = ($s8 >> 16) | ($s9 << 5);
        
// s[24] = s9 >> 3;
        
$s[24] = $s9 >> 3;
        
// s[25] = s9 >> 11;
        
$s[25] = $s9 >> 11;
        
// s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2));
        
$s[26] = ($s9 >> 19) | ($s10 << 2);
        
// s[27] = s10 >> 6;
        
$s[27] = $s10 >> 6;
        
// s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7));
        
$s[28] = ($s10 >> 14) | ($s11 << 7);
        
// s[29] = s11 >> 1;
        
$s[29] = $s11 >> 1;
        
// s[30] = s11 >> 9;
        
$s[30] = $s11 >> 9;
        
// s[31] = s11 >> 17;
        
$s[31] = $s11 >> 17;
        return 
self::intArrayToString($s);
    }

    
/**
     * @param string $s
     * @return string
     */
    
public static function sc25519_sq($s)
    {
        return 
self::sc25519_mul($s$s);
    }

    
/**
     * @param string $s
     * @param int $n
     * @param string $a
     * @return string
     */
    
public static function sc25519_sqmul($s$n$a)
    {
        for (
$i 0$i $n; ++$i) {
            
$s self::sc25519_sq($s);
        }
        return 
self::sc25519_mul($s$a);
    }

    
/**
     * @param string $s
     * @return string
     */
    
public static function sc25519_invert($s)
    {
        
$_10 self::sc25519_sq($s);
        
$_11 self::sc25519_mul($s$_10);
        
$_100 self::sc25519_mul($s$_11);
        
$_1000 self::sc25519_sq($_100);
        
$_1010 self::sc25519_mul($_10$_1000);
        
$_1011 self::sc25519_mul($s$_1010);
        
$_10000 self::sc25519_sq($_1000);
        
$_10110 self::sc25519_sq($_1011);
        
$_100000 self::sc25519_mul($_1010$_10110);
        
$_100110 self::sc25519_mul($_10000$_10110);
        
$_1000000 self::sc25519_sq($_100000);
        
$_1010000 self::sc25519_mul($_10000$_1000000);
        
$_1010011 self::sc25519_mul($_11$_1010000);
        
$_1100011 self::sc25519_mul($_10000$_1010011);
        
$_1100111 self::sc25519_mul($_100$_1100011);
        
$_1101011 self::sc25519_mul($_100$_1100111);
        
$_10010011 self::sc25519_mul($_1000000$_1010011);
        
$_10010111 self::sc25519_mul($_100$_10010011);
        
$_10111101 self::sc25519_mul($_100110$_10010111);
        
$_11010011 self::sc25519_mul($_10110$_10111101);
        
$_11100111 self::sc25519_mul($_1010000$_10010111);
        
$_11101011 self::sc25519_mul($_100$_11100111);
        
$_11110101 self::sc25519_mul($_1010$_11101011);

        
$recip self::sc25519_mul($_1011$_11110101);
        
$recip self::sc25519_sqmul($recip126$_1010011);
        
$recip self::sc25519_sqmul($recip9$_10);
        
$recip self::sc25519_mul($recip$_11110101);
        
$recip self::sc25519_sqmul($recip7$_1100111);
        
$recip self::sc25519_sqmul($recip9$_11110101);
        
$recip self::sc25519_sqmul($recip11$_10111101);
        
$recip self::sc25519_sqmul($recip8$_11100111);
        
$recip self::sc25519_sqmul($recip9$_1101011);
        
$recip self::sc25519_sqmul($recip6$_1011);
        
$recip self::sc25519_sqmul($recip14$_10010011);
        
$recip self::sc25519_sqmul($recip10$_1100011);
        
$recip self::sc25519_sqmul($recip9$_10010111);
        
$recip self::sc25519_sqmul($recip10$_11110101);
        
$recip self::sc25519_sqmul($recip8$_11010011);
        return 
self::sc25519_sqmul($recip8$_11101011);
    }

    
/**
     * @param string $s
     * @return string
     */
    
public static function clamp($s)
    {
        
$s_ self::stringToIntArray($s);
        
$s_[0] &= 248;
        
$s_[31] |= 64;
        
$s_[31] &= 128;
        return 
self::intArrayToString($s_);
    }

    
/**
     * Ensure limbs are less than 28 bits long to prevent float promotion.
     *
     * This uses a constant-time conditional swap under the hood.
     *
     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     */
    
public static function fe_normalize(ParagonIE_Sodium_Core_Curve25519_Fe $f)
    {
        
$x = (PHP_INT_SIZE << 3) - 1// 31 or 63

        
$g self::fe_copy($f);
        for (
$i 0$i 10; ++$i) {
            
$mask = -(($g[$i] >> $x) & 1);

            
/*
             * Get two candidate normalized values for $g[$i], depending on the sign of $g[$i]:
             */
            
$a $g[$i] & 0x7ffffff;
            
$b = -((-$g[$i]) & 0x7ffffff);

            
/*
             * Return the appropriate candidate value, based on the sign of the original input:
             *
             * The following is equivalent to this ternary:
             *
             * $g[$i] = (($g[$i] >> $x) & 1) ? $a : $b;
             *
             * Except what's written doesn't contain timing leaks.
             */
            
$g[$i] = ($a ^ (($a $b) & $mask));
        }
        return 
$g;
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.016 ]--