Upgrade/Install: Update sodium_compat to v1.23.0.

The previous version of sodium_compat was overly permissible with `sodium_base642bin()` when the `*_NO_PADDING` variants were specified, which was not compatible with `ext-sodium`. This has been fixed in version 1.22.0.

Version 1.23.0 includes some optimizations by replacing the array in the Curve25519 field element with 10 integer object properties instead. The result is a 7% to 12% speedup for the overall PHPUnit suite.

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

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

Props paragoninitiativeenterprises, SergeyBiryukov.
Fixes #64079.
Built from https://develop.svn.wordpress.org/trunk@60905


git-svn-id: http://core.svn.wordpress.org/trunk@60241 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Sergey Biryukov
2025-10-06 15:48:40 +00:00
parent a6cf78ca4d
commit 988cfffa1e
17 changed files with 660 additions and 390 deletions

View File

@@ -25,6 +25,9 @@ if (class_exists('ParagonIE_Sodium_Compat', false)) {
return;
}
/**
* @api
*/
class ParagonIE_Sodium_Compat
{
/**
@@ -204,9 +207,6 @@ class ParagonIE_Sodium_Compat
/** @var string $encoded */
$encoded = (string) $encoded;
if (ParagonIE_Sodium_Core_Util::strlen($encoded) === 0) {
return '';
}
// Just strip before decoding
if (!empty($ignore)) {
@@ -218,11 +218,11 @@ class ParagonIE_Sodium_Compat
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);
return ParagonIE_Sodium_Core_Base64_Original::decodeNoPadding($encoded);
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);
return ParagonIE_Sodium_Core_Base64_UrlSafe::decodeNoPadding($encoded);
default:
throw new SodiumException('invalid base64 variant identifier');
}
@@ -230,7 +230,7 @@ class ParagonIE_Sodium_Compat
if ($ex instanceof SodiumException) {
throw $ex;
}
throw new SodiumException('invalid base64 string');
throw new SodiumException('invalid base64 string', 0, $ex);
}
}
@@ -356,7 +356,7 @@ class ParagonIE_Sodium_Compat
/* Input validation: */
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS128L_NPUBBYTES) {
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS_128L_NPUBBYTES long');
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_NPUBBYTES long');
}
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS128L_KEYBYTES) {
throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
@@ -410,7 +410,7 @@ class ParagonIE_Sodium_Compat
/* Input validation: */
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS128L_NPUBBYTES) {
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_NPUBBYTES long');
}
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS128L_KEYBYTES) {
throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
@@ -519,10 +519,10 @@ class ParagonIE_Sodium_Compat
/* Input validation: */
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS256_NPUBBYTES) {
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS256_NPUBBYTES long');
}
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS256_KEYBYTES) {
throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long');
throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS256_KEYBYTES long');
}
list($ct, $tag) = ParagonIE_Sodium_Core_AEGIS256::encrypt($plaintext, $assocData, $key, $nonce);
@@ -562,6 +562,9 @@ class ParagonIE_Sodium_Compat
// OpenSSL doesn't support AEAD before 7.1.0
return false;
}
if (!extension_loaded('openssl')) {
return false;
}
if (!is_callable('openssl_encrypt') || !is_callable('openssl_decrypt')) {
// OpenSSL isn't installed
return false;
@@ -615,6 +618,9 @@ class ParagonIE_Sodium_Compat
if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_AES256GCM_ABYTES) {
throw new SodiumException('Message must be at least CRYPTO_AEAD_AES256GCM_ABYTES long');
}
if (!extension_loaded('openssl')) {
throw new SodiumException('The OpenSSL extension is not installed');
}
if (!is_callable('openssl_decrypt')) {
throw new SodiumException('The OpenSSL extension is not installed, or openssl_decrypt() is not available');
}
@@ -675,6 +681,9 @@ class ParagonIE_Sodium_Compat
throw new SodiumException('Key must be CRYPTO_AEAD_AES256GCM_KEYBYTES long');
}
if (!extension_loaded('openssl')) {
throw new SodiumException('The OpenSSL extension is not installed');
}
if (!is_callable('openssl_encrypt')) {
throw new SodiumException('The OpenSSL extension is not installed, or openssl_encrypt() is not available');
}
@@ -823,10 +832,10 @@ class ParagonIE_Sodium_Compat
/* Input validation: */
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES) {
throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES long');
throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES long');
}
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES) {
throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES long');
throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES long');
}
if (self::useNewSodiumAPI()) {
@@ -901,10 +910,10 @@ class ParagonIE_Sodium_Compat
throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES long');
}
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES) {
throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES long');
throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES long');
}
if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_CHACHA20POLY1305_ABYTES) {
throw new SodiumException('Message must be at least CRYPTO_AEAD_CHACHA20POLY1305_ABYTES long');
throw new SodiumException('Message must be at least CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES long');
}
if (self::useNewSodiumAPI()) {
@@ -2781,6 +2790,9 @@ class ParagonIE_Sodium_Compat
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SECRETBOX_KEYBYTES) {
throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.');
}
if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_SECRETBOX_MACBYTES) {
throw new SodiumException("Ciphertext must be at least CRYPTO_SECRETBOX_MACBYTES long");
}
if (PHP_INT_SIZE === 4) {
return ParagonIE_Sodium_Crypto32::secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key);
@@ -3711,6 +3723,9 @@ class ParagonIE_Sodium_Compat
}
$len = ParagonIE_Sodium_Core_Util::strlen($var);
if ($len < 1) {
throw new SodiumException('Argument 1 cannot be empty');
}
$c = 1;
$copy = '';
for ($i = 0; $i < $len; ++$i) {

View File

@@ -185,6 +185,32 @@ class ParagonIE_Sodium_Core_Base64_Original
}
return $dest;
}
/**
* @param string $encodedString
* @return string
*/
public static function decodeNoPadding(
#[SensitiveParameter]
$encodedString
) {
$srcLen = strlen($encodedString);
if ($srcLen === 0) {
return '';
}
if (($srcLen & 3) === 0) {
// If $strLen is not zero, and it is divisible by 4, then it's at least 4.
if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') {
throw new InvalidArgumentException(
"decodeNoPadding() doesn't tolerate padding"
);
}
}
return self::decode(
$encodedString,
true
);
}
// COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
/**

View File

@@ -185,6 +185,33 @@ class ParagonIE_Sodium_Core_Base64_UrlSafe
}
return $dest;
}
/**
* @param string $encodedString
* @return string
*/
public static function decodeNoPadding(
#[SensitiveParameter]
$encodedString
) {
$srcLen = strlen($encodedString);
if ($srcLen === 0) {
return '';
}
if (($srcLen & 3) === 0) {
// If $strLen is not zero, and it is divisible by 4, then it's at least 4.
if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') {
throw new InvalidArgumentException(
"decodeNoPadding() doesn't tolerate padding"
);
}
}
return self::decode(
$encodedString,
true
);
}
// COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
/**
* Uses bitwise operators instead of table-lookups to turn 6-bit integers

View File

@@ -329,7 +329,7 @@ class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function stream($len = 64, $nonce = '', $key = '')
public static function stream($len, $nonce, $key)
{
return self::encryptBytes(
new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce),
@@ -347,7 +347,7 @@ class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function ietfStream($len, $nonce = '', $key = '')
public static function ietfStream($len, $nonce, $key)
{
return self::encryptBytes(
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce),
@@ -366,7 +366,7 @@ class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
public static function ietfStreamXorIc($message, $nonce, $key, $ic = '')
{
return self::encryptBytes(
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce, $ic),
@@ -385,7 +385,7 @@ class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
public static function streamXorIc($message, $nonce, $key, $ic = '')
{
return self::encryptBytes(
new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce, $ic),

View File

@@ -50,13 +50,9 @@ class ParagonIE_Sodium_Core_ChaCha20_Ctx extends ParagonIE_Sodium_Core_Util impl
$this->container[10] = self::load_4(self::substr($key, 24, 4));
$this->container[11] = self::load_4(self::substr($key, 28, 4));
if (empty($counter)) {
$this->container[12] = 0;
$this->container[13] = 0;
} else {
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
$this->container[13] = self::load_4(self::substr($counter, 4, 4));
}
$counter = $this->initCounter($counter);
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
$this->container[13] = self::load_4(self::substr($counter, 4, 4));
$this->container[14] = self::load_4(self::substr($iv, 0, 4));
$this->container[15] = self::load_4(self::substr($iv, 4, 4));
}
@@ -120,4 +116,28 @@ class ParagonIE_Sodium_Core_ChaCha20_Ctx extends ParagonIE_Sodium_Core_Util impl
? $this->container[$offset]
: null;
}
/**
* Initialize (pad) a counter value.
* @throws SodiumException
*
* @param string $ctr
* @return string
*/
public function initCounter(
#[SensitiveParameter]
$ctr
) {
$len = self::strlen($ctr);
if ($len === 0) {
return str_repeat("\0", 8);
}
if ($len < 8) {
return $ctr . str_repeat("\0", 8 - $len);
}
if ($len > 8) {
throw new SodiumException("counter cannot be more than 8 bytes");
}
return $ctr;
}
}

