: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if (class_exists('ParagonIE_Sodium_Core_ChaCha20', false)) {
* Class ParagonIE_Sodium_Core_ChaCha20
class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util
* @internal You should not use this directly from another application
public static function rotate($v, $n)
* The ChaCha20 quarter round function. Works on four 32-bit integers.
* @internal You should not use this directly from another application
* @return array<int, int>
protected static function quarterRound($a, $b, $c, $d)
# a = PLUS(a,b); d = ROTATE(XOR(d,a),16);
$a = ($a + $b) & 0xffffffff;
$d = self::rotate($d ^ $a, 16);
# c = PLUS(c,d); b = ROTATE(XOR(b,c),12);
$c = ($c + $d) & 0xffffffff;
$b = self::rotate($b ^ $c, 12);
# a = PLUS(a,b); d = ROTATE(XOR(d,a), 8);
$a = ($a + $b) & 0xffffffff;
$d = self::rotate($d ^ $a, 8);
# c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
$c = ($c + $d) & 0xffffffff;
$b = self::rotate($b ^ $c, 7);
return array((int) $a, (int) $b, (int) $c, (int) $d);
* @internal You should not use this directly from another application
* @param ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx
* @throws SodiumException
public static function encryptBytes(
ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx,
$bytes = self::strlen($message);
$message .= str_repeat("\x00", 64 - $bytes);
# for (i = 20; i > 0; i -= 2) {
for ($i = 20; $i > 0; $i -= 2) {
# QUARTERROUND( x0, x4, x8, x12)
list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
# QUARTERROUND( x1, x5, x9, x13)
list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
# QUARTERROUND( x2, x6, x10, x14)
list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
# QUARTERROUND( x3, x7, x11, x15)
list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
# QUARTERROUND( x0, x5, x10, x15)
list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
# QUARTERROUND( x1, x6, x11, x12)
list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
# QUARTERROUND( x2, x7, x8, x13)
list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
# QUARTERROUND( x3, x4, x9, x14)
list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
$x0 = ($x0 & 0xffffffff) + $j0;
$x1 = ($x1 & 0xffffffff) + $j1;
$x2 = ($x2 & 0xffffffff) + $j2;
$x3 = ($x3 & 0xffffffff) + $j3;
$x4 = ($x4 & 0xffffffff) + $j4;
$x5 = ($x5 & 0xffffffff) + $j5;
$x6 = ($x6 & 0xffffffff) + $j6;
$x7 = ($x7 & 0xffffffff) + $j7;
$x8 = ($x8 & 0xffffffff) + $j8;
$x9 = ($x9 & 0xffffffff) + $j9;
$x10 = ($x10 & 0xffffffff) + $j10;
$x11 = ($x11 & 0xffffffff) + $j11;
$x12 = ($x12 & 0xffffffff) + $j12;
$x13 = ($x13 & 0xffffffff) + $j13;
$x14 = ($x14 & 0xffffffff) + $j14;
$x15 = ($x15 & 0xffffffff) + $j15;
x0 = XOR(x0, LOAD32_LE(m + 0));
x1 = XOR(x1, LOAD32_LE(m + 4));
x2 = XOR(x2, LOAD32_LE(m + 8));
x3 = XOR(x3, LOAD32_LE(m + 12));
x4 = XOR(x4, LOAD32_LE(m + 16));
x5 = XOR(x5, LOAD32_LE(m + 20));
x6 = XOR(x6, LOAD32_LE(m + 24));
x7 = XOR(x7, LOAD32_LE(m + 28));
x8 = XOR(x8, LOAD32_LE(m + 32));
x9 = XOR(x9, LOAD32_LE(m + 36));
x10 = XOR(x10, LOAD32_LE(m + 40));
x11 = XOR(x11, LOAD32_LE(m + 44));
x12 = XOR(x12, LOAD32_LE(m + 48));
x13 = XOR(x13, LOAD32_LE(m + 52));
x14 = XOR(x14, LOAD32_LE(m + 56));
x15 = XOR(x15, LOAD32_LE(m + 60));
$x0 ^= self::load_4(self::substr($message, 0, 4));
$x1 ^= self::load_4(self::substr($message, 4, 4));
$x2 ^= self::load_4(self::substr($message, 8, 4));
$x3 ^= self::load_4(self::substr($message, 12, 4));
$x4 ^= self::load_4(self::substr($message, 16, 4));
$x5 ^= self::load_4(self::substr($message, 20, 4));
$x6 ^= self::load_4(self::substr($message, 24, 4));
$x7 ^= self::load_4(self::substr($message, 28, 4));
$x8 ^= self::load_4(self::substr($message, 32, 4));
$x9 ^= self::load_4(self::substr($message, 36, 4));
$x10 ^= self::load_4(self::substr($message, 40, 4));
$x11 ^= self::load_4(self::substr($message, 44, 4));
$x12 ^= self::load_4(self::substr($message, 48, 4));
$x13 ^= self::load_4(self::substr($message, 52, 4));
$x14 ^= self::load_4(self::substr($message, 56, 4));
$x15 ^= self::load_4(self::substr($message, 60, 4));
throw new SodiumException('Overflow');
$block = self::store32_le((int) ($x0 & 0xffffffff)) .
self::store32_le((int) ($x1 & 0xffffffff)) .
self::store32_le((int) ($x2 & 0xffffffff)) .
self::store32_le((int) ($x3 & 0xffffffff)) .
self::store32_le((int) ($x4 & 0xffffffff)) .
self::store32_le((int) ($x5 & 0xffffffff)) .
self::store32_le((int) ($x6 & 0xffffffff)) .
self::store32_le((int) ($x7 & 0xffffffff)) .
self::store32_le((int) ($x8 & 0xffffffff)) .
self::store32_le((int) ($x9 & 0xffffffff)) .
self::store32_le((int) ($x10 & 0xffffffff)) .
self::store32_le((int) ($x11 & 0xffffffff)) .
self::store32_le((int) ($x12 & 0xffffffff)) .
self::store32_le((int) ($x13 & 0xffffffff)) .
self::store32_le((int) ($x14 & 0xffffffff)) .
self::store32_le((int) ($x15 & 0xffffffff));
$c .= self::substr($block, 0, $bytes);
$message = self::substr($message, 64);
* @internal You should not use this directly from another application
* @throws SodiumException
public static function stream($len = 64, $nonce = '', $key = '')
return self::encryptBytes(
new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce),
* @internal You should not use this directly from another application
* @throws SodiumException
public static function ietfStream($len, $nonce = '', $key = '')
return self::encryptBytes(
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce),
* @internal You should not use this directly from another application
* @throws SodiumException
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
return self::encryptBytes(
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce, $ic),
* @internal You should not use this directly from another application
* @throws SodiumException
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
return self::encryptBytes(
new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce, $ic),