Commit 9609f94b1d for wordpress.org

commit 9609f94b1dcfafa53b5b611c60e911b597afb1ea
Author: desrosj <desrosj@git.wordpress.org>
Date:   Tue Nov 10 20:48:57 2026 +0000

    External Libraries: Update `sodium_compat` to version `1.24.2`.

    This updates the `sodium_compat` library from version `1.24.1` to `1.42.2`.

    This update is a hardening release.

    A full list of changes can be found on GitHub: https://github.com/paragonie/sodium_compat/compare/v1.24.1...v1.24.2.

    Props johnbillion.
    Fixes #66650.

    Built from https://develop.svn.wordpress.org/trunk@65398


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

diff --git a/wp-includes/sodium_compat/src/Core/ChaCha20.php b/wp-includes/sodium_compat/src/Core/ChaCha20.php
index f116486129..f3c561e8f7 100644
--- a/wp-includes/sodium_compat/src/Core/ChaCha20.php
+++ b/wp-includes/sodium_compat/src/Core/ChaCha20.php
@@ -119,6 +119,9 @@ class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util

         $c = '';
         for (;;) {
+            if ($j12 > 0xffffffff || $j13 > 0xffffffff) {
+                throw new SodiumException('Overflow');
+            }
             if ($bytes < 64) {
                 $message .= str_repeat("\x00", 64 - $bytes);
             }
@@ -258,9 +261,12 @@ class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util
                     j13 = PLUSONE(j13);
                 }
              */
