changes for filter and print

This commit is contained in:
2024-09-29 16:59:27 +05:45
parent 497f567cba
commit 684e01bf48
1335 changed files with 38709 additions and 74987 deletions

View File

@ -1,6 +1,6 @@
ISC License
Copyright (c) 2016-2022, Paragon Initiative Enterprises <security at paragonie dot com>
Copyright (c) 2016-2023, 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

View File

@ -11,12 +11,47 @@
Sodium Compat is a pure PHP polyfill for the Sodium cryptography library
(libsodium), a core extension in PHP 7.2.0+ and otherwise [available in PECL](https://pecl.php.net/package/libsodium).
This library tentatively supports PHP 5.2.4 - 8.x (latest), but officially
only supports [non-EOL'd versions of PHP](https://secure.php.net/supported-versions.php).
If you have the PHP extension installed, Sodium Compat will opportunistically
and transparently use the PHP extension instead of our implementation.
## Major Versions and Branches
sodium_compat v1.21.0 was the last v1.x release from the master branch. From now
on, all future releases that support PHP 5.2 - 5.6 and 32-bit integers will be
[in the `v1.x` branch](v1.x).
Newer versions of sodium_compat (i.e., v2.0.0) will continue to live in the master
branch, unless a new major version is needed. The goal of this work is to improve
code readability and performance, while reducing boilerplate code.
When in doubt, refer to the README file in [the master branch](https://github.com/paragonie/sodium_compat/blob/master/README.md)
for the latest in version information.
### Which version should I use?
| sodium_compat version | PHP versions supported | 32-bit support? | Branch |
|-----------------------|------------------------|-----------------|---------------------------------------------------------------|
| `v1.x.y` | 5.2.4 - LATEST | YES | [v1.x](https://github.com/paragonie/sodium_compat/tree/v1.x) |
| `v2.x.y` | 7.2 - LATEST | NO | **master** |
If you need 32-bit PHP support (`PHP_INT_SIZE == 4`), continue using sodium_compat v1.x.
If you want improved performance and smaller dependencies, use v2.x.
We recommend libraries and frameworks set a Composer version constraint as follows:
```javascript
{
"require": {
/* ... */
"paragonie/sodium_compat": ">= 1"
/* ... */
}
}
```
Applications should, conversely, specify the actual version that matters to them
and their deployments.
## IMPORTANT!
This cryptography library has not been formally audited by an independent third
@ -266,6 +301,10 @@ insightful technical information you may find helpful.
* `crypto_sign()`
* `crypto_sign_open()`
* PECL Libsodium Features
* `crypto_aead_aegis128l_encrypt()`
* `crypto_aead_aegis128l_decrypt()`
* `crypto_aead_aegis256_encrypt()`
* `crypto_aead_aegis256_decrypt()`
* `crypto_aead_aes256gcm_encrypt()`
* `crypto_aead_aes256gcm_decrypt()`
* `crypto_aead_chacha20poly1305_encrypt()`
@ -343,13 +382,13 @@ insightful technical information you may find helpful.
### Features Excluded from this Polyfill
* `\Sodium\memzero()` - Although we expose this API endpoint, we can't reliably
* `sodium_memzero()` - Although we expose this API endpoint, we can't reliably
zero buffers from PHP.
If you have the PHP extension installed, sodium_compat
will use the native implementation to zero out the string provided. Otherwise
it will throw a `SodiumException`.
* `\Sodium\crypto_pwhash()` - It's not feasible to polyfill scrypt or Argon2
* `sodium_crypto_pwhash()` - It's not feasible to polyfill scrypt or Argon2
into PHP and get reasonable performance. Users would feel motivated to select
parameters that downgrade security to avoid denial of service (DoS) attacks.
@ -361,6 +400,8 @@ insightful technical information you may find helpful.
To detect support for Argon2i at runtime, use
`ParagonIE_Sodium_Compat::crypto_pwhash_is_available()`, which returns a
boolean value (`TRUE` or `FALSE`).
* Libsodium's HKDF API (`crypto_kdf_hkdf_*()`) is not included because PHP has
its own [HMAC features](https://php.met/hash_hmac) amd it was not deemed necessary.
### PHPCompatibility Ruleset

View File

@ -54,6 +54,9 @@ if (PHP_VERSION_ID >= 50300) {
// unless PHP >= 5.3.0
require_once dirname(__FILE__) . '/lib/namespaced.php';
require_once dirname(__FILE__) . '/lib/sodium_compat.php';
if (!defined('SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES')) {
require_once dirname(__FILE__) . '/lib/php84compat_const.php';
}
} else {
require_once dirname(__FILE__) . '/src/PHP52/SplFixedArray.php';
}
@ -71,5 +74,8 @@ if (PHP_VERSION_ID < 70200 || !extension_loaded('sodium')) {
// Older versions of {PHP, ext/sodium} will not define these
require_once(dirname(__FILE__) . '/lib/php72compat.php');
}
if (PHP_VERSION_ID < 80400 || !extension_loaded('sodium')) {
require_once dirname(__FILE__) . '/lib/php84compat.php';
}
require_once(dirname(__FILE__) . '/lib/stream-xchacha20.php');
require_once(dirname(__FILE__) . '/lib/ristretto255.php');

View File

@ -14,14 +14,14 @@ foreach (array(
'BASE64_VARIANT_ORIGINAL_NO_PADDING',
'BASE64_VARIANT_URLSAFE',
'BASE64_VARIANT_URLSAFE_NO_PADDING',
'CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_ABYTES',
'CRYPTO_AEAD_AES256GCM_KEYBYTES',
'CRYPTO_AEAD_AES256GCM_NSECBYTES',
'CRYPTO_AEAD_AES256GCM_NPUBBYTES',
'CRYPTO_AEAD_AES256GCM_ABYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_ABYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES',
'CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES',
@ -115,8 +115,12 @@ if (!is_callable('sodium_add')) {
* @return void
* @throws SodiumException
*/
function sodium_add(&$string1, $string2)
{
function sodium_add(
#[\SensitiveParameter]
&$string1,
#[\SensitiveParameter]
$string2
) {
ParagonIE_Sodium_Compat::add($string1, $string2);
}
}
@ -130,8 +134,12 @@ if (!is_callable('sodium_base642bin')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_base642bin($string, $variant, $ignore ='')
{
function sodium_base642bin(
#[\SensitiveParameter]
$string,
$variant,
$ignore =''
) {
return ParagonIE_Sodium_Compat::base642bin($string, $variant, $ignore);
}
}
@ -144,8 +152,11 @@ if (!is_callable('sodium_bin2base64')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_bin2base64($string, $variant)
{
function sodium_bin2base64(
#[\SensitiveParameter]
$string,
$variant
) {
return ParagonIE_Sodium_Compat::bin2base64($string, $variant);
}
}
@ -157,8 +168,10 @@ if (!is_callable('sodium_bin2hex')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_bin2hex($string)
{
function sodium_bin2hex(
#[\SensitiveParameter]
$string
) {
return ParagonIE_Sodium_Compat::bin2hex($string);
}
}
@ -171,8 +184,12 @@ if (!is_callable('sodium_compare')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_compare($string1, $string2)
{
function sodium_compare(
#[\SensitiveParameter]
$string1,
#[\SensitiveParameter]
$string2
) {
return ParagonIE_Sodium_Compat::compare($string1, $string2);
}
}
@ -185,8 +202,13 @@ if (!is_callable('sodium_crypto_aead_aes256gcm_decrypt')) {
* @param string $key
* @return string|bool
*/
function sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $additional_data, $nonce, $key)
{
function sodium_crypto_aead_aes256gcm_decrypt(
$ciphertext,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt(
$ciphertext,
@ -215,8 +237,14 @@ if (!is_callable('sodium_crypto_aead_aes256gcm_encrypt')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_aead_aes256gcm_encrypt($message, $additional_data, $nonce, $key)
{
function sodium_crypto_aead_aes256gcm_encrypt(
#[\SensitiveParameter]
$message,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt($message, $additional_data, $nonce, $key);
}
}
@ -239,8 +267,13 @@ if (!is_callable('sodium_crypto_aead_chacha20poly1305_decrypt')) {
* @param string $key
* @return string|bool
*/
function sodium_crypto_aead_chacha20poly1305_decrypt($ciphertext, $additional_data, $nonce, $key)
{
function sodium_crypto_aead_chacha20poly1305_decrypt(
$ciphertext,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt(
$ciphertext,
@ -266,8 +299,14 @@ if (!is_callable('sodium_crypto_aead_chacha20poly1305_encrypt')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_aead_chacha20poly1305_encrypt($message, $additional_data, $nonce, $key)
{
function sodium_crypto_aead_chacha20poly1305_encrypt(
#[\SensitiveParameter]
$message,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt(
$message,
$additional_data,
@ -296,8 +335,13 @@ if (!is_callable('sodium_crypto_aead_chacha20poly1305_ietf_decrypt')) {
* @param string $key
* @return string|bool
*/
function sodium_crypto_aead_chacha20poly1305_ietf_decrypt($message, $additional_data, $nonce, $key)
{
function sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
$message,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt(
$message,
@ -323,8 +367,14 @@ if (!is_callable('sodium_crypto_aead_chacha20poly1305_ietf_encrypt')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_aead_chacha20poly1305_ietf_encrypt($message, $additional_data, $nonce, $key)
{
function sodium_crypto_aead_chacha20poly1305_ietf_encrypt(
#[\SensitiveParameter]
$message,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt(
$message,
$additional_data,
@ -353,8 +403,13 @@ if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_decrypt')) {
* @param string $key
* @return string|bool
*/
function sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($ciphertext, $additional_data, $nonce, $key)
{
function sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
$ciphertext,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt(
$ciphertext,
@ -382,9 +437,11 @@ if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) {
* @throws TypeError
*/
function sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
#[\SensitiveParameter]
$message,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt(
@ -416,8 +473,11 @@ if (!is_callable('sodium_crypto_auth')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_auth($message, $key)
{
function sodium_crypto_auth(
$message,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_auth($message, $key);
}
}
@ -442,8 +502,12 @@ if (!is_callable('sodium_crypto_auth_verify')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_auth_verify($mac, $message, $key)
{
function sodium_crypto_auth_verify(
$mac,
$message,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_auth_verify($mac, $message, $key);
}
}
@ -457,8 +521,13 @@ if (!is_callable('sodium_crypto_box')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_box($message, $nonce, $key_pair)
{
function sodium_crypto_box(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$key_pair
) {
return ParagonIE_Sodium_Compat::crypto_box($message, $nonce, $key_pair);
}
}
@ -483,8 +552,11 @@ if (!is_callable('sodium_crypto_box_keypair_from_secretkey_and_publickey')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_box_keypair_from_secretkey_and_publickey($secret_key, $public_key)
{
function sodium_crypto_box_keypair_from_secretkey_and_publickey(
#[\SensitiveParameter]
$secret_key,
$public_key
) {
return ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($secret_key, $public_key);
}
}
@ -496,8 +568,12 @@ if (!is_callable('sodium_crypto_box_open')) {
* @param string $key_pair
* @return string|bool
*/
function sodium_crypto_box_open($ciphertext, $nonce, $key_pair)
{
function sodium_crypto_box_open(
$ciphertext,
$nonce,
#[\SensitiveParameter]
$key_pair
) {
try {
return ParagonIE_Sodium_Compat::crypto_box_open($ciphertext, $nonce, $key_pair);
} catch (Error $ex) {
@ -515,8 +591,10 @@ if (!is_callable('sodium_crypto_box_publickey')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_box_publickey($key_pair)
{
function sodium_crypto_box_publickey(
#[\SensitiveParameter]
$key_pair
) {
return ParagonIE_Sodium_Compat::crypto_box_publickey($key_pair);
}
}
@ -528,8 +606,10 @@ if (!is_callable('sodium_crypto_box_publickey_from_secretkey')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_box_publickey_from_secretkey($secret_key)
{
function sodium_crypto_box_publickey_from_secretkey(
#[\SensitiveParameter]
$secret_key
) {
return ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey($secret_key);
}
}
@ -542,8 +622,11 @@ if (!is_callable('sodium_crypto_box_seal')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_box_seal($message, $public_key)
{
function sodium_crypto_box_seal(
#[\SensitiveParameter]
$message,
$public_key
) {
return ParagonIE_Sodium_Compat::crypto_box_seal($message, $public_key);
}
}
@ -555,8 +638,11 @@ if (!is_callable('sodium_crypto_box_seal_open')) {
* @return string|bool
* @throws SodiumException
*/
function sodium_crypto_box_seal_open($message, $key_pair)
{
function sodium_crypto_box_seal_open(
$message,
#[\SensitiveParameter]
$key_pair
) {
try {
return ParagonIE_Sodium_Compat::crypto_box_seal_open($message, $key_pair);
} catch (SodiumException $ex) {
@ -575,8 +661,10 @@ if (!is_callable('sodium_crypto_box_secretkey')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_box_secretkey($key_pair)
{
function sodium_crypto_box_secretkey(
#[\SensitiveParameter]
$key_pair
) {
return ParagonIE_Sodium_Compat::crypto_box_secretkey($key_pair);
}
}
@ -588,8 +676,10 @@ if (!is_callable('sodium_crypto_box_seed_keypair')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_box_seed_keypair($seed)
{
function sodium_crypto_box_seed_keypair(
#[\SensitiveParameter]
$seed
) {
return ParagonIE_Sodium_Compat::crypto_box_seed_keypair($seed);
}
}
@ -603,8 +693,12 @@ if (!is_callable('sodium_crypto_generichash')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_generichash($message, $key = null, $length = 32)
{
function sodium_crypto_generichash(
$message,
#[\SensitiveParameter]
$key = null,
$length = 32
) {
return ParagonIE_Sodium_Compat::crypto_generichash($message, $key, $length);
}
}
@ -631,8 +725,11 @@ if (!is_callable('sodium_crypto_generichash_init')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_generichash_init($key = null, $length = 32)
{
function sodium_crypto_generichash_init(
#[\SensitiveParameter]
$key = null,
$length = 32
) {
return ParagonIE_Sodium_Compat::crypto_generichash_init($key, $length);
}
}
@ -656,8 +753,11 @@ if (!is_callable('sodium_crypto_generichash_update')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_generichash_update(&$state, $message = '')
{
function sodium_crypto_generichash_update(
#[\SensitiveParameter]
&$state,
$message = ''
) {
ParagonIE_Sodium_Compat::crypto_generichash_update($state, $message);
}
}
@ -682,8 +782,13 @@ if (!is_callable('sodium_crypto_kdf_derive_from_key')) {
* @return string
* @throws Exception
*/
function sodium_crypto_kdf_derive_from_key($subkey_length, $subkey_id, $context, $key)
{
function sodium_crypto_kdf_derive_from_key(
$subkey_length,
$subkey_id,
$context,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_kdf_derive_from_key(
$subkey_length,
$subkey_id,
@ -703,8 +808,13 @@ if (!is_callable('sodium_crypto_kx')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_kx($my_secret, $their_public, $client_public, $server_public)
{
function sodium_crypto_kx(
#[\SensitiveParameter]
$my_secret,
$their_public,
$client_public,
$server_public
) {
return ParagonIE_Sodium_Compat::crypto_kx(
$my_secret,
$their_public,
@ -719,8 +829,10 @@ if (!is_callable('sodium_crypto_kx_seed_keypair')) {
* @return string
* @throws Exception
*/
function sodium_crypto_kx_seed_keypair($seed)
{
function sodium_crypto_kx_seed_keypair(
#[\SensitiveParameter]
$seed
) {
return ParagonIE_Sodium_Compat::crypto_kx_seed_keypair($seed);
}
}
@ -741,8 +853,11 @@ if (!is_callable('sodium_crypto_kx_client_session_keys')) {
* @return array{0: string, 1: string}
* @throws SodiumException
*/
function sodium_crypto_kx_client_session_keys($client_key_pair, $server_key)
{
function sodium_crypto_kx_client_session_keys(
#[\SensitiveParameter]
$client_key_pair,
$server_key
) {
return ParagonIE_Sodium_Compat::crypto_kx_client_session_keys($client_key_pair, $server_key);
}
}
@ -753,8 +868,11 @@ if (!is_callable('sodium_crypto_kx_server_session_keys')) {
* @return array{0: string, 1: string}
* @throws SodiumException
*/
function sodium_crypto_kx_server_session_keys($server_key_pair, $client_key)
{
function sodium_crypto_kx_server_session_keys(
#[\SensitiveParameter]
$server_key_pair,
$client_key
) {
return ParagonIE_Sodium_Compat::crypto_kx_server_session_keys($server_key_pair, $client_key);
}
}
@ -764,8 +882,10 @@ if (!is_callable('sodium_crypto_kx_secretkey')) {
* @return string
* @throws Exception
*/
function sodium_crypto_kx_secretkey($key_pair)
{
function sodium_crypto_kx_secretkey(
#[\SensitiveParameter]
$key_pair
) {
return ParagonIE_Sodium_Compat::crypto_kx_secretkey($key_pair);
}
}
@ -775,8 +895,10 @@ if (!is_callable('sodium_crypto_kx_publickey')) {
* @return string
* @throws Exception
*/
function sodium_crypto_kx_publickey($key_pair)
{
function sodium_crypto_kx_publickey(
#[\SensitiveParameter]
$key_pair
) {
return ParagonIE_Sodium_Compat::crypto_kx_publickey($key_pair);
}
}
@ -793,8 +915,15 @@ if (!is_callable('sodium_crypto_pwhash')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_pwhash($length, $passwd, $salt, $opslimit, $memlimit, $algo = null)
{
function sodium_crypto_pwhash(
$length,
#[\SensitiveParameter]
$passwd,
$salt,
$opslimit,
$memlimit,
$algo = null
) {
return ParagonIE_Sodium_Compat::crypto_pwhash($length, $passwd, $salt, $opslimit, $memlimit, $algo);
}
}
@ -808,8 +937,12 @@ if (!is_callable('sodium_crypto_pwhash_str')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_pwhash_str($passwd, $opslimit, $memlimit)
{
function sodium_crypto_pwhash_str(
#[\SensitiveParameter]
$passwd,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_str($passwd, $opslimit, $memlimit);
}
}
@ -823,8 +956,12 @@ if (!is_callable('sodium_crypto_pwhash_str_needs_rehash')) {
*
* @throws SodiumException
*/
function sodium_crypto_pwhash_str_needs_rehash($hash, $opslimit, $memlimit)
{
function sodium_crypto_pwhash_str_needs_rehash(
#[\SensitiveParameter]
$hash,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_str_needs_rehash($hash, $opslimit, $memlimit);
}
}
@ -837,8 +974,12 @@ if (!is_callable('sodium_crypto_pwhash_str_verify')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_pwhash_str_verify($passwd, $hash)
{
function sodium_crypto_pwhash_str_verify(
#[\SensitiveParameter]
$passwd,
#[\SensitiveParameter]
$hash
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_str_verify($passwd, $hash);
}
}
@ -854,8 +995,14 @@ if (!is_callable('sodium_crypto_pwhash_scryptsalsa208sha256')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_pwhash_scryptsalsa208sha256($length, $passwd, $salt, $opslimit, $memlimit)
{
function sodium_crypto_pwhash_scryptsalsa208sha256(
$length,
#[\SensitiveParameter]
$passwd,
$salt,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256(
$length,
$passwd,
@ -875,8 +1022,12 @@ if (!is_callable('sodium_crypto_pwhash_scryptsalsa208sha256_str')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_pwhash_scryptsalsa208sha256_str($passwd, $opslimit, $memlimit)
{
function sodium_crypto_pwhash_scryptsalsa208sha256_str(
#[\SensitiveParameter]
$passwd,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str($passwd, $opslimit, $memlimit);
}
}
@ -889,8 +1040,12 @@ if (!is_callable('sodium_crypto_pwhash_scryptsalsa208sha256_str_verify')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_pwhash_scryptsalsa208sha256_str_verify($passwd, $hash)
{
function sodium_crypto_pwhash_scryptsalsa208sha256_str_verify(
#[\SensitiveParameter]
$passwd,
#[\SensitiveParameter]
$hash
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify($passwd, $hash);
}
}
@ -903,8 +1058,11 @@ if (!is_callable('sodium_crypto_scalarmult')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_scalarmult($n, $p)
{
function sodium_crypto_scalarmult(
#[\SensitiveParameter]
$n,
$p
) {
return ParagonIE_Sodium_Compat::crypto_scalarmult($n, $p);
}
}
@ -916,8 +1074,10 @@ if (!is_callable('sodium_crypto_scalarmult_base')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_scalarmult_base($n)
{
function sodium_crypto_scalarmult_base(
#[\SensitiveParameter]
$n
) {
return ParagonIE_Sodium_Compat::crypto_scalarmult_base($n);
}
}
@ -931,8 +1091,13 @@ if (!is_callable('sodium_crypto_secretbox')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_secretbox($message, $nonce, $key)
{
function sodium_crypto_secretbox(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_secretbox($message, $nonce, $key);
}
}
@ -955,8 +1120,12 @@ if (!is_callable('sodium_crypto_secretbox_open')) {
* @param string $key
* @return string|bool
*/
function sodium_crypto_secretbox_open($ciphertext, $nonce, $key)
{
function sodium_crypto_secretbox_open(
$ciphertext,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_secretbox_open($ciphertext, $nonce, $key);
} catch (Error $ex) {
@ -972,8 +1141,10 @@ if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_init_push')) {
* @return array<int, string>
* @throws SodiumException
*/
function sodium_crypto_secretstream_xchacha20poly1305_init_push($key)
{
function sodium_crypto_secretstream_xchacha20poly1305_init_push(
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_init_push($key);
}
}
@ -987,7 +1158,9 @@ if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_push')) {
* @throws SodiumException
*/
function sodium_crypto_secretstream_xchacha20poly1305_push(
#[\SensitiveParameter]
&$state,
#[\SensitiveParameter]
$message,
$additional_data = '',
$tag = 0
@ -1007,8 +1180,11 @@ if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_init_pull')) {
* @return string
* @throws Exception
*/
function sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key)
{
function sodium_crypto_secretstream_xchacha20poly1305_init_pull(
$header,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_init_pull($header, $key);
}
}
@ -1020,8 +1196,12 @@ if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_pull')) {
* @return bool|array{0: string, 1: int}
* @throws SodiumException
*/
function sodium_crypto_secretstream_xchacha20poly1305_pull(&$state, $ciphertext, $additional_data = '')
{
function sodium_crypto_secretstream_xchacha20poly1305_pull(
#[\SensitiveParameter]
&$state,
$ciphertext,
$additional_data = ''
) {
return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_pull(
$state,
$ciphertext,
@ -1035,8 +1215,10 @@ if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_rekey')) {
* @return void
* @throws SodiumException
*/
function sodium_crypto_secretstream_xchacha20poly1305_rekey(&$state)
{
function sodium_crypto_secretstream_xchacha20poly1305_rekey(
#[\SensitiveParameter]
&$state
) {
ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_rekey($state);
}
}
@ -1059,8 +1241,11 @@ if (!is_callable('sodium_crypto_shorthash')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_shorthash($message, $key = '')
{
function sodium_crypto_shorthash(
$message,
#[\SensitiveParameter]
$key = ''
) {
return ParagonIE_Sodium_Compat::crypto_shorthash($message, $key);
}
}
@ -1084,8 +1269,11 @@ if (!is_callable('sodium_crypto_sign')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_sign($message, $secret_key)
{
function sodium_crypto_sign(
$message,
#[\SensitiveParameter]
$secret_key
) {
return ParagonIE_Sodium_Compat::crypto_sign($message, $secret_key);
}
}
@ -1098,8 +1286,11 @@ if (!is_callable('sodium_crypto_sign_detached')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_sign_detached($message, $secret_key)
{
function sodium_crypto_sign_detached(
$message,
#[\SensitiveParameter]
$secret_key
) {
return ParagonIE_Sodium_Compat::crypto_sign_detached($message, $secret_key);
}
}
@ -1112,8 +1303,11 @@ if (!is_callable('sodium_crypto_sign_keypair_from_secretkey_and_publickey')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_sign_keypair_from_secretkey_and_publickey($secret_key, $public_key)
{
function sodium_crypto_sign_keypair_from_secretkey_and_publickey(
#[\SensitiveParameter]
$secret_key,
$public_key
) {
return ParagonIE_Sodium_Compat::crypto_sign_keypair_from_secretkey_and_publickey($secret_key, $public_key);
}
}
@ -1155,8 +1349,10 @@ if (!is_callable('sodium_crypto_sign_publickey')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_sign_publickey($key_pair)
{
function sodium_crypto_sign_publickey(
#[\SensitiveParameter]
$key_pair
) {
return ParagonIE_Sodium_Compat::crypto_sign_publickey($key_pair);
}
}
@ -1168,8 +1364,10 @@ if (!is_callable('sodium_crypto_sign_publickey_from_secretkey')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_sign_publickey_from_secretkey($secret_key)
{
function sodium_crypto_sign_publickey_from_secretkey(
#[\SensitiveParameter]
$secret_key
) {
return ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey($secret_key);
}
}
@ -1181,8 +1379,10 @@ if (!is_callable('sodium_crypto_sign_secretkey')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_sign_secretkey($key_pair)
{
function sodium_crypto_sign_secretkey(
#[\SensitiveParameter]
$key_pair
) {
return ParagonIE_Sodium_Compat::crypto_sign_secretkey($key_pair);
}
}
@ -1194,8 +1394,10 @@ if (!is_callable('sodium_crypto_sign_seed_keypair')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_sign_seed_keypair($seed)
{
function sodium_crypto_sign_seed_keypair(
#[\SensitiveParameter]
$seed
) {
return ParagonIE_Sodium_Compat::crypto_sign_seed_keypair($seed);
}
}
@ -1235,8 +1437,10 @@ if (!is_callable('sodium_crypto_sign_ed25519_sk_to_curve25519')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_sign_ed25519_sk_to_curve25519($secret_key)
{
function sodium_crypto_sign_ed25519_sk_to_curve25519(
#[\SensitiveParameter]
$secret_key
) {
return ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519($secret_key);
}
}
@ -1250,8 +1454,12 @@ if (!is_callable('sodium_crypto_stream')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_stream($length, $nonce, $key)
{
function sodium_crypto_stream(
$length,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream($length, $nonce, $key);
}
}
@ -1276,8 +1484,13 @@ if (!is_callable('sodium_crypto_stream_xor')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_stream_xor($message, $nonce, $key)
{
function sodium_crypto_stream_xor(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key);
}
}
@ -1291,8 +1504,11 @@ if (!is_callable('sodium_hex2bin')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_hex2bin($string, $ignore = '')
{
function sodium_hex2bin(
#[\SensitiveParameter]
$string,
$ignore = ''
) {
return ParagonIE_Sodium_Compat::hex2bin($string, $ignore);
}
}
@ -1304,8 +1520,10 @@ if (!is_callable('sodium_increment')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_increment(&$string)
{
function sodium_increment(
#[\SensitiveParameter]
&$string
) {
ParagonIE_Sodium_Compat::increment($string);
}
}
@ -1348,8 +1566,12 @@ if (!is_callable('sodium_memcmp')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_memcmp($string1, $string2)
{
function sodium_memcmp(
#[\SensitiveParameter]
$string1,
#[\SensitiveParameter]
$string2
) {
return ParagonIE_Sodium_Compat::memcmp($string1, $string2);
}
}
@ -1360,9 +1582,13 @@ if (!is_callable('sodium_memzero')) {
* @return void
* @throws SodiumException
* @throws TypeError
*
* @psalm-suppress ReferenceConstraintViolation
*/
function sodium_memzero(&$string)
{
function sodium_memzero(
#[\SensitiveParameter]
&$string
) {
ParagonIE_Sodium_Compat::memzero($string);
}
}
@ -1375,8 +1601,11 @@ if (!is_callable('sodium_pad')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_pad($unpadded, $block_size)
{
function sodium_pad(
#[\SensitiveParameter]
$unpadded,
$block_size
) {
return ParagonIE_Sodium_Compat::pad($unpadded, $block_size, true);
}
}
@ -1389,8 +1618,11 @@ if (!is_callable('sodium_unpad')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_unpad($padded, $block_size)
{
function sodium_unpad(
#[\SensitiveParameter]
$padded,
$block_size
) {
return ParagonIE_Sodium_Compat::unpad($padded, $block_size, true);
}
}

View File

@ -0,0 +1,130 @@
<?php
require_once dirname(dirname(__FILE__)) . '/autoload.php';
/**
* This file will monkey patch the pure-PHP implementation in place of the
* PECL functions and constants, but only if they do not already exist.
*
* Thus, the functions or constants just proxy to the appropriate
* ParagonIE_Sodium_Compat method or class constant, respectively.
*/
foreach (array(
'CRYPTO_AEAD_AESGIS128L_KEYBYTES',
'CRYPTO_AEAD_AESGIS128L_NSECBYTES',
'CRYPTO_AEAD_AESGIS128L_NPUBBYTES',
'CRYPTO_AEAD_AESGIS128L_ABYTES',
'CRYPTO_AEAD_AESGIS256_KEYBYTES',
'CRYPTO_AEAD_AESGIS256_NSECBYTES',
'CRYPTO_AEAD_AESGIS256_NPUBBYTES',
'CRYPTO_AEAD_AESGIS256_ABYTES',
) as $constant
) {
if (!defined("SODIUM_$constant") && defined("ParagonIE_Sodium_Compat::$constant")) {
define("SODIUM_$constant", constant("ParagonIE_Sodium_Compat::$constant"));
}
}
if (!is_callable('sodium_crypto_aead_aegis128l_decrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aegis128l_decrypt()
* @param string $ciphertext
* @param string $additional_data
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
*/
function sodium_crypto_aead_aegis128l_decrypt(
$ciphertext,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aegis128l_decrypt(
$ciphertext,
$additional_data,
$nonce,
$key
);
}
}
if (!is_callable('sodium_crypto_aead_aegis128l_encrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aegis128l_encrypt()
* @param string $message
* @param string $additional_data
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_aead_aegis128l_encrypt(
#[\SensitiveParameter]
$message,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aegis128l_encrypt(
$message,
$additional_data,
$nonce,
$key
);
}
}
if (!is_callable('sodium_crypto_aead_aegis256_decrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt()
* @param string $ciphertext
* @param string $additional_data
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
*/
function sodium_crypto_aead_aegis256_decrypt(
$ciphertext,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aegis256_decrypt(
$ciphertext,
$additional_data,
$nonce,
$key
);
}
}
if (!is_callable('sodium_crypto_aead_aegis256_encrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt()
* @param string $message
* @param string $additional_data
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_aead_aegis256_encrypt(
#[\SensitiveParameter]
$message,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt(
$message,
$additional_data,
$nonce,
$key
);
}
}

View File

@ -0,0 +1,10 @@
<?php
const SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES = 16;
const SODIUM_CRYPTO_AEAD_AEGIS128L_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES = 32;
const SODIUM_CRYPTO_AEAD_AEGIS128L_ABYTES = 32;
const SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_AEGIS256_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES = 32;
const SODIUM_CRYPTO_AEAD_AEGIS256_ABYTES = 32;

View File

@ -47,8 +47,12 @@ if (!is_callable('sodium_crypto_core_ristretto255_add')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_add($p, $q)
{
function sodium_crypto_core_ristretto255_add(
#[\SensitiveParameter]
$p,
#[\SensitiveParameter]
$q
) {
return ParagonIE_Sodium_Compat::ristretto255_add($p, $q, true);
}
}
@ -60,8 +64,10 @@ if (!is_callable('sodium_crypto_core_ristretto255_from_hash')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_from_hash($s)
{
function sodium_crypto_core_ristretto255_from_hash(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_from_hash($s, true);
}
}
@ -73,8 +79,10 @@ if (!is_callable('sodium_crypto_core_ristretto255_is_valid_point')) {
* @return bool
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_is_valid_point($s)
{
function sodium_crypto_core_ristretto255_is_valid_point(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_is_valid_point($s, true);
}
}
@ -99,8 +107,12 @@ if (!is_callable('sodium_crypto_core_ristretto255_scalar_add')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_add($x, $y)
{
function sodium_crypto_core_ristretto255_scalar_add(
#[\SensitiveParameter]
$x,
#[\SensitiveParameter]
$y
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_add($x, $y, true);
}
}
@ -112,8 +124,10 @@ if (!is_callable('sodium_crypto_core_ristretto255_scalar_complement')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_complement($s)
{
function sodium_crypto_core_ristretto255_scalar_complement(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_complement($s, true);
}
}
@ -125,8 +139,10 @@ if (!is_callable('sodium_crypto_core_ristretto255_scalar_invert')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_invert($p)
{
function sodium_crypto_core_ristretto255_scalar_invert(
#[\SensitiveParameter]
$p
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_invert($p, true);
}
}
@ -139,8 +155,12 @@ if (!is_callable('sodium_crypto_core_ristretto255_scalar_mul')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_mul($x, $y)
{
function sodium_crypto_core_ristretto255_scalar_mul(
#[\SensitiveParameter]
$x,
#[\SensitiveParameter]
$y
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_mul($x, $y, true);
}
}
@ -152,8 +172,10 @@ if (!is_callable('sodium_crypto_core_ristretto255_scalar_negate')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_negate($s)
{
function sodium_crypto_core_ristretto255_scalar_negate(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_negate($s, true);
}
}
@ -177,8 +199,10 @@ if (!is_callable('sodium_crypto_core_ristretto255_scalar_reduce')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_reduce($s)
{
function sodium_crypto_core_ristretto255_scalar_reduce(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_reduce($s, true);
}
}
@ -191,8 +215,12 @@ if (!is_callable('sodium_crypto_core_ristretto255_scalar_sub')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_sub($x, $y)
{
function sodium_crypto_core_ristretto255_scalar_sub(
#[\SensitiveParameter]
$x,
#[\SensitiveParameter]
$y
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_sub($x, $y, true);
}
}
@ -205,8 +233,12 @@ if (!is_callable('sodium_crypto_core_ristretto255_sub')) {
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_sub($p, $q)
{
function sodium_crypto_core_ristretto255_sub(
#[\SensitiveParameter]
$p,
#[\SensitiveParameter]
$q
) {
return ParagonIE_Sodium_Compat::ristretto255_sub($p, $q, true);
}
}
@ -219,8 +251,12 @@ if (!is_callable('sodium_crypto_scalarmult_ristretto255')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_scalarmult_ristretto255($n, $p)
{
function sodium_crypto_scalarmult_ristretto255(
#[\SensitiveParameter]
$n,
#[\SensitiveParameter]
$p
) {
return ParagonIE_Sodium_Compat::scalarmult_ristretto255($n, $p, true);
}
}
@ -232,8 +268,10 @@ if (!is_callable('sodium_crypto_scalarmult_ristretto255_base')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_scalarmult_ristretto255_base($n)
{
function sodium_crypto_scalarmult_ristretto255_base(
#[\SensitiveParameter]
$n
) {
return ParagonIE_Sodium_Compat::scalarmult_ristretto255_base($n, true);
}
}

View File

@ -20,8 +20,10 @@ if (!is_callable('\\Sodium\\bin2hex')) {
* @throws \SodiumException
* @throws \TypeError
*/
function bin2hex($string)
{
function bin2hex(
#[\SensitiveParameter]
$string
) {
return ParagonIE_Sodium_Compat::bin2hex($string);
}
}
@ -34,8 +36,12 @@ if (!is_callable('\\Sodium\\compare')) {
* @throws \SodiumException
* @throws \TypeError
*/
function compare($a, $b)
{
function compare(
#[\SensitiveParameter]
$a,
#[\SensitiveParameter]
$b
) {
return ParagonIE_Sodium_Compat::compare($a, $b);
}
}
@ -48,8 +54,13 @@ if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_decrypt')) {
* @param string $key
* @return string|bool
*/
function crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key)
{
function crypto_aead_aes256gcm_decrypt(
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key);
} catch (\TypeError $ex) {
@ -70,8 +81,14 @@ if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_encrypt')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_aead_aes256gcm_encrypt($message, $assocData, $nonce, $key)
{
function crypto_aead_aes256gcm_encrypt(
#[\SensitiveParameter]
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt($message, $assocData, $nonce, $key);
}
}
@ -94,8 +111,13 @@ if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_decrypt')) {
* @param string $key
* @return string|bool
*/
function crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key)
{
function crypto_aead_chacha20poly1305_decrypt(
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key);
} catch (\TypeError $ex) {
@ -116,8 +138,14 @@ if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_encrypt')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_aead_chacha20poly1305_encrypt($message, $assocData, $nonce, $key)
{
function crypto_aead_chacha20poly1305_encrypt(
#[\SensitiveParameter]
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt($message, $assocData, $nonce, $key);
}
}
@ -130,8 +158,13 @@ if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_ietf_decrypt')) {
* @param string $key
* @return string|bool
*/
function crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key)
{
function crypto_aead_chacha20poly1305_ietf_decrypt(
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key);
} catch (\TypeError $ex) {
@ -152,8 +185,14 @@ if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_ietf_encrypt')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_aead_chacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key)
{
function crypto_aead_chacha20poly1305_ietf_encrypt(
#[\SensitiveParameter]
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key);
}
}
@ -166,8 +205,11 @@ if (!is_callable('\\Sodium\\crypto_auth')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_auth($message, $key)
{
function crypto_auth(
$message,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_auth($message, $key);
}
}
@ -181,8 +223,12 @@ if (!is_callable('\\Sodium\\crypto_auth_verify')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_auth_verify($mac, $message, $key)
{
function crypto_auth_verify(
$mac,
$message,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_auth_verify($mac, $message, $key);
}
}
@ -196,8 +242,13 @@ if (!is_callable('\\Sodium\\crypto_box')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box($message, $nonce, $kp)
{
function crypto_box(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$kp
) {
return ParagonIE_Sodium_Compat::crypto_box($message, $nonce, $kp);
}
}
@ -222,8 +273,11 @@ if (!is_callable('\\Sodium\\crypto_box_keypair_from_secretkey_and_publickey')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_keypair_from_secretkey_and_publickey($sk, $pk)
{
function crypto_box_keypair_from_secretkey_and_publickey(
#[\SensitiveParameter]
$sk,
$pk
) {
return ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($sk, $pk);
}
}
@ -235,8 +289,13 @@ if (!is_callable('\\Sodium\\crypto_box_open')) {
* @param string $kp
* @return string|bool
*/
function crypto_box_open($message, $nonce, $kp)
{
function crypto_box_open(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$kp
) {
try {
return ParagonIE_Sodium_Compat::crypto_box_open($message, $nonce, $kp);
} catch (\TypeError $ex) {
@ -254,8 +313,10 @@ if (!is_callable('\\Sodium\\crypto_box_publickey')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_publickey($keypair)
{
function crypto_box_publickey(
#[\SensitiveParameter]
$keypair
) {
return ParagonIE_Sodium_Compat::crypto_box_publickey($keypair);
}
}
@ -267,8 +328,10 @@ if (!is_callable('\\Sodium\\crypto_box_publickey_from_secretkey')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_publickey_from_secretkey($sk)
{
function crypto_box_publickey_from_secretkey(
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey($sk);
}
}
@ -281,8 +344,11 @@ if (!is_callable('\\Sodium\\crypto_box_seal')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_seal($message, $publicKey)
{
function crypto_box_seal(
#[\SensitiveParameter]
$message,
$publicKey
) {
return ParagonIE_Sodium_Compat::crypto_box_seal($message, $publicKey);
}
}
@ -293,8 +359,11 @@ if (!is_callable('\\Sodium\\crypto_box_seal_open')) {
* @param string $kp
* @return string|bool
*/
function crypto_box_seal_open($message, $kp)
{
function crypto_box_seal_open(
$message,
#[\SensitiveParameter]
$kp
) {
try {
return ParagonIE_Sodium_Compat::crypto_box_seal_open($message, $kp);
} catch (\TypeError $ex) {
@ -312,8 +381,10 @@ if (!is_callable('\\Sodium\\crypto_box_secretkey')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_secretkey($keypair)
{
function crypto_box_secretkey(
#[\SensitiveParameter]
$keypair
) {
return ParagonIE_Sodium_Compat::crypto_box_secretkey($keypair);
}
}
@ -327,8 +398,12 @@ if (!is_callable('\\Sodium\\crypto_generichash')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_generichash($message, $key = null, $outLen = 32)
{
function crypto_generichash(
$message,
#[\SensitiveParameter]
$key = null,
$outLen = 32
) {
return ParagonIE_Sodium_Compat::crypto_generichash($message, $key, $outLen);
}
}
@ -341,8 +416,11 @@ if (!is_callable('\\Sodium\\crypto_generichash_final')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_generichash_final(&$ctx, $outputLength = 32)
{
function crypto_generichash_final(
#[\SensitiveParameter]
&$ctx,
$outputLength = 32
) {
return ParagonIE_Sodium_Compat::crypto_generichash_final($ctx, $outputLength);
}
}
@ -355,8 +433,11 @@ if (!is_callable('\\Sodium\\crypto_generichash_init')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_generichash_init($key = null, $outLen = 32)
{
function crypto_generichash_init(
#[\SensitiveParameter]
$key = null,
$outLen = 32
) {
return ParagonIE_Sodium_Compat::crypto_generichash_init($key, $outLen);
}
}
@ -369,8 +450,11 @@ if (!is_callable('\\Sodium\\crypto_generichash_update')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_generichash_update(&$ctx, $message = '')
{
function crypto_generichash_update(
#[\SensitiveParameter]
&$ctx,
$message = ''
) {
ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $message);
}
}
@ -385,8 +469,13 @@ if (!is_callable('\\Sodium\\crypto_kx')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_kx($my_secret, $their_public, $client_public, $server_public)
{
function crypto_kx(
#[\SensitiveParameter]
$my_secret,
$their_public,
$client_public,
$server_public
) {
return ParagonIE_Sodium_Compat::crypto_kx(
$my_secret,
$their_public,
@ -408,8 +497,14 @@ if (!is_callable('\\Sodium\\crypto_pwhash')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash($outlen, $passwd, $salt, $opslimit, $memlimit)
{
function crypto_pwhash(
$outlen,
#[\SensitiveParameter]
$passwd,
$salt,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash($outlen, $passwd, $salt, $opslimit, $memlimit);
}
}
@ -423,8 +518,12 @@ if (!is_callable('\\Sodium\\crypto_pwhash_str')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_str($passwd, $opslimit, $memlimit)
{
function crypto_pwhash_str(
#[\SensitiveParameter]
$passwd,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_str($passwd, $opslimit, $memlimit);
}
}
@ -437,8 +536,12 @@ if (!is_callable('\\Sodium\\crypto_pwhash_str_verify')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_str_verify($passwd, $hash)
{
function crypto_pwhash_str_verify(
#[\SensitiveParameter]
$passwd,
#[\SensitiveParameter]
$hash
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_str_verify($passwd, $hash);
}
}
@ -454,8 +557,15 @@ if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_scryptsalsa208sha256($outlen, $passwd, $salt, $opslimit, $memlimit)
{
function crypto_pwhash_scryptsalsa208sha256(
$outlen,
#[\SensitiveParameter]
$passwd,
#[\SensitiveParameter]
$salt,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256($outlen, $passwd, $salt, $opslimit, $memlimit);
}
}
@ -469,8 +579,12 @@ if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_scryptsalsa208sha256_str($passwd, $opslimit, $memlimit)
{
function crypto_pwhash_scryptsalsa208sha256_str(
#[\SensitiveParameter]
$passwd,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str($passwd, $opslimit, $memlimit);
}
}
@ -483,8 +597,12 @@ if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str_verify')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_scryptsalsa208sha256_str_verify($passwd, $hash)
{
function crypto_pwhash_scryptsalsa208sha256_str_verify(
#[\SensitiveParameter]
$passwd,
#[\SensitiveParameter]
$hash
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify($passwd, $hash);
}
}
@ -497,8 +615,11 @@ if (!is_callable('\\Sodium\\crypto_scalarmult')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_scalarmult($n, $p)
{
function crypto_scalarmult(
#[\SensitiveParameter]
$n,
$p
) {
return ParagonIE_Sodium_Compat::crypto_scalarmult($n, $p);
}
}
@ -510,8 +631,10 @@ if (!is_callable('\\Sodium\\crypto_scalarmult_base')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_scalarmult_base($n)
{
function crypto_scalarmult_base(
#[\SensitiveParameter]
$n
) {
return ParagonIE_Sodium_Compat::crypto_scalarmult_base($n);
}
}
@ -525,8 +648,13 @@ if (!is_callable('\\Sodium\\crypto_secretbox')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_secretbox($message, $nonce, $key)
{
function crypto_secretbox(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_secretbox($message, $nonce, $key);
}
}
@ -538,8 +666,12 @@ if (!is_callable('\\Sodium\\crypto_secretbox_open')) {
* @param string $key
* @return string|bool
*/
function crypto_secretbox_open($message, $nonce, $key)
{
function crypto_secretbox_open(
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_secretbox_open($message, $nonce, $key);
} catch (\TypeError $ex) {
@ -558,8 +690,11 @@ if (!is_callable('\\Sodium\\crypto_shorthash')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_shorthash($message, $key = '')
{
function crypto_shorthash(
$message,
#[\SensitiveParameter]
$key = ''
) {
return ParagonIE_Sodium_Compat::crypto_shorthash($message, $key);
}
}
@ -572,8 +707,11 @@ if (!is_callable('\\Sodium\\crypto_sign')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign($message, $sk)
{
function crypto_sign(
$message,
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_sign($message, $sk);
}
}
@ -586,8 +724,11 @@ if (!is_callable('\\Sodium\\crypto_sign_detached')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_detached($message, $sk)
{
function crypto_sign_detached(
$message,
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_sign_detached($message, $sk);
}
}
@ -629,8 +770,10 @@ if (!is_callable('\\Sodium\\crypto_sign_publickey')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_publickey($keypair)
{
function crypto_sign_publickey(
#[\SensitiveParameter]
$keypair
) {
return ParagonIE_Sodium_Compat::crypto_sign_publickey($keypair);
}
}
@ -642,8 +785,10 @@ if (!is_callable('\\Sodium\\crypto_sign_publickey_from_secretkey')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_publickey_from_secretkey($sk)
{
function crypto_sign_publickey_from_secretkey(
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey($sk);
}
}
@ -655,8 +800,10 @@ if (!is_callable('\\Sodium\\crypto_sign_secretkey')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_secretkey($keypair)
{
function crypto_sign_secretkey(
#[\SensitiveParameter]
$keypair
) {
return ParagonIE_Sodium_Compat::crypto_sign_secretkey($keypair);
}
}
@ -668,8 +815,10 @@ if (!is_callable('\\Sodium\\crypto_sign_seed_keypair')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_seed_keypair($seed)
{
function crypto_sign_seed_keypair(
#[\SensitiveParameter]
$seed
) {
return ParagonIE_Sodium_Compat::crypto_sign_seed_keypair($seed);
}
}
@ -709,8 +858,10 @@ if (!is_callable('\\Sodium\\crypto_sign_ed25519_sk_to_curve25519')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_ed25519_sk_to_curve25519($sk)
{
function crypto_sign_ed25519_sk_to_curve25519(
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519($sk);
}
}
@ -724,8 +875,12 @@ if (!is_callable('\\Sodium\\crypto_stream')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_stream($len, $nonce, $key)
{
function crypto_stream(
$len,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream($len, $nonce, $key);
}
}
@ -739,8 +894,13 @@ if (!is_callable('\\Sodium\\crypto_stream_xor')) {
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_stream_xor($message, $nonce, $key)
{
function crypto_stream_xor(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key);
}
}
@ -752,8 +912,10 @@ if (!is_callable('\\Sodium\\hex2bin')) {
* @throws \SodiumException
* @throws \TypeError
*/
function hex2bin($string)
{
function hex2bin(
#[\SensitiveParameter]
$string
) {
return ParagonIE_Sodium_Compat::hex2bin($string);
}
}
@ -766,8 +928,12 @@ if (!is_callable('\\Sodium\\memcmp')) {
* @throws \SodiumException
* @throws \TypeError
*/
function memcmp($a, $b)
{
function memcmp(
#[\SensitiveParameter]
$a,
#[\SensitiveParameter]
$b
) {
return ParagonIE_Sodium_Compat::memcmp($a, $b);
}
}
@ -783,8 +949,10 @@ if (!is_callable('\\Sodium\\memzero')) {
* @psalm-suppress MissingReturnType
* @psalm-suppress ReferenceConstraintViolation
*/
function memzero(&$str)
{
function memzero(
#[\SensitiveParameter]
&$str
) {
ParagonIE_Sodium_Compat::memzero($str);
}
}

View File

@ -10,8 +10,12 @@ if (!is_callable('sodium_crypto_stream_xchacha20')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_stream_xchacha20($len, $nonce, $key)
{
function sodium_crypto_stream_xchacha20(
$len,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20($len, $nonce, $key, true);
}
}
@ -36,8 +40,13 @@ if (!is_callable('sodium_crypto_stream_xchacha20_xor')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_stream_xchacha20_xor($message, $nonce, $key)
{
function sodium_crypto_stream_xchacha20_xor(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor($message, $nonce, $key, true);
}
}
@ -52,8 +61,14 @@ if (!is_callable('sodium_crypto_stream_xchacha20_xor_ic')) {
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_stream_xchacha20_xor_ic($message, $nonce, $counter, $key)
{
function sodium_crypto_stream_xchacha20_xor_ic(
#[\SensitiveParameter]
$message,
$nonce,
$counter,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor_ic($message, $nonce, $counter, $key, true);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,284 @@
<?php
if (class_exists('ParagonIE_Sodium_Core_AEGIS_State128L', false)) {
return;
}
if (!defined('SODIUM_COMPAT_AEGIS_C0')) {
define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\x0d\x15\x22\x37\x59\x90\xe9\x79\x62");
}
if (!defined('SODIUM_COMPAT_AEGIS_C1')) {
define('SODIUM_COMPAT_AEGIS_C1', "\xdb\x3d\x18\x55\x6d\xc2\x2f\xf1\x20\x11\x31\x42\x73\xb5\x28\xdd");
}
class ParagonIE_Sodium_Core_AEGIS_State128L
{
/** @var array<int, string> $state */
protected $state;
public function __construct()
{
$this->state = array_fill(0, 8, '');
}
/**
* @internal Only use this for unit tests!
* @return string[]
*/
public function getState()
{
return array_values($this->state);
}
/**
* @param array $input
* @return self
* @throws SodiumException
*
* @internal Only for unit tests
*/
public static function initForUnitTests(array $input)
{
if (count($input) < 8) {
throw new SodiumException('invalid input');
}
$state = new self();
for ($i = 0; $i < 8; ++$i) {
$state->state[$i] = $input[$i];
}
return $state;
}
/**
* @param string $key
* @param string $nonce
* @return self
*/
public static function init($key, $nonce)
{
$state = new self();
// S0 = key ^ nonce
$state->state[0] = $key ^ $nonce;
// S1 = C1
$state->state[1] = SODIUM_COMPAT_AEGIS_C1;
// S2 = C0
$state->state[2] = SODIUM_COMPAT_AEGIS_C0;
// S3 = C1
$state->state[3] = SODIUM_COMPAT_AEGIS_C1;
// S4 = key ^ nonce
$state->state[4] = $key ^ $nonce;
// S5 = key ^ C0
$state->state[5] = $key ^ SODIUM_COMPAT_AEGIS_C0;
// S6 = key ^ C1
$state->state[6] = $key ^ SODIUM_COMPAT_AEGIS_C1;
// S7 = key ^ C0
$state->state[7] = $key ^ SODIUM_COMPAT_AEGIS_C0;
// Repeat(10, Update(nonce, key))
for ($i = 0; $i < 10; ++$i) {
$state->update($nonce, $key);
}
return $state;
}
/**
* @param string $ai
* @return self
*/
public function absorb($ai)
{
if (ParagonIE_Sodium_Core_Util::strlen($ai) !== 32) {
throw new SodiumException('Input must be two AES blocks in size');
}
$t0 = ParagonIE_Sodium_Core_Util::substr($ai, 0, 16);
$t1 = ParagonIE_Sodium_Core_Util::substr($ai, 16, 16);
return $this->update($t0, $t1);
}
/**
* @param string $ci
* @return string
* @throws SodiumException
*/
public function dec($ci)
{
if (ParagonIE_Sodium_Core_Util::strlen($ci) !== 32) {
throw new SodiumException('Input must be two AES blocks in size');
}
// z0 = S6 ^ S1 ^ (S2 & S3)
$z0 = $this->state[6]
^ $this->state[1]
^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]);
// z1 = S2 ^ S5 ^ (S6 & S7)
$z1 = $this->state[2]
^ $this->state[5]
^ ParagonIE_Sodium_Core_Util::andStrings($this->state[6], $this->state[7]);
// t0, t1 = Split(xi, 128)
$t0 = ParagonIE_Sodium_Core_Util::substr($ci, 0, 16);
$t1 = ParagonIE_Sodium_Core_Util::substr($ci, 16, 16);
// out0 = t0 ^ z0
// out1 = t1 ^ z1
$out0 = $t0 ^ $z0;
$out1 = $t1 ^ $z1;
// Update(out0, out1)
// xi = out0 || out1
$this->update($out0, $out1);
return $out0 . $out1;
}
/**
* @param string $cn
* @return string
*/
public function decPartial($cn)
{
$len = ParagonIE_Sodium_Core_Util::strlen($cn);
// z0 = S6 ^ S1 ^ (S2 & S3)
$z0 = $this->state[6]
^ $this->state[1]
^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]);
// z1 = S2 ^ S5 ^ (S6 & S7)
$z1 = $this->state[2]
^ $this->state[5]
^ ParagonIE_Sodium_Core_Util::andStrings($this->state[6], $this->state[7]);
// t0, t1 = Split(ZeroPad(cn, 256), 128)
$cn = str_pad($cn, 32, "\0", STR_PAD_RIGHT);
$t0 = ParagonIE_Sodium_Core_Util::substr($cn, 0, 16);
$t1 = ParagonIE_Sodium_Core_Util::substr($cn, 16, 16);
// out0 = t0 ^ z0
// out1 = t1 ^ z1
$out0 = $t0 ^ $z0;
$out1 = $t1 ^ $z1;
// xn = Truncate(out0 || out1, |cn|)
$xn = ParagonIE_Sodium_Core_Util::substr($out0 . $out1, 0, $len);
// v0, v1 = Split(ZeroPad(xn, 256), 128)
$padded = str_pad($xn, 32, "\0", STR_PAD_RIGHT);
$v0 = ParagonIE_Sodium_Core_Util::substr($padded, 0, 16);
$v1 = ParagonIE_Sodium_Core_Util::substr($padded, 16, 16);
// Update(v0, v1)
$this->update($v0, $v1);
// return xn
return $xn;
}
/**
* @param string $xi
* @return string
* @throws SodiumException
*/
public function enc($xi)
{
if (ParagonIE_Sodium_Core_Util::strlen($xi) !== 32) {
throw new SodiumException('Input must be two AES blocks in size');
}
// z0 = S6 ^ S1 ^ (S2 & S3)
$z0 = $this->state[6]
^ $this->state[1]
^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]);
// z1 = S2 ^ S5 ^ (S6 & S7)
$z1 = $this->state[2]
^ $this->state[5]
^ ParagonIE_Sodium_Core_Util::andStrings($this->state[6], $this->state[7]);
// t0, t1 = Split(xi, 128)
$t0 = ParagonIE_Sodium_Core_Util::substr($xi, 0, 16);
$t1 = ParagonIE_Sodium_Core_Util::substr($xi, 16, 16);
// out0 = t0 ^ z0
// out1 = t1 ^ z1
$out0 = $t0 ^ $z0;
$out1 = $t1 ^ $z1;
// Update(t0, t1)
// ci = out0 || out1
$this->update($t0, $t1);
// return ci
return $out0 . $out1;
}
/**
* @param int $ad_len_bits
* @param int $msg_len_bits
* @return string
*/
public function finalize($ad_len_bits, $msg_len_bits)
{
$encoded = ParagonIE_Sodium_Core_Util::store64_le($ad_len_bits) .
ParagonIE_Sodium_Core_Util::store64_le($msg_len_bits);
$t = $this->state[2] ^ $encoded;
for ($i = 0; $i < 7; ++$i) {
$this->update($t, $t);
}
return ($this->state[0] ^ $this->state[1] ^ $this->state[2] ^ $this->state[3]) .
($this->state[4] ^ $this->state[5] ^ $this->state[6] ^ $this->state[7]);
}
/**
* @param string $m0
* @param string $m1
* @return self
*/
public function update($m0, $m1)
{
/*
S'0 = AESRound(S7, S0 ^ M0)
S'1 = AESRound(S0, S1)
S'2 = AESRound(S1, S2)
S'3 = AESRound(S2, S3)
S'4 = AESRound(S3, S4 ^ M1)
S'5 = AESRound(S4, S5)
S'6 = AESRound(S5, S6)
S'7 = AESRound(S6, S7)
*/
list($s_0, $s_1) = ParagonIE_Sodium_Core_AES::doubleRound(
$this->state[7], $this->state[0] ^ $m0,
$this->state[0], $this->state[1]
);
list($s_2, $s_3) = ParagonIE_Sodium_Core_AES::doubleRound(
$this->state[1], $this->state[2],
$this->state[2], $this->state[3]
);
list($s_4, $s_5) = ParagonIE_Sodium_Core_AES::doubleRound(
$this->state[3], $this->state[4] ^ $m1,
$this->state[4], $this->state[5]
);
list($s_6, $s_7) = ParagonIE_Sodium_Core_AES::doubleRound(
$this->state[5], $this->state[6],
$this->state[6], $this->state[7]
);
/*
S0 = S'0
S1 = S'1
S2 = S'2
S3 = S'3
S4 = S'4
S5 = S'5
S6 = S'6
S7 = S'7
*/
$this->state[0] = $s_0;
$this->state[1] = $s_1;
$this->state[2] = $s_2;
$this->state[3] = $s_3;
$this->state[4] = $s_4;
$this->state[5] = $s_5;
$this->state[6] = $s_6;
$this->state[7] = $s_7;
return $this;
}
}

View File

@ -0,0 +1,240 @@
<?php
if (class_exists('ParagonIE_Sodium_Core_AEGIS_State256', false)) {
return;
}
if (!defined('SODIUM_COMPAT_AEGIS_C0')) {
define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\x0d\x15\x22\x37\x59\x90\xe9\x79\x62");
}
if (!defined('SODIUM_COMPAT_AEGIS_C1')) {
define('SODIUM_COMPAT_AEGIS_C1', "\xdb\x3d\x18\x55\x6d\xc2\x2f\xf1\x20\x11\x31\x42\x73\xb5\x28\xdd");
}
class ParagonIE_Sodium_Core_AEGIS_State256
{
/** @var array<int, string> $state */
protected $state;
public function __construct()
{
$this->state = array_fill(0, 6, '');
}
/**
* @internal Only use this for unit tests!
* @return string[]
*/
public function getState()
{
return array_values($this->state);
}
/**
* @param array $input
* @return self
* @throws SodiumException
*
* @internal Only for unit tests
*/
public static function initForUnitTests(array $input)
{
if (count($input) < 6) {
throw new SodiumException('invalid input');
}
$state = new self();
for ($i = 0; $i < 6; ++$i) {
$state->state[$i] = $input[$i];
}
return $state;
}
/**
* @param string $key
* @param string $nonce
* @return self
*/
public static function init($key, $nonce)
{
$state = new self();
$k0 = ParagonIE_Sodium_Core_Util::substr($key, 0, 16);
$k1 = ParagonIE_Sodium_Core_Util::substr($key, 16, 16);
$n0 = ParagonIE_Sodium_Core_Util::substr($nonce, 0, 16);
$n1 = ParagonIE_Sodium_Core_Util::substr($nonce, 16, 16);
// S0 = k0 ^ n0
// S1 = k1 ^ n1
// S2 = C1
// S3 = C0
// S4 = k0 ^ C0
// S5 = k1 ^ C1
$k0_n0 = $k0 ^ $n0;
$k1_n1 = $k1 ^ $n1;
$state->state[0] = $k0_n0;
$state->state[1] = $k1_n1;
$state->state[2] = SODIUM_COMPAT_AEGIS_C1;
$state->state[3] = SODIUM_COMPAT_AEGIS_C0;
$state->state[4] = $k0 ^ SODIUM_COMPAT_AEGIS_C0;
$state->state[5] = $k1 ^ SODIUM_COMPAT_AEGIS_C1;
// Repeat(4,
// Update(k0)
// Update(k1)
// Update(k0 ^ n0)
// Update(k1 ^ n1)
// )
for ($i = 0; $i < 4; ++$i) {
$state->update($k0);
$state->update($k1);
$state->update($k0 ^ $n0);
$state->update($k1 ^ $n1);
}
return $state;
}
/**
* @param string $ai
* @return self
* @throws SodiumException
*/
public function absorb($ai)
{
if (ParagonIE_Sodium_Core_Util::strlen($ai) !== 16) {
throw new SodiumException('Input must be an AES block in size');
}
return $this->update($ai);
}
/**
* @param string $ci
* @return string
* @throws SodiumException
*/
public function dec($ci)
{
if (ParagonIE_Sodium_Core_Util::strlen($ci) !== 16) {
throw new SodiumException('Input must be an AES block in size');
}
// z = S1 ^ S4 ^ S5 ^ (S2 & S3)
$z = $this->state[1]
^ $this->state[4]
^ $this->state[5]
^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]);
$xi = $ci ^ $z;
$this->update($xi);
return $xi;
}
/**
* @param string $cn
* @return string
*/
public function decPartial($cn)
{
$len = ParagonIE_Sodium_Core_Util::strlen($cn);
// z = S1 ^ S4 ^ S5 ^ (S2 & S3)
$z = $this->state[1]
^ $this->state[4]
^ $this->state[5]
^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]);
// t = ZeroPad(cn, 128)
$t = str_pad($cn, 16, "\0", STR_PAD_RIGHT);
// out = t ^ z
$out = $t ^ $z;
// xn = Truncate(out, |cn|)
$xn = ParagonIE_Sodium_Core_Util::substr($out, 0, $len);
// v = ZeroPad(xn, 128)
$v = str_pad($xn, 16, "\0", STR_PAD_RIGHT);
// Update(v)
$this->update($v);
// return xn
return $xn;
}
/**
* @param string $xi
* @return string
* @throws SodiumException
*/
public function enc($xi)
{
if (ParagonIE_Sodium_Core_Util::strlen($xi) !== 16) {
throw new SodiumException('Input must be an AES block in size');
}
// z = S1 ^ S4 ^ S5 ^ (S2 & S3)
$z = $this->state[1]
^ $this->state[4]
^ $this->state[5]
^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]);
$this->update($xi);
return $xi ^ $z;
}
/**
* @param int $ad_len_bits
* @param int $msg_len_bits
* @return string
*/
public function finalize($ad_len_bits, $msg_len_bits)
{
$encoded = ParagonIE_Sodium_Core_Util::store64_le($ad_len_bits) .
ParagonIE_Sodium_Core_Util::store64_le($msg_len_bits);
$t = $this->state[3] ^ $encoded;
for ($i = 0; $i < 7; ++$i) {
$this->update($t);
}
return ($this->state[0] ^ $this->state[1] ^ $this->state[2]) .
($this->state[3] ^ $this->state[4] ^ $this->state[5]);
}
/**
* @param string $m
* @return self
*/
public function update($m)
{
/*
S'0 = AESRound(S5, S0 ^ M)
S'1 = AESRound(S0, S1)
S'2 = AESRound(S1, S2)
S'3 = AESRound(S2, S3)
S'4 = AESRound(S3, S4)
S'5 = AESRound(S4, S5)
*/
list($s_0, $s_1) = ParagonIE_Sodium_Core_AES::doubleRound(
$this->state[5],$this->state[0] ^ $m,
$this->state[0], $this->state[1]
);
list($s_2, $s_3) = ParagonIE_Sodium_Core_AES::doubleRound(
$this->state[1], $this->state[2],
$this->state[2], $this->state[3]
);
list($s_4, $s_5) = ParagonIE_Sodium_Core_AES::doubleRound(
$this->state[3], $this->state[4],
$this->state[4], $this->state[5]
);
/*
S0 = S'0
S1 = S'1
S2 = S'2
S3 = S'3
S4 = S'4
S5 = S'5
*/
$this->state[0] = $s_0;
$this->state[1] = $s_1;
$this->state[2] = $s_2;
$this->state[3] = $s_3;
$this->state[4] = $s_4;
$this->state[5] = $s_5;
return $this;
}
}

View File

@ -0,0 +1,119 @@
<?php
if (!defined('SODIUM_COMPAT_AEGIS_C0')) {
define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\x0d\x15\x22\x37\x59\x90\xe9\x79\x62");
}
if (!defined('SODIUM_COMPAT_AEGIS_C1')) {
define('SODIUM_COMPAT_AEGIS_C1', "\xdb\x3d\x18\x55\x6d\xc2\x2f\xf1\x20\x11\x31\x42\x73\xb5\x28\xdd");
}
class ParagonIE_Sodium_Core_AEGIS128L extends ParagonIE_Sodium_Core_AES
{
/**
* @param string $ct
* @param string $tag
* @param string $ad
* @param string $key
* @param string $nonce
* @return string
* @throws SodiumException
*/
public static function decrypt($ct, $tag, $ad, $key, $nonce)
{
$state = self::init($key, $nonce);
$ad_blocks = (self::strlen($ad) + 31) >> 5;
for ($i = 0; $i < $ad_blocks; ++$i) {
$ai = self::substr($ad, $i << 5, 32);
if (self::strlen($ai) < 32) {
$ai = str_pad($ai, 32, "\0", STR_PAD_RIGHT);
}
$state->absorb($ai);
}
$msg = '';
$cn = self::strlen($ct) & 31;
$ct_blocks = self::strlen($ct) >> 5;
for ($i = 0; $i < $ct_blocks; ++$i) {
$msg .= $state->dec(self::substr($ct, $i << 5, 32));
}
if ($cn) {
$start = $ct_blocks << 5;
$msg .= $state->decPartial(self::substr($ct, $start, $cn));
}
$expected_tag = $state->finalize(
self::strlen($ad) << 3,
self::strlen($msg) << 3
);
if (!self::hashEquals($expected_tag, $tag)) {
try {
// The RFC says to erase msg, so we shall try:
ParagonIE_Sodium_Compat::memzero($msg);
} catch (SodiumException $ex) {
// Do nothing if we cannot memzero
}
throw new SodiumException('verification failed');
}
return $msg;
}
/**
* @param string $msg
* @param string $ad
* @param string $key
* @param string $nonce
* @return array
*
* @throws SodiumException
*/
public static function encrypt($msg, $ad, $key, $nonce)
{
$state = self::init($key, $nonce);
// ad_blocks = Split(ZeroPad(ad, 256), 256)
// for ai in ad_blocks:
// Absorb(ai)
$ad_len = self::strlen($ad);
$msg_len = self::strlen($msg);
$ad_blocks = ($ad_len + 31) >> 5;
for ($i = 0; $i < $ad_blocks; ++$i) {
$ai = self::substr($ad, $i << 5, 32);
if (self::strlen($ai) < 32) {
$ai = str_pad($ai, 32, "\0", STR_PAD_RIGHT);
}
$state->absorb($ai);
}
// msg_blocks = Split(ZeroPad(msg, 256), 256)
// for xi in msg_blocks:
// ct = ct || Enc(xi)
$ct = '';
$msg_blocks = ($msg_len + 31) >> 5;
for ($i = 0; $i < $msg_blocks; ++$i) {
$xi = self::substr($msg, $i << 5, 32);
if (self::strlen($xi) < 32) {
$xi = str_pad($xi, 32, "\0", STR_PAD_RIGHT);
}
$ct .= $state->enc($xi);
}
// tag = Finalize(|ad|, |msg|)
// ct = Truncate(ct, |msg|)
$tag = $state->finalize(
$ad_len << 3,
$msg_len << 3
);
// return ct and tag
return array(
self::substr($ct, 0, $msg_len),
$tag
);
}
/**
* @param string $key
* @param string $nonce
* @return ParagonIE_Sodium_Core_AEGIS_State128L
*/
public static function init($key, $nonce)
{
return ParagonIE_Sodium_Core_AEGIS_State128L::init($key, $nonce);
}
}

View File

@ -0,0 +1,118 @@
<?php
if (!defined('SODIUM_COMPAT_AEGIS_C0')) {
define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\x0d\x15\x22\x37\x59\x90\xe9\x79\x62");
}
if (!defined('SODIUM_COMPAT_AEGIS_C1')) {
define('SODIUM_COMPAT_AEGIS_C1', "\xdb\x3d\x18\x55\x6d\xc2\x2f\xf1\x20\x11\x31\x42\x73\xb5\x28\xdd");
}
class ParagonIE_Sodium_Core_AEGIS256 extends ParagonIE_Sodium_Core_AES
{
/**
* @param string $ct
* @param string $tag
* @param string $ad
* @param string $key
* @param string $nonce
* @return string
* @throws SodiumException
*/
public static function decrypt($ct, $tag, $ad, $key, $nonce)
{
$state = self::init($key, $nonce);
// ad_blocks = Split(ZeroPad(ad, 128), 128)
$ad_blocks = (self::strlen($ad) + 15) >> 4;
// for ai in ad_blocks:
// Absorb(ai)
for ($i = 0; $i < $ad_blocks; ++$i) {
$ai = self::substr($ad, $i << 4, 16);
if (self::strlen($ai) < 16) {
$ai = str_pad($ai, 16, "\0", STR_PAD_RIGHT);
}
$state->absorb($ai);
}
$msg = '';
$cn = self::strlen($ct) & 15;
$ct_blocks = self::strlen($ct) >> 4;
// ct_blocks = Split(ZeroPad(ct, 128), 128)
// cn = Tail(ct, |ct| mod 128)
for ($i = 0; $i < $ct_blocks; ++$i) {
$msg .= $state->dec(self::substr($ct, $i << 4, 16));
}
// if cn is not empty:
// msg = msg || DecPartial(cn)
if ($cn) {
$start = $ct_blocks << 4;
$msg .= $state->decPartial(self::substr($ct, $start, $cn));
}
$expected_tag = $state->finalize(
self::strlen($ad) << 3,
self::strlen($msg) << 3
);
if (!self::hashEquals($expected_tag, $tag)) {
try {
// The RFC says to erase msg, so we shall try:
ParagonIE_Sodium_Compat::memzero($msg);
} catch (SodiumException $ex) {
// Do nothing if we cannot memzero
}
throw new SodiumException('verification failed');
}
return $msg;
}
/**
* @param string $msg
* @param string $ad
* @param string $key
* @param string $nonce
* @return array
* @throws SodiumException
*/
public static function encrypt($msg, $ad, $key, $nonce)
{
$state = self::init($key, $nonce);
$ad_len = self::strlen($ad);
$msg_len = self::strlen($msg);
$ad_blocks = ($ad_len + 15) >> 4;
for ($i = 0; $i < $ad_blocks; ++$i) {
$ai = self::substr($ad, $i << 4, 16);
if (self::strlen($ai) < 16) {
$ai = str_pad($ai, 16, "\0", STR_PAD_RIGHT);
}
$state->absorb($ai);
}
$ct = '';
$msg_blocks = ($msg_len + 15) >> 4;
for ($i = 0; $i < $msg_blocks; ++$i) {
$xi = self::substr($msg, $i << 4, 16);
if (self::strlen($xi) < 16) {
$xi = str_pad($xi, 16, "\0", STR_PAD_RIGHT);
}
$ct .= $state->enc($xi);
}
$tag = $state->finalize(
$ad_len << 3,
$msg_len << 3
);
return array(
self::substr($ct, 0, $msg_len),
$tag
);
}
/**
* @param string $key
* @param string $nonce
* @return ParagonIE_Sodium_Core_AEGIS_State256
*/
public static function init($key, $nonce)
{
return ParagonIE_Sodium_Core_AEGIS_State256::init($key, $nonce);
}
}

View File

@ -0,0 +1,518 @@
<?php
if (class_exists('ParagonIE_Sodium_Core_AES', false)) {
return;
}
/**
* Bitsliced implementation of the AES block cipher.
*
* Based on the implementation provided by BearSSL.
*
* @internal This should only be used by sodium_compat
*/
class ParagonIE_Sodium_Core_AES extends ParagonIE_Sodium_Core_Util
{
/**
* @var int[] AES round constants
*/
private static $Rcon = array(
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
);
/**
* Mutates the values of $q!
*
* @param ParagonIE_Sodium_Core_AES_Block $q
* @return void
*/
public static function sbox(ParagonIE_Sodium_Core_AES_Block $q)
{
/**
* @var int $x0
* @var int $x1
* @var int $x2
* @var int $x3
* @var int $x4
* @var int $x5
* @var int $x6
* @var int $x7
*/
$x0 = $q[7] & self::U32_MAX;
$x1 = $q[6] & self::U32_MAX;
$x2 = $q[5] & self::U32_MAX;
$x3 = $q[4] & self::U32_MAX;
$x4 = $q[3] & self::U32_MAX;
$x5 = $q[2] & self::U32_MAX;
$x6 = $q[1] & self::U32_MAX;
$x7 = $q[0] & self::U32_MAX;
$y14 = $x3 ^ $x5;
$y13 = $x0 ^ $x6;
$y9 = $x0 ^ $x3;
$y8 = $x0 ^ $x5;
$t0 = $x1 ^ $x2;
$y1 = $t0 ^ $x7;
$y4 = $y1 ^ $x3;
$y12 = $y13 ^ $y14;
$y2 = $y1 ^ $x0;
$y5 = $y1 ^ $x6;
$y3 = $y5 ^ $y8;
$t1 = $x4 ^ $y12;
$y15 = $t1 ^ $x5;
$y20 = $t1 ^ $x1;
$y6 = $y15 ^ $x7;
$y10 = $y15 ^ $t0;
$y11 = $y20 ^ $y9;
$y7 = $x7 ^ $y11;
$y17 = $y10 ^ $y11;
$y19 = $y10 ^ $y8;
$y16 = $t0 ^ $y11;
$y21 = $y13 ^ $y16;
$y18 = $x0 ^ $y16;
/*
* Non-linear section.
*/
$t2 = $y12 & $y15;
$t3 = $y3 & $y6;
$t4 = $t3 ^ $t2;
$t5 = $y4 & $x7;
$t6 = $t5 ^ $t2;
$t7 = $y13 & $y16;
$t8 = $y5 & $y1;
$t9 = $t8 ^ $t7;
$t10 = $y2 & $y7;
$t11 = $t10 ^ $t7;
$t12 = $y9 & $y11;
$t13 = $y14 & $y17;
$t14 = $t13 ^ $t12;
$t15 = $y8 & $y10;
$t16 = $t15 ^ $t12;
$t17 = $t4 ^ $t14;
$t18 = $t6 ^ $t16;
$t19 = $t9 ^ $t14;
$t20 = $t11 ^ $t16;
$t21 = $t17 ^ $y20;
$t22 = $t18 ^ $y19;
$t23 = $t19 ^ $y21;
$t24 = $t20 ^ $y18;
$t25 = $t21 ^ $t22;
$t26 = $t21 & $t23;
$t27 = $t24 ^ $t26;
$t28 = $t25 & $t27;
$t29 = $t28 ^ $t22;
$t30 = $t23 ^ $t24;
$t31 = $t22 ^ $t26;
$t32 = $t31 & $t30;
$t33 = $t32 ^ $t24;
$t34 = $t23 ^ $t33;
$t35 = $t27 ^ $t33;
$t36 = $t24 & $t35;
$t37 = $t36 ^ $t34;
$t38 = $t27 ^ $t36;
$t39 = $t29 & $t38;
$t40 = $t25 ^ $t39;
$t41 = $t40 ^ $t37;
$t42 = $t29 ^ $t33;
$t43 = $t29 ^ $t40;
$t44 = $t33 ^ $t37;
$t45 = $t42 ^ $t41;
$z0 = $t44 & $y15;
$z1 = $t37 & $y6;
$z2 = $t33 & $x7;
$z3 = $t43 & $y16;
$z4 = $t40 & $y1;
$z5 = $t29 & $y7;
$z6 = $t42 & $y11;
$z7 = $t45 & $y17;
$z8 = $t41 & $y10;
$z9 = $t44 & $y12;
$z10 = $t37 & $y3;
$z11 = $t33 & $y4;
$z12 = $t43 & $y13;
$z13 = $t40 & $y5;
$z14 = $t29 & $y2;
$z15 = $t42 & $y9;
$z16 = $t45 & $y14;
$z17 = $t41 & $y8;
/*
* Bottom linear transformation.
*/
$t46 = $z15 ^ $z16;
$t47 = $z10 ^ $z11;
$t48 = $z5 ^ $z13;
$t49 = $z9 ^ $z10;
$t50 = $z2 ^ $z12;
$t51 = $z2 ^ $z5;
$t52 = $z7 ^ $z8;
$t53 = $z0 ^ $z3;
$t54 = $z6 ^ $z7;
$t55 = $z16 ^ $z17;
$t56 = $z12 ^ $t48;
$t57 = $t50 ^ $t53;
$t58 = $z4 ^ $t46;
$t59 = $z3 ^ $t54;
$t60 = $t46 ^ $t57;
$t61 = $z14 ^ $t57;
$t62 = $t52 ^ $t58;
$t63 = $t49 ^ $t58;
$t64 = $z4 ^ $t59;
$t65 = $t61 ^ $t62;
$t66 = $z1 ^ $t63;
$s0 = $t59 ^ $t63;
$s6 = $t56 ^ ~$t62;
$s7 = $t48 ^ ~$t60;
$t67 = $t64 ^ $t65;
$s3 = $t53 ^ $t66;
$s4 = $t51 ^ $t66;
$s5 = $t47 ^ $t65;
$s1 = $t64 ^ ~$s3;
$s2 = $t55 ^ ~$t67;
$q[7] = $s0 & self::U32_MAX;
$q[6] = $s1 & self::U32_MAX;
$q[5] = $s2 & self::U32_MAX;
$q[4] = $s3 & self::U32_MAX;
$q[3] = $s4 & self::U32_MAX;
$q[2] = $s5 & self::U32_MAX;
$q[1] = $s6 & self::U32_MAX;
$q[0] = $s7 & self::U32_MAX;
}
/**
* Mutates the values of $q!
*
* @param ParagonIE_Sodium_Core_AES_Block $q
* @return void
*/
public static function invSbox(ParagonIE_Sodium_Core_AES_Block $q)
{
self::processInversion($q);
self::sbox($q);
self::processInversion($q);
}
/**
* This is some boilerplate code needed to invert an S-box. Rather than repeat the code
* twice, I moved it to a protected method.
*
* Mutates $q
*
* @param ParagonIE_Sodium_Core_AES_Block $q
* @return void
*/
protected static function processInversion(ParagonIE_Sodium_Core_AES_Block $q)
{
$q0 = (~$q[0]) & self::U32_MAX;
$q1 = (~$q[1]) & self::U32_MAX;
$q2 = $q[2] & self::U32_MAX;
$q3 = $q[3] & self::U32_MAX;
$q4 = $q[4] & self::U32_MAX;
$q5 = (~$q[5]) & self::U32_MAX;
$q6 = (~$q[6]) & self::U32_MAX;
$q7 = $q[7] & self::U32_MAX;
$q[7] = ($q1 ^ $q4 ^ $q6) & self::U32_MAX;
$q[6] = ($q0 ^ $q3 ^ $q5) & self::U32_MAX;
$q[5] = ($q7 ^ $q2 ^ $q4) & self::U32_MAX;
$q[4] = ($q6 ^ $q1 ^ $q3) & self::U32_MAX;
$q[3] = ($q5 ^ $q0 ^ $q2) & self::U32_MAX;
$q[2] = ($q4 ^ $q7 ^ $q1) & self::U32_MAX;
$q[1] = ($q3 ^ $q6 ^ $q0) & self::U32_MAX;
$q[0] = ($q2 ^ $q5 ^ $q7) & self::U32_MAX;
}
/**
* @param int $x
* @return int
*/
public static function subWord($x)
{
$q = ParagonIE_Sodium_Core_AES_Block::fromArray(
array($x, $x, $x, $x, $x, $x, $x, $x)
);
$q->orthogonalize();
self::sbox($q);
$q->orthogonalize();
return $q[0] & self::U32_MAX;
}
/**
* Calculate the key schedule from a given random key
*
* @param string $key
* @return ParagonIE_Sodium_Core_AES_KeySchedule
* @throws SodiumException
*/
public static function keySchedule($key)
{
$key_len = self::strlen($key);
switch ($key_len) {
case 16:
$num_rounds = 10;
break;
case 24:
$num_rounds = 12;
break;
case 32:
$num_rounds = 14;
break;
default:
throw new SodiumException('Invalid key length: ' . $key_len);
}
$skey = array();
$comp_skey = array();
$nk = $key_len >> 2;
$nkf = ($num_rounds + 1) << 2;
$tmp = 0;
for ($i = 0; $i < $nk; ++$i) {
$tmp = self::load_4(self::substr($key, $i << 2, 4));
$skey[($i << 1)] = $tmp;
$skey[($i << 1) + 1] = $tmp;
}
for ($i = $nk, $j = 0, $k = 0; $i < $nkf; ++$i) {
if ($j === 0) {
$tmp = (($tmp & 0xff) << 24) | ($tmp >> 8);
$tmp = (self::subWord($tmp) ^ self::$Rcon[$k]) & self::U32_MAX;
} elseif ($nk > 6 && $j === 4) {
$tmp = self::subWord($tmp);
}
$tmp ^= $skey[($i - $nk) << 1];
$skey[($i << 1)] = $tmp & self::U32_MAX;
$skey[($i << 1) + 1] = $tmp & self::U32_MAX;
if (++$j === $nk) {
/** @psalm-suppress LoopInvalidation */
$j = 0;
++$k;
}
}
for ($i = 0; $i < $nkf; $i += 4) {
$q = ParagonIE_Sodium_Core_AES_Block::fromArray(
array_slice($skey, $i << 1, 8)
);
$q->orthogonalize();
// We have to overwrite $skey since we're not using C pointers like BearSSL did
for ($j = 0; $j < 8; ++$j) {
$skey[($i << 1) + $j] = $q[$j];
}
}
for ($i = 0, $j = 0; $i < $nkf; ++$i, $j += 2) {
$comp_skey[$i] = ($skey[$j] & 0x55555555)
| ($skey[$j + 1] & 0xAAAAAAAA);
}
return new ParagonIE_Sodium_Core_AES_KeySchedule($comp_skey, $num_rounds);
}
/**
* Mutates $q
*
* @param ParagonIE_Sodium_Core_AES_KeySchedule $skey
* @param ParagonIE_Sodium_Core_AES_Block $q
* @param int $offset
* @return void
*/
public static function addRoundKey(
ParagonIE_Sodium_Core_AES_Block $q,
ParagonIE_Sodium_Core_AES_KeySchedule $skey,
$offset = 0
) {
$block = $skey->getRoundKey($offset);
for ($j = 0; $j < 8; ++$j) {
$q[$j] = ($q[$j] ^ $block[$j]) & ParagonIE_Sodium_Core_Util::U32_MAX;
}
}
/**
* This mainly exists for testing, as we need the round key features for AEGIS.
*
* @param string $message
* @param string $key
* @return string
* @throws SodiumException
*/
public static function decryptBlockECB($message, $key)
{
if (self::strlen($message) !== 16) {
throw new SodiumException('decryptBlockECB() expects a 16 byte message');
}
$skey = self::keySchedule($key)->expand();
$q = ParagonIE_Sodium_Core_AES_Block::init();
$q[0] = self::load_4(self::substr($message, 0, 4));
$q[2] = self::load_4(self::substr($message, 4, 4));
$q[4] = self::load_4(self::substr($message, 8, 4));
$q[6] = self::load_4(self::substr($message, 12, 4));
$q->orthogonalize();
self::bitsliceDecryptBlock($skey, $q);
$q->orthogonalize();
return self::store32_le($q[0]) .
self::store32_le($q[2]) .
self::store32_le($q[4]) .
self::store32_le($q[6]);
}
/**
* This mainly exists for testing, as we need the round key features for AEGIS.
*
* @param string $message
* @param string $key
* @return string
* @throws SodiumException
*/
public static function encryptBlockECB($message, $key)
{
if (self::strlen($message) !== 16) {
throw new SodiumException('encryptBlockECB() expects a 16 byte message');
}
$comp_skey = self::keySchedule($key);
$skey = $comp_skey->expand();
$q = ParagonIE_Sodium_Core_AES_Block::init();
$q[0] = self::load_4(self::substr($message, 0, 4));
$q[2] = self::load_4(self::substr($message, 4, 4));
$q[4] = self::load_4(self::substr($message, 8, 4));
$q[6] = self::load_4(self::substr($message, 12, 4));
$q->orthogonalize();
self::bitsliceEncryptBlock($skey, $q);
$q->orthogonalize();
return self::store32_le($q[0]) .
self::store32_le($q[2]) .
self::store32_le($q[4]) .
self::store32_le($q[6]);
}
/**
* Mutates $q
*
* @param ParagonIE_Sodium_Core_AES_Expanded $skey
* @param ParagonIE_Sodium_Core_AES_Block $q
* @return void
*/
public static function bitsliceEncryptBlock(
ParagonIE_Sodium_Core_AES_Expanded $skey,
ParagonIE_Sodium_Core_AES_Block $q
) {
self::addRoundKey($q, $skey);
for ($u = 1; $u < $skey->getNumRounds(); ++$u) {
self::sbox($q);
$q->shiftRows();
$q->mixColumns();
self::addRoundKey($q, $skey, ($u << 3));
}
self::sbox($q);
$q->shiftRows();
self::addRoundKey($q, $skey, ($skey->getNumRounds() << 3));
}
/**
* @param string $x
* @param string $y
* @return string
*/
public static function aesRound($x, $y)
{
$q = ParagonIE_Sodium_Core_AES_Block::init();
$q[0] = self::load_4(self::substr($x, 0, 4));
$q[2] = self::load_4(self::substr($x, 4, 4));
$q[4] = self::load_4(self::substr($x, 8, 4));
$q[6] = self::load_4(self::substr($x, 12, 4));
$rk = ParagonIE_Sodium_Core_AES_Block::init();
$rk[0] = $rk[1] = self::load_4(self::substr($y, 0, 4));
$rk[2] = $rk[3] = self::load_4(self::substr($y, 4, 4));
$rk[4] = $rk[5] = self::load_4(self::substr($y, 8, 4));
$rk[6] = $rk[7] = self::load_4(self::substr($y, 12, 4));
$q->orthogonalize();
self::sbox($q);
$q->shiftRows();
$q->mixColumns();
$q->orthogonalize();
// add round key without key schedule:
for ($i = 0; $i < 8; ++$i) {
$q[$i] ^= $rk[$i];
}
return self::store32_le($q[0]) .
self::store32_le($q[2]) .
self::store32_le($q[4]) .
self::store32_le($q[6]);
}
/**
* Process two AES blocks in one shot.
*
* @param string $b0 First AES block
* @param string $rk0 First round key
* @param string $b1 Second AES block
* @param string $rk1 Second round key
* @return string[]
*/
public static function doubleRound($b0, $rk0, $b1, $rk1)
{
$q = ParagonIE_Sodium_Core_AES_Block::init();
// First block
$q[0] = self::load_4(self::substr($b0, 0, 4));
$q[2] = self::load_4(self::substr($b0, 4, 4));
$q[4] = self::load_4(self::substr($b0, 8, 4));
$q[6] = self::load_4(self::substr($b0, 12, 4));
// Second block
$q[1] = self::load_4(self::substr($b1, 0, 4));
$q[3] = self::load_4(self::substr($b1, 4, 4));
$q[5] = self::load_4(self::substr($b1, 8, 4));
$q[7] = self::load_4(self::substr($b1, 12, 4));;
$rk = ParagonIE_Sodium_Core_AES_Block::init();
// First round key
$rk[0] = self::load_4(self::substr($rk0, 0, 4));
$rk[2] = self::load_4(self::substr($rk0, 4, 4));
$rk[4] = self::load_4(self::substr($rk0, 8, 4));
$rk[6] = self::load_4(self::substr($rk0, 12, 4));
// Second round key
$rk[1] = self::load_4(self::substr($rk1, 0, 4));
$rk[3] = self::load_4(self::substr($rk1, 4, 4));
$rk[5] = self::load_4(self::substr($rk1, 8, 4));
$rk[7] = self::load_4(self::substr($rk1, 12, 4));
$q->orthogonalize();
self::sbox($q);
$q->shiftRows();
$q->mixColumns();
$q->orthogonalize();
// add round key without key schedule:
for ($i = 0; $i < 8; ++$i) {
$q[$i] ^= $rk[$i];
}
return array(
self::store32_le($q[0]) . self::store32_le($q[2]) . self::store32_le($q[4]) . self::store32_le($q[6]),
self::store32_le($q[1]) . self::store32_le($q[3]) . self::store32_le($q[5]) . self::store32_le($q[7]),
);
}
/**
* @param ParagonIE_Sodium_Core_AES_Expanded $skey
* @param ParagonIE_Sodium_Core_AES_Block $q
* @return void
*/
public static function bitsliceDecryptBlock(
ParagonIE_Sodium_Core_AES_Expanded $skey,
ParagonIE_Sodium_Core_AES_Block $q
) {
self::addRoundKey($q, $skey, ($skey->getNumRounds() << 3));
for ($u = $skey->getNumRounds() - 1; $u > 0; --$u) {
$q->inverseShiftRows();
self::invSbox($q);
self::addRoundKey($q, $skey, ($u << 3));
$q->inverseMixColumns();
}
$q->inverseShiftRows();
self::invSbox($q);
self::addRoundKey($q, $skey, ($u << 3));
}
}

View File

@ -0,0 +1,343 @@
<?php
if (class_exists('ParagonIE_Sodium_Core_AES_Block', false)) {
return;
}
/**
* @internal This should only be used by sodium_compat
*/
class ParagonIE_Sodium_Core_AES_Block extends SplFixedArray
{
/**
* @var array<int, int>
*/
protected $values = array();
/**
* @var int
*/
protected $size;
/**
* @param int $size
*/
public function __construct($size = 8)
{
parent::__construct($size);
$this->size = $size;
$this->values = array_fill(0, $size, 0);
}
/**
* @return self
*/
public static function init()
{
return new self(8);
}
/**
* @internal You should not use this directly from another application
*
* @param array<int, int> $array
* @param bool $save_indexes
* @return self
*
* @psalm-suppress MethodSignatureMismatch
*/
#[ReturnTypeWillChange]
public static function fromArray($array, $save_indexes = null)
{
$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_AES_Block();
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]);
}
}
return $obj;
}
/**
* @internal You should not use this directly from another application
*
* @param int|null $offset
* @param int $value
* @return void
*
* @psalm-suppress MethodSignatureMismatch
* @psalm-suppress MixedArrayOffset
*/
#[ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
if (!is_int($value)) {
throw new InvalidArgumentException('Expected an integer');
}
if (is_null($offset)) {
$this->values[] = $value;
} else {
$this->values[$offset] = $value;
}
}
/**
* @internal You should not use this directly from another application
*
* @param int $offset
* @return bool
*
* @psalm-suppress MethodSignatureMismatch
* @psalm-suppress MixedArrayOffset
*/
#[ReturnTypeWillChange]
public function offsetExists($offset)
{
return isset($this->values[$offset]);
}
/**
* @internal You should not use this directly from another application
*
* @param int $offset
* @return void
*
* @psalm-suppress MethodSignatureMismatch
* @psalm-suppress MixedArrayOffset
*/
#[ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->values[$offset]);
}
/**
* @internal You should not use this directly from another application
*
* @param int $offset
* @return int
*
* @psalm-suppress MethodSignatureMismatch
* @psalm-suppress MixedArrayOffset
*/
#[ReturnTypeWillChange]
public function offsetGet($offset)
{
if (!isset($this->values[$offset])) {
$this->values[$offset] = 0;
}
return (int) ($this->values[$offset]);
}
/**
* @internal You should not use this directly from another application
*
* @return array
*/
public function __debugInfo()
{
$out = array();
foreach ($this->values as $v) {
$out[] = str_pad(dechex($v), 8, '0', STR_PAD_LEFT);
}
return array(implode(', ', $out));
/*
return array(implode(', ', $this->values));
*/
}
/**
* @param int $cl low bit mask
* @param int $ch high bit mask
* @param int $s shift
* @param int $x index 1
* @param int $y index 2
* @return self
*/
public function swapN($cl, $ch, $s, $x, $y)
{
static $u32mask = ParagonIE_Sodium_Core_Util::U32_MAX;
$a = $this->values[$x] & $u32mask;
$b = $this->values[$y] & $u32mask;
// (x) = (a & cl) | ((b & cl) << (s));
$this->values[$x] = ($a & $cl) | ((($b & $cl) << $s) & $u32mask);
// (y) = ((a & ch) >> (s)) | (b & ch);
$this->values[$y] = ((($a & $ch) & $u32mask) >> $s) | ($b & $ch);
return $this;
}
/**
* @param int $x index 1
* @param int $y index 2
* @return self
*/
public function swap2($x, $y)
{
return $this->swapN(0x55555555, 0xAAAAAAAA, 1, $x, $y);
}
/**
* @param int $x index 1
* @param int $y index 2
* @return self
*/
public function swap4($x, $y)
{
return $this->swapN(0x33333333, 0xCCCCCCCC, 2, $x, $y);
}
/**
* @param int $x index 1
* @param int $y index 2
* @return self
*/
public function swap8($x, $y)
{
return $this->swapN(0x0F0F0F0F, 0xF0F0F0F0, 4, $x, $y);
}
/**
* @return self
*/
public function orthogonalize()
{
return $this
->swap2(0, 1)
->swap2(2, 3)
->swap2(4, 5)
->swap2(6, 7)
->swap4(0, 2)
->swap4(1, 3)
->swap4(4, 6)
->swap4(5, 7)
->swap8(0, 4)
->swap8(1, 5)
->swap8(2, 6)
->swap8(3, 7);
}
/**
* @return self
*/
public function shiftRows()
{
for ($i = 0; $i < 8; ++$i) {
$x = $this->values[$i] & ParagonIE_Sodium_Core_Util::U32_MAX;
$this->values[$i] = (
($x & 0x000000FF)
| (($x & 0x0000FC00) >> 2) | (($x & 0x00000300) << 6)
| (($x & 0x00F00000) >> 4) | (($x & 0x000F0000) << 4)
| (($x & 0xC0000000) >> 6) | (($x & 0x3F000000) << 2)
) & ParagonIE_Sodium_Core_Util::U32_MAX;
}
return $this;
}
/**
* @param int $x
* @return int
*/
public static function rotr16($x)
{
return (($x << 16) & ParagonIE_Sodium_Core_Util::U32_MAX) | ($x >> 16);
}
/**
* @return self
*/
public function mixColumns()
{
$q0 = $this->values[0];
$q1 = $this->values[1];
$q2 = $this->values[2];
$q3 = $this->values[3];
$q4 = $this->values[4];
$q5 = $this->values[5];
$q6 = $this->values[6];
$q7 = $this->values[7];
$r0 = (($q0 >> 8) | ($q0 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r1 = (($q1 >> 8) | ($q1 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r2 = (($q2 >> 8) | ($q2 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r3 = (($q3 >> 8) | ($q3 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r4 = (($q4 >> 8) | ($q4 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r5 = (($q5 >> 8) | ($q5 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r6 = (($q6 >> 8) | ($q6 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r7 = (($q7 >> 8) | ($q7 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$this->values[0] = $q7 ^ $r7 ^ $r0 ^ self::rotr16($q0 ^ $r0);
$this->values[1] = $q0 ^ $r0 ^ $q7 ^ $r7 ^ $r1 ^ self::rotr16($q1 ^ $r1);
$this->values[2] = $q1 ^ $r1 ^ $r2 ^ self::rotr16($q2 ^ $r2);
$this->values[3] = $q2 ^ $r2 ^ $q7 ^ $r7 ^ $r3 ^ self::rotr16($q3 ^ $r3);
$this->values[4] = $q3 ^ $r3 ^ $q7 ^ $r7 ^ $r4 ^ self::rotr16($q4 ^ $r4);
$this->values[5] = $q4 ^ $r4 ^ $r5 ^ self::rotr16($q5 ^ $r5);
$this->values[6] = $q5 ^ $r5 ^ $r6 ^ self::rotr16($q6 ^ $r6);
$this->values[7] = $q6 ^ $r6 ^ $r7 ^ self::rotr16($q7 ^ $r7);
return $this;
}
/**
* @return self
*/
public function inverseMixColumns()
{
$q0 = $this->values[0];
$q1 = $this->values[1];
$q2 = $this->values[2];
$q3 = $this->values[3];
$q4 = $this->values[4];
$q5 = $this->values[5];
$q6 = $this->values[6];
$q7 = $this->values[7];
$r0 = (($q0 >> 8) | ($q0 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r1 = (($q1 >> 8) | ($q1 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r2 = (($q2 >> 8) | ($q2 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r3 = (($q3 >> 8) | ($q3 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r4 = (($q4 >> 8) | ($q4 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r5 = (($q5 >> 8) | ($q5 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r6 = (($q6 >> 8) | ($q6 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$r7 = (($q7 >> 8) | ($q7 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$this->values[0] = $q5 ^ $q6 ^ $q7 ^ $r0 ^ $r5 ^ $r7 ^ self::rotr16($q0 ^ $q5 ^ $q6 ^ $r0 ^ $r5);
$this->values[1] = $q0 ^ $q5 ^ $r0 ^ $r1 ^ $r5 ^ $r6 ^ $r7 ^ self::rotr16($q1 ^ $q5 ^ $q7 ^ $r1 ^ $r5 ^ $r6);
$this->values[2] = $q0 ^ $q1 ^ $q6 ^ $r1 ^ $r2 ^ $r6 ^ $r7 ^ self::rotr16($q0 ^ $q2 ^ $q6 ^ $r2 ^ $r6 ^ $r7);
$this->values[3] = $q0 ^ $q1 ^ $q2 ^ $q5 ^ $q6 ^ $r0 ^ $r2 ^ $r3 ^ $r5 ^ self::rotr16($q0 ^ $q1 ^ $q3 ^ $q5 ^ $q6 ^ $q7 ^ $r0 ^ $r3 ^ $r5 ^ $r7);
$this->values[4] = $q1 ^ $q2 ^ $q3 ^ $q5 ^ $r1 ^ $r3 ^ $r4 ^ $r5 ^ $r6 ^ $r7 ^ self::rotr16($q1 ^ $q2 ^ $q4 ^ $q5 ^ $q7 ^ $r1 ^ $r4 ^ $r5 ^ $r6);
$this->values[5] = $q2 ^ $q3 ^ $q4 ^ $q6 ^ $r2 ^ $r4 ^ $r5 ^ $r6 ^ $r7 ^ self::rotr16($q2 ^ $q3 ^ $q5 ^ $q6 ^ $r2 ^ $r5 ^ $r6 ^ $r7);
$this->values[6] = $q3 ^ $q4 ^ $q5 ^ $q7 ^ $r3 ^ $r5 ^ $r6 ^ $r7 ^ self::rotr16($q3 ^ $q4 ^ $q6 ^ $q7 ^ $r3 ^ $r6 ^ $r7);
$this->values[7] = $q4 ^ $q5 ^ $q6 ^ $r4 ^ $r6 ^ $r7 ^ self::rotr16($q4 ^ $q5 ^ $q7 ^ $r4 ^ $r7);
return $this;
}
/**
* @return self
*/
public function inverseShiftRows()
{
for ($i = 0; $i < 8; ++$i) {
$x = $this->values[$i];
$this->values[$i] = ParagonIE_Sodium_Core_Util::U32_MAX & (
($x & 0x000000FF)
| (($x & 0x00003F00) << 2) | (($x & 0x0000C000) >> 6)
| (($x & 0x000F0000) << 4) | (($x & 0x00F00000) >> 4)
| (($x & 0x03000000) << 6) | (($x & 0xFC000000) >> 2)
);
}
return $this;
}
}

View File

@ -0,0 +1,14 @@
<?php
if (class_exists('ParagonIE_Sodium_Core_AES_Expanded', false)) {
return;
}
/**
* @internal This should only be used by sodium_compat
*/
class ParagonIE_Sodium_Core_AES_Expanded extends ParagonIE_Sodium_Core_AES_KeySchedule
{
/** @var bool $expanded */
protected $expanded = true;
}

View File

@ -0,0 +1,82 @@
<?php
if (class_exists('ParagonIE_Sodium_Core_AES_KeySchedule', false)) {
return;
}
/**
* @internal This should only be used by sodium_compat
*/
class ParagonIE_Sodium_Core_AES_KeySchedule
{
/** @var array<int, int> $skey -- has size 120 */
protected $skey;
/** @var bool $expanded */
protected $expanded = false;
/** @var int $numRounds */
private $numRounds;
/**
* @param array $skey
* @param int $numRounds
*/
public function __construct(array $skey, $numRounds = 10)
{
$this->skey = $skey;
$this->numRounds = $numRounds;
}
/**
* Get a value at an arbitrary index. Mostly used for unit testing.
*
* @param int $i
* @return int
*/
public function get($i)
{
return $this->skey[$i];
}
/**
* @return int
*/
public function getNumRounds()
{
return $this->numRounds;
}
/**
* @param int $offset
* @return ParagonIE_Sodium_Core_AES_Block
*/
public function getRoundKey($offset)
{
return ParagonIE_Sodium_Core_AES_Block::fromArray(
array_slice($this->skey, $offset, 8)
);
}
/**
* Return an expanded key schedule
*
* @return ParagonIE_Sodium_Core_AES_Expanded
*/
public function expand()
{
$exp = new ParagonIE_Sodium_Core_AES_Expanded(
array_fill(0, 120, 0),
$this->numRounds
);
$n = ($exp->numRounds + 1) << 2;
for ($u = 0, $v = 0; $u < $n; ++$u, $v += 2) {
$x = $y = $this->skey[$u];
$x &= 0x55555555;
$exp->skey[$v] = ($x | ($x << 1)) & ParagonIE_Sodium_Core_Util::U32_MAX;
$y &= 0xAAAAAAAA;
$exp->skey[$v + 1] = ($y | ($y >> 1)) & ParagonIE_Sodium_Core_Util::U32_MAX;
}
return $exp;
}
}

View File

@ -40,26 +40,38 @@ class ParagonIE_Sodium_Core_Curve25519_Ge_Cached
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $T2d
*/
public function __construct(
ParagonIE_Sodium_Core_Curve25519_Fe $YplusX = null,
ParagonIE_Sodium_Core_Curve25519_Fe $YminusX = null,
ParagonIE_Sodium_Core_Curve25519_Fe $Z = null,
ParagonIE_Sodium_Core_Curve25519_Fe $T2d = null
$YplusX = null,
$YminusX = null,
$Z = null,
$T2d = null
) {
if ($YplusX === null) {
$YplusX = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($YplusX instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->YplusX = $YplusX;
if ($YminusX === null) {
$YminusX = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($YminusX instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->YminusX = $YminusX;
if ($Z === null) {
$Z = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($Z instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->Z = $Z;
if ($T2d === null) {
$T2d = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($T2d instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 4 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->T2d = $T2d;
}
}

View File

@ -39,26 +39,38 @@ class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $t
*/
public function __construct(
ParagonIE_Sodium_Core_Curve25519_Fe $x = null,
ParagonIE_Sodium_Core_Curve25519_Fe $y = null,
ParagonIE_Sodium_Core_Curve25519_Fe $z = null,
ParagonIE_Sodium_Core_Curve25519_Fe $t = null
$x = null,
$y = null,
$z = null,
$t = null
) {
if ($x === null) {
$x = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($x instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->X = $x;
if ($y === null) {
$y = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($y instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->Y = $y;
if ($z === null) {
$z = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($z instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->Z = $z;
if ($t === null) {
$t = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($t instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 4 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->T = $t;
}
}

View File

@ -34,21 +34,30 @@ class ParagonIE_Sodium_Core_Curve25519_Ge_P2
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z
*/
public function __construct(
ParagonIE_Sodium_Core_Curve25519_Fe $x = null,
ParagonIE_Sodium_Core_Curve25519_Fe $y = null,
ParagonIE_Sodium_Core_Curve25519_Fe $z = null
$x = null,
$y = null,
$z = null
) {
if ($x === null) {
$x = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($x instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->X = $x;
if ($y === null) {
$y = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($y instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->Y = $y;
if ($z === null) {
$z = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($z instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->Z = $z;
}
}

View File

@ -40,26 +40,38 @@ class ParagonIE_Sodium_Core_Curve25519_Ge_P3
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $t
*/
public function __construct(
ParagonIE_Sodium_Core_Curve25519_Fe $x = null,
ParagonIE_Sodium_Core_Curve25519_Fe $y = null,
ParagonIE_Sodium_Core_Curve25519_Fe $z = null,
ParagonIE_Sodium_Core_Curve25519_Fe $t = null
$x = null,
$y = null,
$z = null,
$t = null
) {
if ($x === null) {
$x = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($x instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->X = $x;
if ($y === null) {
$y = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($y instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->Y = $y;
if ($z === null) {
$z = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($z instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->Z = $z;
if ($t === null) {
$t = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($t instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 4 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->T = $t;
}
}

View File

@ -34,21 +34,30 @@ class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
* @param ParagonIE_Sodium_Core_Curve25519_Fe $xy2d
*/
public function __construct(
ParagonIE_Sodium_Core_Curve25519_Fe $yplusx = null,
ParagonIE_Sodium_Core_Curve25519_Fe $yminusx = null,
ParagonIE_Sodium_Core_Curve25519_Fe $xy2d = null
$yplusx = null,
$yminusx = null,
$xy2d = null
) {
if ($yplusx === null) {
$yplusx = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($yplusx instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->yplusx = $yplusx;
if ($yminusx === null) {
$yminusx = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($yminusx instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->yminusx = $yminusx;
if ($xy2d === null) {
$xy2d = new ParagonIE_Sodium_Core_Curve25519_Fe();
}
if (!($xy2d instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) {
throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe');
}
$this->xy2d = $xy2d;
}
}

View File

@ -210,43 +210,43 @@ class ParagonIE_Sodium_Core_Poly1305_State extends ParagonIE_Sodium_Core_Util
/* h *= r */
$d0 = (
self::mul($h0, $r0, 25) +
self::mul($s4, $h1, 26) +
self::mul($s3, $h2, 26) +
self::mul($s2, $h3, 26) +
self::mul($s1, $h4, 26)
self::mul($h0, $r0, 27) +
self::mul($s4, $h1, 27) +
self::mul($s3, $h2, 27) +
self::mul($s2, $h3, 27) +
self::mul($s1, $h4, 27)
);
$d1 = (
self::mul($h0, $r1, 25) +
self::mul($h1, $r0, 25) +
self::mul($s4, $h2, 26) +
self::mul($s3, $h3, 26) +
self::mul($s2, $h4, 26)
self::mul($h0, $r1, 27) +
self::mul($h1, $r0, 27) +
self::mul($s4, $h2, 27) +
self::mul($s3, $h3, 27) +
self::mul($s2, $h4, 27)
);
$d2 = (
self::mul($h0, $r2, 25) +
self::mul($h1, $r1, 25) +
self::mul($h2, $r0, 25) +
self::mul($s4, $h3, 26) +
self::mul($s3, $h4, 26)
self::mul($h0, $r2, 27) +
self::mul($h1, $r1, 27) +
self::mul($h2, $r0, 27) +
self::mul($s4, $h3, 27) +
self::mul($s3, $h4, 27)
);
$d3 = (
self::mul($h0, $r3, 25) +
self::mul($h1, $r2, 25) +
self::mul($h2, $r1, 25) +
self::mul($h3, $r0, 25) +
self::mul($s4, $h4, 26)
self::mul($h0, $r3, 27) +
self::mul($h1, $r2, 27) +
self::mul($h2, $r1, 27) +
self::mul($h3, $r0, 27) +
self::mul($s4, $h4, 27)
);
$d4 = (
self::mul($h0, $r4, 25) +
self::mul($h1, $r3, 25) +
self::mul($h2, $r2, 25) +
self::mul($h3, $r1, 25) +
self::mul($h4, $r0, 25)
self::mul($h0, $r4, 27) +
self::mul($h1, $r3, 27) +
self::mul($h2, $r2, 27) +
self::mul($h3, $r1, 27) +
self::mul($h4, $r0, 27)
);
/* (partial) h %= p */

View File

@ -9,6 +9,8 @@ if (class_exists('ParagonIE_Sodium_Core_Util', false)) {
*/
abstract class ParagonIE_Sodium_Core_Util
{
const U32_MAX = 0xFFFFFFFF;
/**
* @param int $integer
* @param int $size (16, 32, 64)
@ -33,6 +35,28 @@ abstract class ParagonIE_Sodium_Core_Util
);
}
/**
* @param string $a
* @param string $b
* @return string
* @throws SodiumException
*/
public static function andStrings($a, $b)
{
/* Type checks: */
if (!is_string($a)) {
throw new TypeError('Argument 1 must be a string');
}
if (!is_string($b)) {
throw new TypeError('Argument 2 must be a string');
}
$len = self::strlen($a);
if (self::strlen($b) !== $len) {
throw new SodiumException('Both strings must be of equal length to combine with bitwise AND');
}
return $a & $b;
}
/**
* Convert a binary string into a hexadecimal string without cache-timing
* leaks

View File

@ -255,39 +255,39 @@ class ParagonIE_Sodium_Core32_Poly1305_State extends ParagonIE_Sodium_Core32_Uti
/* h *= r */
$d0 = $zero
->addInt64($h0->mulInt64($r0, 25))
->addInt64($s4->mulInt64($h1, 26))
->addInt64($s3->mulInt64($h2, 26))
->addInt64($s2->mulInt64($h3, 26))
->addInt64($s1->mulInt64($h4, 26));
->addInt64($h0->mulInt64($r0, 27))
->addInt64($s4->mulInt64($h1, 27))
->addInt64($s3->mulInt64($h2, 27))
->addInt64($s2->mulInt64($h3, 27))
->addInt64($s1->mulInt64($h4, 27));
$d1 = $zero
->addInt64($h0->mulInt64($r1, 25))
->addInt64($h1->mulInt64($r0, 25))
->addInt64($s4->mulInt64($h2, 26))
->addInt64($s3->mulInt64($h3, 26))
->addInt64($s2->mulInt64($h4, 26));
->addInt64($h0->mulInt64($r1, 27))
->addInt64($h1->mulInt64($r0, 27))
->addInt64($s4->mulInt64($h2, 27))
->addInt64($s3->mulInt64($h3, 27))
->addInt64($s2->mulInt64($h4, 27));
$d2 = $zero
->addInt64($h0->mulInt64($r2, 25))
->addInt64($h1->mulInt64($r1, 25))
->addInt64($h2->mulInt64($r0, 25))
->addInt64($s4->mulInt64($h3, 26))
->addInt64($s3->mulInt64($h4, 26));
->addInt64($h0->mulInt64($r2, 27))
->addInt64($h1->mulInt64($r1, 27))
->addInt64($h2->mulInt64($r0, 27))
->addInt64($s4->mulInt64($h3, 27))
->addInt64($s3->mulInt64($h4, 27));
$d3 = $zero
->addInt64($h0->mulInt64($r3, 25))
->addInt64($h1->mulInt64($r2, 25))
->addInt64($h2->mulInt64($r1, 25))
->addInt64($h3->mulInt64($r0, 25))
->addInt64($s4->mulInt64($h4, 26));
->addInt64($h0->mulInt64($r3, 27))
->addInt64($h1->mulInt64($r2, 27))
->addInt64($h2->mulInt64($r1, 27))
->addInt64($h3->mulInt64($r0, 27))
->addInt64($s4->mulInt64($h4, 27));
$d4 = $zero
->addInt64($h0->mulInt64($r4, 25))
->addInt64($h1->mulInt64($r3, 25))
->addInt64($h2->mulInt64($r2, 25))
->addInt64($h3->mulInt64($r1, 25))
->addInt64($h4->mulInt64($r0, 25));
->addInt64($h0->mulInt64($r4, 27))
->addInt64($h1->mulInt64($r3, 27))
->addInt64($h2->mulInt64($r2, 27))
->addInt64($h3->mulInt64($r1, 27))
->addInt64($h4->mulInt64($r0, 27));
/* (partial) h %= p */
$c = $d0->shiftRight(26);

View File

@ -25,8 +25,13 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function box($inputFile, $outputFile, $nonce, $keyPair)
{
public static function box(
$inputFile,
$outputFile,
$nonce,
#[\SensitiveParameter]
$keyPair
) {
/* Type checks: */
if (!is_string($inputFile)) {
throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.');
@ -91,8 +96,13 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function box_open($inputFile, $outputFile, $nonce, $keypair)
{
public static function box_open(
$inputFile,
$outputFile,
$nonce,
#[\SensitiveParameter]
$keypair
) {
/* Type checks: */
if (!is_string($inputFile)) {
throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.');
@ -161,8 +171,12 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function box_seal($inputFile, $outputFile, $publicKey)
{
public static function box_seal(
$inputFile,
$outputFile,
#[\SensitiveParameter]
$publicKey
) {
/* Type checks: */
if (!is_string($inputFile)) {
throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.');
@ -265,8 +279,12 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function box_seal_open($inputFile, $outputFile, $ecdhKeypair)
{
public static function box_seal_open(
$inputFile,
$outputFile,
#[\SensitiveParameter]
$ecdhKeypair
) {
/* Type checks: */
if (!is_string($inputFile)) {
throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.');
@ -350,8 +368,12 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
* @throws TypeError
* @psalm-suppress FailedTypeResolution
*/
public static function generichash($filePath, $key = '', $outputLength = 32)
{
public static function generichash(
$filePath,
#[\SensitiveParameter]
$key = '',
$outputLength = 32
) {
/* Type checks: */
if (!is_string($filePath)) {
throw new TypeError('Argument 1 must be a string, ' . gettype($filePath) . ' given.');
@ -428,8 +450,13 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function secretbox($inputFile, $outputFile, $nonce, $key)
{
public static function secretbox(
$inputFile,
$outputFile,
$nonce,
#[\SensitiveParameter]
$key
) {
/* Type checks: */
if (!is_string($inputFile)) {
throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given..');
@ -493,8 +520,13 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function secretbox_open($inputFile, $outputFile, $nonce, $key)
{
public static function secretbox_open(
$inputFile,
$outputFile,
$nonce,
#[\SensitiveParameter]
$key
) {
/* Type checks: */
if (!is_string($inputFile)) {
throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.');
@ -560,8 +592,11 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
* @throws SodiumException
* @throws TypeError
*/
public static function sign($filePath, $secretKey)
{
public static function sign(
$filePath,
#[\SensitiveParameter]
$secretKey
) {
/* Type checks: */
if (!is_string($filePath)) {
throw new TypeError('Argument 1 must be a string, ' . gettype($filePath) . ' given.');
@ -656,8 +691,11 @@ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util
* @throws TypeError
* @throws Exception
*/
public static function verify($sig, $filePath, $publicKey)
{
public static function verify(
$sig,
$filePath,
$publicKey
) {
/* Type checks: */
if (!is_string($sig)) {
throw new TypeError('Argument 1 must be a string, ' . gettype($sig) . ' given.');