View File

@@ -26,11 +26,9 @@ class ParagonIE_Sodium_Core_ChaCha20_IetfCtx extends ParagonIE_Sodium_Core_ChaCh
if (self::strlen($iv) !== 12) {
throw new InvalidArgumentException('ChaCha20 expects a 96-bit nonce in IETF mode.');
}
$counter = $this->initCounter($counter);
parent::__construct($key, self::substr($iv, 0, 8), $counter);
if (!empty($counter)) {
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
}
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
$this->container[13] = self::load_4(self::substr($iv, 0, 4));
$this->container[14] = self::load_4(self::substr($iv, 4, 4));
$this->container[15] = self::load_4(self::substr($iv, 8, 4));

View File

@@ -24,9 +24,7 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
*/
public static function fe_0()
{
return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
);
return new ParagonIE_Sodium_Core_Curve25519_Fe();
}
/**
@@ -38,9 +36,9 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
*/
public static function fe_1()
{
return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
);
$fe = new ParagonIE_Sodium_Core_Curve25519_Fe();
$fe->e0 = 1;
return $fe;
}
/**
@@ -58,12 +56,18 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
ParagonIE_Sodium_Core_Curve25519_Fe $f,
ParagonIE_Sodium_Core_Curve25519_Fe $g
) {
/** @var array<int, int> $arr */
$arr = array();
for ($i = 0; $i < 10; ++$i) {
$arr[$i] = (int) ($f[$i] + $g[$i]);
}
return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($arr);
return new ParagonIE_Sodium_Core_Curve25519_Fe(
(int)($f->e0 + $g->e0),
(int)($f->e1 + $g->e1),
(int)($f->e2 + $g->e2),
(int)($f->e3 + $g->e3),
(int)($f->e4 + $g->e4),
(int)($f->e5 + $g->e5),
(int)($f->e6 + $g->e6),
(int)($f->e7 + $g->e7),
(int)($f->e8 + $g->e8),
(int)($f->e9 + $g->e9)
);
}
/**
@@ -82,14 +86,19 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
ParagonIE_Sodium_Core_Curve25519_Fe $g,
$b = 0
) {
/** @var array<int, int> $h */
$h = array();
$h = new ParagonIE_Sodium_Core_Curve25519_Fe();
$b *= -1;
for ($i = 0; $i < 10; ++$i) {
$x = (($f[$i] ^ $g[$i]) & $b);
$h[$i] = ($f[$i]) ^ $x;
}
return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h);
$x = (($f->e0 ^ $g->e0) & $b); $h->e0 = $f->e0 ^ $x;
$x = (($f->e1 ^ $g->e1) & $b); $h->e1 = $f->e1 ^ $x;
$x = (($f->e2 ^ $g->e2) & $b); $h->e2 = $f->e2 ^ $x;
$x = (($f->e3 ^ $g->e3) & $b); $h->e3 = $f->e3 ^ $x;
$x = (($f->e4 ^ $g->e4) & $b); $h->e4 = $f->e4 ^ $x;
$x = (($f->e5 ^ $g->e5) & $b); $h->e5 = $f->e5 ^ $x;
$x = (($f->e6 ^ $g->e6) & $b); $h->e6 = $f->e6 ^ $x;
$x = (($f->e7 ^ $g->e7) & $b); $h->e7 = $f->e7 ^ $x;
$x = (($f->e8 ^ $g->e8) & $b); $h->e8 = $f->e8 ^ $x;
$x = (($f->e9 ^ $g->e9) & $b); $h->e9 = $f->e9 ^ $x;
return $h;
}
/**
@@ -102,8 +111,7 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
*/
public static function fe_copy(ParagonIE_Sodium_Core_Curve25519_Fe $f)
{
$h = clone $f;
return $h;
return clone $f;
}
/**
@@ -165,19 +173,17 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
$h9 += $carry8;
$h8 -= $carry8 << 26;
return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
array(
(int) $h0,
(int) $h1,
(int) $h2,
(int) $h3,
(int) $h4,
(int) $h5,
(int) $h6,
(int) $h7,
(int) $h8,
(int) $h9
)
return new ParagonIE_Sodium_Core_Curve25519_Fe(
(int) $h0,
(int) $h1,
(int) $h2,
(int) $h3,
(int) $h4,
(int) $h5,
(int) $h6,
(int) $h7,
(int) $h8,
(int) $h9
);
}
@@ -191,16 +197,16 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
*/
public static function fe_tobytes(ParagonIE_Sodium_Core_Curve25519_Fe $h)
{
$h0 = (int) $h[0];
$h1 = (int) $h[1];
$h2 = (int) $h[2];
$h3 = (int) $h[3];
$h4 = (int) $h[4];
$h5 = (int) $h[5];
$h6 = (int) $h[6];
$h7 = (int) $h[7];
$h8 = (int) $h[8];
$h9 = (int) $h[9];
$h0 = (int) $h->e0;
$h1 = (int) $h->e1;
$h2 = (int) $h->e2;
$h3 = (int) $h->e3;
$h4 = (int) $h->e4;
$h5 = (int) $h->e5;
$h6 = (int) $h->e6;
$h7 = (int) $h->e7;
$h8 = (int) $h->e8;
$h9 = (int) $h->e9;
$q = (self::mul($h9, 19, 5) + (1 << 24)) >> 25;
$q = ($h0 + $q) >> 26;
@@ -345,26 +351,26 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
// Ensure limbs aren't oversized.
$f = self::fe_normalize($f);
$g = self::fe_normalize($g);
$f0 = $f[0];
$f1 = $f[1];
$f2 = $f[2];
$f3 = $f[3];
$f4 = $f[4];
$f5 = $f[5];
$f6 = $f[6];
$f7 = $f[7];
$f8 = $f[8];
$f9 = $f[9];
$g0 = $g[0];
$g1 = $g[1];
$g2 = $g[2];
$g3 = $g[3];
$g4 = $g[4];
$g5 = $g[5];
$g6 = $g[6];
$g7 = $g[7];
$g8 = $g[8];
$g9 = $g[9];
$f0 = $f->e0;
$f1 = $f->e1;
$f2 = $f->e2;
$f3 = $f->e3;
$f4 = $f->e4;
$f5 = $f->e5;
$f6 = $f->e6;
$f7 = $f->e7;
$f8 = $f->e8;
$f9 = $f->e9;
$g0 = $g->e0;
$g1 = $g->e1;
$g2 = $g->e2;
$g3 = $g->e3;
$g4 = $g->e4;
$g5 = $g->e5;
$g6 = $g->e6;
$g7 = $g->e7;
$g8 = $g->e8;
$g9 = $g->e9;
$g1_19 = self::mul($g1, 19, 5);
$g2_19 = self::mul($g2, 19, 5);
$g3_19 = self::mul($g3, 19, 5);
@@ -535,19 +541,17 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
$h0 -= $carry0 << 26;
return self::fe_normalize(
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
array(
(int) $h0,
(int) $h1,
(int) $h2,
(int) $h3,
(int) $h4,
(int) $h5,
(int) $h6,
(int) $h7,
(int) $h8,
(int) $h9
)
new ParagonIE_Sodium_Core_Curve25519_Fe(
(int) $h0,
(int) $h1,
(int) $h2,
(int) $h3,
(int) $h4,
(int) $h5,
(int) $h6,
(int) $h7,
(int) $h8,
(int) $h9
)
);
}
@@ -565,11 +569,20 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
*/
public static function fe_neg(ParagonIE_Sodium_Core_Curve25519_Fe $f)
{
$h = new ParagonIE_Sodium_Core_Curve25519_Fe();
for ($i = 0; $i < 10; ++$i) {
$h[$i] = -$f[$i];
}
return self::fe_normalize($h);
return self::fe_normalize(
new ParagonIE_Sodium_Core_Curve25519_Fe(
-$f->e0,
-$f->e1,
-$f->e2,
-$f->e3,
-$f->e4,
-$f->e5,
-$f->e6,
-$f->e7,
-$f->e8,
-$f->e9
)
);
}
/**
@@ -585,16 +598,16 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
public static function fe_sq(ParagonIE_Sodium_Core_Curve25519_Fe $f)
{
$f = self::fe_normalize($f);
$f0 = (int) $f[0];
$f1 = (int) $f[1];
$f2 = (int) $f[2];
$f3 = (int) $f[3];
$f4 = (int) $f[4];
$f5 = (int) $f[5];
$f6 = (int) $f[6];
$f7 = (int) $f[7];
$f8 = (int) $f[8];
$f9 = (int) $f[9];
$f0 = (int) $f->e0;
$f1 = (int) $f->e1;
$f2 = (int) $f->e2;
$f3 = (int) $f->e3;
$f4 = (int) $f->e4;
$f5 = (int) $f->e5;
$f6 = (int) $f->e6;
$f7 = (int) $f->e7;
$f8 = (int) $f->e8;
$f9 = (int) $f->e9;
$f0_2 = $f0 << 1;
$f1_2 = $f1 << 1;
@@ -719,19 +732,17 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
$h0 -= $carry0 << 26;
return self::fe_normalize(
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
array(
(int) $h0,
(int) $h1,
(int) $h2,
(int) $h3,
(int) $h4,
(int) $h5,
(int) $h6,
(int) $h7,
(int) $h8,
(int) $h9
)
new ParagonIE_Sodium_Core_Curve25519_Fe(
(int) $h0,
(int) $h1,
(int) $h2,
(int) $h3,
(int) $h4,
(int) $h5,
(int) $h6,
(int) $h7,
(int) $h8,
(int) $h9
)
);
}
@@ -750,16 +761,16 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
public static function fe_sq2(ParagonIE_Sodium_Core_Curve25519_Fe $f)
{
$f = self::fe_normalize($f);
$f0 = (int) $f[0];
$f1 = (int) $f[1];
$f2 = (int) $f[2];
$f3 = (int) $f[3];
$f4 = (int) $f[4];
$f5 = (int) $f[5];
$f6 = (int) $f[6];
$f7 = (int) $f[7];
$f8 = (int) $f[8];
$f9 = (int) $f[9];
$f0 = (int) $f->e0;
$f1 = (int) $f->e1;
$f2 = (int) $f->e2;
$f3 = (int) $f->e3;
$f4 = (int) $f->e4;
$f5 = (int) $f->e5;
$f6 = (int) $f->e6;
$f7 = (int) $f->e7;
$f8 = (int) $f->e8;
$f9 = (int) $f->e9;
$f0_2 = $f0 << 1;
$f1_2 = $f1 << 1;
@@ -885,19 +896,17 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
$h0 -= $carry0 << 26;
return self::fe_normalize(
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
array(
(int) $h0,
(int) $h1,
(int) $h2,
(int) $h3,
(int) $h4,
(int) $h5,
(int) $h6,
(int) $h7,
(int) $h8,
(int) $h9
)
new ParagonIE_Sodium_Core_Curve25519_Fe(
(int) $h0,
(int) $h1,
(int) $h2,
(int) $h3,
(int) $h4,
(int) $h5,
(int) $h6,
(int) $h7,
(int) $h8,
(int) $h9
)
);
}
@@ -1099,19 +1108,17 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
public static function fe_sub(ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g)
{
return self::fe_normalize(
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
array(
(int) ($f[0] - $g[0]),
(int) ($f[1] - $g[1]),
(int) ($f[2] - $g[2]),
(int) ($f[3] - $g[3]),
(int) ($f[4] - $g[4]),
(int) ($f[5] - $g[5]),
(int) ($f[6] - $g[6]),
(int) ($f[7] - $g[7]),
(int) ($f[8] - $g[8]),
(int) ($f[9] - $g[9])
)
new ParagonIE_Sodium_Core_Curve25519_Fe(
(int) ($f->e0 - $g->e0),
(int) ($f->e1 - $g->e1),
(int) ($f->e2 - $g->e2),
(int) ($f->e3 - $g->e3),
(int) ($f->e4 - $g->e4),
(int) ($f->e5 - $g->e5),
(int) ($f->e6 - $g->e6),
(int) ($f->e7 - $g->e7),
(int) ($f->e8 - $g->e8),
(int) ($f->e9 - $g->e9)
)
);
}
@@ -2800,38 +2807,38 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
* @var array<int, int>
*/
$arr = array(
(int) ($s0 >> 0),
(int) ($s0 >> 8),
(int) (($s0 >> 16) | $s1 << 5),
(int) ($s1 >> 3),
(int) ($s1 >> 11),
(int) (($s1 >> 19) | $s2 << 2),
(int) ($s2 >> 6),
(int) (($s2 >> 14) | $s3 << 7),
(int) ($s3 >> 1),
(int) ($s3 >> 9),
(int) (($s3 >> 17) | $s4 << 4),
(int) ($s4 >> 4),
(int) ($s4 >> 12),
(int) (($s4 >> 20) | $s5 << 1),
(int) ($s5 >> 7),
(int) (($s5 >> 15) | $s6 << 6),
(int) ($s6 >> 2),
(int) ($s6 >> 10),
(int) (($s6 >> 18) | $s7 << 3),
(int) ($s7 >> 5),
(int) ($s7 >> 13),
(int) ($s8 >> 0),
(int) ($s8 >> 8),
(int) (($s8 >> 16) | $s9 << 5),
(int) ($s9 >> 3),
(int) ($s9 >> 11),
(int) (($s9 >> 19) | $s10 << 2),
(int) ($s10 >> 6),
(int) (($s10 >> 14) | $s11 << 7),
(int) ($s11 >> 1),
(int) ($s11 >> 9),
(int) $s11 >> 17
(int) (0xff & ($s0 >> 0)),
(int) (0xff & ($s0 >> 8)),
(int) (0xff & (($s0 >> 16) | $s1 << 5)),
(int) (0xff & ($s1 >> 3)),
(int) (0xff & ($s1 >> 11)),
(int) (0xff & (($s1 >> 19) | $s2 << 2)),
(int) (0xff & ($s2 >> 6)),
(int) (0xff & (($s2 >> 14) | $s3 << 7)),
(int) (0xff & ($s3 >> 1)),
(int) (0xff & ($s3 >> 9)),
(int) (0xff & (($s3 >> 17) | $s4 << 4)),
(int) (0xff & ($s4 >> 4)),
(int) (0xff & ($s4 >> 12)),
(int) (0xff & (($s4 >> 20) | $s5 << 1)),
(int) (0xff & ($s5 >> 7)),
(int) (0xff & (($s5 >> 15) | $s6 << 6)),
(int) (0xff & ($s6 >> 2)),
(int) (0xff & ($s6 >> 10)),
(int) (0xff & (($s6 >> 18) | $s7 << 3)),
(int) (0xff & ($s7 >> 5)),
(int) (0xff & ($s7 >> 13)),
(int) (0xff & ($s8 >> 0)),
(int) (0xff & ($s8 >> 8)),
(int) (0xff & (($s8 >> 16) | $s9 << 5)),
(int) (0xff & ($s9 >> 3)),
(int) (0xff & ($s9 >> 11)),
(int) (0xff & (($s9 >> 19) | $s10 << 2)),
(int) (0xff & ($s10 >> 6)),
(int) (0xff & (($s10 >> 14) | $s11 << 7)),
(int) (0xff & ($s11 >> 1)),
(int) (0xff & ($s11 >> 9)),
(int) (0xff & ($s11 >> 17))
);
return self::intArrayToString($arr);
}
@@ -3794,7 +3801,7 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
$s_ = self::stringToIntArray($s);
$s_[0] &= 248;
$s_[31] |= 64;
$s_[31] &= 128;
$s_[31] &= 127;
return self::intArrayToString($s_);
}
@@ -3811,26 +3818,40 @@ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Cu
$x = (PHP_INT_SIZE << 3) - 1; // 31 or 63
$g = self::fe_copy($f);
$e = array(
$g->e0, $g->e1, $g->e2, $g->e3, $g->e4,
$g->e5, $g->e6, $g->e7, $g->e8, $g->e9
);
for ($i = 0; $i < 10; ++$i) {
$mask = -(($g[$i] >> $x) & 1);
$mask = -(($e[$i] >> $x) & 1);
/*
* Get two candidate normalized values for $g[$i], depending on the sign of $g[$i]:
* Get two candidate normalized values for $e[$i], depending on the sign of $e[$i]:
*/
$a = $g[$i] & 0x7ffffff;
$b = -((-$g[$i]) & 0x7ffffff);
$a = $e[$i] & 0x7ffffff;
$b = -((-$e[$i]) & 0x7ffffff);
/*
* Return the appropriate candidate value, based on the sign of the original input:
*
* The following is equivalent to this ternary:
*
* $g[$i] = (($g[$i] >> $x) & 1) ? $a : $b;
* $e[$i] = (($e[$i] >> $x) & 1) ? $a : $b;
*
* Except what's written doesn't contain timing leaks.
*/
$g[$i] = ($a ^ (($a ^ $b) & $mask));
$e[$i] = ($a ^ (($a ^ $b) & $mask));
}
$g->e0 = $e[0];
$g->e1 = $e[1];
$g->e2 = $e[2];
$g->e3 = $e[3];
$g->e4 = $e[4];
$g->e5 = $e[5];
$g->e6 = $e[6];
$g->e7 = $e[7];
$g->e8 = $e[8];
$g->e9 = $e[9];
return $g;
}
}
}

