Index: wp-includes/sodium_compat/src/Core/Poly1305/State.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core/Poly1305/State.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Core/Poly1305/State.php	(date 1571493283137)
@@ -79,6 +79,29 @@
         $this->final = false;
     }
 
+    /**
+     * Zero internal buffer upon destruction
+     */
+    public function __destruct()
+    {
+        $this->r[0] ^= $this->r[0];
+        $this->r[1] ^= $this->r[1];
+        $this->r[2] ^= $this->r[2];
+        $this->r[3] ^= $this->r[3];
+        $this->r[4] ^= $this->r[4];
+        $this->h[0] ^= $this->h[0];
+        $this->h[1] ^= $this->h[1];
+        $this->h[2] ^= $this->h[2];
+        $this->h[3] ^= $this->h[3];
+        $this->h[4] ^= $this->h[4];
+        $this->pad[0] ^= $this->pad[0];
+        $this->pad[1] ^= $this->pad[1];
+        $this->pad[2] ^= $this->pad[2];
+        $this->pad[3] ^= $this->pad[3];
+        $this->leftover = 0;
+        $this->final = true;
+    }
+
     /**
      * @internal You should not use this directly from another application
      *
@@ -90,6 +113,9 @@
     public function update($message = '')
     {
         $bytes = self::strlen($message);
+        if ($bytes < 1) {
+            return $this;
+        }
 
         /* handle leftover */
         if ($this->leftover) {
@@ -111,7 +137,7 @@
             }
 
             $this->blocks(
-                static::intArrayToString($this->buffer),
+                self::intArrayToString($this->buffer),
                 ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
             );
             $this->leftover = 0;
@@ -296,7 +322,7 @@
             $this->final = true;
             $this->blocks(
                 self::substr(
-                    static::intArrayToString($this->buffer),
+                    self::intArrayToString($this->buffer),
                     0,
                     ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
                 ),
Index: wp-includes/sodium_compat/src/Core/Base64/Original.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core/Base64/Original.php	(date 1568244100287)
+++ wp-includes/sodium_compat/src/Core/Base64/Original.php	(date 1568244100287)
@@ -0,0 +1,248 @@
+<?php
+
+/**
+ * Class ParagonIE_Sodium_Core_Base64
+ *
+ *  Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
+ *  Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
+ */
+class ParagonIE_Sodium_Core_Base64_Original
+{
+    // COPY ParagonIE_Sodium_Core_Base64_Common STARTING HERE
+    /**
+     * Encode into Base64
+     *
+     * Base64 character set "[A-Z][a-z][0-9]+/"
+     *
+     * @param string $src
+     * @return string
+     * @throws TypeError
+     */
+    public static function encode($src)
+    {
+        return self::doEncode($src, true);
+    }
+
+    /**
+     * Encode into Base64, no = padding
+     *
+     * Base64 character set "[A-Z][a-z][0-9]+/"
+     *
+     * @param string $src
+     * @return string
+     * @throws TypeError
+     */
+    public static function encodeUnpadded($src)
+    {
+        return self::doEncode($src, false);
+    }
+
+    /**
+     * @param string $src
+     * @param bool $pad   Include = padding?
+     * @return string
+     * @throws TypeError
+     */
+    protected static function doEncode($src, $pad = true)
+    {
+        $dest = '';
+        $srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
+        // Main loop (no padding):
+        for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 3));
+            $b0 = $chunk[1];
+            $b1 = $chunk[2];
+            $b2 = $chunk[3];
+
+            $dest .=
+                self::encode6Bits(               $b0 >> 2       ) .
+                self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
+                self::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) .
+                self::encode6Bits(  $b2                     & 63);
+        }
+        // The last chunk, which may have padding:
+        if ($i < $srcLen) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
+            $b0 = $chunk[1];
+            if ($i + 1 < $srcLen) {
+                $b1 = $chunk[2];
+                $dest .=
+                    self::encode6Bits($b0 >> 2) .
+                    self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
+                    self::encode6Bits(($b1 << 2) & 63);
+                if ($pad) {
+                    $dest .= '=';
+                }
+            } else {
+                $dest .=
+                    self::encode6Bits( $b0 >> 2) .
+                    self::encode6Bits(($b0 << 4) & 63);
+                if ($pad) {
+                    $dest .= '==';
+                }
+            }
+        }
+        return $dest;
+    }
+
+    /**
+     * decode from base64 into binary
+     *
+     * Base64 character set "./[A-Z][a-z][0-9]"
+     *
+     * @param string $src
+     * @param bool $strictPadding
+     * @return string
+     * @throws RangeException
+     * @throws TypeError
+     * @psalm-suppress RedundantCondition
+     */
+    public static function decode($src, $strictPadding = false)
+    {
+        // Remove padding
+        $srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
+        if ($srcLen === 0) {
+            return '';
+        }
+
+        if ($strictPadding) {
+            if (($srcLen & 3) === 0) {
+                if ($src[$srcLen - 1] === '=') {
+                    $srcLen--;
+                    if ($src[$srcLen - 1] === '=') {
+                        $srcLen--;
+                    }
+                }
+            }
+            if (($srcLen & 3) === 1) {
+                throw new RangeException(
+                    'Incorrect padding'
+                );
+            }
+            if ($src[$srcLen - 1] === '=') {
+                throw new RangeException(
+                    'Incorrect padding'
+                );
+            }
+        } else {
+            $src = rtrim($src, '=');
+            $srcLen =  ParagonIE_Sodium_Core_Util::strlen($src);
+        }
+
+        $err = 0;
+        $dest = '';
+        // Main loop (no padding):
+        for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 4));
+            $c0 = self::decode6Bits($chunk[1]);
+            $c1 = self::decode6Bits($chunk[2]);
+            $c2 = self::decode6Bits($chunk[3]);
+            $c3 = self::decode6Bits($chunk[4]);
+
+            $dest .= pack(
+                'CCC',
+                ((($c0 << 2) | ($c1 >> 4)) & 0xff),
+                ((($c1 << 4) | ($c2 >> 2)) & 0xff),
+                ((($c2 << 6) | $c3) & 0xff)
+            );
+            $err |= ($c0 | $c1 | $c2 | $c3) >> 8;
+        }
+        // The last chunk, which may have padding:
+        if ($i < $srcLen) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
+            $c0 = self::decode6Bits($chunk[1]);
+
+            if ($i + 2 < $srcLen) {
+                $c1 = self::decode6Bits($chunk[2]);
+                $c2 = self::decode6Bits($chunk[3]);
+                $dest .= pack(
+                    'CC',
+                    ((($c0 << 2) | ($c1 >> 4)) & 0xff),
+                    ((($c1 << 4) | ($c2 >> 2)) & 0xff)
+                );
+                $err |= ($c0 | $c1 | $c2) >> 8;
+            } elseif ($i + 1 < $srcLen) {
+                $c1 = self::decode6Bits($chunk[2]);
+                $dest .= pack(
+                    'C',
+                    ((($c0 << 2) | ($c1 >> 4)) & 0xff)
+                );
+                $err |= ($c0 | $c1) >> 8;
+            } elseif ($i < $srcLen && $strictPadding) {
+                $err |= 1;
+            }
+        }
+        /** @var bool $check */
+        $check = ($err === 0);
+        if (!$check) {
+            throw new RangeException(
+                'Base64::decode() only expects characters in the correct base64 alphabet'
+            );
+        }
+        return $dest;
+    }
+    // COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
+
+    /**
+     * Uses bitwise operators instead of table-lookups to turn 6-bit integers
+     * into 8-bit integers.
+     *
+     * Base64 character set:
+     * [A-Z]      [a-z]      [0-9]      +     /
+     * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
+     *
+     * @param int $src
+     * @return int
+     */
+    protected static function decode6Bits($src)
+    {
+        $ret = -1;
+
+        // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
+        $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
+
+        // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
+        $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
+
+        // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
+        $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
+
+        // if ($src == 0x2b) $ret += 62 + 1;
+        $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63;
+
+        // if ($src == 0x2f) ret += 63 + 1;
+        $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64;
+
+        return $ret;
+    }
+
+    /**
+     * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+     * into 6-bit integers.
+     *
+     * @param int $src
+     * @return string
+     */
+    protected static function encode6Bits($src)
+    {
+        $diff = 0x41;
+
+        // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
+        $diff += ((25 - $src) >> 8) & 6;
+
+        // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
+        $diff -= ((51 - $src) >> 8) & 75;
+
+        // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15
+        $diff -= ((61 - $src) >> 8) & 15;
+
+        // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3
+        $diff += ((62 - $src) >> 8) & 3;
+
+        return pack('C', $src + $diff);
+    }
+}
Index: wp-includes/sodium_compat/LICENSE
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/LICENSE	(date 1571337483000)
+++ wp-includes/sodium_compat/LICENSE	(date 1571498691051)
@@ -1,10 +1,10 @@
 /*
  * ISC License
  *
- * Copyright (c) 2016-2018
+ * Copyright (c) 2016-2019
  * Paragon Initiative Enterprises <security at paragonie dot com>
  *
- * Copyright (c) 2013-2018
+ * Copyright (c) 2013-2019
  * Frank Denis <j at pureftpd dot org>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
Index: wp-includes/sodium_compat/src/Core/Base64/UrlSafe.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core/Base64/UrlSafe.php	(date 1568244100305)
+++ wp-includes/sodium_compat/src/Core/Base64/UrlSafe.php	(date 1568244100305)
@@ -0,0 +1,247 @@
+<?php
+
+/**
+ * Class ParagonIE_Sodium_Core_Base64UrlSafe
+ *
+ *  Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
+ *  Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
+ */
+class ParagonIE_Sodium_Core_Base64_UrlSafe
+{
+    // COPY ParagonIE_Sodium_Core_Base64_Common STARTING HERE
+    /**
+     * Encode into Base64
+     *
+     * Base64 character set "[A-Z][a-z][0-9]+/"
+     *
+     * @param string $src
+     * @return string
+     * @throws TypeError
+     */
+    public static function encode($src)
+    {
+        return self::doEncode($src, true);
+    }
+
+    /**
+     * Encode into Base64, no = padding
+     *
+     * Base64 character set "[A-Z][a-z][0-9]+/"
+     *
+     * @param string $src
+     * @return string
+     * @throws TypeError
+     */
+    public static function encodeUnpadded($src)
+    {
+        return self::doEncode($src, false);
+    }
+
+    /**
+     * @param string $src
+     * @param bool $pad   Include = padding?
+     * @return string
+     * @throws TypeError
+     */
+    protected static function doEncode($src, $pad = true)
+    {
+        $dest = '';
+        $srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
+        // Main loop (no padding):
+        for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 3));
+            $b0 = $chunk[1];
+            $b1 = $chunk[2];
+            $b2 = $chunk[3];
+
+            $dest .=
+                self::encode6Bits(               $b0 >> 2       ) .
+                self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
+                self::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) .
+                self::encode6Bits(  $b2                     & 63);
+        }
+        // The last chunk, which may have padding:
+        if ($i < $srcLen) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
+            $b0 = $chunk[1];
+            if ($i + 1 < $srcLen) {
+                $b1 = $chunk[2];
+                $dest .=
+                    self::encode6Bits($b0 >> 2) .
+                    self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
+                    self::encode6Bits(($b1 << 2) & 63);
+                if ($pad) {
+                    $dest .= '=';
+                }
+            } else {
+                $dest .=
+                    self::encode6Bits( $b0 >> 2) .
+                    self::encode6Bits(($b0 << 4) & 63);
+                if ($pad) {
+                    $dest .= '==';
+                }
+            }
+        }
+        return $dest;
+    }
+
+    /**
+     * decode from base64 into binary
+     *
+     * Base64 character set "./[A-Z][a-z][0-9]"
+     *
+     * @param string $src
+     * @param bool $strictPadding
+     * @return string
+     * @throws RangeException
+     * @throws TypeError
+     * @psalm-suppress RedundantCondition
+     */
+    public static function decode($src, $strictPadding = false)
+    {
+        // Remove padding
+        $srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
+        if ($srcLen === 0) {
+            return '';
+        }
+
+        if ($strictPadding) {
+            if (($srcLen & 3) === 0) {
+                if ($src[$srcLen - 1] === '=') {
+                    $srcLen--;
+                    if ($src[$srcLen - 1] === '=') {
+                        $srcLen--;
+                    }
+                }
+            }
+            if (($srcLen & 3) === 1) {
+                throw new RangeException(
+                    'Incorrect padding'
+                );
+            }
+            if ($src[$srcLen - 1] === '=') {
+                throw new RangeException(
+                    'Incorrect padding'
+                );
+            }
+        } else {
+            $src = rtrim($src, '=');
+            $srcLen =  ParagonIE_Sodium_Core_Util::strlen($src);
+        }
+
+        $err = 0;
+        $dest = '';
+        // Main loop (no padding):
+        for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 4));
+            $c0 = self::decode6Bits($chunk[1]);
+            $c1 = self::decode6Bits($chunk[2]);
+            $c2 = self::decode6Bits($chunk[3]);
+            $c3 = self::decode6Bits($chunk[4]);
+
+            $dest .= pack(
+                'CCC',
+                ((($c0 << 2) | ($c1 >> 4)) & 0xff),
+                ((($c1 << 4) | ($c2 >> 2)) & 0xff),
+                ((($c2 << 6) | $c3) & 0xff)
+            );
+            $err |= ($c0 | $c1 | $c2 | $c3) >> 8;
+        }
+        // The last chunk, which may have padding:
+        if ($i < $srcLen) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
+            $c0 = self::decode6Bits($chunk[1]);
+
+            if ($i + 2 < $srcLen) {
+                $c1 = self::decode6Bits($chunk[2]);
+                $c2 = self::decode6Bits($chunk[3]);
+                $dest .= pack(
+                    'CC',
+                    ((($c0 << 2) | ($c1 >> 4)) & 0xff),
+                    ((($c1 << 4) | ($c2 >> 2)) & 0xff)
+                );
+                $err |= ($c0 | $c1 | $c2) >> 8;
+            } elseif ($i + 1 < $srcLen) {
+                $c1 = self::decode6Bits($chunk[2]);
+                $dest .= pack(
+                    'C',
+                    ((($c0 << 2) | ($c1 >> 4)) & 0xff)
+                );
+                $err |= ($c0 | $c1) >> 8;
+            } elseif ($i < $srcLen && $strictPadding) {
+                $err |= 1;
+            }
+        }
+        /** @var bool $check */
+        $check = ($err === 0);
+        if (!$check) {
+            throw new RangeException(
+                'Base64::decode() only expects characters in the correct base64 alphabet'
+            );
+        }
+        return $dest;
+    }
+    // COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
+    /**
+     * Uses bitwise operators instead of table-lookups to turn 6-bit integers
+     * into 8-bit integers.
+     *
+     * Base64 character set:
+     * [A-Z]      [a-z]      [0-9]      +     /
+     * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
+     *
+     * @param int $src
+     * @return int
+     */
+    protected static function decode6Bits($src)
+    {
+        $ret = -1;
+
+        // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
+        $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
+
+        // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
+        $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
+
+        // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
+        $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
+
+        // if ($src == 0x2c) $ret += 62 + 1;
+        $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63;
+
+        // if ($src == 0x5f) ret += 63 + 1;
+        $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64;
+
+        return $ret;
+    }
+
+    /**
+     * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+     * into 6-bit integers.
+     *
+     * @param int $src
+     * @return string
+     */
+    protected static function encode6Bits($src)
+    {
+        $diff = 0x41;
+
+        // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
+        $diff += ((25 - $src) >> 8) & 6;
+
+        // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
+        $diff -= ((51 - $src) >> 8) & 75;
+
+        // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13
+        $diff -= ((61 - $src) >> 8) & 13;
+
+        // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3
+        $diff += ((62 - $src) >> 8) & 49;
+
+        return pack('C', $src + $diff);
+    }
+}
Index: wp-includes/sodium_compat/composer.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/composer.json	(date 1571337483000)
+++ wp-includes/sodium_compat/composer.json	(date 1571498691052)
@@ -54,7 +54,7 @@
     "paragonie/random_compat": ">=1"
   },
   "require-dev": {
-    "phpunit/phpunit": "^3|^4|^5"
+    "phpunit/phpunit": "^3|^4|^5|^6|^7"
   },
   "suggest": {
     "ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
Index: wp-includes/sodium_compat/src/Core/BLAKE2b.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core/BLAKE2b.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Core/BLAKE2b.php	(date 1571498691053)
@@ -88,10 +88,10 @@
     {
         $l = ($x[1] + $y[1]) & 0xffffffff;
         return self::new64(
-            $x[0] + $y[0] + (
+            (int) ($x[0] + $y[0] + (
                 ($l < $x[1]) ? 1 : 0
-            ),
-            $l
+            )),
+            (int) $l
         );
     }
 
@@ -132,8 +132,8 @@
             throw new SodiumException('y[1] is not an integer');
         }
         return self::new64(
-            (int) ($x[0] ^ $y[0]),
-            (int) ($x[1] ^ $y[1])
+            (int) (($x[0] ^ $y[0]) & 0xffffffff),
+            (int) (($x[1] ^ $y[1]) & 0xffffffff)
         );
     }
 