-            ++$j12;
-            if ($j12 & 0xf0000000) {
-                throw new SodiumException('Overflow');
+            if (
+                ++$j12 > 0xffffffff &&
+                !($ctx instanceof ParagonIE_Sodium_Core_ChaCha20_IetfCtx)
+            ) {
+                $j12 = 0;
+                ++$j13;
             }

             /*
diff --git a/wp-includes/sodium_compat/src/Core/Curve25519.php b/wp-includes/sodium_compat/src/Core/Curve25519.php
index 7dab1cd0bb..6d6849d423 100644
--- a/wp-includes/sodium_compat/src/Core/Curve25519.php
+++ b/wp-includes/sodium_compat/src/Core/Curve25519.php
@@ -3855,4 +3855,4 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
         $g->e9 = $e[9];
         return $g;
     }
-}
\ No newline at end of file
+}
diff --git a/wp-includes/sodium_compat/src/Core/Ed25519.php b/wp-includes/sodium_compat/src/Core/Ed25519.php
index 5cae0f180c..5328928ef7 100644
--- a/wp-includes/sodium_compat/src/Core/Ed25519.php
+++ b/wp-includes/sodium_compat/src/Core/Ed25519.php
@@ -317,40 +317,47 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
         if ($d === 0) {
             throw new SodiumException('All zero public key');
         }
+        if (self::small_order($pk)) {
+            throw new SodiumException('Public key has small order');
+        }

         /** @var bool The original value of ParagonIE_Sodium_Compat::$fastMult */
         $orig = ParagonIE_Sodium_Compat::$fastMult;

         // Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification.
         ParagonIE_Sodium_Compat::$fastMult = true;
+        try {
+            /** @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 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(
-            'sha512',
-            self::substr($sig, 0, 32) .
-                self::substr($pk, 0, 32) .
-                $message,
-            true
-        );
+            /** @var string $hDigest */
+            $hDigest = hash(
+                'sha512',
+                self::substr($sig, 0, 32) .
+                    self::substr($pk, 0, 32) .
+                    $message,
+                true
+            );

-        /** @var string $h */
-        $h = self::sc_reduce($hDigest) . self::substr($hDigest, 32);
+            /** @var string $h */
+            $h = self::sc_reduce($hDigest) . self::substr($hDigest, 32);

-        /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P2 $R */
-        $R = self::ge_double_scalarmult_vartime(
-            $h,
-            $A,
-            self::substr($sig, 32)
-        );
+            /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P2 $R */
+            $R = self::ge_double_scalarmult_vartime(
+                $h,
+                $A,
+                self::substr($sig, 32)
+            );

-        /** @var string $rcheck */
-        $rcheck = self::ge_tobytes($R);
+            /** @var string $rcheck */
+            $rcheck = self::ge_tobytes($R);
+        } catch (Exception $ex) {
+            ParagonIE_Sodium_Compat::$fastMult = $orig;
+            throw $ex;
+        }

         // Reset ParagonIE_Sodium_Compat::$fastMult to what it was before.
         ParagonIE_Sodium_Compat::$fastMult = $orig;
diff --git a/wp-includes/sodium_compat/src/Core/Ristretto255.php b/wp-includes/sodium_compat/src/Core/Ristretto255.php
index 2727260d21..4c43faee3d 100644
--- a/wp-includes/sodium_compat/src/Core/Ristretto255.php
+++ b/wp-includes/sodium_compat/src/Core/Ristretto255.php
@@ -584,6 +584,9 @@ class ParagonIE_Sodium_Core_Ristretto255 extends ParagonIE_Sodium_Core_Ed25519
      */
     public static function ristretto255_scalar_invert($s)
     {
+        if (ParagonIE_Sodium_Compat::is_zero($s)) {
+            throw new SodiumException('Cannot invert a zero scalar');
+        }
         return self::sc25519_invert($s);
     }

diff --git a/wp-includes/sodium_compat/src/Core/SecretStream/State.php b/wp-includes/sodium_compat/src/Core/SecretStream/State.php
index 2412f6549e..48b7bd835f 100644
--- a/wp-includes/sodium_compat/src/Core/SecretStream/State.php
+++ b/wp-includes/sodium_compat/src/Core/SecretStream/State.php
@@ -96,7 +96,7 @@ class ParagonIE_Sodium_Core_SecretStream_State
      */
     public function needsRekey()
     {
-        return ($this->counter & 0xffff) === 0;
+        return ($this->counter & 0xffffffff) === 0;
     }

     /**
diff --git a/wp-includes/sodium_compat/src/Core32/ChaCha20.php b/wp-includes/sodium_compat/src/Core32/ChaCha20.php
index 6f8c0bff9f..7002a9cb84 100644
--- a/wp-includes/sodium_compat/src/Core32/ChaCha20.php
+++ b/wp-includes/sodium_compat/src/Core32/ChaCha20.php
@@ -138,6 +138,9 @@ class ParagonIE_Sodium_Core32_ChaCha20 extends ParagonIE_Sodium_Core32_Util

         $c = '';
         for (;;) {
+            if ($ctx->isExhausted()) {
+                throw new SodiumException('Overflow');
+            }
             if ($bytes < 64) {
                 $message .= str_repeat("\x00", 64 - $bytes);
             }
@@ -264,7 +267,14 @@ class ParagonIE_Sodium_Core32_ChaCha20 extends ParagonIE_Sodium_Core32_Util
             /** @var ParagonIE_Sodium_Core32_Int32 $j12 */
             $j12 = $j12->addInt(1);
             if ($j12->limbs[0] === 0 && $j12->limbs[1] === 0) {
-                $j13 = $j13->addInt(1);
+                if ($ctx instanceof ParagonIE_Sodium_Core32_ChaCha20_IetfCtx) {
+                    $ctx->markExhausted();
+                } else {
+                    $j13 = $j13->addInt(1);
+                    if ($j13->limbs[0] === 0 && $j13->limbs[1] === 0) {
+                        $ctx->markExhausted();
+                    }
+                }
             }

             /*
diff --git a/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php b/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php
index 37b058f250..1a70dec036 100644
--- a/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php
+++ b/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php
@@ -14,6 +14,21 @@ class ParagonIE_Sodium_Core32_ChaCha20_Ctx extends ParagonIE_Sodium_Core32_Util
      */
     protected $container;

+    /** @var bool */
+    protected $exhausted = false;
+
+    /** @return bool */
+    public function isExhausted()
+    {
+        return $this->exhausted;
+    }
+
+    /** @return void */
+    public function markExhausted()
+    {
+        $this->exhausted = true;
+    }
+
     /**
      * ParagonIE_Sodium_Core_ChaCha20_Ctx constructor.
      *
diff --git a/wp-includes/sodium_compat/src/Core32/Ed25519.php b/wp-includes/sodium_compat/src/Core32/Ed25519.php
index 8a0ea8e3e2..23d6ef1442 100644
--- a/wp-includes/sodium_compat/src/Core32/Ed25519.php
+++ b/wp-includes/sodium_compat/src/Core32/Ed25519.php
@@ -319,34 +319,38 @@ abstract class ParagonIE_Sodium_Core32_Ed25519 extends ParagonIE_Sodium_Core32_C

         // Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification.
         ParagonIE_Sodium_Compat::$fastMult = true;
+        try {
+            /** @var ParagonIE_Sodium_Core32_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 ParagonIE_Sodium_Core32_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(
-            'sha512',
-            self::substr($sig, 0, 32) .
-            self::substr($pk, 0, 32) .
-            $message,
-            true
-        );
+            /** @var string $hDigest */
+            $hDigest = hash(
+                'sha512',
+                self::substr($sig, 0, 32) .
+                self::substr($pk, 0, 32) .
+                $message,
+                true
+            );

-        /** @var string $h */
-        $h = self::sc_reduce($hDigest) . self::substr($hDigest, 32);
+            /** @var string $h */
+            $h = self::sc_reduce($hDigest) . self::substr($hDigest, 32);

-        /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $R */
-        $R = self::ge_double_scalarmult_vartime(
-            $h,
-            $A,
-            self::substr($sig, 32)
-        );
+            /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $R */
+            $R = self::ge_double_scalarmult_vartime(
+                $h,
+                $A,
+                self::substr($sig, 32)
+            );

-        /** @var string $rcheck */
-        $rcheck = self::ge_tobytes($R);
+            /** @var string $rcheck */
+            $rcheck = self::ge_tobytes($R);
+        } catch (Exception $ex) {
+            ParagonIE_Sodium_Compat::$fastMult = $orig;
+            throw $ex;
+        }

         // Reset ParagonIE_Sodium_Compat::$fastMult to what it was before.
         ParagonIE_Sodium_Compat::$fastMult = $orig;
