/htdocs/wp-includes/sodium_compat/src/Core/Curve25519.php
https://gitlab.com/VTTE/sitios-vtte · PHP · 1469 lines · 950 code · 83 blank · 436 comment · 37 complexity · 89d6bbc2c88f13bee1d52da8597985c2 MD5 · raw file
- <?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(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
- );
- }
- /**
- * 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(1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
- );
- }
- /**
- * 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) {
- /** @var int $x */
- $x = (($f[$i] ^ $g[$i]) & $b);
- $h[$i] = (int) ((int) ($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.');
- }
- /** @var int $h0 */
- $h0 = self::load_4($s);
- /** @var int $h1 */
- $h1 = self::load_3(self::substr($s, 4, 3)) << 6;
- /** @var int $h2 */
- $h2 = self::load_3(self::substr($s, 7, 3)) << 5;
- /** @var int $h3 */
- $h3 = self::load_3(self::substr($s, 10, 3)) << 3;
- /** @var int $h4 */
- $h4 = self::load_3(self::substr($s, 13, 3)) << 2;
- /** @var int $h5 */
- $h5 = self::load_4(self::substr($s, 16, 4));
- /** @var int $h6 */
- $h6 = self::load_3(self::substr($s, 20, 3)) << 7;
- /** @var int $h7 */
- $h7 = self::load_3(self::substr($s, 23, 3)) << 5;
- /** @var int $h8 */
- $h8 = self::load_3(self::substr($s, 26, 3)) << 4;
- /** @var int $h9 */
- $h9 = (self::load_3(self::substr($s, 29, 3)) & 8388607) << 2;
- /** @var int $carry9 */
- $carry9 = ($h9 + (1 << 24)) >> 25;
- $h0 += self::mul($carry9, 19, 5);
- $h9 -= $carry9 << 25;
- /** @var int $carry1 */
- $carry1 = ($h1 + (1 << 24)) >> 25;
- $h2 += $carry1;
- $h1 -= $carry1 << 25;
- /** @var int $carry3 */
- $carry3 = ($h3 + (1 << 24)) >> 25;
- $h4 += $carry3;
- $h3 -= $carry3 << 25;
- /** @var int $carry5 */
- $carry5 = ($h5 + (1 << 24)) >> 25;
- $h6 += $carry5;
- $h5 -= $carry5 << 25;
- /** @var int $carry7 */
- $carry7 = ($h7 + (1 << 24)) >> 25;
- $h8 += $carry7;
- $h7 -= $carry7 << 25;
- /** @var int $carry0 */
- $carry0 = ($h0 + (1 << 25)) >> 26;
- $h1 += $carry0;
- $h0 -= $carry0 << 26;
- /** @var int $carry2 */
- $carry2 = ($h2 + (1 << 25)) >> 26;
- $h3 += $carry2;
- $h2 -= $carry2 << 26;
- /** @var int $carry4 */
- $carry4 = ($h4 + (1 << 25)) >> 26;
- $h5 += $carry4;
- $h4 -= $carry4 << 26;
- /** @var int $carry6 */
- $carry6 = ($h6 + (1 << 25)) >> 26;
- $h7 += $carry6;
- $h6 -= $carry6 << 26;
- /** @var int $carry8 */
- $carry8 = ($h8 + (1 << 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)
- {
- /** @var int $h0 */
- $h0 = (int) $h[0];
- /** @var int $h1 */
- $h1 = (int) $h[1];
- /** @var int $h2 */
- $h2 = (int) $h[2];
- /** @var int $h3 */
- $h3 = (int) $h[3];
- /** @var int $h4 */
- $h4 = (int) $h[4];
- /** @var int $h5 */
- $h5 = (int) $h[5];
- /** @var int $h6 */
- $h6 = (int) $h[6];
- /** @var int $h7 */
- $h7 = (int) $h[7];
- /** @var int $h8 */
- $h8 = (int) $h[8];
- /** @var int $h9 */
- $h9 = (int) $h[9];
- /** @var int $q */
- $q = (self::mul($h9, 19, 5) + (1 << 24)) >> 25;
- /** @var int $q */
- $q = ($h0 + $q) >> 26;
- /** @var int $q */
- $q = ($h1 + $q) >> 25;
- /** @var int $q */
- $q = ($h2 + $q) >> 26;
- /** @var int $q */
- $q = ($h3 + $q) >> 25;
- /** @var int $q */
- $q = ($h4 + $q) >> 26;
- /** @var int $q */
- $q = ($h5 + $q) >> 25;
- /** @var int $q */
- $q = ($h6 + $q) >> 26;
- /** @var int $q */
- $q = ($h7 + $q) >> 25;
- /** @var int $q */
- $q = ($h8 + $q) >> 26;
- /** @var int $q */
- $q = ($h9 + $q) >> 25;
- $h0 += self::mul($q, 19, 5);
- /** @var int $carry0 */
- $carry0 = $h0 >> 26;
- $h1 += $carry0;
- $h0 -= $carry0 << 26;
- /** @var int $carry1 */
- $carry1 = $h1 >> 25;
- $h2 += $carry1;
- $h1 -= $carry1 << 25;
- /** @var int $carry2 */
- $carry2 = $h2 >> 26;
- $h3 += $carry2;
- $h2 -= $carry2 << 26;
- /** @var int $carry3 */
- $carry3 = $h3 >> 25;
- $h4 += $carry3;
- $h3 -= $carry3 << 25;
- /** @var int $carry4 */
- $carry4 = $h4 >> 26;
- $h5 += $carry4;
- $h4 -= $carry4 << 26;
- /** @var int $carry5 */
- $carry5 = $h5 >> 25;
- $h6 += $carry5;
- $h5 -= $carry5 << 25;
- /** @var int $carry6 */
- $carry6 = $h6 >> 26;
- $h7 += $carry6;
- $h6 -= $carry6 << 26;
- /** @var int $carry7 */
- $carry7 = $h7 >> 25;
- $h8 += $carry7;
- $h7 -= $carry7 << 25;
- /** @var int $carry8 */
- $carry8 = $h8 >> 26;
- $h9 += $carry8;
- $h8 -= $carry8 << 26;
- /** @var int $carry9 */
- $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
- ) {
- /** @var int $f0 */
- $f0 = $f[0];
- /** @var int $f1 */
- $f1 = $f[1];
- /** @var int $f2 */
- $f2 = $f[2];
- /** @var int $f3 */
- $f3 = $f[3];
- /** @var int $f4 */
- $f4 = $f[4];
- /** @var int $f5 */
- $f5 = $f[5];
- /** @var int $f6 */
- $f6 = $f[6];
- /** @var int $f7 */
- $f7 = $f[7];
- /** @var int $f8 */
- $f8 = $f[8];
- /** @var int $f9 */
- $f9 = $f[9];
- /** @var int $g0 */
- $g0 = $g[0];
- /** @var int $g1 */
- $g1 = $g[1];
- /** @var int $g2 */
- $g2 = $g[2];
- /** @var int $g3 */
- $g3 = $g[3];
- /** @var int $g4 */
- $g4 = $g[4];
- /** @var int $g5 */
- $g5 = $g[5];
- /** @var int $g6 */
- $g6 = $g[6];
- /** @var int $g7 */
- $g7 = $g[7];
- /** @var int $g8 */
- $g8 = $g[8];
- /** @var int $g9 */
- $g9 = $g[9];
- $g1_19 = self::mul($g1, 19, 5);
- $g2_19 = self::mul($g2, 19, 5);
- $g3_19 = self::mul($g3, 19, 5);
- $g4_19 = self::mul($g4, 19, 5);
- $g5_19 = self::mul($g5, 19, 5);
- $g6_19 = self::mul($g6, 19, 5);
- $g7_19 = self::mul($g7, 19, 5);
- $g8_19 = self::mul($g8, 19, 5);
- $g9_19 = self::mul($g9, 19, 5);
- /** @var int $f1_2 */
- $f1_2 = $f1 << 1;
- /** @var int $f3_2 */
- $f3_2 = $f3 << 1;
- /** @var int $f5_2 */
- $f5_2 = $f5 << 1;
- /** @var int $f7_2 */
- $f7_2 = $f7 << 1;
- /** @var int $f9_2 */
- $f9_2 = $f9 << 1;
- $f0g0 = self::mul($f0, $g0, 26);
- $f0g1 = self::mul($f0, $g1, 25);
- $f0g2 = self::mul($f0, $g2, 26);
- $f0g3 = self::mul($f0, $g3, 25);
- $f0g4 = self::mul($f0, $g4, 26);
- $f0g5 = self::mul($f0, $g5, 25);
- $f0g6 = self::mul($f0, $g6, 26);
- $f0g7 = self::mul($f0, $g7, 25);
- $f0g8 = self::mul($f0, $g8, 26);
- $f0g9 = self::mul($f0, $g9, 26);
- $f1g0 = self::mul($f1, $g0, 26);
- $f1g1_2 = self::mul($f1_2, $g1, 25);
- $f1g2 = self::mul($f1, $g2, 26);
- $f1g3_2 = self::mul($f1_2, $g3, 25);
- $f1g4 = self::mul($f1, $g4, 26);
- $f1g5_2 = self::mul($f1_2, $g5, 25);
- $f1g6 = self::mul($f1, $g6, 26);
- $f1g7_2 = self::mul($f1_2, $g7, 25);
- $f1g8 = self::mul($f1, $g8, 26);
- $f1g9_38 = self::mul($g9_19, $f1_2, 26);
- $f2g0 = self::mul($f2, $g0, 26);
- $f2g1 = self::mul($f2, $g1, 25);
- $f2g2 = self::mul($f2, $g2, 26);
- $f2g3 = self::mul($f2, $g3, 25);
- $f2g4 = self::mul($f2, $g4, 26);
- $f2g5 = self::mul($f2, $g5, 25);
- $f2g6 = self::mul($f2, $g6, 26);
- $f2g7 = self::mul($f2, $g7, 25);
- $f2g8_19 = self::mul($g8_19, $f2, 26);
- $f2g9_19 = self::mul($g9_19, $f2, 26);
- $f3g0 = self::mul($f3, $g0, 26);
- $f3g1_2 = self::mul($f3_2, $g1, 25);
- $f3g2 = self::mul($f3, $g2, 26);
- $f3g3_2 = self::mul($f3_2, $g3, 25);
- $f3g4 = self::mul($f3, $g4, 26);
- $f3g5_2 = self::mul($f3_2, $g5, 25);
- $f3g6 = self::mul($f3, $g6, 26);
- $f3g7_38 = self::mul($g7_19, $f3_2, 26);
- $f3g8_19 = self::mul($g8_19, $f3, 25);
- $f3g9_38 = self::mul($g9_19, $f3_2, 26);
- $f4g0 = self::mul($f4, $g0, 26);
- $f4g1 = self::mul($f4, $g1, 25);
- $f4g2 = self::mul($f4, $g2, 26);
- $f4g3 = self::mul($f4, $g3, 25);
- $f4g4 = self::mul($f4, $g4, 26);
- $f4g5 = self::mul($f4, $g5, 25);
- $f4g6_19 = self::mul($g6_19, $f4, 26);
- $f4g7_19 = self::mul($g7_19, $f4, 26);
- $f4g8_19 = self::mul($g8_19, $f4, 26);
- $f4g9_19 = self::mul($g9_19, $f4, 26);
- $f5g0 = self::mul($f5, $g0, 26);
- $f5g1_2 = self::mul($f5_2, $g1, 25);
- $f5g2 = self::mul($f5, $g2, 26);
- $f5g3_2 = self::mul($f5_2, $g3, 25);
- $f5g4 = self::mul($f5, $g4, 26);
- $f5g5_38 = self::mul($g5_19, $f5_2, 26);
- $f5g6_19 = self::mul($g6_19, $f5, 25);
- $f5g7_38 = self::mul($g7_19, $f5_2, 26);
- $f5g8_19 = self::mul($g8_19, $f5, 25);
- $f5g9_38 = self::mul($g9_19, $f5_2, 26);
- $f6g0 = self::mul($f6, $g0, 26);
- $f6g1 = self::mul($f6, $g1, 25);
- $f6g2 = self::mul($f6, $g2, 26);
- $f6g3 = self::mul($f6, $g3, 25);
- $f6g4_19 = self::mul($g4_19, $f6, 26);
- $f6g5_19 = self::mul($g5_19, $f6, 26);
- $f6g6_19 = self::mul($g6_19, $f6, 26);
- $f6g7_19 = self::mul($g7_19, $f6, 26);
- $f6g8_19 = self::mul($g8_19, $f6, 26);
- $f6g9_19 = self::mul($g9_19, $f6, 26);
- $f7g0 = self::mul($f7, $g0, 26);
- $f7g1_2 = self::mul($f7_2, $g1, 25);
- $f7g2 = self::mul($f7, $g2, 26);
- $f7g3_38 = self::mul($g3_19, $f7_2, 26);
- $f7g4_19 = self::mul($g4_19, $f7, 26);
- $f7g5_38 = self::mul($g5_19, $f7_2, 26);
- $f7g6_19 = self::mul($g6_19, $f7, 25);
- $f7g7_38 = self::mul($g7_19, $f7_2, 26);
- $f7g8_19 = self::mul($g8_19, $f7, 25);
- $f7g9_38 = self::mul($g9_19,$f7_2, 26);
- $f8g0 = self::mul($f8, $g0, 26);
- $f8g1 = self::mul($f8, $g1, 25);
- $f8g2_19 = self::mul($g2_19, $f8, 26);
- $f8g3_19 = self::mul($g3_19, $f8, 26);
- $f8g4_19 = self::mul($g4_19, $f8, 26);
- $f8g5_19 = self::mul($g5_19, $f8, 26);
- $f8g6_19 = self::mul($g6_19, $f8, 26);
- $f8g7_19 = self::mul($g7_19, $f8, 26);
- $f8g8_19 = self::mul($g8_19, $f8, 26);
- $f8g9_19 = self::mul($g9_19, $f8, 26);
- $f9g0 = self::mul($f9, $g0, 26);
- $f9g1_38 = self::mul($g1_19, $f9_2, 26);
- $f9g2_19 = self::mul($g2_19, $f9, 25);
- $f9g3_38 = self::mul($g3_19, $f9_2, 26);
- $f9g4_19 = self::mul($g4_19, $f9, 25);
- $f9g5_38 = self::mul($g5_19, $f9_2, 26);
- $f9g6_19 = self::mul($g6_19, $f9, 25);
- $f9g7_38 = self::mul($g7_19, $f9_2, 26);
- $f9g8_19 = self::mul($g8_19, $f9, 25);
- $f9g9_38 = self::mul($g9_19, $f9_2, 26);
- $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 ;
- /** @var int $carry0 */
- $carry0 = ($h0 + (1 << 25)) >> 26;
- $h1 += $carry0;
- $h0 -= $carry0 << 26;
- /** @var int $carry4 */
- $carry4 = ($h4 + (1 << 25)) >> 26;
- $h5 += $carry4;
- $h4 -= $carry4 << 26;
- /** @var int $carry1 */
- $carry1 = ($h1 + (1 << 24)) >> 25;
- $h2 += $carry1;
- $h1 -= $carry1 << 25;
- /** @var int $carry5 */
- $carry5 = ($h5 + (1 << 24)) >> 25;
- $h6 += $carry5;
- $h5 -= $carry5 << 25;
- /** @var int $carry2 */
- $carry2 = ($h2 + (1 << 25)) >> 26;
- $h3 += $carry2;
- $h2 -= $carry2 << 26;
- /** @var int $carry6 */
- $carry6 = ($h6 + (1 << 25)) >> 26;
- $h7 += $carry6;
- $h6 -= $carry6 << 26;
- /** @var int $carry3 */
- $carry3 = ($h3 + (1 << 24)) >> 25;
- $h4 += $carry3;
- $h3 -= $carry3 << 25;
- /** @var int $carry7 */
- $carry7 = ($h7 + (1 << 24)) >> 25;
- $h8 += $carry7;
- $h7 -= $carry7 << 25;
- /** @var int $carry4 */
- $carry4 = ($h4 + (1 << 25)) >> 26;
- $h5 += $carry4;
- $h4 -= $carry4 << 26;
- /** @var int $carry8 */
- $carry8 = ($h8 + (1 << 25)) >> 26;
- $h9 += $carry8;
- $h8 -= $carry8 << 26;
- /** @var int $carry9 */
- $carry9 = ($h9 + (1 << 24)) >> 25;
- $h0 += self::mul($carry9, 19, 5);
- $h9 -= $carry9 << 25;
- /** @var int $carry0 */
- $carry0 = ($h0 + (1 << 25)) >> 26;
- $h1 += $carry0;
- $h0 -= $carry0 << 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
- )
- );
- }
- /**
- * 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 $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)
- {
- $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];
- /** @var int $f0_2 */
- $f0_2 = $f0 << 1;
- /** @var int $f1_2 */
- $f1_2 = $f1 << 1;
- /** @var int $f2_2 */
- $f2_2 = $f2 << 1;
- /** @var int $f3_2 */
- $f3_2 = $f3 << 1;
- /** @var int $f4_2 */
- $f4_2 = $f4 << 1;
- /** @var int $f5_2 */
- $f5_2 = $f5 << 1;
- /** @var int $f6_2 */
- $f6_2 = $f6 << 1;
- /** @var int $f7_2 */
- $f7_2 = $f7 << 1;
- $f5_38 = self::mul($f5, 38, 6);
- $f6_19 = self::mul($f6, 19, 5);
- $f7_38 = self::mul($f7, 38, 6);
- $f8_19 = self::mul($f8, 19, 5);
- $f9_38 = self::mul($f9, 38, 6);
- $f0f0 = self::mul($f0, $f0, 25);
- $f0f1_2 = self::mul($f0_2, $f1, 24);
- $f0f2_2 = self::mul($f0_2, $f2, 25);
- $f0f3_2 = self::mul($f0_2, $f3, 24);
- $f0f4_2 = self::mul($f0_2, $f4, 25);
- $f0f5_2 = self::mul($f0_2, $f5, 25);
- $f0f6_2 = self::mul($f0_2, $f6, 25);
- $f0f7_2 = self::mul($f0_2, $f7, 24);
- $f0f8_2 = self::mul($f0_2, $f8, 25);
- $f0f9_2 = self::mul($f0_2, $f9, 25);
- $f1f1_2 = self::mul($f1_2, $f1, 24);
- $f1f2_2 = self::mul($f1_2, $f2, 25);
- $f1f3_4 = self::mul($f1_2, $f3_2, 25);
- $f1f4_2 = self::mul($f1_2, $f4, 25);
- $f1f5_4 = self::mul($f1_2, $f5_2, 26);
- $f1f6_2 = self::mul($f1_2, $f6, 25);
- $f1f7_4 = self::mul($f1_2, $f7_2, 25);
- $f1f8_2 = self::mul($f1_2, $f8, 25);
- $f1f9_76 = self::mul($f9_38, $f1_2, 25);
- $f2f2 = self::mul($f2, $f2, 25);
- $f2f3_2 = self::mul($f2_2, $f3, 24);
- $f2f4_2 = self::mul($f2_2, $f4, 25);
- $f2f5_2 = self::mul($f2_2, $f5, 25);
- $f2f6_2 = self::mul($f2_2, $f6, 25);
- $f2f7_2 = self::mul($f2_2, $f7, 24);
- $f2f8_38 = self::mul($f8_19, $f2_2, 26);
- $f2f9_38 = self::mul($f9_38, $f2, 25);
- $f3f3_2 = self::mul($f3_2, $f3, 24);
- $f3f4_2 = self::mul($f3_2, $f4, 25);
- $f3f5_4 = self::mul($f3_2, $f5_2, 26);
- $f3f6_2 = self::mul($f3_2, $f6, 25);
- $f3f7_76 = self::mul($f7_38, $f3_2, 25);
- $f3f8_38 = self::mul($f8_19, $f3_2, 25);
- $f3f9_76 = self::mul($f9_38, $f3_2, 25);
- $f4f4 = self::mul($f4, $f4, 25);
- $f4f5_2 = self::mul($f4_2, $f5, 25);
- $f4f6_38 = self::mul($f6_19, $f4_2, 26);
- $f4f7_38 = self::mul($f7_38, $f4, 25);
- $f4f8_38 = self::mul($f8_19, $f4_2, 26);
- $f4f9_38 = self::mul($f9_38, $f4, 25);
- $f5f5_38 = self::mul($f5_38, $f5, 25);
- $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, 25);
- $f6f7_38 = self::mul($f7_38, $f6, 25);
- $f6f8_38 = self::mul($f8_19, $f6_2, 26);
- $f6f9_38 = self::mul($f9_38, $f6, 25);
- $f7f7_38 = self::mul($f7_38, $f7, 24);
- $f7f8_38 = self::mul($f8_19, $f7_2, 25);
- $f7f9_76 = self::mul($f9_38, $f7_2, 25);
- $f8f8_19 = self::mul($f8_19, $f8, 25);
- $f8f9_38 = self::mul($f9_38, $f8, 25);
- $f9f9_38 = self::mul($f9_38, $f9, 25);
- $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;
- /** @var int $carry0 */
- $carry0 = ($h0 + (1 << 25)) >> 26;
- $h1 += $carry0;
- $h0 -= $carry0 << 26;
- /** @var int $carry4 */
- $carry4 = ($h4 + (1 << 25)) >> 26;
- $h5 += $carry4;
- $h4 -= $carry4 << 26;
- /** @var int $carry1 */
- $carry1 = ($h1 + (1 << 24)) >> 25;
- $h2 += $carry1;
- $h1 -= $carry1 << 25;
- /** @var int $carry5 */
- $carry5 = ($h5 + (1 << 24)) >> 25;
- $h6 += $carry5;
- $h5 -= $carry5 << 25;
- /** @var int $carry2 */
- $carry2 = ($h2 + (1 << 25)) >> 26;
- $h3 += $carry2;
- $h2 -= $carry2 << 26;
- /** @var int $carry6 */
- $carry6 = ($h6 + (1 << 25)) >> 26;
- $h7 += $carry6;
- $h6 -= $carry6 << 26;
- /** @var int $carry3 */
- $carry3 = ($h3 + (1 << 24)) >> 25;
- $h4 += $carry3;
- $h3 -= $carry3 << 25;
- /** @var int $carry7 */
- $carry7 = ($h7 + (1 << 24)) >> 25;
- $h8 += $carry7;
- $h7 -= $carry7 << 25;
- /** @var int $carry4 */
- $carry4 = ($h4 + (1 << 25)) >> 26;
- $h5 += $carry4;
- $h4 -= $carry4 << 26;
- /** @var int $carry8 */
- $carry8 = ($h8 + (1 << 25)) >> 26;
- $h9 += $carry8;
- $h8 -= $carry8 << 26;
- /** @var int $carry9 */
- $carry9 = ($h9 + (1 << 24)) >> 25;
- $h0 += self::mul($carry9, 19, 5);
- $h9 -= $carry9 << 25;
- /** @var int $carry0 */
- $carry0 = ($h0 + (1 << 25)) >> 26;
- $h1 += $carry0;
- $h0 -= $carry0 << 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
- )
- );
- }
- /**
- * 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)
- {
- $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];
- /** @var int $f0_2 */
- $f0_2 = $f0 << 1;
- /** @var int $f1_2 */
- $f1_2 = $f1 << 1;
- /** @var int $f2_2 */
- $f2_2 = $f2 << 1;
- /** @var int $f3_2 */
- $f3_2 = $f3 << 1;
- /** @var int $f4_2 */
- $f4_2 = $f4 << 1;
- /** @var int $f5_2 */
- $f5_2 = $f5 << 1;
- /** @var int $f6_2 */
- $f6_2 = $f6 << 1;
- /** @var int $f7_2 */
- $f7_2 = $f7 << 1;
- $f5_38 = self::mul($f5, 38, 6); /* 1.959375*2^30 */
- $f6_19 = self::mul($f6, 19, 5); /* 1.959375*2^30 */
- $f7_38 = self::mul($f7, 38, 6); /* 1.959375*2^30 */
- $f8_19 = self::mul($f8, 19, 5); /* 1.959375*2^30 */
- $f9_38 = self::mul($f9, 38, 6); /* 1.959375*2^30 */
- $f0f0 = self::mul($f0, $f0, 24);
- $f0f1_2 = self::mul($f0_2, $f1, 24);
- $f0f2_2 = self::mul($f0_2, $f2, 24);
- $f0f3_2 = self::mul($f0_2, $f3, 24);
- $f0f4_2 = self::mul($f0_2, $f4, 24);
- $f0f5_2 = self::mul($f0_2, $f5, 24);
- $f0f6_2 = self::mul($f0_2, $f6, 24);
- $f0f7_2 = self::mul($f0_2, $f7, 24);
- $f0f8_2 = self::mul($f0_2, $f8, 24);
- $f0f9_2 = self::mul($f0_2, $f9, 24);
- $f1f1_2 = self::mul($f1_2, $f1, 24);
- $f1f2_2 = self::mul($f1_2, $f2, 24);
- $f1f3_4 = self::mul($f1_2, $f3_2, 24);
- $f1f4_2 = self::mul($f1_2, $f4, 24);
- $f1f5_4 = self::mul($f1_2, $f5_2, 24);
- $f1f6_2 = self::mul($f1_2, $f6, 24);
- $f1f7_4 = self::mul($f1_2, $f7_2, 24);
- $f1f8_2 = self::mul($f1_2, $f8, 24);
- $f1f9_76 = self::mul($f9_38, $f1_2, 24);
- $f2f2 = self::mul($f2, $f2, 24);
- $f2f3_2 = self::mul($f2_2, $f3, 24);
- $f2f4_2 = self::mul($f2_2, $f4, 24);
- $f2f5_2 = self::mul($f2_2, $f5, 24);
- $f2f6_2 = self::mul($f2_2, $f6, 24);
- $f2f7_2 = self::mul($f2_2, $f7, 24);
- $f2f8_38 = self::mul($f8_19, $f2_2, 25);
- $f2f9_38 = self::mul($f9_38, $f2, 24);
- $f3f3_2 = self::mul($f3_2, $f3, 24);
- $f3f4_2 = self::mul($f3_2, $f4, 24);
- $f3f5_4 = self::mul($f3_2, $f5_2, 24);
- $f3f6_2 = self::mul($f3_2, $f6, 24);
- $f3f7_76 = self::mul($f7_38, $f3_2, 24);
- $f3f8_38 = self::mul($f8_19, $f3_2, 24);
- $f3f9_76 = self::mul($f9_38, $f3_2, 24);
- $f4f4 = self::mul($f4, $f4, 24);
- $f4f5_2 = self::mul($f4_2, $f5, 24);
- $f4f6_38 = self::mul($f6_19, $f4_2, 25);
- $f4f7_38 = self::mul($f7_38, $f4, 24);
- $f4f8_38 = self::mul($f8_19, $f4_2, 25);
- $f4f9_38 = self::mul($f9_38, $f4, 24);
- $f5f5_38 = self::mul($f5_38, $f5, 24);
- $f5f6_38 = self::mul($f6_19, $f5_2, 24);
- $f5f7_76 = self::mul($f7_38, $f5_2, 24);
- $f5f8_38 = self::mul($f8_19, $f5_2, 24);
- $f5f9_76 = self::mul($f9_38, $f5_2, 24);
- $f6f6_19 = self::mul($f6_19, $f6, 24);
- $f6f7_38 = self::mul($f7_38, $f6, 24);
- $f6f8_38 = self::mul($f8_19, $f6_2, 25);
- $f6f9_38 = self::mul($f9_38, $f6, 24);
- $f7f7_38 = self::mul($f7_38, $f7, 24);
- $f7f8_38 = self::mul($f8_19, $f7_2, 24);
- $f7f9_76 = self::mul($f9_38, $f7_2, 24);
- $f8f8_19 = self::mul($f8_19, $f8, 24);
- $f8f9_38 = self::mul($f9_38, $f8, 24);
- $f9f9_38 = self::mul($f9_38, $f9, 24);
- /** @var int $h0 */
- $h0 = (int) ($f0f0 + $f1f9_76 + $f2f8_38 + $f3f7_76 + $f4f6_38 + $f5f5_38) << 1;
- /** @var int $h1 */
- $h1 = (int) ($f0f1_2 + $f2f9_38 + $f3f8_38 + $f4f7_38 + $f5f6_38) << 1;
- /** @var int $h2 */
- $h2 = (int) ($f0f2_2 + $f1f1_2 + $f3f9_76 + $f4f8_38 + $f5f7_76 + $f6f6_19) << 1;
- /** @var int $h3 */
- $h3 = (int) ($f0f3_2 + $f1f2_2 + $f4f9_38 + $f5f8_38 + $f6f7_38) << 1;
- /** @var int $h4 */
- $h4 = (int) ($f0f4_2 + $f1f3_4 + $f2f2 + $f5f9_76 + $f6f8_38 + $f7f7_38) << 1;
- /** @var int $h5 */
- $h5 = (int) ($f0f5_2 + $f1f4_2 + $f2f3_2 + $f6f9_38 + $f7f8_38) << 1;
- /** @var int $h6 */
- $h6 = (int) ($f0f6_2 + $f1f5_4 + $f2f4_2 + $f3f3_2 + $f7f9_76 + $f8f8_19) << 1;
- /** @var int $h7 */
- $h7 = (int) ($f0f7_2 + $f1f6_2 + $f2f5_2 + $f3f4_2 + $f8f9_38) << 1;
- /** @var int $h8 */
- $h8 = (int) ($f0f8_2 + $f1f7_4 + $f2f6_2 + $f3f5_4 + $f4f4 + $f9f9_38) << 1;
- /** @var int $h9 */
- $h9 = (int) ($f0f9_2 + $f1f8_2 + $f2f7_2 + $f3f6_2 + $f4f5_2) << 1;
- /** @var int $carry0 */
- $carry0 = ($h0 + (1 << 25)) >> 26;
- $h1 += $carry0;
- $h0 -= $carry0 << 26;
- /** @var int $carry4 */
- $carry4 = ($h4 + (1 << 25)) >> 26;
- $h5 += $carry4;
- $h4 -= $carry4 << 26;
- /** @var int $carry1 */
- $carry1 = ($h1 + (1 << 24)) >> 25;
- $h2 += $carry1;
- $h1 -= $carry1 << 25;
- /** @var int $carry5 */
- $carry5 = ($h5 + (1 << 24)) >> 25;
- $h6 += $carry5;
- $h5 -= $carry5 << 25;
- /** @var int $carry2 */
- $carry2 = ($h2 + (1 << 25)) >> 26;
- $h3 += $carry2;
- $h2 -= $carry2 << 26;
- /** @var int $carry6 */
- $carry6 = ($h6 + (1 << 25)) >> 26;
- $h7 += $carry6;
- $h6 -= $carry6 << 26;
- /** @var int $carry3 */
- $carry3 = ($h3 + (1 << 24)) >> 25;
- $h4 += $carry3;
- $h3 -= $carry3 << 25;
- /** @var int $carry7 */
- $carry7 = ($h7 + (1 << 24)) >> 25;
- $h8 += $carry7;
- $h7 -= $carry7 << 25;
- /** @var int $carry4 */
- $carry4 = ($h4 + (1 << 25)) >> 26;
- $h5 += $carry4;
- $h4 -= $carry4 << 26;
- /** @var int $carry8 */
- $carry8 = ($h8 + (1 << 25)) >> 26;
- $h9 += $carry8;
- $h8 -= $carry8 << 26;
- /** @var int $carry9 */
- $carry9 = ($h9 + (1 << 24)) >> 25;
- $h0 += self::mul($carry9, 19, 5);
- $h9 -= $carry9 << 25;
- /** @var int $carry0 */
- $carry0 = ($h0 + (1 << 25)) >> 26;
- $h1 += $carry0;
- $h0 -= $carry0 << 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
- )
- );
- }
- /**
- * @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)
- {
- # 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 $f, ParagonIE_Sodium_Core_Curve25519_Fe $g)
- {
- return 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->X = self::fe_add($p->Y, $p->X);
- $r->Y = self::fe_sub($p->Y, $p->X);
- $r->Z = self::fe_mul($r->X, $q->YplusX);
- $r->Y = self::fe_mul($r->Y, $q->YminusX);
- $r->T = self::fe_mul($q->T2d, $p->T);
- $r->X = self::fe_mul($p->Z, $q->Z);
- $t0 = self::fe_add($r->X, $r->X);
- $r->X = self::fe_sub($r->Z, $r->Y);
- $r->Y = self::fe_add($r->Z, $r->Y);
- $r->Z = self::fe_add($t0, $r->T);
- $r->T = self::fe_sub($t0, $r->T);
- return $r;
- }
- /**
- * @internal You should not use this directly from another application
- *
- * @ref https://github.com/jedisct1/libsodium/blob/157c4a80c13b117608aeae12178b2d38825f9f8f/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1185-L1215
- * @param string $a
- * @return array<int, mixed>
- * @throws SodiumException
- * @throws TypeError
- */
- public static function slide($a)
- {
- if (self::strlen($a) < 256) {
- if (self::strlen($a) < 16) {
- $a = str_pad($a, 256, '0', STR_PAD_RIGHT);
- }
- }
- /** @var array<int, int> $r */
- $r = array();
- /** @var int $i */
- for ($i = 0; $i < 256; ++$i) {
- $r[$i] = (int) (
- 1 & (
- self::chrToInt($a[(int) ($i >> 3)])
- >>
- ($i & 7)
- )
- );
- }
- for ($i = 0;$i < 256;++$i) {
- if ($r[$i]) {
- for ($b = 1;$b <= 6 && $i + $b < 256;++$b) {
- if ($r[$i + $b]) {
- if ($r[$i] + ($r[$i + $b] << $b) <= 15) {
- $r[$i] += $r[$i + $b] << $b;
- $r[$i + $b] = 0;
- } elseif ($r[$i] - ($r[$i + $b] << $b) >= -15) {
- $r[$i] -= $r[$i + $b] << $b;
- for ($k = $i + $b; $k < 256; ++$k) {
- if (!$r[$k]) {
- $r[$k] = 1;
- break;
- }
- $r[$k] = 0;
- }
- } else {
- break;
- }
- }
- }
- }
- }
- return $r;
- }
- /**
- * @internal You should not use this directly from another application
- *
- * @param string $s
- * @return ParagonIE_Sodium_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->X = self::fe_sq($v3);
- $h->X = self::fe_mul($h->X, $v);
- $h->X = self::fe_mul($h->X, $u); /* x = uv^7 */
- # fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */
- # fe_mul(h->X,h->X,v3);
- # fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */
- $h->X = self::fe_pow22523($h->X); /* x = (uv^7)^((q-5)/8) */
- $h->X = self::fe_mul($h->X, $v3);
- $h->X = self::fe_mul($h->X, $u); /* x = uv^3(uv^7)^((q-5)/8) */
- # fe_sq(vxx,h->X);
- # fe_mul(vxx,vxx,v);
- # fe_sub(check,vxx,u); /* vx^2-u */
- $vxx = self::fe_sq($h->X);
- $vxx = self::fe_mul($vxx, $v);
- $check = self::fe_sub($vxx, $u); /* vx^2 - u */
- # if (fe_isnonzero(check)) {
- # fe_add(check,vxx,u); /* vx^2+u */
- # if (fe_isnonzero(check)) {
- # return -1;
- # }
- # fe_mul(h->X,h->X,sqrtm1);
- # }
- if (self::fe_isnonzero($check)) {
- $check = self::fe_add($vxx, $u); /* vx^2 + u */
- if (self::fe_isnonzero($check)) {
- throw new RangeException('Internal check failed.');
- }
- $h->X = self::fe_mul(
- $h->X,
- ParagonIE_Sodium_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->X = self::fe_neg($h->X);
- }
- # fe_mul(h->T,h->X,h->Y);
- $h->T = self::fe_mul($h->X, $h->Y);
- return $h;
- }
- /**
- * @internal You should not use this directly from another application
- *
- * @param ParagonIE_Sodium_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->X = self::fe_add($p->Y, $p->X);
- $r->Y = self::fe_sub($p->Y, $p->X);
- $r->Z = self::fe_mul($r->X, $q->yplusx);
- $r->Y = self::fe_mul($r->Y, $q->yminusx);
- $r->T = self::fe_mul($q->xy2d, $p->T);
- $t0 = self::fe_add(clone $p->Z, clone $p->Z);
- $r->X = self::fe_sub($r->Z, $r->Y);
- $r->Y = self::fe_add($r->Z, $r->Y);
- $r->Z = self::fe_add($t0, $r->T);
- $r->T = self::fe_sub($t0, $r->T);
- return $r;
- }
- /**
- * @internal You should not use this directly from another application
- *
- * @param ParagonIE_Sodium_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->X = self::fe_add($p->Y, $p->X);
- $r->Y = self::fe_sub($p->Y, $p->X);
- $r->Z = self::fe_mul($r->X, $q->yminusx);
- $r->Y = self::fe_mul($r->Y, $q->yplusx);
- $r->T = self::fe_mul($q->xy2d, $p->T);
- $t0 = self::fe_add($p->Z, $p->Z);
- $r->X = self::fe_sub($r->Z, $r->Y);
- $r->Y = self::fe_add($r->Z, $r->Y);
- $r->Z = self