@@ -299,12 +299,13 @@
      */
     protected static function context()
     {
-        $ctx    = new SplFixedArray(5);
+        $ctx    = new SplFixedArray(6);
         $ctx[0] = new SplFixedArray(8);   // h
         $ctx[1] = new SplFixedArray(2);   // t
         $ctx[2] = new SplFixedArray(2);   // f
         $ctx[3] = new SplFixedArray(256); // buf
         $ctx[4] = 0;                      // buflen
+        $ctx[5] = 0;                      // last_node (uint8_t)
 
         for ($i = 8; $i--;) {
             $ctx[0][$i] = self::$iv[$i];
@@ -550,6 +551,8 @@
      *
      * @param SplFixedArray|null $key
      * @param int $outlen
+     * @param SplFixedArray|null $salt
+     * @param SplFixedArray|null $personal
      * @return SplFixedArray
      * @throws SodiumException
      * @throws TypeError
@@ -559,8 +562,12 @@
      * @psalm-suppress MixedArrayAssignment
      * @psalm-suppress MixedArrayOffset
      */
-    public static function init($key = null, $outlen = 64)
-    {
+    public static function init(
+        $key = null,
+        $outlen = 64,
+        $salt = null,
+        $personal = null
+    ) {
         self::pseudoConstructor();
         $klen = 0;
 
@@ -578,6 +585,7 @@
         $ctx = self::context();
 
         $p = new SplFixedArray(64);
+        // Zero our param buffer...
         for ($i = 64; --$i;) {
             $p[$i] = 0;
         }
@@ -587,10 +595,32 @@
         $p[2] = 1;       // fanout
         $p[3] = 1;       // depth
 
+        if ($salt instanceof SplFixedArray) {
+            // salt: [32] through [47]
+            for ($i = 0; $i < 16; ++$i) {
+                $p[32 + $i] = (int) $salt[$i];
+            }
+        }
+        if ($personal instanceof SplFixedArray) {
+            // personal: [48] through [63]
+            for ($i = 0; $i < 16; ++$i) {
+                $p[48 + $i] = (int) $personal[$i];
+            }
+        }
+
         $ctx[0][0] = self::xor64(
             $ctx[0][0],
             self::load64($p, 0)
         );
+        if ($salt instanceof SplFixedArray || $personal instanceof SplFixedArray) {
+            // We need to do what blake2b_init_param() does:
+            for ($i = 1; $i < 8; ++$i) {
+                $ctx[0][$i] = self::xor64(
+                    $ctx[0][$i],
+                    self::load64($p, $i << 3)
+                );
+            }
+        }
 
         if ($klen > 0 && $key instanceof SplFixedArray) {
             $block = new SplFixedArray(128);
@@ -601,6 +631,7 @@
                 $block[$i] = $key[$i];
             }
             self::update($ctx, $block, 128);
+            $ctx[4] = 128;
         }
 
         return $ctx;
@@ -693,7 +724,7 @@
             self::intToChr(($ctx4 >> 56) & 0xff)
         ));
         # uint8_t last_node;
-        return $str . "\x00";
+        return $str . self::intToChr($ctx[5]) . str_repeat("\x00", 23);
     }
 
     /**
@@ -746,7 +777,6 @@
         # uint8_t buf[2 * 128];
         $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256));
 
-
         # uint8_t buf[2 * 128];
         $int = 0;
         for ($i = 0; $i < 8; ++$i) {
Index: wp-includes/sodium_compat/src/Core/SecretStream/State.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core/SecretStream/State.php	(date 1568244100307)
+++ wp-includes/sodium_compat/src/Core/SecretStream/State.php	(date 1568244100307)
@@ -0,0 +1,163 @@
+<?php
+
+/**
+ * Class ParagonIE_Sodium_Core_SecretStream_State
+ */
+class ParagonIE_Sodium_Core_SecretStream_State
+{
+    /** @var string $key */
+    protected $key;
+
+    /** @var int $counter */
+    protected $counter;
+
+    /** @var string $nonce */
+    protected $nonce;
+
+    /** @var string $_pad */
+    protected $_pad;
+
+    /**
+     * ParagonIE_Sodium_Core_SecretStream_State constructor.
+     * @param string $key
+     * @param string|null $nonce
+     */
+    public function __construct($key, $nonce = null)
+    {
+        $this->key = $key;
+        $this->counter = 1;
+        if (is_null($nonce)) {
+            $nonce = str_repeat("\0", 12);
+        }
+        $this->nonce = str_pad($nonce, 12, "\0", STR_PAD_RIGHT);;
+        $this->_pad = str_repeat("\0", 4);
+    }
+
+    /**
+     * @return self
+     */
+    public function counterReset()
+    {
+        $this->counter = 1;
+        $this->_pad = str_repeat("\0", 4);
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getKey()
+    {
+        return $this->key;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCounter()
+    {
+        return ParagonIE_Sodium_Core_Util::store32_le($this->counter);
+    }
+
+    /**
+     * @return string
+     */
+    public function getNonce()
+    {
+        if (!is_string($this->nonce)) {
+            $this->nonce = str_repeat("\0", 12);
+        }
+        if (ParagonIE_Sodium_Core_Util::strlen($this->nonce) !== 12) {
+            $this->nonce = str_pad($this->nonce, 12, "\0", STR_PAD_RIGHT);
+        }
+        return $this->nonce;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCombinedNonce()
+    {
+        return $this->getCounter() .
+            ParagonIE_Sodium_Core_Util::substr($this->getNonce(), 0, 8);
+    }
+
+    /**
+     * @return self
+     */
+    public function incrementCounter()
+    {
+        ++$this->counter;
+        return $this;
+    }
+
+    /**
+     * @return bool
+     */
+    public function needsRekey()
+    {
+        return ($this->counter & 0xffff) === 0;
+    }
+
+    /**
+     * @param string $newKeyAndNonce
+     * @return self
+     */
+    public function rekey($newKeyAndNonce)
+    {
+        $this->key = ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 0, 32);
+        $this->nonce = str_pad(
+            ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 32),
+            12,
+            "\0",
+            STR_PAD_RIGHT
+        );
+        return $this;
+    }
+
+    /**
+     * @param string $str
+     * @return self
+     */
+    public function xorNonce($str)
+    {
+        $this->nonce = ParagonIE_Sodium_Core_Util::xorStrings(
+            $this->getNonce(),
+            str_pad(
+                ParagonIE_Sodium_Core_Util::substr($str, 0, 8),
+                12,
+                "\0",
+                STR_PAD_RIGHT
+            )
+        );
+        return $this;
+    }
+
+    /**
+     * @param string $string
+     * @return self
+     */
+    public static function fromString($string)
+    {
+        $state = new ParagonIE_Sodium_Core_SecretStream_State(
+            ParagonIE_Sodium_Core_Util::substr($string, 0, 32)
+        );
+        $state->counter = ParagonIE_Sodium_Core_Util::load_4(
+            ParagonIE_Sodium_Core_Util::substr($string, 32, 4)
+        );
+        $state->nonce = ParagonIE_Sodium_Core_Util::substr($string, 36, 12);
+        $state->_pad = ParagonIE_Sodium_Core_Util::substr($string, 48, 8);
+        return $state;
+    }
+
+    /**
+     * @return string
+     */
+    public function toString()
+    {
+        return $this->key .
+            $this->getCounter() .
+            $this->nonce .
+            $this->_pad;
+    }
+}
Index: wp-includes/sodium_compat/src/Core/Ed25519.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core/Ed25519.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Core/Ed25519.php	(date 1571412398304)
@@ -276,7 +276,7 @@
         if (self::strlen($sig) < 64) {
             throw new SodiumException('Signature is too short');
         }
-        if (self::check_S_lt_L(self::substr($sig, 32, 32))) {
+        if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) {
             throw new SodiumException('S < L - Invalid signature');
         }
         if (self::small_order($sig)) {
Index: wp-includes/sodium_compat/lib/constants.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/lib/constants.php	(date 1571337483000)
+++ wp-includes/sodium_compat/lib/constants.php	(date 1571412398298)
@@ -1,6 +1,8 @@
 <?php
 namespace Sodium;
 
+require_once dirname(dirname(__FILE__)) . '/autoload.php';
+
 use ParagonIE_Sodium_Compat;
 
 const CRYPTO_AEAD_AES256GCM_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_KEYBYTES;
Index: wp-includes/sodium_compat/src/PHP52/SplFixedArray.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/PHP52/SplFixedArray.php	(date 1571493283171)
+++ wp-includes/sodium_compat/src/PHP52/SplFixedArray.php	(date 1571493283171)
@@ -0,0 +1,187 @@
+<?php
+
+if (class_exists('SplFixedArray')) {
+    return;
+}
+
+/**
+ * The SplFixedArray class provides the main functionalities of array. The
+ * main differences between a SplFixedArray and a normal PHP array is that
+ * the SplFixedArray is of fixed length and allows only integers within
+ * the range as indexes. The advantage is that it allows a faster array
+ * implementation.
+ */
+class SplFixedArray implements Iterator, ArrayAccess, Countable
+{
+    /** @var array<int, mixed> */
+    private $internalArray = array();
+
+    /** @var int $size */
+    private $size = 0;
+
+    /**
+     * SplFixedArray constructor.
+     * @param int $size
+     */
+    public function __construct($size = 0)
+    {
+        $this->size = $size;
+        $this->internalArray = array();
+    }
+
+    /**
+     * @return int
+     */
+    public function count()
+    {
+        return count($this->internalArray);
+    }
+
+    /**
+     * @return array
+     */
+    public function toArray()
+    {
+        ksort($this->internalArray);
+        return (array) $this->internalArray;
+    }
+
+    /**
+     * @param array $array
+     * @param bool $save_indexes
+     * @return SplFixedArray
+     * @psalm-suppress MixedAssignment
+     */
+    public static function fromArray(array $array, $save_indexes = true)
+    {
+        $self = new SplFixedArray(count($array));
+        if($save_indexes) {
+            foreach($array as $key => $value) {
+                $self[(int) $key] = $value;
+            }
+        } else {
+            $i = 0;
+            foreach (array_values($array) as $value) {
+                $self[$i] = $value;
+                $i++;
+            }
+        }
+        return $self;
+    }
+
+    /**
+     * @return int
+     */
+    public function getSize()
+    {
+        return $this->size;
+    }
+
+    /**
+     * @param int $size
+     * @return bool
+     */
+    public function setSize($size)
+    {
+        $this->size = $size;
+        return true;
+    }
+
+    /**
+     * @param string|int $index
+     * @return bool
+     */
+    public function offsetExists($index)
+    {
+        return array_key_exists((int) $index, $this->internalArray);
+    }
+
+    /**
+     * @param string|int $index
+     * @return mixed
+     */
+    public function offsetGet($index)
+    {
+        return $this->internalArray[(int) $index];
+    }
+
+    /**
+     * @param string|int $index
+     * @param mixed $newval
+     * @psalm-suppress MixedAssignment
+     */
+    public function offsetSet($index, $newval)
+    {
+        $this->internalArray[(int) $index] = $newval;
+    }
+
+    /**
+     * @param string|int $index
+     */
+    public function offsetUnset($index)
+    {
+        unset($this->internalArray[(int) $index]);
+    }
+
+    /**
+     * Rewind iterator back to the start
+     * @link https://php.net/manual/en/splfixedarray.rewind.php
+     * @return void
+     * @since 5.3.0
+     */
+    public function rewind()
+    {
+        reset($this->internalArray);
+    }
+
+    /**
+     * Return current array entry
+     * @link https://php.net/manual/en/splfixedarray.current.php
+     * @return mixed The current element value.
+     * @since 5.3.0
+     */
+    public function current()
+    {
+        return current($this->internalArray);
+    }
+
+    /**
+     * Return current array index
+     * @return int The current array index.
+     */
+    public function key()
+    {
+        return key($this->internalArray);
+    }
+
+    /**
+     * @return void
+     */
+    public function next()
+    {
+        next($this->internalArray);
+    }
+
+    /**
+     * Check whether the array contains more elements
+     * @link https://php.net/manual/en/splfixedarray.valid.php
+     * @return bool true if the array contains any more elements, false otherwise.
+     */
+    public function valid()
+    {
+        if (empty($this->internalArray)) {
+            return false;
+        }
+        $result = next($this->internalArray) !== false;
+        prev($this->internalArray);
+        return $result;
+    }
+
+    /**
+     * Do nothing.
+     */
+    public function __wakeup()
+    {
+        // NOP
+    }
+}
\ No newline at end of file
Index: wp-includes/sodium_compat/src/Core/XChaCha20.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core/XChaCha20.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Core/XChaCha20.php	(date 1562948578399)
@@ -36,6 +36,33 @@
         );
     }
 
+    /**
+     * @internal You should not use this directly from another application
+     *
+     * @param int $len
+     * @param string $nonce
+     * @param string $key
+     * @return string
+     * @throws SodiumException
+     * @throws TypeError
+     */
+    public static function ietfStream($len = 64, $nonce = '', $key = '')
+    {
+        if (self::strlen($nonce) !== 24) {
+            throw new SodiumException('Nonce must be 24 bytes long');
+        }
+        return self::encryptBytes(
+            new ParagonIE_Sodium_Core_ChaCha20_IetfCtx(
+                self::hChaCha20(
+                    self::substr($nonce, 0, 16),
+                    $key
+                ),
+                "\x00\x00\x00\x00" . self::substr($nonce, 16, 8)
+            ),
+            str_repeat("\x00", $len)
+        );
+    }
+
     /**
      * @internal You should not use this directly from another application
      *
@@ -61,4 +88,30 @@
             $message
         );
     }
+
+    /**
+     * @internal You should not use this directly from another application
+     *
+     * @param string $message
+     * @param string $nonce
+     * @param string $key
+     * @param string $ic
+     * @return string
+     * @throws SodiumException
+     * @throws TypeError
+     */
+    public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
+    {
+        if (self::strlen($nonce) !== 24) {
+            throw new SodiumException('Nonce must be 24 bytes long');
+        }
+        return self::encryptBytes(
+            new ParagonIE_Sodium_Core_ChaCha20_IetfCtx(
+                self::hChaCha20(self::substr($nonce, 0, 16), $key),
+                "\x00\x00\x00\x00" . self::substr($nonce, 16, 8),
+                $ic
+            ),
+            $message
+        );
+    }
 }
