diff --git a/src/wp-includes/sodium_compat/LICENSE b/src/wp-includes/sodium_compat/LICENSE
index ce41e508c0..532a3cf527 100644
--- a/src/wp-includes/sodium_compat/LICENSE
+++ b/src/wp-includes/sodium_compat/LICENSE
@@ -1,10 +1,10 @@
 /*
  * ISC License
  *
- * Copyright (c) 2016-2019
+ * Copyright (c) 2016-2018
  * Paragon Initiative Enterprises <security at paragonie dot com>
  *
- * Copyright (c) 2013-2019
+ * Copyright (c) 2013-2018
  * Frank Denis <j at pureftpd dot org>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
diff --git a/src/wp-includes/sodium_compat/composer.json b/src/wp-includes/sodium_compat/composer.json
index 075b8b3040..b69808d922 100644
--- a/src/wp-includes/sodium_compat/composer.json
+++ b/src/wp-includes/sodium_compat/composer.json
@@ -50,7 +50,7 @@
     "files": ["autoload.php"]
   },
   "require": {
-    "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7",
+    "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8",
     "paragonie/random_compat": ">=1"
   },
   "require-dev": {
diff --git a/src/wp-includes/sodium_compat/lib/php72compat.php b/src/wp-includes/sodium_compat/lib/php72compat.php
index 9cc53ed8d5..3074af3a68 100644
--- a/src/wp-includes/sodium_compat/lib/php72compat.php
+++ b/src/wp-includes/sodium_compat/lib/php72compat.php
@@ -107,7 +107,7 @@ function sodium_compare($a, $b)
      * @param string $assocData
      * @param string $nonce
      * @param string $key
-     * @return string
+     * @return string|bool
      */
     function sodium_crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key)
     {
@@ -153,7 +153,7 @@ function sodium_crypto_aead_aes256gcm_is_available()
      * @param string $assocData
      * @param string $nonce
      * @param string $key
-     * @return string
+     * @return string|bool
      */
     function sodium_crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key)
     {
@@ -199,7 +199,7 @@ function sodium_crypto_aead_chacha20poly1305_keygen()
      * @param string $assocData
      * @param string $nonce
      * @param string $key
-     * @return string
+     * @return string|bool
      */
     function sodium_crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key)
     {
@@ -245,12 +245,12 @@ function sodium_crypto_aead_chacha20poly1305_ietf_keygen()
      * @param string $assocData
      * @param string $nonce
      * @param string $key
-     * @return string
+     * @return string|bool
      */
     function sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key)
     {
         try {
-            return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key);
+            return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key, true);
         } catch (Error $ex) {
             return false;
         } catch (Exception $ex) {
@@ -271,7 +271,7 @@ function sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($message, $assocData,
      */
     function sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key)
     {
-        return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key);
+        return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key, true);
     }
 }
 if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_keygen')) {
@@ -952,7 +952,7 @@ function sodium_hex2bin($string)
 if (!is_callable('sodium_increment')) {
     /**
      * @see ParagonIE_Sodium_Compat::increment()
-     * @param &string $string
+     * @param string $string
      * @return void
      * @throws SodiumException
      * @throws TypeError
@@ -1009,7 +1009,7 @@ function sodium_memcmp($a, $b)
 if (!is_callable('sodium_memzero')) {
     /**
      * @see ParagonIE_Sodium_Compat::memzero()
-     * @param string &$str
+     * @param string $str
      * @return void
      * @throws SodiumException
      * @throws TypeError
diff --git a/src/wp-includes/sodium_compat/lib/sodium_compat.php b/src/wp-includes/sodium_compat/lib/sodium_compat.php
index 1799bb57e3..ec5e5b5b51 100644
--- a/src/wp-includes/sodium_compat/lib/sodium_compat.php
+++ b/src/wp-includes/sodium_compat/lib/sodium_compat.php
@@ -45,16 +45,14 @@ function compare($a, $b)
      * @param string $nonce
      * @param string $key
      * @return string|bool
-     * @throws \SodiumException
-     * @throws \TypeError
      */
     function crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key)
     {
         try {
             return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key);
-        } catch (Error $ex) {
+        } catch (\TypeError $ex) {
             return false;
-        } catch (Exception $ex) {
+        } catch (\SodiumException $ex) {
             return false;
         }
     }
@@ -93,16 +91,14 @@ function crypto_aead_aes256gcm_is_available()
      * @param string $nonce
      * @param string $key
      * @return string|bool
-     * @throws \SodiumException
-     * @throws \TypeError
      */
     function crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key)
     {
         try {
             return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key);
-        } catch (Error $ex) {
+        } catch (\TypeError $ex) {
             return false;
-        } catch (Exception $ex) {
+        } catch (\SodiumException $ex) {
             return false;
         }
     }
@@ -131,16 +127,14 @@ function crypto_aead_chacha20poly1305_encrypt($message, $assocData, $nonce, $key
      * @param string $nonce
      * @param string $key
      * @return string|bool
-     * @throws \SodiumException
-     * @throws \TypeError
      */
     function crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key)
     {
         try {
             return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key);
-        } catch (Error $ex) {
+        } catch (\TypeError $ex) {
             return false;
-        } catch (Exception $ex) {
+        } catch (\SodiumException $ex) {
             return false;
         }
     }
@@ -238,16 +232,14 @@ function crypto_box_keypair_from_secretkey_and_publickey($sk, $pk)
      * @param string $nonce
      * @param string $kp
      * @return string|bool