diff --git a/wp-includes/sodium_compat/src/Core32/SecretStream/State.php b/wp-includes/sodium_compat/src/Core32/SecretStream/State.php
index 6f20486297..d90a2a2ae9 100644
--- a/wp-includes/sodium_compat/src/Core32/SecretStream/State.php
+++ b/wp-includes/sodium_compat/src/Core32/SecretStream/State.php
@@ -96,7 +96,7 @@ class ParagonIE_Sodium_Core32_SecretStream_State
      */
     public function needsRekey()
     {
-        return ($this->counter & 0xffff) === 0;
+        return ($this->counter & 0xffffffff) === 0;
     }

     /**
diff --git a/wp-includes/sodium_compat/src/File.php b/wp-includes/sodium_compat/src/File.php
index 658dcd9736..460d0dcbb3 100644
--- a/wp-includes/sodium_compat/src/File.php
+++ b/wp-includes/sodium_compat/src/File.php
@@ -140,16 +140,32 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
             throw new SodiumException('Could not open input file for reading');
         }

+        /** @var resource $destination */
+        $destination = self::openOutputFile($outputFile);
+        if (!is_resource($destination)) {
+            fclose($ifp);
+            throw new SodiumException('Could not open output file for writing');
+        }
         /** @var resource $ofp */
-        $ofp = @fopen($outputFile, 'wb');
+        $ofp = tmpfile();
         if (!is_resource($ofp)) {
             fclose($ifp);
-            throw new SodiumException('Could not open output file for writing');
+            fclose($destination);
+            throw new SodiumException('Could not open temporary output file for writing');
         }

-        $res = self::box_decrypt($ifp, $ofp, $size, $nonce, $keypair);
+        try {
+            $res = self::box_decrypt($ifp, $ofp, $size, $nonce, $keypair);
+            self::commitAuthenticatedOutput($ofp, $destination);
+        } catch (Exception $ex) {
+            fclose($ifp);
+            fclose($ofp);
+            fclose($destination);
+            throw $ex;
+        }
         fclose($ifp);
         fclose($ofp);
+        fclose($destination);
         try {
             ParagonIE_Sodium_Compat::memzero($nonce);
             ParagonIE_Sodium_Compat::memzero($ephKeypair);
@@ -324,20 +340,13 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
             throw new SodiumException('Could not open input file for reading');
         }

-        /** @var resource $ofp */
-        $ofp = @fopen($outputFile, 'wb');
-        if (!is_resource($ofp)) {
-            fclose($ifp);
-            throw new SodiumException('Could not open output file for writing');
-        }
-
         $ephemeralPK = fread($ifp, ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES);
         if (!is_string($ephemeralPK)) {
+            fclose($ifp);
             throw new SodiumException('Could not read input file');
         }
         if (self::strlen($ephemeralPK) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES) {
             fclose($ifp);
-            fclose($ofp);
             throw new SodiumException('Could not read public key from sealed file');
         }