Index: wp-includes/sodium_compat/lib/php72compat_const.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/lib/php72compat_const.php	(date 1571412398301)
+++ wp-includes/sodium_compat/lib/php72compat_const.php	(date 1571412398301)
@@ -0,0 +1,90 @@
+<?php
+
+const SODIUM_LIBRARY_MAJOR_VERSION = 9;
+const SODIUM_LIBRARY_MINOR_VERSION = 1;
+const SODIUM_LIBRARY_VERSION = '1.0.8';
+
+const SODIUM_BASE64_VARIANT_ORIGINAL = 1;
+const SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING = 3;
+const SODIUM_BASE64_VARIANT_URLSAFE = 5;
+const SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING = 7;
+const SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES = 32;
+const SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES = 0;
+const SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES = 12;
+const SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES = 16;
+const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = 32;
+const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = 0;
+const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = 8;
+const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = 16;
+const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = 32;
+const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = 0;
+const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = 12;
+const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = 16;
+const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES = 32;
+const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES = 0;
+const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES = 24;
+const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES = 16;
+const SODIUM_CRYPTO_AUTH_BYTES = 32;
+const SODIUM_CRYPTO_AUTH_KEYBYTES = 32;
+const SODIUM_CRYPTO_BOX_SEALBYTES = 16;
+const SODIUM_CRYPTO_BOX_SECRETKEYBYTES = 32;
+const SODIUM_CRYPTO_BOX_PUBLICKEYBYTES = 32;
+const SODIUM_CRYPTO_BOX_KEYPAIRBYTES = 64;
+const SODIUM_CRYPTO_BOX_MACBYTES = 16;
+const SODIUM_CRYPTO_BOX_NONCEBYTES = 24;
+const SODIUM_CRYPTO_BOX_SEEDBYTES = 32;
+const SODIUM_CRYPTO_KDF_BYTES_MIN = 16;
+const SODIUM_CRYPTO_KDF_BYTES_MAX = 64;
+const SODIUM_CRYPTO_KDF_CONTEXTBYTES = 8;
+const SODIUM_CRYPTO_KDF_KEYBYTES = 32;
+const SODIUM_CRYPTO_KX_BYTES = 32;
+const SODIUM_CRYPTO_KX_PRIMITIVE = 'x25519blake2b';
+const SODIUM_CRYPTO_KX_SEEDBYTES = 32;
+const SODIUM_CRYPTO_KX_KEYPAIRBYTES = 64;
+const SODIUM_CRYPTO_KX_PUBLICKEYBYTES = 32;
+const SODIUM_CRYPTO_KX_SECRETKEYBYTES = 32;
+const SODIUM_CRYPTO_KX_SESSIONKEYBYTES = 32;
+const SODIUM_CRYPTO_GENERICHASH_BYTES = 32;
+const SODIUM_CRYPTO_GENERICHASH_BYTES_MIN = 16;
+const SODIUM_CRYPTO_GENERICHASH_BYTES_MAX = 64;
+const SODIUM_CRYPTO_GENERICHASH_KEYBYTES = 32;
+const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN = 16;
+const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX = 64;
+const SODIUM_CRYPTO_PWHASH_SALTBYTES = 16;
+const SODIUM_CRYPTO_PWHASH_STRPREFIX = '$argon2id$';
+const SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13 = 1;
+const SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13 = 2;
+const SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE = 33554432;
+const SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE = 4;
+const SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE = 134217728;
+const SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE = 6;
+const SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE = 536870912;
+const SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE = 8;
+const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES = 32;
+const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX = '$7$';
+const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE = 534288;
+const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216;
+const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432;
+const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824;
+const SODIUM_CRYPTO_SCALARMULT_BYTES = 32;
+const SODIUM_CRYPTO_SCALARMULT_SCALARBYTES = 32;
+const SODIUM_CRYPTO_SHORTHASH_BYTES = 8;
+const SODIUM_CRYPTO_SHORTHASH_KEYBYTES = 16;
+const SODIUM_CRYPTO_SECRETBOX_KEYBYTES = 32;
+const SODIUM_CRYPTO_SECRETBOX_MACBYTES = 16;
+const SODIUM_CRYPTO_SECRETBOX_NONCEBYTES = 24;
+const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17;
+const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24;
+const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32;
+const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0;
+const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1;
+const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2;
+const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3;
+const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80;
+const SODIUM_CRYPTO_SIGN_BYTES = 64;
+const SODIUM_CRYPTO_SIGN_SEEDBYTES = 32;
+const SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES = 32;
+const SODIUM_CRYPTO_SIGN_SECRETKEYBYTES = 64;
+const SODIUM_CRYPTO_SIGN_KEYPAIRBYTES = 96;
+const SODIUM_CRYPTO_STREAM_KEYBYTES = 32;
+const SODIUM_CRYPTO_STREAM_NONCEBYTES = 24;
Index: wp-includes/sodium_compat/lib/sodium_compat.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/lib/sodium_compat.php	(date 1571337483000)
+++ wp-includes/sodium_compat/lib/sodium_compat.php	(date 1571412398303)
@@ -1,6 +1,8 @@
 <?php
 namespace Sodium;
 
+require_once dirname(dirname(__FILE__)) . '/autoload.php';
+
 use ParagonIE_Sodium_Compat;
 
 /**
Index: wp-includes/sodium_compat/lib/php72compat.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/lib/php72compat.php	(date 1571337483000)
+++ wp-includes/sodium_compat/lib/php72compat.php	(date 1571412398300)
@@ -1,5 +1,7 @@
 <?php
 
+require_once dirname(dirname(__FILE__)) . '/autoload.php';
+
 /**
  * This file will monkey patch the pure-PHP implementation in place of the
  * PECL functions and constants, but only if they do not already exist.
@@ -8,6 +10,10 @@
  * ParagonIE_Sodium_Compat method or class constant, respectively.
  */
 foreach (array(
+    'BASE64_VARIANT_ORIGINAL',
+    'BASE64_VARIANT_ORIGINAL_NO_PADDING',
+    'BASE64_VARIANT_URLSAFE',
+    'BASE64_VARIANT_URLSAFE_NO_PADDING',
     'CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES',
     'CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES',
     'CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES',
@@ -29,10 +35,17 @@
     'CRYPTO_BOX_MACBYTES',
     'CRYPTO_BOX_NONCEBYTES',
     'CRYPTO_BOX_SEEDBYTES',
+    'CRYPTO_KDF_BYTES_MIN',
+    'CRYPTO_KDF_BYTES_MAX',
+    'CRYPTO_KDF_CONTEXTBYTES',
+    'CRYPTO_KDF_KEYBYTES',
     'CRYPTO_KX_BYTES',
+    'CRYPTO_KX_KEYPAIRBYTES',
+    'CRYPTO_KX_PRIMITIVE',
     'CRYPTO_KX_SEEDBYTES',
     'CRYPTO_KX_PUBLICKEYBYTES',
     'CRYPTO_KX_SECRETKEYBYTES',
+    'CRYPTO_KX_SESSIONKEYBYTES',
     'CRYPTO_GENERICHASH_BYTES',
     'CRYPTO_GENERICHASH_BYTES_MIN',
     'CRYPTO_GENERICHASH_BYTES_MAX',
@@ -56,6 +69,14 @@
     'CRYPTO_SECRETBOX_KEYBYTES',
     'CRYPTO_SECRETBOX_MACBYTES',
     'CRYPTO_SECRETBOX_NONCEBYTES',
+    'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES',
+    'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES',
+    'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES',
+    'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH',
+    'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL',
+    'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY',
+    'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL',
+    'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX',
     'CRYPTO_SIGN_BYTES',
     'CRYPTO_SIGN_SEEDBYTES',
     'CRYPTO_SIGN_PUBLICKEYBYTES',
@@ -68,11 +89,52 @@
     'VERSION_STRING'
     ) as $constant
 ) {
-    if (!defined("SODIUM_$constant")) {
+    if (!defined("SODIUM_$constant") && defined("ParagonIE_Sodium_Compat::$constant")) {
         define("SODIUM_$constant", constant("ParagonIE_Sodium_Compat::$constant"));
     }
 }
-
+if (!is_callable('sodium_add')) {
+    /**
+     * @see ParagonIE_Sodium_Compat::add()
+     * @param string $val
+     * @param string $addv
+     * @return void
+     * @throws SodiumException
+     */
+    function sodium_add(&$val, $addv)
+    {
+        ParagonIE_Sodium_Compat::add($val, $addv);
+    }
+}
+if (!is_callable('sodium_base642bin')) {
+    /**
+     * @see ParagonIE_Sodium_Compat::bin2base64()
+     * @param string $string
+     * @param int $variant
+     * @param string $ignore
+     * @return string
+     * @throws SodiumException
+     * @throws TypeError
+     */
+    function sodium_base642bin($string, $variant, $ignore ='')
+    {
+        return ParagonIE_Sodium_Compat::base642bin($string, $variant, $ignore);
+    }
+}
+if (!is_callable('sodium_bin2base64')) {
+    /**
+     * @see ParagonIE_Sodium_Compat::bin2base64()
+     * @param string $string
+     * @param int $variant
+     * @return string
+     * @throws SodiumException
+     * @throws TypeError
+     */
+    function sodium_bin2base64($string, $variant)
+    {
+        return ParagonIE_Sodium_Compat::bin2base64($string, $variant);
+    }
+}
 if (!is_callable('sodium_bin2hex')) {
     /**
      * @see ParagonIE_Sodium_Compat::hex2bin()
@@ -186,6 +248,7 @@
     /**
      * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_keygen()
      * @return string
+     * @throws Exception
      */
     function sodium_crypto_aead_chacha20poly1305_keygen()
     {
@@ -232,6 +295,7 @@
     /**
      * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_keygen()
      * @return string
+     * @throws Exception
      */
     function sodium_crypto_aead_chacha20poly1305_ietf_keygen()
     {
@@ -278,6 +342,7 @@
     /**
      * @see ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_keygen()
      * @return string
+     * @throws Exception
      */
     function sodium_crypto_aead_xchacha20poly1305_ietf_keygen()
     {
@@ -302,6 +367,7 @@
     /**
      * @see ParagonIE_Sodium_Compat::crypto_auth_keygen()
      * @return string
+     * @throws Exception
      */
     function sodium_crypto_auth_keygen()
     {
@@ -516,6 +582,7 @@
     /**
      * @see ParagonIE_Sodium_Compat::crypto_generichash_keygen()
      * @return string
+     * @throws Exception
      */
     function sodium_crypto_generichash_keygen()
     {
@@ -536,6 +603,37 @@
         ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $message);
     }
 }
+if (!is_callable('sodium_crypto_kdf_keygen')) {
+    /**
+     * @see ParagonIE_Sodium_Compat::crypto_kdf_keygen()
+     * @return string
+     * @throws Exception
+     */
+    function sodium_crypto_kdf_keygen()
+    {
+        return ParagonIE_Sodium_Compat::crypto_kdf_keygen();
+    }
+}
+if (!is_callable('sodium_crypto_kdf_derive_from_key')) {
+    /**
+     * @see ParagonIE_Sodium_Compat::crypto_kdf_derive_from_key()
+     * @param int $subkey_len
+     * @param int $subkey_id
+     * @param string $context
+     * @param string $key
+     * @return string
+     * @throws Exception
+     */
+    function sodium_crypto_kdf_derive_from_key($subkey_len, $subkey_id, $context, $key)
+    {
+        return ParagonIE_Sodium_Compat::crypto_kdf_derive_from_key(
+            $subkey_len,
+            $subkey_id,
+            $context,
+            $key
+        );
+    }
+}
 if (!is_callable('sodium_crypto_kx')) {
     /**
      * @see ParagonIE_Sodium_Compat::crypto_kx()
@@ -557,6 +655,73 @@
         );
     }
 }
+if (!is_callable('sodium_crypto_kx_seed_keypair')) {
+    /**
+     * @param string $seed
+     * @return string
+     * @throws Exception
+     */
+    function sodium_crypto_kx_seed_keypair($seed)
+    {
+        return ParagonIE_Sodium_Compat::crypto_kx_seed_keypair($seed);
+    }
+}
+if (!is_callable('sodium_crypto_kx_keypair')) {
+    /**
+     * @return string
+     * @throws Exception
+     */
+    function sodium_crypto_kx_keypair()
+    {
+        return ParagonIE_Sodium_Compat::crypto_kx_keypair();
+    }
+}
+if (!is_callable('sodium_crypto_kx_client_session_keys')) {
+    /**
+     * @param string $keypair
+     * @param string $serverPublicKey
+     * @return array{0: string, 1: string}
+     * @throws SodiumException
+     */
+    function sodium_crypto_kx_client_session_keys($keypair, $serverPublicKey)
+    {
+        return ParagonIE_Sodium_Compat::crypto_kx_client_session_keys($keypair, $serverPublicKey);
+    }
+}
+if (!is_callable('sodium_crypto_kx_server_session_keys')) {
+    /**
+     * @param string $keypair
+     * @param string $clientPublicKey
+     * @return array{0: string, 1: string}
+     * @throws SodiumException
+     */
+    function sodium_crypto_kx_server_session_keys($keypair, $clientPublicKey)
+    {
+        return ParagonIE_Sodium_Compat::crypto_kx_server_session_keys($keypair, $clientPublicKey);
+    }
+}
+if (!is_callable('sodium_crypto_kx_secretkey')) {
+    /**
+     * @param string $keypair
+     * @return string
+     * @throws Exception
+     */
+    function sodium_crypto_kx_secretkey($keypair)
+    {
+        return ParagonIE_Sodium_Compat::crypto_kx_secretkey($keypair);
+    }
+}
+if (!is_callable('sodium_crypto_kx_publickey')) {
+    /**
+     * @param string $keypair
+     * @return string
+     * @throws Exception
+     */
+    function sodium_crypto_kx_publickey($keypair)
+    {
+        return ParagonIE_Sodium_Compat::crypto_kx_publickey($keypair);
+    }
+}
 if (!is_callable('sodium_crypto_pwhash')) {
     /**
      * @see ParagonIE_Sodium_Compat::crypto_pwhash()
@@ -590,6 +755,21 @@
         return ParagonIE_Sodium_Compat::crypto_pwhash_str($passwd, $opslimit, $memlimit);
     }
 }
+if (!is_callable('sodium_crypto_pwhash_str_needs_rehash')) {
+    /**
+     * @see ParagonIE_Sodium_Compat::crypto_pwhash_str_needs_rehash()
+     * @param string $hash
+     * @param int $opslimit
+     * @param int $memlimit
+     * @return bool
+     *
+     * @throws SodiumException
+     */
+    function sodium_crypto_pwhash_str_needs_rehash($hash, $opslimit, $memlimit)
+    {
+        return ParagonIE_Sodium_Compat::crypto_pwhash_str_needs_rehash($hash, $opslimit, $memlimit);
+    }
+}
 if (!is_callable('sodium_crypto_pwhash_str_verify')) {
     /**
      * @see ParagonIE_Sodium_Compat::crypto_pwhash_str_verify()
@@ -696,6 +876,7 @@
     /**
      * @see ParagonIE_Sodium_Compat::crypto_secretbox_keygen()
      * @return string
+     * @throws Exception
      */
     function sodium_crypto_secretbox_keygen()
     {
@@ -721,6 +902,77 @@
         }
     }
 }
+if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_init_push')) {
+    /**
+     * @param string $key
+     * @return array<int, string>
+     * @throws SodiumException
+     */
+    function sodium_crypto_secretstream_xchacha20poly1305_init_push($key)
+    {
+        return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_init_push($key);
+    }
+}
+if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_push')) {
+    /**
+     * @param string $state
+     * @param string $msg
+     * @param string $aad
+     * @param int $tag
+     * @return string
+     * @throws SodiumException
+     */
+    function sodium_crypto_secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0)
+    {
+        return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_push($state, $msg, $aad, $tag);
+    }
+}
+if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_init_pull')) {
+    /**
+     * @param string $header
+     * @param string $key
+     * @return string
+     * @throws Exception
+     */
+    function sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key)
+    {
+        return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_init_pull($header, $key);
+    }
+}
+if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_pull')) {
+    /**
+     * @param string $state
+     * @param string $cipher
+     * @param string $aad
+     * @return bool|array{0: string, 1: int}
+     * @throws SodiumException
+     */
+    function sodium_crypto_secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '')
+    {
+        return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_pull($state, $cipher, $aad);
+    }
+}
+if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_rekey')) {
+    /**
+     * @param string $state
+     * @return void
+     * @throws SodiumException
+     */
+    function sodium_crypto_secretstream_xchacha20poly1305_rekey(&$state)
+    {
+        ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_rekey($state);
+    }
+}
+if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_keygen')) {
+    /**
+     * @return string
+     * @throws Exception
+     */
+    function sodium_crypto_secretstream_xchacha20poly1305_keygen()
+    {
+        return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_keygen();
+    }
+}
 if (!is_callable('sodium_crypto_shorthash')) {
     /**
      * @see ParagonIE_Sodium_Compat::crypto_shorthash()
@@ -739,6 +991,7 @@
     /**
      * @see ParagonIE_Sodium_Compat::crypto_shorthash_keygen()
      * @return string
+     * @throws Exception
      */
     function sodium_crypto_shorthash_keygen()
     {
@@ -773,6 +1026,20 @@
         return ParagonIE_Sodium_Compat::crypto_sign_detached($message, $sk);
     }
 }
