: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$carry1 = ($h1 + (1 << 24)) >> 25;
$carry5 = ($h5 + (1 << 24)) >> 25;
$carry2 = ($h2 + (1 << 25)) >> 26;
$carry6 = ($h6 + (1 << 25)) >> 26;
$carry3 = ($h3 + (1 << 24)) >> 25;
$carry7 = ($h7 + (1 << 24)) >> 25;
$carry4 = ($h4 + (1 << 25)) >> 26;
$carry8 = ($h8 + (1 << 25)) >> 26;
$carry9 = ($h9 + (1 << 24)) >> 25;
$h0 += self::mul($carry9, 19, 5);
$carry0 = ($h0 + (1 << 25)) >> 26;
return self::fe_normalize(
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
* Get the negative values for each piece of the 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
* @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) {
return self::fe_normalize($h);
* @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);
$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, 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 + (1 << 25)) >> 26;
$carry4 = ($h4 + (1 << 25)) >> 26;
$carry1 = ($h1 + (1 << 24)) >> 25;
$carry5 = ($h5 + (1 << 24)) >> 25;
$carry2 = ($h2 + (1 << 25)) >> 26;
$carry6 = ($h6 + (1 << 25)) >> 26;
$carry3 = ($h3 + (1 << 24)) >> 25;
$carry7 = ($h7 + (1 << 24)) >> 25;
$carry4 = ($h4 + (1 << 25)) >> 26;
$carry8 = ($h8 + (1 << 25)) >> 26;
$carry9 = ($h9 + (1 << 24)) >> 25;
$h0 += self::mul($carry9, 19, 5);
$carry0 = ($h0 + (1 << 25)) >> 26;
return self::fe_normalize(
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
* Square and double 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_sq2(ParagonIE_Sodium_Core_Curve25519_Fe $f)
$f = self::fe_normalize($f);
$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);
$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 + (1 << 25)) >> 26;
$carry4 = ($h4 + (1 << 25)) >> 26;
$carry1 = ($h1 + (1 << 24)) >> 25;
$carry5 = ($h5 + (1 << 24)) >> 25;
$carry2 = ($h2 + (1 << 25)) >> 26;
$carry6 = ($h6 + (1 << 25)) >> 26;
$carry3 = ($h3 + (1 << 24)) >> 25;
$carry7 = ($h7 + (1 << 24)) >> 25;
$carry4 = ($h4 + (1 << 25)) >> 26;
$carry8 = ($h8 + (1 << 25)) >> 26;
$carry9 = ($h9 + (1 << 24)) >> 25;
$h0 += self::mul($carry9, 19, 5);
$carry0 = ($h0 + (1 << 25)) >> 26;
return self::fe_normalize(
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
* @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)
$t1 = self::fe_mul($z, $t1);
$t0 = self::fe_mul($t0, $t1);
$t1 = self::fe_mul($t1, $t2);
for ($i = 1; $i < 5; ++$i) {
$t1 = self::fe_mul($t2, $t1);
for ($i = 1; $i < 10; ++$i) {
$t2 = self::fe_mul($t2, $t1);
for ($i = 1; $i < 20; ++$i) {
$t2 = self::fe_mul($t3, $t2);
for ($i = 1; $i < 10; ++$i) {
$t1 = self::fe_mul($t2, $t1);
for ($i = 1; $i < 50; ++$i) {
$t2 = self::fe_mul($t2, $t1);
for ($i = 1; $i < 100; ++$i) {
$t2 = self::fe_mul($t3, $t2);
for ($i = 1; $i < 50; ++$i) {
$t1 = self::fe_mul($t2, $t1);
for ($i = 1; $i < 5; ++$i) {
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);
$t1 = self::fe_mul($z, $t1);
$t0 = self::fe_mul($t0, $t1);
$t0 = self::fe_mul($t1, $t0);
# for (i = 1; i < 5; ++i) {
for ($i = 1; $i < 5; ++$i) {
$t0 = self::fe_mul($t1, $t0);