@@ -351,9 +360,32 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
             $ephemeralPK
         );

-        $res = self::box_decrypt($ifp, $ofp, $size, $nonce, $msgKeypair);
+        /** @var resource $destination */
+        $destination = self::openOutputFile($outputFile);
+        if (!is_resource($destination)) {
+            fclose($ifp);
+            throw new SodiumException('Could not open output file for writing');
+        }
+        /** @var resource $ofp */
+        $ofp = tmpfile();
+        if (!is_resource($ofp)) {
+            fclose($ifp);
+            fclose($destination);
+            throw new SodiumException('Could not open temporary output file for writing');
+        }
+
+        try {
+            $res = self::box_decrypt($ifp, $ofp, $size, $nonce, $msgKeypair);
+            self::commitAuthenticatedOutput($ofp, $destination);
+        } catch (Exception $ex) {
+            fclose($ifp);
+            fclose($ofp);
+            fclose($destination);
+            throw $ex;
+        }
         fclose($ifp);
         fclose($ofp);
+        fclose($destination);
         try {
             ParagonIE_Sodium_Compat::memzero($nonce);
             ParagonIE_Sodium_Compat::memzero($ephKeypair);
@@ -579,16 +611,32 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
             throw new SodiumException('Could not open input file for reading');
         }

+        /** @var resource $destination */
+        $destination = self::openOutputFile($outputFile);
+        if (!is_resource($destination)) {
+            fclose($ifp);
+            throw new SodiumException('Could not open output file for writing');
+        }
         /** @var resource $ofp */
-        $ofp = @fopen($outputFile, 'wb');
+        $ofp = tmpfile();
         if (!is_resource($ofp)) {
             fclose($ifp);
-            throw new SodiumException('Could not open output file for writing');
+            fclose($destination);
+            throw new SodiumException('Could not open temporary output file for writing');
         }

-        $res = self::secretbox_decrypt($ifp, $ofp, $size, $nonce, $key);
+        try {
+            $res = self::secretbox_decrypt($ifp, $ofp, $size, $nonce, $key);
+            self::commitAuthenticatedOutput($ofp, $destination);
+        } catch (Exception $ex) {
+            fclose($ifp);
+            fclose($ofp);
+            fclose($destination);
+            throw $ex;
+        }
         fclose($ifp);
         fclose($ofp);
+        fclose($destination);
         try {
             ParagonIE_Sodium_Compat::memzero($key);
         } catch (SodiumException $ex) {
@@ -785,36 +833,41 @@ 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;
+        try {
+            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');
+            }

-        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));
-        self::hash_update($hs, self::substr($publicKey, 0, 32));
-        /** @var resource $hs */
-        $hs = self::updateHashWithFile($hs, $fp, $size);
-        /** @var string $hDigest */
-        $hDigest = hash_final($hs, true);
-
-        /** @var string $h */
-        $h = ParagonIE_Sodium_Core_Ed25519::sc_reduce($hDigest) . self::substr($hDigest, 32);
-
-        /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P2 $R */
-        $R = ParagonIE_Sodium_Core_Ed25519::ge_double_scalarmult_vartime(
-            $h,
-            $A,
-            self::substr($sig, 32)
-        );
+            $hs = hash_init('sha512');
+            self::hash_update($hs, self::substr($sig, 0, 32));
+            self::hash_update($hs, self::substr($publicKey, 0, 32));
+            /** @var resource $hs */
+            $hs = self::updateHashWithFile($hs, $fp, $size);
+            /** @var string $hDigest */
+            $hDigest = hash_final($hs, true);
+
+            /** @var string $h */
+            $h = ParagonIE_Sodium_Core_Ed25519::sc_reduce($hDigest) . self::substr($hDigest, 32);
+
+            /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P2 $R */
+            $R = ParagonIE_Sodium_Core_Ed25519::ge_double_scalarmult_vartime(
+                $h,
+                $A,
+                self::substr($sig, 32)
+            );