+if (!is_callable('sodium_crypto_sign_keypair_from_secretkey_and_publickey')) {
+    /**
+     * @see ParagonIE_Sodium_Compat::crypto_sign_keypair_from_secretkey_and_publickey()
+     * @param string $sk
+     * @param string $pk
+     * @return string
+     * @throws SodiumException
+     * @throws TypeError
+     */
+    function sodium_crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk)
+    {
+        return ParagonIE_Sodium_Compat::crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk);
+    }
+}
 if (!is_callable('sodium_crypto_sign_keypair')) {
     /**
      * @see ParagonIE_Sodium_Compat::crypto_sign_keypair()
@@ -915,6 +1182,7 @@
     /**
      * @see ParagonIE_Sodium_Compat::crypto_stream_keygen()
      * @return string
+     * @throws Exception
      */
     function sodium_crypto_stream_keygen()
     {
@@ -1019,6 +1287,34 @@
         ParagonIE_Sodium_Compat::memzero($str);
     }
 }
+if (!is_callable('sodium_pad')) {
+    /**
+     * @see ParagonIE_Sodium_Compat::pad()
+     * @param string $unpadded
+     * @param int $blockSize
+     * @return int
+     * @throws SodiumException
+     * @throws TypeError
+     */
+    function sodium_pad($unpadded, $blockSize)
+    {
+        return ParagonIE_Sodium_Compat::pad($unpadded, $blockSize, true);
+    }
+}
+if (!is_callable('sodium_unpad')) {
+    /**
+     * @see ParagonIE_Sodium_Compat::pad()
+     * @param string $padded
+     * @param int $blockSize
+     * @return int
+     * @throws SodiumException
+     * @throws TypeError
+     */
+    function sodium_unpad($padded, $blockSize)
+    {
+        return ParagonIE_Sodium_Compat::unpad($padded, $blockSize, true);
+    }
+}
 if (!is_callable('sodium_randombytes_buf')) {
     /**
      * @see ParagonIE_Sodium_Compat::randombytes_buf()
@@ -1049,6 +1345,7 @@
     /**
      * @see ParagonIE_Sodium_Compat::randombytes_random16()
      * @return int
+     * @throws Exception
      */
     function sodium_randombytes_random16()
     {
Index: wp-includes/sodium_compat/lib/namespaced.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/lib/namespaced.php	(date 1571337483000)
+++ wp-includes/sodium_compat/lib/namespaced.php	(date 1571493283078)
@@ -1,5 +1,7 @@
 <?php
 
+require_once dirname(dirname(__FILE__)) . '/autoload.php';
+
 if (PHP_VERSION_ID < 50300) {
     return;
 }
@@ -36,7 +38,7 @@
     // Replace the namespace prefix with the base directory, replace namespace
     // separators with directory separators in the relative class name, append
     // with .php
-    $file = dirname(__DIR__) . '/namespaced/' . str_replace('\\', '/', $relative_class) . '.php';
+    $file = dirname(dirname(__FILE__)) . '/namespaced/' . str_replace('\\', '/', $relative_class) . '.php';
     // if the file exists, require it
     if (file_exists($file)) {
         require_once $file;
Index: wp-includes/sodium_compat/src/Core32/Poly1305/State.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core32/Poly1305/State.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Core32/Poly1305/State.php	(date 1571493283151)
@@ -142,7 +142,7 @@
             }
 
             $this->blocks(
-                static::intArrayToString($this->buffer),
+                self::intArrayToString($this->buffer),
                 ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
             );
             $this->leftover = 0;
@@ -346,7 +346,7 @@
             $this->final = true;
             $this->blocks(
                 self::substr(
-                    static::intArrayToString($this->buffer),
+                    self::intArrayToString($this->buffer),
                     0,
                     ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
                 ),
Index: wp-includes/sodium_compat/src/Core32/Ed25519.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core32/Ed25519.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Core32/Ed25519.php	(date 1571412398305)
@@ -278,7 +278,7 @@
         if (self::strlen($sig) < 64) {
             throw new SodiumException('Signature is too short');
         }
-        if (self::check_S_lt_L(self::substr($sig, 32, 32))) {
+        if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) {
             throw new SodiumException('S < L - Invalid signature');
         }
         if (self::small_order($sig)) {
Index: wp-includes/sodium_compat/src/Core32/BLAKE2b.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core32/BLAKE2b.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Core32/BLAKE2b.php	(date 1571498691054)
@@ -223,12 +223,13 @@
      */
     protected static function context()
     {
-        $ctx    = new SplFixedArray(5);
+        $ctx    = new SplFixedArray(6);
         $ctx[0] = new SplFixedArray(8);   // h
         $ctx[1] = new SplFixedArray(2);   // t
         $ctx[2] = new SplFixedArray(2);   // f
         $ctx[3] = new SplFixedArray(256); // buf
         $ctx[4] = 0;                      // buflen
+        $ctx[5] = 0;                      // last_node (uint8_t)
 
         for ($i = 8; $i--;) {
             $ctx[0][$i] = self::$iv[$i];
@@ -482,6 +483,8 @@
      *
      * @param SplFixedArray|null $key
      * @param int $outlen
+     * @param SplFixedArray|null $salt
+     * @param SplFixedArray|null $personal
      * @return SplFixedArray
      * @throws SodiumException
      * @throws TypeError
@@ -491,8 +494,12 @@
      * @psalm-suppress MixedArrayAssignment
      * @psalm-suppress MixedMethodCall
      */
-    public static function init($key = null, $outlen = 64)
-    {
+    public static function init(
+        $key = null,
+        $outlen = 64,
+        $salt = null,
+        $personal = null
+    ) {
         self::pseudoConstructor();
         $klen = 0;
 
@@ -510,6 +517,7 @@
         $ctx = self::context();
 
         $p = new SplFixedArray(64);
+        // Zero our param buffer...
         for ($i = 64; --$i;) {
             $p[$i] = 0;
         }
@@ -519,11 +527,34 @@
         $p[2] = 1;       // fanout
         $p[3] = 1;       // depth
 
+        if ($salt instanceof SplFixedArray) {
+            // salt: [32] through [47]
+            for ($i = 0; $i < 16; ++$i) {
+                $p[32 + $i] = (int) $salt[$i];
+            }
+        }
+        if ($personal instanceof SplFixedArray) {
+            // personal: [48] through [63]
+            for ($i = 0; $i < 16; ++$i) {
+                $p[48 + $i] = (int) $personal[$i];
+            }
+        }
+
         $ctx[0][0] = self::xor64(
             $ctx[0][0],
             self::load64($p, 0)
         );
 
+        if ($salt instanceof SplFixedArray || $personal instanceof SplFixedArray) {
+            // We need to do what blake2b_init_param() does:
+            for ($i = 1; $i < 8; ++$i) {
+                $ctx[0][$i] = self::xor64(
+                    $ctx[0][$i],
+                    self::load64($p, $i << 3)
+                );
+            }
+        }
+
         if ($klen > 0 && $key instanceof SplFixedArray) {
             $block = new SplFixedArray(128);
             for ($i = 128; $i--;) {
@@ -533,6 +564,7 @@
                 $block[$i] = $key[$i];
             }
             self::update($ctx, $block, 128);
+            $ctx[4] = 128;
         }
 
         return $ctx;
@@ -595,7 +627,7 @@
             }
             /** @var ParagonIE_Sodium_Core32_Int64 $ctxAi */
             $ctxAi = $ctxA[$i];
-            $str .= $ctxAi->toString();
+            $str .= $ctxAi->toReverseString();
         }
 
         # uint64_t t[2];
@@ -608,8 +640,8 @@
             /** @var ParagonIE_Sodium_Core32_Int64 $ctxA2 */
             $ctxA2 = $ctxA[1];
 
-            $str .= $ctxA1->toString();
-            $str .= $ctxA2->toString();
+            $str .= $ctxA1->toReverseString();
+            $str .= $ctxA2->toReverseString();
         }
 
         # uint8_t buf[2 * 128];
@@ -624,13 +656,16 @@
             self::intToChr(($ctx4 >> 8) & 0xff),
             self::intToChr(($ctx4 >> 16) & 0xff),
             self::intToChr(($ctx4 >> 24) & 0xff),
+            "\x00\x00\x00\x00"
+            /*
             self::intToChr(($ctx4 >> 32) & 0xff),
             self::intToChr(($ctx4 >> 40) & 0xff),
             self::intToChr(($ctx4 >> 48) & 0xff),
             self::intToChr(($ctx4 >> 56) & 0xff)
+            */
         ));
         # uint8_t last_node;
-        return $str . "\x00";
+        return $str . self::intToChr($ctx[5]) . str_repeat("\x00", 23);
     }
 
     /**
@@ -652,7 +687,7 @@
 
         # uint64_t h[8];
         for ($i = 0; $i < 8; ++$i) {
-            $ctx[0][$i] = ParagonIE_Sodium_Core32_Int64::fromString(
+            $ctx[0][$i] = ParagonIE_Sodium_Core32_Int64::fromReverseString(
                 self::substr($string, (($i << 3) + 0), 8)
             );
         }
@@ -660,10 +695,10 @@
         # uint64_t t[2];
         # uint64_t f[2];
         for ($i = 1; $i < 3; ++$i) {
-            $ctx[$i][1] = ParagonIE_Sodium_Core32_Int64::fromString(
+            $ctx[$i][1] = ParagonIE_Sodium_Core32_Int64::fromReverseString(
                 self::substr($string, 72 + (($i - 1) << 4), 8)
             );
-            $ctx[$i][0] = ParagonIE_Sodium_Core32_Int64::fromString(
+            $ctx[$i][0] = ParagonIE_Sodium_Core32_Int64::fromReverseString(
                 self::substr($string, 64 + (($i - 1) << 4), 8)
             );
         }
@@ -671,7 +706,6 @@
         # uint8_t buf[2 * 128];
         $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256));
 
-
         # uint8_t buf[2 * 128];
         $int = 0;
         for ($i = 0; $i < 8; ++$i) {
Index: wp-includes/sodium_compat/src/Core32/X25519.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core32/X25519.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Core32/X25519.php	(date 1566495450414)
@@ -151,8 +151,9 @@
         for ($i = 0; $i < 10; ++$i) {
             $h[$i] = $h[$i]->toInt32();
         }
-        /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
-        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h);
+        /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h2 */
+        $h2 = $h;
+        return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h2);
     }
 
     /**
Index: wp-includes/sodium_compat/src/Core32/SecretStream/State.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core32/SecretStream/State.php	(date 1568244100308)
+++ wp-includes/sodium_compat/src/Core32/SecretStream/State.php	(date 1568244100308)
@@ -0,0 +1,163 @@
+<?php
+
+/**
+ * Class ParagonIE_Sodium_Core32_SecretStream_State
+ */
+class ParagonIE_Sodium_Core32_SecretStream_State
+{
+    /** @var string $key */
+    protected $key;
+
+    /** @var int $counter */
+    protected $counter;
+
+    /** @var string $nonce */
+    protected $nonce;
+
+    /** @var string $_pad */
+    protected $_pad;
+
+    /**
+     * ParagonIE_Sodium_Core32_SecretStream_State constructor.
+     * @param string $key
+     * @param string|null $nonce
+     */
+    public function __construct($key, $nonce = null)
+    {
+        $this->key = $key;
+        $this->counter = 1;
+        if (is_null($nonce)) {
+            $nonce = str_repeat("\0", 12);
+        }
+        $this->nonce = str_pad($nonce, 12, "\0", STR_PAD_RIGHT);;
+        $this->_pad = str_repeat("\0", 4);
+    }
+
+    /**
+     * @return self
+     */
+    public function counterReset()
+    {
+        $this->counter = 1;
+        $this->_pad = str_repeat("\0", 4);
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getKey()
+    {
+        return $this->key;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCounter()
+    {
+        return ParagonIE_Sodium_Core32_Util::store32_le($this->counter);
+    }
+
+    /**
+     * @return string
+     */
+    public function getNonce()
+    {
+        if (!is_string($this->nonce)) {
+            $this->nonce = str_repeat("\0", 12);
+        }
+        if (ParagonIE_Sodium_Core32_Util::strlen($this->nonce) !== 12) {
+            $this->nonce = str_pad($this->nonce, 12, "\0", STR_PAD_RIGHT);
+        }
+        return $this->nonce;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCombinedNonce()
+    {
+        return $this->getCounter() .
+            ParagonIE_Sodium_Core32_Util::substr($this->getNonce(), 0, 8);
+    }
+
+    /**
+     * @return self
+     */
+    public function incrementCounter()
+    {
+        ++$this->counter;
+        return $this;
+    }
+
+    /**
+     * @return bool
+     */
+    public function needsRekey()
+    {
+        return ($this->counter & 0xffff) === 0;
+    }
+
+    /**
+     * @param string $newKeyAndNonce
+     * @return self
+     */
+    public function rekey($newKeyAndNonce)
+    {
+        $this->key = ParagonIE_Sodium_Core32_Util::substr($newKeyAndNonce, 0, 32);
+        $this->nonce = str_pad(
+            ParagonIE_Sodium_Core32_Util::substr($newKeyAndNonce, 32),
+            12,
+            "\0",
+            STR_PAD_RIGHT
+        );
+        return $this;
+    }
+
+    /**
+     * @param string $str
+     * @return self
+     */
+    public function xorNonce($str)
+    {
+        $this->nonce = ParagonIE_Sodium_Core32_Util::xorStrings(
+            $this->getNonce(),
+            str_pad(
+                ParagonIE_Sodium_Core32_Util::substr($str, 0, 8),
+                12,
+                "\0",
+                STR_PAD_RIGHT
+            )
+        );
+        return $this;
+    }
+
+    /**
+     * @param string $string
+     * @return self
+     */
+    public static function fromString($string)
+    {
+        $state = new ParagonIE_Sodium_Core32_SecretStream_State(
+            ParagonIE_Sodium_Core32_Util::substr($string, 0, 32)
+        );
+        $state->counter = ParagonIE_Sodium_Core32_Util::load_4(
+            ParagonIE_Sodium_Core32_Util::substr($string, 32, 4)
+        );
+        $state->nonce = ParagonIE_Sodium_Core32_Util::substr($string, 36, 12);
+        $state->_pad = ParagonIE_Sodium_Core32_Util::substr($string, 48, 8);
+        return $state;
+    }
+
+    /**
+     * @return string
+     */
+    public function toString()
+    {
+        return $this->key .
+            $this->getCounter() .
+            $this->nonce .
+            $this->_pad;
+    }
+}
Index: wp-includes/sodium_compat/src/Core/Base64/Common.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Core/Base64/Common.php	(date 1568244100279)
+++ wp-includes/sodium_compat/src/Core/Base64/Common.php	(date 1568244100279)
@@ -0,0 +1,213 @@
+<?php
+
+/**
+ * Class ParagonIE_Sodium_Core_Base64
+ *
+ *  Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
+ *  Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
+ *
+ * We have to copy/paste the contents into the variant files because PHP 5.2
+ * doesn't support late static binding, and we have no better workaround
+ * available that won't break PHP 7+. Therefore, we're forced to duplicate code.
+ */
+abstract class ParagonIE_Sodium_Core_Base64_Common
+{
+    /**
+     * Encode into Base64
+     *
+     * Base64 character set "[A-Z][a-z][0-9]+/"
+     *
+     * @param string $src
+     * @return string
+     * @throws TypeError
+     */
+    public static function encode($src)
+    {
+        return self::doEncode($src, true);
+    }
+
+    /**
+     * Encode into Base64, no = padding
+     *
+     * Base64 character set "[A-Z][a-z][0-9]+/"
+     *
+     * @param string $src
+     * @return string
+     * @throws TypeError
+     */
+    public static function encodeUnpadded($src)
+    {
+        return self::doEncode($src, false);
+    }
+
+    /**
+     * @param string $src
+     * @param bool $pad   Include = padding?
+     * @return string
+     * @throws TypeError
+     */
+    protected static function doEncode($src, $pad = true)
+    {
+        $dest = '';
+        $srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
+        // Main loop (no padding):
+        for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 3));
+            $b0 = $chunk[1];
+            $b1 = $chunk[2];
+            $b2 = $chunk[3];
+
+            $dest .=
+                self::encode6Bits(               $b0 >> 2       ) .
+                self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
+                self::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) .
+                self::encode6Bits(  $b2                     & 63);
+        }
+        // The last chunk, which may have padding:
+        if ($i < $srcLen) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
+            $b0 = $chunk[1];
+            if ($i + 1 < $srcLen) {
+                $b1 = $chunk[2];
+                $dest .=
+                    self::encode6Bits($b0 >> 2) .
+                    self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
+                    self::encode6Bits(($b1 << 2) & 63);
+                if ($pad) {
+                    $dest .= '=';
+                }
+            } else {
+                $dest .=
+                    self::encode6Bits( $b0 >> 2) .
+                    self::encode6Bits(($b0 << 4) & 63);
+                if ($pad) {
+                    $dest .= '==';
+                }
+            }
+        }
+        return $dest;
+    }
+
+    /**
+     * decode from base64 into binary
+     *
+     * Base64 character set "./[A-Z][a-z][0-9]"
+     *
+     * @param string $src
+     * @param bool $strictPadding
+     * @return string
+     * @throws RangeException
+     * @throws TypeError
+     * @psalm-suppress RedundantCondition
+     */
+    public static function decode($src, $strictPadding = false)
+    {
+        // Remove padding
+        $srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
+        if ($srcLen === 0) {
+            return '';
+        }
+
+        if ($strictPadding) {
+            if (($srcLen & 3) === 0) {
+                if ($src[$srcLen - 1] === '=') {
+                    $srcLen--;
+                    if ($src[$srcLen - 1] === '=') {
+                        $srcLen--;
+                    }
+                }
+            }
+            if (($srcLen & 3) === 1) {
+                throw new RangeException(
+                    'Incorrect padding'
+                );
+            }
+            if ($src[$srcLen - 1] === '=') {
+                throw new RangeException(
+                    'Incorrect padding'
+                );
+            }
+        } else {
+            $src = rtrim($src, '=');
+            $srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
+        }
+
+        $err = 0;
+        $dest = '';
+        // Main loop (no padding):
+        for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 4));
+            $c0 = self::decode6Bits($chunk[1]);
+            $c1 = self::decode6Bits($chunk[2]);
+            $c2 = self::decode6Bits($chunk[3]);
+            $c3 = self::decode6Bits($chunk[4]);
+
+            $dest .= pack(
+                'CCC',
+                ((($c0 << 2) | ($c1 >> 4)) & 0xff),
+                ((($c1 << 4) | ($c2 >> 2)) & 0xff),
+                ((($c2 << 6) |  $c3      ) & 0xff)
+            );
+            $err |= ($c0 | $c1 | $c2 | $c3) >> 8;
+        }
+        // The last chunk, which may have padding:
+        if ($i < $srcLen) {
+            /** @var array<int, int> $chunk */
+            $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
+            $c0 = self::decode6Bits($chunk[1]);
+
+            if ($i + 2 < $srcLen) {
+                $c1 = self::decode6Bits($chunk[2]);
+                $c2 = self::decode6Bits($chunk[3]);
+                $dest .= pack(
+                    'CC',
+                    ((($c0 << 2) | ($c1 >> 4)) & 0xff),
+                    ((($c1 << 4) | ($c2 >> 2)) & 0xff)
+                );
+                $err |= ($c0 | $c1 | $c2) >> 8;
+            } elseif ($i + 1 < $srcLen) {
+                $c1 = self::decode6Bits($chunk[2]);
+                $dest .= pack(
+                    'C',
+                    ((($c0 << 2) | ($c1 >> 4)) & 0xff)
+                );
+                $err |= ($c0 | $c1) >> 8;
+            } elseif ($i < $srcLen && $strictPadding) {
+                $err |= 1;
+            }
+        }
+        /** @var bool $check */
+        $check = ($err === 0);
+        if (!$check) {
+            throw new RangeException(
+                'Base64::decode() only expects characters in the correct base64 alphabet'
+            );
+        }
+        return $dest;
+    }
+
+    /**
+     * Uses bitwise operators instead of table-lookups to turn 6-bit integers
+     * into 8-bit integers.
+     *
+     * Base64 character set:
+     * [A-Z]      [a-z]      [0-9]      +     /
+     * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
+     *
+     * @param int $src
+     * @return int
+     */
+    abstract protected static function decode6Bits($src);
+
+    /**
+     * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+     * into 6-bit integers.
+     *
+     * @param int $src
+     * @return string
+     */
+    abstract protected static function encode6Bits($src);
+}
Index: wp-includes/sodium_compat/autoload.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/autoload.php	(date 1571337483000)
+++ wp-includes/sodium_compat/autoload.php	(date 1571493282986)
@@ -43,7 +43,17 @@
     // unless PHP >= 5.3.0
     require_once dirname(__FILE__) . '/lib/namespaced.php';
     require_once dirname(__FILE__) . '/lib/sodium_compat.php';