View File

@@ -12,43 +12,110 @@ if (class_exists('ParagonIE_Sodium_Core_Curve25519_Fe', false)) {
class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
{
/**
* @var array<int, int>
* @var int
*/
protected $container = array();
public $e0 = 0;
/**
* @var int
*/
protected $size = 10;
public $e1 = 0;
/**
* @var int
*/
public $e2 = 0;
/**
* @var int
*/
public $e3 = 0;
/**
* @var int
*/
public $e4 = 0;
/**
* @var int
*/
public $e5 = 0;
/**
* @var int
*/
public $e6 = 0;
/**
* @var int
*/
public $e7 = 0;
/**
* @var int
*/
public $e8 = 0;
/**
* @var int
*/
public $e9 = 0;
/**
* @param int $e0
* @param int $e1
* @param int $e2
* @param int $e3
* @param int $e4
* @param int $e5
* @param int $e6
* @param int $e7
* @param int $e8
* @param int $e9
*/
public function __construct(
$e0 = 0,
$e1 = 0,
$e2 = 0,
$e3 = 0,
$e4 = 0,
$e5 = 0,
$e6 = 0,
$e7 = 0,
$e8 = 0,
$e9 = 0
) {
$this->e0 = $e0;
$this->e1 = $e1;
$this->e2 = $e2;
$this->e3 = $e3;
$this->e4 = $e4;
$this->e5 = $e5;
$this->e6 = $e6;
$this->e7 = $e7;
$this->e8 = $e8;
$this->e9 = $e9;
}
/**
* @internal You should not use this directly from another application
*
* @param array<int, int> $array
* @param bool $save_indexes
* @param array $array
* @return self
*/
public static function fromArray($array, $save_indexes = null)
public static function fromArray($array)
{
$count = count($array);
if ($save_indexes) {
$keys = array_keys($array);
} else {
$keys = range(0, $count - 1);
}
$array = array_values($array);
/** @var array<int, int> $keys */
$obj = new ParagonIE_Sodium_Core_Curve25519_Fe();
if ($save_indexes) {
for ($i = 0; $i < $count; ++$i) {
$obj->offsetSet($keys[$i], $array[$i]);
}
} else {
for ($i = 0; $i < $count; ++$i) {
$obj->offsetSet($i, $array[$i]);
}
}
$obj->e0 = isset($array[0]) ? (int) $array[0] : 0;
$obj->e1 = isset($array[1]) ? (int) $array[1] : 0;
$obj->e2 = isset($array[2]) ? (int) $array[2] : 0;
$obj->e3 = isset($array[3]) ? (int) $array[3] : 0;
$obj->e4 = isset($array[4]) ? (int) $array[4] : 0;
$obj->e5 = isset($array[5]) ? (int) $array[5] : 0;
$obj->e6 = isset($array[6]) ? (int) $array[6] : 0;
$obj->e7 = isset($array[7]) ? (int) $array[7] : 0;
$obj->e8 = isset($array[8]) ? (int) $array[8] : 0;
$obj->e9 = isset($array[9]) ? (int) $array[9] : 0;
return $obj;
}
@@ -58,7 +125,6 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
* @param int|null $offset
* @param int $value
* @return void
* @psalm-suppress MixedArrayOffset
*/
#[ReturnTypeWillChange]
public function offsetSet($offset, $value)
@@ -66,10 +132,39 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
if (!is_int($value)) {
throw new InvalidArgumentException('Expected an integer');
}
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
switch ($offset) {
case 0:
$this->e0 = $value;
break;
case 1:
$this->e1 = $value;
break;
case 2:
$this->e2 = $value;
break;
case 3:
$this->e3 = $value;
break;
case 4:
$this->e4 = $value;
break;
case 5:
$this->e5 = $value;
break;
case 6:
$this->e6 = $value;
break;
case 7:
$this->e7 = $value;
break;
case 8:
$this->e8 = $value;
break;
case 9:
$this->e9 = $value;
break;
default:
throw new OutOfBoundsException('Index out of bounds');
}
}
@@ -78,12 +173,11 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
*
* @param int $offset
* @return bool
* @psalm-suppress MixedArrayOffset
*/
#[ReturnTypeWillChange]
public function offsetExists($offset)
{
return isset($this->container[$offset]);
return $offset >= 0 && $offset < 10;
}
/**
@@ -91,12 +185,44 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
*
* @param int $offset
* @return void
* @psalm-suppress MixedArrayOffset
*/
#[ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->container[$offset]);
switch ($offset) {
case 0:
$this->e0 = 0;
break;
case 1:
$this->e1 = 0;
break;
case 2:
$this->e2 = 0;
break;
case 3:
$this->e3 = 0;
break;
case 4:
$this->e4 = 0;
break;
case 5:
$this->e5 = 0;
break;
case 6:
$this->e6 = 0;
break;
case 7:
$this->e7 = 0;
break;
case 8:
$this->e8 = 0;
break;
case 9:
$this->e9 = 0;
break;
default:
throw new OutOfBoundsException('Index out of bounds');
}
}
/**
@@ -104,15 +230,34 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
*
* @param int $offset
* @return int
* @psalm-suppress MixedArrayOffset
*/
#[ReturnTypeWillChange]
public function offsetGet($offset)
{
if (!isset($this->container[$offset])) {
$this->container[$offset] = 0;
switch ($offset) {
case 0:
return (int) $this->e0;
case 1:
return (int) $this->e1;
case 2:
return (int) $this->e2;
case 3:
return (int) $this->e3;
case 4:
return (int) $this->e4;
case 5:
return (int) $this->e5;
case 6:
return (int) $this->e6;
case 7:
return (int) $this->e7;
case 8:
return (int) $this->e8;
case 9:
return (int) $this->e9;
default:
throw new OutOfBoundsException('Index out of bounds');
}
return (int) ($this->container[$offset]);
}
/**
@@ -122,6 +267,11 @@ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
*/
public function __debugInfo()
{
return array(implode(', ', $this->container));
return array(
implode(', ', array(
$this->e0, $this->e1, $this->e2, $this->e3, $this->e4,
$this->e5, $this->e6, $this->e7, $this->e8, $this->e9
))
);
}
}