-     * @throws \SodiumException
-     * @throws \TypeError
      */
     function crypto_box_open($message, $nonce, $kp)
     {
         try {
             return ParagonIE_Sodium_Compat::crypto_box_open($message, $nonce, $kp);
-        } catch (Error $ex) {
+        } catch (\TypeError $ex) {
             return false;
-        } catch (Exception $ex) {
+        } catch (\SodiumException $ex) {
             return false;
         }
     }
@@ -298,15 +290,14 @@ function crypto_box_seal($message, $publicKey)
      * @param string $message
      * @param string $kp
      * @return string|bool
-     * @throws \TypeError
      */
     function crypto_box_seal_open($message, $kp)
     {
         try {
             return ParagonIE_Sodium_Compat::crypto_box_seal_open($message, $kp);
-        } catch (\Error $ex) {
+        } catch (\TypeError $ex) {
             return false;
-        } catch (\Exception $ex) {
+        } catch (\SodiumException $ex) {
             return false;
         }
     }
@@ -543,16 +534,14 @@ function crypto_secretbox($message, $nonce, $key)
      * @param string $nonce
      * @param string $key
      * @return string|bool
-     * @throws \SodiumException
-     * @throws \TypeError
      */
     function crypto_secretbox_open($message, $nonce, $key)
     {
         try {
             return ParagonIE_Sodium_Compat::crypto_secretbox_open($message, $nonce, $key);
-        } catch (Error $ex) {
+        } catch (\TypeError $ex) {
             return false;
-        } catch (Exception $ex) {
+        } catch (\SodiumException $ex) {
             return false;
         }
     }
@@ -622,9 +611,9 @@ function crypto_sign_open($signedMessage, $pk)
     {
         try {
             return ParagonIE_Sodium_Compat::crypto_sign_open($signedMessage, $pk);
-        } catch (\Error $ex) {
+        } catch (\TypeError $ex) {
             return false;
-        } catch (\Exception $ex) {
+        } catch (\SodiumException $ex) {
             return false;
         }
     }
@@ -810,7 +799,7 @@ function randombytes_buf($amount)
      * @see ParagonIE_Sodium_Compat::randombytes_uniform()
      * @param int $upperLimit
      * @return int
-     * @throws \Exception
+     * @throws \SodiumException
      * @throws \Error
      */
     function randombytes_uniform($upperLimit)
diff --git a/src/wp-includes/sodium_compat/namespaced/Core/Salsa20.php b/src/wp-includes/sodium_compat/namespaced/Core/Salsa20.php
index ac83f73967..a6112398de 100644
--- a/src/wp-includes/sodium_compat/namespaced/Core/Salsa20.php
+++ b/src/wp-includes/sodium_compat/namespaced/Core/Salsa20.php
@@ -1,7 +1,7 @@
 <?php
 namespace ParagonIE\Sodium\Core;
 
-class SipHash extends \ParagonIE_Sodium_Core_Salsa20
+class Salsa20 extends \ParagonIE_Sodium_Core_Salsa20
 {
 
-}
\ No newline at end of file
+}
diff --git a/src/wp-includes/sodium_compat/namespaced/Core/Xsalsa20.php b/src/wp-includes/sodium_compat/namespaced/Core/Xsalsa20.php
index 5338d52c15..5297e4917b 100644
--- a/src/wp-includes/sodium_compat/namespaced/Core/Xsalsa20.php
+++ b/src/wp-includes/sodium_compat/namespaced/Core/Xsalsa20.php
@@ -1,7 +1,7 @@
 <?php
 namespace ParagonIE\Sodium\Core;
 
-class Xsalsa20 extends \ParagonIE_Sodium_Core_Xsalsa20
+class Xsalsa20 extends \ParagonIE_Sodium_Core_XSalsa20
 {
 
 }
diff --git a/src/wp-includes/sodium_compat/src/Compat.php b/src/wp-includes/sodium_compat/src/Compat.php
index 8c948e4693..26387ea337 100644
--- a/src/wp-includes/sodium_compat/src/Compat.php
+++ b/src/wp-includes/sodium_compat/src/Compat.php
@@ -144,9 +144,9 @@ public static function bin2hex($string)
      *
      * @param string $left  The left operand; must be a string
      * @param string $right The right operand; must be a string
-     * @return int          < 0 if the left operand is less than the right
-     *                      = 0 if both strings are equal
-     *                      > 0 if the right operand is less than the left
+     * @return int          If < 0 if the left operand is less than the right
+     *                      If = 0 if both strings are equal
+     *                      If > 0 if the right operand is less than the left
      * @throws SodiumException
      * @throws TypeError
      * @psalm-suppress MixedArgument
@@ -669,12 +669,13 @@ public static function crypto_aead_chacha20poly1305_ietf_keygen()
      * This mode uses a 64-bit random nonce with a 64-bit counter.
      * IETF mode uses a 96-bit random nonce with a 32-bit counter.
      *
-     * @param string $ciphertext Encrypted message (with Poly1305 MAC appended)
-     * @param string $assocData Authenticated Associated Data (unencrypted)
-     * @param string $nonce Number to be used only Once; must be 8 bytes
-     * @param string $key Encryption key
+     * @param string $ciphertext   Encrypted message (with Poly1305 MAC appended)
+     * @param string $assocData    Authenticated Associated Data (unencrypted)
+     * @param string $nonce        Number to be used only Once; must be 8 bytes
+     * @param string $key          Encryption key
+     * @param bool   $dontFallback Don't fallback to ext/sodium
      *
-     * @return string            The original plaintext message
+     * @return string|bool         The original plaintext message
      * @throws SodiumException
      * @throws TypeError
      * @psalm-suppress MixedArgument