+} else {
+    require_once dirname(__FILE__) . '/src/PHP52/SplFixedArray.php';
 }
 if (PHP_VERSION_ID < 70200 || !extension_loaded('sodium')) {
-    require_once dirname(__FILE__) . '/lib/php72compat.php';
+    if (PHP_VERSION_ID >= 50300 && !defined('SODIUM_LIBRARY_MAJOR_VERSION')) {
+        require_once dirname(__FILE__) . '/lib/php72compat_const.php';
+    }
+    if (PHP_VERSION_ID >= 70000) {
+        assert(class_exists('ParagonIE_Sodium_Compat'), 'Possible filesystem/autoloader bug?');
+    } else {
+        assert(class_exists('ParagonIE_Sodium_Compat'));
+    }
+    require_once (dirname(__FILE__) . '/lib/php72compat.php');
 }
Index: wp-includes/sodium_compat/src/Crypto32.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Crypto32.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Crypto32.php	(date 1571442584429)
@@ -776,6 +776,53 @@
         return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx);
     }
 
+    /**
+     * Initialize a hashing context for BLAKE2b.
+     *
+     * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
+     *
+     * @param string $key
+     * @param int $outputLength
+     * @param string $salt
+     * @param string $personal
+     * @return string
+     * @throws RangeException
+     * @throws SodiumException
+     * @throws TypeError
+     */
+    public static function generichash_init_salt_personal(
+        $key = '',
+        $outputLength = 32,
+        $salt = '',
+        $personal = ''
+    ) {
+        // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized
+        ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor();
+
+        $k = null;
+        if (!empty($key)) {
+            $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key);
+            if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) {
+                throw new RangeException('Invalid key size');
+            }
+        }
+        if (!empty($salt)) {
+            $s = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($salt);
+        } else {
+            $s = null;
+        }
+        if (!empty($salt)) {
+            $p = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($personal);
+        } else {
+            $p = null;
+        }
+
+        /** @var SplFixedArray $ctx */
+        $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outputLength, $s, $p);
+
+        return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx);
+    }
+
     /**
      * Update a hashing context for BLAKE2b with $message
      *
@@ -1184,6 +1231,362 @@
         return $m;
     }
 
+    /**
+     * @param string $key
+     * @return array<int, string> Returns a state and a header.
+     * @throws Exception
+     * @throws SodiumException
+     */
+    public static function secretstream_xchacha20poly1305_init_push($key)
+    {
+        # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES);
+        $out = random_bytes(24);
+
+        # crypto_core_hchacha20(state->k, out, k, NULL);
+        $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20($out, $key);
+        $state = new ParagonIE_Sodium_Core32_SecretStream_State(
+            $subkey,
+            ParagonIE_Sodium_Core32_Util::substr($out, 16, 8) . str_repeat("\0", 4)
+        );
+
+        # _crypto_secretstream_xchacha20poly1305_counter_reset(state);
+        $state->counterReset();
+
+        # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES,
+        #        crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+        # memset(state->_pad, 0, sizeof state->_pad);
+        return array(
+            $state->toString(),
+            $out
+        );
+    }
+
+    /**
+     * @param string $key
+     * @param string $header
+     * @return string Returns a state.
+     * @throws Exception
+     */
+    public static function secretstream_xchacha20poly1305_init_pull($key, $header)
+    {
+        # crypto_core_hchacha20(state->k, in, k, NULL);
+        $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20(
+            ParagonIE_Sodium_Core32_Util::substr($header, 0, 16),
+            $key
+        );
+        $state = new ParagonIE_Sodium_Core32_SecretStream_State(
+            $subkey,
+            ParagonIE_Sodium_Core32_Util::substr($header, 16)
+        );
+        $state->counterReset();
+        # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES,
+        #     crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+        # memset(state->_pad, 0, sizeof state->_pad);
+        # return 0;
+        return $state->toString();
+    }
+
+    /**
+     * @param string $state
+     * @param string $msg
+     * @param string $aad
+     * @param int $tag
+     * @return string
+     * @throws SodiumException
+     */
+    public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0)
+    {
+        $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state);
+        # crypto_onetimeauth_poly1305_state poly1305_state;
+        # unsigned char                     block[64U];
+        # unsigned char                     slen[8U];
+        # unsigned char                    *c;
+        # unsigned char                    *mac;
+
+        $msglen = ParagonIE_Sodium_Core32_Util::strlen($msg);
+        $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad);
+
+        if ((($msglen + 63) >> 6) > 0xfffffffe) {
+            throw new SodiumException(
+                'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes'
+            );
+        }
+
+        # if (outlen_p != NULL) {
+        #     *outlen_p = 0U;
+        # }
+        # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) {
+        #     sodium_misuse();
+        # }
+
+        # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k);
+        # crypto_onetimeauth_poly1305_init(&poly1305_state, block);
+        # sodium_memzero(block, sizeof block);
+        $auth = new ParagonIE_Sodium_Core32_Poly1305_State(
+            ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey())
+        );
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen);
+        $auth->update($aad);
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0,
+        #     (0x10 - adlen) & 0xf);
+        $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf)));
+
+        # memset(block, 0, sizeof block);
+        # block[0] = tag;
+        # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
+        #                                    state->nonce, 1U, state->k);
+        $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
+            ParagonIE_Sodium_Core32_Util::intToChr($tag) . str_repeat("\0", 63),
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core32_Util::store64_le(1)
+        );
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
+        $auth->update($block);
+
+        # out[0] = block[0];
+        $out = $block[0];
+        # c = out + (sizeof tag);
+        # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k);
+        $cipher = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
+            $msg,
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core32_Util::store64_le(2)
+        );
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
+        $auth->update($cipher);
+
+        $out .= $cipher;
+        unset($cipher);
+
+        # crypto_onetimeauth_poly1305_update
+        # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
+        $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf)));
+
+        # STORE64_LE(slen, (uint64_t) adlen);
+        $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen);
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+        $auth->update($slen);
+
+        # STORE64_LE(slen, (sizeof block) + mlen);
+        $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen);
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+        $auth->update($slen);
+
+        # mac = c + mlen;
+        # crypto_onetimeauth_poly1305_final(&poly1305_state, mac);
+        $mac = $auth->finish();
+        $out .= $mac;
+
+        # sodium_memzero(&poly1305_state, sizeof poly1305_state);
+        unset($auth);
+
+
+        # XOR_BUF(STATE_INONCE(state), mac,
+        #     crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+        $st->xorNonce($mac);
+
+        # sodium_increment(STATE_COUNTER(state),
+        #     crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
+        $st->incrementCounter();
+        // Overwrite by reference:
+        $state = $st->toString();
+
+        /** @var bool $rekey */
+        $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0;
+        # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||
+        #     sodium_is_zero(STATE_COUNTER(state),
+        #         crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {
+        #     crypto_secretstream_xchacha20poly1305_rekey(state);
+        # }
+        if ($rekey || $st->needsRekey()) {
+            // DO REKEY
+            self::secretstream_xchacha20poly1305_rekey($state);
+        }
+        # if (outlen_p != NULL) {
+        #     *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen;
+        # }
+        return $out;
+    }
+
+    /**
+     * @param string $state
+     * @param string $cipher
+     * @param string $aad
+     * @return bool|array{0: string, 1: int}
+     * @throws SodiumException
+     */
+    public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '')
+    {
+        $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state);
+
+        $cipherlen = ParagonIE_Sodium_Core32_Util::strlen($cipher);
+        #     mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES;
+        $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES;
+        $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad);
+
+        #     if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) {
+        #         sodium_misuse();
+        #     }
+        if ((($msglen + 63) >> 6) > 0xfffffffe) {
+            throw new SodiumException(
+                'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes'
+            );
+        }
+
+        #     crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k);
+        #     crypto_onetimeauth_poly1305_init(&poly1305_state, block);
+        #     sodium_memzero(block, sizeof block);
+        $auth = new ParagonIE_Sodium_Core32_Poly1305_State(
+            ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey())
+        );
+
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen);
+        $auth->update($aad);
+
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0,
+        #         (0x10 - adlen) & 0xf);
+        $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf)));
+
+
+        #     memset(block, 0, sizeof block);
+        #     block[0] = in[0];
+        #     crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
+        #                                        state->nonce, 1U, state->k);
+        $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
+            $cipher[0] . str_repeat("\0", 63),
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core32_Util::store64_le(1)
+        );
+        #     tag = block[0];
+        #     block[0] = in[0];
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
+        $tag = ParagonIE_Sodium_Core32_Util::chrToInt($block[0]);
+        $block[0] = $cipher[0];
+        $auth->update($block);
+
+
+        #     c = in + (sizeof tag);
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
+        $auth->update(ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen));
+
+        #     crypto_onetimeauth_poly1305_update
+        #     (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
+        $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf)));
+
+        #     STORE64_LE(slen, (uint64_t) adlen);
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+        $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen);
+        $auth->update($slen);
+
+        #     STORE64_LE(slen, (sizeof block) + mlen);
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+        $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen);
+        $auth->update($slen);
+
+        #     crypto_onetimeauth_poly1305_final(&poly1305_state, mac);
+        #     sodium_memzero(&poly1305_state, sizeof poly1305_state);
+        $mac = $auth->finish();
+
+        #     stored_mac = c + mlen;
+        #     if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) {
+        #     sodium_memzero(mac, sizeof mac);
+        #         return -1;
+        #     }
+
+        $stored = ParagonIE_Sodium_Core32_Util::substr($cipher, $msglen + 1, 16);
+        if (!ParagonIE_Sodium_Core32_Util::hashEquals($mac, $stored)) {
+            return false;
+        }
+
+        #     crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k);
+        $out = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
+            ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen),
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core32_Util::store64_le(2)
+        );
+
+        #     XOR_BUF(STATE_INONCE(state), mac,
+        #         crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+        $st->xorNonce($mac);
+
+        #     sodium_increment(STATE_COUNTER(state),
+        #         crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
+        $st->incrementCounter();
+
+        #     if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||
+        #         sodium_is_zero(STATE_COUNTER(state),
+        #             crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {
+        #         crypto_secretstream_xchacha20poly1305_rekey(state);
+        #     }
+
+        // Overwrite by reference:
+        $state = $st->toString();
+
+        /** @var bool $rekey */
+        $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0;
+        if ($rekey || $st->needsRekey()) {
+            // DO REKEY
+            self::secretstream_xchacha20poly1305_rekey($state);
+        }
+        return array($out, $tag);
+    }
+
+    /**
+     * @param string $state
+     * @return void
+     * @throws SodiumException
+     */
+    public static function secretstream_xchacha20poly1305_rekey(&$state)
+    {
+        $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state);
+        # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES +
+        # crypto_secretstream_xchacha20poly1305_INONCEBYTES];
+        # size_t        i;
+        # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
+        #     new_key_and_inonce[i] = state->k[i];
+        # }
+        $new_key_and_inonce = $st->getKey();
+
+        # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
+        #     new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] =
+        #         STATE_INONCE(state)[i];
+        # }
+        $new_key_and_inonce .= ParagonIE_Sodium_Core32_Util::substR($st->getNonce(), 0, 8);
+
+        # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce,
+        #                                 sizeof new_key_and_inonce,
+        #                                 state->nonce, state->k);
+
+        $st->rekey(ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(
+            $new_key_and_inonce,
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core32_Util::store64_le(0)
+        ));
+
+        # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
+        #     state->k[i] = new_key_and_inonce[i];
+        # }
+        # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
+        #     STATE_INONCE(state)[i] =
+        #          new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i];
+        # }
+        # _crypto_secretstream_xchacha20poly1305_counter_reset(state);
+        $st->counterReset();
+
+        $state = $st->toString();
+    }
+
     /**
      * Detached Ed25519 signature.
      *
Index: wp-includes/sodium_compat/src/Crypto.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Crypto.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Crypto.php	(date 1568244100309)
@@ -777,6 +777,53 @@
         return ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx);
     }
 
+    /**
+     * Initialize a hashing context for BLAKE2b.
+     *
+     * @internal Do not use this directly. Use ParagonIE_Sodium_Compat.
+     *
+     * @param string $key
+     * @param int $outputLength
+     * @param string $salt
+     * @param string $personal
+     * @return string
+     * @throws RangeException
+     * @throws SodiumException
+     * @throws TypeError
+     */
+    public static function generichash_init_salt_personal(
+        $key = '',
+        $outputLength = 32,
+        $salt = '',
+        $personal = ''
+    ) {
+        // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized
+        ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor();
+
+        $k = null;
+        if (!empty($key)) {
+            $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key);
+            if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) {
+                throw new RangeException('Invalid key size');
+            }
+        }
+        if (!empty($salt)) {
+            $s = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($salt);
+        } else {
+            $s = null;
+        }
+        if (!empty($salt)) {
+            $p = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($personal);
+        } else {
+            $p = null;
+        }
+
+        /** @var SplFixedArray $ctx */
+        $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outputLength, $s, $p);
+
+        return ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx);
+    }
+
     /**
      * Update a hashing context for BLAKE2b with $message
      *
@@ -1185,6 +1232,362 @@
         return $m;
     }
 
+    /**
+     * @param string $key
+     * @return array<int, string> Returns a state and a header.
+     * @throws Exception
+     * @throws SodiumException
+     */
+    public static function secretstream_xchacha20poly1305_init_push($key)
+    {
+        # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES);
+        $out = random_bytes(24);
+
+        # crypto_core_hchacha20(state->k, out, k, NULL);
+        $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20($out, $key);
+        $state = new ParagonIE_Sodium_Core_SecretStream_State(
+            $subkey,
+            ParagonIE_Sodium_Core_Util::substr($out, 16, 8) . str_repeat("\0", 4)
+        );
+
+        # _crypto_secretstream_xchacha20poly1305_counter_reset(state);
+        $state->counterReset();
+
+        # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES,
+        #        crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+        # memset(state->_pad, 0, sizeof state->_pad);
+        return array(
+            $state->toString(),
+            $out
+        );
+    }
+
+    /**
+     * @param string $key
+     * @param string $header
+     * @return string Returns a state.
+     * @throws Exception
+     */
+    public static function secretstream_xchacha20poly1305_init_pull($key, $header)
+    {
+        # crypto_core_hchacha20(state->k, in, k, NULL);
+        $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20(
+            ParagonIE_Sodium_Core_Util::substr($header, 0, 16),
+            $key
+        );
+        $state = new ParagonIE_Sodium_Core_SecretStream_State(
+            $subkey,
+            ParagonIE_Sodium_Core_Util::substr($header, 16)
+        );
+        $state->counterReset();
+        # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES,
+        #     crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+        # memset(state->_pad, 0, sizeof state->_pad);
+        # return 0;
+        return $state->toString();
+    }
+
+    /**
+     * @param string $state
+     * @param string $msg
+     * @param string $aad
+     * @param int $tag
+     * @return string
+     * @throws SodiumException
+     */
+    public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0)
+    {
+        $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state);
+        # crypto_onetimeauth_poly1305_state poly1305_state;
+        # unsigned char                     block[64U];
+        # unsigned char                     slen[8U];
+        # unsigned char                    *c;
+        # unsigned char                    *mac;
+
+        $msglen = ParagonIE_Sodium_Core_Util::strlen($msg);
+        $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad);
+
+        if ((($msglen + 63) >> 6) > 0xfffffffe) {
+            throw new SodiumException(
+                'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes'
+            );
+        }
+
+        # if (outlen_p != NULL) {
+        #     *outlen_p = 0U;
+        # }
+        # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) {
+        #     sodium_misuse();
+        # }
+
+        # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k);
+        # crypto_onetimeauth_poly1305_init(&poly1305_state, block);
+        # sodium_memzero(block, sizeof block);
+        $auth = new ParagonIE_Sodium_Core_Poly1305_State(
+            ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey())
+        );
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen);
+        $auth->update($aad);
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0,
+        #     (0x10 - adlen) & 0xf);
+        $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf)));
+
+        # memset(block, 0, sizeof block);
+        # block[0] = tag;
+        # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
+        #                                    state->nonce, 1U, state->k);
+        $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc(
+            ParagonIE_Sodium_Core_Util::intToChr($tag) . str_repeat("\0", 63),
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core_Util::store64_le(1)
+        );
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
+        $auth->update($block);
+
+        # out[0] = block[0];
+        $out = $block[0];
+        # c = out + (sizeof tag);
+        # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k);
+        $cipher = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc(
+            $msg,
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core_Util::store64_le(2)
+        );
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
+        $auth->update($cipher);
+
+        $out .= $cipher;
+        unset($cipher);
+
+        # crypto_onetimeauth_poly1305_update
+        # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
+        $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf)));
+
+        # STORE64_LE(slen, (uint64_t) adlen);
+        $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen);
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+        $auth->update($slen);
+
+        # STORE64_LE(slen, (sizeof block) + mlen);
+        $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen);
+
+        # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+        $auth->update($slen);
+
+        # mac = c + mlen;
+        # crypto_onetimeauth_poly1305_final(&poly1305_state, mac);
+        $mac = $auth->finish();
+        $out .= $mac;
+
+        # sodium_memzero(&poly1305_state, sizeof poly1305_state);
+        unset($auth);
+
+
+        # XOR_BUF(STATE_INONCE(state), mac,
+        #     crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+        $st->xorNonce($mac);
+
+        # sodium_increment(STATE_COUNTER(state),
+        #     crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
+        $st->incrementCounter();
+        // Overwrite by reference:
+        $state = $st->toString();
+
+        /** @var bool $rekey */
+        $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0;
+        # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||
+        #     sodium_is_zero(STATE_COUNTER(state),
+        #         crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {
+        #     crypto_secretstream_xchacha20poly1305_rekey(state);
+        # }
+        if ($rekey || $st->needsRekey()) {
+            // DO REKEY
+            self::secretstream_xchacha20poly1305_rekey($state);
+        }
+        # if (outlen_p != NULL) {
+        #     *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen;
+        # }
+        return $out;
+    }
+
+    /**
+     * @param string $state
+     * @param string $cipher
+     * @param string $aad
+     * @return bool|array{0: string, 1: int}
+     * @throws SodiumException
+     */
+    public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '')
+    {
+        $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state);
+
+        $cipherlen = ParagonIE_Sodium_Core_Util::strlen($cipher);
+        #     mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES;
+        $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES;
+        $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad);
+
+        #     if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) {
+        #         sodium_misuse();
+        #     }
+        if ((($msglen + 63) >> 6) > 0xfffffffe) {
+            throw new SodiumException(
+                'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes'
+            );
+        }
+
+        #     crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k);
+        #     crypto_onetimeauth_poly1305_init(&poly1305_state, block);
+        #     sodium_memzero(block, sizeof block);
+        $auth = new ParagonIE_Sodium_Core_Poly1305_State(
+            ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey())
+        );
+
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen);
+        $auth->update($aad);
+
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0,
+        #         (0x10 - adlen) & 0xf);
+        $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf)));
+
+
+        #     memset(block, 0, sizeof block);
+        #     block[0] = in[0];
+        #     crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,
+        #                                        state->nonce, 1U, state->k);
+        $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc(
+            $cipher[0] . str_repeat("\0", 63),
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core_Util::store64_le(1)
+        );
+        #     tag = block[0];
+        #     block[0] = in[0];
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
+        $tag = ParagonIE_Sodium_Core_Util::chrToInt($block[0]);
+        $block[0] = $cipher[0];
+        $auth->update($block);
+
+
+        #     c = in + (sizeof tag);
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
+        $auth->update(ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen));
+
+        #     crypto_onetimeauth_poly1305_update
+        #     (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
+        $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf)));
+
+        #     STORE64_LE(slen, (uint64_t) adlen);
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+        $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen);
+        $auth->update($slen);
+
+        #     STORE64_LE(slen, (sizeof block) + mlen);
+        #     crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
+        $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen);
+        $auth->update($slen);
+
+        #     crypto_onetimeauth_poly1305_final(&poly1305_state, mac);
+        #     sodium_memzero(&poly1305_state, sizeof poly1305_state);
+        $mac = $auth->finish();
+
+        #     stored_mac = c + mlen;
+        #     if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) {
+        #     sodium_memzero(mac, sizeof mac);
+        #         return -1;
+        #     }
+
+        $stored = ParagonIE_Sodium_Core_Util::substr($cipher, $msglen + 1, 16);
+        if (!ParagonIE_Sodium_Core_Util::hashEquals($mac, $stored)) {
+            return false;
+        }
+
+        #     crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k);
+        $out = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc(
+            ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen),
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core_Util::store64_le(2)
+        );
+
+        #     XOR_BUF(STATE_INONCE(state), mac,
+        #         crypto_secretstream_xchacha20poly1305_INONCEBYTES);
+        $st->xorNonce($mac);
+
+        #     sodium_increment(STATE_COUNTER(state),
+        #         crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
+        $st->incrementCounter();
+
+        #     if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||
+        #         sodium_is_zero(STATE_COUNTER(state),
+        #             crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {
+        #         crypto_secretstream_xchacha20poly1305_rekey(state);
+        #     }
+
+        // Overwrite by reference:
+        $state = $st->toString();
+
+        /** @var bool $rekey */
+        $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0;
+        if ($rekey || $st->needsRekey()) {
+            // DO REKEY
+            self::secretstream_xchacha20poly1305_rekey($state);
+        }
+        return array($out, $tag);
+    }
+
+    /**
+     * @param string $state
+     * @return void
+     * @throws SodiumException
+     */
+    public static function secretstream_xchacha20poly1305_rekey(&$state)
+    {
+        $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state);
+        # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES +
+        # crypto_secretstream_xchacha20poly1305_INONCEBYTES];
+        # size_t        i;
+        # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
+        #     new_key_and_inonce[i] = state->k[i];
+        # }
+        $new_key_and_inonce = $st->getKey();
+
+        # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
+        #     new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] =
+        #         STATE_INONCE(state)[i];
+        # }
+        $new_key_and_inonce .= ParagonIE_Sodium_Core_Util::substR($st->getNonce(), 0, 8);
+
+        # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce,
+        #                                 sizeof new_key_and_inonce,
+        #                                 state->nonce, state->k);
+
+        $st->rekey(ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc(
+            $new_key_and_inonce,
+            $st->getCombinedNonce(),
+            $st->getKey(),
+            ParagonIE_Sodium_Core_Util::store64_le(0)
+        ));
+
+        # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
+        #     state->k[i] = new_key_and_inonce[i];
+        # }
+        # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
+        #     STATE_INONCE(state)[i] =
+        #          new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i];
+        # }
+        # _crypto_secretstream_xchacha20poly1305_counter_reset(state);
+        $st->counterReset();
+
+        $state = $st->toString();
+    }
+
     /**
      * Detached Ed25519 signature.
      *
Index: wp-includes/sodium_compat/src/Compat.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/Compat.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/Compat.php	(date 1571496047308)
@@ -49,6 +49,10 @@
     const VERSION_STRING = 'polyfill-1.0.8';
 
     // From libsodium
+    const BASE64_VARIANT_ORIGINAL = 1;
+    const BASE64_VARIANT_ORIGINAL_NO_PADDING = 3;
+    const BASE64_VARIANT_URLSAFE = 5;
+    const BASE64_VARIANT_URLSAFE_NO_PADDING = 7;
     const CRYPTO_AEAD_AES256GCM_KEYBYTES = 32;
     const CRYPTO_AEAD_AES256GCM_NSECBYTES = 0;
     const CRYPTO_AEAD_AES256GCM_NPUBBYTES = 12;
@@ -74,10 +78,17 @@
     const CRYPTO_BOX_MACBYTES = 16;
     const CRYPTO_BOX_NONCEBYTES = 24;
     const CRYPTO_BOX_SEEDBYTES = 32;
+    const CRYPTO_KDF_BYTES_MIN = 16;
+    const CRYPTO_KDF_BYTES_MAX = 64;
+    const CRYPTO_KDF_CONTEXTBYTES = 8;
+    const CRYPTO_KDF_KEYBYTES = 32;
     const CRYPTO_KX_BYTES = 32;
+    const CRYPTO_KX_PRIMITIVE = 'x25519blake2b';
     const CRYPTO_KX_SEEDBYTES = 32;
+    const CRYPTO_KX_KEYPAIRBYTES = 64;
     const CRYPTO_KX_PUBLICKEYBYTES = 32;
     const CRYPTO_KX_SECRETKEYBYTES = 32;
+    const CRYPTO_KX_SESSIONKEYBYTES = 32;
     const CRYPTO_GENERICHASH_BYTES = 32;
     const CRYPTO_GENERICHASH_BYTES_MIN = 16;
     const CRYPTO_GENERICHASH_BYTES_MAX = 64;
@@ -85,7 +96,7 @@
     const CRYPTO_GENERICHASH_KEYBYTES_MIN = 16;
     const CRYPTO_GENERICHASH_KEYBYTES_MAX = 64;
     const CRYPTO_PWHASH_SALTBYTES = 16;
-    const CRYPTO_PWHASH_STRPREFIX = '$argon2i$';
+    const CRYPTO_PWHASH_STRPREFIX = '$argon2id$';
     const CRYPTO_PWHASH_ALG_ARGON2I13 = 1;
     const CRYPTO_PWHASH_ALG_ARGON2ID13 = 2;
     const CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE = 33554432;
@@ -107,6 +118,14 @@
     const CRYPTO_SECRETBOX_KEYBYTES = 32;
     const CRYPTO_SECRETBOX_MACBYTES = 16;
     const CRYPTO_SECRETBOX_NONCEBYTES = 24;
+    const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17;
+    const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24;
+    const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32;
+    const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0;
+    const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1;
+    const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2;
+    const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3;
+    const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80;
     const CRYPTO_SIGN_BYTES = 64;
     const CRYPTO_SIGN_SEEDBYTES = 32;
     const CRYPTO_SIGN_PUBLICKEYBYTES = 32;
@@ -115,6 +134,110 @@
     const CRYPTO_STREAM_KEYBYTES = 32;
     const CRYPTO_STREAM_NONCEBYTES = 24;
 
+    /**
+     * Add two numbers (little-endian unsigned), storing the value in the first
+     * parameter.
+     *
+     * This mutates $val.
+     *
+     * @param string $val
+     * @param string $addv
+     * @return void
+     * @throws SodiumException
+     */
+    public static function add(&$val, $addv)
+    {
+        $val_len = ParagonIE_Sodium_Core_Util::strlen($val);
+        $addv_len = ParagonIE_Sodium_Core_Util::strlen($addv);
+        if ($val_len !== $addv_len) {
+            throw new SodiumException('values must have the same length');
+        }
+        $A = ParagonIE_Sodium_Core_Util::stringToIntArray($val);
+        $B = ParagonIE_Sodium_Core_Util::stringToIntArray($addv);
+
+        $c = 0;
+        for ($i = 0; $i < $val_len; $i++) {
+            $c += ($A[$i] + $B[$i]);
+            $A[$i] = ($c & 0xff);
+            $c >>= 8;
+        }
+        $val = ParagonIE_Sodium_Core_Util::intArrayToString($A);
+    }
+
+    /**
+     * @param string $encoded
+     * @param int $variant
+     * @param string $ignore
+     * @return string
+     * @throws SodiumException
+     */
+    public static function base642bin($encoded, $variant, $ignore = '')
+    {
+        /* Type checks: */
+        ParagonIE_Sodium_Core_Util::declareScalarType($encoded, 'string', 1);
+
+        /** @var string $encoded */
+        $encoded = (string) $encoded;
+        if (ParagonIE_Sodium_Core_Util::strlen($encoded) === 0) {
+            return '';
+        }
+
+        // Just strip before decoding
+        if (!empty($ignore)) {
+            $encoded = str_replace($ignore, '', $encoded);
+        }
+
+        try {
+            switch ($variant) {
+                case self::BASE64_VARIANT_ORIGINAL:
+                    return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, true);
+                case self::BASE64_VARIANT_ORIGINAL_NO_PADDING:
+                    return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, false);
+                case self::BASE64_VARIANT_URLSAFE:
+                    return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, true);
+                case self::BASE64_VARIANT_URLSAFE_NO_PADDING:
+                    return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, false);
+                default:
+                    throw new SodiumException('invalid base64 variant identifier');
+            }
+        } catch (Exception $ex) {
+            if ($ex instanceof SodiumException) {
+                throw $ex;
+            }
+            throw new SodiumException('invalid base64 string');
+        }
+    }
+
+    /**
+     * @param string $decoded
+     * @param int $variant
+     * @return string
+     * @throws SodiumException
+     */
+    public static function bin2base64($decoded, $variant)
+    {
+        /* Type checks: */
+        ParagonIE_Sodium_Core_Util::declareScalarType($decoded, 'string', 1);
+        /** @var string $decoded */
+        $decoded = (string) $decoded;
+        if (ParagonIE_Sodium_Core_Util::strlen($decoded) === 0) {
+            return '';
+        }
+
+        switch ($variant) {
+            case self::BASE64_VARIANT_ORIGINAL:
+                return ParagonIE_Sodium_Core_Base64_Original::encode($decoded);
+            case self::BASE64_VARIANT_ORIGINAL_NO_PADDING:
+                return ParagonIE_Sodium_Core_Base64_Original::encodeUnpadded($decoded);
+            case self::BASE64_VARIANT_URLSAFE:
+                return ParagonIE_Sodium_Core_Base64_UrlSafe::encode($decoded);
+            case self::BASE64_VARIANT_URLSAFE_NO_PADDING:
+                return ParagonIE_Sodium_Core_Base64_UrlSafe::encodeUnpadded($decoded);
+            default:
+                throw new SodiumException('invalid base64 variant identifier');
+        }
+    }
+
     /**
      * Cache-timing-safe implementation of bin2hex().
      *
@@ -1310,6 +1433,7 @@
      * @throws TypeError
      * @psalm-suppress MixedArgument
      * @psalm-suppress ReferenceConstraintViolation
+     * @psalm-suppress ConflictingReferenceConstraint
      */
     public static function crypto_generichash_final(&$ctx, $length = self::CRYPTO_GENERICHASH_BYTES)
     {
@@ -1324,6 +1448,14 @@
             $func = '\\Sodium\\crypto_generichash_final';
             return (string) $func($ctx, $length);
         }