-        /** @var string $rcheck */
-        $rcheck = ParagonIE_Sodium_Core_Ed25519::ge_tobytes($R);
+            /** @var string $rcheck */
+            $rcheck = ParagonIE_Sodium_Core_Ed25519::ge_tobytes($R);
+        } catch (Exception $ex) {
+            fclose($fp);
+            ParagonIE_Sodium_Compat::$fastMult = $orig;
+            throw $ex;
+        }

         // Close the file handle
         fclose($fp);
@@ -1147,6 +1200,35 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
         return $res;
     }

+    /**
+     * @param string $outputFile
+     * @return resource|bool
+     */
+    protected static function openOutputFile($outputFile)
+    {
+        $destination = @fopen($outputFile, 'r+b');
+        return is_resource($destination) ? $destination : @fopen($outputFile, 'x+b');
+    }
+
+    /**
+     * @param resource $tmp
+     * @param resource $destination
+     * @return void
+     * @throws SodiumException
+     */
+    protected static function commitAuthenticatedOutput($tmp, $destination)
+    {
+        if (fseek($tmp, 0) !== 0) {
+            throw new SodiumException('Could not rewind temporary output file');
+        }
+        if (fseek($destination, 0) !== 0 || !ftruncate($destination, 0)) {
+            throw new SodiumException('Could not prepare output file for writing');
+        }
+        if (stream_copy_to_stream($tmp, $destination) === false) {
+            throw new SodiumException('Could not write to output file');
+        }
+    }
+
     /**
      * Update a hash context with the contents of a file, without
      * loading the entire file into memory.
@@ -1328,36 +1410,41 @@ 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;
+        try {
+            if (ParagonIE_Sodium_Core32_Ed25519::small_order($publicKey)) {
+                throw new SodiumException('Public key has small order');
+            }
+            /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A */
+            $A = ParagonIE_Sodium_Core32_Ed25519::ge_frombytes_negate_vartime($publicKey);
+            if (!ParagonIE_Sodium_Core32_Ed25519::is_on_main_subgroup($A)) {
+                throw new SodiumException('Public key is not on a member of the main subgroup');
+            }

-        if (ParagonIE_Sodium_Core32_Ed25519::small_order($publicKey)) {
-            throw new SodiumException('Public key has small order');
-        }
-        /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A */
-        $A = ParagonIE_Sodium_Core32_Ed25519::ge_frombytes_negate_vartime($publicKey);
-        if (!ParagonIE_Sodium_Core32_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));
-        self::hash_update($hs, self::substr($publicKey, 0, 32));
-        /** @var resource $hs */
-        $hs = self::updateHashWithFile($hs, $fp, $size);
-        /** @var string $hDigest */
-        $hDigest = hash_final($hs, true);
-
-        /** @var string $h */
-        $h = ParagonIE_Sodium_Core32_Ed25519::sc_reduce($hDigest) . self::substr($hDigest, 32);
-
-        /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $R */
-        $R = ParagonIE_Sodium_Core32_Ed25519::ge_double_scalarmult_vartime(
-            $h,
-            $A,
-            self::substr($sig, 32)
-        );
+            $hs = hash_init('sha512');
+            self::hash_update($hs, self::substr($sig, 0, 32));
+            self::hash_update($hs, self::substr($publicKey, 0, 32));
+            /** @var resource $hs */
+            $hs = self::updateHashWithFile($hs, $fp, $size);
+            /** @var string $hDigest */
+            $hDigest = hash_final($hs, true);
+
+            /** @var string $h */
+            $h = ParagonIE_Sodium_Core32_Ed25519::sc_reduce($hDigest) . self::substr($hDigest, 32);
+
+            /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $R */
+            $R = ParagonIE_Sodium_Core32_Ed25519::ge_double_scalarmult_vartime(
+                $h,
+                $A,
+                self::substr($sig, 32)
+            );

-        /** @var string $rcheck */
-        $rcheck = ParagonIE_Sodium_Core32_Ed25519::ge_tobytes($R);
+            /** @var string $rcheck */
+            $rcheck = ParagonIE_Sodium_Core32_Ed25519::ge_tobytes($R);
+        } catch (Exception $ex) {
+            fclose($fp);
+            ParagonIE_Sodium_Compat::$fastMult = $orig;
+            throw $ex;
+        }

         // Close the file handle
         fclose($fp);
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 97df4a97b7..9e207aadbd 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '7.2-beta5-65397';
+$wp_version = '7.2-beta5-65398';

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