@@ -683,7 +684,8 @@ public static function crypto_aead_xchacha20poly1305_ietf_decrypt(
         $ciphertext = '',
         $assocData = '',
         $nonce = '',
-        $key = ''
+        $key = '',
+        $dontFallback = false
     ) {
         /* Type checks: */
         ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1);
@@ -701,6 +703,16 @@ public static function crypto_aead_xchacha20poly1305_ietf_decrypt(
         if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES) {
             throw new SodiumException('Message must be at least CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES long');
         }
+        if (self::useNewSodiumAPI() && !$dontFallback) {
+            if (is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_decrypt')) {
+                return sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
+                    $ciphertext,
+                    $assocData,
+                    $nonce,
+                    $key
+                );
+            }
+        }
 
         if (PHP_INT_SIZE === 4) {
             return ParagonIE_Sodium_Crypto32::aead_xchacha20poly1305_ietf_decrypt(
@@ -727,10 +739,11 @@ public static function crypto_aead_xchacha20poly1305_ietf_decrypt(
      * This mode uses a 64-bit random nonce with a 64-bit counter.
      * IETF mode uses a 96-bit random nonce with a 32-bit counter.
      *
-     * @param string $plaintext Message to be encrypted
-     * @param string $assocData Authenticated Associated Data (unencrypted)
-     * @param string $nonce Number to be used only Once; must be 8 bytes
-     * @param string $key Encryption key
+     * @param string $plaintext    Message to be encrypted
+     * @param string $assocData    Authenticated Associated Data (unencrypted)
+     * @param string $nonce        Number to be used only Once; must be 8 bytes
+     * @param string $key          Encryption key
+     * @param bool   $dontFallback Don't fallback to ext/sodium
      *
      * @return string           Ciphertext with a 16-byte Poly1305 message
      *                          authentication code appended
@@ -742,7 +755,8 @@ public static function crypto_aead_xchacha20poly1305_ietf_encrypt(
         $plaintext = '',
         $assocData = '',
         $nonce = '',
-        $key = ''
+        $key = '',
+        $dontFallback = false
     ) {
         /* Type checks: */
         ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1);
@@ -757,6 +771,16 @@ public static function crypto_aead_xchacha20poly1305_ietf_encrypt(
         if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES) {
             throw new SodiumException('Key must be CRYPTO_AEAD_XCHACHA20POLY1305_KEYBYTES long');
         }
+        if (self::useNewSodiumAPI() && !$dontFallback) {
+            if (is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) {
+                return sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
+                    $plaintext,
+                    $assocData,
+                    $nonce,
+                    $key
+                );
+            }
+        }
 
         if (PHP_INT_SIZE === 4) {
             return ParagonIE_Sodium_Crypto32::aead_xchacha20poly1305_ietf_encrypt(
@@ -1279,12 +1303,13 @@ public static function crypto_generichash($message, $key = '', $length = self::C
     /**
      * Get the final BLAKE2b hash output for a given context.
      *
-     * @param string &$ctx BLAKE2 hashing context. Generated by crypto_generichash_init().
-     * @param int $length  Hash output size.
-     * @return string      Final BLAKE2b hash.
+     * @param string $ctx BLAKE2 hashing context. Generated by crypto_generichash_init().
+     * @param int $length Hash output size.
+     * @return string     Final BLAKE2b hash.
      * @throws SodiumException
      * @throws TypeError
      * @psalm-suppress MixedArgument
+     * @psalm-suppress ReferenceConstraintViolation
      */
     public static function crypto_generichash_final(&$ctx, $length = self::CRYPTO_GENERICHASH_BYTES)
     {
@@ -1357,13 +1382,15 @@ public static function crypto_generichash_init($key = '', $length = self::CRYPTO
     /**
      * Update a BLAKE2b hashing context with additional data.
      *
-     * @param string &$ctx    BLAKE2 hashing context. Generated by crypto_generichash_init().
-     *                        $ctx is passed by reference and gets updated in-place.
+     * @param string $ctx    BLAKE2 hashing context. Generated by crypto_generichash_init().
+     *                       $ctx is passed by reference and gets updated in-place.
+     * @param-out string $ctx
      * @param string $message The message to append to the existing hash state.
      * @return void
      * @throws SodiumException
      * @throws TypeError
      * @psalm-suppress MixedArgument
+     * @psalm-suppress ReferenceConstraintViolation
      */
     public static function crypto_generichash_update(&$ctx, $message)
     {
@@ -2610,6 +2637,7 @@ public static function memcmp($left, $right)
      * native library for that.
      *
      * @param string|null $var
+     * @param-out string|null $var
      *
      * @return void
      * @throws SodiumException (Unless libsodium is installed)
@@ -2622,6 +2650,7 @@ public static function memzero(&$var)
         ParagonIE_Sodium_Core_Util::declareScalarType($var, 'string', 1);
 
         if (self::useNewSodiumAPI()) {
+            /** @psalm-suppress MixedArgument */
             sodium_memzero($var);
             return;
         }
@@ -2725,6 +2754,42 @@ public static function randombytes_random16()
         return random_int(0, 65535);
     }
 
+    /**
+     * Runtime testing method for 32-bit platforms.
+     *
+     * Usage: If runtime_speed_test() returns FALSE, then our 32-bit
+     *        implementation is to slow to use safely without risking timeouts.
+     *        If this happens, install sodium from PECL to get acceptable
+     *        performance.
+     *
+     * @param int $iterations Number of multiplications to attempt
+     * @param int $maxTimeout Milliseconds
+     * @return bool           TRUE if we're fast enough, FALSE is not
+     * @throws SodiumException
+     */
+    public static function runtime_speed_test($iterations, $maxTimeout)
+    {
+        if (self::polyfill_is_fast()) {
+            return true;
+        }
+        /** @var float $end */
+        $end = 0.0;
+        /** @var float $start */
+        $start = microtime(true);
+        /** @var ParagonIE_Sodium_Core32_Int64 $a */
+        $a = ParagonIE_Sodium_Core32_Int64::fromInt(random_int(3, 1 << 16));
+        for ($i = 0; $i < $iterations; ++$i) {
+            /** @var ParagonIE_Sodium_Core32_Int64 $b */
+            $b = ParagonIE_Sodium_Core32_Int64::fromInt(random_int(3, 1 << 16));
+            $a->mulInt64($b);
+        }
+        /** @var float $end */
+        $end = microtime(true);
+        /** @var int $diff */
+        $diff = (int) ceil(($end - $start) * 1000);
+        return $diff < $maxTimeout;
+    }
+
     /**
      * This emulates libsodium's version_string() function, except ours is
      * prefixed with 'polyfill-'.
diff --git a/src/wp-includes/sodium_compat/src/Core/BLAKE2b.php b/src/wp-includes/sodium_compat/src/Core/BLAKE2b.php
index f0369df0c8..5d295ce615 100644
--- a/src/wp-includes/sodium_compat/src/Core/BLAKE2b.php
+++ b/src/wp-includes/sodium_compat/src/Core/BLAKE2b.php
@@ -256,6 +256,7 @@ protected static function store64(SplFixedArray $x, $i, SplFixedArray $u)
             if (++$i > $maxLength) {
                 return;
             }
+            /** @psalm-suppress MixedOperand */
             $u[$uIdx] >>= 8;
         }
     }
@@ -642,7 +643,7 @@ public static function SplFixedArrayToString(SplFixedArray $a)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param SplFixedArray[SplFixedArray] $ctx
+     * @param SplFixedArray $ctx
      * @return string
      * @throws TypeError
      * @psalm-suppress MixedArgument
diff --git a/src/wp-includes/sodium_compat/src/Core/ChaCha20/Ctx.php b/src/wp-includes/sodium_compat/src/Core/ChaCha20/Ctx.php
index b29ab90054..47a42b70de 100644
--- a/src/wp-includes/sodium_compat/src/Core/ChaCha20/Ctx.php
+++ b/src/wp-includes/sodium_compat/src/Core/ChaCha20/Ctx.php
@@ -83,9 +83,8 @@ public function offsetSet($offset, $value)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
+     * @param int $offset
      * @return bool
-     * @psalm-suppress MixedArrayOffset
      */
     public function offsetExists($offset)
     {
@@ -95,7 +94,7 @@ public function offsetExists($offset)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
+     * @param int $offset
      * @return void
      * @psalm-suppress MixedArrayOffset
      */
@@ -107,7 +106,7 @@ public function offsetUnset($offset)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
+     * @param int $offset
      * @return mixed|null
      * @psalm-suppress MixedArrayOffset
      */
diff --git a/src/wp-includes/sodium_compat/src/Core/Curve25519/Fe.php b/src/wp-includes/sodium_compat/src/Core/Curve25519/Fe.php
index 881e3695a1..64c489ae08 100644
--- a/src/wp-includes/sodium_compat/src/Core/Curve25519/Fe.php
+++ b/src/wp-includes/sodium_compat/src/Core/Curve25519/Fe.php
@@ -12,7 +12,7 @@
 class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
 {
     /**
-     * @var array
+     * @var array<int, int>
      */
     protected $container = array();
 
@@ -24,7 +24,7 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
     /**
      * @internal You should not use this directly from another application
      *
-     * @param array $array
+     * @param array<int, int> $array
      * @param bool $save_indexes
      * @return self
      */
@@ -37,6 +37,7 @@ public static function fromArray($array, $save_indexes = null)
             $keys = range(0, $count - 1);
         }
         $array = array_values($array);
+        /** @var array<int, int> $keys */
 
         $obj = new ParagonIE_Sodium_Core_Curve25519_Fe();
         if ($save_indexes) {
@@ -54,8 +55,8 @@ public static function fromArray($array, $save_indexes = null)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
-     * @param mixed $value
+     * @param int|null $offset
+     * @param int $value
      * @return void
      * @psalm-suppress MixedArrayOffset
      */
@@ -74,7 +75,7 @@ public function offsetSet($offset, $value)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
+     * @param int $offset
      * @return bool
      * @psalm-suppress MixedArrayOffset
      */
@@ -86,7 +87,7 @@ public function offsetExists($offset)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
+     * @param int $offset
      * @return void
      * @psalm-suppress MixedArrayOffset
      */
@@ -98,15 +99,16 @@ public function offsetUnset($offset)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
-     * @return mixed|null
+     * @param int $offset
+     * @return int
      * @psalm-suppress MixedArrayOffset
      */
     public function offsetGet($offset)
     {
-        return isset($this->container[$offset])
-            ? $this->container[$offset]
-            : null;
+        if (!isset($this->container[$offset])) {
+            $this->container[$offset] = 0;
+        }
+        return (int) ($this->container[$offset]);
     }
 
     /**
diff --git a/src/wp-includes/sodium_compat/src/Core/Util.php b/src/wp-includes/sodium_compat/src/Core/Util.php
index 5caa3ffa32..a5808b191d 100644
--- a/src/wp-includes/sodium_compat/src/Core/Util.php
+++ b/src/wp-includes/sodium_compat/src/Core/Util.php
@@ -817,7 +817,7 @@ public static function substr($str, $start = 0, $length = null)
         } else {
             $sub = (string) substr($str, $start, $length);
         }
-        if (isset($sub)) {
+        if ($sub !== '') {
             return $sub;
         }
         return '';
diff --git a/src/wp-includes/sodium_compat/src/Core32/BLAKE2b.php b/src/wp-includes/sodium_compat/src/Core32/BLAKE2b.php
index ee7f415d3a..f33b7b626e 100644
--- a/src/wp-includes/sodium_compat/src/Core32/BLAKE2b.php
+++ b/src/wp-includes/sodium_compat/src/Core32/BLAKE2b.php
@@ -574,7 +574,7 @@ public static function SplFixedArrayToString(SplFixedArray $a)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param SplFixedArray[SplFixedArray] $ctx
+     * @param SplFixedArray $ctx
      * @return string
      * @throws TypeError
      * @psalm-suppress MixedArgument
diff --git a/src/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php b/src/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php
index 996acf23e5..3f47d03b00 100644
--- a/src/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php
+++ b/src/wp-includes/sodium_compat/src/Core32/ChaCha20/Ctx.php
@@ -89,7 +89,7 @@ public function offsetSet($offset, $value)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
+     * @param int $offset
      * @return bool
      * @psalm-suppress MixedArrayOffset
      */
@@ -101,7 +101,7 @@ public function offsetExists($offset)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
+     * @param int $offset
      * @return void
      * @psalm-suppress MixedArrayOffset
      */
@@ -113,7 +113,7 @@ public function offsetUnset($offset)
     /**
      * @internal You should not use this directly from another application
      *
-     * @param mixed $offset
+     * @param int $offset
      * @return mixed|null
      * @psalm-suppress MixedArrayOffset
      */
diff --git a/src/wp-includes/sodium_compat/src/Core32/Int32.php b/src/wp-includes/sodium_compat/src/Core32/Int32.php
index 68c4b55f44..c3a17900a5 100644
--- a/src/wp-includes/sodium_compat/src/Core32/Int32.php
+++ b/src/wp-includes/sodium_compat/src/Core32/Int32.php
@@ -150,6 +150,136 @@ public function mask($m = 0)
         );
     }
 
+    /**
+     * @param array<int, int> $a
+     * @param array<int, int> $b
+     * @param int $baseLog2
+     * @return array<int, int>
+     */
+    public function multiplyLong(array $a, array $b, $baseLog2 = 16)
+    {
+        $a_l = count($a);
+        $b_l = count($b);
+        /** @var array<int, int> $r */
+        $r = array_fill(0, $a_l + $b_l + 1, 0);
+        $base = 1 << $baseLog2;
+        for ($i = 0; $i < $a_l; ++$i) {
+            $a_i = $a[$i];
+            for ($j = 0; $j < $a_l; ++$j) {
+                $b_j = $b[$j];
+                $product = ($a_i * $b_j) + $r[$i + $j];
+                $carry = ($product >> $baseLog2 & 0xffff);
+                $r[$i + $j] = ($product - (int) ($carry * $base)) & 0xffff;
+                $r[$i + $j + 1] += $carry;
+            }
+        }
+        return array_slice($r, 0, 5);
+    }
+
+    /**
+     * @param int $int
+     * @return ParagonIE_Sodium_Core32_Int32
+     */
+    public function mulIntFast($int)
+    {
+        // Handle negative numbers
+        $aNeg = ($this->limbs[0] >> 15) & 1;
+        $bNeg = ($int >> 31) & 1;
+        $a = array_reverse($this->limbs);
+        $b = array(
+            $int & 0xffff,
+            ($int >> 16) & 0xffff
+        );
+        if ($aNeg) {
+            for ($i = 0; $i < 2; ++$i) {
+                $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
+            }
+            ++$a[0];
+        }
+        if ($bNeg) {
+            for ($i = 0; $i < 2; ++$i) {
+                $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
+            }
+            ++$b[0];
+        }
+        // Multiply
+        $res = $this->multiplyLong($a, $b);
+
+        // Re-apply negation to results
+        if ($aNeg !== $bNeg) {
+            for ($i = 0; $i < 2; ++$i) {
+                $res[$i] = (0xffff ^ $res[$i]) & 0xffff;
+            }
+            // Handle integer overflow
+            $c = 1;
+            for ($i = 0; $i < 2; ++$i) {
+                $res[$i] += $c;
+                $c = $res[$i] >> 16;
+                $res[$i] &= 0xffff;
+            }
+        }
+
+        // Return our values
+        $return = new ParagonIE_Sodium_Core32_Int32();
+        $return->limbs = array(
+            $res[1] & 0xffff,
+            $res[0] & 0xffff
+        );
+        if (count($res) > 2) {
+            $return->overflow = $res[2] & 0xffff;
+        }
+        $return->unsignedInt = $this->unsignedInt;
+        return $return;
+    }
+
+    /**
+     * @param ParagonIE_Sodium_Core32_Int32 $right
+     * @return ParagonIE_Sodium_Core32_Int32
+     */
+    public function mulInt32Fast(ParagonIE_Sodium_Core32_Int32 $right)
+    {
+        $aNeg = ($this->limbs[0] >> 15) & 1;
+        $bNeg = ($right->limbs[0] >> 15) & 1;
+
+        $a = array_reverse($this->limbs);
+        $b = array_reverse($right->limbs);
+        if ($aNeg) {
+            for ($i = 0; $i < 2; ++$i) {
+                $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
+            }
+            ++$a[0];
+        }
+        if ($bNeg) {
+            for ($i = 0; $i < 2; ++$i) {
+                $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
+            }
+            ++$b[0];
+        }
+        $res = $this->multiplyLong($a, $b);
+        if ($aNeg !== $bNeg) {
+            if ($aNeg !== $bNeg) {
+                for ($i = 0; $i < 2; ++$i) {
+                    $res[$i] = ($res[$i] ^ 0xffff) & 0xffff;
+                }
+                $c = 1;
+                for ($i = 0; $i < 2; ++$i) {
+                    $res[$i] += $c;
+                    $c = $res[$i] >> 16;
+                    $res[$i] &= 0xffff;
+                }
+            }
+        }
+        $return = new ParagonIE_Sodium_Core32_Int32();
+        $return->limbs = array(
+            $res[1] & 0xffff,
+            $res[0] & 0xffff
+        );
+        if (count($res) > 2) {
+            $return->overflow = $res[2];
+        }
+        return $return;
+    }
+
     /**
      * @param int $int
      * @param int $size
@@ -161,6 +291,9 @@ public function mulInt($int = 0, $size = 0)
     {
         ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1);
         ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
+        if (ParagonIE_Sodium_Compat::$fastMult) {
+            return $this->mulIntFast((int) $int);
+        }
         /** @var int $int */
         $int = (int) $int;
         /** @var int $size */
@@ -218,6 +351,9 @@ public function mulInt($int = 0, $size = 0)
     public function mulInt32(ParagonIE_Sodium_Core32_Int32 $int, $size = 0)
     {
         ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
+        if (ParagonIE_Sodium_Compat::$fastMult) {
+            return $this->mulInt32Fast($int);
+        }
         if (!$size) {
             $size = 31;
         }
@@ -491,7 +627,7 @@ public function shiftRight($c = 0)
             /** @var int $c */
             return $this->shiftLeft(-$c);
         } else {
-            if (is_null($c)) {
+            if (!is_int($c)) {
                 throw new TypeError();
             }
             /** @var int $c */
diff --git a/src/wp-includes/sodium_compat/src/Core32/Int64.php b/src/wp-includes/sodium_compat/src/Core32/Int64.php
index cc7b69f86d..dd06a3fbeb 100644
--- a/src/wp-includes/sodium_compat/src/Core32/Int64.php
+++ b/src/wp-includes/sodium_compat/src/Core32/Int64.php
@@ -205,6 +205,9 @@ public function mask64($hi = 0, $lo = 0)
      */
     public function mulInt($int = 0, $size = 0)
     {
+        if (ParagonIE_Sodium_Compat::$fastMult) {
+            return $this->mulIntFast($int);
+        }
         ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1);
         ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
         /** @var int $int */
@@ -268,11 +271,11 @@ public function mulInt($int = 0, $size = 0)
             $a3 &= 0xffff;
 
             $int >>= 1;
-            $return->limbs[0] = $ret0;
-            $return->limbs[1] = $ret1;
-            $return->limbs[2] = $ret2;
-            $return->limbs[3] = $ret3;
         }
+        $return->limbs[0] = $ret0;
+        $return->limbs[1] = $ret1;
+        $return->limbs[2] = $ret2;
+        $return->limbs[3] = $ret3;
         return $return;
     }
 
@@ -317,6 +320,142 @@ public static function ctSelect(
         );
     }
 
+    /**
+     * @param array<int, int> $a
+     * @param array<int, int> $b
+     * @param int $baseLog2
+     * @return array<int, int>
+     */
+    public function multiplyLong(array $a, array $b, $baseLog2 = 16)
+    {
+        $a_l = count($a);
+        $b_l = count($b);
+        /** @var array<int, int> $r */
+        $r = array_fill(0, $a_l + $b_l + 1, 0);
+        $base = 1 << $baseLog2;
+        for ($i = 0; $i < $a_l; ++$i) {
+            $a_i = $a[$i];
+            for ($j = 0; $j < $a_l; ++$j) {
+                $b_j = $b[$j];
+                $product = ($a_i * $b_j) + $r[$i + $j];
+                $carry = ($product >> $baseLog2 & 0xffff);
+                $r[$i + $j] = ($product - (int) ($carry * $base)) & 0xffff;
+                $r[$i + $j + 1] += $carry;
+            }
+        }
+        return array_slice($r, 0, 5);
+    }
+
+    /**
+     * @param int $int
+     * @return ParagonIE_Sodium_Core32_Int64
+     */
+    public function mulIntFast($int)
+    {
+        // Handle negative numbers
+        $aNeg = ($this->limbs[0] >> 15) & 1;
+        $bNeg = ($int >> 31) & 1;
+        $a = array_reverse($this->limbs);
+        $b = array(
+            $int & 0xffff,
+            ($int >> 16) & 0xffff,
+            -$bNeg & 0xffff,
+            -$bNeg & 0xffff
+        );
+        if ($aNeg) {
+            for ($i = 0; $i < 4; ++$i) {
+                $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
+            }
+            ++$a[0];
+        }
+        if ($bNeg) {
+            for ($i = 0; $i < 4; ++$i) {
+                $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
+            }
+            ++$b[0];
+        }
+        // Multiply
+        $res = $this->multiplyLong($a, $b);
+
+        // Re-apply negation to results
+        if ($aNeg !== $bNeg) {
+            for ($i = 0; $i < 4; ++$i) {
+                $res[$i] = (0xffff ^ $res[$i]) & 0xffff;
+            }
+            // Handle integer overflow
+            $c = 1;
+            for ($i = 0; $i < 4; ++$i) {
+                $res[$i] += $c;
+                $c = $res[$i] >> 16;
+                $res[$i] &= 0xffff;
+            }
+        }
+
+        // Return our values
+        $return = new ParagonIE_Sodium_Core32_Int64();
+        $return->limbs = array(
+            $res[3] & 0xffff,
+            $res[2] & 0xffff,
+            $res[1] & 0xffff,
+            $res[0] & 0xffff
+        );
+        if (count($res) > 4) {
+            $return->overflow = $res[4] & 0xffff;
+        }
+        $return->unsignedInt = $this->unsignedInt;
+        return $return;
+    }
+
+    /**
+     * @param ParagonIE_Sodium_Core32_Int64 $right
+     * @return ParagonIE_Sodium_Core32_Int64
+     */
+    public function mulInt64Fast(ParagonIE_Sodium_Core32_Int64 $right)
+    {
+        $aNeg = ($this->limbs[0] >> 15) & 1;
+        $bNeg = ($right->limbs[0] >> 15) & 1;
+
+        $a = array_reverse($this->limbs);
+        $b = array_reverse($right->limbs);
+        if ($aNeg) {
+            for ($i = 0; $i < 4; ++$i) {
+                $a[$i] = ($a[$i] ^ 0xffff) & 0xffff;
+            }
+            ++$a[0];
+        }
+        if ($bNeg) {
+            for ($i = 0; $i < 4; ++$i) {
+                $b[$i] = ($b[$i] ^ 0xffff) & 0xffff;
+            }
+            ++$b[0];
+        }
+        $res = $this->multiplyLong($a, $b);
+        if ($aNeg !== $bNeg) {
+            if ($aNeg !== $bNeg) {
+                for ($i = 0; $i < 4; ++$i) {
+                    $res[$i] = ($res[$i] ^ 0xffff) & 0xffff;
+                }
+                $c = 1;
+                for ($i = 0; $i < 4; ++$i) {
+                    $res[$i] += $c;
+                    $c = $res[$i] >> 16;
+                    $res[$i] &= 0xffff;
+                }
+            }
+        }
+        $return = new ParagonIE_Sodium_Core32_Int64();
+        $return->limbs = array(
+            $res[3] & 0xffff,
+            $res[2] & 0xffff,
+            $res[1] & 0xffff,
+            $res[0] & 0xffff
+        );
+        if (count($res) > 4) {
+            $return->overflow = $res[4];
+        }
+        return $return;
+    }
+
     /**
      * @param ParagonIE_Sodium_Core32_Int64 $int
      * @param int $size
@@ -327,6 +466,9 @@ public static function ctSelect(
      */
     public function mulInt64(ParagonIE_Sodium_Core32_Int64 $int, $size = 0)
     {
+        if (ParagonIE_Sodium_Compat::$fastMult) {
+            return $this->mulInt64Fast($int);
+        }
         ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2);
         if (!$size) {
             $size = 63;
@@ -566,7 +708,7 @@ public function shiftLeft($c = 0)
             /** @var int $c */
             return $this->shiftRight(-$c);
         } else {
-            if (is_null($c)) {
+            if (!is_int($c)) {
                 throw new TypeError();
             }
             /** @var int $carry */
@@ -591,10 +733,11 @@ public function shiftLeft($c = 0)
     public function shiftRight($c = 0)
     {
         ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1);
+        $c = (int) $c;
+        /** @var int $c */
         $return = new ParagonIE_Sodium_Core32_Int64();
         $return->unsignedInt = $this->unsignedInt;
         $c &= 63;
-        /** @var int $c */
 
         $negative = -(($this->limbs[0] >> 15) & 1);
         if ($c >= 16) {
diff --git a/src/wp-includes/sodium_compat/src/Core32/X25519.php b/src/wp-includes/sodium_compat/src/Core32/X25519.php
index fd4b056a81..3eb96900c5 100644
--- a/src/wp-includes/sodium_compat/src/Core32/X25519.php
+++ b/src/wp-includes/sodium_compat/src/Core32/X25519.php
@@ -102,58 +102,48 @@ public static function fe_cswap(
      */
     public static function fe_mul121666(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
     {
-        /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
+        /** @var array<int, ParagonIE_Sodium_Core32_Int64> $h */
         $h = array();
         for ($i = 0; $i < 10; ++$i) {
             $h[$i] = $f[$i]->toInt64()->mulInt(121666, 17);
         }
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry9 */
         $carry9 = $h[9]->addInt(1 << 24)->shiftRight(25);
         $h[0] = $h[0]->addInt64($carry9->mulInt(19, 5));
         $h[9] = $h[9]->subInt64($carry9->shiftLeft(25));
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry1 */
         $carry1 = $h[1]->addInt(1 << 24)->shiftRight(25);
         $h[2] = $h[2]->addInt64($carry1);
         $h[1] = $h[1]->subInt64($carry1->shiftLeft(25));
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry3 */
         $carry3 = $h[3]->addInt(1 << 24)->shiftRight(25);
         $h[4] = $h[4]->addInt64($carry3);
         $h[3] = $h[3]->subInt64($carry3->shiftLeft(25));
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry5 */
         $carry5 = $h[5]->addInt(1 << 24)->shiftRight(25);
         $h[6] = $h[6]->addInt64($carry5);
         $h[5] = $h[5]->subInt64($carry5->shiftLeft(25));
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry7 */
         $carry7 = $h[7]->addInt(1 << 24)->shiftRight(25);
         $h[8] = $h[8]->addInt64($carry7);
         $h[7] = $h[7]->subInt64($carry7->shiftLeft(25));
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry0 */
         $carry0 = $h[0]->addInt(1 << 25)->shiftRight(26);
         $h[1] = $h[1]->addInt64($carry0);
         $h[0] = $h[0]->subInt64($carry0->shiftLeft(26));
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry2 */
         $carry2 = $h[2]->addInt(1 << 25)->shiftRight(26);
         $h[3] = $h[3]->addInt64($carry2);
         $h[2] = $h[2]->subInt64($carry2->shiftLeft(26));
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry4 */
         $carry4 = $h[4]->addInt(1 << 25)->shiftRight(26);
         $h[5] = $h[5]->addInt64($carry4);
         $h[4] = $h[4]->subInt64($carry4->shiftLeft(26));
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry6 */
         $carry6 = $h[6]->addInt(1 << 25)->shiftRight(26);
         $h[7] = $h[7]->addInt64($carry6);
         $h[6] = $h[6]->subInt64($carry6->shiftLeft(26));
 
-        /** @var ParagonIE_Sodium_Core32_Int32 $carry8 */
         $carry8 = $h[8]->addInt(1 << 25)->shiftRight(26);
         $h[9] = $h[9]->addInt64($carry8);
         $h[8] = $h[8]->subInt64($carry8->shiftLeft(26));
diff --git a/src/wp-includes/sodium_compat/src/Crypto.php b/src/wp-includes/sodium_compat/src/Crypto.php
index 3040763229..2e3383ff6f 100644
--- a/src/wp-includes/sodium_compat/src/Crypto.php
+++ b/src/wp-includes/sodium_compat/src/Crypto.php
@@ -819,8 +819,8 @@ public static function generichash_update($ctx, $message)
      */
     public static function keyExchange($my_sk, $their_pk, $client_pk, $server_pk)
     {
-        return self::generichash(
-            self::scalarmult($my_sk, $their_pk) .
+        return ParagonIE_Sodium_Compat::crypto_generichash(
+            ParagonIE_Sodium_Compat::crypto_scalarmult($my_sk, $their_pk) .
             $client_pk .
             $server_pk
         );
diff --git a/src/wp-includes/sodium_compat/src/File.php b/src/wp-includes/sodium_compat/src/File.php
index e675593c31..da6366b675 100644
--- a/src/wp-includes/sodium_compat/src/File.php
+++ b/src/wp-includes/sodium_compat/src/File.php
@@ -590,7 +590,6 @@ public static function sign($filePath, $secretKey)
         $az[0] = self::intToChr(self::chrToInt($az[0]) & 248);
         $az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64);
 
-        /** @var resource $hs */
         $hs = hash_init('sha512');
         hash_update($hs, self::substr($az, 32, 32));
         /** @var resource $hs */
@@ -610,7 +609,6 @@ public static function sign($filePath, $secretKey)
             ParagonIE_Sodium_Core_Ed25519::ge_scalarmult_base($nonce)
         );
 
-        /** @var resource $hs */
         $hs = hash_init('sha512');
         hash_update($hs, self::substr($sig, 0, 32));
         hash_update($hs, self::substr($pk, 0, 32));
@@ -719,7 +717,6 @@ public static function verify($sig, $filePath, $publicKey)
         /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A */
         $A = ParagonIE_Sodium_Core_Ed25519::ge_frombytes_negate_vartime($publicKey);
 
-        /** @var resource $hs */
         $hs = hash_init('sha512');
         hash_update($hs, self::substr($sig, 0, 32));
         hash_update($hs, self::substr($publicKey, 0, 32));
@@ -1079,7 +1076,7 @@ protected static function onetimeauth_verify(
      * @param resource|object $hash
      * @param resource $fp
      * @param int $size
-     * @return mixed (resource on PHP < 7.2, object on PHP >= 7.2)
+     * @return resource|object Resource on PHP < 7.2, HashContext object on PHP >= 7.2
      * @throws SodiumException
      * @throws TypeError
      * @psalm-suppress PossiblyInvalidArgument
@@ -1095,12 +1092,12 @@ public static function updateHashWithFile($hash, $fp, $size = 0)
             if (!is_resource($hash)) {
                 throw new TypeError('Argument 1 must be a resource, ' . gettype($hash) . ' given.');
             }
-
         } else {
             if (!is_object($hash)) {
                 throw new TypeError('Argument 1 must be an object (PHP 7.2+), ' . gettype($hash) . ' given.');
             }
         }
+
         if (!is_resource($fp)) {
             throw new TypeError('Argument 2 must be a resource, ' . gettype($fp) . ' given.');
         }
@@ -1167,7 +1164,6 @@ private static function sign_core32($filePath, $secretKey)
         $az[0] = self::intToChr(self::chrToInt($az[0]) & 248);
         $az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64);
 
-        /** @var resource $hs */
         $hs = hash_init('sha512');
         hash_update($hs, self::substr($az, 32, 32));
         /** @var resource $hs */
@@ -1187,7 +1183,6 @@ private static function sign_core32($filePath, $secretKey)
             ParagonIE_Sodium_Core32_Ed25519::ge_scalarmult_base($nonce)
         );
 
-        /** @var resource $hs */
         $hs = hash_init('sha512');
         hash_update($hs, self::substr($sig, 0, 32));
         hash_update($hs, self::substr($pk, 0, 32));
@@ -1272,7 +1267,6 @@ public static function verify_core32($sig, $filePath, $publicKey)
         /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A */
         $A = ParagonIE_Sodium_Core32_Ed25519::ge_frombytes_negate_vartime($publicKey);
 
-        /** @var resource $hs */
         $hs = hash_init('sha512');
         hash_update($hs, self::substr($sig, 0, 32));
         hash_update($hs, self::substr($publicKey, 0, 32));