+        if ($length < 1) {
+            try {
+                self::memzero($ctx);
+            } catch (SodiumException $ex) {
+                unset($ctx);
+            }
+            return '';
+        }
         if (PHP_INT_SIZE === 4) {
             $result = ParagonIE_Sodium_Crypto32::generichash_final($ctx, $length);
         } else {
@@ -1379,6 +1511,53 @@
         return ParagonIE_Sodium_Crypto::generichash_init($key, $length);
     }
 
+    /**
+     * Initialize a BLAKE2b hashing context, for use in a streaming interface.
+     *
+     * @param string|null $key If specified must be a string between 16 and 64 bytes
+     * @param int $length      The size of the desired hash output
+     * @param string $salt     Salt (up to 16 bytes)
+     * @param string $personal Personalization string (up to 16 bytes)
+     * @return string          A BLAKE2 hashing context, encoded as a string
+     *                         (To be 100% compatible with ext/libsodium)
+     * @throws SodiumException
+     * @throws TypeError
+     * @psalm-suppress MixedArgument
+     */
+    public static function crypto_generichash_init_salt_personal(
+        $key = '',
+        $length = self::CRYPTO_GENERICHASH_BYTES,
+        $salt = '',
+        $personal = ''
+    ) {
+        /* Type checks: */
+        if (is_null($key)) {
+            $key = '';
+        }
+        ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 1);
+        ParagonIE_Sodium_Core_Util::declareScalarType($length, 'int', 2);
+        ParagonIE_Sodium_Core_Util::declareScalarType($salt, 'string', 3);
+        ParagonIE_Sodium_Core_Util::declareScalarType($personal, 'string', 4);
+        $salt = str_pad($salt, 16, "\0", STR_PAD_RIGHT);
+        $personal = str_pad($personal, 16, "\0", STR_PAD_RIGHT);
+
+        /* Input validation: */
+        if (!empty($key)) {
+            /*
+            if (ParagonIE_Sodium_Core_Util::strlen($key) < self::CRYPTO_GENERICHASH_KEYBYTES_MIN) {
+                throw new SodiumException('Unsupported key size. Must be at least CRYPTO_GENERICHASH_KEYBYTES_MIN bytes long.');
+            }
+            */
+            if (ParagonIE_Sodium_Core_Util::strlen($key) > self::CRYPTO_GENERICHASH_KEYBYTES_MAX) {
+                throw new SodiumException('Unsupported key size. Must be at most CRYPTO_GENERICHASH_KEYBYTES_MAX bytes long.');
+            }
+        }
+        if (PHP_INT_SIZE === 4) {
+            return ParagonIE_Sodium_Crypto32::generichash_init_salt_personal($key, $length, $salt, $personal);
+        }
+        return ParagonIE_Sodium_Crypto::generichash_init_salt_personal($key, $length, $salt, $personal);
+    }
+
     /**
      * Update a BLAKE2b hashing context with additional data.
      *
@@ -1424,6 +1603,65 @@
         return random_bytes(self::CRYPTO_GENERICHASH_KEYBYTES);
     }
 
+    /**
+     * @param int $subkey_len
+     * @param int $subkey_id
+     * @param string $context
+     * @param string $key
+     * @return string
+     * @throws SodiumException
+     */
+    public static function crypto_kdf_derive_from_key(
+        $subkey_len,
+        $subkey_id,
+        $context,
+        $key
+    ) {
+        ParagonIE_Sodium_Core_Util::declareScalarType($subkey_len, 'int', 1);
+        ParagonIE_Sodium_Core_Util::declareScalarType($subkey_id, 'int', 2);
+        ParagonIE_Sodium_Core_Util::declareScalarType($context, 'string', 3);
+        ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
+        $subkey_id = (int) $subkey_id;
+        $subkey_len = (int) $subkey_len;
+        $context = (string) $context;
+        $key = (string) $key;
+
+        if ($subkey_len < self::CRYPTO_KDF_BYTES_MIN) {
+            throw new SodiumException('subkey cannot be smaller than SODIUM_CRYPTO_KDF_BYTES_MIN');
+        }
+        if ($subkey_len > self::CRYPTO_KDF_BYTES_MAX) {
+            throw new SodiumException('subkey cannot be larger than SODIUM_CRYPTO_KDF_BYTES_MAX');
+        }
+        if ($subkey_id < 0) {
+            throw new SodiumException('subkey_id cannot be negative');
+        }
+        if (ParagonIE_Sodium_Core_Util::strlen($context) !== self::CRYPTO_KDF_CONTEXTBYTES) {
+            throw new SodiumException('context should be SODIUM_CRYPTO_KDF_CONTEXTBYTES bytes');
+        }
+        if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_KDF_KEYBYTES) {
+            throw new SodiumException('key should be SODIUM_CRYPTO_KDF_KEYBYTES bytes');
+        }
+
+        $salt = ParagonIE_Sodium_Core_Util::store64_le($subkey_id);
+        $state = self::crypto_generichash_init_salt_personal(
+            $key,
+            $subkey_len,
+            $salt,
+            $context
+        );
+        return self::crypto_generichash_final($state, $subkey_len);
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     * @throws Error
+     */
+    public static function crypto_kdf_keygen()
+    {
+        return random_bytes(self::CRYPTO_KDF_KEYBYTES);
+    }
+
     /**
      * Perform a key exchange, between a designated client and a server.
      *
@@ -1510,6 +1748,149 @@
         );
     }
 
+    /**
+     * @param string $seed
+     * @return string
+     * @throws SodiumException
+     */
+    public static function crypto_kx_seed_keypair($seed)
+    {
+        ParagonIE_Sodium_Core_Util::declareScalarType($seed, 'string', 1);
+
+        $seed = (string) $seed;
+
+        if (ParagonIE_Sodium_Core_Util::strlen($seed) !== self::CRYPTO_KX_SEEDBYTES) {
+            throw new SodiumException('seed must be SODIUM_CRYPTO_KX_SEEDBYTES bytes');
+        }
+
+        $sk = self::crypto_generichash($seed, '', self::CRYPTO_KX_SECRETKEYBYTES);
+        $pk = self::crypto_scalarmult_base($sk);
+        return $sk . $pk;
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     */
+    public static function crypto_kx_keypair()
+    {
+        $sk = self::randombytes_buf(self::CRYPTO_KX_SECRETKEYBYTES);
+        $pk = self::crypto_scalarmult_base($sk);
+        return $sk . $pk;
+    }
+
+    /**
+     * @param string $keypair
+     * @param string $serverPublicKey
+     * @return array{0: string, 1: string}
+     * @throws SodiumException
+     */
+    public static function crypto_kx_client_session_keys($keypair, $serverPublicKey)
+    {
+        ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1);
+        ParagonIE_Sodium_Core_Util::declareScalarType($serverPublicKey, 'string', 2);
+
+        $keypair = (string) $keypair;
+        $serverPublicKey = (string) $serverPublicKey;
+
+        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_KX_KEYPAIRBYTES) {
+            throw new SodiumException('keypair should be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes');
+        }
+        if (ParagonIE_Sodium_Core_Util::strlen($serverPublicKey) !== self::CRYPTO_KX_PUBLICKEYBYTES) {
+            throw new SodiumException('public keys must be SODIUM_CRYPTO_KX_PUBLICKEYBYTES bytes');
+        }
+
+        $sk = self::crypto_kx_secretkey($keypair);
+        $pk = self::crypto_kx_publickey($keypair);
+        $h = self::crypto_generichash_init(null, self::CRYPTO_KX_SESSIONKEYBYTES * 2);
+        self::crypto_generichash_update($h, self::crypto_scalarmult($sk, $serverPublicKey));
+        self::crypto_generichash_update($h, $pk);
+        self::crypto_generichash_update($h, $serverPublicKey);
+        $sessionKeys = self::crypto_generichash_final($h, self::CRYPTO_KX_SESSIONKEYBYTES * 2);
+        return array(
+            ParagonIE_Sodium_Core_Util::substr(
+                $sessionKeys,
+                0,
+                self::CRYPTO_KX_SESSIONKEYBYTES
+            ),
+            ParagonIE_Sodium_Core_Util::substr(
+                $sessionKeys,
+                self::CRYPTO_KX_SESSIONKEYBYTES,
+                self::CRYPTO_KX_SESSIONKEYBYTES
+            )
+        );
+    }
+
+    /**
+     * @param string $keypair
+     * @param string $clientPublicKey
+     * @return array{0: string, 1: string}
+     * @throws SodiumException
+     */
+    public static function crypto_kx_server_session_keys($keypair, $clientPublicKey)
+    {
+        ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1);
+        ParagonIE_Sodium_Core_Util::declareScalarType($clientPublicKey, 'string', 2);
+
+        $keypair = (string) $keypair;
+        $clientPublicKey = (string) $clientPublicKey;
+
+        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_KX_KEYPAIRBYTES) {
+            throw new SodiumException('keypair should be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes');
+        }
+        if (ParagonIE_Sodium_Core_Util::strlen($clientPublicKey) !== self::CRYPTO_KX_PUBLICKEYBYTES) {
+            throw new SodiumException('public keys must be SODIUM_CRYPTO_KX_PUBLICKEYBYTES bytes');
+        }
+
+        $sk = self::crypto_kx_secretkey($keypair);
+        $pk = self::crypto_kx_publickey($keypair);
+        $h = self::crypto_generichash_init(null, self::CRYPTO_KX_SESSIONKEYBYTES * 2);
+        self::crypto_generichash_update($h, self::crypto_scalarmult($sk, $clientPublicKey));
+        self::crypto_generichash_update($h, $clientPublicKey);
+        self::crypto_generichash_update($h, $pk);
+        $sessionKeys = self::crypto_generichash_final($h, self::CRYPTO_KX_SESSIONKEYBYTES * 2);
+        return array(
+            ParagonIE_Sodium_Core_Util::substr(
+                $sessionKeys,
+                self::CRYPTO_KX_SESSIONKEYBYTES,
+                self::CRYPTO_KX_SESSIONKEYBYTES
+            ),
+            ParagonIE_Sodium_Core_Util::substr(
+                $sessionKeys,
+                0,
+                self::CRYPTO_KX_SESSIONKEYBYTES
+            )
+        );
+    }
+
+    /**
+     * @param string $kp
+     * @return string
+     * @throws SodiumException
+     */
+    public static function crypto_kx_secretkey($kp)
+    {
+        return ParagonIE_Sodium_Core_Util::substr(
+            $kp,
+            0,
+            self::CRYPTO_KX_SECRETKEYBYTES
+        );
+    }
+
+    /**
+     * @param string $kp
+     * @return string
+     * @throws SodiumException
+     */
+    public static function crypto_kx_publickey($kp)
+    {
+        return ParagonIE_Sodium_Core_Util::substr(
+            $kp,
+            self::CRYPTO_KX_SECRETKEYBYTES,
+            self::CRYPTO_KX_PUBLICKEYBYTES
+        );
+    }
+
     /**
      * @param int $outlen
      * @param string $passwd
@@ -1592,6 +1973,36 @@
         );
     }
 
+    /**
+     * Do we need to rehash this password?
+     *
+     * @param string $hash
+     * @param int $opslimit
+     * @param int $memlimit
+     * @return bool
+     * @throws SodiumException
+     */
+    public static function crypto_pwhash_str_needs_rehash($hash, $opslimit, $memlimit)
+    {
+        ParagonIE_Sodium_Core_Util::declareScalarType($hash, 'string', 1);
+        ParagonIE_Sodium_Core_Util::declareScalarType($opslimit, 'int', 2);
+        ParagonIE_Sodium_Core_Util::declareScalarType($memlimit, 'int', 3);
+
+        // Just grab the first 4 pieces.
+        $pieces = explode('$', (string) $hash);
+        $prefix = implode('$', array_slice($pieces, 0, 4));
+
+        // Rebuild the expected header.
+        /** @var int $ops */
+        $ops = (int) $opslimit;
+        /** @var int $mem */
+        $mem = (int) $memlimit >> 10;
+        $encoded = self::CRYPTO_PWHASH_STRPREFIX . 'v=19$m=' . $mem . ',t=' . $ops . ',p=1';
+
+        // Do they match? If so, we don't need to rehash, so return false.
+        return !ParagonIE_Sodium_Core_Util::hashEquals($encoded, $prefix);
+    }
+
     /**
      * @param string $passwd
      * @param string $hash
@@ -1987,6 +2398,111 @@
         return ParagonIE_Sodium_Crypto::secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key);
     }
 
+    /**
+     * @param string $key
+     * @return array<int, string> Returns a state and a header.
+     * @throws Exception
+     * @throws SodiumException
+     */
+    public static function crypto_secretstream_xchacha20poly1305_init_push($key)
+    {
+        if (PHP_INT_SIZE === 4) {
+            return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_init_push($key);
+        }
+        return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_init_push($key);
+    }
+
+    /**
+     * @param string $header
+     * @param string $key
+     * @return string Returns a state.
+     * @throws Exception
+     */
+    public static function crypto_secretstream_xchacha20poly1305_init_pull($header, $key)
+    {
+        if (ParagonIE_Sodium_Core_Util::strlen($header) < self::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES) {
+            throw new SodiumException(
+                'header size should be SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES bytes'
+            );
+        }
+        if (PHP_INT_SIZE === 4) {
+            return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_init_pull($key, $header);
+        }
+        return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_init_pull($key, $header);
+    }
+
+    /**
+     * @param string $state
+     * @param string $msg
+     * @param string $aad
+     * @param int $tag
+     * @return string
+     * @throws SodiumException
+     */
+    public static function crypto_secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0)
+    {
+        if (PHP_INT_SIZE === 4) {
+            return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_push(
+                $state,
+                $msg,
+                $aad,
+                $tag
+            );
+        }
+        return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_push(
+            $state,
+            $msg,
+            $aad,
+            $tag
+        );
+    }
+
+    /**
+     * @param string $state
+     * @param string $msg
+     * @param string $aad
+     * @return bool|array{0: string, 1: int}
+     * @throws SodiumException
+     */
+    public static function crypto_secretstream_xchacha20poly1305_pull(&$state, $msg, $aad = '')
+    {
+        if (PHP_INT_SIZE === 4) {
+            return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_pull(
+                $state,
+                $msg,
+                $aad
+            );
+        }
+        return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_pull(
+            $state,
+            $msg,
+            $aad
+        );
+    }
+
+    /**
+     * @return string
+     * @throws Exception
+     */
+    public static function crypto_secretstream_xchacha20poly1305_keygen()
+    {
+        return random_bytes(self::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES);
+    }
+
+    /**
+     * @param string $state
+     * @return void
+     * @throws SodiumException
+     */
+    public static function crypto_secretstream_xchacha20poly1305_rekey(&$state)
+    {
+        if (PHP_INT_SIZE === 4) {
+            ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_rekey($state);
+        } else {
+            ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_rekey($state);
+        }
+    }
+
     /**
      * Calculates a SipHash-2-4 hash of a message for a given key.
      *
@@ -2136,6 +2652,32 @@
         return ParagonIE_Sodium_Core_Ed25519::keypair();
     }
 
+    /**
+     * @param string $sk
+     * @param string $pk
+     * @return string
+     * @throws SodiumException
+     */
+    public static function crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk)
+    {
+        ParagonIE_Sodium_Core_Util::declareScalarType($sk, 'string', 1);
+        ParagonIE_Sodium_Core_Util::declareScalarType($pk, 'string', 1);
+        $sk = (string) $sk;
+        $pk = (string) $pk;
+
+        if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_SIGN_SECRETKEYBYTES) {
+            throw new SodiumException('secretkey should be SODIUM_CRYPTO_SIGN_SECRETKEYBYTES bytes');
+        }
+        if (ParagonIE_Sodium_Core_Util::strlen($pk) !== self::CRYPTO_SIGN_PUBLICKEYBYTES) {
+            throw new SodiumException('publickey should be SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES bytes');
+        }
+
+        if (self::useNewSodiumAPI()) {
+            return sodium_crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk);
+        }
+        return $sk . $pk;
+    }
+
     /**
      * Generate an Ed25519 keypair from a seed.
      *
@@ -2624,6 +3166,9 @@
         ParagonIE_Sodium_Core_Util::declareScalarType($left, 'string', 1);
         ParagonIE_Sodium_Core_Util::declareScalarType($right, 'string', 2);
 
+        if (self::useNewSodiumAPI()) {
+            return sodium_memcmp($left, $right);
+        }
         if (self::use_fallback('memcmp')) {
             return (int) call_user_func('\\Sodium\\memcmp', $left, $right);
         }
@@ -2668,6 +3213,158 @@
         );
     }
 
+    /**
+     * @param string $unpadded
+     * @param int $blockSize
+     * @param bool $dontFallback
+     * @return string
+     * @throws SodiumException
+     */
+    public static function pad($unpadded, $blockSize, $dontFallback = false)
+    {
+        /* Type checks: */
+        ParagonIE_Sodium_Core_Util::declareScalarType($unpadded, 'string', 1);
+        ParagonIE_Sodium_Core_Util::declareScalarType($blockSize, 'int', 2);
+
+        $unpadded = (string) $unpadded;
+        $blockSize = (int) $blockSize;
+
+        if (self::useNewSodiumAPI() && !$dontFallback) {
+            return (string) sodium_pad($unpadded, $blockSize);
+        }
+
+        if ($blockSize <= 0) {
+            throw new SodiumException(
+                'block size cannot be less than 1'
+            );
+        }
+        $unpadded_len = ParagonIE_Sodium_Core_Util::strlen($unpadded);
+        $xpadlen = ($blockSize - 1);
+        if (($blockSize & ($blockSize - 1)) === 0) {
+            $xpadlen -= $unpadded_len & ($blockSize - 1);
+        } else {
+            $xpadlen -= $unpadded_len % $blockSize;
+        }
+
+        $xpadded_len = $unpadded_len + $xpadlen;
+        $padded = str_repeat("\0", $xpadded_len - 1);
+        if ($unpadded_len > 0) {
+            $st = 1;
+            $i = 0;
+            $k = $unpadded_len;
+            for ($j = 0; $j <= $xpadded_len; ++$j) {
+                $i = (int) $i;
+                $k = (int) $k;
+                $st = (int) $st;
+                if ($j >= $unpadded_len) {
+                    $padded[$j] = "\0";
+                } else {
+                    $padded[$j] = $unpadded[$j];
+                }
+                /** @var int $k */
+                $k -= $st;
+                $st = (int) (~(
+                            (
+                                (
+                                    ($k >> 48)
+                                        |
+                                    ($k >> 32)
+                                        |
+                                    ($k >> 16)
+                                        |
+                                    $k
+                                ) - 1
+                            ) >> 16
+                        )
+                    ) & 1;
+                $i += $st;
+            }
+        }
+
+        $mask = 0;
+        $tail = $xpadded_len;
+        for ($i = 0; $i < $blockSize; ++$i) {
+            # barrier_mask = (unsigned char)
+            #     (((i ^ xpadlen) - 1U) >> ((sizeof(size_t) - 1U) * CHAR_BIT));
+            $barrier_mask = (($i ^ $xpadlen) -1) >> ((PHP_INT_SIZE << 3) - 1);
+            # tail[-i] = (tail[-i] & mask) | (0x80 & barrier_mask);
+            $padded[$tail - $i] = ParagonIE_Sodium_Core_Util::intToChr(
+                (ParagonIE_Sodium_Core_Util::chrToInt($padded[$tail - $i]) & $mask)
+                    |
+                (0x80 & $barrier_mask)
+            );
+            # mask |= barrier_mask;
+            $mask |= $barrier_mask;
+        }
+        return $padded;
+    }
+
+    /**
+     * @param string $padded
+     * @param int $blockSize
+     * @param bool $dontFallback
+     * @return string
+     * @throws SodiumException
+     */
+    public static function unpad($padded, $blockSize, $dontFallback = false)
+    {
+        /* Type checks: */
+        ParagonIE_Sodium_Core_Util::declareScalarType($padded, 'string', 1);
+        ParagonIE_Sodium_Core_Util::declareScalarType($blockSize, 'int', 2);
+
+        $padded = (string) $padded;
+        $blockSize = (int) $blockSize;
+
+        if (self::useNewSodiumAPI() && !$dontFallback) {
+            return (string) sodium_unpad($padded, $blockSize);
+        }
+        if ($blockSize <= 0) {
+            throw new SodiumException('block size cannot be less than 1');
+        }
+        $padded_len = ParagonIE_Sodium_Core_Util::strlen($padded);
+        if ($padded_len < $blockSize) {
+            throw new SodiumException('invalid padding');
+        }
+
+        # tail = &padded[padded_len - 1U];
+        $tail = $padded_len - 1;
+
+        $acc = 0;
+        $valid = 0;
+        $pad_len = 0;
+
+        $found = 0;
+        for ($i = 0; $i < $blockSize; ++$i) {
+            # c = tail[-i];
+            $c = ParagonIE_Sodium_Core_Util::chrToInt($padded[$tail - $i]);
+
+            # is_barrier =
+            #     (( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U;
+            $is_barrier = (
+                (
+                    ($acc - 1) & ($pad_len - 1) & (($c ^ 80) - 1)
+                ) >> 7
+            ) & 1;
+            $is_barrier &= ~$found;
+            $found |= $is_barrier;
+
+            # acc |= c;
+            $acc |= $c;
+
+            # pad_len |= i & (1U + ~is_barrier);
+            $pad_len |= $i & (1 + ~$is_barrier);
+
+            # valid |= (unsigned char) is_barrier;
+            $valid |= ($is_barrier & 0xff);
+        }
+        # unpadded_len = padded_len - 1U - pad_len;
+        $unpadded_len = $padded_len - 1 - $pad_len;
+        if ($valid !== 1) {
+            throw new SodiumException('invalid padding');
+        }
+        return ParagonIE_Sodium_Core_Util::substr($padded, 0, $unpadded_len);
+    }
+
     /**
      * Will sodium_compat run fast on the current hardware and PHP configuration?
      *
Index: wp-includes/sodium_compat/src/File.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- wp-includes/sodium_compat/src/File.php	(date 1571337483000)
+++ wp-includes/sodium_compat/src/File.php	(date 1571412398307)
@@ -679,7 +679,11 @@
         }
 
         /* Security checks */
