Commit 7340ebcae3 for wordpress.org

commit 7340ebcae3d1dee31b43bdd74d74492d0436d508
Author: Sergey Biryukov <sergeybiryukov.ru@gmail.com>
Date:   Tue Dec 30 22:55:37 2025 +0000

    Upgrade/Install: Update sodium_compat to v1.24.0.

    The latest version includes a security fix to ensure that the public key is on the prime order subgroup.

    References:
    * [https://github.com/paragonie/sodium_compat/releases/tag/v1.24.0 sodium_compat 1.24.0 release notes]
    * [https://github.com/paragonie/sodium_compat/compare/v1.23.0...v1.24.0 Full list of changes in sodium_compat 1.24.0]

    Follow-up to [55699], [58752], [58753], [60787], [60905].

    Props paragoninitiativeenterprises, johnbillion, SergeyBiryukov.
    Fixes #64462.
    Built from https://develop.svn.wordpress.org/trunk@61419


    git-svn-id: http://core.svn.wordpress.org/trunk@60731 1a063a9b-81f0-0310-95a4-ce76da25c4cd

diff --git a/wp-includes/sodium_compat/src/Core/Ed25519.php b/wp-includes/sodium_compat/src/Core/Ed25519.php
index 01457bad46..bf6b5cfbd7 100644
--- a/wp-includes/sodium_compat/src/Core/Ed25519.php
+++ b/wp-includes/sodium_compat/src/Core/Ed25519.php
@@ -106,6 +106,22 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
         return self::sk_to_pk($sk);
     }

+    /**
+     * Returns TRUE if $A represents a point on the order of the Edwards25519 prime order subgroup.
+     * Returns FALSE if $A is on a different subgroup.
+     *
+     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A
+     * @return bool
+     *
+     * @throws SodiumException
+     */
+    public static function is_on_main_subgroup(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A)
+    {
+        $p1 = self::ge_mul_l($A);
+        $t = self::fe_sub($p1->Y, $p1->Z);
+        return self::fe_isnonzero($p1->X) && self::fe_isnonzero($t);
+    }
+
     /**
      * @param string $pk
      * @return string
@@ -118,9 +134,8 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
             throw new SodiumException('Public key is on a small order');
         }
         $A = self::ge_frombytes_negate_vartime(self::substr($pk, 0, 32));
-        $p1 = self::ge_mul_l($A);
-        if (!self::fe_isnonzero($p1->X)) {
-            throw new SodiumException('Unexpected zero result');
+        if (!self::is_on_main_subgroup($A)) {
+            throw new SodiumException('Public key is not on a member of the main subgroup');
         }

         # fe_1(one_minus_y);
@@ -287,7 +302,7 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
             throw new SodiumException('Argument 3 must be CRYPTO_SIGN_PUBLICKEYBYTES long');
         }
         if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) {
-            throw new SodiumException('S < L - Invalid signature');
+            throw new SodiumException('S >= L - Invalid signature');
         }
         if (self::small_order($sig)) {
             throw new SodiumException('Signature is on too small of an order');
@@ -311,6 +326,9 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve

         /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A */
         $A = self::ge_frombytes_negate_vartime($pk);
+        if (!self::is_on_main_subgroup($A)) {
+            throw new SodiumException('Public key is not on a member of the main subgroup');
+        }

         /** @var string $hDigest */
         $hDigest = hash(
diff --git a/wp-includes/sodium_compat/src/File.php b/wp-includes/sodium_compat/src/File.php
index 80d625fa29..c132a92e25 100644
--- a/wp-includes/sodium_compat/src/File.php
+++ b/wp-includes/sodium_compat/src/File.php
@@ -786,8 +786,14 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
         // Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification.
         ParagonIE_Sodium_Compat::$fastMult = true;

+        if (ParagonIE_Sodium_Core_Ed25519::small_order($publicKey)) {
+            throw new SodiumException('Public key has small order');
+        }
         /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A */
         $A = ParagonIE_Sodium_Core_Ed25519::ge_frombytes_negate_vartime($publicKey);
+        if (!ParagonIE_Sodium_Core_Ed25519::is_on_main_subgroup($A)) {
+            throw new SodiumException('Public key is not on a member of the main subgroup');
+        }

         $hs = hash_init('sha512');
         self::hash_update($hs, self::substr($sig, 0, 32));
diff --git a/wp-includes/version.php b/wp-includes/version.php
index ac2047f6ae..c6c5a0e35e 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '7.0-alpha-61418';
+$wp_version = '7.0-alpha-61419';

 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.