View File

@@ -46,7 +46,7 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
public static function seed_keypair(&$pk, &$sk, $seed)
{
if (self::strlen($seed) !== self::SEED_BYTES) {
throw new RangeException('crypto_sign keypair seed must be 32 bytes long');
throw new SodiumException('crypto_sign keypair seed must be 32 bytes long');
}
/** @var string $pk */
@@ -65,7 +65,7 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
public static function secretkey($keypair)
{
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
throw new RangeException('crypto_sign keypair must be 96 bytes long');
throw new SodiumException('crypto_sign keypair must be 96 bytes long');
}
return self::substr($keypair, 0, 64);
}
@@ -80,7 +80,7 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
public static function publickey($keypair)
{
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
throw new RangeException('crypto_sign keypair must be 96 bytes long');
throw new SodiumException('crypto_sign keypair must be 96 bytes long');
}
return self::substr($keypair, 64, 32);
}
@@ -212,6 +212,9 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
*/
public static function sign_detached($message, $sk)
{
if (self::strlen($sk) !== 64) {
throw new SodiumException('Argument 2 must be CRYPTO_SIGN_SECRETKEYBYTES long');
}
# crypto_hash_sha512(az, sk, 32);
$az = hash('sha512', self::substr($sk, 0, 32), true);
@@ -277,8 +280,11 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
*/
public static function verify_detached($sig, $message, $pk)
{
if (self::strlen($sig) < 64) {
throw new SodiumException('Signature is too short');
if (self::strlen($sig) !== 64) {
throw new SodiumException('Argument 1 must be CRYPTO_SIGN_BYTES long');
}
if (self::strlen($pk) !== 32) {
throw new SodiumException('Argument 3 must be CRYPTO_SIGN_PUBLICKEYBYTES long');
}
if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) {
throw new SodiumException('S < L - Invalid signature');

View File

@@ -14,10 +14,18 @@ class ParagonIE_Sodium_Core_HChaCha20 extends ParagonIE_Sodium_Core_ChaCha20
* @param string $key
* @param string|null $c
* @return string
*
* @throws SodiumException
* @throws TypeError
*/
public static function hChaCha20($in = '', $key = '', $c = null)
public static function hChaCha20($in, $key, $c = null)
{
if (self::strlen($in) !== 16) {
throw new SodiumException('Argument 1 must be 16 bytes');
}
if (self::strlen($key) !== 32) {
throw new SodiumException('Argument 2 must be 32 bytes');
}
$ctx = array();
if ($c === null) {

View File

@@ -22,7 +22,7 @@ abstract class ParagonIE_Sodium_Core_Poly1305 extends ParagonIE_Sodium_Core_Util
*/
public static function onetimeauth($m, $key)
{
if (self::strlen($key) < 32) {
if (self::strlen($key) !== 32) {
throw new InvalidArgumentException(
'Key must be 32 bytes long.'
);

View File

@@ -181,6 +181,8 @@ abstract class ParagonIE_Sodium_Core_Util
$len = max($leftLen, $rightLen);
$left = str_pad($left, $len, "\x00", STR_PAD_RIGHT);
$right = str_pad($right, $len, "\x00", STR_PAD_RIGHT);
} elseif ($leftLen !== $rightLen) {
throw new SodiumException("Argument #1 and argument #2 must have the same length");
}
$gt = 0;
@@ -336,7 +338,8 @@ abstract class ParagonIE_Sodium_Core_Util
* @param string $ignore
* @param bool $strictPadding
* @return string (raw binary)
* @throws RangeException
*
* @throws SodiumException
* @throws TypeError
*/
public static function hex2bin($hexString, $ignore = '', $strictPadding = false)
@@ -354,16 +357,6 @@ abstract class ParagonIE_Sodium_Core_Util
$c_acc = 0;
$hex_len = self::strlen($hexString);
$state = 0;
if (($hex_len & 1) !== 0) {
if ($strictPadding) {
throw new RangeException(
'Expected an even number of hexadecimal characters'
);
} else {
$hexString = '0' . $hexString;
++$hex_len;
}
}
$chunk = unpack('C*', $hexString);
while ($hex_pos < $hex_len) {
@@ -390,6 +383,11 @@ abstract class ParagonIE_Sodium_Core_Util
}
$state ^= 1;
}
if ($strictPadding && $state !== 0) {
throw new SodiumException(
'Expected an even number of hexadecimal characters'
);
}
return $bin;
}
@@ -534,10 +532,8 @@ abstract class ParagonIE_Sodium_Core_Util
*/
public static function memcmp($left, $right)
{
if (self::hashEquals($left, $right)) {
return 0;
}
return -1;
$e = (int) !self::hashEquals($left, $right);
return 0 - $e;
}
/**

View File

@@ -25,57 +25,37 @@ abstract class ParagonIE_Sodium_Core_X25519 extends ParagonIE_Sodium_Core_Curve2
ParagonIE_Sodium_Core_Curve25519_Fe $g,
$b = 0
) {
$f0 = (int) $f[0];
$f1 = (int) $f[1];
$f2 = (int) $f[2];
$f3 = (int) $f[3];
$f4 = (int) $f[4];
$f5 = (int) $f[5];
$f6 = (int) $f[6];
$f7 = (int) $f[7];
$f8 = (int) $f[8];
$f9 = (int) $f[9];
$g0 = (int) $g[0];
$g1 = (int) $g[1];
$g2 = (int) $g[2];
$g3 = (int) $g[3];
$g4 = (int) $g[4];
$g5 = (int) $g[5];
$g6 = (int) $g[6];
$g7 = (int) $g[7];
$g8 = (int) $g[8];
$g9 = (int) $g[9];
$b = -$b;
$x0 = ($f0 ^ $g0) & $b;
$x1 = ($f1 ^ $g1) & $b;
$x2 = ($f2 ^ $g2) & $b;
$x3 = ($f3 ^ $g3) & $b;
$x4 = ($f4 ^ $g4) & $b;
$x5 = ($f5 ^ $g5) & $b;
$x6 = ($f6 ^ $g6) & $b;
$x7 = ($f7 ^ $g7) & $b;
$x8 = ($f8 ^ $g8) & $b;
$x9 = ($f9 ^ $g9) & $b;
$f[0] = $f0 ^ $x0;
$f[1] = $f1 ^ $x1;
$f[2] = $f2 ^ $x2;
$f[3] = $f3 ^ $x3;
$f[4] = $f4 ^ $x4;
$f[5] = $f5 ^ $x5;
$f[6] = $f6 ^ $x6;
$f[7] = $f7 ^ $x7;
$f[8] = $f8 ^ $x8;
$f[9] = $f9 ^ $x9;
$g[0] = $g0 ^ $x0;
$g[1] = $g1 ^ $x1;
$g[2] = $g2 ^ $x2;
$g[3] = $g3 ^ $x3;
$g[4] = $g4 ^ $x4;
$g[5] = $g5 ^ $x5;
$g[6] = $g6 ^ $x6;
$g[7] = $g7 ^ $x7;
$g[8] = $g8 ^ $x8;
$g[9] = $g9 ^ $x9;
$x0 = ($f->e0 ^ $g->e0) & $b;
$x1 = ($f->e1 ^ $g->e1) & $b;
$x2 = ($f->e2 ^ $g->e2) & $b;
$x3 = ($f->e3 ^ $g->e3) & $b;
$x4 = ($f->e4 ^ $g->e4) & $b;
$x5 = ($f->e5 ^ $g->e5) & $b;
$x6 = ($f->e6 ^ $g->e6) & $b;
$x7 = ($f->e7 ^ $g->e7) & $b;
$x8 = ($f->e8 ^ $g->e8) & $b;
$x9 = ($f->e9 ^ $g->e9) & $b;
$f->e0 ^= $x0;
$f->e1 ^= $x1;
$f->e2 ^= $x2;
$f->e3 ^= $x3;
$f->e4 ^= $x4;
$f->e5 ^= $x5;
$f->e6 ^= $x6;
$f->e7 ^= $x7;
$f->e8 ^= $x8;
$f->e9 ^= $x9;
$g->e0 ^= $x0;
$g->e1 ^= $x1;
$g->e2 ^= $x2;
$g->e3 ^= $x3;
$g->e4 ^= $x4;
$g->e5 ^= $x5;
$g->e6 ^= $x6;
$g->e7 ^= $x7;
$g->e8 ^= $x8;
$g->e9 ^= $x9;
}
/**
@@ -86,65 +66,58 @@ abstract class ParagonIE_Sodium_Core_X25519 extends ParagonIE_Sodium_Core_Curve2
*/
public static function fe_mul121666(ParagonIE_Sodium_Core_Curve25519_Fe $f)
{
$h = array(
self::mul((int) $f[0], 121666, 17),
self::mul((int) $f[1], 121666, 17),
self::mul((int) $f[2], 121666, 17),
self::mul((int) $f[3], 121666, 17),
self::mul((int) $f[4], 121666, 17),
self::mul((int) $f[5], 121666, 17),
self::mul((int) $f[6], 121666, 17),
self::mul((int) $f[7], 121666, 17),
self::mul((int) $f[8], 121666, 17),
self::mul((int) $f[9], 121666, 17)
);
$h0 = self::mul($f->e0, 121666, 17);
$h1 = self::mul($f->e1, 121666, 17);
$h2 = self::mul($f->e2, 121666, 17);
$h3 = self::mul($f->e3, 121666, 17);
$h4 = self::mul($f->e4, 121666, 17);
$h5 = self::mul($f->e5, 121666, 17);
$h6 = self::mul($f->e6, 121666, 17);
$h7 = self::mul($f->e7, 121666, 17);
$h8 = self::mul($f->e8, 121666, 17);
$h9 = self::mul($f->e9, 121666, 17);
/** @var int $carry9 */
$carry9 = ($h[9] + (1 << 24)) >> 25;
$h[0] += self::mul($carry9, 19, 5);
$h[9] -= $carry9 << 25;
/** @var int $carry1 */
$carry1 = ($h[1] + (1 << 24)) >> 25;
$h[2] += $carry1;
$h[1] -= $carry1 << 25;
/** @var int $carry3 */
$carry3 = ($h[3] + (1 << 24)) >> 25;
$h[4] += $carry3;
$h[3] -= $carry3 << 25;
/** @var int $carry5 */
$carry5 = ($h[5] + (1 << 24)) >> 25;
$h[6] += $carry5;
$h[5] -= $carry5 << 25;
/** @var int $carry7 */
$carry7 = ($h[7] + (1 << 24)) >> 25;
$h[8] += $carry7;
$h[7] -= $carry7 << 25;
$carry9 = ($h9 + (1 << 24)) >> 25;
$h0 += self::mul($carry9, 19, 5);
$h9 -= $carry9 << 25;
/** @var int $carry0 */
$carry0 = ($h[0] + (1 << 25)) >> 26;
$h[1] += $carry0;
$h[0] -= $carry0 << 26;
/** @var int $carry2 */
$carry2 = ($h[2] + (1 << 25)) >> 26;
$h[3] += $carry2;
$h[2] -= $carry2 << 26;
/** @var int $carry4 */
$carry4 = ($h[4] + (1 << 25)) >> 26;
$h[5] += $carry4;
$h[4] -= $carry4 << 26;
/** @var int $carry6 */
$carry6 = ($h[6] + (1 << 25)) >> 26;
$h[7] += $carry6;
$h[6] -= $carry6 << 26;
/** @var int $carry8 */
$carry8 = ($h[8] + (1 << 25)) >> 26;
$h[9] += $carry8;
$h[8] -= $carry8 << 26;
$carry1 = ($h1 + (1 << 24)) >> 25;
$h2 += $carry1;
$h1 -= $carry1 << 25;
foreach ($h as $i => $value) {
$h[$i] = (int) $value;
}
return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h);
$carry3 = ($h3 + (1 << 24)) >> 25;
$h4 += $carry3;
$h3 -= $carry3 << 25;
$carry5 = ($h5 + (1 << 24)) >> 25;
$h6 += $carry5;
$h5 -= $carry5 << 25;
$carry7 = ($h7 + (1 << 24)) >> 25;
$h8 += $carry7;
$h7 -= $carry7 << 25;
$carry0 = ($h0 + (1 << 25)) >> 26;
$h1 += $carry0;
$h0 -= $carry0 << 26;
$carry2 = ($h2 + (1 << 25)) >> 26;
$h3 += $carry2;
$h2 -= $carry2 << 26;
$carry4 = ($h4 + (1 << 25)) >> 26;
$h5 += $carry4;
$h4 -= $carry4 << 26;
$carry6 = ($h6 + (1 << 25)) >> 26;
$h7 += $carry6;
$h6 -= $carry6 << 26;
$carry8 = ($h8 + (1 << 25)) >> 26;
$h9 += $carry8;
$h8 -= $carry8 << 26;
return new ParagonIE_Sodium_Core_Curve25519_Fe($h0, $h1, $h2, $h3, $h4, $h5, $h6, $h7, $h8, $h9);
}
/**

View File

@@ -19,7 +19,7 @@ class ParagonIE_Sodium_Core_XChaCha20 extends ParagonIE_Sodium_Core_HChaCha20
* @throws SodiumException
* @throws TypeError
*/
public static function stream($len = 64, $nonce = '', $key = '')
public static function stream($len, $nonce, $key)
{
if (self::strlen($nonce) !== 24) {
throw new SodiumException('Nonce must be 24 bytes long');
@@ -46,7 +46,7 @@ class ParagonIE_Sodium_Core_XChaCha20 extends ParagonIE_Sodium_Core_HChaCha20
* @throws SodiumException
* @throws TypeError
*/
public static function ietfStream($len = 64, $nonce = '', $key = '')
public static function ietfStream($len, $nonce, $key)
{
if (self::strlen($nonce) !== 24) {
throw new SodiumException('Nonce must be 24 bytes long');
@@ -74,7 +74,7 @@ class ParagonIE_Sodium_Core_XChaCha20 extends ParagonIE_Sodium_Core_HChaCha20
* @throws SodiumException
* @throws TypeError
*/
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
public static function streamXorIc($message, $nonce, $key, $ic = '')
{
if (self::strlen($nonce) !== 24) {
throw new SodiumException('Nonce must be 24 bytes long');
@@ -100,7 +100,7 @@ class ParagonIE_Sodium_Core_XChaCha20 extends ParagonIE_Sodium_Core_HChaCha20
* @throws SodiumException
* @throws TypeError
*/
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
public static function ietfStreamXorIc($message, $nonce, $key, $ic = '')
{
if (self::strlen($nonce) !== 24) {
throw new SodiumException('Nonce must be 24 bytes long');

View File

@@ -1188,7 +1188,10 @@ abstract class ParagonIE_Sodium_Crypto
$clen = ParagonIE_Sodium_Core_Util::strlen($c);
/** @var string $subkey */
$subkey = ParagonIE_Sodium_Core_HChaCha20::hchacha20($nonce, $key);
$subkey = ParagonIE_Sodium_Core_HChaCha20::hchacha20(
ParagonIE_Sodium_Core_Util::substr($nonce, 0, 16),
$key
);
/** @var string $block0 */
$block0 = ParagonIE_Sodium_Core_ChaCha20::stream(
@@ -1244,7 +1247,10 @@ abstract class ParagonIE_Sodium_Crypto
$out = random_bytes(24);
# crypto_core_hchacha20(state->k, out, k, NULL);
$subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20($out, $key);
$subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20(
ParagonIE_Sodium_Core_Util::substr($out, 0, 16),
$key
);
$state = new ParagonIE_Sodium_Core_SecretStream_State(
$subkey,
ParagonIE_Sodium_Core_Util::substr($out, 16, 8) . str_repeat("\0", 4)

View File

@@ -125,6 +125,9 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
throw new TypeError('Argument 4 must be CRYPTO_BOX_KEYPAIRBYTES bytes');
}
if (!file_exists($inputFile)) {
throw new SodiumException('Input file does not exist');
}
/** @var int $size */
$size = filesize($inputFile);
if (!is_int($size)) {
@@ -138,7 +141,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
}
/** @var resource $ofp */
$ofp = fopen($outputFile, 'wb');
$ofp = @fopen($outputFile, 'wb');
if (!is_resource($ofp)) {
fclose($ifp);
throw new SodiumException('Could not open output file for writing');
@@ -193,6 +196,9 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
throw new TypeError('Argument 3 must be CRYPTO_BOX_PUBLICKEYBYTES bytes');
}
if (!file_exists($inputFile)) {
throw new SodiumException('Input file does not exist');
}
/** @var int $size */
$size = filesize($inputFile);
if (!is_int($size)) {
@@ -206,7 +212,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
}
/** @var resource $ofp */
$ofp = fopen($outputFile, 'wb');
$ofp = @fopen($outputFile, 'wb');
if (!is_resource($ofp)) {
fclose($ifp);
throw new SodiumException('Could not open output file for writing');
@@ -303,6 +309,9 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
$publicKey = ParagonIE_Sodium_Compat::crypto_box_publickey($ecdhKeypair);
if (!file_exists($inputFile)) {
throw new SodiumException('Input file does not exist');
}
/** @var int $size */
$size = filesize($inputFile);
if (!is_int($size)) {
@@ -316,7 +325,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
}
/** @var resource $ofp */
$ofp = fopen($outputFile, 'wb');
$ofp = @fopen($outputFile, 'wb');
if (!is_resource($ofp)) {
fclose($ifp);
throw new SodiumException('Could not open output file for writing');
@@ -408,6 +417,9 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
throw new SodiumException('Argument 3 must be at least CRYPTO_GENERICHASH_BYTES_MAX');
}
if (!file_exists($filePath)) {
throw new SodiumException('File does not exist');
}
/** @var int $size */
$size = filesize($filePath);
if (!is_int($size)) {
@@ -479,6 +491,9 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
throw new TypeError('Argument 4 must be CRYPTO_SECRETBOX_KEYBYTES bytes');
}
if (!file_exists($inputFile)) {
throw new SodiumException('Input file does not exist');
}
/** @var int $size */
$size = filesize($inputFile);
if (!is_int($size)) {
@@ -486,7 +501,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
}
/** @var resource $ifp */
$ifp = fopen($inputFile, 'rb');
$ifp = @fopen($inputFile, 'rb');
if (!is_resource($ifp)) {
throw new SodiumException('Could not open input file for reading');
}
@@ -543,12 +558,15 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
/* Input validation: */
if (self::strlen($nonce) !== ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_NONCEBYTES) {
throw new TypeError('Argument 4 must be CRYPTO_SECRETBOX_NONCEBYTES bytes');
throw new TypeError('Argument 3 must be CRYPTO_SECRETBOX_NONCEBYTES bytes');
}
if (self::strlen($key) !== ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_KEYBYTES) {
throw new TypeError('Argument 4 must be CRYPTO_SECRETBOXBOX_KEYBYTES bytes');
throw new TypeError('Argument 4 must be CRYPTO_SECRETBOX_KEYBYTES bytes');
}
if (!file_exists($inputFile)) {
throw new SodiumException('Input file does not exist');
}
/** @var int $size */
$size = filesize($inputFile);
if (!is_int($size)) {
@@ -562,7 +580,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
}
/** @var resource $ofp */
$ofp = fopen($outputFile, 'wb');
$ofp = @fopen($outputFile, 'wb');
if (!is_resource($ofp)) {
fclose($ifp);
throw new SodiumException('Could not open output file for writing');
@@ -613,6 +631,9 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
return self::sign_core32($filePath, $secretKey);
}
if (!file_exists($filePath)) {
throw new SodiumException('File does not exist');
}
/** @var int $size */
$size = filesize($filePath);
if (!is_int($size)) {
@@ -744,6 +765,9 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
throw new SodiumException('All zero public key');
}
if (!file_exists($filePath)) {
throw new SodiumException('File does not exist');
}
/** @var int $size */
$size = filesize($filePath);
if (!is_int($size)) {

View File

@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.9-alpha-60904';
$wp_version = '6.9-alpha-60905';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.