-        if (ParagonIE_Sodium_Core_Ed25519::check_S_lt_L(self::substr($sig, 32, 32))) {
+        if (
+            (ParagonIE_Sodium_Core_Ed25519::chrToInt($sig[63]) & 240)
+                &&
+            ParagonIE_Sodium_Core_Ed25519::check_S_lt_L(self::substr($sig, 32, 32))
+        ) {
             throw new SodiumException('S < L - Invalid signature');
         }
         if (ParagonIE_Sodium_Core_Ed25519::small_order($sig)) {
@@ -841,7 +845,7 @@
         if (!is_string($plaintext)) {
             throw new SodiumException('Could not read input file');
         }
-        $first32 = ftell($ifp);
+        $first32 = self::ftell($ifp);
 
         /** @var string $subkey */
         $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key);
@@ -875,7 +879,7 @@
         );
 
         // Pre-write 16 blank bytes for the Poly1305 tag
-        $start = ftell($ofp);
+        $start = self::ftell($ofp);
         fwrite($ofp, str_repeat("\x00", 16));
 
         /** @var string $c */
@@ -926,7 +930,7 @@
             $block0 = null;
             $subkey = null;
         }
-        $end = ftell($ofp);
+        $end = self::ftell($ofp);
 
         /*
          * Write the Poly1305 authentication tag that provides integrity
@@ -1043,7 +1047,7 @@
         $mlen = 0
     ) {
         /** @var int $pos */
