Upgrade/Install: Update sodium_compat to v1.16.1.
The latest version of sodium_compat includes polyfills for new features slated to land in PHP 8.1: https://paragonie.com/blog/2021/05/ristretto255-for-php-community It also fixes a race condition with the autoloader that caused an "undefined constant" error on some systems: https://github.com/paragonie/sodium_compat/issues/122 A full list of changes in this update can be found on GitHub: https://github.com/paragonie/sodium_compat/compare/v1.14.0...v1.16.1 Follow-up to [49741]. Props paragoninitiativeenterprises, oxyrealm. Fixes #53274. Built from https://develop.svn.wordpress.org/trunk@51002 git-svn-id: http://core.svn.wordpress.org/trunk@50611 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
f6af848c72
commit
30d411f482
|
@ -1,21 +1,16 @@
|
|||
/*
|
||||
* ISC License
|
||||
*
|
||||
* Copyright (c) 2016-2019
|
||||
* Paragon Initiative Enterprises <security at paragonie dot com>
|
||||
*
|
||||
* Copyright (c) 2013-2019
|
||||
* Frank Denis <j at pureftpd dot org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2016-2021, Paragon Initiative Enterprises <security at paragonie dot com>
|
||||
Copyright (c) 2013-2019, Frank Denis <j at pureftpd dot org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
|
|
@ -41,6 +41,9 @@ if (PHP_VERSION_ID < 70000) {
|
|||
require_once dirname(__FILE__) . '/autoload-php7.php';
|
||||
}
|
||||
|
||||
/* Explicitly, always load the Compat class: */
|
||||
require_once dirname(__FILE__) . '/src/Compat.php';
|
||||
|
||||
if (!class_exists('SodiumException', false)) {
|
||||
require_once dirname(__FILE__) . '/src/SodiumException.php';
|
||||
}
|
||||
|
@ -62,4 +65,8 @@ if (PHP_VERSION_ID < 70200 || !extension_loaded('sodium')) {
|
|||
assert(class_exists('ParagonIE_Sodium_Compat'));
|
||||
}
|
||||
require_once(dirname(__FILE__) . '/lib/php72compat.php');
|
||||
} elseif (!function_exists('sodium_crypto_stream_xchacha20_xor')) {
|
||||
// Older versions of {PHP, ext/sodium} will not define these
|
||||
require_once(dirname(__FILE__) . '/lib/php72compat.php');
|
||||
}
|
||||
require_once(dirname(__FILE__) . '/lib/ristretto255.php');
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
"require-dev": {
|
||||
"phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
|
||||
"ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security."
|
||||
|
|
|
@ -94,6 +94,8 @@ foreach (array(
|
|||
'CRYPTO_SIGN_KEYPAIRBYTES',
|
||||
'CRYPTO_STREAM_KEYBYTES',
|
||||
'CRYPTO_STREAM_NONCEBYTES',
|
||||
'CRYPTO_STREAM_XCHACHA20_KEYBYTES',
|
||||
'CRYPTO_STREAM_XCHACHA20_NONCEBYTES',
|
||||
'LIBRARY_MAJOR_VERSION',
|
||||
'LIBRARY_MINOR_VERSION',
|
||||
'LIBRARY_VERSION_MAJOR',
|
||||
|
@ -1216,6 +1218,7 @@ if (!is_callable('sodium_crypto_stream_xor')) {
|
|||
return ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key);
|
||||
}
|
||||
}
|
||||
require_once dirname(__FILE__) . '/stream-xchacha20.php';
|
||||
if (!is_callable('sodium_hex2bin')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::hex2bin()
|
||||
|
|
|
@ -88,3 +88,5 @@ const SODIUM_CRYPTO_SIGN_SECRETKEYBYTES = 64;
|
|||
const SODIUM_CRYPTO_SIGN_KEYPAIRBYTES = 96;
|
||||
const SODIUM_CRYPTO_STREAM_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_STREAM_NONCEBYTES = 24;
|
||||
const SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES = 24;
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
<?php
|
||||
|
||||
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_BYTES
|
||||
);
|
||||
define('SODIUM_COMPAT_POLYFILLED_RISTRETTO255', true);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_HASHBYTES
|
||||
);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_SCALARBYTES
|
||||
);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES
|
||||
);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES
|
||||
);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_BYTES
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_add')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_add()
|
||||
*
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_add($p, $q)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_add($p, $q, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_from_hash')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_from_hash()
|
||||
*
|
||||
* @param string $r
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_from_hash($r)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_from_hash($r, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_is_valid_point')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_is_valid_point()
|
||||
*
|
||||
* @param string $p
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_is_valid_point($p)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_is_valid_point($p, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_random')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_random()
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_random()
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_random(true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_add')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_add()
|
||||
*
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_add($p, $q)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_add($p, $q, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_complement')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_complement()
|
||||
*
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_complement($p)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_complement($p, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_invert')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_invert()
|
||||
*
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_invert($p)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_invert($p, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_mul')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_mul()
|
||||
*
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_mul($p, $q)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_mul($p, $q, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_negate')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_negate()
|
||||
*
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_negate($p)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_negate($p, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_random')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_random()
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_random()
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_random(true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_reduce')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_reduce()
|
||||
*
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_reduce($p)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_reduce($p, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_sub')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_sub()
|
||||
*
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_sub($p, $q)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_sub($p, $q, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_sub')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_sub()
|
||||
*
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_sub($p, $q)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_sub($p, $q, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_scalarmult_ristretto255')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255()
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_scalarmult_ristretto255($n, $p)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::scalarmult_ristretto255($n, $p, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_scalarmult_ristretto255_base')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255_base()
|
||||
* @param string $n
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_scalarmult_ristretto255_base($n)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::scalarmult_ristretto255_base($n, true);
|
||||
}
|
||||
}
|
|
@ -391,7 +391,8 @@ if (!is_callable('\\Sodium\\crypto_kx')) {
|
|||
$my_secret,
|
||||
$their_public,
|
||||
$client_public,
|
||||
$server_public
|
||||
$server_public,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
if (!is_callable('sodium_crypto_stream_xchacha20')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20()
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_stream_xchacha20($len, $nonce, $key)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20($len, $nonce, $key, true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_stream_xchacha20_keygen')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen()
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
function sodium_crypto_stream_xchacha20_keygen()
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen();
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_stream_xchacha20_xor')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor()
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_stream_xchacha20_xor($message, $nonce, $key)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor($message, $nonce, $key, true);
|
||||
}
|
||||
}
|
|
@ -80,6 +80,10 @@ class ParagonIE_Sodium_Compat
|
|||
const CRYPTO_BOX_MACBYTES = 16;
|
||||
const CRYPTO_BOX_NONCEBYTES = 24;
|
||||
const CRYPTO_BOX_SEEDBYTES = 32;
|
||||
const CRYPTO_CORE_RISTRETTO255_BYTES = 32;
|
||||
const CRYPTO_CORE_RISTRETTO255_SCALARBYTES = 32;
|
||||
const CRYPTO_CORE_RISTRETTO255_HASHBYTES = 64;
|
||||
const CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES = 64;
|
||||
const CRYPTO_KDF_BYTES_MIN = 16;
|
||||
const CRYPTO_KDF_BYTES_MAX = 64;
|
||||
const CRYPTO_KDF_CONTEXTBYTES = 8;
|
||||
|
@ -115,6 +119,8 @@ class ParagonIE_Sodium_Compat
|
|||
const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824;
|
||||
const CRYPTO_SCALARMULT_BYTES = 32;
|
||||
const CRYPTO_SCALARMULT_SCALARBYTES = 32;
|
||||
const CRYPTO_SCALARMULT_RISTRETTO255_BYTES = 32;
|
||||
const CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES = 32;
|
||||
const CRYPTO_SHORTHASH_BYTES = 8;
|
||||
const CRYPTO_SHORTHASH_KEYBYTES = 16;
|
||||
const CRYPTO_SECRETBOX_KEYBYTES = 32;
|
||||
|
@ -135,6 +141,8 @@ class ParagonIE_Sodium_Compat
|
|||
const CRYPTO_SIGN_KEYPAIRBYTES = 96;
|
||||
const CRYPTO_STREAM_KEYBYTES = 32;
|
||||
const CRYPTO_STREAM_NONCEBYTES = 24;
|
||||
const CRYPTO_STREAM_XCHACHA20_KEYBYTES = 32;
|
||||
const CRYPTO_STREAM_XCHACHA20_NONCEBYTES = 24;
|
||||
|
||||
/**
|
||||
* Add two numbers (little-endian unsigned), storing the value in the first
|
||||
|
@ -727,7 +735,9 @@ class ParagonIE_Sodium_Compat
|
|||
) {
|
||||
/* Type checks: */
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1);
|
||||
if (!is_null($assocData)) {
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2);
|
||||
}
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3);
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
|
||||
|
||||
|
@ -814,7 +824,11 @@ class ParagonIE_Sodium_Compat
|
|||
) {
|
||||
/* Type checks: */
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1);
|
||||
if (!is_null($assocData)) {
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2);
|
||||
} else {
|
||||
$assocData = '';
|
||||
}
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3);
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
|
||||
|
||||
|
@ -885,7 +899,11 @@ class ParagonIE_Sodium_Compat
|
|||
) {
|
||||
/* Type checks: */
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1);
|
||||
if (!is_null($assocData)) {
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2);
|
||||
} else {
|
||||
$assocData = '';
|
||||
}
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3);
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
|
||||
|
||||
|
@ -1688,12 +1706,13 @@ class ParagonIE_Sodium_Compat
|
|||
* @param string $their_public
|
||||
* @param string $client_public
|
||||
* @param string $server_public
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress MixedArgument
|
||||
*/
|
||||
public static function crypto_kx($my_secret, $their_public, $client_public, $server_public)
|
||||
public static function crypto_kx($my_secret, $their_public, $client_public, $server_public, $dontFallback = false)
|
||||
{
|
||||
/* Type checks: */
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($my_secret, 'string', 1);
|
||||
|
@ -1715,7 +1734,7 @@ class ParagonIE_Sodium_Compat
|
|||
throw new SodiumException('Argument 4 must be CRYPTO_BOX_PUBLICKEYBYTES long.');
|
||||
}
|
||||
|
||||
if (self::useNewSodiumAPI()) {
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
if (is_callable('sodium_crypto_kx')) {
|
||||
return (string) sodium_crypto_kx(
|
||||
$my_secret,
|
||||
|
@ -3050,6 +3069,103 @@ class ParagonIE_Sodium_Compat
|
|||
return random_bytes(self::CRYPTO_STREAM_KEYBYTES);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expand a key and nonce into a keystream of pseudorandom bytes.
|
||||
*
|
||||
* @param int $len Number of bytes desired
|
||||
* @param string $nonce Number to be used Once; must be 24 bytes
|
||||
* @param string $key XChaCha20 key
|
||||
* @param bool $dontFallback
|
||||
* @return string Pseudorandom stream that can be XORed with messages
|
||||
* to provide encryption (but not authentication; see
|
||||
* Poly1305 or crypto_auth() for that, which is not
|
||||
* optional for security)
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress MixedArgument
|
||||
*/
|
||||
public static function crypto_stream_xchacha20($len, $nonce, $key, $dontFallback = false)
|
||||
{
|
||||
/* Type checks: */
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($len, 'int', 1);
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2);
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3);
|
||||
|
||||
/* Input validation: */
|
||||
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_XCHACHA20_NONCEBYTES) {
|
||||
throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_XCHACHA20_NONCEBYTES long.');
|
||||
}
|
||||
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_XCHACHA20_KEYBYTES) {
|
||||
throw new SodiumException('Argument 3 must be CRYPTO_STREAM_XCHACHA20_KEYBYTES long.');
|
||||
}
|
||||
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_stream_xchacha20($len, $nonce, $key);
|
||||
}
|
||||
if (PHP_INT_SIZE === 4) {
|
||||
return ParagonIE_Sodium_Core32_XChaCha20::stream($len, $nonce, $key);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_XChaCha20::stream($len, $nonce, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* DANGER! UNAUTHENTICATED ENCRYPTION!
|
||||
*
|
||||
* Unless you are following expert advice, do not used this feature.
|
||||
*
|
||||
* Algorithm: XChaCha20
|
||||
*
|
||||
* This DOES NOT provide ciphertext integrity.
|
||||
*
|
||||
* @param string $message Plaintext message
|
||||
* @param string $nonce Number to be used Once; must be 24 bytes
|
||||
* @param string $key Encryption key
|
||||
* @return string Encrypted text which is vulnerable to chosen-
|
||||
* ciphertext attacks unless you implement some
|
||||
* other mitigation to the ciphertext (i.e.
|
||||
* Encrypt then MAC)
|
||||
* @param bool $dontFallback
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress MixedArgument
|
||||
*/
|
||||
public static function crypto_stream_xchacha20_xor($message, $nonce, $key, $dontFallback = false)
|
||||
{
|
||||
/* Type checks: */
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1);
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2);
|
||||
ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3);
|
||||
|
||||
/* Input validation: */
|
||||
if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_XCHACHA20_NONCEBYTES) {
|
||||
throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_XCHACHA20_NONCEBYTES long.');
|
||||
}
|
||||
if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_XCHACHA20_KEYBYTES) {
|
||||
throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_XCHACHA20_KEYBYTES long.');
|
||||
}
|
||||
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_stream_xchacha20_xor($message, $nonce, $key);
|
||||
}
|
||||
if (PHP_INT_SIZE === 4) {
|
||||
return ParagonIE_Sodium_Core32_XChaCha20::streamXorIc($message, $nonce, $key);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_XChaCha20::streamXorIc($message, $nonce, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a secure random key for use with crypto_stream_xchacha20
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
* @throws Error
|
||||
*/
|
||||
public static function crypto_stream_xchacha20_keygen()
|
||||
{
|
||||
return random_bytes(self::CRYPTO_STREAM_XCHACHA20_KEYBYTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache-timing-safe implementation of hex2bin().
|
||||
*
|
||||
|
@ -3114,6 +3230,21 @@ class ParagonIE_Sodium_Compat
|
|||
$var = $copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @return bool
|
||||
*
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function is_zero($str)
|
||||
{
|
||||
$d = 0;
|
||||
for ($i = 0; $i < 32; ++$i) {
|
||||
$d |= ParagonIE_Sodium_Core_Util::chrToInt($str[$i]);
|
||||
}
|
||||
return ((($d - 1) >> 31) & 1) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The equivalent to the libsodium minor version we aim to be compatible
|
||||
* with (sans pwhash and memzero).
|
||||
|
@ -3451,6 +3582,232 @@ class ParagonIE_Sodium_Compat
|
|||
return random_int(0, 65535);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $p
|
||||
* @param bool $dontFallback
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_is_valid_point($p, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_is_valid_point($p);
|
||||
}
|
||||
try {
|
||||
$r = ParagonIE_Sodium_Core_Ristretto255::ristretto255_frombytes($p);
|
||||
return $r['res'] === 0 &&
|
||||
ParagonIE_Sodium_Core_Ristretto255::ristretto255_point_is_canonical($p) === 1;
|
||||
} catch (SodiumException $ex) {
|
||||
if ($ex->getMessage() === 'S is not canonical') {
|
||||
return false;
|
||||
}
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_add($p, $q, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_add($p, $q);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_add($p, $q);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_sub($p, $q, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_sub($p, $q);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_sub($p, $q);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $r
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
*
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_from_hash($r, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_from_hash($r);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_from_hash($r);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
*
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_random($dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_random();
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_random();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
*
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_random($dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_scalar_random();
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_random();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_invert($s, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_scalar_invert($s);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_invert($s);
|
||||
}
|
||||
/**
|
||||
* @param string $s
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_negate($s, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_scalar_negate($s);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_negate($s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_complement($s, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_scalar_complement($s);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_complement($s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_add($x, $y, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_scalar_add($x, $y);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_add($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_sub($x, $y, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_scalar_sub($x, $y);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_sub($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_mul($x, $y, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_scalar_mul($x, $y);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_mul($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalarmult_ristretto255($n, $p, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_scalarmult_ristretto255($n, $p);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::scalarmult_ristretto255($n, $p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalarmult_ristretto255_base($n, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_scalarmult_ristretto255_base($n);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::scalarmult_ristretto255_base($n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @param bool $dontFallback
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_reduce($s, $dontFallback = false)
|
||||
{
|
||||
if (self::useNewSodiumAPI() && !$dontFallback) {
|
||||
return sodium_crypto_core_ristretto255_scalar_reduce($s);
|
||||
}
|
||||
return ParagonIE_Sodium_Core_Ristretto255::sc_reduce($s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime testing method for 32-bit platforms.
|
||||
*
|
||||
|
@ -3487,6 +3844,36 @@ class ParagonIE_Sodium_Compat
|
|||
return $diff < $maxTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 sub(&$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] - $c);
|
||||
$A[$i] = ($c & 0xff);
|
||||
$c = ($c >> 8) & 1;
|
||||
}
|
||||
$val = ParagonIE_Sodium_Core_Util::intArrayToString($A);
|
||||
}
|
||||
|
||||
/**
|
||||
* This emulates libsodium's version_string() function, except ours is
|
||||
* prefixed with 'polyfill-'.
|
||||
|
|
|
@ -644,6 +644,7 @@ abstract class ParagonIE_Sodium_Core_BLAKE2b extends ParagonIE_Sodium_Core_Util
|
|||
*
|
||||
* @param string $str
|
||||
* @return SplFixedArray
|
||||
* @psalm-suppress MixedArgumentTypeCoercion
|
||||
*/
|
||||
public static function stringToSplFixedArray($str = '')
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1464,4 +1464,86 @@ class ParagonIE_Sodium_Core_Curve25519_H extends ParagonIE_Sodium_Core_Util
|
|||
326686,
|
||||
11406482
|
||||
);
|
||||
|
||||
/**
|
||||
* 1 / sqrt(a - d)
|
||||
*
|
||||
* @var array<int, int>
|
||||
*/
|
||||
protected static $invsqrtamd = array(
|
||||
6111485,
|
||||
4156064,
|
||||
-27798727,
|
||||
12243468,
|
||||
-25904040,
|
||||
120897,
|
||||
20826367,
|
||||
-7060776,
|
||||
6093568,
|
||||
-1986012
|
||||
);
|
||||
|
||||
/**
|
||||
* sqrt(ad - 1) with a = -1 (mod p)
|
||||
*
|
||||
* @var array<int, int>
|
||||
*/
|
||||
protected static $sqrtadm1 = array(
|
||||
24849947,
|
||||
-153582,
|
||||
-23613485,
|
||||
6347715,
|
||||
-21072328,
|
||||
-667138,
|
||||
-25271143,
|
||||
-15367704,
|
||||
-870347,
|
||||
14525639
|
||||
);
|
||||
|
||||
/**
|
||||
* 1 - d ^ 2
|
||||
*
|
||||
* @var array<int, int>
|
||||
*/
|
||||
protected static $onemsqd = array(
|
||||
6275446,
|
||||
-16617371,
|
||||
-22938544,
|
||||
-3773710,
|
||||
11667077,
|
||||
7397348,
|
||||
-27922721,
|
||||
1766195,
|
||||
-24433858,
|
||||
672203
|
||||
);
|
||||
|
||||
/**
|
||||
* (d - 1) ^ 2
|
||||
* @var array<int, int>
|
||||
*/
|
||||
protected static $sqdmone = array(
|
||||
15551795,
|
||||
-11097455,
|
||||
-13425098,
|
||||
-10125071,
|
||||
-11896535,
|
||||
10178284,
|
||||
-26634327,
|
||||
4729244,
|
||||
-5282110,
|
||||
-10116402
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* 2^252+27742317777372353535851937790883648493
|
||||
static const unsigned char L[] = {
|
||||
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
|
||||
0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
|
||||
};
|
||||
*/
|
||||
const L = "\xed\xd3\xf5\x5c\x1a\x63\x12\x58\xd6\x9c\xf7\xa2\xde\xf9\xde\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10";
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
|
|||
{
|
||||
const KEYPAIR_BYTES = 96;
|
||||
const SEED_BYTES = 32;
|
||||
const SCALAR_BYTES = 32;
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
|
@ -477,4 +478,74 @@ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_complement($s)
|
||||
{
|
||||
$t_ = self::L . str_repeat("\x00", 32);
|
||||
sodium_increment($t_);
|
||||
$s_ = $s . str_repeat("\x00", 32);
|
||||
ParagonIE_Sodium_Compat::sub($t_, $s_);
|
||||
return self::sc_reduce($t_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_random()
|
||||
{
|
||||
do {
|
||||
$r = ParagonIE_Sodium_Compat::randombytes_buf(self::SCALAR_BYTES);
|
||||
$r[self::SCALAR_BYTES - 1] = self::intToChr(
|
||||
self::chrToInt($r[self::SCALAR_BYTES - 1]) & 0x1f
|
||||
);
|
||||
} while (
|
||||
!self::check_S_lt_L($r) || ParagonIE_Sodium_Compat::is_zero($r)
|
||||
);
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_negate($s)
|
||||
{
|
||||
$t_ = self::L . str_repeat("\x00", 32) ;
|
||||
$s_ = $s . str_repeat("\x00", 32) ;
|
||||
ParagonIE_Sodium_Compat::sub($t_, $s_);
|
||||
return self::sc_reduce($t_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_add($a, $b)
|
||||
{
|
||||
$a_ = $a . str_repeat("\x00", 32);
|
||||
$b_ = $b . str_repeat("\x00", 32);
|
||||
ParagonIE_Sodium_Compat::add($a_, $b_);
|
||||
return self::sc_reduce($a_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_sub($x, $y)
|
||||
{
|
||||
$yn = self::scalar_negate($y);
|
||||
return self::scalar_add($x, $yn);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,707 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Ristretto255
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Ristretto255 extends ParagonIE_Sodium_Core_Ed25519
|
||||
{
|
||||
const crypto_core_ristretto255_HASHBYTES = 64;
|
||||
const HASH_SC_L = 48;
|
||||
const CORE_H2C_SHA256 = 1;
|
||||
const CORE_H2C_SHA512 = 2;
|
||||
|
||||
/**
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $f
|
||||
* @param int $b
|
||||
* @return ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public static function fe_cneg(ParagonIE_Sodium_Core_Curve25519_Fe $f, $b)
|
||||
{
|
||||
$negf = self::fe_neg($f);
|
||||
return self::fe_cmov($f, $negf, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $f
|
||||
* @return ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function fe_abs(ParagonIE_Sodium_Core_Curve25519_Fe $f)
|
||||
{
|
||||
return self::fe_cneg($f, self::fe_isnegative($f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 0 if this field element results in all NUL bytes.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $f
|
||||
* @return int
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function fe_iszero(ParagonIE_Sodium_Core_Curve25519_Fe $f)
|
||||
{
|
||||
static $zero;
|
||||
if ($zero === null) {
|
||||
$zero = str_repeat("\x00", 32);
|
||||
}
|
||||
/** @var string $zero */
|
||||
$str = self::fe_tobytes($f);
|
||||
|
||||
$d = 0;
|
||||
for ($i = 0; $i < 32; ++$i) {
|
||||
$d |= self::chrToInt($str[$i]);
|
||||
}
|
||||
return (($d - 1) >> 31) & 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $u
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $v
|
||||
* @return array{x: ParagonIE_Sodium_Core_Curve25519_Fe, nonsquare: int}
|
||||
*
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_sqrt_ratio_m1(
|
||||
ParagonIE_Sodium_Core_Curve25519_Fe $u,
|
||||
ParagonIE_Sodium_Core_Curve25519_Fe $v
|
||||
) {
|
||||
$sqrtm1 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtm1);
|
||||
|
||||
$v3 = self::fe_mul(
|
||||
self::fe_sq($v),
|
||||
$v
|
||||
); /* v3 = v^3 */
|
||||
$x = self::fe_mul(
|
||||
self::fe_mul(
|
||||
self::fe_sq($v3),
|
||||
$u
|
||||
),
|
||||
$v
|
||||
); /* x = uv^7 */
|
||||
|
||||
$x = self::fe_mul(
|
||||
self::fe_mul(
|
||||
self::fe_pow22523($x), /* x = (uv^7)^((q-5)/8) */
|
||||
$v3
|
||||
),
|
||||
$u
|
||||
); /* x = uv^3(uv^7)^((q-5)/8) */
|
||||
|
||||
$vxx = self::fe_mul(
|
||||
self::fe_sq($x),
|
||||
$v
|
||||
); /* vx^2 */
|
||||
|
||||
$m_root_check = self::fe_sub($vxx, $u); /* vx^2-u */
|
||||
$p_root_check = self::fe_add($vxx, $u); /* vx^2+u */
|
||||
$f_root_check = self::fe_mul($u, $sqrtm1); /* u*sqrt(-1) */
|
||||
$f_root_check = self::fe_add($vxx, $f_root_check); /* vx^2+u*sqrt(-1) */
|
||||
|
||||
$has_m_root = self::fe_iszero($m_root_check);
|
||||
$has_p_root = self::fe_iszero($p_root_check);
|
||||
$has_f_root = self::fe_iszero($f_root_check);
|
||||
|
||||
$x_sqrtm1 = self::fe_mul($x, $sqrtm1); /* x*sqrt(-1) */
|
||||
|
||||
$x = self::fe_abs(
|
||||
self::fe_cmov($x, $x_sqrtm1, $has_p_root | $has_f_root)
|
||||
);
|
||||
return array(
|
||||
'x' => $x,
|
||||
'nonsquare' => $has_m_root | $has_p_root
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @return int
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_point_is_canonical($s)
|
||||
{
|
||||
$c = (self::chrToInt($s[31]) & 0x7f) ^ 0x7f;
|
||||
for ($i = 30; $i > 0; --$i) {
|
||||
$c |= self::chrToInt($s[$i]) ^ 0xff;
|
||||
}
|
||||
$c = ($c - 1) >> 8;
|
||||
$d = (0xed - 1 - self::chrToInt($s[0])) >> 8;
|
||||
$e = self::chrToInt($s[31]) >> 7;
|
||||
|
||||
return 1 - ((($c & $d) | $e | self::chrToInt($s[0])) & 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @param bool $skipCanonicalCheck
|
||||
* @return array{h: ParagonIE_Sodium_Core_Curve25519_Ge_P3, res: int}
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_frombytes($s, $skipCanonicalCheck = false)
|
||||
{
|
||||
if (!$skipCanonicalCheck) {
|
||||
if (!self::ristretto255_point_is_canonical($s)) {
|
||||
throw new SodiumException('S is not canonical');
|
||||
}
|
||||
}
|
||||
|
||||
$s_ = self::fe_frombytes($s);
|
||||
$ss = self::fe_sq($s_); /* ss = s^2 */
|
||||
|
||||
$u1 = self::fe_sub(self::fe_1(), $ss); /* u1 = 1-ss */
|
||||
$u1u1 = self::fe_sq($u1); /* u1u1 = u1^2 */
|
||||
|
||||
$u2 = self::fe_add(self::fe_1(), $ss); /* u2 = 1+ss */
|
||||
$u2u2 = self::fe_sq($u2); /* u2u2 = u2^2 */
|
||||
|
||||
$v = self::fe_mul(
|
||||
ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d),
|
||||
$u1u1
|
||||
); /* v = d*u1^2 */
|
||||
$v = self::fe_neg($v); /* v = -d*u1^2 */
|
||||
$v = self::fe_sub($v, $u2u2); /* v = -(d*u1^2)-u2^2 */
|
||||
$v_u2u2 = self::fe_mul($v, $u2u2); /* v_u2u2 = v*u2^2 */
|
||||
|
||||
// fe25519_1(one);
|
||||
// notsquare = ristretto255_sqrt_ratio_m1(inv_sqrt, one, v_u2u2);
|
||||
$one = self::fe_1();
|
||||
$result = self::ristretto255_sqrt_ratio_m1($one, $v_u2u2);
|
||||
$inv_sqrt = $result['x'];
|
||||
$notsquare = $result['nonsquare'];
|
||||
|
||||
$h = new ParagonIE_Sodium_Core_Curve25519_Ge_P3();
|
||||
|
||||
$h->X = self::fe_mul($inv_sqrt, $u2);
|
||||
$h->Y = self::fe_mul(self::fe_mul($inv_sqrt, $h->X), $v);
|
||||
|
||||
$h->X = self::fe_mul($h->X, $s_);
|
||||
$h->X = self::fe_abs(
|
||||
self::fe_add($h->X, $h->X)
|
||||
);
|
||||
$h->Y = self::fe_mul($u1, $h->Y);
|
||||
$h->Z = self::fe_1();
|
||||
$h->T = self::fe_mul($h->X, $h->Y);
|
||||
|
||||
$res = - ((1 - $notsquare) | self::fe_isnegative($h->T) | self::fe_iszero($h->Y));
|
||||
return array('h' => $h, 'res' => $res);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_p3_tobytes(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h)
|
||||
{
|
||||
$sqrtm1 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtm1);
|
||||
$invsqrtamd = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$invsqrtamd);
|
||||
|
||||
$u1 = self::fe_add($h->Z, $h->Y); /* u1 = Z+Y */
|
||||
$zmy = self::fe_sub($h->Z, $h->Y); /* zmy = Z-Y */
|
||||
$u1 = self::fe_mul($u1, $zmy); /* u1 = (Z+Y)*(Z-Y) */
|
||||
$u2 = self::fe_mul($h->X, $h->Y); /* u2 = X*Y */
|
||||
|
||||
$u1_u2u2 = self::fe_mul(self::fe_sq($u2), $u1); /* u1_u2u2 = u1*u2^2 */
|
||||
$one = self::fe_1();
|
||||
|
||||
// fe25519_1(one);
|
||||
// (void) ristretto255_sqrt_ratio_m1(inv_sqrt, one, u1_u2u2);
|
||||
$result = self::ristretto255_sqrt_ratio_m1($one, $u1_u2u2);
|
||||
$inv_sqrt = $result['x'];
|
||||
|
||||
$den1 = self::fe_mul($inv_sqrt, $u1); /* den1 = inv_sqrt*u1 */
|
||||
$den2 = self::fe_mul($inv_sqrt, $u2); /* den2 = inv_sqrt*u2 */
|
||||
$z_inv = self::fe_mul($h->T, self::fe_mul($den1, $den2)); /* z_inv = den1*den2*T */
|
||||
|
||||
$ix = self::fe_mul($h->X, $sqrtm1); /* ix = X*sqrt(-1) */
|
||||
$iy = self::fe_mul($h->Y, $sqrtm1); /* iy = Y*sqrt(-1) */
|
||||
$eden = self::fe_mul($den1, $invsqrtamd);
|
||||
|
||||
$t_z_inv = self::fe_mul($h->T, $z_inv); /* t_z_inv = T*z_inv */
|
||||
$rotate = self::fe_isnegative($t_z_inv);
|
||||
|
||||
$x_ = self::fe_copy($h->X);
|
||||
$y_ = self::fe_copy($h->Y);
|
||||
$den_inv = self::fe_copy($den2);
|
||||
|
||||
$x_ = self::fe_cmov($x_, $iy, $rotate);
|
||||
$y_ = self::fe_cmov($y_, $ix, $rotate);
|
||||
$den_inv = self::fe_cmov($den_inv, $eden, $rotate);
|
||||
|
||||
$x_z_inv = self::fe_mul($x_, $z_inv);
|
||||
$y_ = self::fe_cneg($y_, self::fe_isnegative($x_z_inv));
|
||||
|
||||
|
||||
// fe25519_sub(s_, h->Z, y_);
|
||||
// fe25519_mul(s_, den_inv, s_);
|
||||
// fe25519_abs(s_, s_);
|
||||
// fe25519_tobytes(s, s_);
|
||||
return self::fe_tobytes(
|
||||
self::fe_abs(
|
||||
self::fe_mul(
|
||||
$den_inv,
|
||||
self::fe_sub($h->Z, $y_)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $t
|
||||
* @return ParagonIE_Sodium_Core_Curve25519_Ge_P3
|
||||
*
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_elligator(ParagonIE_Sodium_Core_Curve25519_Fe $t)
|
||||
{
|
||||
$sqrtm1 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtm1);
|
||||
$onemsqd = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$onemsqd);
|
||||
$d = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d);
|
||||
$sqdmone = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqdmone);
|
||||
$sqrtadm1 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtadm1);
|
||||
|
||||
$one = self::fe_1();
|
||||
$r = self::fe_mul($sqrtm1, self::fe_sq($t)); /* r = sqrt(-1)*t^2 */
|
||||
$u = self::fe_mul(self::fe_add($r, $one), $onemsqd); /* u = (r+1)*(1-d^2) */
|
||||
$c = self::fe_neg(self::fe_1()); /* c = -1 */
|
||||
$rpd = self::fe_add($r, $d); /* rpd = r+d */
|
||||
|
||||
$v = self::fe_mul(
|
||||
self::fe_sub(
|
||||
$c,
|
||||
self::fe_mul($r, $d)
|
||||
),
|
||||
$rpd
|
||||
); /* v = (c-r*d)*(r+d) */
|
||||
|
||||
$result = self::ristretto255_sqrt_ratio_m1($u, $v);
|
||||
$s = $result['x'];
|
||||
$wasnt_square = 1 - $result['nonsquare'];
|
||||
|
||||
$s_prime = self::fe_neg(
|
||||
self::fe_abs(
|
||||
self::fe_mul($s, $t)
|
||||
)
|
||||
); /* s_prime = -|s*t| */
|
||||
$s = self::fe_cmov($s, $s_prime, $wasnt_square);
|
||||
$c = self::fe_cmov($c, $r, $wasnt_square);
|
||||
|
||||
// fe25519_sub(n, r, one); /* n = r-1 */
|
||||
// fe25519_mul(n, n, c); /* n = c*(r-1) */
|
||||
// fe25519_mul(n, n, ed25519_sqdmone); /* n = c*(r-1)*(d-1)^2 */
|
||||
// fe25519_sub(n, n, v); /* n = c*(r-1)*(d-1)^2-v */
|
||||
$n = self::fe_sub(
|
||||
self::fe_mul(
|
||||
self::fe_mul(
|
||||
self::fe_sub($r, $one),
|
||||
$c
|
||||
),
|
||||
$sqdmone
|
||||
),
|
||||
$v
|
||||
); /* n = c*(r-1)*(d-1)^2-v */
|
||||
|
||||
$w0 = self::fe_mul(
|
||||
self::fe_add($s, $s),
|
||||
$v
|
||||
); /* w0 = 2s*v */
|
||||
|
||||
$w1 = self::fe_mul($n, $sqrtadm1); /* w1 = n*sqrt(ad-1) */
|
||||
$ss = self::fe_sq($s); /* ss = s^2 */
|
||||
$w2 = self::fe_sub($one, $ss); /* w2 = 1-s^2 */
|
||||
$w3 = self::fe_add($one, $ss); /* w3 = 1+s^2 */
|
||||
|
||||
return new ParagonIE_Sodium_Core_Curve25519_Ge_P3(
|
||||
self::fe_mul($w0, $w3),
|
||||
self::fe_mul($w2, $w1),
|
||||
self::fe_mul($w1, $w3),
|
||||
self::fe_mul($w0, $w2)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $h
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_from_hash($h)
|
||||
{
|
||||
if (self::strlen($h) !== 64) {
|
||||
throw new SodiumException('Hash must be 64 bytes');
|
||||
}
|
||||
//fe25519_frombytes(r0, h);
|
||||
//fe25519_frombytes(r1, h + 32);
|
||||
$r0 = self::fe_frombytes(self::substr($h, 0, 32));
|
||||
$r1 = self::fe_frombytes(self::substr($h, 32, 32));
|
||||
|
||||
//ristretto255_elligator(&p0, r0);
|
||||
//ristretto255_elligator(&p1, r1);
|
||||
$p0 = self::ristretto255_elligator($r0);
|
||||
$p1 = self::ristretto255_elligator($r1);
|
||||
|
||||
//ge25519_p3_to_cached(&p1_cached, &p1);
|
||||
//ge25519_add_cached(&p_p1p1, &p0, &p1_cached);
|
||||
$p_p1p1 = self::ge_add(
|
||||
$p0,
|
||||
self::ge_p3_to_cached($p1)
|
||||
);
|
||||
|
||||
//ge25519_p1p1_to_p3(&p, &p_p1p1);
|
||||
//ristretto255_p3_tobytes(s, &p);
|
||||
return self::ristretto255_p3_tobytes(
|
||||
self::ge_p1p1_to_p3($p_p1p1)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $p
|
||||
* @return int
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function is_valid_point($p)
|
||||
{
|
||||
$result = self::ristretto255_frombytes($p);
|
||||
if ($result['res'] !== 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_add($p, $q)
|
||||
{
|
||||
$p_res = self::ristretto255_frombytes($p);
|
||||
$q_res = self::ristretto255_frombytes($q);
|
||||
if ($p_res['res'] !== 0 || $q_res['res'] !== 0) {
|
||||
throw new SodiumException('Could not add points');
|
||||
}
|
||||
$p_p3 = $p_res['h'];
|
||||
$q_p3 = $q_res['h'];
|
||||
$q_cached = self::ge_p3_to_cached($q_p3);
|
||||
$r_p1p1 = self::ge_add($p_p3, $q_cached);
|
||||
$r_p3 = self::ge_p1p1_to_p3($r_p1p1);
|
||||
return self::ristretto255_p3_tobytes($r_p3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_sub($p, $q)
|
||||
{
|
||||
$p_res = self::ristretto255_frombytes($p);
|
||||
$q_res = self::ristretto255_frombytes($q);
|
||||
if ($p_res['res'] !== 0 || $q_res['res'] !== 0) {
|
||||
throw new SodiumException('Could not add points');
|
||||
}
|
||||
$p_p3 = $p_res['h'];
|
||||
$q_p3 = $q_res['h'];
|
||||
$q_cached = self::ge_p3_to_cached($q_p3);
|
||||
$r_p1p1 = self::ge_sub($p_p3, $q_cached);
|
||||
$r_p3 = self::ge_p1p1_to_p3($r_p1p1);
|
||||
return self::ristretto255_p3_tobytes($r_p3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $hLen
|
||||
* @param ?string $ctx
|
||||
* @param string $msg
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @psalm-suppress PossiblyInvalidArgument hash API
|
||||
*/
|
||||
protected static function h2c_string_to_hash_sha256($hLen, $ctx, $msg)
|
||||
{
|
||||
$h = array_fill(0, $hLen, 0);
|
||||
$ctx_len = !is_null($ctx) ? self::strlen($ctx) : 0;
|
||||
if ($hLen > 0xff) {
|
||||
throw new SodiumException('Hash must be less than 256 bytes');
|
||||
}
|
||||
|
||||
if ($ctx_len > 0xff) {
|
||||
$st = hash_init('sha256');
|
||||
self::hash_update($st, "H2C-OVERSIZE-DST-");
|
||||
self::hash_update($st, $ctx);
|
||||
$ctx = hash_final($st, true);
|
||||
$ctx_len = 32;
|
||||
}
|
||||
$t = array(0, $hLen, 0);
|
||||
$ux = str_repeat("\0", 64);
|
||||
$st = hash_init('sha256');
|
||||
self::hash_update($st, $ux);
|
||||
self::hash_update($st, $msg);
|
||||
self::hash_update($st, self::intArrayToString($t));
|
||||
self::hash_update($st, $ctx);
|
||||
self::hash_update($st, self::intToChr($ctx_len));
|
||||
$u0 = hash_final($st, true);
|
||||
|
||||
for ($i = 0; $i < $hLen; $i += 64) {
|
||||
$ux = self::xorStrings($ux, $u0);
|
||||
++$t[2];
|
||||
$st = hash_init('sha256');
|
||||
self::hash_update($st, $ux);
|
||||
self::hash_update($st, self::intToChr($t[2]));
|
||||
self::hash_update($st, $ctx);
|
||||
self::hash_update($st, self::intToChr($ctx_len));
|
||||
$ux = hash_final($st, true);
|
||||
$amount = min($hLen - $i, 64);
|
||||
for ($j = 0; $j < $amount; ++$j) {
|
||||
$h[$i + $j] = self::chrToInt($ux[$i]);
|
||||
}
|
||||
}
|
||||
return self::intArrayToString(array_slice($h, 0, $hLen));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $hLen
|
||||
* @param ?string $ctx
|
||||
* @param string $msg
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @psalm-suppress PossiblyInvalidArgument hash API
|
||||
*/
|
||||
protected static function h2c_string_to_hash_sha512($hLen, $ctx, $msg)
|
||||
{
|
||||
$h = array_fill(0, $hLen, 0);
|
||||
$ctx_len = !is_null($ctx) ? self::strlen($ctx) : 0;
|
||||
if ($hLen > 0xff) {
|
||||
throw new SodiumException('Hash must be less than 256 bytes');
|
||||
}
|
||||
|
||||
if ($ctx_len > 0xff) {
|
||||
$st = hash_init('sha256');
|
||||
self::hash_update($st, "H2C-OVERSIZE-DST-");
|
||||
self::hash_update($st, $ctx);
|
||||
$ctx = hash_final($st, true);
|
||||
$ctx_len = 32;
|
||||
}
|
||||
$t = array(0, $hLen, 0);
|
||||
$ux = str_repeat("\0", 128);
|
||||
$st = hash_init('sha512');
|
||||
self::hash_update($st, $ux);
|
||||
self::hash_update($st, $msg);
|
||||
self::hash_update($st, self::intArrayToString($t));
|
||||
self::hash_update($st, $ctx);
|
||||
self::hash_update($st, self::intToChr($ctx_len));
|
||||
$u0 = hash_final($st, true);
|
||||
|
||||
for ($i = 0; $i < $hLen; $i += 128) {
|
||||
$ux = self::xorStrings($ux, $u0);
|
||||
++$t[2];
|
||||
$st = hash_init('sha512');
|
||||
self::hash_update($st, $ux);
|
||||
self::hash_update($st, self::intToChr($t[2]));
|
||||
self::hash_update($st, $ctx);
|
||||
self::hash_update($st, self::intToChr($ctx_len));
|
||||
$ux = hash_final($st, true);
|
||||
$amount = min($hLen - $i, 128);
|
||||
for ($j = 0; $j < $amount; ++$j) {
|
||||
$h[$i + $j] = self::chrToInt($ux[$i]);
|
||||
}
|
||||
}
|
||||
return self::intArrayToString(array_slice($h, 0, $hLen));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $hLen
|
||||
* @param ?string $ctx
|
||||
* @param string $msg
|
||||
* @param int $hash_alg
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function h2c_string_to_hash($hLen, $ctx, $msg, $hash_alg)
|
||||
{
|
||||
switch ($hash_alg) {
|
||||
case self::CORE_H2C_SHA256:
|
||||
return self::h2c_string_to_hash_sha256($hLen, $ctx, $msg);
|
||||
case self::CORE_H2C_SHA512:
|
||||
return self::h2c_string_to_hash_sha512($hLen, $ctx, $msg);
|
||||
default:
|
||||
throw new SodiumException('Invalid H2C hash algorithm');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?string $ctx
|
||||
* @param string $msg
|
||||
* @param int $hash_alg
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
protected static function _string_to_element($ctx, $msg, $hash_alg)
|
||||
{
|
||||
return self::ristretto255_from_hash(
|
||||
self::h2c_string_to_hash(self::crypto_core_ristretto255_HASHBYTES, $ctx, $msg, $hash_alg)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function ristretto255_random()
|
||||
{
|
||||
return self::ristretto255_from_hash(
|
||||
ParagonIE_Sodium_Compat::randombytes_buf(self::crypto_core_ristretto255_HASHBYTES)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_random()
|
||||
{
|
||||
return self::scalar_random();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_complement($s)
|
||||
{
|
||||
return self::scalar_complement($s);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
public static function ristretto255_scalar_invert($s)
|
||||
{
|
||||
return self::sc25519_invert($s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_negate($s)
|
||||
{
|
||||
return self::scalar_negate($s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
*/
|
||||
public static function ristretto255_scalar_add($x, $y)
|
||||
{
|
||||
return self::scalar_add($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
*/
|
||||
public static function ristretto255_scalar_sub($x, $y)
|
||||
{
|
||||
return self::scalar_sub($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
*/
|
||||
public static function ristretto255_scalar_mul($x, $y)
|
||||
{
|
||||
return self::sc25519_mul($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ctx
|
||||
* @param string $msg
|
||||
* @param int $hash_alg
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function ristretto255_scalar_from_string($ctx, $msg, $hash_alg)
|
||||
{
|
||||
$h = array_fill(0, 64, 0);
|
||||
$h_be = self::stringToIntArray(
|
||||
self::h2c_string_to_hash(
|
||||
self::HASH_SC_L, $ctx, $msg, $hash_alg
|
||||
)
|
||||
);
|
||||
|
||||
for ($i = 0; $i < self::HASH_SC_L; ++$i) {
|
||||
$h[$i] = $h_be[self::HASH_SC_L - 1 - $i];
|
||||
}
|
||||
return self::ristretto255_scalar_reduce(self::intArrayToString($h));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
public static function ristretto255_scalar_reduce($s)
|
||||
{
|
||||
return self::sc_reduce($s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalarmult_ristretto255($n, $p)
|
||||
{
|
||||
if (self::strlen($n) !== 32) {
|
||||
throw new SodiumException('Scalar must be 32 bytes, ' . self::strlen($p) . ' given.');
|
||||
}
|
||||
if (self::strlen($p) !== 32) {
|
||||
throw new SodiumException('Point must be 32 bytes, ' . self::strlen($p) . ' given.');
|
||||
}
|
||||
$result = self::ristretto255_frombytes($p);
|
||||
if ($result['res'] !== 0) {
|
||||
throw new SodiumException('Could not multiply points');
|
||||
}
|
||||
$P = $result['h'];
|
||||
|
||||
$t = self::stringToIntArray($n);
|
||||
$t[31] &= 0x7f;
|
||||
$Q = self::ge_scalarmult(self::intArrayToString($t), $P);
|
||||
$q = self::ristretto255_p3_tobytes($Q);
|
||||
if (ParagonIE_Sodium_Compat::is_zero($q)) {
|
||||
throw new SodiumException('An unknown error has occurred');
|
||||
}
|
||||
return $q;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $n
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalarmult_ristretto255_base($n)
|
||||
{
|
||||
$t = self::stringToIntArray($n);
|
||||
$t[31] &= 0x7f;
|
||||
$Q = self::ge_scalarmult_base(self::intArrayToString($t));
|
||||
$q = self::ristretto255_p3_tobytes($Q);
|
||||
if (ParagonIE_Sodium_Compat::is_zero($q)) {
|
||||
throw new SodiumException('An unknown error has occurred');
|
||||
}
|
||||
return $q;
|
||||
}
|
||||
}
|
|
@ -14,8 +14,8 @@ class ParagonIE_Sodium_Core_SipHash extends ParagonIE_Sodium_Core_Util
|
|||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param array<array-key, int> $v
|
||||
* @return array<array-key, int>
|
||||
* @param int[] $v
|
||||
* @return int[]
|
||||
*
|
||||
*/
|
||||
public static function sipRound(array $v)
|
||||
|
|
|
@ -286,6 +286,22 @@ abstract class ParagonIE_Sodium_Core_Util
|
|||
return $left === $right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Catch hash_update() failures and throw instead of silently proceding
|
||||
*
|
||||
* @param HashContext|resource &$hs
|
||||
* @param string $data
|
||||
* @return void
|
||||
* @throws SodiumException
|
||||
* @psalm-suppress PossiblyInvalidArgument
|
||||
*/
|
||||
protected static function hash_update(&$hs, $data)
|
||||
{
|
||||
if (!hash_update($hs, $data)) {
|
||||
throw new SodiumException('hash_update() failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a hexadecimal string into a binary string without cache-timing
|
||||
* leaks
|
||||
|
|
|
@ -577,6 +577,7 @@ abstract class ParagonIE_Sodium_Core32_BLAKE2b extends ParagonIE_Sodium_Core_Uti
|
|||
*
|
||||
* @param string $str
|
||||
* @return SplFixedArray
|
||||
* @psalm-suppress MixedArgumentTypeCoercion
|
||||
*/
|
||||
public static function stringToSplFixedArray($str = '')
|
||||
{
|
||||
|
|
|
@ -207,6 +207,7 @@ abstract class ParagonIE_Sodium_Core32_Ed25519 extends ParagonIE_Sodium_Core32_C
|
|||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress PossiblyInvalidArgument
|
||||
*/
|
||||
public static function sign_detached($message, $sk)
|
||||
{
|
||||
|
@ -224,8 +225,8 @@ abstract class ParagonIE_Sodium_Core32_Ed25519 extends ParagonIE_Sodium_Core32_C
|
|||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, nonce);
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($az, 32, 32));
|
||||
hash_update($hs, $message);
|
||||
self::hash_update($hs, self::substr($az, 32, 32));
|
||||
self::hash_update($hs, $message);
|
||||
$nonceHash = hash_final($hs, true);
|
||||
|
||||
# memmove(sig + 32, sk + 32, 32);
|
||||
|
@ -244,9 +245,9 @@ abstract class ParagonIE_Sodium_Core32_Ed25519 extends ParagonIE_Sodium_Core32_C
|
|||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, hram);
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($sig, 0, 32));
|
||||
hash_update($hs, self::substr($pk, 0, 32));
|
||||
hash_update($hs, $message);
|
||||
self::hash_update($hs, self::substr($sig, 0, 32));
|
||||
self::hash_update($hs, self::substr($pk, 0, 32));
|
||||
self::hash_update($hs, $message);
|
||||
$hramHash = hash_final($hs, true);
|
||||
|
||||
# sc_reduce(hram);
|
||||
|
|
|
@ -597,7 +597,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
$az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64);
|
||||
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($az, 32, 32));
|
||||
self::hash_update($hs, self::substr($az, 32, 32));
|
||||
/** @var resource $hs */
|
||||
$hs = self::updateHashWithFile($hs, $fp, $size);
|
||||
|
||||
|
@ -616,8 +616,8 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
);
|
||||
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($sig, 0, 32));
|
||||
hash_update($hs, self::substr($pk, 0, 32));
|
||||
self::hash_update($hs, self::substr($sig, 0, 32));
|
||||
self::hash_update($hs, self::substr($pk, 0, 32));
|
||||
/** @var resource $hs */
|
||||
$hs = self::updateHashWithFile($hs, $fp, $size);
|
||||
|
||||
|
@ -728,8 +728,8 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
$A = ParagonIE_Sodium_Core_Ed25519::ge_frombytes_negate_vartime($publicKey);
|
||||
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($sig, 0, 32));
|
||||
hash_update($hs, self::substr($publicKey, 0, 32));
|
||||
self::hash_update($hs, self::substr($sig, 0, 32));
|
||||
self::hash_update($hs, self::substr($publicKey, 0, 32));
|
||||
/** @var resource $hs */
|
||||
$hs = self::updateHashWithFile($hs, $fp, $size);
|
||||
/** @var string $hDigest */
|
||||
|
@ -1083,7 +1083,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
* Update a hash context with the contents of a file, without
|
||||
* loading the entire file into memory.
|
||||
*
|
||||
* @param resource|object $hash
|
||||
* @param resource|HashContext $hash
|
||||
* @param resource $fp
|
||||
* @param int $size
|
||||
* @return resource|object Resource on PHP < 7.2, HashContext object on PHP >= 7.2
|
||||
|
@ -1133,7 +1133,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
}
|
||||
/** @var string $message */
|
||||
/** @psalm-suppress InvalidArgument */
|
||||
hash_update($hash, $message);
|
||||
self::hash_update($hash, $message);
|
||||
}
|
||||
// Reset file pointer's position
|
||||
fseek($fp, $originalPosition, SEEK_SET);
|
||||
|
@ -1175,7 +1175,7 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
$az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64);
|
||||
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($az, 32, 32));
|
||||
self::hash_update($hs, self::substr($az, 32, 32));
|
||||
/** @var resource $hs */
|
||||
$hs = self::updateHashWithFile($hs, $fp, $size);
|
||||
|
||||
|
@ -1194,8 +1194,8 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
);
|
||||
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($sig, 0, 32));
|
||||
hash_update($hs, self::substr($pk, 0, 32));
|
||||
self::hash_update($hs, self::substr($sig, 0, 32));
|
||||
self::hash_update($hs, self::substr($pk, 0, 32));
|
||||
/** @var resource $hs */
|
||||
$hs = self::updateHashWithFile($hs, $fp, $size);
|
||||
|
||||
|
@ -1278,8 +1278,8 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
$A = ParagonIE_Sodium_Core32_Ed25519::ge_frombytes_negate_vartime($publicKey);
|
||||
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($sig, 0, 32));
|
||||
hash_update($hs, self::substr($publicKey, 0, 32));
|
||||
self::hash_update($hs, self::substr($sig, 0, 32));
|
||||
self::hash_update($hs, self::substr($publicKey, 0, 32));
|
||||
/** @var resource $hs */
|
||||
$hs = self::updateHashWithFile($hs, $fp, $size);
|
||||
/** @var string $hDigest */
|
||||
|
@ -1527,12 +1527,6 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
/** @var int $pos */
|
||||
$pos = self::ftell($ifp);
|
||||
|
||||
/** @var int $iter */
|
||||
$iter = 1;
|
||||
|
||||
/** @var int $incr */
|
||||
$incr = self::BUFFER_SIZE >> 6;
|
||||
|
||||
while ($mlen > 0) {
|
||||
$blockSize = $mlen > self::BUFFER_SIZE
|
||||
? self::BUFFER_SIZE
|
||||
|
@ -1543,7 +1537,6 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
|
|||
}
|
||||
$state->update($ciphertext);
|
||||
$mlen -= $blockSize;
|
||||
$iter += $incr;
|
||||
}
|
||||
$res = ParagonIE_Sodium_Core32_Util::verify_16($tag, $state->finish());
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '5.8-alpha-51001';
|
||||
$wp_version = '5.8-alpha-51002';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
|
Loading…
Reference in New Issue