-        $pos = ftell($ifp);
+        $pos = self::ftell($ifp);
 
         /** @var int $iter */
         $iter = 1;
@@ -1106,7 +1110,7 @@
         }
 
         /** @var int $originalPosition */
-        $originalPosition = ftell($fp);
+        $originalPosition = self::ftell($fp);
 
         // Move file pointer to beginning of file
         fseek($fp, 0, SEEK_SET);
@@ -1314,7 +1318,7 @@
         if (!is_string($plaintext)) {
             throw new SodiumException('Could not read input file');
         }
-        $first32 = ftell($ifp);
+        $first32 = self::ftell($ifp);
 
         /** @var string $subkey */
         $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key);
@@ -1348,7 +1352,7 @@
         );
 
         // Pre-write 16 blank bytes for the Poly1305 tag
-        $start = ftell($ofp);
+        $start = self::ftell($ofp);
         fwrite($ofp, str_repeat("\x00", 16));
 
         /** @var string $c */
@@ -1399,7 +1403,7 @@
             $block0 = null;
             $subkey = null;
         }
-        $end = ftell($ofp);
+        $end = self::ftell($ofp);
 
         /*
          * Write the Poly1305 authentication tag that provides integrity
@@ -1515,7 +1519,7 @@
         $mlen = 0
     ) {
         /** @var int $pos */
-        $pos = ftell($ifp);
+        $pos = self::ftell($ifp);
 
         /** @var int $iter */
         $iter = 1;
@@ -1540,4 +1544,18 @@
         fseek($ifp, $pos, SEEK_SET);
         return $res;
     }
+
+    /**
+     * @param resource $resource
+     * @return int
+     * @throws SodiumException
+     */
+    private static function ftell($resource)
+    {
+        $return = ftell($resource);
+        if (!is_int($return)) {
+            throw new SodiumException('ftell() returned false');
+        }
+        return (int) $return;
+    }
 }
