update
This commit is contained in:
@@ -1,30 +1,31 @@
|
||||
<?php
|
||||
/*
|
||||
This file should only ever be loaded on PHP 7+
|
||||
*/
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This file should only ever be loaded on PHP 7+
|
||||
*/
|
||||
if (\PHP_VERSION_ID < 70000) {
|
||||
return;
|
||||
spl_autoload_register(function ($class) {
|
||||
$namespace = 'ParagonIE_Sodium_';
|
||||
// Does the class use the namespace prefix?
|
||||
$len = strlen($namespace);
|
||||
if (strncmp($namespace, $class, $len) !== 0) {
|
||||
// no, move to the next registered autoloader
|
||||
return false;
|
||||
}
|
||||
\spl_autoload_register(function ($class) {
|
||||
$namespace = 'ParagonIE_Sodium_';
|
||||
// Does the class use the namespace prefix?
|
||||
$len = \strlen($namespace);
|
||||
if (\strncmp($namespace, $class, $len) !== 0) {
|
||||
// no, move to the next registered autoloader
|
||||
return \false;
|
||||
}
|
||||
// Get the relative class name
|
||||
$relative_class = \substr($class, $len);
|
||||
// Replace the namespace prefix with the base directory, replace namespace
|
||||
// separators with directory separators in the relative class name, append
|
||||
// with .php
|
||||
$file = \dirname(__FILE__) . '/src/' . \str_replace('_', '/', $relative_class) . '.php';
|
||||
// if the file exists, require it
|
||||
if (\file_exists($file)) {
|
||||
require_once $file;
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
});
|
||||
|
||||
// Get the relative class name
|
||||
$relative_class = substr($class, $len);
|
||||
|
||||
// Replace the namespace prefix with the base directory, replace namespace
|
||||
// separators with directory separators in the relative class name, append
|
||||
// with .php
|
||||
$file = dirname(__FILE__) . '/src/' . str_replace('_', '/', $relative_class) . '.php';
|
||||
// if the file exists, require it
|
||||
if (file_exists($file)) {
|
||||
require_once $file;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -1,68 +1,66 @@
|
||||
{
|
||||
"name": "paragonie\/sodium_compat",
|
||||
"description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists",
|
||||
"keywords": [
|
||||
"PHP",
|
||||
"cryptography",
|
||||
"elliptic curve",
|
||||
"elliptic curve cryptography",
|
||||
"Pure-PHP cryptography",
|
||||
"side-channel resistant",
|
||||
"Curve25519",
|
||||
"X25519",
|
||||
"ECDH",
|
||||
"Elliptic Curve Diffie-Hellman",
|
||||
"Ed25519",
|
||||
"RFC 7748",
|
||||
"RFC 8032",
|
||||
"EdDSA",
|
||||
"Edwards-curve Digital Signature Algorithm",
|
||||
"ChaCha20",
|
||||
"Salsa20",
|
||||
"Xchacha20",
|
||||
"Xsalsa20",
|
||||
"Poly1305",
|
||||
"BLAKE2b",
|
||||
"public-key cryptography",
|
||||
"secret-key cryptography",
|
||||
"AEAD",
|
||||
"Chapoly",
|
||||
"Salpoly",
|
||||
"ChaCha20-Poly1305",
|
||||
"XSalsa20-Poly1305",
|
||||
"XChaCha20-Poly1305",
|
||||
"encryption",
|
||||
"authentication",
|
||||
"libsodium"
|
||||
],
|
||||
"license": "ISC",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com"
|
||||
},
|
||||
{
|
||||
"name": "Frank Denis",
|
||||
"email": "jedisct1@pureftpd.org"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"files": [
|
||||
"autoload.php"
|
||||
]
|
||||
"name": "paragonie/sodium_compat",
|
||||
"description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists",
|
||||
"keywords": [
|
||||
"PHP",
|
||||
"cryptography",
|
||||
"elliptic curve",
|
||||
"elliptic curve cryptography",
|
||||
"Pure-PHP cryptography",
|
||||
"side-channel resistant",
|
||||
"Curve25519",
|
||||
"X25519",
|
||||
"ECDH",
|
||||
"Elliptic Curve Diffie-Hellman",
|
||||
"Ed25519",
|
||||
"RFC 7748",
|
||||
"RFC 8032",
|
||||
"EdDSA",
|
||||
"Edwards-curve Digital Signature Algorithm",
|
||||
"ChaCha20",
|
||||
"Salsa20",
|
||||
"Xchacha20",
|
||||
"Xsalsa20",
|
||||
"Poly1305",
|
||||
"BLAKE2b",
|
||||
"public-key cryptography",
|
||||
"secret-key cryptography",
|
||||
"AEAD",
|
||||
"Chapoly",
|
||||
"Salpoly",
|
||||
"ChaCha20-Poly1305",
|
||||
"XSalsa20-Poly1305",
|
||||
"XChaCha20-Poly1305",
|
||||
"encryption",
|
||||
"authentication",
|
||||
"libsodium"
|
||||
],
|
||||
"license": "ISC",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com"
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8",
|
||||
"paragonie\/random_compat": ">=1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit\/phpunit": "^3|^4|^5|^6|^7|^8|^9"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
|
||||
"ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security."
|
||||
{
|
||||
"name": "Frank Denis",
|
||||
"email": "jedisct1@pureftpd.org"
|
||||
}
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"files": ["autoload.php"]
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8",
|
||||
"paragonie/random_compat": ">=1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
|
||||
"ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Sodium;
|
||||
|
||||
require_once dirname(dirname(__FILE__)) . '/autoload.php';
|
||||
|
||||
use ParagonIE_Sodium_Compat;
|
||||
|
||||
const CRYPTO_AEAD_AES256GCM_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_KEYBYTES;
|
||||
const CRYPTO_AEAD_AES256GCM_NSECBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_NSECBYTES;
|
||||
const CRYPTO_AEAD_AES256GCM_NPUBBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_NPUBBYTES;
|
||||
|
||||
@@ -1,45 +1,48 @@
|
||||
<?php
|
||||
|
||||
require_once dirname(dirname(__FILE__)) . '/autoload.php';
|
||||
|
||||
require_once \dirname(\dirname(__FILE__)) . '/autoload.php';
|
||||
if (\PHP_VERSION_ID < 50300) {
|
||||
return;
|
||||
if (PHP_VERSION_ID < 50300) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This file is just for convenience, to allow developers to reduce verbosity when
|
||||
* they add this project to their libraries.
|
||||
*
|
||||
* Replace this:
|
||||
*
|
||||
* $x = ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_encrypt(...$args);
|
||||
*
|
||||
* with this:
|
||||
*
|
||||
* use ParagonIE\Sodium\Compat;
|
||||
*
|
||||
* $x = Compat::crypto_aead_xchacha20poly1305_encrypt(...$args);
|
||||
*/
|
||||
spl_autoload_register(function ($class) {
|
||||
if ($class[0] === '\\') {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
/*
|
||||
* This file is just for convenience, to allow developers to reduce verbosity when
|
||||
* they add this project to their libraries.
|
||||
*
|
||||
* Replace this:
|
||||
*
|
||||
* $x = ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_encrypt(...$args);
|
||||
*
|
||||
* with this:
|
||||
*
|
||||
* use ParagonIE\Sodium\Compat;
|
||||
*
|
||||
* $x = Compat::crypto_aead_xchacha20poly1305_encrypt(...$args);
|
||||
*/
|
||||
\spl_autoload_register(function ($class) {
|
||||
if ($class[0] === '\\') {
|
||||
$class = \substr($class, 1);
|
||||
}
|
||||
$namespace = 'ParagonIE\Sodium';
|
||||
// Does the class use the namespace prefix?
|
||||
$len = \strlen($namespace);
|
||||
if (\strncmp($namespace, $class, $len) !== 0) {
|
||||
// no, move to the next registered autoloader
|
||||
return \false;
|
||||
}
|
||||
// Get the relative class name
|
||||
$relative_class = \substr($class, $len);
|
||||
// Replace the namespace prefix with the base directory, replace namespace
|
||||
// separators with directory separators in the relative class name, append
|
||||
// with .php
|
||||
$file = \dirname(\dirname(__FILE__)) . '/namespaced/' . \str_replace('\\', '/', $relative_class) . '.php';
|
||||
// if the file exists, require it
|
||||
if (\file_exists($file)) {
|
||||
require_once $file;
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
});
|
||||
$namespace = 'ParagonIE\\Sodium';
|
||||
// Does the class use the namespace prefix?
|
||||
$len = strlen($namespace);
|
||||
if (strncmp($namespace, $class, $len) !== 0) {
|
||||
// no, move to the next registered autoloader
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the relative class name
|
||||
$relative_class = substr($class, $len);
|
||||
|
||||
// Replace the namespace prefix with the base directory, replace namespace
|
||||
// separators with directory separators in the relative class name, append
|
||||
// with .php
|
||||
$file = dirname(dirname(__FILE__)) . '/namespaced/' . str_replace('\\', '/', $relative_class) . '.php';
|
||||
// if the file exists, require it
|
||||
if (file_exists($file)) {
|
||||
require_once $file;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,92 +1,92 @@
|
||||
<?php
|
||||
|
||||
const SODIUM_LIBRARY_MAJOR_VERSION = 9;
|
||||
const SODIUM_LIBRARY_MINOR_VERSION = 1;
|
||||
const SODIUM_LIBRARY_VERSION = '1.0.8';
|
||||
|
||||
const SODIUM_LIBRARY_MAJOR_VERSION = 9;
|
||||
const SODIUM_LIBRARY_MINOR_VERSION = 1;
|
||||
const SODIUM_LIBRARY_VERSION = '1.0.8';
|
||||
const SODIUM_BASE64_VARIANT_ORIGINAL = 1;
|
||||
const SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING = 3;
|
||||
const SODIUM_BASE64_VARIANT_URLSAFE = 5;
|
||||
const SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING = 7;
|
||||
const SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES = 0;
|
||||
const SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES = 12;
|
||||
const SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES = 16;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = 0;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = 8;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = 16;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = 0;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = 12;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = 16;
|
||||
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES = 0;
|
||||
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES = 24;
|
||||
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES = 16;
|
||||
const SODIUM_CRYPTO_AUTH_BYTES = 32;
|
||||
const SODIUM_CRYPTO_AUTH_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_BOX_SEALBYTES = 16;
|
||||
const SODIUM_CRYPTO_BOX_SECRETKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_BOX_PUBLICKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_BOX_KEYPAIRBYTES = 64;
|
||||
const SODIUM_CRYPTO_BOX_MACBYTES = 16;
|
||||
const SODIUM_CRYPTO_BOX_NONCEBYTES = 24;
|
||||
const SODIUM_CRYPTO_BOX_SEEDBYTES = 32;
|
||||
const SODIUM_CRYPTO_KDF_BYTES_MIN = 16;
|
||||
const SODIUM_CRYPTO_KDF_BYTES_MAX = 64;
|
||||
const SODIUM_CRYPTO_KDF_CONTEXTBYTES = 8;
|
||||
const SODIUM_CRYPTO_KDF_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_BYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_PRIMITIVE = 'x25519blake2b';
|
||||
const SODIUM_CRYPTO_KX_SEEDBYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_KEYPAIRBYTES = 64;
|
||||
const SODIUM_CRYPTO_KX_PUBLICKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_SECRETKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_SESSIONKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_GENERICHASH_BYTES = 32;
|
||||
const SODIUM_CRYPTO_GENERICHASH_BYTES_MIN = 16;
|
||||
const SODIUM_CRYPTO_GENERICHASH_BYTES_MAX = 64;
|
||||
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN = 16;
|
||||
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX = 64;
|
||||
const SODIUM_CRYPTO_PWHASH_SALTBYTES = 16;
|
||||
const SODIUM_CRYPTO_PWHASH_STRPREFIX = '$argon2id$';
|
||||
const SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13 = 1;
|
||||
const SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13 = 2;
|
||||
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE = 33554432;
|
||||
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE = 4;
|
||||
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE = 134217728;
|
||||
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE = 6;
|
||||
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE = 536870912;
|
||||
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE = 8;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES = 32;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX = '$7$';
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE = 534288;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824;
|
||||
const SODIUM_CRYPTO_SCALARMULT_BYTES = 32;
|
||||
const SODIUM_CRYPTO_SCALARMULT_SCALARBYTES = 32;
|
||||
const SODIUM_CRYPTO_SHORTHASH_BYTES = 8;
|
||||
const SODIUM_CRYPTO_SHORTHASH_KEYBYTES = 16;
|
||||
const SODIUM_CRYPTO_SECRETBOX_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_SECRETBOX_MACBYTES = 16;
|
||||
const SODIUM_CRYPTO_SECRETBOX_NONCEBYTES = 24;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80;
|
||||
const SODIUM_CRYPTO_SIGN_BYTES = 64;
|
||||
const SODIUM_CRYPTO_SIGN_SEEDBYTES = 32;
|
||||
const SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_SIGN_SECRETKEYBYTES = 64;
|
||||
const SODIUM_CRYPTO_SIGN_KEYPAIRBYTES = 96;
|
||||
const SODIUM_CRYPTO_STREAM_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_STREAM_NONCEBYTES = 24;
|
||||
const SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES = 24;
|
||||
const SODIUM_BASE64_VARIANT_ORIGINAL = 1;
|
||||
const SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING = 3;
|
||||
const SODIUM_BASE64_VARIANT_URLSAFE = 5;
|
||||
const SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING = 7;
|
||||
const SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES = 0;
|
||||
const SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES = 12;
|
||||
const SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES = 16;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = 0;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = 8;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = 16;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = 0;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = 12;
|
||||
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = 16;
|
||||
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES = 0;
|
||||
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES = 24;
|
||||
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES = 16;
|
||||
const SODIUM_CRYPTO_AUTH_BYTES = 32;
|
||||
const SODIUM_CRYPTO_AUTH_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_BOX_SEALBYTES = 16;
|
||||
const SODIUM_CRYPTO_BOX_SECRETKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_BOX_PUBLICKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_BOX_KEYPAIRBYTES = 64;
|
||||
const SODIUM_CRYPTO_BOX_MACBYTES = 16;
|
||||
const SODIUM_CRYPTO_BOX_NONCEBYTES = 24;
|
||||
const SODIUM_CRYPTO_BOX_SEEDBYTES = 32;
|
||||
const SODIUM_CRYPTO_KDF_BYTES_MIN = 16;
|
||||
const SODIUM_CRYPTO_KDF_BYTES_MAX = 64;
|
||||
const SODIUM_CRYPTO_KDF_CONTEXTBYTES = 8;
|
||||
const SODIUM_CRYPTO_KDF_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_BYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_PRIMITIVE = 'x25519blake2b';
|
||||
const SODIUM_CRYPTO_KX_SEEDBYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_KEYPAIRBYTES = 64;
|
||||
const SODIUM_CRYPTO_KX_PUBLICKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_SECRETKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_KX_SESSIONKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_GENERICHASH_BYTES = 32;
|
||||
const SODIUM_CRYPTO_GENERICHASH_BYTES_MIN = 16;
|
||||
const SODIUM_CRYPTO_GENERICHASH_BYTES_MAX = 64;
|
||||
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN = 16;
|
||||
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX = 64;
|
||||
const SODIUM_CRYPTO_PWHASH_SALTBYTES = 16;
|
||||
const SODIUM_CRYPTO_PWHASH_STRPREFIX = '$argon2id$';
|
||||
const SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13 = 1;
|
||||
const SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13 = 2;
|
||||
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE = 33554432;
|
||||
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE = 4;
|
||||
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE = 134217728;
|
||||
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE = 6;
|
||||
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE = 536870912;
|
||||
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE = 8;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES = 32;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX = '$7$';
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE = 534288;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432;
|
||||
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824;
|
||||
const SODIUM_CRYPTO_SCALARMULT_BYTES = 32;
|
||||
const SODIUM_CRYPTO_SCALARMULT_SCALARBYTES = 32;
|
||||
const SODIUM_CRYPTO_SHORTHASH_BYTES = 8;
|
||||
const SODIUM_CRYPTO_SHORTHASH_KEYBYTES = 16;
|
||||
const SODIUM_CRYPTO_SECRETBOX_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_SECRETBOX_MACBYTES = 16;
|
||||
const SODIUM_CRYPTO_SECRETBOX_NONCEBYTES = 24;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3;
|
||||
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80;
|
||||
const SODIUM_CRYPTO_SIGN_BYTES = 64;
|
||||
const SODIUM_CRYPTO_SIGN_SEEDBYTES = 32;
|
||||
const SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_SIGN_SECRETKEYBYTES = 64;
|
||||
const SODIUM_CRYPTO_SIGN_KEYPAIRBYTES = 96;
|
||||
const SODIUM_CRYPTO_STREAM_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_STREAM_NONCEBYTES = 24;
|
||||
const SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES = 32;
|
||||
const SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES = 24;
|
||||
|
||||
@@ -1,104 +1,130 @@
|
||||
<?php
|
||||
|
||||
require_once dirname(dirname(__FILE__)) . '/autoload.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')) {
|
||||
/**
|
||||
* 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.
|
||||
* @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
|
||||
*/
|
||||
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(
|
||||
function sodium_crypto_aead_aegis128l_decrypt(
|
||||
$ciphertext,
|
||||
$additional_data,
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::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]
|
||||
}
|
||||
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,
|
||||
#[\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(
|
||||
}
|
||||
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,
|
||||
#[\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]
|
||||
}
|
||||
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,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt($message, $additional_data, $nonce, $key);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +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_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;
|
||||
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;
|
||||
|
||||
@@ -1,272 +1,277 @@
|
||||
<?php
|
||||
|
||||
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_BYTES
|
||||
);
|
||||
define('SODIUM_COMPAT_POLYFILLED_RISTRETTO255', true);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_HASHBYTES
|
||||
);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_SCALARBYTES
|
||||
);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES
|
||||
);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES
|
||||
);
|
||||
}
|
||||
if (!defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES')) {
|
||||
define(
|
||||
'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES',
|
||||
ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_BYTES
|
||||
);
|
||||
}
|
||||
|
||||
if (!\defined('SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES')) {
|
||||
\define('SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES', \ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_BYTES);
|
||||
\define('SODIUM_COMPAT_POLYFILLED_RISTRETTO255', \true);
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_add')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_add()
|
||||
*
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_add(
|
||||
#[\SensitiveParameter]
|
||||
$p,
|
||||
#[\SensitiveParameter]
|
||||
$q
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_add($p, $q, true);
|
||||
}
|
||||
if (!\defined('SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES')) {
|
||||
\define('SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES', \ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_HASHBYTES);
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_from_hash')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_from_hash()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_from_hash(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_from_hash($s, true);
|
||||
}
|
||||
if (!\defined('SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES')) {
|
||||
\define('SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES', \ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_SCALARBYTES);
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_is_valid_point')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_is_valid_point()
|
||||
*
|
||||
* @param string $s
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_is_valid_point(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_is_valid_point($s, true);
|
||||
}
|
||||
if (!\defined('SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES')) {
|
||||
\define('SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES', \ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES);
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_random')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_random()
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_random()
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_random(true);
|
||||
}
|
||||
if (!\defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES')) {
|
||||
\define('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES', \ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES);
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_add')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_add()
|
||||
*
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_add(
|
||||
#[\SensitiveParameter]
|
||||
$x,
|
||||
#[\SensitiveParameter]
|
||||
$y
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_add($x, $y, true);
|
||||
}
|
||||
if (!\defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES')) {
|
||||
\define('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES', \ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_BYTES);
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_complement')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_complement()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_complement(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_complement($s, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_add')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_add()
|
||||
*
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_add(
|
||||
#[\SensitiveParameter]
|
||||
$p,
|
||||
#[\SensitiveParameter]
|
||||
$q
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_add($p, $q, \true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_invert')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_invert()
|
||||
*
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_invert(
|
||||
#[\SensitiveParameter]
|
||||
$p
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_invert($p, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_from_hash')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_from_hash()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_from_hash(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_from_hash($s, \true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_mul')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_mul()
|
||||
*
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_mul(
|
||||
#[\SensitiveParameter]
|
||||
$x,
|
||||
#[\SensitiveParameter]
|
||||
$y
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_mul($x, $y, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_is_valid_point')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_is_valid_point()
|
||||
*
|
||||
* @param string $s
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_is_valid_point(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_is_valid_point($s, \true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_negate')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_negate()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_negate(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_negate($s, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_random')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_random()
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_random()
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_random(\true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_random')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_random()
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_random()
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_random(true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_scalar_add')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_add()
|
||||
*
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_add(
|
||||
#[\SensitiveParameter]
|
||||
$x,
|
||||
#[\SensitiveParameter]
|
||||
$y
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_scalar_add($x, $y, \true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_reduce')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_reduce()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_reduce(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_reduce($s, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_scalar_complement')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_complement()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_complement(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_scalar_complement($s, \true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_scalar_sub')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_sub()
|
||||
*
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_sub(
|
||||
#[\SensitiveParameter]
|
||||
$x,
|
||||
#[\SensitiveParameter]
|
||||
$y
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_scalar_sub($x, $y, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_scalar_invert')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_invert()
|
||||
*
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_invert(
|
||||
#[\SensitiveParameter]
|
||||
$p
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_scalar_invert($p, \true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_core_ristretto255_sub')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_sub()
|
||||
*
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_sub(
|
||||
#[\SensitiveParameter]
|
||||
$p,
|
||||
#[\SensitiveParameter]
|
||||
$q
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::ristretto255_sub($p, $q, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_scalar_mul')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_mul()
|
||||
*
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_mul(
|
||||
#[\SensitiveParameter]
|
||||
$x,
|
||||
#[\SensitiveParameter]
|
||||
$y
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_scalar_mul($x, $y, \true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_scalarmult_ristretto255')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255()
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_scalarmult_ristretto255(
|
||||
#[\SensitiveParameter]
|
||||
$n,
|
||||
#[\SensitiveParameter]
|
||||
$p
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::scalarmult_ristretto255($n, $p, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_scalar_negate')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_negate()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_negate(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_scalar_negate($s, \true);
|
||||
}
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_scalar_random')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_random()
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_random()
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_scalar_random(\true);
|
||||
}
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_scalar_reduce')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_reduce()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_reduce(
|
||||
#[\SensitiveParameter]
|
||||
$s
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_scalar_reduce($s, \true);
|
||||
}
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_scalar_sub')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_sub()
|
||||
*
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_scalar_sub(
|
||||
#[\SensitiveParameter]
|
||||
$x,
|
||||
#[\SensitiveParameter]
|
||||
$y
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_scalar_sub($x, $y, \true);
|
||||
}
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_core_ristretto255_sub')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::ristretto255_sub()
|
||||
*
|
||||
* @param string $p
|
||||
* @param string $q
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
function sodium_crypto_core_ristretto255_sub(
|
||||
#[\SensitiveParameter]
|
||||
$p,
|
||||
#[\SensitiveParameter]
|
||||
$q
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::ristretto255_sub($p, $q, \true);
|
||||
}
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_scalarmult_ristretto255')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255()
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_scalarmult_ristretto255(
|
||||
#[\SensitiveParameter]
|
||||
$n,
|
||||
#[\SensitiveParameter]
|
||||
$p
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::scalarmult_ristretto255($n, $p, \true);
|
||||
}
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_scalarmult_ristretto255_base')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255_base()
|
||||
* @param string $n
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_scalarmult_ristretto255_base(
|
||||
#[\SensitiveParameter]
|
||||
$n
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::scalarmult_ristretto255_base($n, \true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_scalarmult_ristretto255_base')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255_base()
|
||||
* @param string $n
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_scalarmult_ristretto255_base(
|
||||
#[\SensitiveParameter]
|
||||
$n
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::scalarmult_ristretto255_base($n, true);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Sodium;
|
||||
|
||||
require_once dirname(dirname(__FILE__)) . '/autoload.php';
|
||||
|
||||
use ParagonIE_Sodium_Compat;
|
||||
|
||||
/**
|
||||
* This file will monkey patch the pure-PHP implementation in place of the
|
||||
* PECL functions, but only if they do not already exist.
|
||||
@@ -11,7 +12,7 @@ use ParagonIE_Sodium_Compat;
|
||||
* Thus, the functions just proxy to the appropriate ParagonIE_Sodium_Compat
|
||||
* method.
|
||||
*/
|
||||
if (!is_callable('\Sodium\bin2hex')) {
|
||||
if (!is_callable('\\Sodium\\bin2hex')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::bin2hex()
|
||||
* @param string $string
|
||||
@@ -22,12 +23,11 @@ if (!is_callable('\Sodium\bin2hex')) {
|
||||
function bin2hex(
|
||||
#[\SensitiveParameter]
|
||||
$string
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::bin2hex($string);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\compare')) {
|
||||
if (!is_callable('\\Sodium\\compare')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::compare()
|
||||
* @param string $a
|
||||
@@ -41,12 +41,11 @@ if (!is_callable('\Sodium\compare')) {
|
||||
$a,
|
||||
#[\SensitiveParameter]
|
||||
$b
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::compare($a, $b);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_aead_aes256gcm_decrypt')) {
|
||||
if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_decrypt')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt()
|
||||
* @param string $message
|
||||
@@ -61,18 +60,17 @@ if (!is_callable('\Sodium\crypto_aead_aes256gcm_decrypt')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
try {
|
||||
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key);
|
||||
} catch (\TypeError $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
} catch (\SodiumException $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_aead_aes256gcm_encrypt')) {
|
||||
if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_encrypt')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt()
|
||||
* @param string $message
|
||||
@@ -90,12 +88,11 @@ if (!is_callable('\Sodium\crypto_aead_aes256gcm_encrypt')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt($message, $assocData, $nonce, $key);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_aead_aes256gcm_is_available')) {
|
||||
if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_is_available')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_is_available()
|
||||
* @return bool
|
||||
@@ -105,7 +102,7 @@ if (!is_callable('\Sodium\crypto_aead_aes256gcm_is_available')) {
|
||||
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_is_available();
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_aead_chacha20poly1305_decrypt')) {
|
||||
if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_decrypt')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt()
|
||||
* @param string $message
|
||||
@@ -120,18 +117,17 @@ if (!is_callable('\Sodium\crypto_aead_chacha20poly1305_decrypt')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
try {
|
||||
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key);
|
||||
} catch (\TypeError $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
} catch (\SodiumException $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_aead_chacha20poly1305_encrypt')) {
|
||||
if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_encrypt')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt()
|
||||
* @param string $message
|
||||
@@ -149,12 +145,11 @@ if (!is_callable('\Sodium\crypto_aead_chacha20poly1305_encrypt')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt($message, $assocData, $nonce, $key);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_aead_chacha20poly1305_ietf_decrypt')) {
|
||||
if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_ietf_decrypt')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt()
|
||||
* @param string $message
|
||||
@@ -169,18 +164,17 @@ if (!is_callable('\Sodium\crypto_aead_chacha20poly1305_ietf_decrypt')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
try {
|
||||
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key);
|
||||
} catch (\TypeError $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
} catch (\SodiumException $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_aead_chacha20poly1305_ietf_encrypt')) {
|
||||
if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_ietf_encrypt')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt()
|
||||
* @param string $message
|
||||
@@ -198,12 +192,11 @@ if (!is_callable('\Sodium\crypto_aead_chacha20poly1305_ietf_encrypt')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_auth')) {
|
||||
if (!is_callable('\\Sodium\\crypto_auth')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_auth()
|
||||
* @param string $message
|
||||
@@ -216,12 +209,11 @@ if (!is_callable('\Sodium\crypto_auth')) {
|
||||
$message,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_auth($message, $key);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_auth_verify')) {
|
||||
if (!is_callable('\\Sodium\\crypto_auth_verify')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_auth_verify()
|
||||
* @param string $mac
|
||||
@@ -236,12 +228,11 @@ if (!is_callable('\Sodium\crypto_auth_verify')) {
|
||||
$message,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_auth_verify($mac, $message, $key);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_box')) {
|
||||
if (!is_callable('\\Sodium\\crypto_box')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_box()
|
||||
* @param string $message
|
||||
@@ -257,12 +248,11 @@ if (!is_callable('\Sodium\crypto_box')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$kp
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_box($message, $nonce, $kp);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_box_keypair')) {
|
||||
if (!is_callable('\\Sodium\\crypto_box_keypair')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_box_keypair()
|
||||
* @return string
|
||||
@@ -274,7 +264,7 @@ if (!is_callable('\Sodium\crypto_box_keypair')) {
|
||||
return ParagonIE_Sodium_Compat::crypto_box_keypair();
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_box_keypair_from_secretkey_and_publickey')) {
|
||||
if (!is_callable('\\Sodium\\crypto_box_keypair_from_secretkey_and_publickey')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey()
|
||||
* @param string $sk
|
||||
@@ -287,12 +277,11 @@ if (!is_callable('\Sodium\crypto_box_keypair_from_secretkey_and_publickey')) {
|
||||
#[\SensitiveParameter]
|
||||
$sk,
|
||||
$pk
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($sk, $pk);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_box_open')) {
|
||||
if (!is_callable('\\Sodium\\crypto_box_open')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_box_open()
|
||||
* @param string $message
|
||||
@@ -306,18 +295,17 @@ if (!is_callable('\Sodium\crypto_box_open')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$kp
|
||||
)
|
||||
{
|
||||
) {
|
||||
try {
|
||||
return ParagonIE_Sodium_Compat::crypto_box_open($message, $nonce, $kp);
|
||||
} catch (\TypeError $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
} catch (\SodiumException $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_box_publickey')) {
|
||||
if (!is_callable('\\Sodium\\crypto_box_publickey')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_box_publickey()
|
||||
* @param string $keypair
|
||||
@@ -328,12 +316,11 @@ if (!is_callable('\Sodium\crypto_box_publickey')) {
|
||||
function crypto_box_publickey(
|
||||
#[\SensitiveParameter]
|
||||
$keypair
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_box_publickey($keypair);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_box_publickey_from_secretkey')) {
|
||||
if (!is_callable('\\Sodium\\crypto_box_publickey_from_secretkey')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey()
|
||||
* @param string $sk
|
||||
@@ -344,12 +331,11 @@ if (!is_callable('\Sodium\crypto_box_publickey_from_secretkey')) {
|
||||
function crypto_box_publickey_from_secretkey(
|
||||
#[\SensitiveParameter]
|
||||
$sk
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey($sk);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_box_seal')) {
|
||||
if (!is_callable('\\Sodium\\crypto_box_seal')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_box_seal_open()
|
||||
* @param string $message
|
||||
@@ -362,12 +348,11 @@ if (!is_callable('\Sodium\crypto_box_seal')) {
|
||||
#[\SensitiveParameter]
|
||||
$message,
|
||||
$publicKey
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_box_seal($message, $publicKey);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_box_seal_open')) {
|
||||
if (!is_callable('\\Sodium\\crypto_box_seal_open')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_box_seal_open()
|
||||
* @param string $message
|
||||
@@ -378,18 +363,17 @@ if (!is_callable('\Sodium\crypto_box_seal_open')) {
|
||||
$message,
|
||||
#[\SensitiveParameter]
|
||||
$kp
|
||||
)
|
||||
{
|
||||
) {
|
||||
try {
|
||||
return ParagonIE_Sodium_Compat::crypto_box_seal_open($message, $kp);
|
||||
} catch (\TypeError $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
} catch (\SodiumException $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_box_secretkey')) {
|
||||
if (!is_callable('\\Sodium\\crypto_box_secretkey')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_box_secretkey()
|
||||
* @param string $keypair
|
||||
@@ -400,12 +384,11 @@ if (!is_callable('\Sodium\crypto_box_secretkey')) {
|
||||
function crypto_box_secretkey(
|
||||
#[\SensitiveParameter]
|
||||
$keypair
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_box_secretkey($keypair);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_generichash')) {
|
||||
if (!is_callable('\\Sodium\\crypto_generichash')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_generichash()
|
||||
* @param string $message
|
||||
@@ -420,12 +403,11 @@ if (!is_callable('\Sodium\crypto_generichash')) {
|
||||
#[\SensitiveParameter]
|
||||
$key = null,
|
||||
$outLen = 32
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_generichash($message, $key, $outLen);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_generichash_final')) {
|
||||
if (!is_callable('\\Sodium\\crypto_generichash_final')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_generichash_final()
|
||||
* @param string|null $ctx
|
||||
@@ -438,12 +420,11 @@ if (!is_callable('\Sodium\crypto_generichash_final')) {
|
||||
#[\SensitiveParameter]
|
||||
&$ctx,
|
||||
$outputLength = 32
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_generichash_final($ctx, $outputLength);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_generichash_init')) {
|
||||
if (!is_callable('\\Sodium\\crypto_generichash_init')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_generichash_init()
|
||||
* @param string|null $key
|
||||
@@ -456,12 +437,11 @@ if (!is_callable('\Sodium\crypto_generichash_init')) {
|
||||
#[\SensitiveParameter]
|
||||
$key = null,
|
||||
$outLen = 32
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_generichash_init($key, $outLen);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_generichash_update')) {
|
||||
if (!is_callable('\\Sodium\\crypto_generichash_update')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_generichash_update()
|
||||
* @param string|null $ctx
|
||||
@@ -474,12 +454,11 @@ if (!is_callable('\Sodium\crypto_generichash_update')) {
|
||||
#[\SensitiveParameter]
|
||||
&$ctx,
|
||||
$message = ''
|
||||
)
|
||||
{
|
||||
) {
|
||||
ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $message);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_kx')) {
|
||||
if (!is_callable('\\Sodium\\crypto_kx')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_kx()
|
||||
* @param string $my_secret
|
||||
@@ -496,12 +475,17 @@ if (!is_callable('\Sodium\crypto_kx')) {
|
||||
$their_public,
|
||||
$client_public,
|
||||
$server_public
|
||||
)
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::crypto_kx($my_secret, $their_public, $client_public, $server_public, \true);
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_kx(
|
||||
$my_secret,
|
||||
$their_public,
|
||||
$client_public,
|
||||
$server_public,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_pwhash')) {
|
||||
if (!is_callable('\\Sodium\\crypto_pwhash')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_pwhash()
|
||||
* @param int $outlen
|
||||
@@ -520,12 +504,11 @@ if (!is_callable('\Sodium\crypto_pwhash')) {
|
||||
$salt,
|
||||
$opslimit,
|
||||
$memlimit
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_pwhash($outlen, $passwd, $salt, $opslimit, $memlimit);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_pwhash_str')) {
|
||||
if (!is_callable('\\Sodium\\crypto_pwhash_str')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_pwhash_str()
|
||||
* @param string $passwd
|
||||
@@ -540,12 +523,11 @@ if (!is_callable('\Sodium\crypto_pwhash_str')) {
|
||||
$passwd,
|
||||
$opslimit,
|
||||
$memlimit
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_pwhash_str($passwd, $opslimit, $memlimit);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_pwhash_str_verify')) {
|
||||
if (!is_callable('\\Sodium\\crypto_pwhash_str_verify')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_pwhash_str_verify()
|
||||
* @param string $passwd
|
||||
@@ -559,12 +541,11 @@ if (!is_callable('\Sodium\crypto_pwhash_str_verify')) {
|
||||
$passwd,
|
||||
#[\SensitiveParameter]
|
||||
$hash
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_pwhash_str_verify($passwd, $hash);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_pwhash_scryptsalsa208sha256')) {
|
||||
if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256()
|
||||
* @param int $outlen
|
||||
@@ -584,12 +565,11 @@ if (!is_callable('\Sodium\crypto_pwhash_scryptsalsa208sha256')) {
|
||||
$salt,
|
||||
$opslimit,
|
||||
$memlimit
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256($outlen, $passwd, $salt, $opslimit, $memlimit);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_pwhash_scryptsalsa208sha256_str')) {
|
||||
if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str()
|
||||
* @param string $passwd
|
||||
@@ -604,12 +584,11 @@ if (!is_callable('\Sodium\crypto_pwhash_scryptsalsa208sha256_str')) {
|
||||
$passwd,
|
||||
$opslimit,
|
||||
$memlimit
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str($passwd, $opslimit, $memlimit);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify')) {
|
||||
if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str_verify')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify()
|
||||
* @param string $passwd
|
||||
@@ -623,12 +602,11 @@ if (!is_callable('\Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify')) {
|
||||
$passwd,
|
||||
#[\SensitiveParameter]
|
||||
$hash
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify($passwd, $hash);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_scalarmult')) {
|
||||
if (!is_callable('\\Sodium\\crypto_scalarmult')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_scalarmult()
|
||||
* @param string $n
|
||||
@@ -641,12 +619,11 @@ if (!is_callable('\Sodium\crypto_scalarmult')) {
|
||||
#[\SensitiveParameter]
|
||||
$n,
|
||||
$p
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_scalarmult($n, $p);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_scalarmult_base')) {
|
||||
if (!is_callable('\\Sodium\\crypto_scalarmult_base')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_base()
|
||||
* @param string $n
|
||||
@@ -657,12 +634,11 @@ if (!is_callable('\Sodium\crypto_scalarmult_base')) {
|
||||
function crypto_scalarmult_base(
|
||||
#[\SensitiveParameter]
|
||||
$n
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_scalarmult_base($n);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_secretbox')) {
|
||||
if (!is_callable('\\Sodium\\crypto_secretbox')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_secretbox()
|
||||
* @param string $message
|
||||
@@ -678,12 +654,11 @@ if (!is_callable('\Sodium\crypto_secretbox')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_secretbox($message, $nonce, $key);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_secretbox_open')) {
|
||||
if (!is_callable('\\Sodium\\crypto_secretbox_open')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_secretbox_open()
|
||||
* @param string $message
|
||||
@@ -696,18 +671,17 @@ if (!is_callable('\Sodium\crypto_secretbox_open')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
try {
|
||||
return ParagonIE_Sodium_Compat::crypto_secretbox_open($message, $nonce, $key);
|
||||
} catch (\TypeError $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
} catch (\SodiumException $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_shorthash')) {
|
||||
if (!is_callable('\\Sodium\\crypto_shorthash')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_shorthash()
|
||||
* @param string $message
|
||||
@@ -720,12 +694,11 @@ if (!is_callable('\Sodium\crypto_shorthash')) {
|
||||
$message,
|
||||
#[\SensitiveParameter]
|
||||
$key = ''
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_shorthash($message, $key);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign()
|
||||
* @param string $message
|
||||
@@ -738,12 +711,11 @@ if (!is_callable('\Sodium\crypto_sign')) {
|
||||
$message,
|
||||
#[\SensitiveParameter]
|
||||
$sk
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign($message, $sk);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_detached')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_detached')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_detached()
|
||||
* @param string $message
|
||||
@@ -756,12 +728,11 @@ if (!is_callable('\Sodium\crypto_sign_detached')) {
|
||||
$message,
|
||||
#[\SensitiveParameter]
|
||||
$sk
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_detached($message, $sk);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_keypair')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_keypair')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_keypair()
|
||||
* @return string
|
||||
@@ -773,7 +744,7 @@ if (!is_callable('\Sodium\crypto_sign_keypair')) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_keypair();
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_open')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_open')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_open()
|
||||
* @param string $signedMessage
|
||||
@@ -785,13 +756,13 @@ if (!is_callable('\Sodium\crypto_sign_open')) {
|
||||
try {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_open($signedMessage, $pk);
|
||||
} catch (\TypeError $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
} catch (\SodiumException $ex) {
|
||||
return \false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_publickey')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_publickey')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_publickey()
|
||||
* @param string $keypair
|
||||
@@ -802,12 +773,11 @@ if (!is_callable('\Sodium\crypto_sign_publickey')) {
|
||||
function crypto_sign_publickey(
|
||||
#[\SensitiveParameter]
|
||||
$keypair
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_publickey($keypair);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_publickey_from_secretkey')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_publickey_from_secretkey')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey()
|
||||
* @param string $sk
|
||||
@@ -818,12 +788,11 @@ if (!is_callable('\Sodium\crypto_sign_publickey_from_secretkey')) {
|
||||
function crypto_sign_publickey_from_secretkey(
|
||||
#[\SensitiveParameter]
|
||||
$sk
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey($sk);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_secretkey')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_secretkey')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_secretkey()
|
||||
* @param string $keypair
|
||||
@@ -834,12 +803,11 @@ if (!is_callable('\Sodium\crypto_sign_secretkey')) {
|
||||
function crypto_sign_secretkey(
|
||||
#[\SensitiveParameter]
|
||||
$keypair
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_secretkey($keypair);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_seed_keypair')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_seed_keypair')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_seed_keypair()
|
||||
* @param string $seed
|
||||
@@ -850,12 +818,11 @@ if (!is_callable('\Sodium\crypto_sign_seed_keypair')) {
|
||||
function crypto_sign_seed_keypair(
|
||||
#[\SensitiveParameter]
|
||||
$seed
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_seed_keypair($seed);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_verify_detached')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_verify_detached')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_verify_detached()
|
||||
* @param string $signature
|
||||
@@ -870,7 +837,7 @@ if (!is_callable('\Sodium\crypto_sign_verify_detached')) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_verify_detached($signature, $message, $pk);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_ed25519_pk_to_curve25519')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_ed25519_pk_to_curve25519')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_ed25519_pk_to_curve25519()
|
||||
* @param string $pk
|
||||
@@ -883,7 +850,7 @@ if (!is_callable('\Sodium\crypto_sign_ed25519_pk_to_curve25519')) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_ed25519_pk_to_curve25519($pk);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_sign_ed25519_sk_to_curve25519')) {
|
||||
if (!is_callable('\\Sodium\\crypto_sign_ed25519_sk_to_curve25519')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519()
|
||||
* @param string $sk
|
||||
@@ -894,12 +861,11 @@ if (!is_callable('\Sodium\crypto_sign_ed25519_sk_to_curve25519')) {
|
||||
function crypto_sign_ed25519_sk_to_curve25519(
|
||||
#[\SensitiveParameter]
|
||||
$sk
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519($sk);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_stream')) {
|
||||
if (!is_callable('\\Sodium\\crypto_stream')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream()
|
||||
* @param int $len
|
||||
@@ -914,12 +880,11 @@ if (!is_callable('\Sodium\crypto_stream')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_stream($len, $nonce, $key);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\crypto_stream_xor')) {
|
||||
if (!is_callable('\\Sodium\\crypto_stream_xor')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xor()
|
||||
* @param string $message
|
||||
@@ -935,12 +900,11 @@ if (!is_callable('\Sodium\crypto_stream_xor')) {
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\hex2bin')) {
|
||||
if (!is_callable('\\Sodium\\hex2bin')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::hex2bin()
|
||||
* @param string $string
|
||||
@@ -951,12 +915,11 @@ if (!is_callable('\Sodium\hex2bin')) {
|
||||
function hex2bin(
|
||||
#[\SensitiveParameter]
|
||||
$string
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::hex2bin($string);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\memcmp')) {
|
||||
if (!is_callable('\\Sodium\\memcmp')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::memcmp()
|
||||
* @param string $a
|
||||
@@ -970,12 +933,11 @@ if (!is_callable('\Sodium\memcmp')) {
|
||||
$a,
|
||||
#[\SensitiveParameter]
|
||||
$b
|
||||
)
|
||||
{
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::memcmp($a, $b);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\memzero')) {
|
||||
if (!is_callable('\\Sodium\\memzero')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::memzero()
|
||||
* @param string $str
|
||||
@@ -990,12 +952,11 @@ if (!is_callable('\Sodium\memzero')) {
|
||||
function memzero(
|
||||
#[\SensitiveParameter]
|
||||
&$str
|
||||
)
|
||||
{
|
||||
) {
|
||||
ParagonIE_Sodium_Compat::memzero($str);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\randombytes_buf')) {
|
||||
if (!is_callable('\\Sodium\\randombytes_buf')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::randombytes_buf()
|
||||
* @param int $amount
|
||||
@@ -1007,7 +968,8 @@ if (!is_callable('\Sodium\randombytes_buf')) {
|
||||
return ParagonIE_Sodium_Compat::randombytes_buf($amount);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\randombytes_uniform')) {
|
||||
|
||||
if (!is_callable('\\Sodium\\randombytes_uniform')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::randombytes_uniform()
|
||||
* @param int $upperLimit
|
||||
@@ -1020,7 +982,8 @@ if (!is_callable('\Sodium\randombytes_uniform')) {
|
||||
return ParagonIE_Sodium_Compat::randombytes_uniform($upperLimit);
|
||||
}
|
||||
}
|
||||
if (!is_callable('\Sodium\randombytes_random16')) {
|
||||
|
||||
if (!is_callable('\\Sodium\\randombytes_random16')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::randombytes_random16()
|
||||
* @return int
|
||||
@@ -1030,6 +993,7 @@ if (!is_callable('\Sodium\randombytes_random16')) {
|
||||
return ParagonIE_Sodium_Compat::randombytes_random16();
|
||||
}
|
||||
}
|
||||
if (!defined('\Sodium\CRYPTO_AUTH_BYTES')) {
|
||||
|
||||
if (!defined('\\Sodium\\CRYPTO_AUTH_BYTES')) {
|
||||
require_once dirname(__FILE__) . '/constants.php';
|
||||
}
|
||||
|
||||
@@ -1,78 +1,74 @@
|
||||
<?php
|
||||
|
||||
|
||||
if (!\is_callable('sodium_crypto_stream_xchacha20')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20()
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_stream_xchacha20(
|
||||
$len,
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::crypto_stream_xchacha20($len, $nonce, $key, \true);
|
||||
}
|
||||
if (!is_callable('sodium_crypto_stream_xchacha20')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20()
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_stream_xchacha20(
|
||||
$len,
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20($len, $nonce, $key, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_stream_xchacha20_keygen')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen()
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
function sodium_crypto_stream_xchacha20_keygen()
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen();
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_stream_xchacha20_keygen')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen()
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
function sodium_crypto_stream_xchacha20_keygen()
|
||||
{
|
||||
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen();
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_stream_xchacha20_xor')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor()
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_stream_xchacha20_xor(
|
||||
#[\SensitiveParameter]
|
||||
$message,
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
)
|
||||
{
|
||||
return \ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor($message, $nonce, $key, \true);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_stream_xchacha20_xor')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor()
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
function sodium_crypto_stream_xchacha20_xor(
|
||||
#[\SensitiveParameter]
|
||||
$message,
|
||||
$nonce,
|
||||
#[\SensitiveParameter]
|
||||
$key
|
||||
) {
|
||||
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor($message, $nonce, $key, true);
|
||||
}
|
||||
if (!\is_callable('sodium_crypto_stream_xchacha20_xor_ic')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor_ic()
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param int $counter
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (!is_callable('sodium_crypto_stream_xchacha20_xor_ic')) {
|
||||
/**
|
||||
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor_ic()
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param int $counter
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium;
|
||||
|
||||
class Compat extends \ParagonIE_Sodium_Compat
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class BLAKE2b extends \ParagonIE_Sodium_Core_BLAKE2b
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class ChaCha20 extends \ParagonIE_Sodium_Core_ChaCha20
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\ChaCha20;
|
||||
|
||||
class Ctx extends \ParagonIE_Sodium_Core_ChaCha20_Ctx
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\ChaCha20;
|
||||
|
||||
class IetfCtx extends \ParagonIE_Sodium_Core_ChaCha20_IetfCtx
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class Curve25519 extends \ParagonIE_Sodium_Core_Curve25519
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\Curve25519;
|
||||
|
||||
class Fe extends \ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
|
||||
|
||||
class Cached extends \ParagonIE_Sodium_Core_Curve25519_Ge_Cached
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
|
||||
|
||||
class P1p1 extends \ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
|
||||
|
||||
class P2 extends \ParagonIE_Sodium_Core_Curve25519_Ge_P2
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
|
||||
|
||||
class P3 extends \ParagonIE_Sodium_Core_Curve25519_Ge_P3
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
|
||||
|
||||
class Precomp extends \ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\Curve25519;
|
||||
|
||||
class H extends \ParagonIE_Sodium_Core_Curve25519_H
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class Ed25519 extends \ParagonIE_Sodium_Core_Ed25519
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class HChaCha20 extends \ParagonIE_Sodium_Core_HChaCha20
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class HSalsa20 extends \ParagonIE_Sodium_Core_HSalsa20
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class Poly1305 extends \ParagonIE_Sodium_Core_Poly1305
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core\Poly1305;
|
||||
|
||||
class State extends \ParagonIE_Sodium_Core_Poly1305_State
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class Salsa20 extends \ParagonIE_Sodium_Core_Salsa20
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class SipHash extends \ParagonIE_Sodium_Core_SipHash
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class Util extends \ParagonIE_Sodium_Core_Util
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class X25519 extends \ParagonIE_Sodium_Core_X25519
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class XChaCha20 extends \ParagonIE_Sodium_Core_XChaCha20
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium\Core;
|
||||
|
||||
class Xsalsa20 extends \ParagonIE_Sodium_Core_XSalsa20
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium;
|
||||
|
||||
class Crypto extends \ParagonIE_Sodium_Crypto
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ParagonIE\Sodium;
|
||||
|
||||
class File extends \ParagonIE_Sodium_File
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,229 +1,284 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_AEGIS_State128L', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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\r\x15\"7Y\x90\xe9yb");
|
||||
}
|
||||
if (!\defined('SODIUM_COMPAT_AEGIS_C1')) {
|
||||
\define('SODIUM_COMPAT_AEGIS_C1', "\xdb=\x18Um\xc2/\xf1 \x111Bs\xb5(\xdd");
|
||||
}
|
||||
class ParagonIE_Sodium_Core_AEGIS_State128L
|
||||
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()
|
||||
{
|
||||
/** @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, "\x00", \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, "\x00", \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;
|
||||
}
|
||||
$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;
|
||||
}
|
||||
}
|
||||
@@ -1,200 +1,240 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_AEGIS_State256', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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\r\x15\"7Y\x90\xe9yb");
|
||||
}
|
||||
if (!\defined('SODIUM_COMPAT_AEGIS_C1')) {
|
||||
\define('SODIUM_COMPAT_AEGIS_C1', "\xdb=\x18Um\xc2/\xf1 \x111Bs\xb5(\xdd");
|
||||
}
|
||||
class ParagonIE_Sodium_Core_AEGIS_State256
|
||||
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()
|
||||
{
|
||||
/** @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, "\x00", \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, "\x00", \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;
|
||||
}
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,107 +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");
|
||||
}
|
||||
|
||||
if (!\defined('SODIUM_COMPAT_AEGIS_C0')) {
|
||||
\define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\r\x15\"7Y\x90\xe9yb");
|
||||
}
|
||||
if (!\defined('SODIUM_COMPAT_AEGIS_C1')) {
|
||||
\define('SODIUM_COMPAT_AEGIS_C1', "\xdb=\x18Um\xc2/\xf1 \x111Bs\xb5(\xdd");
|
||||
}
|
||||
class ParagonIE_Sodium_Core_AEGIS128L extends \ParagonIE_Sodium_Core_AES
|
||||
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)
|
||||
{
|
||||
/**
|
||||
* @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, "\x00", \STR_PAD_RIGHT);
|
||||
}
|
||||
$state->absorb($ai);
|
||||
$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);
|
||||
}
|
||||
$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;
|
||||
$state->absorb($ai);
|
||||
}
|
||||
/**
|
||||
* @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, "\x00", \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, "\x00", \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);
|
||||
|
||||
$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));
|
||||
}
|
||||
/**
|
||||
* @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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,104 +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");
|
||||
}
|
||||
|
||||
if (!\defined('SODIUM_COMPAT_AEGIS_C0')) {
|
||||
\define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\r\x15\"7Y\x90\xe9yb");
|
||||
}
|
||||
if (!\defined('SODIUM_COMPAT_AEGIS_C1')) {
|
||||
\define('SODIUM_COMPAT_AEGIS_C1', "\xdb=\x18Um\xc2/\xf1 \x111Bs\xb5(\xdd");
|
||||
}
|
||||
class ParagonIE_Sodium_Core_AEGIS256 extends \ParagonIE_Sodium_Core_AES
|
||||
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)
|
||||
{
|
||||
/**
|
||||
* @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, "\x00", \STR_PAD_RIGHT);
|
||||
}
|
||||
$state->absorb($ai);
|
||||
$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);
|
||||
}
|
||||
$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;
|
||||
$state->absorb($ai);
|
||||
}
|
||||
/**
|
||||
* @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, "\x00", \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, "\x00", \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);
|
||||
|
||||
$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));
|
||||
}
|
||||
/**
|
||||
* @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);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,472 +1,518 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_AES', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
/**
|
||||
* Bitsliced implementation of the AES block cipher.
|
||||
*
|
||||
* Based on the implementation provided by BearSSL.
|
||||
*
|
||||
* @internal This should only be used by sodium_compat
|
||||
* @var int[] AES round constants
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_AES extends \ParagonIE_Sodium_Core_Util
|
||||
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[] AES round constants
|
||||
* @var int $x0
|
||||
* @var int $x1
|
||||
* @var int $x2
|
||||
* @var int $x3
|
||||
* @var int $x4
|
||||
* @var int $x5
|
||||
* @var int $x6
|
||||
* @var int $x7
|
||||
*/
|
||||
private static $Rcon = array(0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36);
|
||||
/**
|
||||
* Mutates the values of $q!
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_AES_Block $q
|
||||
* @return void
|
||||
$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.
|
||||
*/
|
||||
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;
|
||||
$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);
|
||||
}
|
||||
/**
|
||||
* 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);
|
||||
$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;
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @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));
|
||||
for ($i = 0; $i < $nkf; $i += 4) {
|
||||
$q = ParagonIE_Sodium_Core_AES_Block::fromArray(
|
||||
array_slice($skey, $i << 1, 8)
|
||||
);
|
||||
$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);
|
||||
// We have to overwrite $skey since we're not using C pointers like BearSSL did
|
||||
for ($j = 0; $j < 8; ++$j) {
|
||||
$q[$j] = ($q[$j] ^ $block[$j]) & \ParagonIE_Sodium_Core_Util::U32_MAX;
|
||||
$skey[($i << 1) + $j] = $q[$j];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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]);
|
||||
for ($i = 0, $j = 0; $i < $nkf; ++$i, $j += 2) {
|
||||
$comp_skey[$i] = ($skey[$j] & 0x55555555)
|
||||
| ($skey[$j + 1] & 0xAAAAAAAA);
|
||||
}
|
||||
/**
|
||||
* 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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bitsliced implementation of the AES block cipher.
|
||||
* This mainly exists for testing, as we need the round key features for AEGIS.
|
||||
*
|
||||
* Based on the implementation provided by BearSSL.
|
||||
*
|
||||
* @internal This should only be used by sodium_compat
|
||||
* @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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,300 +1,343 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_AES_Block', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
/**
|
||||
* @internal This should only be used by sodium_compat
|
||||
* @var array<int, int>
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_AES_Block extends \SplFixedArray
|
||||
protected $values = array();
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $size;
|
||||
|
||||
/**
|
||||
* @param int $size
|
||||
*/
|
||||
public function __construct($size = 8)
|
||||
{
|
||||
/**
|
||||
* @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);
|
||||
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);
|
||||
}
|
||||
/**
|
||||
* @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]);
|
||||
}
|
||||
$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;
|
||||
} else {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$obj->offsetSet($i, $array[$i]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @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]);
|
||||
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');
|
||||
}
|
||||
/**
|
||||
* @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(0xf0f0f0f, 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 & 0xff | ($x & 0xfc00) >> 2 | ($x & 0x300) << 6 | ($x & 0xf00000) >> 4 | ($x & 0xf0000) << 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 & 0xff | ($x & 0x3f00) << 2 | ($x & 0xc000) >> 6 | ($x & 0xf0000) << 4 | ($x & 0xf00000) >> 4 | ($x & 0x3000000) << 6 | ($x & 0xfc000000) >> 2);
|
||||
}
|
||||
return $this;
|
||||
if (is_null($offset)) {
|
||||
$this->values[] = $value;
|
||||
} else {
|
||||
$this->values[$offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal This should only be used by sodium_compat
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_AES_Expanded', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/**
|
||||
* @internal This should only be used by sodium_compat
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
@@ -1,74 +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;
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_AES_KeySchedule', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* @internal This should only be used by sodium_compat
|
||||
* @param array $skey
|
||||
* @param int $numRounds
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_AES_KeySchedule
|
||||
public function __construct(array $skey, $numRounds = 10)
|
||||
{
|
||||
/** @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;
|
||||
}
|
||||
$this->skey = $skey;
|
||||
$this->numRounds = $numRounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal This should only be used by sodium_compat
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,208 +1,274 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Base64
|
||||
*
|
||||
* Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Base64_Original
|
||||
{
|
||||
// COPY ParagonIE_Sodium_Core_Base64_Common STARTING HERE
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encode($src)
|
||||
{
|
||||
return self::doEncode($src, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Base64
|
||||
* Encode into Base64, no = padding
|
||||
*
|
||||
* Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Base64_Original
|
||||
public static function encodeUnpadded($src)
|
||||
{
|
||||
// COPY ParagonIE_Sodium_Core_Base64_Common STARTING HERE
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encode($src)
|
||||
{
|
||||
return self::doEncode($src, \true);
|
||||
return self::doEncode($src, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $src
|
||||
* @param bool $pad Include = padding?
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
protected static function doEncode($src, $pad = true)
|
||||
{
|
||||
$dest = '';
|
||||
$srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 3));
|
||||
$b0 = $chunk[1];
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
|
||||
$dest .=
|
||||
self::encode6Bits( $b0 >> 2 ) .
|
||||
self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
|
||||
self::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) .
|
||||
self::encode6Bits( $b2 & 63);
|
||||
}
|
||||
/**
|
||||
* Encode into Base64, no = padding
|
||||
*
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encodeUnpadded($src)
|
||||
{
|
||||
return self::doEncode($src, \false);
|
||||
}
|
||||
/**
|
||||
* @param string $src
|
||||
* @param bool $pad Include = padding?
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
protected static function doEncode($src, $pad = \true)
|
||||
{
|
||||
$dest = '';
|
||||
$srcLen = \ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', \ParagonIE_Sodium_Core_Util::substr($src, $i, 3));
|
||||
$b0 = $chunk[1];
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
|
||||
$b0 = $chunk[1];
|
||||
if ($i + 1 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
$dest .= self::encode6Bits($b0 >> 2) . self::encode6Bits(($b0 << 4 | $b1 >> 4) & 63) . self::encode6Bits(($b1 << 2 | $b2 >> 6) & 63) . self::encode6Bits($b2 & 63);
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', \ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
|
||||
$b0 = $chunk[1];
|
||||
if ($i + 1 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$dest .= self::encode6Bits($b0 >> 2) . self::encode6Bits(($b0 << 4 | $b1 >> 4) & 63) . self::encode6Bits($b1 << 2 & 63);
|
||||
if ($pad) {
|
||||
$dest .= '=';
|
||||
}
|
||||
} else {
|
||||
$dest .= self::encode6Bits($b0 >> 2) . self::encode6Bits($b0 << 4 & 63);
|
||||
if ($pad) {
|
||||
$dest .= '==';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
/**
|
||||
* decode from base64 into binary
|
||||
*
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $strictPadding
|
||||
* @return string
|
||||
* @throws RangeException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress RedundantCondition
|
||||
*/
|
||||
public static function decode($src, $strictPadding = \false)
|
||||
{
|
||||
// Remove padding
|
||||
$srcLen = \ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
if ($strictPadding) {
|
||||
if (($srcLen & 3) === 0) {
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (($srcLen & 3) === 1) {
|
||||
throw new \RangeException('Incorrect padding');
|
||||
}
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
throw new \RangeException('Incorrect padding');
|
||||
$dest .=
|
||||
self::encode6Bits($b0 >> 2) .
|
||||
self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
|
||||
self::encode6Bits(($b1 << 2) & 63);
|
||||
if ($pad) {
|
||||
$dest .= '=';
|
||||
}
|
||||
} else {
|
||||
$src = \rtrim($src, '=');
|
||||
$srcLen = \ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
}
|
||||
$err = 0;
|
||||
$dest = '';
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', \ParagonIE_Sodium_Core_Util::substr($src, $i, 4));
|
||||
$c0 = self::decode6Bits($chunk[1]);
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$c2 = self::decode6Bits($chunk[3]);
|
||||
$c3 = self::decode6Bits($chunk[4]);
|
||||
$dest .= \pack('CCC', ($c0 << 2 | $c1 >> 4) & 0xff, ($c1 << 4 | $c2 >> 2) & 0xff, ($c2 << 6 | $c3) & 0xff);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3) >> 8;
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', \ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
|
||||
$c0 = self::decode6Bits($chunk[1]);
|
||||
if ($i + 2 < $srcLen) {
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$c2 = self::decode6Bits($chunk[3]);
|
||||
$dest .= \pack('CC', ($c0 << 2 | $c1 >> 4) & 0xff, ($c1 << 4 | $c2 >> 2) & 0xff);
|
||||
$err |= ($c0 | $c1 | $c2) >> 8;
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$dest .= \pack('C', ($c0 << 2 | $c1 >> 4) & 0xff);
|
||||
$err |= ($c0 | $c1) >> 8;
|
||||
} elseif ($i < $srcLen && $strictPadding) {
|
||||
$err |= 1;
|
||||
$dest .=
|
||||
self::encode6Bits( $b0 >> 2) .
|
||||
self::encode6Bits(($b0 << 4) & 63);
|
||||
if ($pad) {
|
||||
$dest .= '==';
|
||||
}
|
||||
}
|
||||
/** @var bool $check */
|
||||
$check = $err === 0;
|
||||
if (!$check) {
|
||||
throw new \RangeException('Base64::decode() only expects characters in the correct base64 alphabet');
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
// COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [A-Z] [a-z] [0-9] + /
|
||||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits($src)
|
||||
{
|
||||
$ret = -1;
|
||||
// if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
|
||||
$ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 64;
|
||||
// if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
|
||||
$ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 70;
|
||||
// if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
|
||||
$ret += (0x2f - $src & $src - 0x3a) >> 8 & $src + 5;
|
||||
// if ($src == 0x2b) $ret += 62 + 1;
|
||||
$ret += (0x2a - $src & $src - 0x2c) >> 8 & 63;
|
||||
// if ($src == 0x2f) ret += 63 + 1;
|
||||
$ret += (0x2e - $src & $src - 0x30) >> 8 & 64;
|
||||
return $ret;
|
||||
}
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits($src)
|
||||
{
|
||||
$diff = 0x41;
|
||||
// if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
|
||||
$diff += 25 - $src >> 8 & 6;
|
||||
// if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
|
||||
$diff -= 51 - $src >> 8 & 75;
|
||||
// if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15
|
||||
$diff -= 61 - $src >> 8 & 15;
|
||||
// if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3
|
||||
$diff += 62 - $src >> 8 & 3;
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Base64
|
||||
* decode from base64 into binary
|
||||
*
|
||||
* Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $strictPadding
|
||||
* @return string
|
||||
* @throws RangeException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress RedundantCondition
|
||||
*/
|
||||
|
||||
public static function decode($src, $strictPadding = false)
|
||||
{
|
||||
// Remove padding
|
||||
$srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($strictPadding) {
|
||||
if (($srcLen & 3) === 0) {
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (($srcLen & 3) === 1) {
|
||||
throw new RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
throw new RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$src = rtrim($src, '=');
|
||||
$srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
}
|
||||
|
||||
$err = 0;
|
||||
$dest = '';
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 4));
|
||||
$c0 = self::decode6Bits($chunk[1]);
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$c2 = self::decode6Bits($chunk[3]);
|
||||
$c3 = self::decode6Bits($chunk[4]);
|
||||
|
||||
$dest .= pack(
|
||||
'CCC',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff),
|
||||
((($c1 << 4) | ($c2 >> 2)) & 0xff),
|
||||
((($c2 << 6) | $c3) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3) >> 8;
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
|
||||
$c0 = self::decode6Bits($chunk[1]);
|
||||
|
||||
if ($i + 2 < $srcLen) {
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$c2 = self::decode6Bits($chunk[3]);
|
||||
$dest .= pack(
|
||||
'CC',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff),
|
||||
((($c1 << 4) | ($c2 >> 2)) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2) >> 8;
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$dest .= pack(
|
||||
'C',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1) >> 8;
|
||||
} elseif ($i < $srcLen && $strictPadding) {
|
||||
$err |= 1;
|
||||
}
|
||||
}
|
||||
/** @var bool $check */
|
||||
$check = ($err === 0);
|
||||
if (!$check) {
|
||||
throw new RangeException(
|
||||
'Base64::decode() only expects characters in the correct base64 alphabet'
|
||||
);
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $encodedString
|
||||
* @return string
|
||||
*/
|
||||
public static function decodeNoPadding(
|
||||
#[SensitiveParameter]
|
||||
$encodedString
|
||||
) {
|
||||
$srcLen = strlen($encodedString);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
if (($srcLen & 3) === 0) {
|
||||
// If $strLen is not zero, and it is divisible by 4, then it's at least 4.
|
||||
if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') {
|
||||
throw new InvalidArgumentException(
|
||||
"decodeNoPadding() doesn't tolerate padding"
|
||||
);
|
||||
}
|
||||
}
|
||||
return self::decode(
|
||||
$encodedString,
|
||||
true
|
||||
);
|
||||
}
|
||||
// COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [A-Z] [a-z] [0-9] + /
|
||||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits($src)
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
|
||||
|
||||
// if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
|
||||
|
||||
// if ($src == 0x2b) $ret += 62 + 1;
|
||||
$ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63;
|
||||
|
||||
// if ($src == 0x2f) ret += 63 + 1;
|
||||
$ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits($src)
|
||||
{
|
||||
$diff = 0x41;
|
||||
|
||||
// if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
|
||||
$diff += ((25 - $src) >> 8) & 6;
|
||||
|
||||
// if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
|
||||
$diff -= ((51 - $src) >> 8) & 75;
|
||||
|
||||
// if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15
|
||||
$diff -= ((61 - $src) >> 8) & 15;
|
||||
|
||||
// if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3
|
||||
$diff += ((62 - $src) >> 8) & 3;
|
||||
|
||||
return pack('C', $src + $diff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,208 +1,274 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Base64UrlSafe
|
||||
*
|
||||
* Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Base64_UrlSafe
|
||||
{
|
||||
// COPY ParagonIE_Sodium_Core_Base64_Common STARTING HERE
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encode($src)
|
||||
{
|
||||
return self::doEncode($src, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Base64UrlSafe
|
||||
* Encode into Base64, no = padding
|
||||
*
|
||||
* Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Base64_UrlSafe
|
||||
public static function encodeUnpadded($src)
|
||||
{
|
||||
// COPY ParagonIE_Sodium_Core_Base64_Common STARTING HERE
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encode($src)
|
||||
{
|
||||
return self::doEncode($src, \true);
|
||||
return self::doEncode($src, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $src
|
||||
* @param bool $pad Include = padding?
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
protected static function doEncode($src, $pad = true)
|
||||
{
|
||||
$dest = '';
|
||||
$srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 3));
|
||||
$b0 = $chunk[1];
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
|
||||
$dest .=
|
||||
self::encode6Bits( $b0 >> 2 ) .
|
||||
self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
|
||||
self::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) .
|
||||
self::encode6Bits( $b2 & 63);
|
||||
}
|
||||
/**
|
||||
* Encode into Base64, no = padding
|
||||
*
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encodeUnpadded($src)
|
||||
{
|
||||
return self::doEncode($src, \false);
|
||||
}
|
||||
/**
|
||||
* @param string $src
|
||||
* @param bool $pad Include = padding?
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
protected static function doEncode($src, $pad = \true)
|
||||
{
|
||||
$dest = '';
|
||||
$srcLen = \ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', \ParagonIE_Sodium_Core_Util::substr($src, $i, 3));
|
||||
$b0 = $chunk[1];
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
|
||||
$b0 = $chunk[1];
|
||||
if ($i + 1 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
$dest .= self::encode6Bits($b0 >> 2) . self::encode6Bits(($b0 << 4 | $b1 >> 4) & 63) . self::encode6Bits(($b1 << 2 | $b2 >> 6) & 63) . self::encode6Bits($b2 & 63);
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', \ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
|
||||
$b0 = $chunk[1];
|
||||
if ($i + 1 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$dest .= self::encode6Bits($b0 >> 2) . self::encode6Bits(($b0 << 4 | $b1 >> 4) & 63) . self::encode6Bits($b1 << 2 & 63);
|
||||
if ($pad) {
|
||||
$dest .= '=';
|
||||
}
|
||||
} else {
|
||||
$dest .= self::encode6Bits($b0 >> 2) . self::encode6Bits($b0 << 4 & 63);
|
||||
if ($pad) {
|
||||
$dest .= '==';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
/**
|
||||
* decode from base64 into binary
|
||||
*
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $strictPadding
|
||||
* @return string
|
||||
* @throws RangeException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress RedundantCondition
|
||||
*/
|
||||
public static function decode($src, $strictPadding = \false)
|
||||
{
|
||||
// Remove padding
|
||||
$srcLen = \ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
if ($strictPadding) {
|
||||
if (($srcLen & 3) === 0) {
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (($srcLen & 3) === 1) {
|
||||
throw new \RangeException('Incorrect padding');
|
||||
}
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
throw new \RangeException('Incorrect padding');
|
||||
$dest .=
|
||||
self::encode6Bits($b0 >> 2) .
|
||||
self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
|
||||
self::encode6Bits(($b1 << 2) & 63);
|
||||
if ($pad) {
|
||||
$dest .= '=';
|
||||
}
|
||||
} else {
|
||||
$src = \rtrim($src, '=');
|
||||
$srcLen = \ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
}
|
||||
$err = 0;
|
||||
$dest = '';
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', \ParagonIE_Sodium_Core_Util::substr($src, $i, 4));
|
||||
$c0 = self::decode6Bits($chunk[1]);
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$c2 = self::decode6Bits($chunk[3]);
|
||||
$c3 = self::decode6Bits($chunk[4]);
|
||||
$dest .= \pack('CCC', ($c0 << 2 | $c1 >> 4) & 0xff, ($c1 << 4 | $c2 >> 2) & 0xff, ($c2 << 6 | $c3) & 0xff);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3) >> 8;
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', \ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
|
||||
$c0 = self::decode6Bits($chunk[1]);
|
||||
if ($i + 2 < $srcLen) {
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$c2 = self::decode6Bits($chunk[3]);
|
||||
$dest .= \pack('CC', ($c0 << 2 | $c1 >> 4) & 0xff, ($c1 << 4 | $c2 >> 2) & 0xff);
|
||||
$err |= ($c0 | $c1 | $c2) >> 8;
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$dest .= \pack('C', ($c0 << 2 | $c1 >> 4) & 0xff);
|
||||
$err |= ($c0 | $c1) >> 8;
|
||||
} elseif ($i < $srcLen && $strictPadding) {
|
||||
$err |= 1;
|
||||
$dest .=
|
||||
self::encode6Bits( $b0 >> 2) .
|
||||
self::encode6Bits(($b0 << 4) & 63);
|
||||
if ($pad) {
|
||||
$dest .= '==';
|
||||
}
|
||||
}
|
||||
/** @var bool $check */
|
||||
$check = $err === 0;
|
||||
if (!$check) {
|
||||
throw new \RangeException('Base64::decode() only expects characters in the correct base64 alphabet');
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
// COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [A-Z] [a-z] [0-9] + /
|
||||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits($src)
|
||||
{
|
||||
$ret = -1;
|
||||
// if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
|
||||
$ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 64;
|
||||
// if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
|
||||
$ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 70;
|
||||
// if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
|
||||
$ret += (0x2f - $src & $src - 0x3a) >> 8 & $src + 5;
|
||||
// if ($src == 0x2c) $ret += 62 + 1;
|
||||
$ret += (0x2c - $src & $src - 0x2e) >> 8 & 63;
|
||||
// if ($src == 0x5f) ret += 63 + 1;
|
||||
$ret += (0x5e - $src & $src - 0x60) >> 8 & 64;
|
||||
return $ret;
|
||||
}
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits($src)
|
||||
{
|
||||
$diff = 0x41;
|
||||
// if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
|
||||
$diff += 25 - $src >> 8 & 6;
|
||||
// if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
|
||||
$diff -= 51 - $src >> 8 & 75;
|
||||
// if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13
|
||||
$diff -= 61 - $src >> 8 & 13;
|
||||
// if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3
|
||||
$diff += 62 - $src >> 8 & 49;
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Base64UrlSafe
|
||||
* decode from base64 into binary
|
||||
*
|
||||
* Copyright (c) 2016 - 2018 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $strictPadding
|
||||
* @return string
|
||||
* @throws RangeException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress RedundantCondition
|
||||
*/
|
||||
|
||||
public static function decode($src, $strictPadding = false)
|
||||
{
|
||||
// Remove padding
|
||||
$srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($strictPadding) {
|
||||
if (($srcLen & 3) === 0) {
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (($srcLen & 3) === 1) {
|
||||
throw new RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
throw new RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$src = rtrim($src, '=');
|
||||
$srcLen = ParagonIE_Sodium_Core_Util::strlen($src);
|
||||
}
|
||||
|
||||
$err = 0;
|
||||
$dest = '';
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 4));
|
||||
$c0 = self::decode6Bits($chunk[1]);
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$c2 = self::decode6Bits($chunk[3]);
|
||||
$c3 = self::decode6Bits($chunk[4]);
|
||||
|
||||
$dest .= pack(
|
||||
'CCC',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff),
|
||||
((($c1 << 4) | ($c2 >> 2)) & 0xff),
|
||||
((($c2 << 6) | $c3) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3) >> 8;
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i));
|
||||
$c0 = self::decode6Bits($chunk[1]);
|
||||
|
||||
if ($i + 2 < $srcLen) {
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$c2 = self::decode6Bits($chunk[3]);
|
||||
$dest .= pack(
|
||||
'CC',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff),
|
||||
((($c1 << 4) | ($c2 >> 2)) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2) >> 8;
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
$c1 = self::decode6Bits($chunk[2]);
|
||||
$dest .= pack(
|
||||
'C',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1) >> 8;
|
||||
} elseif ($i < $srcLen && $strictPadding) {
|
||||
$err |= 1;
|
||||
}
|
||||
}
|
||||
/** @var bool $check */
|
||||
$check = ($err === 0);
|
||||
if (!$check) {
|
||||
throw new RangeException(
|
||||
'Base64::decode() only expects characters in the correct base64 alphabet'
|
||||
);
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $encodedString
|
||||
* @return string
|
||||
*/
|
||||
public static function decodeNoPadding(
|
||||
#[SensitiveParameter]
|
||||
$encodedString
|
||||
) {
|
||||
$srcLen = strlen($encodedString);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
if (($srcLen & 3) === 0) {
|
||||
// If $strLen is not zero, and it is divisible by 4, then it's at least 4.
|
||||
if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') {
|
||||
throw new InvalidArgumentException(
|
||||
"decodeNoPadding() doesn't tolerate padding"
|
||||
);
|
||||
}
|
||||
}
|
||||
return self::decode(
|
||||
$encodedString,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [A-Z] [a-z] [0-9] + /
|
||||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits($src)
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
|
||||
|
||||
// if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
|
||||
|
||||
// if ($src == 0x2c) $ret += 62 + 1;
|
||||
$ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63;
|
||||
|
||||
// if ($src == 0x5f) ret += 63 + 1;
|
||||
$ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits($src)
|
||||
{
|
||||
$diff = 0x41;
|
||||
|
||||
// if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
|
||||
$diff += ((25 - $src) >> 8) & 6;
|
||||
|
||||
// if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
|
||||
$diff -= ((51 - $src) >> 8) & 75;
|
||||
|
||||
// if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13
|
||||
$diff -= ((61 - $src) >> 8) & 13;
|
||||
|
||||
// if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3
|
||||
$diff += ((62 - $src) >> 8) & 49;
|
||||
|
||||
return pack('C', $src + $diff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,338 +1,395 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_ChaCha20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_ChaCha20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_ChaCha20
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_ChaCha20
|
||||
* Bitwise left rotation
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $v
|
||||
* @param int $n
|
||||
* @return int
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_ChaCha20 extends \ParagonIE_Sodium_Core_Util
|
||||
public static function rotate($v, $n)
|
||||
{
|
||||
/**
|
||||
* Bitwise left rotation
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $v
|
||||
* @param int $n
|
||||
* @return int
|
||||
*/
|
||||
public static function rotate($v, $n)
|
||||
{
|
||||
$v &= 0xffffffff;
|
||||
$n &= 31;
|
||||
return (int) (0xffffffff & ($v << $n | $v >> 32 - $n));
|
||||
}
|
||||
/**
|
||||
* The ChaCha20 quarter round function. Works on four 32-bit integers.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $a
|
||||
* @param int $b
|
||||
* @param int $c
|
||||
* @param int $d
|
||||
* @return array<int, int>
|
||||
*/
|
||||
protected static function quarterRound($a, $b, $c, $d)
|
||||
{
|
||||
# a = PLUS(a,b); d = ROTATE(XOR(d,a),16);
|
||||
/** @var int $a */
|
||||
$a = $a + $b & 0xffffffff;
|
||||
$d = self::rotate($d ^ $a, 16);
|
||||
# c = PLUS(c,d); b = ROTATE(XOR(b,c),12);
|
||||
/** @var int $c */
|
||||
$c = $c + $d & 0xffffffff;
|
||||
$b = self::rotate($b ^ $c, 12);
|
||||
# a = PLUS(a,b); d = ROTATE(XOR(d,a), 8);
|
||||
/** @var int $a */
|
||||
$a = $a + $b & 0xffffffff;
|
||||
$d = self::rotate($d ^ $a, 8);
|
||||
# c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
|
||||
/** @var int $c */
|
||||
$c = $c + $d & 0xffffffff;
|
||||
$b = self::rotate($b ^ $c, 7);
|
||||
return array((int) $a, (int) $b, (int) $c, (int) $d);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx
|
||||
* @param string $message
|
||||
*
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function encryptBytes(\ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx, $message = '')
|
||||
{
|
||||
$bytes = self::strlen($message);
|
||||
/*
|
||||
j0 = ctx->input[0];
|
||||
j1 = ctx->input[1];
|
||||
j2 = ctx->input[2];
|
||||
j3 = ctx->input[3];
|
||||
j4 = ctx->input[4];
|
||||
j5 = ctx->input[5];
|
||||
j6 = ctx->input[6];
|
||||
j7 = ctx->input[7];
|
||||
j8 = ctx->input[8];
|
||||
j9 = ctx->input[9];
|
||||
j10 = ctx->input[10];
|
||||
j11 = ctx->input[11];
|
||||
j12 = ctx->input[12];
|
||||
j13 = ctx->input[13];
|
||||
j14 = ctx->input[14];
|
||||
j15 = ctx->input[15];
|
||||
*/
|
||||
$j0 = (int) $ctx[0];
|
||||
$j1 = (int) $ctx[1];
|
||||
$j2 = (int) $ctx[2];
|
||||
$j3 = (int) $ctx[3];
|
||||
$j4 = (int) $ctx[4];
|
||||
$j5 = (int) $ctx[5];
|
||||
$j6 = (int) $ctx[6];
|
||||
$j7 = (int) $ctx[7];
|
||||
$j8 = (int) $ctx[8];
|
||||
$j9 = (int) $ctx[9];
|
||||
$j10 = (int) $ctx[10];
|
||||
$j11 = (int) $ctx[11];
|
||||
$j12 = (int) $ctx[12];
|
||||
$j13 = (int) $ctx[13];
|
||||
$j14 = (int) $ctx[14];
|
||||
$j15 = (int) $ctx[15];
|
||||
$c = '';
|
||||
for (;;) {
|
||||
if ($bytes < 64) {
|
||||
$message .= \str_repeat("\x00", 64 - $bytes);
|
||||
}
|
||||
$x0 = (int) $j0;
|
||||
$x1 = (int) $j1;
|
||||
$x2 = (int) $j2;
|
||||
$x3 = (int) $j3;
|
||||
$x4 = (int) $j4;
|
||||
$x5 = (int) $j5;
|
||||
$x6 = (int) $j6;
|
||||
$x7 = (int) $j7;
|
||||
$x8 = (int) $j8;
|
||||
$x9 = (int) $j9;
|
||||
$x10 = (int) $j10;
|
||||
$x11 = (int) $j11;
|
||||
$x12 = (int) $j12;
|
||||
$x13 = (int) $j13;
|
||||
$x14 = (int) $j14;
|
||||
$x15 = (int) $j15;
|
||||
# for (i = 20; i > 0; i -= 2) {
|
||||
for ($i = 20; $i > 0; $i -= 2) {
|
||||
# QUARTERROUND( x0, x4, x8, x12)
|
||||
list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
|
||||
# QUARTERROUND( x1, x5, x9, x13)
|
||||
list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
|
||||
# QUARTERROUND( x2, x6, x10, x14)
|
||||
list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
|
||||
# QUARTERROUND( x3, x7, x11, x15)
|
||||
list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
|
||||
# QUARTERROUND( x0, x5, x10, x15)
|
||||
list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
|
||||
# QUARTERROUND( x1, x6, x11, x12)
|
||||
list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
|
||||
# QUARTERROUND( x2, x7, x8, x13)
|
||||
list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
|
||||
# QUARTERROUND( x3, x4, x9, x14)
|
||||
list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
|
||||
}
|
||||
/*
|
||||
x0 = PLUS(x0, j0);
|
||||
x1 = PLUS(x1, j1);
|
||||
x2 = PLUS(x2, j2);
|
||||
x3 = PLUS(x3, j3);
|
||||
x4 = PLUS(x4, j4);
|
||||
x5 = PLUS(x5, j5);
|
||||
x6 = PLUS(x6, j6);
|
||||
x7 = PLUS(x7, j7);
|
||||
x8 = PLUS(x8, j8);
|
||||
x9 = PLUS(x9, j9);
|
||||
x10 = PLUS(x10, j10);
|
||||
x11 = PLUS(x11, j11);
|
||||
x12 = PLUS(x12, j12);
|
||||
x13 = PLUS(x13, j13);
|
||||
x14 = PLUS(x14, j14);
|
||||
x15 = PLUS(x15, j15);
|
||||
*/
|
||||
/** @var int $x0 */
|
||||
$x0 = ($x0 & 0xffffffff) + $j0;
|
||||
/** @var int $x1 */
|
||||
$x1 = ($x1 & 0xffffffff) + $j1;
|
||||
/** @var int $x2 */
|
||||
$x2 = ($x2 & 0xffffffff) + $j2;
|
||||
/** @var int $x3 */
|
||||
$x3 = ($x3 & 0xffffffff) + $j3;
|
||||
/** @var int $x4 */
|
||||
$x4 = ($x4 & 0xffffffff) + $j4;
|
||||
/** @var int $x5 */
|
||||
$x5 = ($x5 & 0xffffffff) + $j5;
|
||||
/** @var int $x6 */
|
||||
$x6 = ($x6 & 0xffffffff) + $j6;
|
||||
/** @var int $x7 */
|
||||
$x7 = ($x7 & 0xffffffff) + $j7;
|
||||
/** @var int $x8 */
|
||||
$x8 = ($x8 & 0xffffffff) + $j8;
|
||||
/** @var int $x9 */
|
||||
$x9 = ($x9 & 0xffffffff) + $j9;
|
||||
/** @var int $x10 */
|
||||
$x10 = ($x10 & 0xffffffff) + $j10;
|
||||
/** @var int $x11 */
|
||||
$x11 = ($x11 & 0xffffffff) + $j11;
|
||||
/** @var int $x12 */
|
||||
$x12 = ($x12 & 0xffffffff) + $j12;
|
||||
/** @var int $x13 */
|
||||
$x13 = ($x13 & 0xffffffff) + $j13;
|
||||
/** @var int $x14 */
|
||||
$x14 = ($x14 & 0xffffffff) + $j14;
|
||||
/** @var int $x15 */
|
||||
$x15 = ($x15 & 0xffffffff) + $j15;
|
||||
/*
|
||||
x0 = XOR(x0, LOAD32_LE(m + 0));
|
||||
x1 = XOR(x1, LOAD32_LE(m + 4));
|
||||
x2 = XOR(x2, LOAD32_LE(m + 8));
|
||||
x3 = XOR(x3, LOAD32_LE(m + 12));
|
||||
x4 = XOR(x4, LOAD32_LE(m + 16));
|
||||
x5 = XOR(x5, LOAD32_LE(m + 20));
|
||||
x6 = XOR(x6, LOAD32_LE(m + 24));
|
||||
x7 = XOR(x7, LOAD32_LE(m + 28));
|
||||
x8 = XOR(x8, LOAD32_LE(m + 32));
|
||||
x9 = XOR(x9, LOAD32_LE(m + 36));
|
||||
x10 = XOR(x10, LOAD32_LE(m + 40));
|
||||
x11 = XOR(x11, LOAD32_LE(m + 44));
|
||||
x12 = XOR(x12, LOAD32_LE(m + 48));
|
||||
x13 = XOR(x13, LOAD32_LE(m + 52));
|
||||
x14 = XOR(x14, LOAD32_LE(m + 56));
|
||||
x15 = XOR(x15, LOAD32_LE(m + 60));
|
||||
*/
|
||||
$x0 ^= self::load_4(self::substr($message, 0, 4));
|
||||
$x1 ^= self::load_4(self::substr($message, 4, 4));
|
||||
$x2 ^= self::load_4(self::substr($message, 8, 4));
|
||||
$x3 ^= self::load_4(self::substr($message, 12, 4));
|
||||
$x4 ^= self::load_4(self::substr($message, 16, 4));
|
||||
$x5 ^= self::load_4(self::substr($message, 20, 4));
|
||||
$x6 ^= self::load_4(self::substr($message, 24, 4));
|
||||
$x7 ^= self::load_4(self::substr($message, 28, 4));
|
||||
$x8 ^= self::load_4(self::substr($message, 32, 4));
|
||||
$x9 ^= self::load_4(self::substr($message, 36, 4));
|
||||
$x10 ^= self::load_4(self::substr($message, 40, 4));
|
||||
$x11 ^= self::load_4(self::substr($message, 44, 4));
|
||||
$x12 ^= self::load_4(self::substr($message, 48, 4));
|
||||
$x13 ^= self::load_4(self::substr($message, 52, 4));
|
||||
$x14 ^= self::load_4(self::substr($message, 56, 4));
|
||||
$x15 ^= self::load_4(self::substr($message, 60, 4));
|
||||
/*
|
||||
j12 = PLUSONE(j12);
|
||||
if (!j12) {
|
||||
j13 = PLUSONE(j13);
|
||||
}
|
||||
*/
|
||||
++$j12;
|
||||
if ($j12 & 0xf0000000) {
|
||||
throw new \SodiumException('Overflow');
|
||||
}
|
||||
/*
|
||||
STORE32_LE(c + 0, x0);
|
||||
STORE32_LE(c + 4, x1);
|
||||
STORE32_LE(c + 8, x2);
|
||||
STORE32_LE(c + 12, x3);
|
||||
STORE32_LE(c + 16, x4);
|
||||
STORE32_LE(c + 20, x5);
|
||||
STORE32_LE(c + 24, x6);
|
||||
STORE32_LE(c + 28, x7);
|
||||
STORE32_LE(c + 32, x8);
|
||||
STORE32_LE(c + 36, x9);
|
||||
STORE32_LE(c + 40, x10);
|
||||
STORE32_LE(c + 44, x11);
|
||||
STORE32_LE(c + 48, x12);
|
||||
STORE32_LE(c + 52, x13);
|
||||
STORE32_LE(c + 56, x14);
|
||||
STORE32_LE(c + 60, x15);
|
||||
*/
|
||||
$block = self::store32_le((int) ($x0 & 0xffffffff)) . self::store32_le((int) ($x1 & 0xffffffff)) . self::store32_le((int) ($x2 & 0xffffffff)) . self::store32_le((int) ($x3 & 0xffffffff)) . self::store32_le((int) ($x4 & 0xffffffff)) . self::store32_le((int) ($x5 & 0xffffffff)) . self::store32_le((int) ($x6 & 0xffffffff)) . self::store32_le((int) ($x7 & 0xffffffff)) . self::store32_le((int) ($x8 & 0xffffffff)) . self::store32_le((int) ($x9 & 0xffffffff)) . self::store32_le((int) ($x10 & 0xffffffff)) . self::store32_le((int) ($x11 & 0xffffffff)) . self::store32_le((int) ($x12 & 0xffffffff)) . self::store32_le((int) ($x13 & 0xffffffff)) . self::store32_le((int) ($x14 & 0xffffffff)) . self::store32_le((int) ($x15 & 0xffffffff));
|
||||
/* Partial block */
|
||||
if ($bytes < 64) {
|
||||
$c .= self::substr($block, 0, $bytes);
|
||||
break;
|
||||
}
|
||||
/* Full block */
|
||||
$c .= $block;
|
||||
$bytes -= 64;
|
||||
if ($bytes <= 0) {
|
||||
break;
|
||||
}
|
||||
$message = self::substr($message, 64);
|
||||
}
|
||||
/* end for(;;) loop */
|
||||
$ctx[12] = $j12;
|
||||
$ctx[13] = $j13;
|
||||
return $c;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function stream($len = 64, $nonce = '', $key = '')
|
||||
{
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce), \str_repeat("\x00", $len));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStream($len, $nonce = '', $key = '')
|
||||
{
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce), \str_repeat("\x00", $len));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce, $ic), $message);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce, $ic), $message);
|
||||
}
|
||||
$v &= 0xffffffff;
|
||||
$n &= 31;
|
||||
return (int) (
|
||||
0xffffffff & (
|
||||
($v << $n)
|
||||
|
|
||||
($v >> (32 - $n))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_ChaCha20
|
||||
* The ChaCha20 quarter round function. Works on four 32-bit integers.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $a
|
||||
* @param int $b
|
||||
* @param int $c
|
||||
* @param int $d
|
||||
* @return array<int, int>
|
||||
*/
|
||||
|
||||
protected static function quarterRound($a, $b, $c, $d)
|
||||
{
|
||||
# a = PLUS(a,b); d = ROTATE(XOR(d,a),16);
|
||||
/** @var int $a */
|
||||
$a = ($a + $b) & 0xffffffff;
|
||||
$d = self::rotate($d ^ $a, 16);
|
||||
|
||||
# c = PLUS(c,d); b = ROTATE(XOR(b,c),12);
|
||||
/** @var int $c */
|
||||
$c = ($c + $d) & 0xffffffff;
|
||||
$b = self::rotate($b ^ $c, 12);
|
||||
|
||||
# a = PLUS(a,b); d = ROTATE(XOR(d,a), 8);
|
||||
/** @var int $a */
|
||||
$a = ($a + $b) & 0xffffffff;
|
||||
$d = self::rotate($d ^ $a, 8);
|
||||
|
||||
# c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
|
||||
/** @var int $c */
|
||||
$c = ($c + $d) & 0xffffffff;
|
||||
$b = self::rotate($b ^ $c, 7);
|
||||
return array((int) $a, (int) $b, (int) $c, (int) $d);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx
|
||||
* @param string $message
|
||||
*
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function encryptBytes(
|
||||
ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx,
|
||||
$message = ''
|
||||
) {
|
||||
$bytes = self::strlen($message);
|
||||
|
||||
/*
|
||||
j0 = ctx->input[0];
|
||||
j1 = ctx->input[1];
|
||||
j2 = ctx->input[2];
|
||||
j3 = ctx->input[3];
|
||||
j4 = ctx->input[4];
|
||||
j5 = ctx->input[5];
|
||||
j6 = ctx->input[6];
|
||||
j7 = ctx->input[7];
|
||||
j8 = ctx->input[8];
|
||||
j9 = ctx->input[9];
|
||||
j10 = ctx->input[10];
|
||||
j11 = ctx->input[11];
|
||||
j12 = ctx->input[12];
|
||||
j13 = ctx->input[13];
|
||||
j14 = ctx->input[14];
|
||||
j15 = ctx->input[15];
|
||||
*/
|
||||
$j0 = (int) $ctx[0];
|
||||
$j1 = (int) $ctx[1];
|
||||
$j2 = (int) $ctx[2];
|
||||
$j3 = (int) $ctx[3];
|
||||
$j4 = (int) $ctx[4];
|
||||
$j5 = (int) $ctx[5];
|
||||
$j6 = (int) $ctx[6];
|
||||
$j7 = (int) $ctx[7];
|
||||
$j8 = (int) $ctx[8];
|
||||
$j9 = (int) $ctx[9];
|
||||
$j10 = (int) $ctx[10];
|
||||
$j11 = (int) $ctx[11];
|
||||
$j12 = (int) $ctx[12];
|
||||
$j13 = (int) $ctx[13];
|
||||
$j14 = (int) $ctx[14];
|
||||
$j15 = (int) $ctx[15];
|
||||
|
||||
$c = '';
|
||||
for (;;) {
|
||||
if ($bytes < 64) {
|
||||
$message .= str_repeat("\x00", 64 - $bytes);
|
||||
}
|
||||
|
||||
$x0 = (int) $j0;
|
||||
$x1 = (int) $j1;
|
||||
$x2 = (int) $j2;
|
||||
$x3 = (int) $j3;
|
||||
$x4 = (int) $j4;
|
||||
$x5 = (int) $j5;
|
||||
$x6 = (int) $j6;
|
||||
$x7 = (int) $j7;
|
||||
$x8 = (int) $j8;
|
||||
$x9 = (int) $j9;
|
||||
$x10 = (int) $j10;
|
||||
$x11 = (int) $j11;
|
||||
$x12 = (int) $j12;
|
||||
$x13 = (int) $j13;
|
||||
$x14 = (int) $j14;
|
||||
$x15 = (int) $j15;
|
||||
|
||||
# for (i = 20; i > 0; i -= 2) {
|
||||
for ($i = 20; $i > 0; $i -= 2) {
|
||||
# QUARTERROUND( x0, x4, x8, x12)
|
||||
list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
|
||||
|
||||
# QUARTERROUND( x1, x5, x9, x13)
|
||||
list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
|
||||
|
||||
# QUARTERROUND( x2, x6, x10, x14)
|
||||
list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
|
||||
|
||||
# QUARTERROUND( x3, x7, x11, x15)
|
||||
list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
|
||||
|
||||
# QUARTERROUND( x0, x5, x10, x15)
|
||||
list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
|
||||
|
||||
# QUARTERROUND( x1, x6, x11, x12)
|
||||
list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
|
||||
|
||||
# QUARTERROUND( x2, x7, x8, x13)
|
||||
list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
|
||||
|
||||
# QUARTERROUND( x3, x4, x9, x14)
|
||||
list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
|
||||
}
|
||||
/*
|
||||
x0 = PLUS(x0, j0);
|
||||
x1 = PLUS(x1, j1);
|
||||
x2 = PLUS(x2, j2);
|
||||
x3 = PLUS(x3, j3);
|
||||
x4 = PLUS(x4, j4);
|
||||
x5 = PLUS(x5, j5);
|
||||
x6 = PLUS(x6, j6);
|
||||
x7 = PLUS(x7, j7);
|
||||
x8 = PLUS(x8, j8);
|
||||
x9 = PLUS(x9, j9);
|
||||
x10 = PLUS(x10, j10);
|
||||
x11 = PLUS(x11, j11);
|
||||
x12 = PLUS(x12, j12);
|
||||
x13 = PLUS(x13, j13);
|
||||
x14 = PLUS(x14, j14);
|
||||
x15 = PLUS(x15, j15);
|
||||
*/
|
||||
/** @var int $x0 */
|
||||
$x0 = ($x0 & 0xffffffff) + $j0;
|
||||
/** @var int $x1 */
|
||||
$x1 = ($x1 & 0xffffffff) + $j1;
|
||||
/** @var int $x2 */
|
||||
$x2 = ($x2 & 0xffffffff) + $j2;
|
||||
/** @var int $x3 */
|
||||
$x3 = ($x3 & 0xffffffff) + $j3;
|
||||
/** @var int $x4 */
|
||||
$x4 = ($x4 & 0xffffffff) + $j4;
|
||||
/** @var int $x5 */
|
||||
$x5 = ($x5 & 0xffffffff) + $j5;
|
||||
/** @var int $x6 */
|
||||
$x6 = ($x6 & 0xffffffff) + $j6;
|
||||
/** @var int $x7 */
|
||||
$x7 = ($x7 & 0xffffffff) + $j7;
|
||||
/** @var int $x8 */
|
||||
$x8 = ($x8 & 0xffffffff) + $j8;
|
||||
/** @var int $x9 */
|
||||
$x9 = ($x9 & 0xffffffff) + $j9;
|
||||
/** @var int $x10 */
|
||||
$x10 = ($x10 & 0xffffffff) + $j10;
|
||||
/** @var int $x11 */
|
||||
$x11 = ($x11 & 0xffffffff) + $j11;
|
||||
/** @var int $x12 */
|
||||
$x12 = ($x12 & 0xffffffff) + $j12;
|
||||
/** @var int $x13 */
|
||||
$x13 = ($x13 & 0xffffffff) + $j13;
|
||||
/** @var int $x14 */
|
||||
$x14 = ($x14 & 0xffffffff) + $j14;
|
||||
/** @var int $x15 */
|
||||
$x15 = ($x15 & 0xffffffff) + $j15;
|
||||
|
||||
/*
|
||||
x0 = XOR(x0, LOAD32_LE(m + 0));
|
||||
x1 = XOR(x1, LOAD32_LE(m + 4));
|
||||
x2 = XOR(x2, LOAD32_LE(m + 8));
|
||||
x3 = XOR(x3, LOAD32_LE(m + 12));
|
||||
x4 = XOR(x4, LOAD32_LE(m + 16));
|
||||
x5 = XOR(x5, LOAD32_LE(m + 20));
|
||||
x6 = XOR(x6, LOAD32_LE(m + 24));
|
||||
x7 = XOR(x7, LOAD32_LE(m + 28));
|
||||
x8 = XOR(x8, LOAD32_LE(m + 32));
|
||||
x9 = XOR(x9, LOAD32_LE(m + 36));
|
||||
x10 = XOR(x10, LOAD32_LE(m + 40));
|
||||
x11 = XOR(x11, LOAD32_LE(m + 44));
|
||||
x12 = XOR(x12, LOAD32_LE(m + 48));
|
||||
x13 = XOR(x13, LOAD32_LE(m + 52));
|
||||
x14 = XOR(x14, LOAD32_LE(m + 56));
|
||||
x15 = XOR(x15, LOAD32_LE(m + 60));
|
||||
*/
|
||||
$x0 ^= self::load_4(self::substr($message, 0, 4));
|
||||
$x1 ^= self::load_4(self::substr($message, 4, 4));
|
||||
$x2 ^= self::load_4(self::substr($message, 8, 4));
|
||||
$x3 ^= self::load_4(self::substr($message, 12, 4));
|
||||
$x4 ^= self::load_4(self::substr($message, 16, 4));
|
||||
$x5 ^= self::load_4(self::substr($message, 20, 4));
|
||||
$x6 ^= self::load_4(self::substr($message, 24, 4));
|
||||
$x7 ^= self::load_4(self::substr($message, 28, 4));
|
||||
$x8 ^= self::load_4(self::substr($message, 32, 4));
|
||||
$x9 ^= self::load_4(self::substr($message, 36, 4));
|
||||
$x10 ^= self::load_4(self::substr($message, 40, 4));
|
||||
$x11 ^= self::load_4(self::substr($message, 44, 4));
|
||||
$x12 ^= self::load_4(self::substr($message, 48, 4));
|
||||
$x13 ^= self::load_4(self::substr($message, 52, 4));
|
||||
$x14 ^= self::load_4(self::substr($message, 56, 4));
|
||||
$x15 ^= self::load_4(self::substr($message, 60, 4));
|
||||
|
||||
/*
|
||||
j12 = PLUSONE(j12);
|
||||
if (!j12) {
|
||||
j13 = PLUSONE(j13);
|
||||
}
|
||||
*/
|
||||
++$j12;
|
||||
if ($j12 & 0xf0000000) {
|
||||
throw new SodiumException('Overflow');
|
||||
}
|
||||
|
||||
/*
|
||||
STORE32_LE(c + 0, x0);
|
||||
STORE32_LE(c + 4, x1);
|
||||
STORE32_LE(c + 8, x2);
|
||||
STORE32_LE(c + 12, x3);
|
||||
STORE32_LE(c + 16, x4);
|
||||
STORE32_LE(c + 20, x5);
|
||||
STORE32_LE(c + 24, x6);
|
||||
STORE32_LE(c + 28, x7);
|
||||
STORE32_LE(c + 32, x8);
|
||||
STORE32_LE(c + 36, x9);
|
||||
STORE32_LE(c + 40, x10);
|
||||
STORE32_LE(c + 44, x11);
|
||||
STORE32_LE(c + 48, x12);
|
||||
STORE32_LE(c + 52, x13);
|
||||
STORE32_LE(c + 56, x14);
|
||||
STORE32_LE(c + 60, x15);
|
||||
*/
|
||||
$block = self::store32_le((int) ($x0 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x1 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x2 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x3 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x4 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x5 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x6 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x7 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x8 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x9 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x10 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x11 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x12 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x13 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x14 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x15 & 0xffffffff));
|
||||
|
||||
/* Partial block */
|
||||
if ($bytes < 64) {
|
||||
$c .= self::substr($block, 0, $bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Full block */
|
||||
$c .= $block;
|
||||
$bytes -= 64;
|
||||
if ($bytes <= 0) {
|
||||
break;
|
||||
}
|
||||
$message = self::substr($message, 64);
|
||||
}
|
||||
/* end for(;;) loop */
|
||||
|
||||
$ctx[12] = $j12;
|
||||
$ctx[13] = $j13;
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function stream($len, $nonce, $key)
|
||||
{
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce),
|
||||
str_repeat("\x00", $len)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStream($len, $nonce, $key)
|
||||
{
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce),
|
||||
str_repeat("\x00", $len)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStreamXorIc($message, $nonce, $key, $ic = '')
|
||||
{
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce, $ic),
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function streamXorIc($message, $nonce, $key, $ic = '')
|
||||
{
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce, $ic),
|
||||
$message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,118 +1,143 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_ChaCha20_Ctx', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_ChaCha20_Ctx', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_ChaCha20_Ctx
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_ChaCha20_Ctx extends ParagonIE_Sodium_Core_Util implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_ChaCha20_Ctx
|
||||
* @var SplFixedArray internally, <int, int>
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_ChaCha20_Ctx extends \ParagonIE_Sodium_Core_Util implements \ArrayAccess
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_ChaCha20_Ctx constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key ChaCha20 key.
|
||||
* @param string $iv Initialization Vector (a.k.a. nonce).
|
||||
* @param string $counter The initial counter value.
|
||||
* Defaults to 8 0x00 bytes.
|
||||
* @throws InvalidArgumentException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '', $iv = '', $counter = '')
|
||||
{
|
||||
/**
|
||||
* @var SplFixedArray internally, <int, int>
|
||||
*/
|
||||
protected $container;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_ChaCha20_Ctx constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key ChaCha20 key.
|
||||
* @param string $iv Initialization Vector (a.k.a. nonce).
|
||||
* @param string $counter The initial counter value.
|
||||
* Defaults to 8 0x00 bytes.
|
||||
* @throws InvalidArgumentException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '', $iv = '', $counter = '')
|
||||
{
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new \InvalidArgumentException('ChaCha20 expects a 256-bit key.');
|
||||
}
|
||||
if (self::strlen($iv) !== 8) {
|
||||
throw new \InvalidArgumentException('ChaCha20 expects a 64-bit nonce.');
|
||||
}
|
||||
$this->container = new \SplFixedArray(16);
|
||||
/* "expand 32-byte k" as per ChaCha20 spec */
|
||||
$this->container[0] = 0x61707865;
|
||||
$this->container[1] = 0x3320646e;
|
||||
$this->container[2] = 0x79622d32;
|
||||
$this->container[3] = 0x6b206574;
|
||||
$this->container[4] = self::load_4(self::substr($key, 0, 4));
|
||||
$this->container[5] = self::load_4(self::substr($key, 4, 4));
|
||||
$this->container[6] = self::load_4(self::substr($key, 8, 4));
|
||||
$this->container[7] = self::load_4(self::substr($key, 12, 4));
|
||||
$this->container[8] = self::load_4(self::substr($key, 16, 4));
|
||||
$this->container[9] = self::load_4(self::substr($key, 20, 4));
|
||||
$this->container[10] = self::load_4(self::substr($key, 24, 4));
|
||||
$this->container[11] = self::load_4(self::substr($key, 28, 4));
|
||||
if (empty($counter)) {
|
||||
$this->container[12] = 0;
|
||||
$this->container[13] = 0;
|
||||
} else {
|
||||
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
|
||||
$this->container[13] = self::load_4(self::substr($counter, 4, 4));
|
||||
}
|
||||
$this->container[14] = self::load_4(self::substr($iv, 0, 4));
|
||||
$this->container[15] = self::load_4(self::substr($iv, 4, 4));
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new InvalidArgumentException('ChaCha20 expects a 256-bit key.');
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $value
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!\is_int($offset)) {
|
||||
throw new \InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
if (!\is_int($value)) {
|
||||
throw new \InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
$this->container[$offset] = $value;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->container[$offset]);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->container[$offset]);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return mixed|null
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->container[$offset]) ? $this->container[$offset] : null;
|
||||
if (self::strlen($iv) !== 8) {
|
||||
throw new InvalidArgumentException('ChaCha20 expects a 64-bit nonce.');
|
||||
}
|
||||
$this->container = new SplFixedArray(16);
|
||||
|
||||
/* "expand 32-byte k" as per ChaCha20 spec */
|
||||
$this->container[0] = 0x61707865;
|
||||
$this->container[1] = 0x3320646e;
|
||||
$this->container[2] = 0x79622d32;
|
||||
$this->container[3] = 0x6b206574;
|
||||
$this->container[4] = self::load_4(self::substr($key, 0, 4));
|
||||
$this->container[5] = self::load_4(self::substr($key, 4, 4));
|
||||
$this->container[6] = self::load_4(self::substr($key, 8, 4));
|
||||
$this->container[7] = self::load_4(self::substr($key, 12, 4));
|
||||
$this->container[8] = self::load_4(self::substr($key, 16, 4));
|
||||
$this->container[9] = self::load_4(self::substr($key, 20, 4));
|
||||
$this->container[10] = self::load_4(self::substr($key, 24, 4));
|
||||
$this->container[11] = self::load_4(self::substr($key, 28, 4));
|
||||
|
||||
$counter = $this->initCounter($counter);
|
||||
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
|
||||
$this->container[13] = self::load_4(self::substr($counter, 4, 4));
|
||||
$this->container[14] = self::load_4(self::substr($iv, 0, 4));
|
||||
$this->container[15] = self::load_4(self::substr($iv, 4, 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_ChaCha20_Ctx
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $value
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!is_int($offset)) {
|
||||
throw new InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
if (!is_int($value)) {
|
||||
throw new InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
$this->container[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->container[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->container[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return mixed|null
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->container[$offset])
|
||||
? $this->container[$offset]
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize (pad) a counter value.
|
||||
* @throws SodiumException
|
||||
*
|
||||
* @param string $ctr
|
||||
* @return string
|
||||
*/
|
||||
public function initCounter(
|
||||
#[SensitiveParameter]
|
||||
$ctr
|
||||
) {
|
||||
$len = self::strlen($ctr);
|
||||
if ($len === 0) {
|
||||
return str_repeat("\0", 8);
|
||||
}
|
||||
if ($len < 8) {
|
||||
return $ctr . str_repeat("\0", 8 - $len);
|
||||
}
|
||||
if ($len > 8) {
|
||||
throw new SodiumException("counter cannot be more than 8 bytes");
|
||||
}
|
||||
return $ctr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +1,36 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_ChaCha20_IetfCtx', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_ChaCha20_IetfCtx', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_ChaCha20_IetfCtx
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_ChaCha20_IetfCtx extends ParagonIE_Sodium_Core_ChaCha20_Ctx
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_ChaCha20_IetfCtx
|
||||
* ParagonIE_Sodium_Core_ChaCha20_IetfCtx constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key ChaCha20 key.
|
||||
* @param string $iv Initialization Vector (a.k.a. nonce).
|
||||
* @param string $counter The initial counter value.
|
||||
* Defaults to 4 0x00 bytes.
|
||||
* @throws InvalidArgumentException
|
||||
* @throws TypeError
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_ChaCha20_IetfCtx extends \ParagonIE_Sodium_Core_ChaCha20_Ctx
|
||||
public function __construct($key = '', $iv = '', $counter = '')
|
||||
{
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_ChaCha20_IetfCtx constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key ChaCha20 key.
|
||||
* @param string $iv Initialization Vector (a.k.a. nonce).
|
||||
* @param string $counter The initial counter value.
|
||||
* Defaults to 4 0x00 bytes.
|
||||
* @throws InvalidArgumentException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '', $iv = '', $counter = '')
|
||||
{
|
||||
if (self::strlen($iv) !== 12) {
|
||||
throw new \InvalidArgumentException('ChaCha20 expects a 96-bit nonce in IETF mode.');
|
||||
}
|
||||
parent::__construct($key, self::substr($iv, 0, 8), $counter);
|
||||
if (!empty($counter)) {
|
||||
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
|
||||
}
|
||||
$this->container[13] = self::load_4(self::substr($iv, 0, 4));
|
||||
$this->container[14] = self::load_4(self::substr($iv, 4, 4));
|
||||
$this->container[15] = self::load_4(self::substr($iv, 8, 4));
|
||||
if (self::strlen($iv) !== 12) {
|
||||
throw new InvalidArgumentException('ChaCha20 expects a 96-bit nonce in IETF mode.');
|
||||
}
|
||||
$counter = $this->initCounter($counter);
|
||||
parent::__construct($key, self::substr($iv, 0, 8), $counter);
|
||||
$this->container[12] = self::load_4(self::substr($counter, 0, 4));
|
||||
$this->container[13] = self::load_4(self::substr($iv, 0, 4));
|
||||
$this->container[14] = self::load_4(self::substr($iv, 4, 4));
|
||||
$this->container[15] = self::load_4(self::substr($iv, 8, 4));
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_ChaCha20_IetfCtx
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,125 +1,277 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_Curve25519_Fe', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Curve25519_Fe', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*
|
||||
* This represents a Field Element
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*
|
||||
* This represents a Field Element
|
||||
* @var int
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Fe implements \ArrayAccess
|
||||
public $e0 = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $e1 = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $e2 = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $e3 = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $e4 = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $e5 = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $e6 = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $e7 = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $e8 = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $e9 = 0;
|
||||
|
||||
/**
|
||||
* @param int $e0
|
||||
* @param int $e1
|
||||
* @param int $e2
|
||||
* @param int $e3
|
||||
* @param int $e4
|
||||
* @param int $e5
|
||||
* @param int $e6
|
||||
* @param int $e7
|
||||
* @param int $e8
|
||||
* @param int $e9
|
||||
*/
|
||||
public function __construct(
|
||||
$e0 = 0,
|
||||
$e1 = 0,
|
||||
$e2 = 0,
|
||||
$e3 = 0,
|
||||
$e4 = 0,
|
||||
$e5 = 0,
|
||||
$e6 = 0,
|
||||
$e7 = 0,
|
||||
$e8 = 0,
|
||||
$e9 = 0
|
||||
) {
|
||||
$this->e0 = $e0;
|
||||
$this->e1 = $e1;
|
||||
$this->e2 = $e2;
|
||||
$this->e3 = $e3;
|
||||
$this->e4 = $e4;
|
||||
$this->e5 = $e5;
|
||||
$this->e6 = $e6;
|
||||
$this->e7 = $e7;
|
||||
$this->e8 = $e8;
|
||||
$this->e9 = $e9;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param array $array
|
||||
* @return self
|
||||
*/
|
||||
public static function fromArray($array)
|
||||
{
|
||||
/**
|
||||
* @var array<int, int>
|
||||
*/
|
||||
protected $container = array();
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $size = 10;
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param array<int, int> $array
|
||||
* @param bool $save_indexes
|
||||
* @return self
|
||||
*/
|
||||
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_Curve25519_Fe();
|
||||
if ($save_indexes) {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$obj->offsetSet($keys[$i], $array[$i]);
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$obj->offsetSet($i, $array[$i]);
|
||||
}
|
||||
}
|
||||
return $obj;
|
||||
$obj = new ParagonIE_Sodium_Core_Curve25519_Fe();
|
||||
$obj->e0 = isset($array[0]) ? (int) $array[0] : 0;
|
||||
$obj->e1 = isset($array[1]) ? (int) $array[1] : 0;
|
||||
$obj->e2 = isset($array[2]) ? (int) $array[2] : 0;
|
||||
$obj->e3 = isset($array[3]) ? (int) $array[3] : 0;
|
||||
$obj->e4 = isset($array[4]) ? (int) $array[4] : 0;
|
||||
$obj->e5 = isset($array[5]) ? (int) $array[5] : 0;
|
||||
$obj->e6 = isset($array[6]) ? (int) $array[6] : 0;
|
||||
$obj->e7 = isset($array[7]) ? (int) $array[7] : 0;
|
||||
$obj->e8 = isset($array[8]) ? (int) $array[8] : 0;
|
||||
$obj->e9 = isset($array[9]) ? (int) $array[9] : 0;
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int|null $offset
|
||||
* @param int $value
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!is_int($value)) {
|
||||
throw new InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int|null $offset
|
||||
* @param int $value
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!\is_int($value)) {
|
||||
throw new \InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
if (\is_null($offset)) {
|
||||
$this->container[] = $value;
|
||||
} else {
|
||||
$this->container[$offset] = $value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->container[$offset]);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->container[$offset]);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return int
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (!isset($this->container[$offset])) {
|
||||
$this->container[$offset] = 0;
|
||||
}
|
||||
return (int) $this->container[$offset];
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo()
|
||||
{
|
||||
return array(\implode(', ', $this->container));
|
||||
switch ($offset) {
|
||||
case 0:
|
||||
$this->e0 = $value;
|
||||
break;
|
||||
case 1:
|
||||
$this->e1 = $value;
|
||||
break;
|
||||
case 2:
|
||||
$this->e2 = $value;
|
||||
break;
|
||||
case 3:
|
||||
$this->e3 = $value;
|
||||
break;
|
||||
case 4:
|
||||
$this->e4 = $value;
|
||||
break;
|
||||
case 5:
|
||||
$this->e5 = $value;
|
||||
break;
|
||||
case 6:
|
||||
$this->e6 = $value;
|
||||
break;
|
||||
case 7:
|
||||
$this->e7 = $value;
|
||||
break;
|
||||
case 8:
|
||||
$this->e8 = $value;
|
||||
break;
|
||||
case 9:
|
||||
$this->e9 = $value;
|
||||
break;
|
||||
default:
|
||||
throw new OutOfBoundsException('Index out of bounds');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* This represents a Field Element
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $offset >= 0 && $offset < 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
switch ($offset) {
|
||||
case 0:
|
||||
$this->e0 = 0;
|
||||
break;
|
||||
case 1:
|
||||
$this->e1 = 0;
|
||||
break;
|
||||
case 2:
|
||||
$this->e2 = 0;
|
||||
break;
|
||||
case 3:
|
||||
$this->e3 = 0;
|
||||
break;
|
||||
case 4:
|
||||
$this->e4 = 0;
|
||||
break;
|
||||
case 5:
|
||||
$this->e5 = 0;
|
||||
break;
|
||||
case 6:
|
||||
$this->e6 = 0;
|
||||
break;
|
||||
case 7:
|
||||
$this->e7 = 0;
|
||||
break;
|
||||
case 8:
|
||||
$this->e8 = 0;
|
||||
break;
|
||||
case 9:
|
||||
$this->e9 = 0;
|
||||
break;
|
||||
default:
|
||||
throw new OutOfBoundsException('Index out of bounds');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return int
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
switch ($offset) {
|
||||
case 0:
|
||||
return (int) $this->e0;
|
||||
case 1:
|
||||
return (int) $this->e1;
|
||||
case 2:
|
||||
return (int) $this->e2;
|
||||
case 3:
|
||||
return (int) $this->e3;
|
||||
case 4:
|
||||
return (int) $this->e4;
|
||||
case 5:
|
||||
return (int) $this->e5;
|
||||
case 6:
|
||||
return (int) $this->e6;
|
||||
case 7:
|
||||
return (int) $this->e7;
|
||||
case 8:
|
||||
return (int) $this->e8;
|
||||
case 9:
|
||||
return (int) $this->e9;
|
||||
default:
|
||||
throw new OutOfBoundsException('Index out of bounds');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo()
|
||||
{
|
||||
return array(
|
||||
implode(', ', array(
|
||||
$this->e0, $this->e1, $this->e2, $this->e3, $this->e4,
|
||||
$this->e5, $this->e6, $this->e7, $this->e8, $this->e9
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +1,77 @@
|
||||
<?php
|
||||
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_Cached', \false)) {
|
||||
return;
|
||||
}
|
||||
if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_Cached', false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_Cached
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_Cached
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_Cached
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_Cached
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $YplusX;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $YminusX;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $T2d;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_Cached constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $YplusX
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $YminusX
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $Z
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $T2d
|
||||
*/
|
||||
public function __construct($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;
|
||||
public $YplusX;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $YminusX;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $T2d;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_Cached constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $YplusX
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $YminusX
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $Z
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $T2d
|
||||
*/
|
||||
public function __construct(
|
||||
$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;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_Cached
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,73 +1,76 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_P1p1', false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $X;
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_P1p1', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $X;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $T;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $t
|
||||
*/
|
||||
public function __construct($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;
|
||||
public $Y;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $T;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $t
|
||||
*/
|
||||
public function __construct(
|
||||
$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;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,61 +1,63 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_P2', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_P2', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_P2
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_P2
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_P2
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_P2
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $X;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_P2 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z
|
||||
*/
|
||||
public function __construct($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;
|
||||
public $X;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_P2 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z
|
||||
*/
|
||||
public function __construct(
|
||||
$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;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_P2
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,73 +1,77 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_P3', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_P3', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_P3
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_P3
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_P3
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_P3
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $X;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $T;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_P3 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $t
|
||||
*/
|
||||
public function __construct($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;
|
||||
public $X;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $T;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_P3 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe|null $t
|
||||
*/
|
||||
public function __construct(
|
||||
$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;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_P3
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,61 +1,63 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_Precomp', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_Precomp', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $yplusx;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $yminusx;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $xy2d;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_Precomp constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $yplusx
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $yminusx
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $xy2d
|
||||
*/
|
||||
public function __construct($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;
|
||||
public $yplusx;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $yminusx;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public $xy2d;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Curve25519_Ge_Precomp constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $yplusx
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $yminusx
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $xy2d
|
||||
*/
|
||||
public function __construct(
|
||||
$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;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,414 +1,560 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_Ed25519', false)) {
|
||||
return;
|
||||
}
|
||||
if (!class_exists('ParagonIE_Sodium_Core_Curve25519', false)) {
|
||||
require_once dirname(__FILE__) . '/Curve25519.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Ed25519
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve25519
|
||||
{
|
||||
const KEYPAIR_BYTES = 96;
|
||||
const SEED_BYTES = 32;
|
||||
const SCALAR_BYTES = 32;
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Ed25519', \false)) {
|
||||
return;
|
||||
}
|
||||
if (!\class_exists('ParagonIE_Sodium_Core_Curve25519', \false)) {
|
||||
require_once \dirname(__FILE__) . '/Curve25519.php';
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Ed25519
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return string (96 bytes)
|
||||
* @throws Exception
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_Ed25519 extends \ParagonIE_Sodium_Core_Curve25519
|
||||
public static function keypair()
|
||||
{
|
||||
const KEYPAIR_BYTES = 96;
|
||||
const SEED_BYTES = 32;
|
||||
const SCALAR_BYTES = 32;
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return string (96 bytes)
|
||||
* @throws Exception
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function keypair()
|
||||
{
|
||||
$seed = \random_bytes(self::SEED_BYTES);
|
||||
$pk = '';
|
||||
$sk = '';
|
||||
self::seed_keypair($pk, $sk, $seed);
|
||||
return $sk . $pk;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $pk
|
||||
* @param string $sk
|
||||
* @param string $seed
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function seed_keypair(&$pk, &$sk, $seed)
|
||||
{
|
||||
if (self::strlen($seed) !== self::SEED_BYTES) {
|
||||
throw new \RangeException('crypto_sign keypair seed must be 32 bytes long');
|
||||
}
|
||||
/** @var string $pk */
|
||||
$pk = self::publickey_from_secretkey($seed);
|
||||
$sk = $seed . $pk;
|
||||
return $sk;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $keypair
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function secretkey($keypair)
|
||||
{
|
||||
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
|
||||
throw new \RangeException('crypto_sign keypair must be 96 bytes long');
|
||||
}
|
||||
return self::substr($keypair, 0, 64);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $keypair
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function publickey($keypair)
|
||||
{
|
||||
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
|
||||
throw new \RangeException('crypto_sign keypair must be 96 bytes long');
|
||||
}
|
||||
return self::substr($keypair, 64, 32);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function publickey_from_secretkey($sk)
|
||||
{
|
||||
/** @var string $sk */
|
||||
$sk = \hash('sha512', self::substr($sk, 0, 32), \true);
|
||||
$sk[0] = self::intToChr(self::chrToInt($sk[0]) & 248);
|
||||
$sk[31] = self::intToChr(self::chrToInt($sk[31]) & 63 | 64);
|
||||
return self::sk_to_pk($sk);
|
||||
}
|
||||
/**
|
||||
* @param string $pk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function pk_to_curve25519($pk)
|
||||
{
|
||||
if (self::small_order($pk)) {
|
||||
throw new \SodiumException('Public key is on a small order');
|
||||
}
|
||||
$A = self::ge_frombytes_negate_vartime(self::substr($pk, 0, 32));
|
||||
$p1 = self::ge_mul_l($A);
|
||||
if (!self::fe_isnonzero($p1->X)) {
|
||||
throw new \SodiumException('Unexpected zero result');
|
||||
}
|
||||
# fe_1(one_minus_y);
|
||||
# fe_sub(one_minus_y, one_minus_y, A.Y);
|
||||
# fe_invert(one_minus_y, one_minus_y);
|
||||
$one_minux_y = self::fe_invert(self::fe_sub(self::fe_1(), $A->Y));
|
||||
# fe_1(x);
|
||||
# fe_add(x, x, A.Y);
|
||||
# fe_mul(x, x, one_minus_y);
|
||||
$x = self::fe_mul(self::fe_add(self::fe_1(), $A->Y), $one_minux_y);
|
||||
# fe_tobytes(curve25519_pk, x);
|
||||
return self::fe_tobytes($x);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sk_to_pk($sk)
|
||||
{
|
||||
return self::ge_p3_tobytes(self::ge_scalarmult_base(self::substr($sk, 0, 32)));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign($message, $sk)
|
||||
{
|
||||
/** @var string $signature */
|
||||
$signature = self::sign_detached($message, $sk);
|
||||
return $signature . $message;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message A signed message
|
||||
* @param string $pk Public key
|
||||
* @return string Message (without signature)
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign_open($message, $pk)
|
||||
{
|
||||
/** @var string $signature */
|
||||
$signature = self::substr($message, 0, 64);
|
||||
/** @var string $message */
|
||||
$message = self::substr($message, 64);
|
||||
if (self::verify_detached($signature, $message, $pk)) {
|
||||
return $message;
|
||||
}
|
||||
throw new \SodiumException('Invalid signature');
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign_detached($message, $sk)
|
||||
{
|
||||
# crypto_hash_sha512(az, sk, 32);
|
||||
$az = \hash('sha512', self::substr($sk, 0, 32), \true);
|
||||
# az[0] &= 248;
|
||||
# az[31] &= 63;
|
||||
# az[31] |= 64;
|
||||
$az[0] = self::intToChr(self::chrToInt($az[0]) & 248);
|
||||
$az[31] = self::intToChr(self::chrToInt($az[31]) & 63 | 64);
|
||||
# crypto_hash_sha512_init(&hs);
|
||||
# crypto_hash_sha512_update(&hs, az + 32, 32);
|
||||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, nonce);
|
||||
$hs = \hash_init('sha512');
|
||||
\hash_update($hs, self::substr($az, 32, 32));
|
||||
\hash_update($hs, $message);
|
||||
$nonceHash = \hash_final($hs, \true);
|
||||
# memmove(sig + 32, sk + 32, 32);
|
||||
$pk = self::substr($sk, 32, 32);
|
||||
# sc_reduce(nonce);
|
||||
# ge_scalarmult_base(&R, nonce);
|
||||
# ge_p3_tobytes(sig, &R);
|
||||
$nonce = self::sc_reduce($nonceHash) . self::substr($nonceHash, 32);
|
||||
$sig = self::ge_p3_tobytes(self::ge_scalarmult_base($nonce));
|
||||
# crypto_hash_sha512_init(&hs);
|
||||
# crypto_hash_sha512_update(&hs, sig, 64);
|
||||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, hram);
|
||||
$hs = \hash_init('sha512');
|
||||
\hash_update($hs, self::substr($sig, 0, 32));
|
||||
\hash_update($hs, self::substr($pk, 0, 32));
|
||||
\hash_update($hs, $message);
|
||||
$hramHash = \hash_final($hs, \true);
|
||||
# sc_reduce(hram);
|
||||
# sc_muladd(sig + 32, hram, az, nonce);
|
||||
$hram = self::sc_reduce($hramHash);
|
||||
$sigAfter = self::sc_muladd($hram, $az, $nonce);
|
||||
$sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32);
|
||||
try {
|
||||
\ParagonIE_Sodium_Compat::memzero($az);
|
||||
} catch (\SodiumException $ex) {
|
||||
$az = null;
|
||||
}
|
||||
return $sig;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sig
|
||||
* @param string $message
|
||||
* @param string $pk
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function verify_detached($sig, $message, $pk)
|
||||
{
|
||||
if (self::strlen($sig) < 64) {
|
||||
throw new \SodiumException('Signature is too short');
|
||||
}
|
||||
if (self::chrToInt($sig[63]) & 240 && self::check_S_lt_L(self::substr($sig, 32, 32))) {
|
||||
throw new \SodiumException('S < L - Invalid signature');
|
||||
}
|
||||
if (self::small_order($sig)) {
|
||||
throw new \SodiumException('Signature is on too small of an order');
|
||||
}
|
||||
if ((self::chrToInt($sig[63]) & 224) !== 0) {
|
||||
throw new \SodiumException('Invalid signature');
|
||||
}
|
||||
$d = 0;
|
||||
for ($i = 0; $i < 32; ++$i) {
|
||||
$d |= self::chrToInt($pk[$i]);
|
||||
}
|
||||
if ($d === 0) {
|
||||
throw new \SodiumException('All zero public key');
|
||||
}
|
||||
/** @var bool The original value of ParagonIE_Sodium_Compat::$fastMult */
|
||||
$orig = \ParagonIE_Sodium_Compat::$fastMult;
|
||||
// Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification.
|
||||
\ParagonIE_Sodium_Compat::$fastMult = \true;
|
||||
/** @var ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A */
|
||||
$A = self::ge_frombytes_negate_vartime($pk);
|
||||
/** @var string $hDigest */
|
||||
$hDigest = \hash('sha512', self::substr($sig, 0, 32) . self::substr($pk, 0, 32) . $message, \true);
|
||||
/** @var string $h */
|
||||
$h = self::sc_reduce($hDigest) . self::substr($hDigest, 32);
|
||||
/** @var ParagonIE_Sodium_Core_Curve25519_Ge_P2 $R */
|
||||
$R = self::ge_double_scalarmult_vartime($h, $A, self::substr($sig, 32));
|
||||
/** @var string $rcheck */
|
||||
$rcheck = self::ge_tobytes($R);
|
||||
// Reset ParagonIE_Sodium_Compat::$fastMult to what it was before.
|
||||
\ParagonIE_Sodium_Compat::$fastMult = $orig;
|
||||
return self::verify_32($rcheck, self::substr($sig, 0, 32));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $S
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function check_S_lt_L($S)
|
||||
{
|
||||
if (self::strlen($S) < 32) {
|
||||
throw new \SodiumException('Signature must be 32 bytes');
|
||||
}
|
||||
$L = array(0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10);
|
||||
$c = 0;
|
||||
$n = 1;
|
||||
$i = 32;
|
||||
/** @var array<int, int> $L */
|
||||
do {
|
||||
--$i;
|
||||
$x = self::chrToInt($S[$i]);
|
||||
$c |= $x - $L[$i] >> 8 & $n;
|
||||
$n &= ($x ^ $L[$i]) - 1 >> 8;
|
||||
} while ($i !== 0);
|
||||
return $c === 0;
|
||||
}
|
||||
/**
|
||||
* @param string $R
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function small_order($R)
|
||||
{
|
||||
/** @var array<int, array<int, int>> $blocklist */
|
||||
$blocklist = array(
|
||||
/* 0 (order 4) */
|
||||
array(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0),
|
||||
/* 1 (order 1) */
|
||||
array(0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0),
|
||||
/* 2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
|
||||
array(0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x5, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x2, 0x88, 0x6d, 0x53, 0xfc, 0x5),
|
||||
/* 55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
|
||||
array(0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0xb, 0x76, 0xd, 0x10, 0x67, 0xf, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x3, 0x7a),
|
||||
/* p-1 (order 2) */
|
||||
array(0x13, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x5, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x2, 0x88, 0x6d, 0x53, 0xfc, 0x85),
|
||||
/* p (order 4) */
|
||||
array(0xb4, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0xb, 0x76, 0xd, 0x10, 0x67, 0xf, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x3, 0xfa),
|
||||
/* p+1 (order 1) */
|
||||
array(0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f),
|
||||
/* p+2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
|
||||
array(0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f),
|
||||
/* p+55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
|
||||
array(0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f),
|
||||
/* 2p-1 (order 2) */
|
||||
array(0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),
|
||||
/* 2p (order 4) */
|
||||
array(0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),
|
||||
/* 2p+1 (order 1) */
|
||||
array(0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),
|
||||
);
|
||||
/** @var int $countBlocklist */
|
||||
$countBlocklist = \count($blocklist);
|
||||
for ($i = 0; $i < $countBlocklist; ++$i) {
|
||||
$c = 0;
|
||||
for ($j = 0; $j < 32; ++$j) {
|
||||
$c |= self::chrToInt($R[$j]) ^ (int) $blocklist[$i][$j];
|
||||
}
|
||||
if ($c === 0) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_complement($s)
|
||||
{
|
||||
$t_ = self::L . \str_repeat("\x00", 32);
|
||||
\sodium_increment($t_);
|
||||
$s_ = $s . \str_repeat("\x00", 32);
|
||||
\ParagonIE_Sodium_Compat::sub($t_, $s_);
|
||||
return self::sc_reduce($t_);
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_random()
|
||||
{
|
||||
do {
|
||||
$r = \ParagonIE_Sodium_Compat::randombytes_buf(self::SCALAR_BYTES);
|
||||
$r[self::SCALAR_BYTES - 1] = self::intToChr(self::chrToInt($r[self::SCALAR_BYTES - 1]) & 0x1f);
|
||||
} while (!self::check_S_lt_L($r) || \ParagonIE_Sodium_Compat::is_zero($r));
|
||||
return $r;
|
||||
}
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_negate($s)
|
||||
{
|
||||
$t_ = self::L . \str_repeat("\x00", 32);
|
||||
$s_ = $s . \str_repeat("\x00", 32);
|
||||
\ParagonIE_Sodium_Compat::sub($t_, $s_);
|
||||
return self::sc_reduce($t_);
|
||||
}
|
||||
/**
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_add($a, $b)
|
||||
{
|
||||
$a_ = $a . \str_repeat("\x00", 32);
|
||||
$b_ = $b . \str_repeat("\x00", 32);
|
||||
\ParagonIE_Sodium_Compat::add($a_, $b_);
|
||||
return self::sc_reduce($a_);
|
||||
}
|
||||
/**
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_sub($x, $y)
|
||||
{
|
||||
$yn = self::scalar_negate($y);
|
||||
return self::scalar_add($x, $yn);
|
||||
}
|
||||
$seed = random_bytes(self::SEED_BYTES);
|
||||
$pk = '';
|
||||
$sk = '';
|
||||
self::seed_keypair($pk, $sk, $seed);
|
||||
return $sk . $pk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Ed25519
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $pk
|
||||
* @param string $sk
|
||||
* @param string $seed
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function seed_keypair(&$pk, &$sk, $seed)
|
||||
{
|
||||
if (self::strlen($seed) !== self::SEED_BYTES) {
|
||||
throw new SodiumException('crypto_sign keypair seed must be 32 bytes long');
|
||||
}
|
||||
|
||||
/** @var string $pk */
|
||||
$pk = self::publickey_from_secretkey($seed);
|
||||
$sk = $seed . $pk;
|
||||
return $sk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $keypair
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function secretkey($keypair)
|
||||
{
|
||||
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
|
||||
throw new SodiumException('crypto_sign keypair must be 96 bytes long');
|
||||
}
|
||||
return self::substr($keypair, 0, 64);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $keypair
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function publickey($keypair)
|
||||
{
|
||||
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
|
||||
throw new SodiumException('crypto_sign keypair must be 96 bytes long');
|
||||
}
|
||||
return self::substr($keypair, 64, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function publickey_from_secretkey($sk)
|
||||
{
|
||||
/** @var string $sk */
|
||||
$sk = hash('sha512', self::substr($sk, 0, 32), true);
|
||||
$sk[0] = self::intToChr(
|
||||
self::chrToInt($sk[0]) & 248
|
||||
);
|
||||
$sk[31] = self::intToChr(
|
||||
(self::chrToInt($sk[31]) & 63) | 64
|
||||
);
|
||||
return self::sk_to_pk($sk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function pk_to_curve25519($pk)
|
||||
{
|
||||
if (self::small_order($pk)) {
|
||||
throw new SodiumException('Public key is on a small order');
|
||||
}
|
||||
$A = self::ge_frombytes_negate_vartime(self::substr($pk, 0, 32));
|
||||
$p1 = self::ge_mul_l($A);
|
||||
if (!self::fe_isnonzero($p1->X)) {
|
||||
throw new SodiumException('Unexpected zero result');
|
||||
}
|
||||
|
||||
# fe_1(one_minus_y);
|
||||
# fe_sub(one_minus_y, one_minus_y, A.Y);
|
||||
# fe_invert(one_minus_y, one_minus_y);
|
||||
$one_minux_y = self::fe_invert(
|
||||
self::fe_sub(
|
||||
self::fe_1(),
|
||||
$A->Y
|
||||
)
|
||||
);
|
||||
|
||||
# fe_1(x);
|
||||
# fe_add(x, x, A.Y);
|
||||
# fe_mul(x, x, one_minus_y);
|
||||
$x = self::fe_mul(
|
||||
self::fe_add(self::fe_1(), $A->Y),
|
||||
$one_minux_y
|
||||
);
|
||||
|
||||
# fe_tobytes(curve25519_pk, x);
|
||||
return self::fe_tobytes($x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sk_to_pk($sk)
|
||||
{
|
||||
return self::ge_p3_tobytes(
|
||||
self::ge_scalarmult_base(
|
||||
self::substr($sk, 0, 32)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign($message, $sk)
|
||||
{
|
||||
/** @var string $signature */
|
||||
$signature = self::sign_detached($message, $sk);
|
||||
return $signature . $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message A signed message
|
||||
* @param string $pk Public key
|
||||
* @return string Message (without signature)
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign_open($message, $pk)
|
||||
{
|
||||
/** @var string $signature */
|
||||
$signature = self::substr($message, 0, 64);
|
||||
|
||||
/** @var string $message */
|
||||
$message = self::substr($message, 64);
|
||||
|
||||
if (self::verify_detached($signature, $message, $pk)) {
|
||||
return $message;
|
||||
}
|
||||
throw new SodiumException('Invalid signature');
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign_detached($message, $sk)
|
||||
{
|
||||
if (self::strlen($sk) !== 64) {
|
||||
throw new SodiumException('Argument 2 must be CRYPTO_SIGN_SECRETKEYBYTES long');
|
||||
}
|
||||
# crypto_hash_sha512(az, sk, 32);
|
||||
$az = hash('sha512', self::substr($sk, 0, 32), true);
|
||||
|
||||
# az[0] &= 248;
|
||||
# az[31] &= 63;
|
||||
# az[31] |= 64;
|
||||
$az[0] = self::intToChr(self::chrToInt($az[0]) & 248);
|
||||
$az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64);
|
||||
|
||||
# crypto_hash_sha512_init(&hs);
|
||||
# crypto_hash_sha512_update(&hs, az + 32, 32);
|
||||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, nonce);
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($az, 32, 32));
|
||||
hash_update($hs, $message);
|
||||
$nonceHash = hash_final($hs, true);
|
||||
|
||||
# memmove(sig + 32, sk + 32, 32);
|
||||
$pk = self::substr($sk, 32, 32);
|
||||
|
||||
# sc_reduce(nonce);
|
||||
# ge_scalarmult_base(&R, nonce);
|
||||
# ge_p3_tobytes(sig, &R);
|
||||
$nonce = self::sc_reduce($nonceHash) . self::substr($nonceHash, 32);
|
||||
$sig = self::ge_p3_tobytes(
|
||||
self::ge_scalarmult_base($nonce)
|
||||
);
|
||||
|
||||
# crypto_hash_sha512_init(&hs);
|
||||
# crypto_hash_sha512_update(&hs, sig, 64);
|
||||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, hram);
|
||||
$hs = hash_init('sha512');
|
||||
hash_update($hs, self::substr($sig, 0, 32));
|
||||
hash_update($hs, self::substr($pk, 0, 32));
|
||||
hash_update($hs, $message);
|
||||
$hramHash = hash_final($hs, true);
|
||||
|
||||
# sc_reduce(hram);
|
||||
# sc_muladd(sig + 32, hram, az, nonce);
|
||||
$hram = self::sc_reduce($hramHash);
|
||||
$sigAfter = self::sc_muladd($hram, $az, $nonce);
|
||||
$sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32);
|
||||
|
||||
try {
|
||||
ParagonIE_Sodium_Compat::memzero($az);
|
||||
} catch (SodiumException $ex) {
|
||||
$az = null;
|
||||
}
|
||||
return $sig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sig
|
||||
* @param string $message
|
||||
* @param string $pk
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function verify_detached($sig, $message, $pk)
|
||||
{
|
||||
if (self::strlen($sig) !== 64) {
|
||||
throw new SodiumException('Argument 1 must be CRYPTO_SIGN_BYTES long');
|
||||
}
|
||||
if (self::strlen($pk) !== 32) {
|
||||
throw new SodiumException('Argument 3 must be CRYPTO_SIGN_PUBLICKEYBYTES long');
|
||||
}
|
||||
if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) {
|
||||
throw new SodiumException('S < L - Invalid signature');
|
||||
}
|
||||
if (self::small_order($sig)) {
|
||||
throw new SodiumException('Signature is on too small of an order');
|
||||
}
|
||||
if ((self::chrToInt($sig[63]) & 224) !== 0) {
|
||||
throw new SodiumException('Invalid signature');
|
||||
}
|
||||
$d = 0;
|
||||
for ($i = 0; $i < 32; ++$i) {
|
||||
$d |= self::chrToInt($pk[$i]);
|
||||
}
|
||||
if ($d === 0) {
|
||||
throw new SodiumException('All zero public key');
|
||||
}
|
||||
|
||||
/** @var bool The original value of ParagonIE_Sodium_Compat::$fastMult */
|
||||
$orig = ParagonIE_Sodium_Compat::$fastMult;
|
||||
|
||||
// Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification.
|
||||
ParagonIE_Sodium_Compat::$fastMult = true;
|
||||
|
||||
/** @var ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A */
|
||||
$A = self::ge_frombytes_negate_vartime($pk);
|
||||
|
||||
/** @var string $hDigest */
|
||||
$hDigest = hash(
|
||||
'sha512',
|
||||
self::substr($sig, 0, 32) .
|
||||
self::substr($pk, 0, 32) .
|
||||
$message,
|
||||
true
|
||||
);
|
||||
|
||||
/** @var string $h */
|
||||
$h = self::sc_reduce($hDigest) . self::substr($hDigest, 32);
|
||||
|
||||
/** @var ParagonIE_Sodium_Core_Curve25519_Ge_P2 $R */
|
||||
$R = self::ge_double_scalarmult_vartime(
|
||||
$h,
|
||||
$A,
|
||||
self::substr($sig, 32)
|
||||
);
|
||||
|
||||
/** @var string $rcheck */
|
||||
$rcheck = self::ge_tobytes($R);
|
||||
|
||||
// Reset ParagonIE_Sodium_Compat::$fastMult to what it was before.
|
||||
ParagonIE_Sodium_Compat::$fastMult = $orig;
|
||||
|
||||
return self::verify_32($rcheck, self::substr($sig, 0, 32));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $S
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function check_S_lt_L($S)
|
||||
{
|
||||
if (self::strlen($S) < 32) {
|
||||
throw new SodiumException('Signature must be 32 bytes');
|
||||
}
|
||||
$L = array(
|
||||
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
|
||||
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
|
||||
);
|
||||
$c = 0;
|
||||
$n = 1;
|
||||
$i = 32;
|
||||
|
||||
/** @var array<int, int> $L */
|
||||
do {
|
||||
--$i;
|
||||
$x = self::chrToInt($S[$i]);
|
||||
$c |= (
|
||||
(($x - $L[$i]) >> 8) & $n
|
||||
);
|
||||
$n &= (
|
||||
(($x ^ $L[$i]) - 1) >> 8
|
||||
);
|
||||
} while ($i !== 0);
|
||||
|
||||
return $c === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $R
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function small_order($R)
|
||||
{
|
||||
/** @var array<int, array<int, int>> $blocklist */
|
||||
$blocklist = array(
|
||||
/* 0 (order 4) */
|
||||
array(
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
),
|
||||
/* 1 (order 1) */
|
||||
array(
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
),
|
||||
/* 2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
|
||||
array(
|
||||
0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0,
|
||||
0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0,
|
||||
0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39,
|
||||
0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05
|
||||
),
|
||||
/* 55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
|
||||
array(
|
||||
0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f,
|
||||
0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f,
|
||||
0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6,
|
||||
0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a
|
||||
),
|
||||
/* p-1 (order 2) */
|
||||
array(
|
||||
0x13, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0,
|
||||
0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0,
|
||||
0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39,
|
||||
0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x85
|
||||
),
|
||||
/* p (order 4) */
|
||||
array(
|
||||
0xb4, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f,
|
||||
0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f,
|
||||
0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6,
|
||||
0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0xfa
|
||||
),
|
||||
/* p+1 (order 1) */
|
||||
array(
|
||||
0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
|
||||
),
|
||||
/* p+2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
|
||||
array(
|
||||
0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
|
||||
),
|
||||
/* p+55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
|
||||
array(
|
||||
0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
|
||||
),
|
||||
/* 2p-1 (order 2) */
|
||||
array(
|
||||
0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
),
|
||||
/* 2p (order 4) */
|
||||
array(
|
||||
0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
),
|
||||
/* 2p+1 (order 1) */
|
||||
array(
|
||||
0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
)
|
||||
);
|
||||
/** @var int $countBlocklist */
|
||||
$countBlocklist = count($blocklist);
|
||||
|
||||
for ($i = 0; $i < $countBlocklist; ++$i) {
|
||||
$c = 0;
|
||||
for ($j = 0; $j < 32; ++$j) {
|
||||
$c |= self::chrToInt($R[$j]) ^ (int) $blocklist[$i][$j];
|
||||
}
|
||||
if ($c === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_complement($s)
|
||||
{
|
||||
$t_ = self::L . str_repeat("\x00", 32);
|
||||
sodium_increment($t_);
|
||||
$s_ = $s . str_repeat("\x00", 32);
|
||||
ParagonIE_Sodium_Compat::sub($t_, $s_);
|
||||
return self::sc_reduce($t_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_random()
|
||||
{
|
||||
do {
|
||||
$r = ParagonIE_Sodium_Compat::randombytes_buf(self::SCALAR_BYTES);
|
||||
$r[self::SCALAR_BYTES - 1] = self::intToChr(
|
||||
self::chrToInt($r[self::SCALAR_BYTES - 1]) & 0x1f
|
||||
);
|
||||
} while (
|
||||
!self::check_S_lt_L($r) || ParagonIE_Sodium_Compat::is_zero($r)
|
||||
);
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_negate($s)
|
||||
{
|
||||
$t_ = self::L . str_repeat("\x00", 32) ;
|
||||
$s_ = $s . str_repeat("\x00", 32) ;
|
||||
ParagonIE_Sodium_Compat::sub($t_, $s_);
|
||||
return self::sc_reduce($t_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_add($a, $b)
|
||||
{
|
||||
$a_ = $a . str_repeat("\x00", 32);
|
||||
$b_ = $b . str_repeat("\x00", 32);
|
||||
ParagonIE_Sodium_Compat::add($a_, $b_);
|
||||
return self::sc_reduce($a_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $x
|
||||
* @param string $y
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
*/
|
||||
public static function scalar_sub($x, $y)
|
||||
{
|
||||
$yn = self::scalar_negate($y);
|
||||
return self::scalar_add($x, $yn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,94 +1,116 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_HChaCha20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_HChaCha20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_HChaCha20
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_HChaCha20 extends ParagonIE_Sodium_Core_ChaCha20
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_HChaCha20
|
||||
* @param string $in
|
||||
* @param string $key
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
*
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_HChaCha20 extends \ParagonIE_Sodium_Core_ChaCha20
|
||||
public static function hChaCha20($in, $key, $c = null)
|
||||
{
|
||||
/**
|
||||
* @param string $in
|
||||
* @param string $key
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function hChaCha20($in = '', $key = '', $c = null)
|
||||
{
|
||||
$ctx = array();
|
||||
if ($c === null) {
|
||||
$ctx[0] = 0x61707865;
|
||||
$ctx[1] = 0x3320646e;
|
||||
$ctx[2] = 0x79622d32;
|
||||
$ctx[3] = 0x6b206574;
|
||||
} else {
|
||||
$ctx[0] = self::load_4(self::substr($c, 0, 4));
|
||||
$ctx[1] = self::load_4(self::substr($c, 4, 4));
|
||||
$ctx[2] = self::load_4(self::substr($c, 8, 4));
|
||||
$ctx[3] = self::load_4(self::substr($c, 12, 4));
|
||||
}
|
||||
$ctx[4] = self::load_4(self::substr($key, 0, 4));
|
||||
$ctx[5] = self::load_4(self::substr($key, 4, 4));
|
||||
$ctx[6] = self::load_4(self::substr($key, 8, 4));
|
||||
$ctx[7] = self::load_4(self::substr($key, 12, 4));
|
||||
$ctx[8] = self::load_4(self::substr($key, 16, 4));
|
||||
$ctx[9] = self::load_4(self::substr($key, 20, 4));
|
||||
$ctx[10] = self::load_4(self::substr($key, 24, 4));
|
||||
$ctx[11] = self::load_4(self::substr($key, 28, 4));
|
||||
$ctx[12] = self::load_4(self::substr($in, 0, 4));
|
||||
$ctx[13] = self::load_4(self::substr($in, 4, 4));
|
||||
$ctx[14] = self::load_4(self::substr($in, 8, 4));
|
||||
$ctx[15] = self::load_4(self::substr($in, 12, 4));
|
||||
return self::hChaCha20Bytes($ctx);
|
||||
if (self::strlen($in) !== 16) {
|
||||
throw new SodiumException('Argument 1 must be 16 bytes');
|
||||
}
|
||||
/**
|
||||
* @param array $ctx
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
protected static function hChaCha20Bytes(array $ctx)
|
||||
{
|
||||
$x0 = (int) $ctx[0];
|
||||
$x1 = (int) $ctx[1];
|
||||
$x2 = (int) $ctx[2];
|
||||
$x3 = (int) $ctx[3];
|
||||
$x4 = (int) $ctx[4];
|
||||
$x5 = (int) $ctx[5];
|
||||
$x6 = (int) $ctx[6];
|
||||
$x7 = (int) $ctx[7];
|
||||
$x8 = (int) $ctx[8];
|
||||
$x9 = (int) $ctx[9];
|
||||
$x10 = (int) $ctx[10];
|
||||
$x11 = (int) $ctx[11];
|
||||
$x12 = (int) $ctx[12];
|
||||
$x13 = (int) $ctx[13];
|
||||
$x14 = (int) $ctx[14];
|
||||
$x15 = (int) $ctx[15];
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
# QUARTERROUND( x0, x4, x8, x12)
|
||||
list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
|
||||
# QUARTERROUND( x1, x5, x9, x13)
|
||||
list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
|
||||
# QUARTERROUND( x2, x6, x10, x14)
|
||||
list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
|
||||
# QUARTERROUND( x3, x7, x11, x15)
|
||||
list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
|
||||
# QUARTERROUND( x0, x5, x10, x15)
|
||||
list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
|
||||
# QUARTERROUND( x1, x6, x11, x12)
|
||||
list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
|
||||
# QUARTERROUND( x2, x7, x8, x13)
|
||||
list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
|
||||
# QUARTERROUND( x3, x4, x9, x14)
|
||||
list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
|
||||
}
|
||||
return self::store32_le((int) ($x0 & 0xffffffff)) . self::store32_le((int) ($x1 & 0xffffffff)) . self::store32_le((int) ($x2 & 0xffffffff)) . self::store32_le((int) ($x3 & 0xffffffff)) . self::store32_le((int) ($x12 & 0xffffffff)) . self::store32_le((int) ($x13 & 0xffffffff)) . self::store32_le((int) ($x14 & 0xffffffff)) . self::store32_le((int) ($x15 & 0xffffffff));
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new SodiumException('Argument 2 must be 32 bytes');
|
||||
}
|
||||
$ctx = array();
|
||||
|
||||
if ($c === null) {
|
||||
$ctx[0] = 0x61707865;
|
||||
$ctx[1] = 0x3320646e;
|
||||
$ctx[2] = 0x79622d32;
|
||||
$ctx[3] = 0x6b206574;
|
||||
} else {
|
||||
$ctx[0] = self::load_4(self::substr($c, 0, 4));
|
||||
$ctx[1] = self::load_4(self::substr($c, 4, 4));
|
||||
$ctx[2] = self::load_4(self::substr($c, 8, 4));
|
||||
$ctx[3] = self::load_4(self::substr($c, 12, 4));
|
||||
}
|
||||
$ctx[4] = self::load_4(self::substr($key, 0, 4));
|
||||
$ctx[5] = self::load_4(self::substr($key, 4, 4));
|
||||
$ctx[6] = self::load_4(self::substr($key, 8, 4));
|
||||
$ctx[7] = self::load_4(self::substr($key, 12, 4));
|
||||
$ctx[8] = self::load_4(self::substr($key, 16, 4));
|
||||
$ctx[9] = self::load_4(self::substr($key, 20, 4));
|
||||
$ctx[10] = self::load_4(self::substr($key, 24, 4));
|
||||
$ctx[11] = self::load_4(self::substr($key, 28, 4));
|
||||
$ctx[12] = self::load_4(self::substr($in, 0, 4));
|
||||
$ctx[13] = self::load_4(self::substr($in, 4, 4));
|
||||
$ctx[14] = self::load_4(self::substr($in, 8, 4));
|
||||
$ctx[15] = self::load_4(self::substr($in, 12, 4));
|
||||
return self::hChaCha20Bytes($ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_HChaCha20
|
||||
* @param array $ctx
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
protected static function hChaCha20Bytes(array $ctx)
|
||||
{
|
||||
$x0 = (int) $ctx[0];
|
||||
$x1 = (int) $ctx[1];
|
||||
$x2 = (int) $ctx[2];
|
||||
$x3 = (int) $ctx[3];
|
||||
$x4 = (int) $ctx[4];
|
||||
$x5 = (int) $ctx[5];
|
||||
$x6 = (int) $ctx[6];
|
||||
$x7 = (int) $ctx[7];
|
||||
$x8 = (int) $ctx[8];
|
||||
$x9 = (int) $ctx[9];
|
||||
$x10 = (int) $ctx[10];
|
||||
$x11 = (int) $ctx[11];
|
||||
$x12 = (int) $ctx[12];
|
||||
$x13 = (int) $ctx[13];
|
||||
$x14 = (int) $ctx[14];
|
||||
$x15 = (int) $ctx[15];
|
||||
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
# QUARTERROUND( x0, x4, x8, x12)
|
||||
list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
|
||||
|
||||
# QUARTERROUND( x1, x5, x9, x13)
|
||||
list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
|
||||
|
||||
# QUARTERROUND( x2, x6, x10, x14)
|
||||
list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
|
||||
|
||||
# QUARTERROUND( x3, x7, x11, x15)
|
||||
list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
|
||||
|
||||
# QUARTERROUND( x0, x5, x10, x15)
|
||||
list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
|
||||
|
||||
# QUARTERROUND( x1, x6, x11, x12)
|
||||
list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
|
||||
|
||||
# QUARTERROUND( x2, x7, x8, x13)
|
||||
list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
|
||||
|
||||
# QUARTERROUND( x3, x4, x9, x14)
|
||||
list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
|
||||
}
|
||||
|
||||
return self::store32_le((int) ($x0 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x1 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x2 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x3 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x12 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x13 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x14 & 0xffffffff)) .
|
||||
self::store32_le((int) ($x15 & 0xffffffff));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,91 +1,96 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_HSalsa20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_HSalsa20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_HSalsa20
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_HSalsa20 extends ParagonIE_Sodium_Core_Salsa20
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_HSalsa20
|
||||
* Calculate an hsalsa20 hash of a single block
|
||||
*
|
||||
* HSalsa20 doesn't have a counter and will never be used for more than
|
||||
* one block (used to derive a subkey for xsalsa20).
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $k
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_HSalsa20 extends \ParagonIE_Sodium_Core_Salsa20
|
||||
public static function hsalsa20($in, $k, $c = null)
|
||||
{
|
||||
/**
|
||||
* Calculate an hsalsa20 hash of a single block
|
||||
*
|
||||
* HSalsa20 doesn't have a counter and will never be used for more than
|
||||
* one block (used to derive a subkey for xsalsa20).
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $k
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function hsalsa20($in, $k, $c = null)
|
||||
{
|
||||
if ($c === null) {
|
||||
$x0 = 0x61707865;
|
||||
$x5 = 0x3320646e;
|
||||
$x10 = 0x79622d32;
|
||||
$x15 = 0x6b206574;
|
||||
} else {
|
||||
$x0 = self::load_4(self::substr($c, 0, 4));
|
||||
$x5 = self::load_4(self::substr($c, 4, 4));
|
||||
$x10 = self::load_4(self::substr($c, 8, 4));
|
||||
$x15 = self::load_4(self::substr($c, 12, 4));
|
||||
}
|
||||
$x1 = self::load_4(self::substr($k, 0, 4));
|
||||
$x2 = self::load_4(self::substr($k, 4, 4));
|
||||
$x3 = self::load_4(self::substr($k, 8, 4));
|
||||
$x4 = self::load_4(self::substr($k, 12, 4));
|
||||
$x11 = self::load_4(self::substr($k, 16, 4));
|
||||
$x12 = self::load_4(self::substr($k, 20, 4));
|
||||
$x13 = self::load_4(self::substr($k, 24, 4));
|
||||
$x14 = self::load_4(self::substr($k, 28, 4));
|
||||
$x6 = self::load_4(self::substr($in, 0, 4));
|
||||
$x7 = self::load_4(self::substr($in, 4, 4));
|
||||
$x8 = self::load_4(self::substr($in, 8, 4));
|
||||
$x9 = self::load_4(self::substr($in, 12, 4));
|
||||
for ($i = self::ROUNDS; $i > 0; $i -= 2) {
|
||||
$x4 ^= self::rotate($x0 + $x12, 7);
|
||||
$x8 ^= self::rotate($x4 + $x0, 9);
|
||||
$x12 ^= self::rotate($x8 + $x4, 13);
|
||||
$x0 ^= self::rotate($x12 + $x8, 18);
|
||||
$x9 ^= self::rotate($x5 + $x1, 7);
|
||||
$x13 ^= self::rotate($x9 + $x5, 9);
|
||||
$x1 ^= self::rotate($x13 + $x9, 13);
|
||||
$x5 ^= self::rotate($x1 + $x13, 18);
|
||||
$x14 ^= self::rotate($x10 + $x6, 7);
|
||||
$x2 ^= self::rotate($x14 + $x10, 9);
|
||||
$x6 ^= self::rotate($x2 + $x14, 13);
|
||||
$x10 ^= self::rotate($x6 + $x2, 18);
|
||||
$x3 ^= self::rotate($x15 + $x11, 7);
|
||||
$x7 ^= self::rotate($x3 + $x15, 9);
|
||||
$x11 ^= self::rotate($x7 + $x3, 13);
|
||||
$x15 ^= self::rotate($x11 + $x7, 18);
|
||||
$x1 ^= self::rotate($x0 + $x3, 7);
|
||||
$x2 ^= self::rotate($x1 + $x0, 9);
|
||||
$x3 ^= self::rotate($x2 + $x1, 13);
|
||||
$x0 ^= self::rotate($x3 + $x2, 18);
|
||||
$x6 ^= self::rotate($x5 + $x4, 7);
|
||||
$x7 ^= self::rotate($x6 + $x5, 9);
|
||||
$x4 ^= self::rotate($x7 + $x6, 13);
|
||||
$x5 ^= self::rotate($x4 + $x7, 18);
|
||||
$x11 ^= self::rotate($x10 + $x9, 7);
|
||||
$x8 ^= self::rotate($x11 + $x10, 9);
|
||||
$x9 ^= self::rotate($x8 + $x11, 13);
|
||||
$x10 ^= self::rotate($x9 + $x8, 18);
|
||||
$x12 ^= self::rotate($x15 + $x14, 7);
|
||||
$x13 ^= self::rotate($x12 + $x15, 9);
|
||||
$x14 ^= self::rotate($x13 + $x12, 13);
|
||||
$x15 ^= self::rotate($x14 + $x13, 18);
|
||||
}
|
||||
return self::store32_le($x0) . self::store32_le($x5) . self::store32_le($x10) . self::store32_le($x15) . self::store32_le($x6) . self::store32_le($x7) . self::store32_le($x8) . self::store32_le($x9);
|
||||
if ($c === null) {
|
||||
$x0 = 0x61707865;
|
||||
$x5 = 0x3320646e;
|
||||
$x10 = 0x79622d32;
|
||||
$x15 = 0x6b206574;
|
||||
} else {
|
||||
$x0 = self::load_4(self::substr($c, 0, 4));
|
||||
$x5 = self::load_4(self::substr($c, 4, 4));
|
||||
$x10 = self::load_4(self::substr($c, 8, 4));
|
||||
$x15 = self::load_4(self::substr($c, 12, 4));
|
||||
}
|
||||
$x1 = self::load_4(self::substr($k, 0, 4));
|
||||
$x2 = self::load_4(self::substr($k, 4, 4));
|
||||
$x3 = self::load_4(self::substr($k, 8, 4));
|
||||
$x4 = self::load_4(self::substr($k, 12, 4));
|
||||
$x11 = self::load_4(self::substr($k, 16, 4));
|
||||
$x12 = self::load_4(self::substr($k, 20, 4));
|
||||
$x13 = self::load_4(self::substr($k, 24, 4));
|
||||
$x14 = self::load_4(self::substr($k, 28, 4));
|
||||
$x6 = self::load_4(self::substr($in, 0, 4));
|
||||
$x7 = self::load_4(self::substr($in, 4, 4));
|
||||
$x8 = self::load_4(self::substr($in, 8, 4));
|
||||
$x9 = self::load_4(self::substr($in, 12, 4));
|
||||
|
||||
for ($i = self::ROUNDS; $i > 0; $i -= 2) {
|
||||
$x4 ^= self::rotate($x0 + $x12, 7);
|
||||
$x8 ^= self::rotate($x4 + $x0, 9);
|
||||
$x12 ^= self::rotate($x8 + $x4, 13);
|
||||
$x0 ^= self::rotate($x12 + $x8, 18);
|
||||
$x9 ^= self::rotate($x5 + $x1, 7);
|
||||
$x13 ^= self::rotate($x9 + $x5, 9);
|
||||
$x1 ^= self::rotate($x13 + $x9, 13);
|
||||
$x5 ^= self::rotate($x1 + $x13, 18);
|
||||
$x14 ^= self::rotate($x10 + $x6, 7);
|
||||
$x2 ^= self::rotate($x14 + $x10, 9);
|
||||
$x6 ^= self::rotate($x2 + $x14, 13);
|
||||
$x10 ^= self::rotate($x6 + $x2, 18);
|
||||
$x3 ^= self::rotate($x15 + $x11, 7);
|
||||
$x7 ^= self::rotate($x3 + $x15, 9);
|
||||
$x11 ^= self::rotate($x7 + $x3, 13);
|
||||
$x15 ^= self::rotate($x11 + $x7, 18);
|
||||
$x1 ^= self::rotate($x0 + $x3, 7);
|
||||
$x2 ^= self::rotate($x1 + $x0, 9);
|
||||
$x3 ^= self::rotate($x2 + $x1, 13);
|
||||
$x0 ^= self::rotate($x3 + $x2, 18);
|
||||
$x6 ^= self::rotate($x5 + $x4, 7);
|
||||
$x7 ^= self::rotate($x6 + $x5, 9);
|
||||
$x4 ^= self::rotate($x7 + $x6, 13);
|
||||
$x5 ^= self::rotate($x4 + $x7, 18);
|
||||
$x11 ^= self::rotate($x10 + $x9, 7);
|
||||
$x8 ^= self::rotate($x11 + $x10, 9);
|
||||
$x9 ^= self::rotate($x8 + $x11, 13);
|
||||
$x10 ^= self::rotate($x9 + $x8, 18);
|
||||
$x12 ^= self::rotate($x15 + $x14, 7);
|
||||
$x13 ^= self::rotate($x12 + $x15, 9);
|
||||
$x14 ^= self::rotate($x13 + $x12, 13);
|
||||
$x15 ^= self::rotate($x14 + $x13, 18);
|
||||
}
|
||||
|
||||
return self::store32_le($x0) .
|
||||
self::store32_le($x5) .
|
||||
self::store32_le($x10) .
|
||||
self::store32_le($x15) .
|
||||
self::store32_le($x6) .
|
||||
self::store32_le($x7) .
|
||||
self::store32_le($x8) .
|
||||
self::store32_le($x9);
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_HSalsa20
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,53 +1,63 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_Poly1305', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Poly1305
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_Poly1305 extends ParagonIE_Sodium_Core_Util
|
||||
{
|
||||
const BLOCK_SIZE = 16;
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Poly1305', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Poly1305
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $m
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_Poly1305 extends \ParagonIE_Sodium_Core_Util
|
||||
public static function onetimeauth($m, $key)
|
||||
{
|
||||
const BLOCK_SIZE = 16;
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $m
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function onetimeauth($m, $key)
|
||||
{
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new \InvalidArgumentException('Key must be 32 bytes long.');
|
||||
}
|
||||
$state = new \ParagonIE_Sodium_Core_Poly1305_State(self::substr($key, 0, 32));
|
||||
return $state->update($m)->finish();
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $mac
|
||||
* @param string $m
|
||||
* @param string $key
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function onetimeauth_verify($mac, $m, $key)
|
||||
{
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new \InvalidArgumentException('Key must be 32 bytes long.');
|
||||
}
|
||||
$state = new \ParagonIE_Sodium_Core_Poly1305_State(self::substr($key, 0, 32));
|
||||
$calc = $state->update($m)->finish();
|
||||
return self::verify_16($calc, $mac);
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new InvalidArgumentException(
|
||||
'Key must be 32 bytes long.'
|
||||
);
|
||||
}
|
||||
$state = new ParagonIE_Sodium_Core_Poly1305_State(
|
||||
self::substr($key, 0, 32)
|
||||
);
|
||||
return $state
|
||||
->update($m)
|
||||
->finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Poly1305
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $mac
|
||||
* @param string $m
|
||||
* @param string $key
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function onetimeauth_verify($mac, $m, $key)
|
||||
{
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new InvalidArgumentException(
|
||||
'Key must be 32 bytes long.'
|
||||
);
|
||||
}
|
||||
$state = new ParagonIE_Sodium_Core_Poly1305_State(
|
||||
self::substr($key, 0, 32)
|
||||
);
|
||||
$calc = $state
|
||||
->update($m)
|
||||
->finish();
|
||||
return self::verify_16($calc, $mac);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,339 +1,445 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_Poly1305_State', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Poly1305_State', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Poly1305_State
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Poly1305_State extends ParagonIE_Sodium_Core_Util
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Poly1305_State
|
||||
* @var array<int, int>
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_Poly1305_State extends \ParagonIE_Sodium_Core_Util
|
||||
protected $buffer = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $final = false;
|
||||
|
||||
/**
|
||||
* @var array<int, int>
|
||||
*/
|
||||
public $h;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $leftover = 0;
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
public $r;
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
public $pad;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Poly1305_State constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key
|
||||
* @throws InvalidArgumentException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '')
|
||||
{
|
||||
/**
|
||||
* @var array<int, int>
|
||||
*/
|
||||
protected $buffer = array();
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $final = \false;
|
||||
/**
|
||||
* @var array<int, int>
|
||||
*/
|
||||
public $h;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $leftover = 0;
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
public $r;
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
public $pad;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_Poly1305_State constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key
|
||||
* @throws InvalidArgumentException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '')
|
||||
{
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new \InvalidArgumentException('Poly1305 requires a 32-byte key');
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new InvalidArgumentException(
|
||||
'Poly1305 requires a 32-byte key'
|
||||
);
|
||||
}
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
$this->r = array(
|
||||
(int) ((self::load_4(self::substr($key, 0, 4))) & 0x3ffffff),
|
||||
(int) ((self::load_4(self::substr($key, 3, 4)) >> 2) & 0x3ffff03),
|
||||
(int) ((self::load_4(self::substr($key, 6, 4)) >> 4) & 0x3ffc0ff),
|
||||
(int) ((self::load_4(self::substr($key, 9, 4)) >> 6) & 0x3f03fff),
|
||||
(int) ((self::load_4(self::substr($key, 12, 4)) >> 8) & 0x00fffff)
|
||||
);
|
||||
|
||||
/* h = 0 */
|
||||
$this->h = array(0, 0, 0, 0, 0);
|
||||
|
||||
/* save pad for later */
|
||||
$this->pad = array(
|
||||
self::load_4(self::substr($key, 16, 4)),
|
||||
self::load_4(self::substr($key, 20, 4)),
|
||||
self::load_4(self::substr($key, 24, 4)),
|
||||
self::load_4(self::substr($key, 28, 4)),
|
||||
);
|
||||
|
||||
$this->leftover = 0;
|
||||
$this->final = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero internal buffer upon destruction
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->r[0] ^= $this->r[0];
|
||||
$this->r[1] ^= $this->r[1];
|
||||
$this->r[2] ^= $this->r[2];
|
||||
$this->r[3] ^= $this->r[3];
|
||||
$this->r[4] ^= $this->r[4];
|
||||
$this->h[0] ^= $this->h[0];
|
||||
$this->h[1] ^= $this->h[1];
|
||||
$this->h[2] ^= $this->h[2];
|
||||
$this->h[3] ^= $this->h[3];
|
||||
$this->h[4] ^= $this->h[4];
|
||||
$this->pad[0] ^= $this->pad[0];
|
||||
$this->pad[1] ^= $this->pad[1];
|
||||
$this->pad[2] ^= $this->pad[2];
|
||||
$this->pad[3] ^= $this->pad[3];
|
||||
$this->leftover = 0;
|
||||
$this->final = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function update($message = '')
|
||||
{
|
||||
$bytes = self::strlen($message);
|
||||
if ($bytes < 1) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* handle leftover */
|
||||
if ($this->leftover) {
|
||||
$want = ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - $this->leftover;
|
||||
if ($want > $bytes) {
|
||||
$want = $bytes;
|
||||
}
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
$this->r = array((int) (self::load_4(self::substr($key, 0, 4)) & 0x3ffffff), (int) (self::load_4(self::substr($key, 3, 4)) >> 2 & 0x3ffff03), (int) (self::load_4(self::substr($key, 6, 4)) >> 4 & 0x3ffc0ff), (int) (self::load_4(self::substr($key, 9, 4)) >> 6 & 0x3f03fff), (int) (self::load_4(self::substr($key, 12, 4)) >> 8 & 0xfffff));
|
||||
/* h = 0 */
|
||||
$this->h = array(0, 0, 0, 0, 0);
|
||||
/* save pad for later */
|
||||
$this->pad = array(self::load_4(self::substr($key, 16, 4)), self::load_4(self::substr($key, 20, 4)), self::load_4(self::substr($key, 24, 4)), self::load_4(self::substr($key, 28, 4)));
|
||||
$this->leftover = 0;
|
||||
$this->final = \false;
|
||||
}
|
||||
/**
|
||||
* Zero internal buffer upon destruction
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->r[0] ^= $this->r[0];
|
||||
$this->r[1] ^= $this->r[1];
|
||||
$this->r[2] ^= $this->r[2];
|
||||
$this->r[3] ^= $this->r[3];
|
||||
$this->r[4] ^= $this->r[4];
|
||||
$this->h[0] ^= $this->h[0];
|
||||
$this->h[1] ^= $this->h[1];
|
||||
$this->h[2] ^= $this->h[2];
|
||||
$this->h[3] ^= $this->h[3];
|
||||
$this->h[4] ^= $this->h[4];
|
||||
$this->pad[0] ^= $this->pad[0];
|
||||
$this->pad[1] ^= $this->pad[1];
|
||||
$this->pad[2] ^= $this->pad[2];
|
||||
$this->pad[3] ^= $this->pad[3];
|
||||
$this->leftover = 0;
|
||||
$this->final = \true;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function update($message = '')
|
||||
{
|
||||
for ($i = 0; $i < $want; ++$i) {
|
||||
$mi = self::chrToInt($message[$i]);
|
||||
$this->buffer[$this->leftover + $i] = $mi;
|
||||
}
|
||||
// We snip off the leftmost bytes.
|
||||
$message = self::substr($message, $want);
|
||||
$bytes = self::strlen($message);
|
||||
if ($bytes < 1) {
|
||||
$this->leftover += $want;
|
||||
if ($this->leftover < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
// We still don't have enough to run $this->blocks()
|
||||
return $this;
|
||||
}
|
||||
/* handle leftover */
|
||||
if ($this->leftover) {
|
||||
$want = \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - $this->leftover;
|
||||
if ($want > $bytes) {
|
||||
$want = $bytes;
|
||||
}
|
||||
for ($i = 0; $i < $want; ++$i) {
|
||||
$mi = self::chrToInt($message[$i]);
|
||||
$this->buffer[$this->leftover + $i] = $mi;
|
||||
}
|
||||
// We snip off the leftmost bytes.
|
||||
$message = self::substr($message, $want);
|
||||
$bytes = self::strlen($message);
|
||||
$this->leftover += $want;
|
||||
if ($this->leftover < \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
// We still don't have enough to run $this->blocks()
|
||||
return $this;
|
||||
}
|
||||
$this->blocks(self::intArrayToString($this->buffer), \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE);
|
||||
$this->leftover = 0;
|
||||
}
|
||||
/* process full blocks */
|
||||
if ($bytes >= \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
/** @var int $want */
|
||||
$want = $bytes & ~(\ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - 1);
|
||||
if ($want >= \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
$block = self::substr($message, 0, $want);
|
||||
if (self::strlen($block) >= \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
$this->blocks($block, $want);
|
||||
$message = self::substr($message, $want);
|
||||
$bytes = self::strlen($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* store leftover */
|
||||
if ($bytes) {
|
||||
for ($i = 0; $i < $bytes; ++$i) {
|
||||
$mi = self::chrToInt($message[$i]);
|
||||
$this->buffer[$this->leftover + $i] = $mi;
|
||||
}
|
||||
$this->leftover = (int) $this->leftover + $bytes;
|
||||
}
|
||||
return $this;
|
||||
|
||||
$this->blocks(
|
||||
self::intArrayToString($this->buffer),
|
||||
ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
|
||||
);
|
||||
$this->leftover = 0;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $bytes
|
||||
* @return self
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function blocks($message, $bytes)
|
||||
{
|
||||
if (self::strlen($message) < 16) {
|
||||
$message = \str_pad($message, 16, "\x00", \STR_PAD_RIGHT);
|
||||
}
|
||||
/** @var int $hibit */
|
||||
$hibit = $this->final ? 0 : 1 << 24;
|
||||
/* 1 << 128 */
|
||||
$r0 = (int) $this->r[0];
|
||||
$r1 = (int) $this->r[1];
|
||||
$r2 = (int) $this->r[2];
|
||||
$r3 = (int) $this->r[3];
|
||||
$r4 = (int) $this->r[4];
|
||||
$s1 = self::mul($r1, 5, 3);
|
||||
$s2 = self::mul($r2, 5, 3);
|
||||
$s3 = self::mul($r3, 5, 3);
|
||||
$s4 = self::mul($r4, 5, 3);
|
||||
$h0 = $this->h[0];
|
||||
$h1 = $this->h[1];
|
||||
$h2 = $this->h[2];
|
||||
$h3 = $this->h[3];
|
||||
$h4 = $this->h[4];
|
||||
while ($bytes >= \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
/* h += m[i] */
|
||||
$h0 += self::load_4(self::substr($message, 0, 4)) & 0x3ffffff;
|
||||
$h1 += self::load_4(self::substr($message, 3, 4)) >> 2 & 0x3ffffff;
|
||||
$h2 += self::load_4(self::substr($message, 6, 4)) >> 4 & 0x3ffffff;
|
||||
$h3 += self::load_4(self::substr($message, 9, 4)) >> 6 & 0x3ffffff;
|
||||
$h4 += self::load_4(self::substr($message, 12, 4)) >> 8 | $hibit;
|
||||
/* h *= r */
|
||||
$d0 = 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, 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, 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, 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, 27) + self::mul($h1, $r3, 27) + self::mul($h2, $r2, 27) + self::mul($h3, $r1, 27) + self::mul($h4, $r0, 27);
|
||||
/* (partial) h %= p */
|
||||
/** @var int $c */
|
||||
$c = $d0 >> 26;
|
||||
/** @var int $h0 */
|
||||
$h0 = $d0 & 0x3ffffff;
|
||||
$d1 += $c;
|
||||
/** @var int $c */
|
||||
$c = $d1 >> 26;
|
||||
/** @var int $h1 */
|
||||
$h1 = $d1 & 0x3ffffff;
|
||||
$d2 += $c;
|
||||
/** @var int $c */
|
||||
$c = $d2 >> 26;
|
||||
/** @var int $h2 */
|
||||
$h2 = $d2 & 0x3ffffff;
|
||||
$d3 += $c;
|
||||
/** @var int $c */
|
||||
$c = $d3 >> 26;
|
||||
/** @var int $h3 */
|
||||
$h3 = $d3 & 0x3ffffff;
|
||||
$d4 += $c;
|
||||
/** @var int $c */
|
||||
$c = $d4 >> 26;
|
||||
/** @var int $h4 */
|
||||
$h4 = $d4 & 0x3ffffff;
|
||||
$h0 += (int) self::mul($c, 5, 3);
|
||||
/** @var int $c */
|
||||
$c = $h0 >> 26;
|
||||
/** @var int $h0 */
|
||||
$h0 &= 0x3ffffff;
|
||||
$h1 += $c;
|
||||
// Chop off the left 32 bytes.
|
||||
$message = self::substr($message, \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE);
|
||||
$bytes -= \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE;
|
||||
}
|
||||
$this->h = array((int) ($h0 & 0xffffffff), (int) ($h1 & 0xffffffff), (int) ($h2 & 0xffffffff), (int) ($h3 & 0xffffffff), (int) ($h4 & 0xffffffff));
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
/* process the remaining block */
|
||||
if ($this->leftover) {
|
||||
$i = $this->leftover;
|
||||
$this->buffer[$i++] = 1;
|
||||
for (; $i < \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE; ++$i) {
|
||||
$this->buffer[$i] = 0;
|
||||
|
||||
/* process full blocks */
|
||||
if ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
/** @var int $want */
|
||||
$want = $bytes & ~(ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - 1);
|
||||
if ($want >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
$block = self::substr($message, 0, $want);
|
||||
if (self::strlen($block) >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
$this->blocks($block, $want);
|
||||
$message = self::substr($message, $want);
|
||||
$bytes = self::strlen($message);
|
||||
}
|
||||
$this->final = \true;
|
||||
$this->blocks(self::substr(self::intArrayToString($this->buffer), 0, \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE), \ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE);
|
||||
}
|
||||
$h0 = (int) $this->h[0];
|
||||
$h1 = (int) $this->h[1];
|
||||
$h2 = (int) $this->h[2];
|
||||
$h3 = (int) $this->h[3];
|
||||
$h4 = (int) $this->h[4];
|
||||
}
|
||||
|
||||
/* store leftover */
|
||||
if ($bytes) {
|
||||
for ($i = 0; $i < $bytes; ++$i) {
|
||||
$mi = self::chrToInt($message[$i]);
|
||||
$this->buffer[$this->leftover + $i] = $mi;
|
||||
}
|
||||
$this->leftover = (int) $this->leftover + $bytes;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $bytes
|
||||
* @return self
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function blocks($message, $bytes)
|
||||
{
|
||||
if (self::strlen($message) < 16) {
|
||||
$message = str_pad($message, 16, "\x00", STR_PAD_RIGHT);
|
||||
}
|
||||
/** @var int $hibit */
|
||||
$hibit = $this->final ? 0 : 1 << 24; /* 1 << 128 */
|
||||
$r0 = (int) $this->r[0];
|
||||
$r1 = (int) $this->r[1];
|
||||
$r2 = (int) $this->r[2];
|
||||
$r3 = (int) $this->r[3];
|
||||
$r4 = (int) $this->r[4];
|
||||
|
||||
$s1 = self::mul($r1, 5, 3);
|
||||
$s2 = self::mul($r2, 5, 3);
|
||||
$s3 = self::mul($r3, 5, 3);
|
||||
$s4 = self::mul($r4, 5, 3);
|
||||
|
||||
$h0 = $this->h[0];
|
||||
$h1 = $this->h[1];
|
||||
$h2 = $this->h[2];
|
||||
$h3 = $this->h[3];
|
||||
$h4 = $this->h[4];
|
||||
|
||||
while ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
|
||||
/* h += m[i] */
|
||||
$h0 += self::load_4(self::substr($message, 0, 4)) & 0x3ffffff;
|
||||
$h1 += (self::load_4(self::substr($message, 3, 4)) >> 2) & 0x3ffffff;
|
||||
$h2 += (self::load_4(self::substr($message, 6, 4)) >> 4) & 0x3ffffff;
|
||||
$h3 += (self::load_4(self::substr($message, 9, 4)) >> 6) & 0x3ffffff;
|
||||
$h4 += (self::load_4(self::substr($message, 12, 4)) >> 8) | $hibit;
|
||||
|
||||
/* h *= r */
|
||||
$d0 = (
|
||||
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, 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, 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, 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, 27) +
|
||||
self::mul($h1, $r3, 27) +
|
||||
self::mul($h2, $r2, 27) +
|
||||
self::mul($h3, $r1, 27) +
|
||||
self::mul($h4, $r0, 27)
|
||||
);
|
||||
|
||||
/* (partial) h %= p */
|
||||
/** @var int $c */
|
||||
$c = $h1 >> 26;
|
||||
/** @var int $h1 */
|
||||
$h1 &= 0x3ffffff;
|
||||
/** @var int $h2 */
|
||||
$h2 += $c;
|
||||
/** @var int $c */
|
||||
$c = $h2 >> 26;
|
||||
/** @var int $h2 */
|
||||
$h2 &= 0x3ffffff;
|
||||
$h3 += $c;
|
||||
/** @var int $c */
|
||||
$c = $h3 >> 26;
|
||||
$h3 &= 0x3ffffff;
|
||||
$h4 += $c;
|
||||
/** @var int $c */
|
||||
$c = $h4 >> 26;
|
||||
$h4 &= 0x3ffffff;
|
||||
$c = $d0 >> 26;
|
||||
/** @var int $h0 */
|
||||
$h0 += self::mul($c, 5, 3);
|
||||
$h0 = $d0 & 0x3ffffff;
|
||||
$d1 += $c;
|
||||
|
||||
/** @var int $c */
|
||||
$c = $d1 >> 26;
|
||||
/** @var int $h1 */
|
||||
$h1 = $d1 & 0x3ffffff;
|
||||
$d2 += $c;
|
||||
|
||||
/** @var int $c */
|
||||
$c = $d2 >> 26;
|
||||
/** @var int $h2 */
|
||||
$h2 = $d2 & 0x3ffffff;
|
||||
$d3 += $c;
|
||||
|
||||
/** @var int $c */
|
||||
$c = $d3 >> 26;
|
||||
/** @var int $h3 */
|
||||
$h3 = $d3 & 0x3ffffff;
|
||||
$d4 += $c;
|
||||
|
||||
/** @var int $c */
|
||||
$c = $d4 >> 26;
|
||||
/** @var int $h4 */
|
||||
$h4 = $d4 & 0x3ffffff;
|
||||
$h0 += (int) self::mul($c, 5, 3);
|
||||
|
||||
/** @var int $c */
|
||||
$c = $h0 >> 26;
|
||||
/** @var int $h0 */
|
||||
$h0 &= 0x3ffffff;
|
||||
/** @var int $h1 */
|
||||
$h1 += $c;
|
||||
/* compute h + -p */
|
||||
/** @var int $g0 */
|
||||
$g0 = $h0 + 5;
|
||||
/** @var int $c */
|
||||
$c = $g0 >> 26;
|
||||
/** @var int $g0 */
|
||||
$g0 &= 0x3ffffff;
|
||||
/** @var int $g1 */
|
||||
$g1 = $h1 + $c;
|
||||
/** @var int $c */
|
||||
$c = $g1 >> 26;
|
||||
$g1 &= 0x3ffffff;
|
||||
/** @var int $g2 */
|
||||
$g2 = $h2 + $c;
|
||||
/** @var int $c */
|
||||
$c = $g2 >> 26;
|
||||
/** @var int $g2 */
|
||||
$g2 &= 0x3ffffff;
|
||||
/** @var int $g3 */
|
||||
$g3 = $h3 + $c;
|
||||
/** @var int $c */
|
||||
$c = $g3 >> 26;
|
||||
/** @var int $g3 */
|
||||
$g3 &= 0x3ffffff;
|
||||
/** @var int $g4 */
|
||||
$g4 = $h4 + $c - (1 << 26) & 0xffffffff;
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
/** @var int $mask */
|
||||
$mask = ($g4 >> 31) - 1;
|
||||
$g0 &= $mask;
|
||||
$g1 &= $mask;
|
||||
$g2 &= $mask;
|
||||
$g3 &= $mask;
|
||||
$g4 &= $mask;
|
||||
/** @var int $mask */
|
||||
$mask = ~$mask & 0xffffffff;
|
||||
/** @var int $h0 */
|
||||
$h0 = $h0 & $mask | $g0;
|
||||
/** @var int $h1 */
|
||||
$h1 = $h1 & $mask | $g1;
|
||||
/** @var int $h2 */
|
||||
$h2 = $h2 & $mask | $g2;
|
||||
/** @var int $h3 */
|
||||
$h3 = $h3 & $mask | $g3;
|
||||
/** @var int $h4 */
|
||||
$h4 = $h4 & $mask | $g4;
|
||||
/* h = h % (2^128) */
|
||||
/** @var int $h0 */
|
||||
$h0 = ($h0 | $h1 << 26) & 0xffffffff;
|
||||
/** @var int $h1 */
|
||||
$h1 = ($h1 >> 6 | $h2 << 20) & 0xffffffff;
|
||||
/** @var int $h2 */
|
||||
$h2 = ($h2 >> 12 | $h3 << 14) & 0xffffffff;
|
||||
/** @var int $h3 */
|
||||
$h3 = ($h3 >> 18 | $h4 << 8) & 0xffffffff;
|
||||
/* mac = (h + pad) % (2^128) */
|
||||
$f = (int) ($h0 + $this->pad[0]);
|
||||
$h0 = (int) $f;
|
||||
$f = (int) ($h1 + $this->pad[1] + ($f >> 32));
|
||||
$h1 = (int) $f;
|
||||
$f = (int) ($h2 + $this->pad[2] + ($f >> 32));
|
||||
$h2 = (int) $f;
|
||||
$f = (int) ($h3 + $this->pad[3] + ($f >> 32));
|
||||
$h3 = (int) $f;
|
||||
return self::store32_le($h0 & 0xffffffff) . self::store32_le($h1 & 0xffffffff) . self::store32_le($h2 & 0xffffffff) . self::store32_le($h3 & 0xffffffff);
|
||||
|
||||
// Chop off the left 32 bytes.
|
||||
$message = self::substr(
|
||||
$message,
|
||||
ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
|
||||
);
|
||||
$bytes -= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE;
|
||||
}
|
||||
|
||||
$this->h = array(
|
||||
(int) ($h0 & 0xffffffff),
|
||||
(int) ($h1 & 0xffffffff),
|
||||
(int) ($h2 & 0xffffffff),
|
||||
(int) ($h3 & 0xffffffff),
|
||||
(int) ($h4 & 0xffffffff)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Poly1305_State
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public function finish()
|
||||
{
|
||||
/* process the remaining block */
|
||||
if ($this->leftover) {
|
||||
$i = $this->leftover;
|
||||
$this->buffer[$i++] = 1;
|
||||
for (; $i < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE; ++$i) {
|
||||
$this->buffer[$i] = 0;
|
||||
}
|
||||
$this->final = true;
|
||||
$this->blocks(
|
||||
self::substr(
|
||||
self::intArrayToString($this->buffer),
|
||||
0,
|
||||
ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
|
||||
),
|
||||
ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
$h0 = (int) $this->h[0];
|
||||
$h1 = (int) $this->h[1];
|
||||
$h2 = (int) $this->h[2];
|
||||
$h3 = (int) $this->h[3];
|
||||
$h4 = (int) $this->h[4];
|
||||
|
||||
/** @var int $c */
|
||||
$c = $h1 >> 26;
|
||||
/** @var int $h1 */
|
||||
$h1 &= 0x3ffffff;
|
||||
/** @var int $h2 */
|
||||
$h2 += $c;
|
||||
/** @var int $c */
|
||||
$c = $h2 >> 26;
|
||||
/** @var int $h2 */
|
||||
$h2 &= 0x3ffffff;
|
||||
$h3 += $c;
|
||||
/** @var int $c */
|
||||
$c = $h3 >> 26;
|
||||
$h3 &= 0x3ffffff;
|
||||
$h4 += $c;
|
||||
/** @var int $c */
|
||||
$c = $h4 >> 26;
|
||||
$h4 &= 0x3ffffff;
|
||||
/** @var int $h0 */
|
||||
$h0 += self::mul($c, 5, 3);
|
||||
/** @var int $c */
|
||||
$c = $h0 >> 26;
|
||||
/** @var int $h0 */
|
||||
$h0 &= 0x3ffffff;
|
||||
/** @var int $h1 */
|
||||
$h1 += $c;
|
||||
|
||||
/* compute h + -p */
|
||||
/** @var int $g0 */
|
||||
$g0 = $h0 + 5;
|
||||
/** @var int $c */
|
||||
$c = $g0 >> 26;
|
||||
/** @var int $g0 */
|
||||
$g0 &= 0x3ffffff;
|
||||
|
||||
/** @var int $g1 */
|
||||
$g1 = $h1 + $c;
|
||||
/** @var int $c */
|
||||
$c = $g1 >> 26;
|
||||
$g1 &= 0x3ffffff;
|
||||
|
||||
/** @var int $g2 */
|
||||
$g2 = $h2 + $c;
|
||||
/** @var int $c */
|
||||
$c = $g2 >> 26;
|
||||
/** @var int $g2 */
|
||||
$g2 &= 0x3ffffff;
|
||||
|
||||
/** @var int $g3 */
|
||||
$g3 = $h3 + $c;
|
||||
/** @var int $c */
|
||||
$c = $g3 >> 26;
|
||||
/** @var int $g3 */
|
||||
$g3 &= 0x3ffffff;
|
||||
|
||||
/** @var int $g4 */
|
||||
$g4 = ($h4 + $c - (1 << 26)) & 0xffffffff;
|
||||
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
/** @var int $mask */
|
||||
$mask = ($g4 >> 31) - 1;
|
||||
|
||||
$g0 &= $mask;
|
||||
$g1 &= $mask;
|
||||
$g2 &= $mask;
|
||||
$g3 &= $mask;
|
||||
$g4 &= $mask;
|
||||
|
||||
/** @var int $mask */
|
||||
$mask = ~$mask & 0xffffffff;
|
||||
/** @var int $h0 */
|
||||
$h0 = ($h0 & $mask) | $g0;
|
||||
/** @var int $h1 */
|
||||
$h1 = ($h1 & $mask) | $g1;
|
||||
/** @var int $h2 */
|
||||
$h2 = ($h2 & $mask) | $g2;
|
||||
/** @var int $h3 */
|
||||
$h3 = ($h3 & $mask) | $g3;
|
||||
/** @var int $h4 */
|
||||
$h4 = ($h4 & $mask) | $g4;
|
||||
|
||||
/* h = h % (2^128) */
|
||||
/** @var int $h0 */
|
||||
$h0 = (($h0) | ($h1 << 26)) & 0xffffffff;
|
||||
/** @var int $h1 */
|
||||
$h1 = (($h1 >> 6) | ($h2 << 20)) & 0xffffffff;
|
||||
/** @var int $h2 */
|
||||
$h2 = (($h2 >> 12) | ($h3 << 14)) & 0xffffffff;
|
||||
/** @var int $h3 */
|
||||
$h3 = (($h3 >> 18) | ($h4 << 8)) & 0xffffffff;
|
||||
|
||||
/* mac = (h + pad) % (2^128) */
|
||||
$f = (int) ($h0 + $this->pad[0]);
|
||||
$h0 = (int) $f;
|
||||
$f = (int) ($h1 + $this->pad[1] + ($f >> 32));
|
||||
$h1 = (int) $f;
|
||||
$f = (int) ($h2 + $this->pad[2] + ($f >> 32));
|
||||
$h2 = (int) $f;
|
||||
$f = (int) ($h3 + $this->pad[3] + ($f >> 32));
|
||||
$h3 = (int) $f;
|
||||
|
||||
return self::store32_le($h0 & 0xffffffff) .
|
||||
self::store32_le($h1 & 0xffffffff) .
|
||||
self::store32_le($h2 & 0xffffffff) .
|
||||
self::store32_le($h3 & 0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,221 +1,273 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_Salsa20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Salsa20
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_Salsa20 extends ParagonIE_Sodium_Core_Util
|
||||
{
|
||||
const ROUNDS = 20;
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_Salsa20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Salsa20
|
||||
* Calculate an salsa20 hash of a single block
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $k
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_Salsa20 extends \ParagonIE_Sodium_Core_Util
|
||||
public static function core_salsa20($in, $k, $c = null)
|
||||
{
|
||||
const ROUNDS = 20;
|
||||
/**
|
||||
* Calculate an salsa20 hash of a single block
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $k
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function core_salsa20($in, $k, $c = null)
|
||||
{
|
||||
if (self::strlen($k) < 32) {
|
||||
throw new \RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
if ($c === null) {
|
||||
$j0 = $x0 = 0x61707865;
|
||||
$j5 = $x5 = 0x3320646e;
|
||||
$j10 = $x10 = 0x79622d32;
|
||||
$j15 = $x15 = 0x6b206574;
|
||||
} else {
|
||||
$j0 = $x0 = self::load_4(self::substr($c, 0, 4));
|
||||
$j5 = $x5 = self::load_4(self::substr($c, 4, 4));
|
||||
$j10 = $x10 = self::load_4(self::substr($c, 8, 4));
|
||||
$j15 = $x15 = self::load_4(self::substr($c, 12, 4));
|
||||
}
|
||||
$j1 = $x1 = self::load_4(self::substr($k, 0, 4));
|
||||
$j2 = $x2 = self::load_4(self::substr($k, 4, 4));
|
||||
$j3 = $x3 = self::load_4(self::substr($k, 8, 4));
|
||||
$j4 = $x4 = self::load_4(self::substr($k, 12, 4));
|
||||
$j6 = $x6 = self::load_4(self::substr($in, 0, 4));
|
||||
$j7 = $x7 = self::load_4(self::substr($in, 4, 4));
|
||||
$j8 = $x8 = self::load_4(self::substr($in, 8, 4));
|
||||
$j9 = $x9 = self::load_4(self::substr($in, 12, 4));
|
||||
$j11 = $x11 = self::load_4(self::substr($k, 16, 4));
|
||||
$j12 = $x12 = self::load_4(self::substr($k, 20, 4));
|
||||
$j13 = $x13 = self::load_4(self::substr($k, 24, 4));
|
||||
$j14 = $x14 = self::load_4(self::substr($k, 28, 4));
|
||||
for ($i = self::ROUNDS; $i > 0; $i -= 2) {
|
||||
$x4 ^= self::rotate($x0 + $x12, 7);
|
||||
$x8 ^= self::rotate($x4 + $x0, 9);
|
||||
$x12 ^= self::rotate($x8 + $x4, 13);
|
||||
$x0 ^= self::rotate($x12 + $x8, 18);
|
||||
$x9 ^= self::rotate($x5 + $x1, 7);
|
||||
$x13 ^= self::rotate($x9 + $x5, 9);
|
||||
$x1 ^= self::rotate($x13 + $x9, 13);
|
||||
$x5 ^= self::rotate($x1 + $x13, 18);
|
||||
$x14 ^= self::rotate($x10 + $x6, 7);
|
||||
$x2 ^= self::rotate($x14 + $x10, 9);
|
||||
$x6 ^= self::rotate($x2 + $x14, 13);
|
||||
$x10 ^= self::rotate($x6 + $x2, 18);
|
||||
$x3 ^= self::rotate($x15 + $x11, 7);
|
||||
$x7 ^= self::rotate($x3 + $x15, 9);
|
||||
$x11 ^= self::rotate($x7 + $x3, 13);
|
||||
$x15 ^= self::rotate($x11 + $x7, 18);
|
||||
$x1 ^= self::rotate($x0 + $x3, 7);
|
||||
$x2 ^= self::rotate($x1 + $x0, 9);
|
||||
$x3 ^= self::rotate($x2 + $x1, 13);
|
||||
$x0 ^= self::rotate($x3 + $x2, 18);
|
||||
$x6 ^= self::rotate($x5 + $x4, 7);
|
||||
$x7 ^= self::rotate($x6 + $x5, 9);
|
||||
$x4 ^= self::rotate($x7 + $x6, 13);
|
||||
$x5 ^= self::rotate($x4 + $x7, 18);
|
||||
$x11 ^= self::rotate($x10 + $x9, 7);
|
||||
$x8 ^= self::rotate($x11 + $x10, 9);
|
||||
$x9 ^= self::rotate($x8 + $x11, 13);
|
||||
$x10 ^= self::rotate($x9 + $x8, 18);
|
||||
$x12 ^= self::rotate($x15 + $x14, 7);
|
||||
$x13 ^= self::rotate($x12 + $x15, 9);
|
||||
$x14 ^= self::rotate($x13 + $x12, 13);
|
||||
$x15 ^= self::rotate($x14 + $x13, 18);
|
||||
}
|
||||
$x0 += $j0;
|
||||
$x1 += $j1;
|
||||
$x2 += $j2;
|
||||
$x3 += $j3;
|
||||
$x4 += $j4;
|
||||
$x5 += $j5;
|
||||
$x6 += $j6;
|
||||
$x7 += $j7;
|
||||
$x8 += $j8;
|
||||
$x9 += $j9;
|
||||
$x10 += $j10;
|
||||
$x11 += $j11;
|
||||
$x12 += $j12;
|
||||
$x13 += $j13;
|
||||
$x14 += $j14;
|
||||
$x15 += $j15;
|
||||
return self::store32_le($x0) . self::store32_le($x1) . self::store32_le($x2) . self::store32_le($x3) . self::store32_le($x4) . self::store32_le($x5) . self::store32_le($x6) . self::store32_le($x7) . self::store32_le($x8) . self::store32_le($x9) . self::store32_le($x10) . self::store32_le($x11) . self::store32_le($x12) . self::store32_le($x13) . self::store32_le($x14) . self::store32_le($x15);
|
||||
if (self::strlen($k) < 32) {
|
||||
throw new RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20($len, $nonce, $key)
|
||||
{
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new \RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
$kcopy = '' . $key;
|
||||
$in = self::substr($nonce, 0, 8) . \str_repeat("\x00", 8);
|
||||
$c = '';
|
||||
while ($len >= 64) {
|
||||
$c .= self::core_salsa20($in, $kcopy, null);
|
||||
$u = 1;
|
||||
// Internal counter.
|
||||
for ($i = 8; $i < 16; ++$i) {
|
||||
$u += self::chrToInt($in[$i]);
|
||||
$in[$i] = self::intToChr($u & 0xff);
|
||||
$u >>= 8;
|
||||
}
|
||||
$len -= 64;
|
||||
}
|
||||
if ($len > 0) {
|
||||
$c .= self::substr(self::core_salsa20($in, $kcopy, null), 0, $len);
|
||||
}
|
||||
try {
|
||||
\ParagonIE_Sodium_Compat::memzero($kcopy);
|
||||
} catch (\SodiumException $ex) {
|
||||
$kcopy = null;
|
||||
}
|
||||
return $c;
|
||||
if ($c === null) {
|
||||
$j0 = $x0 = 0x61707865;
|
||||
$j5 = $x5 = 0x3320646e;
|
||||
$j10 = $x10 = 0x79622d32;
|
||||
$j15 = $x15 = 0x6b206574;
|
||||
} else {
|
||||
$j0 = $x0 = self::load_4(self::substr($c, 0, 4));
|
||||
$j5 = $x5 = self::load_4(self::substr($c, 4, 4));
|
||||
$j10 = $x10 = self::load_4(self::substr($c, 8, 4));
|
||||
$j15 = $x15 = self::load_4(self::substr($c, 12, 4));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $m
|
||||
* @param string $n
|
||||
* @param int $ic
|
||||
* @param string $k
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20_xor_ic($m, $n, $ic, $k)
|
||||
{
|
||||
$mlen = self::strlen($m);
|
||||
if ($mlen < 1) {
|
||||
return '';
|
||||
}
|
||||
$kcopy = self::substr($k, 0, 32);
|
||||
$in = self::substr($n, 0, 8);
|
||||
// Initialize the counter
|
||||
$in .= \ParagonIE_Sodium_Core_Util::store64_le($ic);
|
||||
$c = '';
|
||||
while ($mlen >= 64) {
|
||||
$block = self::core_salsa20($in, $kcopy, null);
|
||||
$c .= self::xorStrings(self::substr($m, 0, 64), self::substr($block, 0, 64));
|
||||
$u = 1;
|
||||
for ($i = 8; $i < 16; ++$i) {
|
||||
$u += self::chrToInt($in[$i]);
|
||||
$in[$i] = self::intToChr($u & 0xff);
|
||||
$u >>= 8;
|
||||
}
|
||||
$mlen -= 64;
|
||||
$m = self::substr($m, 64);
|
||||
}
|
||||
if ($mlen) {
|
||||
$block = self::core_salsa20($in, $kcopy, null);
|
||||
$c .= self::xorStrings(self::substr($m, 0, $mlen), self::substr($block, 0, $mlen));
|
||||
}
|
||||
try {
|
||||
\ParagonIE_Sodium_Compat::memzero($block);
|
||||
\ParagonIE_Sodium_Compat::memzero($kcopy);
|
||||
} catch (\SodiumException $ex) {
|
||||
$block = null;
|
||||
$kcopy = null;
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20_xor($message, $nonce, $key)
|
||||
{
|
||||
return self::xorStrings($message, self::salsa20(self::strlen($message), $nonce, $key));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $u
|
||||
* @param int $c
|
||||
* @return int
|
||||
*/
|
||||
public static function rotate($u, $c)
|
||||
{
|
||||
$u &= 0xffffffff;
|
||||
$c %= 32;
|
||||
return (int) (0xffffffff & ($u << $c | $u >> 32 - $c));
|
||||
$j1 = $x1 = self::load_4(self::substr($k, 0, 4));
|
||||
$j2 = $x2 = self::load_4(self::substr($k, 4, 4));
|
||||
$j3 = $x3 = self::load_4(self::substr($k, 8, 4));
|
||||
$j4 = $x4 = self::load_4(self::substr($k, 12, 4));
|
||||
$j6 = $x6 = self::load_4(self::substr($in, 0, 4));
|
||||
$j7 = $x7 = self::load_4(self::substr($in, 4, 4));
|
||||
$j8 = $x8 = self::load_4(self::substr($in, 8, 4));
|
||||
$j9 = $x9 = self::load_4(self::substr($in, 12, 4));
|
||||
$j11 = $x11 = self::load_4(self::substr($k, 16, 4));
|
||||
$j12 = $x12 = self::load_4(self::substr($k, 20, 4));
|
||||
$j13 = $x13 = self::load_4(self::substr($k, 24, 4));
|
||||
$j14 = $x14 = self::load_4(self::substr($k, 28, 4));
|
||||
|
||||
for ($i = self::ROUNDS; $i > 0; $i -= 2) {
|
||||
$x4 ^= self::rotate($x0 + $x12, 7);
|
||||
$x8 ^= self::rotate($x4 + $x0, 9);
|
||||
$x12 ^= self::rotate($x8 + $x4, 13);
|
||||
$x0 ^= self::rotate($x12 + $x8, 18);
|
||||
|
||||
$x9 ^= self::rotate($x5 + $x1, 7);
|
||||
$x13 ^= self::rotate($x9 + $x5, 9);
|
||||
$x1 ^= self::rotate($x13 + $x9, 13);
|
||||
$x5 ^= self::rotate($x1 + $x13, 18);
|
||||
|
||||
$x14 ^= self::rotate($x10 + $x6, 7);
|
||||
$x2 ^= self::rotate($x14 + $x10, 9);
|
||||
$x6 ^= self::rotate($x2 + $x14, 13);
|
||||
$x10 ^= self::rotate($x6 + $x2, 18);
|
||||
|
||||
$x3 ^= self::rotate($x15 + $x11, 7);
|
||||
$x7 ^= self::rotate($x3 + $x15, 9);
|
||||
$x11 ^= self::rotate($x7 + $x3, 13);
|
||||
$x15 ^= self::rotate($x11 + $x7, 18);
|
||||
|
||||
$x1 ^= self::rotate($x0 + $x3, 7);
|
||||
$x2 ^= self::rotate($x1 + $x0, 9);
|
||||
$x3 ^= self::rotate($x2 + $x1, 13);
|
||||
$x0 ^= self::rotate($x3 + $x2, 18);
|
||||
|
||||
$x6 ^= self::rotate($x5 + $x4, 7);
|
||||
$x7 ^= self::rotate($x6 + $x5, 9);
|
||||
$x4 ^= self::rotate($x7 + $x6, 13);
|
||||
$x5 ^= self::rotate($x4 + $x7, 18);
|
||||
|
||||
$x11 ^= self::rotate($x10 + $x9, 7);
|
||||
$x8 ^= self::rotate($x11 + $x10, 9);
|
||||
$x9 ^= self::rotate($x8 + $x11, 13);
|
||||
$x10 ^= self::rotate($x9 + $x8, 18);
|
||||
|
||||
$x12 ^= self::rotate($x15 + $x14, 7);
|
||||
$x13 ^= self::rotate($x12 + $x15, 9);
|
||||
$x14 ^= self::rotate($x13 + $x12, 13);
|
||||
$x15 ^= self::rotate($x14 + $x13, 18);
|
||||
}
|
||||
|
||||
$x0 += $j0;
|
||||
$x1 += $j1;
|
||||
$x2 += $j2;
|
||||
$x3 += $j3;
|
||||
$x4 += $j4;
|
||||
$x5 += $j5;
|
||||
$x6 += $j6;
|
||||
$x7 += $j7;
|
||||
$x8 += $j8;
|
||||
$x9 += $j9;
|
||||
$x10 += $j10;
|
||||
$x11 += $j11;
|
||||
$x12 += $j12;
|
||||
$x13 += $j13;
|
||||
$x14 += $j14;
|
||||
$x15 += $j15;
|
||||
|
||||
return self::store32_le($x0) .
|
||||
self::store32_le($x1) .
|
||||
self::store32_le($x2) .
|
||||
self::store32_le($x3) .
|
||||
self::store32_le($x4) .
|
||||
self::store32_le($x5) .
|
||||
self::store32_le($x6) .
|
||||
self::store32_le($x7) .
|
||||
self::store32_le($x8) .
|
||||
self::store32_le($x9) .
|
||||
self::store32_le($x10) .
|
||||
self::store32_le($x11) .
|
||||
self::store32_le($x12) .
|
||||
self::store32_le($x13) .
|
||||
self::store32_le($x14) .
|
||||
self::store32_le($x15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Salsa20
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function salsa20($len, $nonce, $key)
|
||||
{
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
$kcopy = '' . $key;
|
||||
$in = self::substr($nonce, 0, 8) . str_repeat("\0", 8);
|
||||
$c = '';
|
||||
while ($len >= 64) {
|
||||
$c .= self::core_salsa20($in, $kcopy, null);
|
||||
$u = 1;
|
||||
// Internal counter.
|
||||
for ($i = 8; $i < 16; ++$i) {
|
||||
$u += self::chrToInt($in[$i]);
|
||||
$in[$i] = self::intToChr($u & 0xff);
|
||||
$u >>= 8;
|
||||
}
|
||||
$len -= 64;
|
||||
}
|
||||
if ($len > 0) {
|
||||
$c .= self::substr(
|
||||
self::core_salsa20($in, $kcopy, null),
|
||||
0,
|
||||
$len
|
||||
);
|
||||
}
|
||||
try {
|
||||
ParagonIE_Sodium_Compat::memzero($kcopy);
|
||||
} catch (SodiumException $ex) {
|
||||
$kcopy = null;
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $m
|
||||
* @param string $n
|
||||
* @param int $ic
|
||||
* @param string $k
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20_xor_ic($m, $n, $ic, $k)
|
||||
{
|
||||
$mlen = self::strlen($m);
|
||||
if ($mlen < 1) {
|
||||
return '';
|
||||
}
|
||||
$kcopy = self::substr($k, 0, 32);
|
||||
$in = self::substr($n, 0, 8);
|
||||
// Initialize the counter
|
||||
$in .= ParagonIE_Sodium_Core_Util::store64_le($ic);
|
||||
|
||||
$c = '';
|
||||
while ($mlen >= 64) {
|
||||
$block = self::core_salsa20($in, $kcopy, null);
|
||||
$c .= self::xorStrings(
|
||||
self::substr($m, 0, 64),
|
||||
self::substr($block, 0, 64)
|
||||
);
|
||||
$u = 1;
|
||||
for ($i = 8; $i < 16; ++$i) {
|
||||
$u += self::chrToInt($in[$i]);
|
||||
$in[$i] = self::intToChr($u & 0xff);
|
||||
$u >>= 8;
|
||||
}
|
||||
|
||||
$mlen -= 64;
|
||||
$m = self::substr($m, 64);
|
||||
}
|
||||
|
||||
if ($mlen) {
|
||||
$block = self::core_salsa20($in, $kcopy, null);
|
||||
$c .= self::xorStrings(
|
||||
self::substr($m, 0, $mlen),
|
||||
self::substr($block, 0, $mlen)
|
||||
);
|
||||
}
|
||||
try {
|
||||
ParagonIE_Sodium_Compat::memzero($block);
|
||||
ParagonIE_Sodium_Compat::memzero($kcopy);
|
||||
} catch (SodiumException $ex) {
|
||||
$block = null;
|
||||
$kcopy = null;
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20_xor($message, $nonce, $key)
|
||||
{
|
||||
return self::xorStrings(
|
||||
$message,
|
||||
self::salsa20(
|
||||
self::strlen($message),
|
||||
$nonce,
|
||||
$key
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $u
|
||||
* @param int $c
|
||||
* @return int
|
||||
*/
|
||||
public static function rotate($u, $c)
|
||||
{
|
||||
$u &= 0xffffffff;
|
||||
$c %= 32;
|
||||
return (int) (0xffffffff & (
|
||||
($u << $c)
|
||||
|
|
||||
($u >> (32 - $c))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,132 +1,163 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_SecretStream_State
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_SecretStream_State
|
||||
{
|
||||
/** @var string $key */
|
||||
protected $key;
|
||||
|
||||
/** @var int $counter */
|
||||
protected $counter;
|
||||
|
||||
/** @var string $nonce */
|
||||
protected $nonce;
|
||||
|
||||
/** @var string $_pad */
|
||||
protected $_pad;
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_SecretStream_State
|
||||
* ParagonIE_Sodium_Core_SecretStream_State constructor.
|
||||
* @param string $key
|
||||
* @param string|null $nonce
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_SecretStream_State
|
||||
public function __construct($key, $nonce = null)
|
||||
{
|
||||
/** @var string $key */
|
||||
protected $key;
|
||||
/** @var int $counter */
|
||||
protected $counter;
|
||||
/** @var string $nonce */
|
||||
protected $nonce;
|
||||
/** @var string $_pad */
|
||||
protected $_pad;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_SecretStream_State constructor.
|
||||
* @param string $key
|
||||
* @param string|null $nonce
|
||||
*/
|
||||
public function __construct($key, $nonce = null)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->counter = 1;
|
||||
if (\is_null($nonce)) {
|
||||
$nonce = \str_repeat("\x00", 12);
|
||||
}
|
||||
$this->nonce = \str_pad($nonce, 12, "\x00", \STR_PAD_RIGHT);
|
||||
$this->_pad = \str_repeat("\x00", 4);
|
||||
}
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function counterReset()
|
||||
{
|
||||
$this->counter = 1;
|
||||
$this->_pad = \str_repeat("\x00", 4);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCounter()
|
||||
{
|
||||
return \ParagonIE_Sodium_Core_Util::store32_le($this->counter);
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNonce()
|
||||
{
|
||||
if (!\is_string($this->nonce)) {
|
||||
$this->nonce = \str_repeat("\x00", 12);
|
||||
}
|
||||
if (\ParagonIE_Sodium_Core_Util::strlen($this->nonce) !== 12) {
|
||||
$this->nonce = \str_pad($this->nonce, 12, "\x00", \STR_PAD_RIGHT);
|
||||
}
|
||||
return $this->nonce;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCombinedNonce()
|
||||
{
|
||||
return $this->getCounter() . \ParagonIE_Sodium_Core_Util::substr($this->getNonce(), 0, 8);
|
||||
}
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function incrementCounter()
|
||||
{
|
||||
++$this->counter;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function needsRekey()
|
||||
{
|
||||
return ($this->counter & 0xffff) === 0;
|
||||
}
|
||||
/**
|
||||
* @param string $newKeyAndNonce
|
||||
* @return self
|
||||
*/
|
||||
public function rekey($newKeyAndNonce)
|
||||
{
|
||||
$this->key = \ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 0, 32);
|
||||
$this->nonce = \str_pad(\ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 32), 12, "\x00", \STR_PAD_RIGHT);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @param string $str
|
||||
* @return self
|
||||
*/
|
||||
public function xorNonce($str)
|
||||
{
|
||||
$this->nonce = \ParagonIE_Sodium_Core_Util::xorStrings($this->getNonce(), \str_pad(\ParagonIE_Sodium_Core_Util::substr($str, 0, 8), 12, "\x00", \STR_PAD_RIGHT));
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
* @return self
|
||||
*/
|
||||
public static function fromString($string)
|
||||
{
|
||||
$state = new \ParagonIE_Sodium_Core_SecretStream_State(\ParagonIE_Sodium_Core_Util::substr($string, 0, 32));
|
||||
$state->counter = \ParagonIE_Sodium_Core_Util::load_4(\ParagonIE_Sodium_Core_Util::substr($string, 32, 4));
|
||||
$state->nonce = \ParagonIE_Sodium_Core_Util::substr($string, 36, 12);
|
||||
$state->_pad = \ParagonIE_Sodium_Core_Util::substr($string, 48, 8);
|
||||
return $state;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->key . $this->getCounter() . $this->nonce . $this->_pad;
|
||||
$this->key = $key;
|
||||
$this->counter = 1;
|
||||
if (is_null($nonce)) {
|
||||
$nonce = str_repeat("\0", 12);
|
||||
}
|
||||
$this->nonce = str_pad($nonce, 12, "\0", STR_PAD_RIGHT);;
|
||||
$this->_pad = str_repeat("\0", 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_SecretStream_State
|
||||
* @return self
|
||||
*/
|
||||
|
||||
public function counterReset()
|
||||
{
|
||||
$this->counter = 1;
|
||||
$this->_pad = str_repeat("\0", 4);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCounter()
|
||||
{
|
||||
return ParagonIE_Sodium_Core_Util::store32_le($this->counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNonce()
|
||||
{
|
||||
if (!is_string($this->nonce)) {
|
||||
$this->nonce = str_repeat("\0", 12);
|
||||
}
|
||||
if (ParagonIE_Sodium_Core_Util::strlen($this->nonce) !== 12) {
|
||||
$this->nonce = str_pad($this->nonce, 12, "\0", STR_PAD_RIGHT);
|
||||
}
|
||||
return $this->nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCombinedNonce()
|
||||
{
|
||||
return $this->getCounter() .
|
||||
ParagonIE_Sodium_Core_Util::substr($this->getNonce(), 0, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function incrementCounter()
|
||||
{
|
||||
++$this->counter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function needsRekey()
|
||||
{
|
||||
return ($this->counter & 0xffff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $newKeyAndNonce
|
||||
* @return self
|
||||
*/
|
||||
public function rekey($newKeyAndNonce)
|
||||
{
|
||||
$this->key = ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 0, 32);
|
||||
$this->nonce = str_pad(
|
||||
ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 32),
|
||||
12,
|
||||
"\0",
|
||||
STR_PAD_RIGHT
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @return self
|
||||
*/
|
||||
public function xorNonce($str)
|
||||
{
|
||||
$this->nonce = ParagonIE_Sodium_Core_Util::xorStrings(
|
||||
$this->getNonce(),
|
||||
str_pad(
|
||||
ParagonIE_Sodium_Core_Util::substr($str, 0, 8),
|
||||
12,
|
||||
"\0",
|
||||
STR_PAD_RIGHT
|
||||
)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return self
|
||||
*/
|
||||
public static function fromString($string)
|
||||
{
|
||||
$state = new ParagonIE_Sodium_Core_SecretStream_State(
|
||||
ParagonIE_Sodium_Core_Util::substr($string, 0, 32)
|
||||
);
|
||||
$state->counter = ParagonIE_Sodium_Core_Util::load_4(
|
||||
ParagonIE_Sodium_Core_Util::substr($string, 32, 4)
|
||||
);
|
||||
$state->nonce = ParagonIE_Sodium_Core_Util::substr($string, 36, 12);
|
||||
$state->_pad = ParagonIE_Sodium_Core_Util::substr($string, 48, 8);
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->key .
|
||||
$this->getCounter() .
|
||||
$this->nonce .
|
||||
$this->_pad;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,249 +1,306 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_SipHash', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_SipHash', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_SodiumCompat_Core_SipHash
|
||||
*
|
||||
* Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_SipHash extends ParagonIE_Sodium_Core_Util
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_SodiumCompat_Core_SipHash
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int[] $v
|
||||
* @return int[]
|
||||
*
|
||||
* Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_SipHash extends \ParagonIE_Sodium_Core_Util
|
||||
public static function sipRound(array $v)
|
||||
{
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int[] $v
|
||||
* @return int[]
|
||||
*
|
||||
*/
|
||||
public static function sipRound(array $v)
|
||||
{
|
||||
# v0 += v1;
|
||||
list($v[0], $v[1]) = self::add(array($v[0], $v[1]), array($v[2], $v[3]));
|
||||
# v1=ROTL(v1,13);
|
||||
list($v[2], $v[3]) = self::rotl_64((int) $v[2], (int) $v[3], 13);
|
||||
# v1 ^= v0;
|
||||
$v[2] = (int) $v[2] ^ (int) $v[0];
|
||||
$v[3] = (int) $v[3] ^ (int) $v[1];
|
||||
# v0=ROTL(v0,32);
|
||||
list($v[0], $v[1]) = self::rotl_64((int) $v[0], (int) $v[1], 32);
|
||||
# v2 += v3;
|
||||
list($v[4], $v[5]) = self::add(array((int) $v[4], (int) $v[5]), array((int) $v[6], (int) $v[7]));
|
||||
# v3=ROTL(v3,16);
|
||||
list($v[6], $v[7]) = self::rotl_64((int) $v[6], (int) $v[7], 16);
|
||||
# v3 ^= v2;
|
||||
$v[6] = (int) $v[6] ^ (int) $v[4];
|
||||
$v[7] = (int) $v[7] ^ (int) $v[5];
|
||||
# v0 += v3;
|
||||
list($v[0], $v[1]) = self::add(array((int) $v[0], (int) $v[1]), array((int) $v[6], (int) $v[7]));
|
||||
# v3=ROTL(v3,21);
|
||||
list($v[6], $v[7]) = self::rotl_64((int) $v[6], (int) $v[7], 21);
|
||||
# v3 ^= v0;
|
||||
$v[6] = (int) $v[6] ^ (int) $v[0];
|
||||
$v[7] = (int) $v[7] ^ (int) $v[1];
|
||||
# v2 += v1;
|
||||
list($v[4], $v[5]) = self::add(array((int) $v[4], (int) $v[5]), array((int) $v[2], (int) $v[3]));
|
||||
# v1=ROTL(v1,17);
|
||||
list($v[2], $v[3]) = self::rotl_64((int) $v[2], (int) $v[3], 17);
|
||||
# v1 ^= v2;;
|
||||
$v[2] = (int) $v[2] ^ (int) $v[4];
|
||||
$v[3] = (int) $v[3] ^ (int) $v[5];
|
||||
# v2=ROTL(v2,32)
|
||||
list($v[4], $v[5]) = self::rotl_64((int) $v[4], (int) $v[5], 32);
|
||||
return $v;
|
||||
}
|
||||
/**
|
||||
* Add two 32 bit integers representing a 64-bit integer.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int[] $a
|
||||
* @param int[] $b
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function add(array $a, array $b)
|
||||
{
|
||||
/** @var int $x1 */
|
||||
$x1 = $a[1] + $b[1];
|
||||
/** @var int $c */
|
||||
$c = $x1 >> 32;
|
||||
// Carry if ($a + $b) > 0xffffffff
|
||||
/** @var int $x0 */
|
||||
$x0 = $a[0] + $b[0] + $c;
|
||||
return array($x0 & 0xffffffff, $x1 & 0xffffffff);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $int0
|
||||
* @param int $int1
|
||||
* @param int $c
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function rotl_64($int0, $int1, $c)
|
||||
{
|
||||
$int0 &= 0xffffffff;
|
||||
$int1 &= 0xffffffff;
|
||||
$c &= 63;
|
||||
if ($c === 32) {
|
||||
return array($int1, $int0);
|
||||
}
|
||||
if ($c > 31) {
|
||||
$tmp = $int1;
|
||||
$int1 = $int0;
|
||||
$int0 = $tmp;
|
||||
$c &= 31;
|
||||
}
|
||||
if ($c === 0) {
|
||||
return array($int0, $int1);
|
||||
}
|
||||
return array(0xffffffff & ($int0 << $c | $int1 >> 32 - $c), 0xffffffff & ($int1 << $c | $int0 >> 32 - $c));
|
||||
}
|
||||
/**
|
||||
* Implements Siphash-2-4 using only 32-bit numbers.
|
||||
*
|
||||
* When we split an int into two, the higher bits go to the lower index.
|
||||
* e.g. 0xDEADBEEFAB10C92D becomes [
|
||||
* 0 => 0xDEADBEEF,
|
||||
* 1 => 0xAB10C92D
|
||||
* ].
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sipHash24($in, $key)
|
||||
{
|
||||
$inlen = self::strlen($in);
|
||||
# /* "somepseudorandomlygeneratedbytes" */
|
||||
# u64 v0 = 0x736f6d6570736575ULL;
|
||||
# u64 v1 = 0x646f72616e646f6dULL;
|
||||
# u64 v2 = 0x6c7967656e657261ULL;
|
||||
# u64 v3 = 0x7465646279746573ULL;
|
||||
$v = array(
|
||||
0x736f6d65,
|
||||
// 0
|
||||
0x70736575,
|
||||
// 1
|
||||
0x646f7261,
|
||||
// 2
|
||||
0x6e646f6d,
|
||||
// 3
|
||||
0x6c796765,
|
||||
// 4
|
||||
0x6e657261,
|
||||
// 5
|
||||
0x74656462,
|
||||
// 6
|
||||
0x79746573,
|
||||
);
|
||||
// v0 => $v[0], $v[1]
|
||||
// v1 => $v[2], $v[3]
|
||||
// v2 => $v[4], $v[5]
|
||||
// v3 => $v[6], $v[7]
|
||||
# u64 k0 = LOAD64_LE( k );
|
||||
# u64 k1 = LOAD64_LE( k + 8 );
|
||||
$k = array(self::load_4(self::substr($key, 4, 4)), self::load_4(self::substr($key, 0, 4)), self::load_4(self::substr($key, 12, 4)), self::load_4(self::substr($key, 8, 4)));
|
||||
// k0 => $k[0], $k[1]
|
||||
// k1 => $k[2], $k[3]
|
||||
# b = ( ( u64 )inlen ) << 56;
|
||||
$b = array($inlen << 24, 0);
|
||||
// See docblock for why the 0th index gets the higher bits.
|
||||
# v3 ^= k1;
|
||||
$v[6] ^= $k[2];
|
||||
$v[7] ^= $k[3];
|
||||
# v2 ^= k0;
|
||||
$v[4] ^= $k[0];
|
||||
$v[5] ^= $k[1];
|
||||
# v1 ^= k1;
|
||||
$v[2] ^= $k[2];
|
||||
$v[3] ^= $k[3];
|
||||
# v0 ^= k0;
|
||||
$v[0] ^= $k[0];
|
||||
$v[1] ^= $k[1];
|
||||
$left = $inlen;
|
||||
# for ( ; in != end; in += 8 )
|
||||
while ($left >= 8) {
|
||||
# m = LOAD64_LE( in );
|
||||
$m = array(self::load_4(self::substr($in, 4, 4)), self::load_4(self::substr($in, 0, 4)));
|
||||
# v3 ^= m;
|
||||
$v[6] ^= $m[0];
|
||||
$v[7] ^= $m[1];
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
# v0 ^= m;
|
||||
$v[0] ^= $m[0];
|
||||
$v[1] ^= $m[1];
|
||||
$in = self::substr($in, 8);
|
||||
$left -= 8;
|
||||
}
|
||||
# switch( left )
|
||||
# {
|
||||
# case 7: b |= ( ( u64 )in[ 6] ) << 48;
|
||||
# case 6: b |= ( ( u64 )in[ 5] ) << 40;
|
||||
# case 5: b |= ( ( u64 )in[ 4] ) << 32;
|
||||
# case 4: b |= ( ( u64 )in[ 3] ) << 24;
|
||||
# case 3: b |= ( ( u64 )in[ 2] ) << 16;
|
||||
# case 2: b |= ( ( u64 )in[ 1] ) << 8;
|
||||
# case 1: b |= ( ( u64 )in[ 0] ); break;
|
||||
# case 0: break;
|
||||
# }
|
||||
switch ($left) {
|
||||
case 7:
|
||||
$b[0] |= self::chrToInt($in[6]) << 16;
|
||||
case 6:
|
||||
$b[0] |= self::chrToInt($in[5]) << 8;
|
||||
case 5:
|
||||
$b[0] |= self::chrToInt($in[4]);
|
||||
case 4:
|
||||
$b[1] |= self::chrToInt($in[3]) << 24;
|
||||
case 3:
|
||||
$b[1] |= self::chrToInt($in[2]) << 16;
|
||||
case 2:
|
||||
$b[1] |= self::chrToInt($in[1]) << 8;
|
||||
case 1:
|
||||
$b[1] |= self::chrToInt($in[0]);
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
// See docblock for why the 0th index gets the higher bits.
|
||||
# v3 ^= b;
|
||||
$v[6] ^= $b[0];
|
||||
$v[7] ^= $b[1];
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
# v0 ^= b;
|
||||
$v[0] ^= $b[0];
|
||||
$v[1] ^= $b[1];
|
||||
// Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation
|
||||
# v2 ^= 0xff;
|
||||
$v[5] ^= 0xff;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
# b = v0 ^ v1 ^ v2 ^ v3;
|
||||
# STORE64_LE( out, b );
|
||||
return self::store32_le($v[1] ^ $v[3] ^ $v[5] ^ $v[7]) . self::store32_le($v[0] ^ $v[2] ^ $v[4] ^ $v[6]);
|
||||
}
|
||||
# v0 += v1;
|
||||
list($v[0], $v[1]) = self::add(
|
||||
array($v[0], $v[1]),
|
||||
array($v[2], $v[3])
|
||||
);
|
||||
|
||||
# v1=ROTL(v1,13);
|
||||
list($v[2], $v[3]) = self::rotl_64((int) $v[2], (int) $v[3], 13);
|
||||
|
||||
# v1 ^= v0;
|
||||
$v[2] = (int) $v[2] ^ (int) $v[0];
|
||||
$v[3] = (int) $v[3] ^ (int) $v[1];
|
||||
|
||||
# v0=ROTL(v0,32);
|
||||
list($v[0], $v[1]) = self::rotl_64((int) $v[0], (int) $v[1], 32);
|
||||
|
||||
# v2 += v3;
|
||||
list($v[4], $v[5]) = self::add(
|
||||
array((int) $v[4], (int) $v[5]),
|
||||
array((int) $v[6], (int) $v[7])
|
||||
);
|
||||
|
||||
# v3=ROTL(v3,16);
|
||||
list($v[6], $v[7]) = self::rotl_64((int) $v[6], (int) $v[7], 16);
|
||||
|
||||
# v3 ^= v2;
|
||||
$v[6] = (int) $v[6] ^ (int) $v[4];
|
||||
$v[7] = (int) $v[7] ^ (int) $v[5];
|
||||
|
||||
# v0 += v3;
|
||||
list($v[0], $v[1]) = self::add(
|
||||
array((int) $v[0], (int) $v[1]),
|
||||
array((int) $v[6], (int) $v[7])
|
||||
);
|
||||
|
||||
# v3=ROTL(v3,21);
|
||||
list($v[6], $v[7]) = self::rotl_64((int) $v[6], (int) $v[7], 21);
|
||||
|
||||
# v3 ^= v0;
|
||||
$v[6] = (int) $v[6] ^ (int) $v[0];
|
||||
$v[7] = (int) $v[7] ^ (int) $v[1];
|
||||
|
||||
# v2 += v1;
|
||||
list($v[4], $v[5]) = self::add(
|
||||
array((int) $v[4], (int) $v[5]),
|
||||
array((int) $v[2], (int) $v[3])
|
||||
);
|
||||
|
||||
# v1=ROTL(v1,17);
|
||||
list($v[2], $v[3]) = self::rotl_64((int) $v[2], (int) $v[3], 17);
|
||||
|
||||
# v1 ^= v2;;
|
||||
$v[2] = (int) $v[2] ^ (int) $v[4];
|
||||
$v[3] = (int) $v[3] ^ (int) $v[5];
|
||||
|
||||
# v2=ROTL(v2,32)
|
||||
list($v[4], $v[5]) = self::rotl_64((int) $v[4], (int) $v[5], 32);
|
||||
|
||||
return $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_SodiumCompat_Core_SipHash
|
||||
* Add two 32 bit integers representing a 64-bit integer.
|
||||
*
|
||||
* Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int[] $a
|
||||
* @param int[] $b
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
|
||||
public static function add(array $a, array $b)
|
||||
{
|
||||
/** @var int $x1 */
|
||||
$x1 = $a[1] + $b[1];
|
||||
/** @var int $c */
|
||||
$c = $x1 >> 32; // Carry if ($a + $b) > 0xffffffff
|
||||
/** @var int $x0 */
|
||||
$x0 = $a[0] + $b[0] + $c;
|
||||
return array(
|
||||
$x0 & 0xffffffff,
|
||||
$x1 & 0xffffffff
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $int0
|
||||
* @param int $int1
|
||||
* @param int $c
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
public static function rotl_64($int0, $int1, $c)
|
||||
{
|
||||
$int0 &= 0xffffffff;
|
||||
$int1 &= 0xffffffff;
|
||||
$c &= 63;
|
||||
if ($c === 32) {
|
||||
return array($int1, $int0);
|
||||
}
|
||||
if ($c > 31) {
|
||||
$tmp = $int1;
|
||||
$int1 = $int0;
|
||||
$int0 = $tmp;
|
||||
$c &= 31;
|
||||
}
|
||||
if ($c === 0) {
|
||||
return array($int0, $int1);
|
||||
}
|
||||
return array(
|
||||
0xffffffff & (
|
||||
($int0 << $c)
|
||||
|
|
||||
($int1 >> (32 - $c))
|
||||
),
|
||||
0xffffffff & (
|
||||
($int1 << $c)
|
||||
|
|
||||
($int0 >> (32 - $c))
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Siphash-2-4 using only 32-bit numbers.
|
||||
*
|
||||
* When we split an int into two, the higher bits go to the lower index.
|
||||
* e.g. 0xDEADBEEFAB10C92D becomes [
|
||||
* 0 => 0xDEADBEEF,
|
||||
* 1 => 0xAB10C92D
|
||||
* ].
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sipHash24($in, $key)
|
||||
{
|
||||
$inlen = self::strlen($in);
|
||||
|
||||
# /* "somepseudorandomlygeneratedbytes" */
|
||||
# u64 v0 = 0x736f6d6570736575ULL;
|
||||
# u64 v1 = 0x646f72616e646f6dULL;
|
||||
# u64 v2 = 0x6c7967656e657261ULL;
|
||||
# u64 v3 = 0x7465646279746573ULL;
|
||||
$v = array(
|
||||
0x736f6d65, // 0
|
||||
0x70736575, // 1
|
||||
0x646f7261, // 2
|
||||
0x6e646f6d, // 3
|
||||
0x6c796765, // 4
|
||||
0x6e657261, // 5
|
||||
0x74656462, // 6
|
||||
0x79746573 // 7
|
||||
);
|
||||
// v0 => $v[0], $v[1]
|
||||
// v1 => $v[2], $v[3]
|
||||
// v2 => $v[4], $v[5]
|
||||
// v3 => $v[6], $v[7]
|
||||
|
||||
# u64 k0 = LOAD64_LE( k );
|
||||
# u64 k1 = LOAD64_LE( k + 8 );
|
||||
$k = array(
|
||||
self::load_4(self::substr($key, 4, 4)),
|
||||
self::load_4(self::substr($key, 0, 4)),
|
||||
self::load_4(self::substr($key, 12, 4)),
|
||||
self::load_4(self::substr($key, 8, 4))
|
||||
);
|
||||
// k0 => $k[0], $k[1]
|
||||
// k1 => $k[2], $k[3]
|
||||
|
||||
# b = ( ( u64 )inlen ) << 56;
|
||||
$b = array(
|
||||
$inlen << 24,
|
||||
0
|
||||
);
|
||||
// See docblock for why the 0th index gets the higher bits.
|
||||
|
||||
# v3 ^= k1;
|
||||
$v[6] ^= $k[2];
|
||||
$v[7] ^= $k[3];
|
||||
# v2 ^= k0;
|
||||
$v[4] ^= $k[0];
|
||||
$v[5] ^= $k[1];
|
||||
# v1 ^= k1;
|
||||
$v[2] ^= $k[2];
|
||||
$v[3] ^= $k[3];
|
||||
# v0 ^= k0;
|
||||
$v[0] ^= $k[0];
|
||||
$v[1] ^= $k[1];
|
||||
|
||||
$left = $inlen;
|
||||
# for ( ; in != end; in += 8 )
|
||||
while ($left >= 8) {
|
||||
# m = LOAD64_LE( in );
|
||||
$m = array(
|
||||
self::load_4(self::substr($in, 4, 4)),
|
||||
self::load_4(self::substr($in, 0, 4))
|
||||
);
|
||||
|
||||
# v3 ^= m;
|
||||
$v[6] ^= $m[0];
|
||||
$v[7] ^= $m[1];
|
||||
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
|
||||
# v0 ^= m;
|
||||
$v[0] ^= $m[0];
|
||||
$v[1] ^= $m[1];
|
||||
|
||||
$in = self::substr($in, 8);
|
||||
$left -= 8;
|
||||
}
|
||||
|
||||
# switch( left )
|
||||
# {
|
||||
# case 7: b |= ( ( u64 )in[ 6] ) << 48;
|
||||
# case 6: b |= ( ( u64 )in[ 5] ) << 40;
|
||||
# case 5: b |= ( ( u64 )in[ 4] ) << 32;
|
||||
# case 4: b |= ( ( u64 )in[ 3] ) << 24;
|
||||
# case 3: b |= ( ( u64 )in[ 2] ) << 16;
|
||||
# case 2: b |= ( ( u64 )in[ 1] ) << 8;
|
||||
# case 1: b |= ( ( u64 )in[ 0] ); break;
|
||||
# case 0: break;
|
||||
# }
|
||||
switch ($left) {
|
||||
case 7:
|
||||
$b[0] |= self::chrToInt($in[6]) << 16;
|
||||
case 6:
|
||||
$b[0] |= self::chrToInt($in[5]) << 8;
|
||||
case 5:
|
||||
$b[0] |= self::chrToInt($in[4]);
|
||||
case 4:
|
||||
$b[1] |= self::chrToInt($in[3]) << 24;
|
||||
case 3:
|
||||
$b[1] |= self::chrToInt($in[2]) << 16;
|
||||
case 2:
|
||||
$b[1] |= self::chrToInt($in[1]) << 8;
|
||||
case 1:
|
||||
$b[1] |= self::chrToInt($in[0]);
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
// See docblock for why the 0th index gets the higher bits.
|
||||
|
||||
# v3 ^= b;
|
||||
$v[6] ^= $b[0];
|
||||
$v[7] ^= $b[1];
|
||||
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
|
||||
# v0 ^= b;
|
||||
$v[0] ^= $b[0];
|
||||
$v[1] ^= $b[1];
|
||||
|
||||
// Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation
|
||||
# v2 ^= 0xff;
|
||||
$v[5] ^= 0xff;
|
||||
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
|
||||
# b = v0 ^ v1 ^ v2 ^ v3;
|
||||
# STORE64_LE( out, b );
|
||||
return self::store32_le($v[1] ^ $v[3] ^ $v[5] ^ $v[7]) .
|
||||
self::store32_le($v[0] ^ $v[2] ^ $v[4] ^ $v[6]);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,269 +1,300 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_X25519', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_X25519', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_X25519
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_X25519 extends ParagonIE_Sodium_Core_Curve25519
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_X25519
|
||||
* Alters the objects passed to this method in place.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $f
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $g
|
||||
* @param int $b
|
||||
* @return void
|
||||
* @psalm-suppress MixedAssignment
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_X25519 extends \ParagonIE_Sodium_Core_Curve25519
|
||||
public static function fe_cswap(
|
||||
ParagonIE_Sodium_Core_Curve25519_Fe $f,
|
||||
ParagonIE_Sodium_Core_Curve25519_Fe $g,
|
||||
$b = 0
|
||||
) {
|
||||
$b = -$b;
|
||||
$x0 = ($f->e0 ^ $g->e0) & $b;
|
||||
$x1 = ($f->e1 ^ $g->e1) & $b;
|
||||
$x2 = ($f->e2 ^ $g->e2) & $b;
|
||||
$x3 = ($f->e3 ^ $g->e3) & $b;
|
||||
$x4 = ($f->e4 ^ $g->e4) & $b;
|
||||
$x5 = ($f->e5 ^ $g->e5) & $b;
|
||||
$x6 = ($f->e6 ^ $g->e6) & $b;
|
||||
$x7 = ($f->e7 ^ $g->e7) & $b;
|
||||
$x8 = ($f->e8 ^ $g->e8) & $b;
|
||||
$x9 = ($f->e9 ^ $g->e9) & $b;
|
||||
$f->e0 ^= $x0;
|
||||
$f->e1 ^= $x1;
|
||||
$f->e2 ^= $x2;
|
||||
$f->e3 ^= $x3;
|
||||
$f->e4 ^= $x4;
|
||||
$f->e5 ^= $x5;
|
||||
$f->e6 ^= $x6;
|
||||
$f->e7 ^= $x7;
|
||||
$f->e8 ^= $x8;
|
||||
$f->e9 ^= $x9;
|
||||
$g->e0 ^= $x0;
|
||||
$g->e1 ^= $x1;
|
||||
$g->e2 ^= $x2;
|
||||
$g->e3 ^= $x3;
|
||||
$g->e4 ^= $x4;
|
||||
$g->e5 ^= $x5;
|
||||
$g->e6 ^= $x6;
|
||||
$g->e7 ^= $x7;
|
||||
$g->e8 ^= $x8;
|
||||
$g->e9 ^= $x9;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $f
|
||||
* @return ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public static function fe_mul121666(ParagonIE_Sodium_Core_Curve25519_Fe $f)
|
||||
{
|
||||
/**
|
||||
* Alters the objects passed to this method in place.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $f
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $g
|
||||
* @param int $b
|
||||
* @return void
|
||||
* @psalm-suppress MixedAssignment
|
||||
*/
|
||||
public static function fe_cswap(\ParagonIE_Sodium_Core_Curve25519_Fe $f, \ParagonIE_Sodium_Core_Curve25519_Fe $g, $b = 0)
|
||||
{
|
||||
$f0 = (int) $f[0];
|
||||
$f1 = (int) $f[1];
|
||||
$f2 = (int) $f[2];
|
||||
$f3 = (int) $f[3];
|
||||
$f4 = (int) $f[4];
|
||||
$f5 = (int) $f[5];
|
||||
$f6 = (int) $f[6];
|
||||
$f7 = (int) $f[7];
|
||||
$f8 = (int) $f[8];
|
||||
$f9 = (int) $f[9];
|
||||
$g0 = (int) $g[0];
|
||||
$g1 = (int) $g[1];
|
||||
$g2 = (int) $g[2];
|
||||
$g3 = (int) $g[3];
|
||||
$g4 = (int) $g[4];
|
||||
$g5 = (int) $g[5];
|
||||
$g6 = (int) $g[6];
|
||||
$g7 = (int) $g[7];
|
||||
$g8 = (int) $g[8];
|
||||
$g9 = (int) $g[9];
|
||||
$b = -$b;
|
||||
$x0 = ($f0 ^ $g0) & $b;
|
||||
$x1 = ($f1 ^ $g1) & $b;
|
||||
$x2 = ($f2 ^ $g2) & $b;
|
||||
$x3 = ($f3 ^ $g3) & $b;
|
||||
$x4 = ($f4 ^ $g4) & $b;
|
||||
$x5 = ($f5 ^ $g5) & $b;
|
||||
$x6 = ($f6 ^ $g6) & $b;
|
||||
$x7 = ($f7 ^ $g7) & $b;
|
||||
$x8 = ($f8 ^ $g8) & $b;
|
||||
$x9 = ($f9 ^ $g9) & $b;
|
||||
$f[0] = $f0 ^ $x0;
|
||||
$f[1] = $f1 ^ $x1;
|
||||
$f[2] = $f2 ^ $x2;
|
||||
$f[3] = $f3 ^ $x3;
|
||||
$f[4] = $f4 ^ $x4;
|
||||
$f[5] = $f5 ^ $x5;
|
||||
$f[6] = $f6 ^ $x6;
|
||||
$f[7] = $f7 ^ $x7;
|
||||
$f[8] = $f8 ^ $x8;
|
||||
$f[9] = $f9 ^ $x9;
|
||||
$g[0] = $g0 ^ $x0;
|
||||
$g[1] = $g1 ^ $x1;
|
||||
$g[2] = $g2 ^ $x2;
|
||||
$g[3] = $g3 ^ $x3;
|
||||
$g[4] = $g4 ^ $x4;
|
||||
$g[5] = $g5 ^ $x5;
|
||||
$g[6] = $g6 ^ $x6;
|
||||
$g[7] = $g7 ^ $x7;
|
||||
$g[8] = $g8 ^ $x8;
|
||||
$g[9] = $g9 ^ $x9;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $f
|
||||
* @return ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public static function fe_mul121666(\ParagonIE_Sodium_Core_Curve25519_Fe $f)
|
||||
{
|
||||
$h = array(self::mul((int) $f[0], 121666, 17), self::mul((int) $f[1], 121666, 17), self::mul((int) $f[2], 121666, 17), self::mul((int) $f[3], 121666, 17), self::mul((int) $f[4], 121666, 17), self::mul((int) $f[5], 121666, 17), self::mul((int) $f[6], 121666, 17), self::mul((int) $f[7], 121666, 17), self::mul((int) $f[8], 121666, 17), self::mul((int) $f[9], 121666, 17));
|
||||
/** @var int $carry9 */
|
||||
$carry9 = $h[9] + (1 << 24) >> 25;
|
||||
$h[0] += self::mul($carry9, 19, 5);
|
||||
$h[9] -= $carry9 << 25;
|
||||
/** @var int $carry1 */
|
||||
$carry1 = $h[1] + (1 << 24) >> 25;
|
||||
$h[2] += $carry1;
|
||||
$h[1] -= $carry1 << 25;
|
||||
/** @var int $carry3 */
|
||||
$carry3 = $h[3] + (1 << 24) >> 25;
|
||||
$h[4] += $carry3;
|
||||
$h[3] -= $carry3 << 25;
|
||||
/** @var int $carry5 */
|
||||
$carry5 = $h[5] + (1 << 24) >> 25;
|
||||
$h[6] += $carry5;
|
||||
$h[5] -= $carry5 << 25;
|
||||
/** @var int $carry7 */
|
||||
$carry7 = $h[7] + (1 << 24) >> 25;
|
||||
$h[8] += $carry7;
|
||||
$h[7] -= $carry7 << 25;
|
||||
/** @var int $carry0 */
|
||||
$carry0 = $h[0] + (1 << 25) >> 26;
|
||||
$h[1] += $carry0;
|
||||
$h[0] -= $carry0 << 26;
|
||||
/** @var int $carry2 */
|
||||
$carry2 = $h[2] + (1 << 25) >> 26;
|
||||
$h[3] += $carry2;
|
||||
$h[2] -= $carry2 << 26;
|
||||
/** @var int $carry4 */
|
||||
$carry4 = $h[4] + (1 << 25) >> 26;
|
||||
$h[5] += $carry4;
|
||||
$h[4] -= $carry4 << 26;
|
||||
/** @var int $carry6 */
|
||||
$carry6 = $h[6] + (1 << 25) >> 26;
|
||||
$h[7] += $carry6;
|
||||
$h[6] -= $carry6 << 26;
|
||||
/** @var int $carry8 */
|
||||
$carry8 = $h[8] + (1 << 25) >> 26;
|
||||
$h[9] += $carry8;
|
||||
$h[8] -= $carry8 << 26;
|
||||
foreach ($h as $i => $value) {
|
||||
$h[$i] = (int) $value;
|
||||
}
|
||||
return \ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* Inline comments preceded by # are from libsodium's ref10 code.
|
||||
*
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function crypto_scalarmult_curve25519_ref10($n, $p)
|
||||
{
|
||||
# for (i = 0;i < 32;++i) e[i] = n[i];
|
||||
$e = '' . $n;
|
||||
# e[0] &= 248;
|
||||
$e[0] = self::intToChr(self::chrToInt($e[0]) & 248);
|
||||
# e[31] &= 127;
|
||||
# e[31] |= 64;
|
||||
$e[31] = self::intToChr(self::chrToInt($e[31]) & 127 | 64);
|
||||
# fe_frombytes(x1,p);
|
||||
$x1 = self::fe_frombytes($p);
|
||||
# fe_1(x2);
|
||||
$x2 = self::fe_1();
|
||||
# fe_0(z2);
|
||||
$z2 = self::fe_0();
|
||||
# fe_copy(x3,x1);
|
||||
$x3 = self::fe_copy($x1);
|
||||
# fe_1(z3);
|
||||
$z3 = self::fe_1();
|
||||
# swap = 0;
|
||||
/** @var int $swap */
|
||||
$swap = 0;
|
||||
# for (pos = 254;pos >= 0;--pos) {
|
||||
for ($pos = 254; $pos >= 0; --$pos) {
|
||||
# b = e[pos / 8] >> (pos & 7);
|
||||
/** @var int $b */
|
||||
$b = self::chrToInt($e[(int) \floor($pos / 8)]) >> ($pos & 7);
|
||||
# b &= 1;
|
||||
$b &= 1;
|
||||
# swap ^= b;
|
||||
$swap ^= $b;
|
||||
# fe_cswap(x2,x3,swap);
|
||||
self::fe_cswap($x2, $x3, $swap);
|
||||
# fe_cswap(z2,z3,swap);
|
||||
self::fe_cswap($z2, $z3, $swap);
|
||||
# swap = b;
|
||||
$swap = $b;
|
||||
# fe_sub(tmp0,x3,z3);
|
||||
$tmp0 = self::fe_sub($x3, $z3);
|
||||
# fe_sub(tmp1,x2,z2);
|
||||
$tmp1 = self::fe_sub($x2, $z2);
|
||||
# fe_add(x2,x2,z2);
|
||||
$x2 = self::fe_add($x2, $z2);
|
||||
# fe_add(z2,x3,z3);
|
||||
$z2 = self::fe_add($x3, $z3);
|
||||
# fe_mul(z3,tmp0,x2);
|
||||
$z3 = self::fe_mul($tmp0, $x2);
|
||||
# fe_mul(z2,z2,tmp1);
|
||||
$z2 = self::fe_mul($z2, $tmp1);
|
||||
# fe_sq(tmp0,tmp1);
|
||||
$tmp0 = self::fe_sq($tmp1);
|
||||
# fe_sq(tmp1,x2);
|
||||
$tmp1 = self::fe_sq($x2);
|
||||
# fe_add(x3,z3,z2);
|
||||
$x3 = self::fe_add($z3, $z2);
|
||||
# fe_sub(z2,z3,z2);
|
||||
$z2 = self::fe_sub($z3, $z2);
|
||||
# fe_mul(x2,tmp1,tmp0);
|
||||
$x2 = self::fe_mul($tmp1, $tmp0);
|
||||
# fe_sub(tmp1,tmp1,tmp0);
|
||||
$tmp1 = self::fe_sub($tmp1, $tmp0);
|
||||
# fe_sq(z2,z2);
|
||||
$z2 = self::fe_sq($z2);
|
||||
# fe_mul121666(z3,tmp1);
|
||||
$z3 = self::fe_mul121666($tmp1);
|
||||
# fe_sq(x3,x3);
|
||||
$x3 = self::fe_sq($x3);
|
||||
# fe_add(tmp0,tmp0,z3);
|
||||
$tmp0 = self::fe_add($tmp0, $z3);
|
||||
# fe_mul(z3,x1,z2);
|
||||
$z3 = self::fe_mul($x1, $z2);
|
||||
# fe_mul(z2,tmp1,tmp0);
|
||||
$z2 = self::fe_mul($tmp1, $tmp0);
|
||||
}
|
||||
$h0 = self::mul($f->e0, 121666, 17);
|
||||
$h1 = self::mul($f->e1, 121666, 17);
|
||||
$h2 = self::mul($f->e2, 121666, 17);
|
||||
$h3 = self::mul($f->e3, 121666, 17);
|
||||
$h4 = self::mul($f->e4, 121666, 17);
|
||||
$h5 = self::mul($f->e5, 121666, 17);
|
||||
$h6 = self::mul($f->e6, 121666, 17);
|
||||
$h7 = self::mul($f->e7, 121666, 17);
|
||||
$h8 = self::mul($f->e8, 121666, 17);
|
||||
$h9 = self::mul($f->e9, 121666, 17);
|
||||
|
||||
$carry9 = ($h9 + (1 << 24)) >> 25;
|
||||
$h0 += self::mul($carry9, 19, 5);
|
||||
$h9 -= $carry9 << 25;
|
||||
|
||||
$carry1 = ($h1 + (1 << 24)) >> 25;
|
||||
$h2 += $carry1;
|
||||
$h1 -= $carry1 << 25;
|
||||
|
||||
$carry3 = ($h3 + (1 << 24)) >> 25;
|
||||
$h4 += $carry3;
|
||||
$h3 -= $carry3 << 25;
|
||||
|
||||
$carry5 = ($h5 + (1 << 24)) >> 25;
|
||||
$h6 += $carry5;
|
||||
$h5 -= $carry5 << 25;
|
||||
|
||||
$carry7 = ($h7 + (1 << 24)) >> 25;
|
||||
$h8 += $carry7;
|
||||
$h7 -= $carry7 << 25;
|
||||
|
||||
|
||||
$carry0 = ($h0 + (1 << 25)) >> 26;
|
||||
$h1 += $carry0;
|
||||
$h0 -= $carry0 << 26;
|
||||
|
||||
$carry2 = ($h2 + (1 << 25)) >> 26;
|
||||
$h3 += $carry2;
|
||||
$h2 -= $carry2 << 26;
|
||||
|
||||
$carry4 = ($h4 + (1 << 25)) >> 26;
|
||||
$h5 += $carry4;
|
||||
$h4 -= $carry4 << 26;
|
||||
|
||||
$carry6 = ($h6 + (1 << 25)) >> 26;
|
||||
$h7 += $carry6;
|
||||
$h6 -= $carry6 << 26;
|
||||
|
||||
$carry8 = ($h8 + (1 << 25)) >> 26;
|
||||
$h9 += $carry8;
|
||||
$h8 -= $carry8 << 26;
|
||||
return new ParagonIE_Sodium_Core_Curve25519_Fe($h0, $h1, $h2, $h3, $h4, $h5, $h6, $h7, $h8, $h9);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* Inline comments preceded by # are from libsodium's ref10 code.
|
||||
*
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function crypto_scalarmult_curve25519_ref10($n, $p)
|
||||
{
|
||||
# for (i = 0;i < 32;++i) e[i] = n[i];
|
||||
$e = '' . $n;
|
||||
# e[0] &= 248;
|
||||
$e[0] = self::intToChr(
|
||||
self::chrToInt($e[0]) & 248
|
||||
);
|
||||
# e[31] &= 127;
|
||||
# e[31] |= 64;
|
||||
$e[31] = self::intToChr(
|
||||
(self::chrToInt($e[31]) & 127) | 64
|
||||
);
|
||||
# fe_frombytes(x1,p);
|
||||
$x1 = self::fe_frombytes($p);
|
||||
# fe_1(x2);
|
||||
$x2 = self::fe_1();
|
||||
# fe_0(z2);
|
||||
$z2 = self::fe_0();
|
||||
# fe_copy(x3,x1);
|
||||
$x3 = self::fe_copy($x1);
|
||||
# fe_1(z3);
|
||||
$z3 = self::fe_1();
|
||||
|
||||
# swap = 0;
|
||||
/** @var int $swap */
|
||||
$swap = 0;
|
||||
|
||||
# for (pos = 254;pos >= 0;--pos) {
|
||||
for ($pos = 254; $pos >= 0; --$pos) {
|
||||
# b = e[pos / 8] >> (pos & 7);
|
||||
/** @var int $b */
|
||||
$b = self::chrToInt(
|
||||
$e[(int) floor($pos / 8)]
|
||||
) >> ($pos & 7);
|
||||
# b &= 1;
|
||||
$b &= 1;
|
||||
# swap ^= b;
|
||||
$swap ^= $b;
|
||||
# fe_cswap(x2,x3,swap);
|
||||
self::fe_cswap($x2, $x3, $swap);
|
||||
# fe_cswap(z2,z3,swap);
|
||||
self::fe_cswap($z2, $z3, $swap);
|
||||
# fe_invert(z2,z2);
|
||||
$z2 = self::fe_invert($z2);
|
||||
# fe_mul(x2,x2,z2);
|
||||
$x2 = self::fe_mul($x2, $z2);
|
||||
# fe_tobytes(q,x2);
|
||||
return self::fe_tobytes($x2);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $edwardsY
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $edwardsZ
|
||||
* @return ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
public static function edwards_to_montgomery(\ParagonIE_Sodium_Core_Curve25519_Fe $edwardsY, \ParagonIE_Sodium_Core_Curve25519_Fe $edwardsZ)
|
||||
{
|
||||
$tempX = self::fe_add($edwardsZ, $edwardsY);
|
||||
$tempZ = self::fe_sub($edwardsZ, $edwardsY);
|
||||
$tempZ = self::fe_invert($tempZ);
|
||||
return self::fe_mul($tempX, $tempZ);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $n
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function crypto_scalarmult_curve25519_ref10_base($n)
|
||||
{
|
||||
# for (i = 0;i < 32;++i) e[i] = n[i];
|
||||
$e = '' . $n;
|
||||
# e[0] &= 248;
|
||||
$e[0] = self::intToChr(self::chrToInt($e[0]) & 248);
|
||||
# e[31] &= 127;
|
||||
# e[31] |= 64;
|
||||
$e[31] = self::intToChr(self::chrToInt($e[31]) & 127 | 64);
|
||||
$A = self::ge_scalarmult_base($e);
|
||||
if (!$A->Y instanceof \ParagonIE_Sodium_Core_Curve25519_Fe || !$A->Z instanceof \ParagonIE_Sodium_Core_Curve25519_Fe) {
|
||||
throw new \TypeError('Null points encountered');
|
||||
}
|
||||
$pk = self::edwards_to_montgomery($A->Y, $A->Z);
|
||||
return self::fe_tobytes($pk);
|
||||
# swap = b;
|
||||
$swap = $b;
|
||||
# fe_sub(tmp0,x3,z3);
|
||||
$tmp0 = self::fe_sub($x3, $z3);
|
||||
# fe_sub(tmp1,x2,z2);
|
||||
$tmp1 = self::fe_sub($x2, $z2);
|
||||
|
||||
# fe_add(x2,x2,z2);
|
||||
$x2 = self::fe_add($x2, $z2);
|
||||
|
||||
# fe_add(z2,x3,z3);
|
||||
$z2 = self::fe_add($x3, $z3);
|
||||
|
||||
# fe_mul(z3,tmp0,x2);
|
||||
$z3 = self::fe_mul($tmp0, $x2);
|
||||
|
||||
# fe_mul(z2,z2,tmp1);
|
||||
$z2 = self::fe_mul($z2, $tmp1);
|
||||
|
||||
# fe_sq(tmp0,tmp1);
|
||||
$tmp0 = self::fe_sq($tmp1);
|
||||
|
||||
# fe_sq(tmp1,x2);
|
||||
$tmp1 = self::fe_sq($x2);
|
||||
|
||||
# fe_add(x3,z3,z2);
|
||||
$x3 = self::fe_add($z3, $z2);
|
||||
|
||||
# fe_sub(z2,z3,z2);
|
||||
$z2 = self::fe_sub($z3, $z2);
|
||||
|
||||
# fe_mul(x2,tmp1,tmp0);
|
||||
$x2 = self::fe_mul($tmp1, $tmp0);
|
||||
|
||||
# fe_sub(tmp1,tmp1,tmp0);
|
||||
$tmp1 = self::fe_sub($tmp1, $tmp0);
|
||||
|
||||
# fe_sq(z2,z2);
|
||||
$z2 = self::fe_sq($z2);
|
||||
|
||||
# fe_mul121666(z3,tmp1);
|
||||
$z3 = self::fe_mul121666($tmp1);
|
||||
|
||||
# fe_sq(x3,x3);
|
||||
$x3 = self::fe_sq($x3);
|
||||
|
||||
# fe_add(tmp0,tmp0,z3);
|
||||
$tmp0 = self::fe_add($tmp0, $z3);
|
||||
|
||||
# fe_mul(z3,x1,z2);
|
||||
$z3 = self::fe_mul($x1, $z2);
|
||||
|
||||
# fe_mul(z2,tmp1,tmp0);
|
||||
$z2 = self::fe_mul($tmp1, $tmp0);
|
||||
}
|
||||
|
||||
# fe_cswap(x2,x3,swap);
|
||||
self::fe_cswap($x2, $x3, $swap);
|
||||
|
||||
# fe_cswap(z2,z3,swap);
|
||||
self::fe_cswap($z2, $z3, $swap);
|
||||
|
||||
# fe_invert(z2,z2);
|
||||
$z2 = self::fe_invert($z2);
|
||||
|
||||
# fe_mul(x2,x2,z2);
|
||||
$x2 = self::fe_mul($x2, $z2);
|
||||
# fe_tobytes(q,x2);
|
||||
return self::fe_tobytes($x2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_X25519
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $edwardsY
|
||||
* @param ParagonIE_Sodium_Core_Curve25519_Fe $edwardsZ
|
||||
* @return ParagonIE_Sodium_Core_Curve25519_Fe
|
||||
*/
|
||||
|
||||
public static function edwards_to_montgomery(
|
||||
ParagonIE_Sodium_Core_Curve25519_Fe $edwardsY,
|
||||
ParagonIE_Sodium_Core_Curve25519_Fe $edwardsZ
|
||||
) {
|
||||
$tempX = self::fe_add($edwardsZ, $edwardsY);
|
||||
$tempZ = self::fe_sub($edwardsZ, $edwardsY);
|
||||
$tempZ = self::fe_invert($tempZ);
|
||||
return self::fe_mul($tempX, $tempZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $n
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function crypto_scalarmult_curve25519_ref10_base($n)
|
||||
{
|
||||
# for (i = 0;i < 32;++i) e[i] = n[i];
|
||||
$e = '' . $n;
|
||||
|
||||
# e[0] &= 248;
|
||||
$e[0] = self::intToChr(
|
||||
self::chrToInt($e[0]) & 248
|
||||
);
|
||||
|
||||
# e[31] &= 127;
|
||||
# e[31] |= 64;
|
||||
$e[31] = self::intToChr(
|
||||
(self::chrToInt($e[31]) & 127) | 64
|
||||
);
|
||||
|
||||
$A = self::ge_scalarmult_base($e);
|
||||
if (
|
||||
!($A->Y instanceof ParagonIE_Sodium_Core_Curve25519_Fe)
|
||||
||
|
||||
!($A->Z instanceof ParagonIE_Sodium_Core_Curve25519_Fe)
|
||||
) {
|
||||
throw new TypeError('Null points encountered');
|
||||
}
|
||||
$pk = self::edwards_to_montgomery($A->Y, $A->Z);
|
||||
return self::fe_tobytes($pk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +1,117 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_XChaCha20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_XChaCha20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_XChaCha20
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_XChaCha20 extends ParagonIE_Sodium_Core_HChaCha20
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_XChaCha20
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
class ParagonIE_Sodium_Core_XChaCha20 extends \ParagonIE_Sodium_Core_HChaCha20
|
||||
public static function stream($len, $nonce, $key)
|
||||
{
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function stream($len = 64, $nonce = '', $key = '')
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new \SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core_ChaCha20_Ctx(self::hChaCha20(self::substr($nonce, 0, 16), $key), self::substr($nonce, 16, 8)), \str_repeat("\x00", $len));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStream($len = 64, $nonce = '', $key = '')
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new \SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core_ChaCha20_IetfCtx(self::hChaCha20(self::substr($nonce, 0, 16), $key), "\x00\x00\x00\x00" . self::substr($nonce, 16, 8)), \str_repeat("\x00", $len));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new \SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core_ChaCha20_Ctx(self::hChaCha20(self::substr($nonce, 0, 16), $key), self::substr($nonce, 16, 8), $ic), $message);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new \SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core_ChaCha20_IetfCtx(self::hChaCha20(self::substr($nonce, 0, 16), $key), "\x00\x00\x00\x00" . self::substr($nonce, 16, 8), $ic), $message);
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core_ChaCha20_Ctx(
|
||||
self::hChaCha20(
|
||||
self::substr($nonce, 0, 16),
|
||||
$key
|
||||
),
|
||||
self::substr($nonce, 16, 8)
|
||||
),
|
||||
str_repeat("\x00", $len)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_XChaCha20
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function ietfStream($len, $nonce, $key)
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx(
|
||||
self::hChaCha20(
|
||||
self::substr($nonce, 0, 16),
|
||||
$key
|
||||
),
|
||||
"\x00\x00\x00\x00" . self::substr($nonce, 16, 8)
|
||||
),
|
||||
str_repeat("\x00", $len)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function streamXorIc($message, $nonce, $key, $ic = '')
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core_ChaCha20_Ctx(
|
||||
self::hChaCha20(self::substr($nonce, 0, 16), $key),
|
||||
self::substr($nonce, 16, 8),
|
||||
$ic
|
||||
),
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStreamXorIc($message, $nonce, $key, $ic = '')
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core_ChaCha20_IetfCtx(
|
||||
self::hChaCha20(self::substr($nonce, 0, 16), $key),
|
||||
"\x00\x00\x00\x00" . self::substr($nonce, 16, 8),
|
||||
$ic
|
||||
),
|
||||
$message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,57 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_XSalsa20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_XSalsa20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_XSalsa20
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_XSalsa20 extends ParagonIE_Sodium_Core_HSalsa20
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_XSalsa20
|
||||
* Expand a key and nonce into an xsalsa20 keystream.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core_XSalsa20 extends \ParagonIE_Sodium_Core_HSalsa20
|
||||
public static function xsalsa20($len, $nonce, $key)
|
||||
{
|
||||
/**
|
||||
* Expand a key and nonce into an xsalsa20 keystream.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function xsalsa20($len, $nonce, $key)
|
||||
{
|
||||
$ret = self::salsa20($len, self::substr($nonce, 16, 8), self::hsalsa20($nonce, $key));
|
||||
return $ret;
|
||||
}
|
||||
/**
|
||||
* Encrypt a string with XSalsa20. Doesn't provide integrity.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function xsalsa20_xor($message, $nonce, $key)
|
||||
{
|
||||
return self::xorStrings($message, self::xsalsa20(self::strlen($message), $nonce, $key));
|
||||
}
|
||||
$ret = self::salsa20(
|
||||
$len,
|
||||
self::substr($nonce, 16, 8),
|
||||
self::hsalsa20($nonce, $key)
|
||||
);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_XSalsa20
|
||||
* Encrypt a string with XSalsa20. Doesn't provide integrity.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function xsalsa20_xor($message, $nonce, $key)
|
||||
{
|
||||
return self::xorStrings(
|
||||
$message,
|
||||
self::xsalsa20(
|
||||
self::strlen($message),
|
||||
$nonce,
|
||||
$key
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,342 +1,400 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_ChaCha20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_ChaCha20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_ChaCha20
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_ChaCha20 extends ParagonIE_Sodium_Core32_Util
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_ChaCha20
|
||||
* The ChaCha20 quarter round function. Works on four 32-bit integers.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Int32 $a
|
||||
* @param ParagonIE_Sodium_Core32_Int32 $b
|
||||
* @param ParagonIE_Sodium_Core32_Int32 $c
|
||||
* @param ParagonIE_Sodium_Core32_Int32 $d
|
||||
* @return array<int, ParagonIE_Sodium_Core32_Int32>
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_ChaCha20 extends \ParagonIE_Sodium_Core32_Util
|
||||
{
|
||||
/**
|
||||
* The ChaCha20 quarter round function. Works on four 32-bit integers.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Int32 $a
|
||||
* @param ParagonIE_Sodium_Core32_Int32 $b
|
||||
* @param ParagonIE_Sodium_Core32_Int32 $c
|
||||
* @param ParagonIE_Sodium_Core32_Int32 $d
|
||||
* @return array<int, ParagonIE_Sodium_Core32_Int32>
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
protected static function quarterRound(\ParagonIE_Sodium_Core32_Int32 $a, \ParagonIE_Sodium_Core32_Int32 $b, \ParagonIE_Sodium_Core32_Int32 $c, \ParagonIE_Sodium_Core32_Int32 $d)
|
||||
{
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $a */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $b */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $c */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $d */
|
||||
# a = PLUS(a,b); d = ROTATE(XOR(d,a),16);
|
||||
$a = $a->addInt32($b);
|
||||
$d = $d->xorInt32($a)->rotateLeft(16);
|
||||
# c = PLUS(c,d); b = ROTATE(XOR(b,c),12);
|
||||
$c = $c->addInt32($d);
|
||||
$b = $b->xorInt32($c)->rotateLeft(12);
|
||||
# a = PLUS(a,b); d = ROTATE(XOR(d,a), 8);
|
||||
$a = $a->addInt32($b);
|
||||
$d = $d->xorInt32($a)->rotateLeft(8);
|
||||
# c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
|
||||
$c = $c->addInt32($d);
|
||||
$b = $b->xorInt32($c)->rotateLeft(7);
|
||||
return array($a, $b, $c, $d);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_ChaCha20_Ctx $ctx
|
||||
* @param string $message
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encryptBytes(\ParagonIE_Sodium_Core32_ChaCha20_Ctx $ctx, $message = '')
|
||||
{
|
||||
$bytes = self::strlen($message);
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x0 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x1 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x2 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x3 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x4 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x5 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x6 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x7 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x8 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x9 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x10 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x11 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x12 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x13 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x14 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x15 */
|
||||
/*
|
||||
j0 = ctx->input[0];
|
||||
j1 = ctx->input[1];
|
||||
j2 = ctx->input[2];
|
||||
j3 = ctx->input[3];
|
||||
j4 = ctx->input[4];
|
||||
j5 = ctx->input[5];
|
||||
j6 = ctx->input[6];
|
||||
j7 = ctx->input[7];
|
||||
j8 = ctx->input[8];
|
||||
j9 = ctx->input[9];
|
||||
j10 = ctx->input[10];
|
||||
j11 = ctx->input[11];
|
||||
j12 = ctx->input[12];
|
||||
j13 = ctx->input[13];
|
||||
j14 = ctx->input[14];
|
||||
j15 = ctx->input[15];
|
||||
*/
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j0 */
|
||||
$j0 = $ctx[0];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j1 */
|
||||
$j1 = $ctx[1];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j2 */
|
||||
$j2 = $ctx[2];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j3 */
|
||||
$j3 = $ctx[3];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j4 */
|
||||
$j4 = $ctx[4];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j5 */
|
||||
$j5 = $ctx[5];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j6 */
|
||||
$j6 = $ctx[6];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j7 */
|
||||
$j7 = $ctx[7];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j8 */
|
||||
$j8 = $ctx[8];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j9 */
|
||||
$j9 = $ctx[9];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j10 */
|
||||
$j10 = $ctx[10];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j11 */
|
||||
$j11 = $ctx[11];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j12 */
|
||||
$j12 = $ctx[12];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j13 */
|
||||
$j13 = $ctx[13];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j14 */
|
||||
$j14 = $ctx[14];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j15 */
|
||||
$j15 = $ctx[15];
|
||||
$c = '';
|
||||
for (;;) {
|
||||
if ($bytes < 64) {
|
||||
$message .= \str_repeat("\x00", 64 - $bytes);
|
||||
}
|
||||
$x0 = clone $j0;
|
||||
$x1 = clone $j1;
|
||||
$x2 = clone $j2;
|
||||
$x3 = clone $j3;
|
||||
$x4 = clone $j4;
|
||||
$x5 = clone $j5;
|
||||
$x6 = clone $j6;
|
||||
$x7 = clone $j7;
|
||||
$x8 = clone $j8;
|
||||
$x9 = clone $j9;
|
||||
$x10 = clone $j10;
|
||||
$x11 = clone $j11;
|
||||
$x12 = clone $j12;
|
||||
$x13 = clone $j13;
|
||||
$x14 = clone $j14;
|
||||
$x15 = clone $j15;
|
||||
# for (i = 20; i > 0; i -= 2) {
|
||||
for ($i = 20; $i > 0; $i -= 2) {
|
||||
# QUARTERROUND( x0, x4, x8, x12)
|
||||
list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
|
||||
# QUARTERROUND( x1, x5, x9, x13)
|
||||
list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
|
||||
# QUARTERROUND( x2, x6, x10, x14)
|
||||
list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
|
||||
# QUARTERROUND( x3, x7, x11, x15)
|
||||
list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
|
||||
# QUARTERROUND( x0, x5, x10, x15)
|
||||
list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
|
||||
# QUARTERROUND( x1, x6, x11, x12)
|
||||
list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
|
||||
# QUARTERROUND( x2, x7, x8, x13)
|
||||
list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
|
||||
# QUARTERROUND( x3, x4, x9, x14)
|
||||
list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
|
||||
}
|
||||
/*
|
||||
x0 = PLUS(x0, j0);
|
||||
x1 = PLUS(x1, j1);
|
||||
x2 = PLUS(x2, j2);
|
||||
x3 = PLUS(x3, j3);
|
||||
x4 = PLUS(x4, j4);
|
||||
x5 = PLUS(x5, j5);
|
||||
x6 = PLUS(x6, j6);
|
||||
x7 = PLUS(x7, j7);
|
||||
x8 = PLUS(x8, j8);
|
||||
x9 = PLUS(x9, j9);
|
||||
x10 = PLUS(x10, j10);
|
||||
x11 = PLUS(x11, j11);
|
||||
x12 = PLUS(x12, j12);
|
||||
x13 = PLUS(x13, j13);
|
||||
x14 = PLUS(x14, j14);
|
||||
x15 = PLUS(x15, j15);
|
||||
*/
|
||||
$x0 = $x0->addInt32($j0);
|
||||
$x1 = $x1->addInt32($j1);
|
||||
$x2 = $x2->addInt32($j2);
|
||||
$x3 = $x3->addInt32($j3);
|
||||
$x4 = $x4->addInt32($j4);
|
||||
$x5 = $x5->addInt32($j5);
|
||||
$x6 = $x6->addInt32($j6);
|
||||
$x7 = $x7->addInt32($j7);
|
||||
$x8 = $x8->addInt32($j8);
|
||||
$x9 = $x9->addInt32($j9);
|
||||
$x10 = $x10->addInt32($j10);
|
||||
$x11 = $x11->addInt32($j11);
|
||||
$x12 = $x12->addInt32($j12);
|
||||
$x13 = $x13->addInt32($j13);
|
||||
$x14 = $x14->addInt32($j14);
|
||||
$x15 = $x15->addInt32($j15);
|
||||
/*
|
||||
x0 = XOR(x0, LOAD32_LE(m + 0));
|
||||
x1 = XOR(x1, LOAD32_LE(m + 4));
|
||||
x2 = XOR(x2, LOAD32_LE(m + 8));
|
||||
x3 = XOR(x3, LOAD32_LE(m + 12));
|
||||
x4 = XOR(x4, LOAD32_LE(m + 16));
|
||||
x5 = XOR(x5, LOAD32_LE(m + 20));
|
||||
x6 = XOR(x6, LOAD32_LE(m + 24));
|
||||
x7 = XOR(x7, LOAD32_LE(m + 28));
|
||||
x8 = XOR(x8, LOAD32_LE(m + 32));
|
||||
x9 = XOR(x9, LOAD32_LE(m + 36));
|
||||
x10 = XOR(x10, LOAD32_LE(m + 40));
|
||||
x11 = XOR(x11, LOAD32_LE(m + 44));
|
||||
x12 = XOR(x12, LOAD32_LE(m + 48));
|
||||
x13 = XOR(x13, LOAD32_LE(m + 52));
|
||||
x14 = XOR(x14, LOAD32_LE(m + 56));
|
||||
x15 = XOR(x15, LOAD32_LE(m + 60));
|
||||
*/
|
||||
$x0 = $x0->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 0, 4)));
|
||||
$x1 = $x1->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 4, 4)));
|
||||
$x2 = $x2->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 8, 4)));
|
||||
$x3 = $x3->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 12, 4)));
|
||||
$x4 = $x4->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 16, 4)));
|
||||
$x5 = $x5->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 20, 4)));
|
||||
$x6 = $x6->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 24, 4)));
|
||||
$x7 = $x7->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 28, 4)));
|
||||
$x8 = $x8->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 32, 4)));
|
||||
$x9 = $x9->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 36, 4)));
|
||||
$x10 = $x10->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 40, 4)));
|
||||
$x11 = $x11->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 44, 4)));
|
||||
$x12 = $x12->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 48, 4)));
|
||||
$x13 = $x13->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 52, 4)));
|
||||
$x14 = $x14->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 56, 4)));
|
||||
$x15 = $x15->xorInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 60, 4)));
|
||||
/*
|
||||
j12 = PLUSONE(j12);
|
||||
if (!j12) {
|
||||
j13 = PLUSONE(j13);
|
||||
}
|
||||
*/
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j12 */
|
||||
$j12 = $j12->addInt(1);
|
||||
if ($j12->limbs[0] === 0 && $j12->limbs[1] === 0) {
|
||||
$j13 = $j13->addInt(1);
|
||||
}
|
||||
/*
|
||||
STORE32_LE(c + 0, x0);
|
||||
STORE32_LE(c + 4, x1);
|
||||
STORE32_LE(c + 8, x2);
|
||||
STORE32_LE(c + 12, x3);
|
||||
STORE32_LE(c + 16, x4);
|
||||
STORE32_LE(c + 20, x5);
|
||||
STORE32_LE(c + 24, x6);
|
||||
STORE32_LE(c + 28, x7);
|
||||
STORE32_LE(c + 32, x8);
|
||||
STORE32_LE(c + 36, x9);
|
||||
STORE32_LE(c + 40, x10);
|
||||
STORE32_LE(c + 44, x11);
|
||||
STORE32_LE(c + 48, x12);
|
||||
STORE32_LE(c + 52, x13);
|
||||
STORE32_LE(c + 56, x14);
|
||||
STORE32_LE(c + 60, x15);
|
||||
*/
|
||||
$block = $x0->toReverseString() . $x1->toReverseString() . $x2->toReverseString() . $x3->toReverseString() . $x4->toReverseString() . $x5->toReverseString() . $x6->toReverseString() . $x7->toReverseString() . $x8->toReverseString() . $x9->toReverseString() . $x10->toReverseString() . $x11->toReverseString() . $x12->toReverseString() . $x13->toReverseString() . $x14->toReverseString() . $x15->toReverseString();
|
||||
/* Partial block */
|
||||
if ($bytes < 64) {
|
||||
$c .= self::substr($block, 0, $bytes);
|
||||
break;
|
||||
}
|
||||
/* Full block */
|
||||
$c .= $block;
|
||||
$bytes -= 64;
|
||||
if ($bytes <= 0) {
|
||||
break;
|
||||
}
|
||||
$message = self::substr($message, 64);
|
||||
protected static function quarterRound(
|
||||
ParagonIE_Sodium_Core32_Int32 $a,
|
||||
ParagonIE_Sodium_Core32_Int32 $b,
|
||||
ParagonIE_Sodium_Core32_Int32 $c,
|
||||
ParagonIE_Sodium_Core32_Int32 $d
|
||||
) {
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $a */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $b */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $c */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $d */
|
||||
|
||||
# a = PLUS(a,b); d = ROTATE(XOR(d,a),16);
|
||||
$a = $a->addInt32($b);
|
||||
$d = $d->xorInt32($a)->rotateLeft(16);
|
||||
|
||||
# c = PLUS(c,d); b = ROTATE(XOR(b,c),12);
|
||||
$c = $c->addInt32($d);
|
||||
$b = $b->xorInt32($c)->rotateLeft(12);
|
||||
|
||||
# a = PLUS(a,b); d = ROTATE(XOR(d,a), 8);
|
||||
$a = $a->addInt32($b);
|
||||
$d = $d->xorInt32($a)->rotateLeft(8);
|
||||
|
||||
# c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
|
||||
$c = $c->addInt32($d);
|
||||
$b = $b->xorInt32($c)->rotateLeft(7);
|
||||
|
||||
return array($a, $b, $c, $d);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_ChaCha20_Ctx $ctx
|
||||
* @param string $message
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encryptBytes(
|
||||
ParagonIE_Sodium_Core32_ChaCha20_Ctx $ctx,
|
||||
$message = ''
|
||||
) {
|
||||
$bytes = self::strlen($message);
|
||||
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x0 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x1 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x2 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x3 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x4 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x5 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x6 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x7 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x8 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x9 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x10 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x11 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x12 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x13 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x14 */
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x15 */
|
||||
|
||||
/*
|
||||
j0 = ctx->input[0];
|
||||
j1 = ctx->input[1];
|
||||
j2 = ctx->input[2];
|
||||
j3 = ctx->input[3];
|
||||
j4 = ctx->input[4];
|
||||
j5 = ctx->input[5];
|
||||
j6 = ctx->input[6];
|
||||
j7 = ctx->input[7];
|
||||
j8 = ctx->input[8];
|
||||
j9 = ctx->input[9];
|
||||
j10 = ctx->input[10];
|
||||
j11 = ctx->input[11];
|
||||
j12 = ctx->input[12];
|
||||
j13 = ctx->input[13];
|
||||
j14 = ctx->input[14];
|
||||
j15 = ctx->input[15];
|
||||
*/
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j0 */
|
||||
$j0 = $ctx[0];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j1 */
|
||||
$j1 = $ctx[1];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j2 */
|
||||
$j2 = $ctx[2];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j3 */
|
||||
$j3 = $ctx[3];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j4 */
|
||||
$j4 = $ctx[4];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j5 */
|
||||
$j5 = $ctx[5];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j6 */
|
||||
$j6 = $ctx[6];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j7 */
|
||||
$j7 = $ctx[7];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j8 */
|
||||
$j8 = $ctx[8];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j9 */
|
||||
$j9 = $ctx[9];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j10 */
|
||||
$j10 = $ctx[10];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j11 */
|
||||
$j11 = $ctx[11];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j12 */
|
||||
$j12 = $ctx[12];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j13 */
|
||||
$j13 = $ctx[13];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j14 */
|
||||
$j14 = $ctx[14];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j15 */
|
||||
$j15 = $ctx[15];
|
||||
|
||||
$c = '';
|
||||
for (;;) {
|
||||
if ($bytes < 64) {
|
||||
$message .= str_repeat("\x00", 64 - $bytes);
|
||||
}
|
||||
/* end for(;;) loop */
|
||||
$ctx[12] = $j12;
|
||||
$ctx[13] = $j13;
|
||||
return $c;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function stream($len = 64, $nonce = '', $key = '')
|
||||
{
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core32_ChaCha20_Ctx($key, $nonce), \str_repeat("\x00", $len));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStream($len, $nonce = '', $key = '')
|
||||
{
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core32_ChaCha20_IetfCtx($key, $nonce), \str_repeat("\x00", $len));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core32_ChaCha20_IetfCtx($key, $nonce, $ic), $message);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core32_ChaCha20_Ctx($key, $nonce, $ic), $message);
|
||||
|
||||
$x0 = clone $j0;
|
||||
$x1 = clone $j1;
|
||||
$x2 = clone $j2;
|
||||
$x3 = clone $j3;
|
||||
$x4 = clone $j4;
|
||||
$x5 = clone $j5;
|
||||
$x6 = clone $j6;
|
||||
$x7 = clone $j7;
|
||||
$x8 = clone $j8;
|
||||
$x9 = clone $j9;
|
||||
$x10 = clone $j10;
|
||||
$x11 = clone $j11;
|
||||
$x12 = clone $j12;
|
||||
$x13 = clone $j13;
|
||||
$x14 = clone $j14;
|
||||
$x15 = clone $j15;
|
||||
|
||||
# for (i = 20; i > 0; i -= 2) {
|
||||
for ($i = 20; $i > 0; $i -= 2) {
|
||||
# QUARTERROUND( x0, x4, x8, x12)
|
||||
list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
|
||||
|
||||
# QUARTERROUND( x1, x5, x9, x13)
|
||||
list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
|
||||
|
||||
# QUARTERROUND( x2, x6, x10, x14)
|
||||
list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
|
||||
|
||||
# QUARTERROUND( x3, x7, x11, x15)
|
||||
list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
|
||||
|
||||
# QUARTERROUND( x0, x5, x10, x15)
|
||||
list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
|
||||
|
||||
# QUARTERROUND( x1, x6, x11, x12)
|
||||
list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
|
||||
|
||||
# QUARTERROUND( x2, x7, x8, x13)
|
||||
list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
|
||||
|
||||
# QUARTERROUND( x3, x4, x9, x14)
|
||||
list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
|
||||
}
|
||||
/*
|
||||
x0 = PLUS(x0, j0);
|
||||
x1 = PLUS(x1, j1);
|
||||
x2 = PLUS(x2, j2);
|
||||
x3 = PLUS(x3, j3);
|
||||
x4 = PLUS(x4, j4);
|
||||
x5 = PLUS(x5, j5);
|
||||
x6 = PLUS(x6, j6);
|
||||
x7 = PLUS(x7, j7);
|
||||
x8 = PLUS(x8, j8);
|
||||
x9 = PLUS(x9, j9);
|
||||
x10 = PLUS(x10, j10);
|
||||
x11 = PLUS(x11, j11);
|
||||
x12 = PLUS(x12, j12);
|
||||
x13 = PLUS(x13, j13);
|
||||
x14 = PLUS(x14, j14);
|
||||
x15 = PLUS(x15, j15);
|
||||
*/
|
||||
$x0 = $x0->addInt32($j0);
|
||||
$x1 = $x1->addInt32($j1);
|
||||
$x2 = $x2->addInt32($j2);
|
||||
$x3 = $x3->addInt32($j3);
|
||||
$x4 = $x4->addInt32($j4);
|
||||
$x5 = $x5->addInt32($j5);
|
||||
$x6 = $x6->addInt32($j6);
|
||||
$x7 = $x7->addInt32($j7);
|
||||
$x8 = $x8->addInt32($j8);
|
||||
$x9 = $x9->addInt32($j9);
|
||||
$x10 = $x10->addInt32($j10);
|
||||
$x11 = $x11->addInt32($j11);
|
||||
$x12 = $x12->addInt32($j12);
|
||||
$x13 = $x13->addInt32($j13);
|
||||
$x14 = $x14->addInt32($j14);
|
||||
$x15 = $x15->addInt32($j15);
|
||||
|
||||
/*
|
||||
x0 = XOR(x0, LOAD32_LE(m + 0));
|
||||
x1 = XOR(x1, LOAD32_LE(m + 4));
|
||||
x2 = XOR(x2, LOAD32_LE(m + 8));
|
||||
x3 = XOR(x3, LOAD32_LE(m + 12));
|
||||
x4 = XOR(x4, LOAD32_LE(m + 16));
|
||||
x5 = XOR(x5, LOAD32_LE(m + 20));
|
||||
x6 = XOR(x6, LOAD32_LE(m + 24));
|
||||
x7 = XOR(x7, LOAD32_LE(m + 28));
|
||||
x8 = XOR(x8, LOAD32_LE(m + 32));
|
||||
x9 = XOR(x9, LOAD32_LE(m + 36));
|
||||
x10 = XOR(x10, LOAD32_LE(m + 40));
|
||||
x11 = XOR(x11, LOAD32_LE(m + 44));
|
||||
x12 = XOR(x12, LOAD32_LE(m + 48));
|
||||
x13 = XOR(x13, LOAD32_LE(m + 52));
|
||||
x14 = XOR(x14, LOAD32_LE(m + 56));
|
||||
x15 = XOR(x15, LOAD32_LE(m + 60));
|
||||
*/
|
||||
$x0 = $x0->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 0, 4)));
|
||||
$x1 = $x1->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 4, 4)));
|
||||
$x2 = $x2->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 8, 4)));
|
||||
$x3 = $x3->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 12, 4)));
|
||||
$x4 = $x4->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 16, 4)));
|
||||
$x5 = $x5->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 20, 4)));
|
||||
$x6 = $x6->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 24, 4)));
|
||||
$x7 = $x7->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 28, 4)));
|
||||
$x8 = $x8->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 32, 4)));
|
||||
$x9 = $x9->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 36, 4)));
|
||||
$x10 = $x10->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 40, 4)));
|
||||
$x11 = $x11->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 44, 4)));
|
||||
$x12 = $x12->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 48, 4)));
|
||||
$x13 = $x13->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 52, 4)));
|
||||
$x14 = $x14->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 56, 4)));
|
||||
$x15 = $x15->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 60, 4)));
|
||||
|
||||
/*
|
||||
j12 = PLUSONE(j12);
|
||||
if (!j12) {
|
||||
j13 = PLUSONE(j13);
|
||||
}
|
||||
*/
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $j12 */
|
||||
$j12 = $j12->addInt(1);
|
||||
if ($j12->limbs[0] === 0 && $j12->limbs[1] === 0) {
|
||||
$j13 = $j13->addInt(1);
|
||||
}
|
||||
|
||||
/*
|
||||
STORE32_LE(c + 0, x0);
|
||||
STORE32_LE(c + 4, x1);
|
||||
STORE32_LE(c + 8, x2);
|
||||
STORE32_LE(c + 12, x3);
|
||||
STORE32_LE(c + 16, x4);
|
||||
STORE32_LE(c + 20, x5);
|
||||
STORE32_LE(c + 24, x6);
|
||||
STORE32_LE(c + 28, x7);
|
||||
STORE32_LE(c + 32, x8);
|
||||
STORE32_LE(c + 36, x9);
|
||||
STORE32_LE(c + 40, x10);
|
||||
STORE32_LE(c + 44, x11);
|
||||
STORE32_LE(c + 48, x12);
|
||||
STORE32_LE(c + 52, x13);
|
||||
STORE32_LE(c + 56, x14);
|
||||
STORE32_LE(c + 60, x15);
|
||||
*/
|
||||
|
||||
$block = $x0->toReverseString() .
|
||||
$x1->toReverseString() .
|
||||
$x2->toReverseString() .
|
||||
$x3->toReverseString() .
|
||||
$x4->toReverseString() .
|
||||
$x5->toReverseString() .
|
||||
$x6->toReverseString() .
|
||||
$x7->toReverseString() .
|
||||
$x8->toReverseString() .
|
||||
$x9->toReverseString() .
|
||||
$x10->toReverseString() .
|
||||
$x11->toReverseString() .
|
||||
$x12->toReverseString() .
|
||||
$x13->toReverseString() .
|
||||
$x14->toReverseString() .
|
||||
$x15->toReverseString();
|
||||
|
||||
/* Partial block */
|
||||
if ($bytes < 64) {
|
||||
$c .= self::substr($block, 0, $bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Full block */
|
||||
$c .= $block;
|
||||
$bytes -= 64;
|
||||
if ($bytes <= 0) {
|
||||
break;
|
||||
}
|
||||
$message = self::substr($message, 64);
|
||||
}
|
||||
/* end for(;;) loop */
|
||||
|
||||
$ctx[12] = $j12;
|
||||
$ctx[13] = $j13;
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_ChaCha20
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function stream($len = 64, $nonce = '', $key = '')
|
||||
{
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core32_ChaCha20_Ctx($key, $nonce),
|
||||
str_repeat("\x00", $len)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStream($len, $nonce = '', $key = '')
|
||||
{
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core32_ChaCha20_IetfCtx($key, $nonce),
|
||||
str_repeat("\x00", $len)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core32_ChaCha20_IetfCtx($key, $nonce, $ic),
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core32_ChaCha20_Ctx($key, $nonce, $ic),
|
||||
$message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,124 +1,130 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_ChaCha20_Ctx', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_ChaCha20_Ctx', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_ChaCha20_Ctx
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_ChaCha20_Ctx extends ParagonIE_Sodium_Core32_Util implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_ChaCha20_Ctx
|
||||
* @var SplFixedArray internally, <int, ParagonIE_Sodium_Core32_Int32>
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_ChaCha20_Ctx extends \ParagonIE_Sodium_Core32_Util implements \ArrayAccess
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_ChaCha20_Ctx constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key ChaCha20 key.
|
||||
* @param string $iv Initialization Vector (a.k.a. nonce).
|
||||
* @param string $counter The initial counter value.
|
||||
* Defaults to 8 0x00 bytes.
|
||||
* @throws InvalidArgumentException
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '', $iv = '', $counter = '')
|
||||
{
|
||||
/**
|
||||
* @var SplFixedArray internally, <int, ParagonIE_Sodium_Core32_Int32>
|
||||
*/
|
||||
protected $container;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_ChaCha20_Ctx constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key ChaCha20 key.
|
||||
* @param string $iv Initialization Vector (a.k.a. nonce).
|
||||
* @param string $counter The initial counter value.
|
||||
* Defaults to 8 0x00 bytes.
|
||||
* @throws InvalidArgumentException
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '', $iv = '', $counter = '')
|
||||
{
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new \InvalidArgumentException('ChaCha20 expects a 256-bit key.');
|
||||
}
|
||||
if (self::strlen($iv) !== 8) {
|
||||
throw new \InvalidArgumentException('ChaCha20 expects a 64-bit nonce.');
|
||||
}
|
||||
$this->container = new \SplFixedArray(16);
|
||||
/* "expand 32-byte k" as per ChaCha20 spec */
|
||||
$this->container[0] = new \ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865));
|
||||
$this->container[1] = new \ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e));
|
||||
$this->container[2] = new \ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32));
|
||||
$this->container[3] = new \ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574));
|
||||
$this->container[4] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4));
|
||||
$this->container[5] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 4, 4));
|
||||
$this->container[6] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 8, 4));
|
||||
$this->container[7] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4));
|
||||
$this->container[8] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4));
|
||||
$this->container[9] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4));
|
||||
$this->container[10] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4));
|
||||
$this->container[11] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4));
|
||||
if (empty($counter)) {
|
||||
$this->container[12] = new \ParagonIE_Sodium_Core32_Int32();
|
||||
$this->container[13] = new \ParagonIE_Sodium_Core32_Int32();
|
||||
} else {
|
||||
$this->container[12] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($counter, 0, 4));
|
||||
$this->container[13] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($counter, 4, 4));
|
||||
}
|
||||
$this->container[14] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 0, 4));
|
||||
$this->container[15] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 4, 4));
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new InvalidArgumentException('ChaCha20 expects a 256-bit key.');
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int|ParagonIE_Sodium_Core32_Int32 $value
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!\is_int($offset)) {
|
||||
throw new \InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
if ($value instanceof \ParagonIE_Sodium_Core32_Int32) {
|
||||
/*
|
||||
} elseif (is_int($value)) {
|
||||
$value = ParagonIE_Sodium_Core32_Int32::fromInt($value);
|
||||
*/
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
$this->container[$offset] = $value;
|
||||
if (self::strlen($iv) !== 8) {
|
||||
throw new InvalidArgumentException('ChaCha20 expects a 64-bit nonce.');
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->container[$offset]);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->container[$offset]);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return mixed|null
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->container[$offset]) ? $this->container[$offset] : null;
|
||||
$this->container = new SplFixedArray(16);
|
||||
|
||||
/* "expand 32-byte k" as per ChaCha20 spec */
|
||||
$this->container[0] = new ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865));
|
||||
$this->container[1] = new ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e));
|
||||
$this->container[2] = new ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32));
|
||||
$this->container[3] = new ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574));
|
||||
|
||||
$this->container[4] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4));
|
||||
$this->container[5] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 4, 4));
|
||||
$this->container[6] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 8, 4));
|
||||
$this->container[7] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4));
|
||||
$this->container[8] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4));
|
||||
$this->container[9] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4));
|
||||
$this->container[10] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4));
|
||||
$this->container[11] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4));
|
||||
|
||||
if (empty($counter)) {
|
||||
$this->container[12] = new ParagonIE_Sodium_Core32_Int32();
|
||||
$this->container[13] = new ParagonIE_Sodium_Core32_Int32();
|
||||
} else {
|
||||
$this->container[12] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($counter, 0, 4));
|
||||
$this->container[13] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($counter, 4, 4));
|
||||
}
|
||||
$this->container[14] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 0, 4));
|
||||
$this->container[15] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 4, 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_ChaCha20_Ctx
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int|ParagonIE_Sodium_Core32_Int32 $value
|
||||
* @return void
|
||||
*/
|
||||
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!is_int($offset)) {
|
||||
throw new InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
if ($value instanceof ParagonIE_Sodium_Core32_Int32) {
|
||||
/*
|
||||
} elseif (is_int($value)) {
|
||||
$value = ParagonIE_Sodium_Core32_Int32::fromInt($value);
|
||||
*/
|
||||
} else {
|
||||
throw new InvalidArgumentException('Expected an integer');
|
||||
}
|
||||
$this->container[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->container[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->container[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $offset
|
||||
* @return mixed|null
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->container[$offset])
|
||||
? $this->container[$offset]
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +1,39 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core_ChaCha20_IetfCtx', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core_ChaCha20_IetfCtx', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_ChaCha20_IetfCtx
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_ChaCha20_IetfCtx extends ParagonIE_Sodium_Core32_ChaCha20_Ctx
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_ChaCha20_IetfCtx
|
||||
* ParagonIE_Sodium_Core_ChaCha20_IetfCtx constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key ChaCha20 key.
|
||||
* @param string $iv Initialization Vector (a.k.a. nonce).
|
||||
* @param string $counter The initial counter value.
|
||||
* Defaults to 4 0x00 bytes.
|
||||
* @throws InvalidArgumentException
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_ChaCha20_IetfCtx extends \ParagonIE_Sodium_Core32_ChaCha20_Ctx
|
||||
public function __construct($key = '', $iv = '', $counter = '')
|
||||
{
|
||||
/**
|
||||
* ParagonIE_Sodium_Core_ChaCha20_IetfCtx constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key ChaCha20 key.
|
||||
* @param string $iv Initialization Vector (a.k.a. nonce).
|
||||
* @param string $counter The initial counter value.
|
||||
* Defaults to 4 0x00 bytes.
|
||||
* @throws InvalidArgumentException
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '', $iv = '', $counter = '')
|
||||
{
|
||||
if (self::strlen($iv) !== 12) {
|
||||
throw new \InvalidArgumentException('ChaCha20 expects a 96-bit nonce in IETF mode.');
|
||||
}
|
||||
parent::__construct($key, self::substr($iv, 0, 8), $counter);
|
||||
if (!empty($counter)) {
|
||||
$this->container[12] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($counter, 0, 4));
|
||||
}
|
||||
$this->container[13] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 0, 4));
|
||||
$this->container[14] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 4, 4));
|
||||
$this->container[15] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 8, 4));
|
||||
if (self::strlen($iv) !== 12) {
|
||||
throw new InvalidArgumentException('ChaCha20 expects a 96-bit nonce in IETF mode.');
|
||||
}
|
||||
parent::__construct($key, self::substr($iv, 0, 8), $counter);
|
||||
|
||||
if (!empty($counter)) {
|
||||
$this->container[12] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($counter, 0, 4));
|
||||
}
|
||||
$this->container[13] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 0, 4));
|
||||
$this->container[14] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 4, 4));
|
||||
$this->container[15] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 8, 4));
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_ChaCha20_IetfCtx
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,177 +1,192 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Fe', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Curve25519_Fe', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*
|
||||
* This represents a Field Element
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Fe implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*
|
||||
* This represents a Field Element
|
||||
* @var array<int, ParagonIE_Sodium_Core32_Int32>
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Fe implements \ArrayAccess
|
||||
protected $container = array();
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $size = 10;
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param array<int, ParagonIE_Sodium_Core32_Int32> $array
|
||||
* @param bool $save_indexes
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function fromArray($array, $save_indexes = null)
|
||||
{
|
||||
/**
|
||||
* @var array<int, ParagonIE_Sodium_Core32_Int32>
|
||||
*/
|
||||
protected $container = array();
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $size = 10;
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param array<int, ParagonIE_Sodium_Core32_Int32> $array
|
||||
* @param bool $save_indexes
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function fromArray($array, $save_indexes = null)
|
||||
{
|
||||
$count = \count($array);
|
||||
if ($save_indexes) {
|
||||
$keys = \array_keys($array);
|
||||
} else {
|
||||
$keys = \range(0, $count - 1);
|
||||
$count = count($array);
|
||||
if ($save_indexes) {
|
||||
$keys = array_keys($array);
|
||||
} else {
|
||||
$keys = range(0, $count - 1);
|
||||
}
|
||||
$array = array_values($array);
|
||||
|
||||
$obj = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
if ($save_indexes) {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$array[$i]->overflow = 0;
|
||||
$obj->offsetSet($keys[$i], $array[$i]);
|
||||
}
|
||||
$array = \array_values($array);
|
||||
$obj = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
if ($save_indexes) {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$array[$i]->overflow = 0;
|
||||
$obj->offsetSet($keys[$i], $array[$i]);
|
||||
} else {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
if (!($array[$i] instanceof ParagonIE_Sodium_Core32_Int32)) {
|
||||
throw new TypeError('Expected ParagonIE_Sodium_Core32_Int32');
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
if (!$array[$i] instanceof \ParagonIE_Sodium_Core32_Int32) {
|
||||
throw new \TypeError('Expected ParagonIE_Sodium_Core32_Int32');
|
||||
}
|
||||
$array[$i]->overflow = 0;
|
||||
$obj->offsetSet($i, $array[$i]);
|
||||
}
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param array<int, int> $array
|
||||
* @param bool $save_indexes
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function fromIntArray($array, $save_indexes = null)
|
||||
{
|
||||
$count = \count($array);
|
||||
if ($save_indexes) {
|
||||
$keys = \array_keys($array);
|
||||
} else {
|
||||
$keys = \range(0, $count - 1);
|
||||
}
|
||||
$array = \array_values($array);
|
||||
$set = array();
|
||||
/** @var int $i */
|
||||
/** @var int $v */
|
||||
foreach ($array as $i => $v) {
|
||||
$set[$i] = \ParagonIE_Sodium_Core32_Int32::fromInt($v);
|
||||
}
|
||||
$obj = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
if ($save_indexes) {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$set[$i]->overflow = 0;
|
||||
$obj->offsetSet($keys[$i], $set[$i]);
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$set[$i]->overflow = 0;
|
||||
$obj->offsetSet($i, $set[$i]);
|
||||
}
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!$value instanceof \ParagonIE_Sodium_Core32_Int32) {
|
||||
throw new \InvalidArgumentException('Expected an instance of ParagonIE_Sodium_Core32_Int32');
|
||||
}
|
||||
if (\is_null($offset)) {
|
||||
$this->container[] = $value;
|
||||
} else {
|
||||
\ParagonIE_Sodium_Core32_Util::declareScalarType($offset, 'int', 1);
|
||||
$this->container[(int) $offset] = $value;
|
||||
$array[$i]->overflow = 0;
|
||||
$obj->offsetSet($i, $array[$i]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->container[$offset]);
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param array<int, int> $array
|
||||
* @param bool $save_indexes
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function fromIntArray($array, $save_indexes = null)
|
||||
{
|
||||
$count = count($array);
|
||||
if ($save_indexes) {
|
||||
$keys = array_keys($array);
|
||||
} else {
|
||||
$keys = range(0, $count - 1);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->container[$offset]);
|
||||
$array = array_values($array);
|
||||
$set = array();
|
||||
/** @var int $i */
|
||||
/** @var int $v */
|
||||
foreach ($array as $i => $v) {
|
||||
$set[$i] = ParagonIE_Sodium_Core32_Int32::fromInt($v);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return ParagonIE_Sodium_Core32_Int32
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (!isset($this->container[$offset])) {
|
||||
$this->container[(int) $offset] = new \ParagonIE_Sodium_Core32_Int32();
|
||||
|
||||
$obj = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
if ($save_indexes) {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$set[$i]->overflow = 0;
|
||||
$obj->offsetSet($keys[$i], $set[$i]);
|
||||
}
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $get */
|
||||
$get = $this->container[$offset];
|
||||
return $get;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo()
|
||||
{
|
||||
if (empty($this->container)) {
|
||||
return array();
|
||||
} else {
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$set[$i]->overflow = 0;
|
||||
$obj->offsetSet($i, $set[$i]);
|
||||
}
|
||||
$c = array((int) $this->container[0]->toInt(), (int) $this->container[1]->toInt(), (int) $this->container[2]->toInt(), (int) $this->container[3]->toInt(), (int) $this->container[4]->toInt(), (int) $this->container[5]->toInt(), (int) $this->container[6]->toInt(), (int) $this->container[7]->toInt(), (int) $this->container[8]->toInt(), (int) $this->container[9]->toInt());
|
||||
return array(\implode(', ', $c));
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!($value instanceof ParagonIE_Sodium_Core32_Int32)) {
|
||||
throw new InvalidArgumentException('Expected an instance of ParagonIE_Sodium_Core32_Int32');
|
||||
}
|
||||
if (is_null($offset)) {
|
||||
$this->container[] = $value;
|
||||
} else {
|
||||
ParagonIE_Sodium_Core32_Util::declareScalarType($offset, 'int', 1);
|
||||
$this->container[(int) $offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* This represents a Field Element
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->container[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return void
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->container[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param mixed $offset
|
||||
* @return ParagonIE_Sodium_Core32_Int32
|
||||
* @psalm-suppress MixedArrayOffset
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (!isset($this->container[$offset])) {
|
||||
$this->container[(int) $offset] = new ParagonIE_Sodium_Core32_Int32();
|
||||
}
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $get */
|
||||
$get = $this->container[$offset];
|
||||
return $get;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo()
|
||||
{
|
||||
if (empty($this->container)) {
|
||||
return array();
|
||||
}
|
||||
$c = array(
|
||||
(int) ($this->container[0]->toInt()),
|
||||
(int) ($this->container[1]->toInt()),
|
||||
(int) ($this->container[2]->toInt()),
|
||||
(int) ($this->container[3]->toInt()),
|
||||
(int) ($this->container[4]->toInt()),
|
||||
(int) ($this->container[5]->toInt()),
|
||||
(int) ($this->container[6]->toInt()),
|
||||
(int) ($this->container[7]->toInt()),
|
||||
(int) ($this->container[8]->toInt()),
|
||||
(int) ($this->container[9]->toInt())
|
||||
);
|
||||
return array(implode(', ', $c));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +1,65 @@
|
||||
<?php
|
||||
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_Cached', \false)) {
|
||||
return;
|
||||
}
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_Cached', false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_Cached
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_Cached
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_Cached
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_Cached
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $YplusX;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $YminusX;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $T2d;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_Cached constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $YplusX
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $YminusX
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $Z
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $T2d
|
||||
*/
|
||||
public function __construct(\ParagonIE_Sodium_Core32_Curve25519_Fe $YplusX = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $YminusX = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $Z = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $T2d = null)
|
||||
{
|
||||
if ($YplusX === null) {
|
||||
$YplusX = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->YplusX = $YplusX;
|
||||
if ($YminusX === null) {
|
||||
$YminusX = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->YminusX = $YminusX;
|
||||
if ($Z === null) {
|
||||
$Z = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Z = $Z;
|
||||
if ($T2d === null) {
|
||||
$T2d = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->T2d = $T2d;
|
||||
public $YplusX;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $YminusX;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $T2d;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_Cached constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $YplusX
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $YminusX
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $Z
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $T2d
|
||||
*/
|
||||
public function __construct(
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $YplusX = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $YminusX = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $Z = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $T2d = null
|
||||
) {
|
||||
if ($YplusX === null) {
|
||||
$YplusX = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->YplusX = $YplusX;
|
||||
if ($YminusX === null) {
|
||||
$YminusX = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->YminusX = $YminusX;
|
||||
if ($Z === null) {
|
||||
$Z = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Z = $Z;
|
||||
if ($T2d === null) {
|
||||
$T2d = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->T2d = $T2d;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_Cached
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,64 +1,67 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1', false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $X;
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $X;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $T;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $z
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $t
|
||||
*
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct(\ParagonIE_Sodium_Core32_Curve25519_Fe $x = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $y = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $z = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $t = null)
|
||||
{
|
||||
if ($x === null) {
|
||||
$x = \ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->X = $x;
|
||||
if ($y === null) {
|
||||
$y = \ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->Y = $y;
|
||||
if ($z === null) {
|
||||
$z = \ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->Z = $z;
|
||||
if ($t === null) {
|
||||
$t = \ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->T = $t;
|
||||
public $Y;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $T;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $z
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $t
|
||||
*
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct(
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $x = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $y = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $z = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $t = null
|
||||
) {
|
||||
if ($x === null) {
|
||||
$x = ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->X = $x;
|
||||
if ($y === null) {
|
||||
$y = ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->Y = $y;
|
||||
if ($z === null) {
|
||||
$z = ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->Z = $z;
|
||||
if ($t === null) {
|
||||
$t = ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->T = $t;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,52 +1,54 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_P2', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_P2', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_P2
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_P2
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_P2
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_P2
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $X;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_P2 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $z
|
||||
*/
|
||||
public function __construct(\ParagonIE_Sodium_Core32_Curve25519_Fe $x = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $y = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $z = null)
|
||||
{
|
||||
if ($x === null) {
|
||||
$x = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->X = $x;
|
||||
if ($y === null) {
|
||||
$y = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Y = $y;
|
||||
if ($z === null) {
|
||||
$z = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Z = $z;
|
||||
public $X;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_P2 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $z
|
||||
*/
|
||||
public function __construct(
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $x = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $y = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $z = null
|
||||
) {
|
||||
if ($x === null) {
|
||||
$x = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->X = $x;
|
||||
if ($y === null) {
|
||||
$y = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Y = $y;
|
||||
if ($z === null) {
|
||||
$z = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Z = $z;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_P2
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,61 +1,65 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_P3', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_P3', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_P3
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_P3
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_P3
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_P3
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $X;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $T;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_P3 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $z
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $t
|
||||
*/
|
||||
public function __construct(\ParagonIE_Sodium_Core32_Curve25519_Fe $x = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $y = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $z = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $t = null)
|
||||
{
|
||||
if ($x === null) {
|
||||
$x = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->X = $x;
|
||||
if ($y === null) {
|
||||
$y = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Y = $y;
|
||||
if ($z === null) {
|
||||
$z = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Z = $z;
|
||||
if ($t === null) {
|
||||
$t = new \ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->T = $t;
|
||||
public $X;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Y;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $Z;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $T;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_P3 constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $x
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $y
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $z
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $t
|
||||
*/
|
||||
public function __construct(
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $x = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $y = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $z = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $t = null
|
||||
) {
|
||||
if ($x === null) {
|
||||
$x = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->X = $x;
|
||||
if ($y === null) {
|
||||
$y = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Y = $y;
|
||||
if ($z === null) {
|
||||
$z = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->Z = $z;
|
||||
if ($t === null) {
|
||||
$t = new ParagonIE_Sodium_Core32_Curve25519_Fe();
|
||||
}
|
||||
$this->T = $t;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_P3
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -1,54 +1,56 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $yplusx;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $yminusx;
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $xy2d;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $yplusx
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $yminusx
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $xy2d
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct(\ParagonIE_Sodium_Core32_Curve25519_Fe $yplusx = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $yminusx = null, \ParagonIE_Sodium_Core32_Curve25519_Fe $xy2d = null)
|
||||
{
|
||||
if ($yplusx === null) {
|
||||
$yplusx = \ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->yplusx = $yplusx;
|
||||
if ($yminusx === null) {
|
||||
$yminusx = \ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->yminusx = $yminusx;
|
||||
if ($xy2d === null) {
|
||||
$xy2d = \ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->xy2d = $xy2d;
|
||||
public $yplusx;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $yminusx;
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
*/
|
||||
public $xy2d;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $yplusx
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $yminusx
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $xy2d
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct(
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $yplusx = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $yminusx = null,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $xy2d = null
|
||||
) {
|
||||
if ($yplusx === null) {
|
||||
$yplusx = ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->yplusx = $yplusx;
|
||||
if ($yminusx === null) {
|
||||
$yminusx = ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->yminusx = $yminusx;
|
||||
if ($xy2d === null) {
|
||||
$xy2d = ParagonIE_Sodium_Core32_Curve25519::fe_0();
|
||||
}
|
||||
$this->xy2d = $xy2d;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,353 +1,485 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Ed25519', false)) {
|
||||
return;
|
||||
}
|
||||
if (!class_exists('ParagonIE_Sodium_Core32_Curve25519')) {
|
||||
require_once dirname(__FILE__) . '/Curve25519.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Ed25519
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_Ed25519 extends ParagonIE_Sodium_Core32_Curve25519
|
||||
{
|
||||
const KEYPAIR_BYTES = 96;
|
||||
const SEED_BYTES = 32;
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Ed25519', \false)) {
|
||||
return;
|
||||
}
|
||||
if (!\class_exists('ParagonIE_Sodium_Core32_Curve25519')) {
|
||||
require_once \dirname(__FILE__) . '/Curve25519.php';
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Ed25519
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return string (96 bytes)
|
||||
* @throws Exception
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_Ed25519 extends \ParagonIE_Sodium_Core32_Curve25519
|
||||
public static function keypair()
|
||||
{
|
||||
const KEYPAIR_BYTES = 96;
|
||||
const SEED_BYTES = 32;
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return string (96 bytes)
|
||||
* @throws Exception
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function keypair()
|
||||
{
|
||||
$seed = \random_bytes(self::SEED_BYTES);
|
||||
$pk = '';
|
||||
$sk = '';
|
||||
self::seed_keypair($pk, $sk, $seed);
|
||||
return $sk . $pk;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $pk
|
||||
* @param string $sk
|
||||
* @param string $seed
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function seed_keypair(&$pk, &$sk, $seed)
|
||||
{
|
||||
if (self::strlen($seed) !== self::SEED_BYTES) {
|
||||
throw new \RangeException('crypto_sign keypair seed must be 32 bytes long');
|
||||
}
|
||||
/** @var string $pk */
|
||||
$pk = self::publickey_from_secretkey($seed);
|
||||
$sk = $seed . $pk;
|
||||
return $sk;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $keypair
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function secretkey($keypair)
|
||||
{
|
||||
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
|
||||
throw new \RangeException('crypto_sign keypair must be 96 bytes long');
|
||||
}
|
||||
return self::substr($keypair, 0, 64);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $keypair
|
||||
* @return string
|
||||
* @throws RangeException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function publickey($keypair)
|
||||
{
|
||||
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
|
||||
throw new \RangeException('crypto_sign keypair must be 96 bytes long');
|
||||
}
|
||||
return self::substr($keypair, 64, 32);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function publickey_from_secretkey($sk)
|
||||
{
|
||||
/** @var string $sk */
|
||||
$sk = \hash('sha512', self::substr($sk, 0, 32), \true);
|
||||
$sk[0] = self::intToChr(self::chrToInt($sk[0]) & 248);
|
||||
$sk[31] = self::intToChr(self::chrToInt($sk[31]) & 63 | 64);
|
||||
return self::sk_to_pk($sk);
|
||||
}
|
||||
/**
|
||||
* @param string $pk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function pk_to_curve25519($pk)
|
||||
{
|
||||
if (self::small_order($pk)) {
|
||||
throw new \SodiumException('Public key is on a small order');
|
||||
}
|
||||
$A = self::ge_frombytes_negate_vartime($pk);
|
||||
$p1 = self::ge_mul_l($A);
|
||||
if (!self::fe_isnonzero($p1->X)) {
|
||||
throw new \SodiumException('Unexpected zero result');
|
||||
}
|
||||
# fe_1(one_minus_y);
|
||||
# fe_sub(one_minus_y, one_minus_y, A.Y);
|
||||
# fe_invert(one_minus_y, one_minus_y);
|
||||
$one_minux_y = self::fe_invert(self::fe_sub(self::fe_1(), $A->Y));
|
||||
# fe_1(x);
|
||||
# fe_add(x, x, A.Y);
|
||||
# fe_mul(x, x, one_minus_y);
|
||||
$x = self::fe_mul(self::fe_add(self::fe_1(), $A->Y), $one_minux_y);
|
||||
# fe_tobytes(curve25519_pk, x);
|
||||
return self::fe_tobytes($x);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sk_to_pk($sk)
|
||||
{
|
||||
return self::ge_p3_tobytes(self::ge_scalarmult_base(self::substr($sk, 0, 32)));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign($message, $sk)
|
||||
{
|
||||
/** @var string $signature */
|
||||
$signature = self::sign_detached($message, $sk);
|
||||
return $signature . $message;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message A signed message
|
||||
* @param string $pk Public key
|
||||
* @return string Message (without signature)
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign_open($message, $pk)
|
||||
{
|
||||
/** @var string $signature */
|
||||
$signature = self::substr($message, 0, 64);
|
||||
/** @var string $message */
|
||||
$message = self::substr($message, 64);
|
||||
if (self::verify_detached($signature, $message, $pk)) {
|
||||
return $message;
|
||||
}
|
||||
throw new \SodiumException('Invalid signature');
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress PossiblyInvalidArgument
|
||||
*/
|
||||
public static function sign_detached($message, $sk)
|
||||
{
|
||||
# crypto_hash_sha512(az, sk, 32);
|
||||
$az = \hash('sha512', self::substr($sk, 0, 32), \true);
|
||||
# az[0] &= 248;
|
||||
# az[31] &= 63;
|
||||
# az[31] |= 64;
|
||||
$az[0] = self::intToChr(self::chrToInt($az[0]) & 248);
|
||||
$az[31] = self::intToChr(self::chrToInt($az[31]) & 63 | 64);
|
||||
# crypto_hash_sha512_init(&hs);
|
||||
# crypto_hash_sha512_update(&hs, az + 32, 32);
|
||||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, nonce);
|
||||
$hs = \hash_init('sha512');
|
||||
self::hash_update($hs, self::substr($az, 32, 32));
|
||||
self::hash_update($hs, $message);
|
||||
$nonceHash = \hash_final($hs, \true);
|
||||
# memmove(sig + 32, sk + 32, 32);
|
||||
$pk = self::substr($sk, 32, 32);
|
||||
# sc_reduce(nonce);
|
||||
# ge_scalarmult_base(&R, nonce);
|
||||
# ge_p3_tobytes(sig, &R);
|
||||
$nonce = self::sc_reduce($nonceHash) . self::substr($nonceHash, 32);
|
||||
$sig = self::ge_p3_tobytes(self::ge_scalarmult_base($nonce));
|
||||
# crypto_hash_sha512_init(&hs);
|
||||
# crypto_hash_sha512_update(&hs, sig, 64);
|
||||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, hram);
|
||||
$hs = \hash_init('sha512');
|
||||
self::hash_update($hs, self::substr($sig, 0, 32));
|
||||
self::hash_update($hs, self::substr($pk, 0, 32));
|
||||
self::hash_update($hs, $message);
|
||||
$hramHash = \hash_final($hs, \true);
|
||||
# sc_reduce(hram);
|
||||
# sc_muladd(sig + 32, hram, az, nonce);
|
||||
$hram = self::sc_reduce($hramHash);
|
||||
$sigAfter = self::sc_muladd($hram, $az, $nonce);
|
||||
$sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32);
|
||||
try {
|
||||
\ParagonIE_Sodium_Compat::memzero($az);
|
||||
} catch (\SodiumException $ex) {
|
||||
$az = null;
|
||||
}
|
||||
return $sig;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sig
|
||||
* @param string $message
|
||||
* @param string $pk
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function verify_detached($sig, $message, $pk)
|
||||
{
|
||||
if (self::strlen($sig) < 64) {
|
||||
throw new \SodiumException('Signature is too short');
|
||||
}
|
||||
if (self::chrToInt($sig[63]) & 240 && self::check_S_lt_L(self::substr($sig, 32, 32))) {
|
||||
throw new \SodiumException('S < L - Invalid signature');
|
||||
}
|
||||
if (self::small_order($sig)) {
|
||||
throw new \SodiumException('Signature is on too small of an order');
|
||||
}
|
||||
if ((self::chrToInt($sig[63]) & 224) !== 0) {
|
||||
throw new \SodiumException('Invalid signature');
|
||||
}
|
||||
$d = 0;
|
||||
for ($i = 0; $i < 32; ++$i) {
|
||||
$d |= self::chrToInt($pk[$i]);
|
||||
}
|
||||
if ($d === 0) {
|
||||
throw new \SodiumException('All zero public key');
|
||||
}
|
||||
/** @var bool The original value of ParagonIE_Sodium_Compat::$fastMult */
|
||||
$orig = \ParagonIE_Sodium_Compat::$fastMult;
|
||||
// Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification.
|
||||
\ParagonIE_Sodium_Compat::$fastMult = \true;
|
||||
/** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A */
|
||||
$A = self::ge_frombytes_negate_vartime($pk);
|
||||
/** @var string $hDigest */
|
||||
$hDigest = \hash('sha512', self::substr($sig, 0, 32) . self::substr($pk, 0, 32) . $message, \true);
|
||||
/** @var string $h */
|
||||
$h = self::sc_reduce($hDigest) . self::substr($hDigest, 32);
|
||||
/** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $R */
|
||||
$R = self::ge_double_scalarmult_vartime($h, $A, self::substr($sig, 32));
|
||||
/** @var string $rcheck */
|
||||
$rcheck = self::ge_tobytes($R);
|
||||
// Reset ParagonIE_Sodium_Compat::$fastMult to what it was before.
|
||||
\ParagonIE_Sodium_Compat::$fastMult = $orig;
|
||||
return self::verify_32($rcheck, self::substr($sig, 0, 32));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $S
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function check_S_lt_L($S)
|
||||
{
|
||||
if (self::strlen($S) < 32) {
|
||||
throw new \SodiumException('Signature must be 32 bytes');
|
||||
}
|
||||
static $L = array(0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10);
|
||||
/** @var array<int, int> $L */
|
||||
$c = 0;
|
||||
$n = 1;
|
||||
$i = 32;
|
||||
do {
|
||||
--$i;
|
||||
$x = self::chrToInt($S[$i]);
|
||||
$c |= $x - $L[$i] >> 8 & $n;
|
||||
$n &= ($x ^ $L[$i]) - 1 >> 8;
|
||||
} while ($i !== 0);
|
||||
return $c === 0;
|
||||
}
|
||||
/**
|
||||
* @param string $R
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function small_order($R)
|
||||
{
|
||||
static $blocklist = array(
|
||||
/* 0 (order 4) */
|
||||
array(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0),
|
||||
/* 1 (order 1) */
|
||||
array(0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0),
|
||||
/* 2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
|
||||
array(0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x5, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x2, 0x88, 0x6d, 0x53, 0xfc, 0x5),
|
||||
/* 55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
|
||||
array(0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0xb, 0x76, 0xd, 0x10, 0x67, 0xf, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x3, 0x7a),
|
||||
/* p-1 (order 2) */
|
||||
array(0x13, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x5, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x2, 0x88, 0x6d, 0x53, 0xfc, 0x85),
|
||||
/* p (order 4) */
|
||||
array(0xb4, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0xb, 0x76, 0xd, 0x10, 0x67, 0xf, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x3, 0xfa),
|
||||
/* p+1 (order 1) */
|
||||
array(0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f),
|
||||
/* p+2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
|
||||
array(0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f),
|
||||
/* p+55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
|
||||
array(0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f),
|
||||
/* 2p-1 (order 2) */
|
||||
array(0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),
|
||||
/* 2p (order 4) */
|
||||
array(0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),
|
||||
/* 2p+1 (order 1) */
|
||||
array(0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),
|
||||
);
|
||||
/** @var array<int, array<int, int>> $blocklist */
|
||||
$countBlocklist = \count($blocklist);
|
||||
for ($i = 0; $i < $countBlocklist; ++$i) {
|
||||
$c = 0;
|
||||
for ($j = 0; $j < 32; ++$j) {
|
||||
$c |= self::chrToInt($R[$j]) ^ $blocklist[$i][$j];
|
||||
}
|
||||
if ($c === 0) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
$seed = random_bytes(self::SEED_BYTES);
|
||||
$pk = '';
|
||||
$sk = '';
|
||||
self::seed_keypair($pk, $sk, $seed);
|
||||
return $sk . $pk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Ed25519
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $pk
|
||||
* @param string $sk
|
||||
* @param string $seed
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function seed_keypair(&$pk, &$sk, $seed)
|
||||
{
|
||||
if (self::strlen($seed) !== self::SEED_BYTES) {
|
||||
throw new RangeException('crypto_sign keypair seed must be 32 bytes long');
|
||||
}
|
||||
|
||||
/** @var string $pk */
|
||||
$pk = self::publickey_from_secretkey($seed);
|
||||
$sk = $seed . $pk;
|
||||
return $sk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $keypair
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function secretkey($keypair)
|
||||
{
|
||||
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
|
||||
throw new RangeException('crypto_sign keypair must be 96 bytes long');
|
||||
}
|
||||
return self::substr($keypair, 0, 64);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $keypair
|
||||
* @return string
|
||||
* @throws RangeException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function publickey($keypair)
|
||||
{
|
||||
if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
|
||||
throw new RangeException('crypto_sign keypair must be 96 bytes long');
|
||||
}
|
||||
return self::substr($keypair, 64, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function publickey_from_secretkey($sk)
|
||||
{
|
||||
/** @var string $sk */
|
||||
$sk = hash('sha512', self::substr($sk, 0, 32), true);
|
||||
$sk[0] = self::intToChr(
|
||||
self::chrToInt($sk[0]) & 248
|
||||
);
|
||||
$sk[31] = self::intToChr(
|
||||
(self::chrToInt($sk[31]) & 63) | 64
|
||||
);
|
||||
return self::sk_to_pk($sk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function pk_to_curve25519($pk)
|
||||
{
|
||||
if (self::small_order($pk)) {
|
||||
throw new SodiumException('Public key is on a small order');
|
||||
}
|
||||
$A = self::ge_frombytes_negate_vartime($pk);
|
||||
$p1 = self::ge_mul_l($A);
|
||||
if (!self::fe_isnonzero($p1->X)) {
|
||||
throw new SodiumException('Unexpected zero result');
|
||||
}
|
||||
|
||||
# fe_1(one_minus_y);
|
||||
# fe_sub(one_minus_y, one_minus_y, A.Y);
|
||||
# fe_invert(one_minus_y, one_minus_y);
|
||||
$one_minux_y = self::fe_invert(
|
||||
self::fe_sub(
|
||||
self::fe_1(),
|
||||
$A->Y
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
# fe_1(x);
|
||||
# fe_add(x, x, A.Y);
|
||||
# fe_mul(x, x, one_minus_y);
|
||||
$x = self::fe_mul(
|
||||
self::fe_add(self::fe_1(), $A->Y),
|
||||
$one_minux_y
|
||||
);
|
||||
|
||||
# fe_tobytes(curve25519_pk, x);
|
||||
return self::fe_tobytes($x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sk_to_pk($sk)
|
||||
{
|
||||
return self::ge_p3_tobytes(
|
||||
self::ge_scalarmult_base(
|
||||
self::substr($sk, 0, 32)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign($message, $sk)
|
||||
{
|
||||
/** @var string $signature */
|
||||
$signature = self::sign_detached($message, $sk);
|
||||
return $signature . $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message A signed message
|
||||
* @param string $pk Public key
|
||||
* @return string Message (without signature)
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sign_open($message, $pk)
|
||||
{
|
||||
/** @var string $signature */
|
||||
$signature = self::substr($message, 0, 64);
|
||||
|
||||
/** @var string $message */
|
||||
$message = self::substr($message, 64);
|
||||
|
||||
if (self::verify_detached($signature, $message, $pk)) {
|
||||
return $message;
|
||||
}
|
||||
throw new SodiumException('Invalid signature');
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $sk
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress PossiblyInvalidArgument
|
||||
*/
|
||||
public static function sign_detached($message, $sk)
|
||||
{
|
||||
# crypto_hash_sha512(az, sk, 32);
|
||||
$az = hash('sha512', self::substr($sk, 0, 32), true);
|
||||
|
||||
# az[0] &= 248;
|
||||
# az[31] &= 63;
|
||||
# az[31] |= 64;
|
||||
$az[0] = self::intToChr(self::chrToInt($az[0]) & 248);
|
||||
$az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64);
|
||||
|
||||
# crypto_hash_sha512_init(&hs);
|
||||
# crypto_hash_sha512_update(&hs, az + 32, 32);
|
||||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, nonce);
|
||||
$hs = hash_init('sha512');
|
||||
self::hash_update($hs, self::substr($az, 32, 32));
|
||||
self::hash_update($hs, $message);
|
||||
$nonceHash = hash_final($hs, true);
|
||||
|
||||
# memmove(sig + 32, sk + 32, 32);
|
||||
$pk = self::substr($sk, 32, 32);
|
||||
|
||||
# sc_reduce(nonce);
|
||||
# ge_scalarmult_base(&R, nonce);
|
||||
# ge_p3_tobytes(sig, &R);
|
||||
$nonce = self::sc_reduce($nonceHash) . self::substr($nonceHash, 32);
|
||||
$sig = self::ge_p3_tobytes(
|
||||
self::ge_scalarmult_base($nonce)
|
||||
);
|
||||
|
||||
# crypto_hash_sha512_init(&hs);
|
||||
# crypto_hash_sha512_update(&hs, sig, 64);
|
||||
# crypto_hash_sha512_update(&hs, m, mlen);
|
||||
# crypto_hash_sha512_final(&hs, hram);
|
||||
$hs = hash_init('sha512');
|
||||
self::hash_update($hs, self::substr($sig, 0, 32));
|
||||
self::hash_update($hs, self::substr($pk, 0, 32));
|
||||
self::hash_update($hs, $message);
|
||||
$hramHash = hash_final($hs, true);
|
||||
|
||||
# sc_reduce(hram);
|
||||
# sc_muladd(sig + 32, hram, az, nonce);
|
||||
$hram = self::sc_reduce($hramHash);
|
||||
$sigAfter = self::sc_muladd($hram, $az, $nonce);
|
||||
$sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32);
|
||||
|
||||
try {
|
||||
ParagonIE_Sodium_Compat::memzero($az);
|
||||
} catch (SodiumException $ex) {
|
||||
$az = null;
|
||||
}
|
||||
return $sig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $sig
|
||||
* @param string $message
|
||||
* @param string $pk
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function verify_detached($sig, $message, $pk)
|
||||
{
|
||||
if (self::strlen($sig) < 64) {
|
||||
throw new SodiumException('Signature is too short');
|
||||
}
|
||||
if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) {
|
||||
throw new SodiumException('S < L - Invalid signature');
|
||||
}
|
||||
if (self::small_order($sig)) {
|
||||
throw new SodiumException('Signature is on too small of an order');
|
||||
}
|
||||
if ((self::chrToInt($sig[63]) & 224) !== 0) {
|
||||
throw new SodiumException('Invalid signature');
|
||||
}
|
||||
$d = 0;
|
||||
for ($i = 0; $i < 32; ++$i) {
|
||||
$d |= self::chrToInt($pk[$i]);
|
||||
}
|
||||
if ($d === 0) {
|
||||
throw new SodiumException('All zero public key');
|
||||
}
|
||||
|
||||
/** @var bool The original value of ParagonIE_Sodium_Compat::$fastMult */
|
||||
$orig = ParagonIE_Sodium_Compat::$fastMult;
|
||||
|
||||
// Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification.
|
||||
ParagonIE_Sodium_Compat::$fastMult = true;
|
||||
|
||||
/** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A */
|
||||
$A = self::ge_frombytes_negate_vartime($pk);
|
||||
|
||||
/** @var string $hDigest */
|
||||
$hDigest = hash(
|
||||
'sha512',
|
||||
self::substr($sig, 0, 32) .
|
||||
self::substr($pk, 0, 32) .
|
||||
$message,
|
||||
true
|
||||
);
|
||||
|
||||
/** @var string $h */
|
||||
$h = self::sc_reduce($hDigest) . self::substr($hDigest, 32);
|
||||
|
||||
/** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $R */
|
||||
$R = self::ge_double_scalarmult_vartime(
|
||||
$h,
|
||||
$A,
|
||||
self::substr($sig, 32)
|
||||
);
|
||||
|
||||
/** @var string $rcheck */
|
||||
$rcheck = self::ge_tobytes($R);
|
||||
|
||||
// Reset ParagonIE_Sodium_Compat::$fastMult to what it was before.
|
||||
ParagonIE_Sodium_Compat::$fastMult = $orig;
|
||||
|
||||
return self::verify_32($rcheck, self::substr($sig, 0, 32));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $S
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function check_S_lt_L($S)
|
||||
{
|
||||
if (self::strlen($S) < 32) {
|
||||
throw new SodiumException('Signature must be 32 bytes');
|
||||
}
|
||||
static $L = array(
|
||||
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
|
||||
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
|
||||
);
|
||||
/** @var array<int, int> $L */
|
||||
$c = 0;
|
||||
$n = 1;
|
||||
$i = 32;
|
||||
|
||||
do {
|
||||
--$i;
|
||||
$x = self::chrToInt($S[$i]);
|
||||
$c |= (
|
||||
(($x - $L[$i]) >> 8) & $n
|
||||
);
|
||||
$n &= (
|
||||
(($x ^ $L[$i]) - 1) >> 8
|
||||
);
|
||||
} while ($i !== 0);
|
||||
|
||||
return $c === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $R
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function small_order($R)
|
||||
{
|
||||
static $blocklist = array(
|
||||
/* 0 (order 4) */
|
||||
array(
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
),
|
||||
/* 1 (order 1) */
|
||||
array(
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
),
|
||||
/* 2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
|
||||
array(
|
||||
0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0,
|
||||
0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0,
|
||||
0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39,
|
||||
0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05
|
||||
),
|
||||
/* 55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
|
||||
array(
|
||||
0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f,
|
||||
0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f,
|
||||
0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6,
|
||||
0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a
|
||||
),
|
||||
/* p-1 (order 2) */
|
||||
array(
|
||||
0x13, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0,
|
||||
0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0,
|
||||
0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39,
|
||||
0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x85
|
||||
),
|
||||
/* p (order 4) */
|
||||
array(
|
||||
0xb4, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f,
|
||||
0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f,
|
||||
0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6,
|
||||
0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0xfa
|
||||
),
|
||||
/* p+1 (order 1) */
|
||||
array(
|
||||
0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
|
||||
),
|
||||
/* p+2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
|
||||
array(
|
||||
0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
|
||||
),
|
||||
/* p+55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
|
||||
array(
|
||||
0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
|
||||
),
|
||||
/* 2p-1 (order 2) */
|
||||
array(
|
||||
0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
),
|
||||
/* 2p (order 4) */
|
||||
array(
|
||||
0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
),
|
||||
/* 2p+1 (order 1) */
|
||||
array(
|
||||
0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
)
|
||||
);
|
||||
/** @var array<int, array<int, int>> $blocklist */
|
||||
$countBlocklist = count($blocklist);
|
||||
|
||||
for ($i = 0; $i < $countBlocklist; ++$i) {
|
||||
$c = 0;
|
||||
for ($j = 0; $j < 32; ++$j) {
|
||||
$c |= self::chrToInt($R[$j]) ^ $blocklist[$i][$j];
|
||||
}
|
||||
if ($c === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,112 +1,127 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_HChaCha20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_HChaCha20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_HChaCha20
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_HChaCha20 extends ParagonIE_Sodium_Core32_ChaCha20
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_HChaCha20
|
||||
* @param string $in
|
||||
* @param string $key
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_HChaCha20 extends \ParagonIE_Sodium_Core32_ChaCha20
|
||||
public static function hChaCha20($in = '', $key = '', $c = null)
|
||||
{
|
||||
/**
|
||||
* @param string $in
|
||||
* @param string $key
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function hChaCha20($in = '', $key = '', $c = null)
|
||||
{
|
||||
$ctx = array();
|
||||
if ($c === null) {
|
||||
$ctx[0] = new \ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865));
|
||||
$ctx[1] = new \ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e));
|
||||
$ctx[2] = new \ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32));
|
||||
$ctx[3] = new \ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574));
|
||||
} else {
|
||||
$ctx[0] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 0, 4));
|
||||
$ctx[1] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 4, 4));
|
||||
$ctx[2] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 8, 4));
|
||||
$ctx[3] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 12, 4));
|
||||
}
|
||||
$ctx[4] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4));
|
||||
$ctx[5] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 4, 4));
|
||||
$ctx[6] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 8, 4));
|
||||
$ctx[7] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4));
|
||||
$ctx[8] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4));
|
||||
$ctx[9] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4));
|
||||
$ctx[10] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4));
|
||||
$ctx[11] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4));
|
||||
$ctx[12] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 0, 4));
|
||||
$ctx[13] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 4, 4));
|
||||
$ctx[14] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 8, 4));
|
||||
$ctx[15] = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 12, 4));
|
||||
return self::hChaCha20Bytes($ctx);
|
||||
}
|
||||
/**
|
||||
* @param array $ctx
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
protected static function hChaCha20Bytes(array $ctx)
|
||||
{
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x0 */
|
||||
$x0 = $ctx[0];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x1 */
|
||||
$x1 = $ctx[1];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x2 */
|
||||
$x2 = $ctx[2];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x3 */
|
||||
$x3 = $ctx[3];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x4 */
|
||||
$x4 = $ctx[4];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x5 */
|
||||
$x5 = $ctx[5];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x6 */
|
||||
$x6 = $ctx[6];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x7 */
|
||||
$x7 = $ctx[7];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x8 */
|
||||
$x8 = $ctx[8];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x9 */
|
||||
$x9 = $ctx[9];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x10 */
|
||||
$x10 = $ctx[10];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x11 */
|
||||
$x11 = $ctx[11];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x12 */
|
||||
$x12 = $ctx[12];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x13 */
|
||||
$x13 = $ctx[13];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x14 */
|
||||
$x14 = $ctx[14];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x15 */
|
||||
$x15 = $ctx[15];
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
# QUARTERROUND( x0, x4, x8, x12)
|
||||
list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
|
||||
# QUARTERROUND( x1, x5, x9, x13)
|
||||
list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
|
||||
# QUARTERROUND( x2, x6, x10, x14)
|
||||
list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
|
||||
# QUARTERROUND( x3, x7, x11, x15)
|
||||
list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
|
||||
# QUARTERROUND( x0, x5, x10, x15)
|
||||
list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
|
||||
# QUARTERROUND( x1, x6, x11, x12)
|
||||
list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
|
||||
# QUARTERROUND( x2, x7, x8, x13)
|
||||
list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
|
||||
# QUARTERROUND( x3, x4, x9, x14)
|
||||
list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
|
||||
}
|
||||
return $x0->toReverseString() . $x1->toReverseString() . $x2->toReverseString() . $x3->toReverseString() . $x12->toReverseString() . $x13->toReverseString() . $x14->toReverseString() . $x15->toReverseString();
|
||||
$ctx = array();
|
||||
|
||||
if ($c === null) {
|
||||
$ctx[0] = new ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865));
|
||||
$ctx[1] = new ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e));
|
||||
$ctx[2] = new ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32));
|
||||
$ctx[3] = new ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574));
|
||||
} else {
|
||||
$ctx[0] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 0, 4));
|
||||
$ctx[1] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 4, 4));
|
||||
$ctx[2] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 8, 4));
|
||||
$ctx[3] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 12, 4));
|
||||
}
|
||||
$ctx[4] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4));
|
||||
$ctx[5] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 4, 4));
|
||||
$ctx[6] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 8, 4));
|
||||
$ctx[7] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4));
|
||||
$ctx[8] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4));
|
||||
$ctx[9] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4));
|
||||
$ctx[10] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4));
|
||||
$ctx[11] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4));
|
||||
$ctx[12] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 0, 4));
|
||||
$ctx[13] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 4, 4));
|
||||
$ctx[14] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 8, 4));
|
||||
$ctx[15] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 12, 4));
|
||||
|
||||
return self::hChaCha20Bytes($ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_HChaCha20
|
||||
* @param array $ctx
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
protected static function hChaCha20Bytes(array $ctx)
|
||||
{
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x0 */
|
||||
$x0 = $ctx[0];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x1 */
|
||||
$x1 = $ctx[1];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x2 */
|
||||
$x2 = $ctx[2];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x3 */
|
||||
$x3 = $ctx[3];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x4 */
|
||||
$x4 = $ctx[4];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x5 */
|
||||
$x5 = $ctx[5];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x6 */
|
||||
$x6 = $ctx[6];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x7 */
|
||||
$x7 = $ctx[7];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x8 */
|
||||
$x8 = $ctx[8];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x9 */
|
||||
$x9 = $ctx[9];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x10 */
|
||||
$x10 = $ctx[10];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x11 */
|
||||
$x11 = $ctx[11];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x12 */
|
||||
$x12 = $ctx[12];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x13 */
|
||||
$x13 = $ctx[13];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x14 */
|
||||
$x14 = $ctx[14];
|
||||
/** @var ParagonIE_Sodium_Core32_Int32 $x15 */
|
||||
$x15 = $ctx[15];
|
||||
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
# QUARTERROUND( x0, x4, x8, x12)
|
||||
list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12);
|
||||
|
||||
# QUARTERROUND( x1, x5, x9, x13)
|
||||
list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13);
|
||||
|
||||
# QUARTERROUND( x2, x6, x10, x14)
|
||||
list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14);
|
||||
|
||||
# QUARTERROUND( x3, x7, x11, x15)
|
||||
list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15);
|
||||
|
||||
# QUARTERROUND( x0, x5, x10, x15)
|
||||
list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15);
|
||||
|
||||
# QUARTERROUND( x1, x6, x11, x12)
|
||||
list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12);
|
||||
|
||||
# QUARTERROUND( x2, x7, x8, x13)
|
||||
list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13);
|
||||
|
||||
# QUARTERROUND( x3, x4, x9, x14)
|
||||
list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14);
|
||||
}
|
||||
|
||||
return $x0->toReverseString() .
|
||||
$x1->toReverseString() .
|
||||
$x2->toReverseString() .
|
||||
$x3->toReverseString() .
|
||||
$x12->toReverseString() .
|
||||
$x13->toReverseString() .
|
||||
$x14->toReverseString() .
|
||||
$x15->toReverseString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,129 +1,141 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_HSalsa20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_HSalsa20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_HSalsa20
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_HSalsa20 extends ParagonIE_Sodium_Core32_Salsa20
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_HSalsa20
|
||||
* Calculate an hsalsa20 hash of a single block
|
||||
*
|
||||
* HSalsa20 doesn't have a counter and will never be used for more than
|
||||
* one block (used to derive a subkey for xsalsa20).
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $k
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_HSalsa20 extends \ParagonIE_Sodium_Core32_Salsa20
|
||||
public static function hsalsa20($in, $k, $c = null)
|
||||
{
|
||||
/**
|
||||
* Calculate an hsalsa20 hash of a single block
|
||||
*
|
||||
* HSalsa20 doesn't have a counter and will never be used for more than
|
||||
* one block (used to derive a subkey for xsalsa20).
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $k
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x5
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x6
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x7
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x8
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x9
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x10
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x11
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x12
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x13
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x14
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x15
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j5
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j6
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j7
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j8
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j9
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j10
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j11
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j12
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j13
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j14
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j15
|
||||
*/
|
||||
public static function hsalsa20($in, $k, $c = null)
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x5
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x6
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x7
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x8
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x9
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x10
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x11
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x12
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x13
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x14
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x15
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j5
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j6
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j7
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j8
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j9
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j10
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j11
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j12
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j13
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j14
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j15
|
||||
*/
|
||||
if (self::strlen($k) < 32) {
|
||||
throw new \RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
if ($c === null) {
|
||||
$x0 = new \ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865));
|
||||
$x5 = new \ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e));
|
||||
$x10 = new \ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32));
|
||||
$x15 = new \ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574));
|
||||
} else {
|
||||
$x0 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 0, 4));
|
||||
$x5 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 4, 4));
|
||||
$x10 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 8, 4));
|
||||
$x15 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 12, 4));
|
||||
}
|
||||
$x1 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 0, 4));
|
||||
$x2 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 4, 4));
|
||||
$x3 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 8, 4));
|
||||
$x4 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 12, 4));
|
||||
$x6 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 0, 4));
|
||||
$x7 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 4, 4));
|
||||
$x8 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 8, 4));
|
||||
$x9 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 12, 4));
|
||||
$x11 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 16, 4));
|
||||
$x12 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 20, 4));
|
||||
$x13 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 24, 4));
|
||||
$x14 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 28, 4));
|
||||
for ($i = self::ROUNDS; $i > 0; $i -= 2) {
|
||||
$x4 = $x4->xorInt32($x0->addInt32($x12)->rotateLeft(7));
|
||||
$x8 = $x8->xorInt32($x4->addInt32($x0)->rotateLeft(9));
|
||||
$x12 = $x12->xorInt32($x8->addInt32($x4)->rotateLeft(13));
|
||||
$x0 = $x0->xorInt32($x12->addInt32($x8)->rotateLeft(18));
|
||||
$x9 = $x9->xorInt32($x5->addInt32($x1)->rotateLeft(7));
|
||||
$x13 = $x13->xorInt32($x9->addInt32($x5)->rotateLeft(9));
|
||||
$x1 = $x1->xorInt32($x13->addInt32($x9)->rotateLeft(13));
|
||||
$x5 = $x5->xorInt32($x1->addInt32($x13)->rotateLeft(18));
|
||||
$x14 = $x14->xorInt32($x10->addInt32($x6)->rotateLeft(7));
|
||||
$x2 = $x2->xorInt32($x14->addInt32($x10)->rotateLeft(9));
|
||||
$x6 = $x6->xorInt32($x2->addInt32($x14)->rotateLeft(13));
|
||||
$x10 = $x10->xorInt32($x6->addInt32($x2)->rotateLeft(18));
|
||||
$x3 = $x3->xorInt32($x15->addInt32($x11)->rotateLeft(7));
|
||||
$x7 = $x7->xorInt32($x3->addInt32($x15)->rotateLeft(9));
|
||||
$x11 = $x11->xorInt32($x7->addInt32($x3)->rotateLeft(13));
|
||||
$x15 = $x15->xorInt32($x11->addInt32($x7)->rotateLeft(18));
|
||||
$x1 = $x1->xorInt32($x0->addInt32($x3)->rotateLeft(7));
|
||||
$x2 = $x2->xorInt32($x1->addInt32($x0)->rotateLeft(9));
|
||||
$x3 = $x3->xorInt32($x2->addInt32($x1)->rotateLeft(13));
|
||||
$x0 = $x0->xorInt32($x3->addInt32($x2)->rotateLeft(18));
|
||||
$x6 = $x6->xorInt32($x5->addInt32($x4)->rotateLeft(7));
|
||||
$x7 = $x7->xorInt32($x6->addInt32($x5)->rotateLeft(9));
|
||||
$x4 = $x4->xorInt32($x7->addInt32($x6)->rotateLeft(13));
|
||||
$x5 = $x5->xorInt32($x4->addInt32($x7)->rotateLeft(18));
|
||||
$x11 = $x11->xorInt32($x10->addInt32($x9)->rotateLeft(7));
|
||||
$x8 = $x8->xorInt32($x11->addInt32($x10)->rotateLeft(9));
|
||||
$x9 = $x9->xorInt32($x8->addInt32($x11)->rotateLeft(13));
|
||||
$x10 = $x10->xorInt32($x9->addInt32($x8)->rotateLeft(18));
|
||||
$x12 = $x12->xorInt32($x15->addInt32($x14)->rotateLeft(7));
|
||||
$x13 = $x13->xorInt32($x12->addInt32($x15)->rotateLeft(9));
|
||||
$x14 = $x14->xorInt32($x13->addInt32($x12)->rotateLeft(13));
|
||||
$x15 = $x15->xorInt32($x14->addInt32($x13)->rotateLeft(18));
|
||||
}
|
||||
return $x0->toReverseString() . $x5->toReverseString() . $x10->toReverseString() . $x15->toReverseString() . $x6->toReverseString() . $x7->toReverseString() . $x8->toReverseString() . $x9->toReverseString();
|
||||
if (self::strlen($k) < 32) {
|
||||
throw new RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
if ($c === null) {
|
||||
$x0 = new ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865));
|
||||
$x5 = new ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e));
|
||||
$x10 = new ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32));
|
||||
$x15 = new ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574));
|
||||
} else {
|
||||
$x0 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 0, 4));
|
||||
$x5 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 4, 4));
|
||||
$x10 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 8, 4));
|
||||
$x15 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 12, 4));
|
||||
}
|
||||
$x1 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 0, 4));
|
||||
$x2 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 4, 4));
|
||||
$x3 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 8, 4));
|
||||
$x4 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 12, 4));
|
||||
$x6 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 0, 4));
|
||||
$x7 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 4, 4));
|
||||
$x8 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 8, 4));
|
||||
$x9 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 12, 4));
|
||||
$x11 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 16, 4));
|
||||
$x12 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 20, 4));
|
||||
$x13 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 24, 4));
|
||||
$x14 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 28, 4));
|
||||
|
||||
for ($i = self::ROUNDS; $i > 0; $i -= 2) {
|
||||
$x4 = $x4->xorInt32($x0->addInt32($x12)->rotateLeft(7));
|
||||
$x8 = $x8->xorInt32($x4->addInt32($x0)->rotateLeft(9));
|
||||
$x12 = $x12->xorInt32($x8->addInt32($x4)->rotateLeft(13));
|
||||
$x0 = $x0->xorInt32($x12->addInt32($x8)->rotateLeft(18));
|
||||
|
||||
$x9 = $x9->xorInt32($x5->addInt32($x1)->rotateLeft(7));
|
||||
$x13 = $x13->xorInt32($x9->addInt32($x5)->rotateLeft(9));
|
||||
$x1 = $x1->xorInt32($x13->addInt32($x9)->rotateLeft(13));
|
||||
$x5 = $x5->xorInt32($x1->addInt32($x13)->rotateLeft(18));
|
||||
|
||||
$x14 = $x14->xorInt32($x10->addInt32($x6)->rotateLeft(7));
|
||||
$x2 = $x2->xorInt32($x14->addInt32($x10)->rotateLeft(9));
|
||||
$x6 = $x6->xorInt32($x2->addInt32($x14)->rotateLeft(13));
|
||||
$x10 = $x10->xorInt32($x6->addInt32($x2)->rotateLeft(18));
|
||||
|
||||
$x3 = $x3->xorInt32($x15->addInt32($x11)->rotateLeft(7));
|
||||
$x7 = $x7->xorInt32($x3->addInt32($x15)->rotateLeft(9));
|
||||
$x11 = $x11->xorInt32($x7->addInt32($x3)->rotateLeft(13));
|
||||
$x15 = $x15->xorInt32($x11->addInt32($x7)->rotateLeft(18));
|
||||
|
||||
$x1 = $x1->xorInt32($x0->addInt32($x3)->rotateLeft(7));
|
||||
$x2 = $x2->xorInt32($x1->addInt32($x0)->rotateLeft(9));
|
||||
$x3 = $x3->xorInt32($x2->addInt32($x1)->rotateLeft(13));
|
||||
$x0 = $x0->xorInt32($x3->addInt32($x2)->rotateLeft(18));
|
||||
|
||||
$x6 = $x6->xorInt32($x5->addInt32($x4)->rotateLeft(7));
|
||||
$x7 = $x7->xorInt32($x6->addInt32($x5)->rotateLeft(9));
|
||||
$x4 = $x4->xorInt32($x7->addInt32($x6)->rotateLeft(13));
|
||||
$x5 = $x5->xorInt32($x4->addInt32($x7)->rotateLeft(18));
|
||||
|
||||
$x11 = $x11->xorInt32($x10->addInt32($x9)->rotateLeft(7));
|
||||
$x8 = $x8->xorInt32($x11->addInt32($x10)->rotateLeft(9));
|
||||
$x9 = $x9->xorInt32($x8->addInt32($x11)->rotateLeft(13));
|
||||
$x10 = $x10->xorInt32($x9->addInt32($x8)->rotateLeft(18));
|
||||
|
||||
$x12 = $x12->xorInt32($x15->addInt32($x14)->rotateLeft(7));
|
||||
$x13 = $x13->xorInt32($x12->addInt32($x15)->rotateLeft(9));
|
||||
$x14 = $x14->xorInt32($x13->addInt32($x12)->rotateLeft(13));
|
||||
$x15 = $x15->xorInt32($x14->addInt32($x13)->rotateLeft(18));
|
||||
}
|
||||
|
||||
return $x0->toReverseString() .
|
||||
$x5->toReverseString() .
|
||||
$x10->toReverseString() .
|
||||
$x15->toReverseString() .
|
||||
$x6->toReverseString() .
|
||||
$x7->toReverseString() .
|
||||
$x8->toReverseString() .
|
||||
$x9->toReverseString();
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_HSalsa20
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,53 +1,63 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Poly1305', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Poly1305
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_Poly1305 extends ParagonIE_Sodium_Core32_Util
|
||||
{
|
||||
const BLOCK_SIZE = 16;
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Poly1305', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Poly1305
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $m
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_Poly1305 extends \ParagonIE_Sodium_Core32_Util
|
||||
public static function onetimeauth($m, $key)
|
||||
{
|
||||
const BLOCK_SIZE = 16;
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $m
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function onetimeauth($m, $key)
|
||||
{
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new \InvalidArgumentException('Key must be 32 bytes long.');
|
||||
}
|
||||
$state = new \ParagonIE_Sodium_Core32_Poly1305_State(self::substr($key, 0, 32));
|
||||
return $state->update($m)->finish();
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $mac
|
||||
* @param string $m
|
||||
* @param string $key
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function onetimeauth_verify($mac, $m, $key)
|
||||
{
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new \InvalidArgumentException('Key must be 32 bytes long.');
|
||||
}
|
||||
$state = new \ParagonIE_Sodium_Core32_Poly1305_State(self::substr($key, 0, 32));
|
||||
$calc = $state->update($m)->finish();
|
||||
return self::verify_16($calc, $mac);
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new InvalidArgumentException(
|
||||
'Key must be 32 bytes long.'
|
||||
);
|
||||
}
|
||||
$state = new ParagonIE_Sodium_Core32_Poly1305_State(
|
||||
self::substr($key, 0, 32)
|
||||
);
|
||||
return $state
|
||||
->update($m)
|
||||
->finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Poly1305
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $mac
|
||||
* @param string $m
|
||||
* @param string $key
|
||||
* @return bool
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function onetimeauth_verify($mac, $m, $key)
|
||||
{
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new InvalidArgumentException(
|
||||
'Key must be 32 bytes long.'
|
||||
);
|
||||
}
|
||||
$state = new ParagonIE_Sodium_Core32_Poly1305_State(
|
||||
self::substr($key, 0, 32)
|
||||
);
|
||||
$calc = $state
|
||||
->update($m)
|
||||
->finish();
|
||||
return self::verify_16($calc, $mac);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,334 +1,451 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Poly1305_State', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Poly1305_State', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Poly1305_State
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Poly1305_State extends ParagonIE_Sodium_Core32_Util
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Poly1305_State
|
||||
* @var array<int, int>
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_Poly1305_State extends \ParagonIE_Sodium_Core32_Util
|
||||
protected $buffer = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $final = false;
|
||||
|
||||
/**
|
||||
* @var array<int, ParagonIE_Sodium_Core32_Int32>
|
||||
*/
|
||||
public $h;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $leftover = 0;
|
||||
|
||||
/**
|
||||
* @var array<int, ParagonIE_Sodium_Core32_Int32>
|
||||
*/
|
||||
public $r;
|
||||
|
||||
/**
|
||||
* @var array<int, ParagonIE_Sodium_Core32_Int64>
|
||||
*/
|
||||
public $pad;
|
||||
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Poly1305_State constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key
|
||||
* @throws InvalidArgumentException
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '')
|
||||
{
|
||||
/**
|
||||
* @var array<int, int>
|
||||
*/
|
||||
protected $buffer = array();
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $final = \false;
|
||||
/**
|
||||
* @var array<int, ParagonIE_Sodium_Core32_Int32>
|
||||
*/
|
||||
public $h;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $leftover = 0;
|
||||
/**
|
||||
* @var array<int, ParagonIE_Sodium_Core32_Int32>
|
||||
*/
|
||||
public $r;
|
||||
/**
|
||||
* @var array<int, ParagonIE_Sodium_Core32_Int64>
|
||||
*/
|
||||
public $pad;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_Poly1305_State constructor.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $key
|
||||
* @throws InvalidArgumentException
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function __construct($key = '')
|
||||
{
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new \InvalidArgumentException('Poly1305 requires a 32-byte key');
|
||||
}
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
$this->r = array(
|
||||
// st->r[0] = ...
|
||||
\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4))->setUnsignedInt(\true)->mask(0x3ffffff),
|
||||
// st->r[1] = ...
|
||||
\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 3, 4))->setUnsignedInt(\true)->shiftRight(2)->mask(0x3ffff03),
|
||||
// st->r[2] = ...
|
||||
\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 6, 4))->setUnsignedInt(\true)->shiftRight(4)->mask(0x3ffc0ff),
|
||||
// st->r[3] = ...
|
||||
\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 9, 4))->setUnsignedInt(\true)->shiftRight(6)->mask(0x3f03fff),
|
||||
// st->r[4] = ...
|
||||
\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4))->setUnsignedInt(\true)->shiftRight(8)->mask(0xfffff),
|
||||
if (self::strlen($key) < 32) {
|
||||
throw new InvalidArgumentException(
|
||||
'Poly1305 requires a 32-byte key'
|
||||
);
|
||||
/* h = 0 */
|
||||
$this->h = array(new \ParagonIE_Sodium_Core32_Int32(array(0, 0), \true), new \ParagonIE_Sodium_Core32_Int32(array(0, 0), \true), new \ParagonIE_Sodium_Core32_Int32(array(0, 0), \true), new \ParagonIE_Sodium_Core32_Int32(array(0, 0), \true), new \ParagonIE_Sodium_Core32_Int32(array(0, 0), \true));
|
||||
/* save pad for later */
|
||||
$this->pad = array(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4))->setUnsignedInt(\true)->toInt64(), \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4))->setUnsignedInt(\true)->toInt64(), \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4))->setUnsignedInt(\true)->toInt64(), \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4))->setUnsignedInt(\true)->toInt64());
|
||||
$this->leftover = 0;
|
||||
$this->final = \false;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function update($message = '')
|
||||
{
|
||||
$bytes = self::strlen($message);
|
||||
/* handle leftover */
|
||||
if ($this->leftover) {
|
||||
/** @var int $want */
|
||||
$want = \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - $this->leftover;
|
||||
if ($want > $bytes) {
|
||||
$want = $bytes;
|
||||
}
|
||||
for ($i = 0; $i < $want; ++$i) {
|
||||
$mi = self::chrToInt($message[$i]);
|
||||
$this->buffer[$this->leftover + $i] = $mi;
|
||||
}
|
||||
// We snip off the leftmost bytes.
|
||||
$message = self::substr($message, $want);
|
||||
$bytes = self::strlen($message);
|
||||
$this->leftover += $want;
|
||||
if ($this->leftover < \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
// We still don't have enough to run $this->blocks()
|
||||
return $this;
|
||||
}
|
||||
$this->blocks(self::intArrayToString($this->buffer), \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE);
|
||||
$this->leftover = 0;
|
||||
}
|
||||
/* process full blocks */
|
||||
if ($bytes >= \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
/** @var int $want */
|
||||
$want = $bytes & ~(\ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - 1);
|
||||
if ($want >= \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
/** @var string $block */
|
||||
$block = self::substr($message, 0, $want);
|
||||
if (self::strlen($block) >= \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
$this->blocks($block, $want);
|
||||
$message = self::substr($message, $want);
|
||||
$bytes = self::strlen($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* store leftover */
|
||||
if ($bytes) {
|
||||
for ($i = 0; $i < $bytes; ++$i) {
|
||||
$mi = self::chrToInt($message[$i]);
|
||||
$this->buffer[$this->leftover + $i] = $mi;
|
||||
}
|
||||
$this->leftover = (int) $this->leftover + $bytes;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $bytes
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function blocks($message, $bytes)
|
||||
{
|
||||
if (self::strlen($message) < 16) {
|
||||
$message = \str_pad($message, 16, "\x00", \STR_PAD_RIGHT);
|
||||
}
|
||||
$hibit = \ParagonIE_Sodium_Core32_Int32::fromInt((int) ($this->final ? 0 : 1 << 24));
|
||||
/* 1 << 128 */
|
||||
$hibit->setUnsignedInt(\true);
|
||||
$zero = new \ParagonIE_Sodium_Core32_Int64(array(0, 0, 0, 0), \true);
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d0
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d1
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d2
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d3
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d4
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r0
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r1
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r2
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r3
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r4
|
||||
*
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h4
|
||||
*/
|
||||
$r0 = $this->r[0]->toInt64();
|
||||
$r1 = $this->r[1]->toInt64();
|
||||
$r2 = $this->r[2]->toInt64();
|
||||
$r3 = $this->r[3]->toInt64();
|
||||
$r4 = $this->r[4]->toInt64();
|
||||
$s1 = $r1->toInt64()->mulInt(5, 3);
|
||||
$s2 = $r2->toInt64()->mulInt(5, 3);
|
||||
$s3 = $r3->toInt64()->mulInt(5, 3);
|
||||
$s4 = $r4->toInt64()->mulInt(5, 3);
|
||||
$h0 = $this->h[0];
|
||||
$h1 = $this->h[1];
|
||||
$h2 = $this->h[2];
|
||||
$h3 = $this->h[3];
|
||||
$h4 = $this->h[4];
|
||||
while ($bytes >= \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
/* h += m[i] */
|
||||
$h0 = $h0->addInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 0, 4))->mask(0x3ffffff))->toInt64();
|
||||
$h1 = $h1->addInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 3, 4))->shiftRight(2)->mask(0x3ffffff))->toInt64();
|
||||
$h2 = $h2->addInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 6, 4))->shiftRight(4)->mask(0x3ffffff))->toInt64();
|
||||
$h3 = $h3->addInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 9, 4))->shiftRight(6)->mask(0x3ffffff))->toInt64();
|
||||
$h4 = $h4->addInt32(\ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 12, 4))->shiftRight(8)->orInt32($hibit))->toInt64();
|
||||
/* h *= r */
|
||||
$d0 = $zero->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, 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, 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, 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, 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);
|
||||
$h0 = $d0->toInt32()->mask(0x3ffffff);
|
||||
$d1 = $d1->addInt64($c);
|
||||
$c = $d1->shiftRight(26);
|
||||
$h1 = $d1->toInt32()->mask(0x3ffffff);
|
||||
$d2 = $d2->addInt64($c);
|
||||
$c = $d2->shiftRight(26);
|
||||
$h2 = $d2->toInt32()->mask(0x3ffffff);
|
||||
$d3 = $d3->addInt64($c);
|
||||
$c = $d3->shiftRight(26);
|
||||
$h3 = $d3->toInt32()->mask(0x3ffffff);
|
||||
$d4 = $d4->addInt64($c);
|
||||
$c = $d4->shiftRight(26);
|
||||
$h4 = $d4->toInt32()->mask(0x3ffffff);
|
||||
$h0 = $h0->addInt32($c->toInt32()->mulInt(5, 3));
|
||||
$c = $h0->shiftRight(26);
|
||||
$h0 = $h0->mask(0x3ffffff);
|
||||
$h1 = $h1->addInt32($c);
|
||||
// Chop off the left 32 bytes.
|
||||
$message = self::substr($message, \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE);
|
||||
$bytes -= \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE;
|
||||
}
|
||||
/** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
|
||||
$this->h = array($h0, $h1, $h2, $h3, $h4);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
/* process the remaining block */
|
||||
if ($this->leftover) {
|
||||
$i = $this->leftover;
|
||||
$this->buffer[$i++] = 1;
|
||||
for (; $i < \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE; ++$i) {
|
||||
$this->buffer[$i] = 0;
|
||||
}
|
||||
$this->final = \true;
|
||||
$this->blocks(self::substr(self::intArrayToString($this->buffer), 0, \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE), $b = \ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE);
|
||||
}
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $f
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h4
|
||||
*/
|
||||
$h0 = $this->h[0];
|
||||
$h1 = $this->h[1];
|
||||
$h2 = $this->h[2];
|
||||
$h3 = $this->h[3];
|
||||
$h4 = $this->h[4];
|
||||
$c = $h1->shiftRight(26);
|
||||
# $c = $h1 >> 26;
|
||||
$h1 = $h1->mask(0x3ffffff);
|
||||
# $h1 &= 0x3ffffff;
|
||||
$h2 = $h2->addInt32($c);
|
||||
# $h2 += $c;
|
||||
$c = $h2->shiftRight(26);
|
||||
# $c = $h2 >> 26;
|
||||
$h2 = $h2->mask(0x3ffffff);
|
||||
# $h2 &= 0x3ffffff;
|
||||
$h3 = $h3->addInt32($c);
|
||||
# $h3 += $c;
|
||||
$c = $h3->shiftRight(26);
|
||||
# $c = $h3 >> 26;
|
||||
$h3 = $h3->mask(0x3ffffff);
|
||||
# $h3 &= 0x3ffffff;
|
||||
$h4 = $h4->addInt32($c);
|
||||
# $h4 += $c;
|
||||
$c = $h4->shiftRight(26);
|
||||
# $c = $h4 >> 26;
|
||||
$h4 = $h4->mask(0x3ffffff);
|
||||
# $h4 &= 0x3ffffff;
|
||||
$h0 = $h0->addInt32($c->mulInt(5, 3));
|
||||
# $h0 += self::mul($c, 5);
|
||||
$c = $h0->shiftRight(26);
|
||||
# $c = $h0 >> 26;
|
||||
$h0 = $h0->mask(0x3ffffff);
|
||||
# $h0 &= 0x3ffffff;
|
||||
$h1 = $h1->addInt32($c);
|
||||
# $h1 += $c;
|
||||
/* compute h + -p */
|
||||
$g0 = $h0->addInt(5);
|
||||
$c = $g0->shiftRight(26);
|
||||
$g0 = $g0->mask(0x3ffffff);
|
||||
$g1 = $h1->addInt32($c);
|
||||
$c = $g1->shiftRight(26);
|
||||
$g1 = $g1->mask(0x3ffffff);
|
||||
$g2 = $h2->addInt32($c);
|
||||
$c = $g2->shiftRight(26);
|
||||
$g2 = $g2->mask(0x3ffffff);
|
||||
$g3 = $h3->addInt32($c);
|
||||
$c = $g3->shiftRight(26);
|
||||
$g3 = $g3->mask(0x3ffffff);
|
||||
$g4 = $h4->addInt32($c)->subInt(1 << 26);
|
||||
# $mask = ($g4 >> 31) - 1;
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
$mask = (int) (($g4->toInt() >> 31) + 1);
|
||||
$g0 = $g0->mask($mask);
|
||||
$g1 = $g1->mask($mask);
|
||||
$g2 = $g2->mask($mask);
|
||||
$g3 = $g3->mask($mask);
|
||||
$g4 = $g4->mask($mask);
|
||||
/** @var int $mask */
|
||||
$mask = ~$mask;
|
||||
$h0 = $h0->mask($mask)->orInt32($g0);
|
||||
$h1 = $h1->mask($mask)->orInt32($g1);
|
||||
$h2 = $h2->mask($mask)->orInt32($g2);
|
||||
$h3 = $h3->mask($mask)->orInt32($g3);
|
||||
$h4 = $h4->mask($mask)->orInt32($g4);
|
||||
/* h = h % (2^128) */
|
||||
$h0 = $h0->orInt32($h1->shiftLeft(26));
|
||||
$h1 = $h1->shiftRight(6)->orInt32($h2->shiftLeft(20));
|
||||
$h2 = $h2->shiftRight(12)->orInt32($h3->shiftLeft(14));
|
||||
$h3 = $h3->shiftRight(18)->orInt32($h4->shiftLeft(8));
|
||||
/* mac = (h + pad) % (2^128) */
|
||||
$f = $h0->toInt64()->addInt64($this->pad[0]);
|
||||
$h0 = $f->toInt32();
|
||||
$f = $h1->toInt64()->addInt64($this->pad[1])->addInt($h0->overflow);
|
||||
$h1 = $f->toInt32();
|
||||
$f = $h2->toInt64()->addInt64($this->pad[2])->addInt($h1->overflow);
|
||||
$h2 = $f->toInt32();
|
||||
$f = $h3->toInt64()->addInt64($this->pad[3])->addInt($h2->overflow);
|
||||
$h3 = $f->toInt32();
|
||||
return $h0->toReverseString() . $h1->toReverseString() . $h2->toReverseString() . $h3->toReverseString();
|
||||
}
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
$this->r = array(
|
||||
// st->r[0] = ...
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4))
|
||||
->setUnsignedInt(true)
|
||||
->mask(0x3ffffff),
|
||||
// st->r[1] = ...
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 3, 4))
|
||||
->setUnsignedInt(true)
|
||||
->shiftRight(2)
|
||||
->mask(0x3ffff03),
|
||||
// st->r[2] = ...
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 6, 4))
|
||||
->setUnsignedInt(true)
|
||||
->shiftRight(4)
|
||||
->mask(0x3ffc0ff),
|
||||
// st->r[3] = ...
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 9, 4))
|
||||
->setUnsignedInt(true)
|
||||
->shiftRight(6)
|
||||
->mask(0x3f03fff),
|
||||
// st->r[4] = ...
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4))
|
||||
->setUnsignedInt(true)
|
||||
->shiftRight(8)
|
||||
->mask(0x00fffff)
|
||||
);
|
||||
|
||||
/* h = 0 */
|
||||
$this->h = array(
|
||||
new ParagonIE_Sodium_Core32_Int32(array(0, 0), true),
|
||||
new ParagonIE_Sodium_Core32_Int32(array(0, 0), true),
|
||||
new ParagonIE_Sodium_Core32_Int32(array(0, 0), true),
|
||||
new ParagonIE_Sodium_Core32_Int32(array(0, 0), true),
|
||||
new ParagonIE_Sodium_Core32_Int32(array(0, 0), true)
|
||||
);
|
||||
|
||||
/* save pad for later */
|
||||
$this->pad = array(
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4))
|
||||
->setUnsignedInt(true)->toInt64(),
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4))
|
||||
->setUnsignedInt(true)->toInt64(),
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4))
|
||||
->setUnsignedInt(true)->toInt64(),
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4))
|
||||
->setUnsignedInt(true)->toInt64(),
|
||||
);
|
||||
|
||||
$this->leftover = 0;
|
||||
$this->final = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Poly1305_State
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public function update($message = '')
|
||||
{
|
||||
$bytes = self::strlen($message);
|
||||
|
||||
/* handle leftover */
|
||||
if ($this->leftover) {
|
||||
/** @var int $want */
|
||||
$want = ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - $this->leftover;
|
||||
if ($want > $bytes) {
|
||||
$want = $bytes;
|
||||
}
|
||||
for ($i = 0; $i < $want; ++$i) {
|
||||
$mi = self::chrToInt($message[$i]);
|
||||
$this->buffer[$this->leftover + $i] = $mi;
|
||||
}
|
||||
// We snip off the leftmost bytes.
|
||||
$message = self::substr($message, $want);
|
||||
$bytes = self::strlen($message);
|
||||
$this->leftover += $want;
|
||||
if ($this->leftover < ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
// We still don't have enough to run $this->blocks()
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->blocks(
|
||||
self::intArrayToString($this->buffer),
|
||||
ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
|
||||
);
|
||||
$this->leftover = 0;
|
||||
}
|
||||
|
||||
/* process full blocks */
|
||||
if ($bytes >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
/** @var int $want */
|
||||
$want = $bytes & ~(ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - 1);
|
||||
if ($want >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
/** @var string $block */
|
||||
$block = self::substr($message, 0, $want);
|
||||
if (self::strlen($block) >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
$this->blocks($block, $want);
|
||||
$message = self::substr($message, $want);
|
||||
$bytes = self::strlen($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* store leftover */
|
||||
if ($bytes) {
|
||||
for ($i = 0; $i < $bytes; ++$i) {
|
||||
$mi = self::chrToInt($message[$i]);
|
||||
$this->buffer[$this->leftover + $i] = $mi;
|
||||
}
|
||||
$this->leftover = (int) $this->leftover + $bytes;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $bytes
|
||||
* @return self
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function blocks($message, $bytes)
|
||||
{
|
||||
if (self::strlen($message) < 16) {
|
||||
$message = str_pad($message, 16, "\x00", STR_PAD_RIGHT);
|
||||
}
|
||||
$hibit = ParagonIE_Sodium_Core32_Int32::fromInt((int) ($this->final ? 0 : 1 << 24)); /* 1 << 128 */
|
||||
$hibit->setUnsignedInt(true);
|
||||
$zero = new ParagonIE_Sodium_Core32_Int64(array(0, 0, 0, 0), true);
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d0
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d1
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d2
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d3
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $d4
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r0
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r1
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r2
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r3
|
||||
* @var ParagonIE_Sodium_Core32_Int64 $r4
|
||||
*
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h4
|
||||
*/
|
||||
$r0 = $this->r[0]->toInt64();
|
||||
$r1 = $this->r[1]->toInt64();
|
||||
$r2 = $this->r[2]->toInt64();
|
||||
$r3 = $this->r[3]->toInt64();
|
||||
$r4 = $this->r[4]->toInt64();
|
||||
|
||||
$s1 = $r1->toInt64()->mulInt(5, 3);
|
||||
$s2 = $r2->toInt64()->mulInt(5, 3);
|
||||
$s3 = $r3->toInt64()->mulInt(5, 3);
|
||||
$s4 = $r4->toInt64()->mulInt(5, 3);
|
||||
|
||||
$h0 = $this->h[0];
|
||||
$h1 = $this->h[1];
|
||||
$h2 = $this->h[2];
|
||||
$h3 = $this->h[3];
|
||||
$h4 = $this->h[4];
|
||||
|
||||
while ($bytes >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) {
|
||||
/* h += m[i] */
|
||||
$h0 = $h0->addInt32(
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 0, 4))
|
||||
->mask(0x3ffffff)
|
||||
)->toInt64();
|
||||
$h1 = $h1->addInt32(
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 3, 4))
|
||||
->shiftRight(2)
|
||||
->mask(0x3ffffff)
|
||||
)->toInt64();
|
||||
$h2 = $h2->addInt32(
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 6, 4))
|
||||
->shiftRight(4)
|
||||
->mask(0x3ffffff)
|
||||
)->toInt64();
|
||||
$h3 = $h3->addInt32(
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 9, 4))
|
||||
->shiftRight(6)
|
||||
->mask(0x3ffffff)
|
||||
)->toInt64();
|
||||
$h4 = $h4->addInt32(
|
||||
ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 12, 4))
|
||||
->shiftRight(8)
|
||||
->orInt32($hibit)
|
||||
)->toInt64();
|
||||
|
||||
/* h *= r */
|
||||
$d0 = $zero
|
||||
->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, 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, 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, 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, 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);
|
||||
$h0 = $d0->toInt32()->mask(0x3ffffff);
|
||||
$d1 = $d1->addInt64($c);
|
||||
|
||||
$c = $d1->shiftRight(26);
|
||||
$h1 = $d1->toInt32()->mask(0x3ffffff);
|
||||
$d2 = $d2->addInt64($c);
|
||||
|
||||
$c = $d2->shiftRight(26);
|
||||
$h2 = $d2->toInt32()->mask(0x3ffffff);
|
||||
$d3 = $d3->addInt64($c);
|
||||
|
||||
$c = $d3->shiftRight(26);
|
||||
$h3 = $d3->toInt32()->mask(0x3ffffff);
|
||||
$d4 = $d4->addInt64($c);
|
||||
|
||||
$c = $d4->shiftRight(26);
|
||||
$h4 = $d4->toInt32()->mask(0x3ffffff);
|
||||
$h0 = $h0->addInt32($c->toInt32()->mulInt(5, 3));
|
||||
|
||||
$c = $h0->shiftRight(26);
|
||||
$h0 = $h0->mask(0x3ffffff);
|
||||
$h1 = $h1->addInt32($c);
|
||||
|
||||
// Chop off the left 32 bytes.
|
||||
$message = self::substr(
|
||||
$message,
|
||||
ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
|
||||
);
|
||||
$bytes -= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */
|
||||
$this->h = array($h0, $h1, $h2, $h3, $h4);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
/* process the remaining block */
|
||||
if ($this->leftover) {
|
||||
$i = $this->leftover;
|
||||
$this->buffer[$i++] = 1;
|
||||
for (; $i < ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE; ++$i) {
|
||||
$this->buffer[$i] = 0;
|
||||
}
|
||||
$this->final = true;
|
||||
$this->blocks(
|
||||
self::substr(
|
||||
self::intArrayToString($this->buffer),
|
||||
0,
|
||||
ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
|
||||
),
|
||||
$b = ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $f
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $g4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $h4
|
||||
*/
|
||||
$h0 = $this->h[0];
|
||||
$h1 = $this->h[1];
|
||||
$h2 = $this->h[2];
|
||||
$h3 = $this->h[3];
|
||||
$h4 = $this->h[4];
|
||||
|
||||
$c = $h1->shiftRight(26); # $c = $h1 >> 26;
|
||||
$h1 = $h1->mask(0x3ffffff); # $h1 &= 0x3ffffff;
|
||||
|
||||
$h2 = $h2->addInt32($c); # $h2 += $c;
|
||||
$c = $h2->shiftRight(26); # $c = $h2 >> 26;
|
||||
$h2 = $h2->mask(0x3ffffff); # $h2 &= 0x3ffffff;
|
||||
|
||||
$h3 = $h3->addInt32($c); # $h3 += $c;
|
||||
$c = $h3->shiftRight(26); # $c = $h3 >> 26;
|
||||
$h3 = $h3->mask(0x3ffffff); # $h3 &= 0x3ffffff;
|
||||
|
||||
$h4 = $h4->addInt32($c); # $h4 += $c;
|
||||
$c = $h4->shiftRight(26); # $c = $h4 >> 26;
|
||||
$h4 = $h4->mask(0x3ffffff); # $h4 &= 0x3ffffff;
|
||||
|
||||
$h0 = $h0->addInt32($c->mulInt(5, 3)); # $h0 += self::mul($c, 5);
|
||||
$c = $h0->shiftRight(26); # $c = $h0 >> 26;
|
||||
$h0 = $h0->mask(0x3ffffff); # $h0 &= 0x3ffffff;
|
||||
$h1 = $h1->addInt32($c); # $h1 += $c;
|
||||
|
||||
/* compute h + -p */
|
||||
$g0 = $h0->addInt(5);
|
||||
$c = $g0->shiftRight(26);
|
||||
$g0 = $g0->mask(0x3ffffff);
|
||||
$g1 = $h1->addInt32($c);
|
||||
$c = $g1->shiftRight(26);
|
||||
$g1 = $g1->mask(0x3ffffff);
|
||||
$g2 = $h2->addInt32($c);
|
||||
$c = $g2->shiftRight(26);
|
||||
$g2 = $g2->mask(0x3ffffff);
|
||||
$g3 = $h3->addInt32($c);
|
||||
$c = $g3->shiftRight(26);
|
||||
$g3 = $g3->mask(0x3ffffff);
|
||||
$g4 = $h4->addInt32($c)->subInt(1 << 26);
|
||||
|
||||
# $mask = ($g4 >> 31) - 1;
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
$mask = (int) (($g4->toInt() >> 31) + 1);
|
||||
|
||||
$g0 = $g0->mask($mask);
|
||||
$g1 = $g1->mask($mask);
|
||||
$g2 = $g2->mask($mask);
|
||||
$g3 = $g3->mask($mask);
|
||||
$g4 = $g4->mask($mask);
|
||||
|
||||
/** @var int $mask */
|
||||
$mask = ~$mask;
|
||||
|
||||
$h0 = $h0->mask($mask)->orInt32($g0);
|
||||
$h1 = $h1->mask($mask)->orInt32($g1);
|
||||
$h2 = $h2->mask($mask)->orInt32($g2);
|
||||
$h3 = $h3->mask($mask)->orInt32($g3);
|
||||
$h4 = $h4->mask($mask)->orInt32($g4);
|
||||
|
||||
/* h = h % (2^128) */
|
||||
$h0 = $h0->orInt32($h1->shiftLeft(26));
|
||||
$h1 = $h1->shiftRight(6)->orInt32($h2->shiftLeft(20));
|
||||
$h2 = $h2->shiftRight(12)->orInt32($h3->shiftLeft(14));
|
||||
$h3 = $h3->shiftRight(18)->orInt32($h4->shiftLeft(8));
|
||||
|
||||
/* mac = (h + pad) % (2^128) */
|
||||
$f = $h0->toInt64()->addInt64($this->pad[0]);
|
||||
$h0 = $f->toInt32();
|
||||
$f = $h1->toInt64()->addInt64($this->pad[1])->addInt($h0->overflow);
|
||||
$h1 = $f->toInt32();
|
||||
$f = $h2->toInt64()->addInt64($this->pad[2])->addInt($h1->overflow);
|
||||
$h2 = $f->toInt32();
|
||||
$f = $h3->toInt64()->addInt64($this->pad[3])->addInt($h2->overflow);
|
||||
$h3 = $f->toInt32();
|
||||
|
||||
return $h0->toReverseString() .
|
||||
$h1->toReverseString() .
|
||||
$h2->toReverseString() .
|
||||
$h3->toReverseString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,259 +1,306 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Salsa20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Salsa20
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_Salsa20 extends ParagonIE_Sodium_Core32_Util
|
||||
{
|
||||
const ROUNDS = 20;
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Salsa20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Salsa20
|
||||
* Calculate an salsa20 hash of a single block
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $k
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_Salsa20 extends \ParagonIE_Sodium_Core32_Util
|
||||
public static function core_salsa20($in, $k, $c = null)
|
||||
{
|
||||
const ROUNDS = 20;
|
||||
/**
|
||||
* Calculate an salsa20 hash of a single block
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $k
|
||||
* @param string|null $c
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x5
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x6
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x7
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x8
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x9
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x10
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x11
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x12
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x13
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x14
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x15
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j5
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j6
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j7
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j8
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j9
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j10
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j11
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j12
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j13
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j14
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j15
|
||||
*/
|
||||
public static function core_salsa20($in, $k, $c = null)
|
||||
{
|
||||
/**
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x5
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x6
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x7
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x8
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x9
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x10
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x11
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x12
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x13
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x14
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $x15
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j0
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j1
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j2
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j3
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j4
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j5
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j6
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j7
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j8
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j9
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j10
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j11
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j12
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j13
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j14
|
||||
* @var ParagonIE_Sodium_Core32_Int32 $j15
|
||||
*/
|
||||
if (self::strlen($k) < 32) {
|
||||
throw new \RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
if ($c === null) {
|
||||
$x0 = new \ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865));
|
||||
$x5 = new \ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e));
|
||||
$x10 = new \ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32));
|
||||
$x15 = new \ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574));
|
||||
} else {
|
||||
$x0 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 0, 4));
|
||||
$x5 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 4, 4));
|
||||
$x10 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 8, 4));
|
||||
$x15 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 12, 4));
|
||||
}
|
||||
$x1 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 0, 4));
|
||||
$x2 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 4, 4));
|
||||
$x3 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 8, 4));
|
||||
$x4 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 12, 4));
|
||||
$x6 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 0, 4));
|
||||
$x7 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 4, 4));
|
||||
$x8 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 8, 4));
|
||||
$x9 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 12, 4));
|
||||
$x11 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 16, 4));
|
||||
$x12 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 20, 4));
|
||||
$x13 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 24, 4));
|
||||
$x14 = \ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 28, 4));
|
||||
$j0 = clone $x0;
|
||||
$j1 = clone $x1;
|
||||
$j2 = clone $x2;
|
||||
$j3 = clone $x3;
|
||||
$j4 = clone $x4;
|
||||
$j5 = clone $x5;
|
||||
$j6 = clone $x6;
|
||||
$j7 = clone $x7;
|
||||
$j8 = clone $x8;
|
||||
$j9 = clone $x9;
|
||||
$j10 = clone $x10;
|
||||
$j11 = clone $x11;
|
||||
$j12 = clone $x12;
|
||||
$j13 = clone $x13;
|
||||
$j14 = clone $x14;
|
||||
$j15 = clone $x15;
|
||||
for ($i = self::ROUNDS; $i > 0; $i -= 2) {
|
||||
$x4 = $x4->xorInt32($x0->addInt32($x12)->rotateLeft(7));
|
||||
$x8 = $x8->xorInt32($x4->addInt32($x0)->rotateLeft(9));
|
||||
$x12 = $x12->xorInt32($x8->addInt32($x4)->rotateLeft(13));
|
||||
$x0 = $x0->xorInt32($x12->addInt32($x8)->rotateLeft(18));
|
||||
$x9 = $x9->xorInt32($x5->addInt32($x1)->rotateLeft(7));
|
||||
$x13 = $x13->xorInt32($x9->addInt32($x5)->rotateLeft(9));
|
||||
$x1 = $x1->xorInt32($x13->addInt32($x9)->rotateLeft(13));
|
||||
$x5 = $x5->xorInt32($x1->addInt32($x13)->rotateLeft(18));
|
||||
$x14 = $x14->xorInt32($x10->addInt32($x6)->rotateLeft(7));
|
||||
$x2 = $x2->xorInt32($x14->addInt32($x10)->rotateLeft(9));
|
||||
$x6 = $x6->xorInt32($x2->addInt32($x14)->rotateLeft(13));
|
||||
$x10 = $x10->xorInt32($x6->addInt32($x2)->rotateLeft(18));
|
||||
$x3 = $x3->xorInt32($x15->addInt32($x11)->rotateLeft(7));
|
||||
$x7 = $x7->xorInt32($x3->addInt32($x15)->rotateLeft(9));
|
||||
$x11 = $x11->xorInt32($x7->addInt32($x3)->rotateLeft(13));
|
||||
$x15 = $x15->xorInt32($x11->addInt32($x7)->rotateLeft(18));
|
||||
$x1 = $x1->xorInt32($x0->addInt32($x3)->rotateLeft(7));
|
||||
$x2 = $x2->xorInt32($x1->addInt32($x0)->rotateLeft(9));
|
||||
$x3 = $x3->xorInt32($x2->addInt32($x1)->rotateLeft(13));
|
||||
$x0 = $x0->xorInt32($x3->addInt32($x2)->rotateLeft(18));
|
||||
$x6 = $x6->xorInt32($x5->addInt32($x4)->rotateLeft(7));
|
||||
$x7 = $x7->xorInt32($x6->addInt32($x5)->rotateLeft(9));
|
||||
$x4 = $x4->xorInt32($x7->addInt32($x6)->rotateLeft(13));
|
||||
$x5 = $x5->xorInt32($x4->addInt32($x7)->rotateLeft(18));
|
||||
$x11 = $x11->xorInt32($x10->addInt32($x9)->rotateLeft(7));
|
||||
$x8 = $x8->xorInt32($x11->addInt32($x10)->rotateLeft(9));
|
||||
$x9 = $x9->xorInt32($x8->addInt32($x11)->rotateLeft(13));
|
||||
$x10 = $x10->xorInt32($x9->addInt32($x8)->rotateLeft(18));
|
||||
$x12 = $x12->xorInt32($x15->addInt32($x14)->rotateLeft(7));
|
||||
$x13 = $x13->xorInt32($x12->addInt32($x15)->rotateLeft(9));
|
||||
$x14 = $x14->xorInt32($x13->addInt32($x12)->rotateLeft(13));
|
||||
$x15 = $x15->xorInt32($x14->addInt32($x13)->rotateLeft(18));
|
||||
}
|
||||
$x0 = $x0->addInt32($j0);
|
||||
$x1 = $x1->addInt32($j1);
|
||||
$x2 = $x2->addInt32($j2);
|
||||
$x3 = $x3->addInt32($j3);
|
||||
$x4 = $x4->addInt32($j4);
|
||||
$x5 = $x5->addInt32($j5);
|
||||
$x6 = $x6->addInt32($j6);
|
||||
$x7 = $x7->addInt32($j7);
|
||||
$x8 = $x8->addInt32($j8);
|
||||
$x9 = $x9->addInt32($j9);
|
||||
$x10 = $x10->addInt32($j10);
|
||||
$x11 = $x11->addInt32($j11);
|
||||
$x12 = $x12->addInt32($j12);
|
||||
$x13 = $x13->addInt32($j13);
|
||||
$x14 = $x14->addInt32($j14);
|
||||
$x15 = $x15->addInt32($j15);
|
||||
return $x0->toReverseString() . $x1->toReverseString() . $x2->toReverseString() . $x3->toReverseString() . $x4->toReverseString() . $x5->toReverseString() . $x6->toReverseString() . $x7->toReverseString() . $x8->toReverseString() . $x9->toReverseString() . $x10->toReverseString() . $x11->toReverseString() . $x12->toReverseString() . $x13->toReverseString() . $x14->toReverseString() . $x15->toReverseString();
|
||||
if (self::strlen($k) < 32) {
|
||||
throw new RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20($len, $nonce, $key)
|
||||
{
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new \RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
$kcopy = '' . $key;
|
||||
$in = self::substr($nonce, 0, 8) . \str_repeat("\x00", 8);
|
||||
$c = '';
|
||||
while ($len >= 64) {
|
||||
$c .= self::core_salsa20($in, $kcopy, null);
|
||||
$u = 1;
|
||||
// Internal counter.
|
||||
for ($i = 8; $i < 16; ++$i) {
|
||||
$u += self::chrToInt($in[$i]);
|
||||
$in[$i] = self::intToChr($u & 0xff);
|
||||
$u >>= 8;
|
||||
}
|
||||
$len -= 64;
|
||||
}
|
||||
if ($len > 0) {
|
||||
$c .= self::substr(self::core_salsa20($in, $kcopy, null), 0, $len);
|
||||
}
|
||||
try {
|
||||
\ParagonIE_Sodium_Compat::memzero($kcopy);
|
||||
} catch (\SodiumException $ex) {
|
||||
$kcopy = null;
|
||||
}
|
||||
return $c;
|
||||
if ($c === null) {
|
||||
$x0 = new ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865));
|
||||
$x5 = new ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e));
|
||||
$x10 = new ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32));
|
||||
$x15 = new ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574));
|
||||
} else {
|
||||
$x0 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 0, 4));
|
||||
$x5 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 4, 4));
|
||||
$x10 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 8, 4));
|
||||
$x15 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 12, 4));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $m
|
||||
* @param string $n
|
||||
* @param int $ic
|
||||
* @param string $k
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20_xor_ic($m, $n, $ic, $k)
|
||||
{
|
||||
$mlen = self::strlen($m);
|
||||
if ($mlen < 1) {
|
||||
return '';
|
||||
}
|
||||
$kcopy = self::substr($k, 0, 32);
|
||||
$in = self::substr($n, 0, 8);
|
||||
// Initialize the counter
|
||||
$in .= \ParagonIE_Sodium_Core32_Util::store64_le($ic);
|
||||
$c = '';
|
||||
while ($mlen >= 64) {
|
||||
$block = self::core_salsa20($in, $kcopy, null);
|
||||
$c .= self::xorStrings(self::substr($m, 0, 64), self::substr($block, 0, 64));
|
||||
$u = 1;
|
||||
for ($i = 8; $i < 16; ++$i) {
|
||||
$u += self::chrToInt($in[$i]);
|
||||
$in[$i] = self::intToChr($u & 0xff);
|
||||
$u >>= 8;
|
||||
}
|
||||
$mlen -= 64;
|
||||
$m = self::substr($m, 64);
|
||||
}
|
||||
if ($mlen) {
|
||||
$block = self::core_salsa20($in, $kcopy, null);
|
||||
$c .= self::xorStrings(self::substr($m, 0, $mlen), self::substr($block, 0, $mlen));
|
||||
}
|
||||
try {
|
||||
\ParagonIE_Sodium_Compat::memzero($block);
|
||||
\ParagonIE_Sodium_Compat::memzero($kcopy);
|
||||
} catch (\SodiumException $ex) {
|
||||
$block = null;
|
||||
$kcopy = null;
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20_xor($message, $nonce, $key)
|
||||
{
|
||||
return self::xorStrings($message, self::salsa20(self::strlen($message), $nonce, $key));
|
||||
$x1 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 0, 4));
|
||||
$x2 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 4, 4));
|
||||
$x3 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 8, 4));
|
||||
$x4 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 12, 4));
|
||||
$x6 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 0, 4));
|
||||
$x7 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 4, 4));
|
||||
$x8 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 8, 4));
|
||||
$x9 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 12, 4));
|
||||
$x11 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 16, 4));
|
||||
$x12 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 20, 4));
|
||||
$x13 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 24, 4));
|
||||
$x14 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 28, 4));
|
||||
|
||||
$j0 = clone $x0;
|
||||
$j1 = clone $x1;
|
||||
$j2 = clone $x2;
|
||||
$j3 = clone $x3;
|
||||
$j4 = clone $x4;
|
||||
$j5 = clone $x5;
|
||||
$j6 = clone $x6;
|
||||
$j7 = clone $x7;
|
||||
$j8 = clone $x8;
|
||||
$j9 = clone $x9;
|
||||
$j10 = clone $x10;
|
||||
$j11 = clone $x11;
|
||||
$j12 = clone $x12;
|
||||
$j13 = clone $x13;
|
||||
$j14 = clone $x14;
|
||||
$j15 = clone $x15;
|
||||
|
||||
for ($i = self::ROUNDS; $i > 0; $i -= 2) {
|
||||
$x4 = $x4->xorInt32($x0->addInt32($x12)->rotateLeft(7));
|
||||
$x8 = $x8->xorInt32($x4->addInt32($x0)->rotateLeft(9));
|
||||
$x12 = $x12->xorInt32($x8->addInt32($x4)->rotateLeft(13));
|
||||
$x0 = $x0->xorInt32($x12->addInt32($x8)->rotateLeft(18));
|
||||
|
||||
$x9 = $x9->xorInt32($x5->addInt32($x1)->rotateLeft(7));
|
||||
$x13 = $x13->xorInt32($x9->addInt32($x5)->rotateLeft(9));
|
||||
$x1 = $x1->xorInt32($x13->addInt32($x9)->rotateLeft(13));
|
||||
$x5 = $x5->xorInt32($x1->addInt32($x13)->rotateLeft(18));
|
||||
|
||||
$x14 = $x14->xorInt32($x10->addInt32($x6)->rotateLeft(7));
|
||||
$x2 = $x2->xorInt32($x14->addInt32($x10)->rotateLeft(9));
|
||||
$x6 = $x6->xorInt32($x2->addInt32($x14)->rotateLeft(13));
|
||||
$x10 = $x10->xorInt32($x6->addInt32($x2)->rotateLeft(18));
|
||||
|
||||
$x3 = $x3->xorInt32($x15->addInt32($x11)->rotateLeft(7));
|
||||
$x7 = $x7->xorInt32($x3->addInt32($x15)->rotateLeft(9));
|
||||
$x11 = $x11->xorInt32($x7->addInt32($x3)->rotateLeft(13));
|
||||
$x15 = $x15->xorInt32($x11->addInt32($x7)->rotateLeft(18));
|
||||
|
||||
$x1 = $x1->xorInt32($x0->addInt32($x3)->rotateLeft(7));
|
||||
$x2 = $x2->xorInt32($x1->addInt32($x0)->rotateLeft(9));
|
||||
$x3 = $x3->xorInt32($x2->addInt32($x1)->rotateLeft(13));
|
||||
$x0 = $x0->xorInt32($x3->addInt32($x2)->rotateLeft(18));
|
||||
|
||||
$x6 = $x6->xorInt32($x5->addInt32($x4)->rotateLeft(7));
|
||||
$x7 = $x7->xorInt32($x6->addInt32($x5)->rotateLeft(9));
|
||||
$x4 = $x4->xorInt32($x7->addInt32($x6)->rotateLeft(13));
|
||||
$x5 = $x5->xorInt32($x4->addInt32($x7)->rotateLeft(18));
|
||||
|
||||
$x11 = $x11->xorInt32($x10->addInt32($x9)->rotateLeft(7));
|
||||
$x8 = $x8->xorInt32($x11->addInt32($x10)->rotateLeft(9));
|
||||
$x9 = $x9->xorInt32($x8->addInt32($x11)->rotateLeft(13));
|
||||
$x10 = $x10->xorInt32($x9->addInt32($x8)->rotateLeft(18));
|
||||
|
||||
$x12 = $x12->xorInt32($x15->addInt32($x14)->rotateLeft(7));
|
||||
$x13 = $x13->xorInt32($x12->addInt32($x15)->rotateLeft(9));
|
||||
$x14 = $x14->xorInt32($x13->addInt32($x12)->rotateLeft(13));
|
||||
$x15 = $x15->xorInt32($x14->addInt32($x13)->rotateLeft(18));
|
||||
}
|
||||
|
||||
$x0 = $x0->addInt32($j0);
|
||||
$x1 = $x1->addInt32($j1);
|
||||
$x2 = $x2->addInt32($j2);
|
||||
$x3 = $x3->addInt32($j3);
|
||||
$x4 = $x4->addInt32($j4);
|
||||
$x5 = $x5->addInt32($j5);
|
||||
$x6 = $x6->addInt32($j6);
|
||||
$x7 = $x7->addInt32($j7);
|
||||
$x8 = $x8->addInt32($j8);
|
||||
$x9 = $x9->addInt32($j9);
|
||||
$x10 = $x10->addInt32($j10);
|
||||
$x11 = $x11->addInt32($j11);
|
||||
$x12 = $x12->addInt32($j12);
|
||||
$x13 = $x13->addInt32($j13);
|
||||
$x14 = $x14->addInt32($j14);
|
||||
$x15 = $x15->addInt32($j15);
|
||||
|
||||
return $x0->toReverseString() .
|
||||
$x1->toReverseString() .
|
||||
$x2->toReverseString() .
|
||||
$x3->toReverseString() .
|
||||
$x4->toReverseString() .
|
||||
$x5->toReverseString() .
|
||||
$x6->toReverseString() .
|
||||
$x7->toReverseString() .
|
||||
$x8->toReverseString() .
|
||||
$x9->toReverseString() .
|
||||
$x10->toReverseString() .
|
||||
$x11->toReverseString() .
|
||||
$x12->toReverseString() .
|
||||
$x13->toReverseString() .
|
||||
$x14->toReverseString() .
|
||||
$x15->toReverseString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_Salsa20
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function salsa20($len, $nonce, $key)
|
||||
{
|
||||
if (self::strlen($key) !== 32) {
|
||||
throw new RangeException('Key must be 32 bytes long');
|
||||
}
|
||||
$kcopy = '' . $key;
|
||||
$in = self::substr($nonce, 0, 8) . str_repeat("\0", 8);
|
||||
$c = '';
|
||||
while ($len >= 64) {
|
||||
$c .= self::core_salsa20($in, $kcopy, null);
|
||||
$u = 1;
|
||||
// Internal counter.
|
||||
for ($i = 8; $i < 16; ++$i) {
|
||||
$u += self::chrToInt($in[$i]);
|
||||
$in[$i] = self::intToChr($u & 0xff);
|
||||
$u >>= 8;
|
||||
}
|
||||
$len -= 64;
|
||||
}
|
||||
if ($len > 0) {
|
||||
$c .= self::substr(
|
||||
self::core_salsa20($in, $kcopy, null),
|
||||
0,
|
||||
$len
|
||||
);
|
||||
}
|
||||
try {
|
||||
ParagonIE_Sodium_Compat::memzero($kcopy);
|
||||
} catch (SodiumException $ex) {
|
||||
$kcopy = null;
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $m
|
||||
* @param string $n
|
||||
* @param int $ic
|
||||
* @param string $k
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20_xor_ic($m, $n, $ic, $k)
|
||||
{
|
||||
$mlen = self::strlen($m);
|
||||
if ($mlen < 1) {
|
||||
return '';
|
||||
}
|
||||
$kcopy = self::substr($k, 0, 32);
|
||||
$in = self::substr($n, 0, 8);
|
||||
// Initialize the counter
|
||||
$in .= ParagonIE_Sodium_Core32_Util::store64_le($ic);
|
||||
|
||||
$c = '';
|
||||
while ($mlen >= 64) {
|
||||
$block = self::core_salsa20($in, $kcopy, null);
|
||||
$c .= self::xorStrings(
|
||||
self::substr($m, 0, 64),
|
||||
self::substr($block, 0, 64)
|
||||
);
|
||||
$u = 1;
|
||||
for ($i = 8; $i < 16; ++$i) {
|
||||
$u += self::chrToInt($in[$i]);
|
||||
$in[$i] = self::intToChr($u & 0xff);
|
||||
$u >>= 8;
|
||||
}
|
||||
|
||||
$mlen -= 64;
|
||||
$m = self::substr($m, 64);
|
||||
}
|
||||
|
||||
if ($mlen) {
|
||||
$block = self::core_salsa20($in, $kcopy, null);
|
||||
$c .= self::xorStrings(
|
||||
self::substr($m, 0, $mlen),
|
||||
self::substr($block, 0, $mlen)
|
||||
);
|
||||
}
|
||||
try {
|
||||
ParagonIE_Sodium_Compat::memzero($block);
|
||||
ParagonIE_Sodium_Compat::memzero($kcopy);
|
||||
} catch (SodiumException $ex) {
|
||||
$block = null;
|
||||
$kcopy = null;
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function salsa20_xor($message, $nonce, $key)
|
||||
{
|
||||
return self::xorStrings(
|
||||
$message,
|
||||
self::salsa20(
|
||||
self::strlen($message),
|
||||
$nonce,
|
||||
$key
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,132 +1,163 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_SecretStream_State
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_SecretStream_State
|
||||
{
|
||||
/** @var string $key */
|
||||
protected $key;
|
||||
|
||||
/** @var int $counter */
|
||||
protected $counter;
|
||||
|
||||
/** @var string $nonce */
|
||||
protected $nonce;
|
||||
|
||||
/** @var string $_pad */
|
||||
protected $_pad;
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_SecretStream_State
|
||||
* ParagonIE_Sodium_Core32_SecretStream_State constructor.
|
||||
* @param string $key
|
||||
* @param string|null $nonce
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_SecretStream_State
|
||||
public function __construct($key, $nonce = null)
|
||||
{
|
||||
/** @var string $key */
|
||||
protected $key;
|
||||
/** @var int $counter */
|
||||
protected $counter;
|
||||
/** @var string $nonce */
|
||||
protected $nonce;
|
||||
/** @var string $_pad */
|
||||
protected $_pad;
|
||||
/**
|
||||
* ParagonIE_Sodium_Core32_SecretStream_State constructor.
|
||||
* @param string $key
|
||||
* @param string|null $nonce
|
||||
*/
|
||||
public function __construct($key, $nonce = null)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->counter = 1;
|
||||
if (\is_null($nonce)) {
|
||||
$nonce = \str_repeat("\x00", 12);
|
||||
}
|
||||
$this->nonce = \str_pad($nonce, 12, "\x00", \STR_PAD_RIGHT);
|
||||
$this->_pad = \str_repeat("\x00", 4);
|
||||
}
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function counterReset()
|
||||
{
|
||||
$this->counter = 1;
|
||||
$this->_pad = \str_repeat("\x00", 4);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCounter()
|
||||
{
|
||||
return \ParagonIE_Sodium_Core32_Util::store32_le($this->counter);
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNonce()
|
||||
{
|
||||
if (!\is_string($this->nonce)) {
|
||||
$this->nonce = \str_repeat("\x00", 12);
|
||||
}
|
||||
if (\ParagonIE_Sodium_Core32_Util::strlen($this->nonce) !== 12) {
|
||||
$this->nonce = \str_pad($this->nonce, 12, "\x00", \STR_PAD_RIGHT);
|
||||
}
|
||||
return $this->nonce;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCombinedNonce()
|
||||
{
|
||||
return $this->getCounter() . \ParagonIE_Sodium_Core32_Util::substr($this->getNonce(), 0, 8);
|
||||
}
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function incrementCounter()
|
||||
{
|
||||
++$this->counter;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function needsRekey()
|
||||
{
|
||||
return ($this->counter & 0xffff) === 0;
|
||||
}
|
||||
/**
|
||||
* @param string $newKeyAndNonce
|
||||
* @return self
|
||||
*/
|
||||
public function rekey($newKeyAndNonce)
|
||||
{
|
||||
$this->key = \ParagonIE_Sodium_Core32_Util::substr($newKeyAndNonce, 0, 32);
|
||||
$this->nonce = \str_pad(\ParagonIE_Sodium_Core32_Util::substr($newKeyAndNonce, 32), 12, "\x00", \STR_PAD_RIGHT);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @param string $str
|
||||
* @return self
|
||||
*/
|
||||
public function xorNonce($str)
|
||||
{
|
||||
$this->nonce = \ParagonIE_Sodium_Core32_Util::xorStrings($this->getNonce(), \str_pad(\ParagonIE_Sodium_Core32_Util::substr($str, 0, 8), 12, "\x00", \STR_PAD_RIGHT));
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
* @return self
|
||||
*/
|
||||
public static function fromString($string)
|
||||
{
|
||||
$state = new \ParagonIE_Sodium_Core32_SecretStream_State(\ParagonIE_Sodium_Core32_Util::substr($string, 0, 32));
|
||||
$state->counter = \ParagonIE_Sodium_Core32_Util::load_4(\ParagonIE_Sodium_Core32_Util::substr($string, 32, 4));
|
||||
$state->nonce = \ParagonIE_Sodium_Core32_Util::substr($string, 36, 12);
|
||||
$state->_pad = \ParagonIE_Sodium_Core32_Util::substr($string, 48, 8);
|
||||
return $state;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->key . $this->getCounter() . $this->nonce . $this->_pad;
|
||||
$this->key = $key;
|
||||
$this->counter = 1;
|
||||
if (is_null($nonce)) {
|
||||
$nonce = str_repeat("\0", 12);
|
||||
}
|
||||
$this->nonce = str_pad($nonce, 12, "\0", STR_PAD_RIGHT);;
|
||||
$this->_pad = str_repeat("\0", 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_SecretStream_State
|
||||
* @return self
|
||||
*/
|
||||
|
||||
public function counterReset()
|
||||
{
|
||||
$this->counter = 1;
|
||||
$this->_pad = str_repeat("\0", 4);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCounter()
|
||||
{
|
||||
return ParagonIE_Sodium_Core32_Util::store32_le($this->counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNonce()
|
||||
{
|
||||
if (!is_string($this->nonce)) {
|
||||
$this->nonce = str_repeat("\0", 12);
|
||||
}
|
||||
if (ParagonIE_Sodium_Core32_Util::strlen($this->nonce) !== 12) {
|
||||
$this->nonce = str_pad($this->nonce, 12, "\0", STR_PAD_RIGHT);
|
||||
}
|
||||
return $this->nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCombinedNonce()
|
||||
{
|
||||
return $this->getCounter() .
|
||||
ParagonIE_Sodium_Core32_Util::substr($this->getNonce(), 0, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function incrementCounter()
|
||||
{
|
||||
++$this->counter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function needsRekey()
|
||||
{
|
||||
return ($this->counter & 0xffff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $newKeyAndNonce
|
||||
* @return self
|
||||
*/
|
||||
public function rekey($newKeyAndNonce)
|
||||
{
|
||||
$this->key = ParagonIE_Sodium_Core32_Util::substr($newKeyAndNonce, 0, 32);
|
||||
$this->nonce = str_pad(
|
||||
ParagonIE_Sodium_Core32_Util::substr($newKeyAndNonce, 32),
|
||||
12,
|
||||
"\0",
|
||||
STR_PAD_RIGHT
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @return self
|
||||
*/
|
||||
public function xorNonce($str)
|
||||
{
|
||||
$this->nonce = ParagonIE_Sodium_Core32_Util::xorStrings(
|
||||
$this->getNonce(),
|
||||
str_pad(
|
||||
ParagonIE_Sodium_Core32_Util::substr($str, 0, 8),
|
||||
12,
|
||||
"\0",
|
||||
STR_PAD_RIGHT
|
||||
)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return self
|
||||
*/
|
||||
public static function fromString($string)
|
||||
{
|
||||
$state = new ParagonIE_Sodium_Core32_SecretStream_State(
|
||||
ParagonIE_Sodium_Core32_Util::substr($string, 0, 32)
|
||||
);
|
||||
$state->counter = ParagonIE_Sodium_Core32_Util::load_4(
|
||||
ParagonIE_Sodium_Core32_Util::substr($string, 32, 4)
|
||||
);
|
||||
$state->nonce = ParagonIE_Sodium_Core32_Util::substr($string, 36, 12);
|
||||
$state->_pad = ParagonIE_Sodium_Core32_Util::substr($string, 48, 8);
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->key .
|
||||
$this->getCounter() .
|
||||
$this->nonce .
|
||||
$this->_pad;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,157 +1,238 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_SipHash', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_SipHash', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_SodiumCompat_Core32_SipHash
|
||||
*
|
||||
* Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_SipHash extends ParagonIE_Sodium_Core32_Util
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_SodiumCompat_Core32_SipHash
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
|
||||
* @param array<int, ParagonIE_Sodium_Core32_Int64> $v
|
||||
* @return array<int, ParagonIE_Sodium_Core32_Int64>
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_SipHash extends \ParagonIE_Sodium_Core32_Util
|
||||
public static function sipRound(array $v)
|
||||
{
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param array<int, ParagonIE_Sodium_Core32_Int64> $v
|
||||
* @return array<int, ParagonIE_Sodium_Core32_Int64>
|
||||
*/
|
||||
public static function sipRound(array $v)
|
||||
{
|
||||
# v0 += v1;
|
||||
$v[0] = $v[0]->addInt64($v[1]);
|
||||
# v1 = ROTL(v1, 13);
|
||||
$v[1] = $v[1]->rotateLeft(13);
|
||||
# v1 ^= v0;
|
||||
$v[1] = $v[1]->xorInt64($v[0]);
|
||||
# v0=ROTL(v0,32);
|
||||
$v[0] = $v[0]->rotateLeft(32);
|
||||
# v2 += v3;
|
||||
$v[2] = $v[2]->addInt64($v[3]);
|
||||
# v3=ROTL(v3,16);
|
||||
$v[3] = $v[3]->rotateLeft(16);
|
||||
# v3 ^= v2;
|
||||
$v[3] = $v[3]->xorInt64($v[2]);
|
||||
# v0 += v3;
|
||||
$v[0] = $v[0]->addInt64($v[3]);
|
||||
# v3=ROTL(v3,21);
|
||||
$v[3] = $v[3]->rotateLeft(21);
|
||||
# v3 ^= v0;
|
||||
$v[3] = $v[3]->xorInt64($v[0]);
|
||||
# v2 += v1;
|
||||
$v[2] = $v[2]->addInt64($v[1]);
|
||||
# v1=ROTL(v1,17);
|
||||
$v[1] = $v[1]->rotateLeft(17);
|
||||
# v1 ^= v2;
|
||||
$v[1] = $v[1]->xorInt64($v[2]);
|
||||
# v2=ROTL(v2,32)
|
||||
$v[2] = $v[2]->rotateLeft(32);
|
||||
return $v;
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $in
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function sipHash24($in, $key)
|
||||
{
|
||||
$inlen = self::strlen($in);
|
||||
# /* "somepseudorandomlygeneratedbytes" */
|
||||
# u64 v0 = 0x736f6d6570736575ULL;
|
||||
# u64 v1 = 0x646f72616e646f6dULL;
|
||||
# u64 v2 = 0x6c7967656e657261ULL;
|
||||
# u64 v3 = 0x7465646279746573ULL;
|
||||
$v = array(new \ParagonIE_Sodium_Core32_Int64(array(0x736f, 0x6d65, 0x7073, 0x6575)), new \ParagonIE_Sodium_Core32_Int64(array(0x646f, 0x7261, 0x6e64, 0x6f6d)), new \ParagonIE_Sodium_Core32_Int64(array(0x6c79, 0x6765, 0x6e65, 0x7261)), new \ParagonIE_Sodium_Core32_Int64(array(0x7465, 0x6462, 0x7974, 0x6573)));
|
||||
# u64 k0 = LOAD64_LE( k );
|
||||
# u64 k1 = LOAD64_LE( k + 8 );
|
||||
$k = array(\ParagonIE_Sodium_Core32_Int64::fromReverseString(self::substr($key, 0, 8)), \ParagonIE_Sodium_Core32_Int64::fromReverseString(self::substr($key, 8, 8)));
|
||||
# b = ( ( u64 )inlen ) << 56;
|
||||
$b = new \ParagonIE_Sodium_Core32_Int64(array($inlen << 8 & 0xffff, 0, 0, 0));
|
||||
# v3 ^= k1;
|
||||
$v[3] = $v[3]->xorInt64($k[1]);
|
||||
# v2 ^= k0;
|
||||
$v[2] = $v[2]->xorInt64($k[0]);
|
||||
# v1 ^= k1;
|
||||
$v[1] = $v[1]->xorInt64($k[1]);
|
||||
# v0 ^= k0;
|
||||
$v[0] = $v[0]->xorInt64($k[0]);
|
||||
$left = $inlen;
|
||||
# for ( ; in != end; in += 8 )
|
||||
while ($left >= 8) {
|
||||
# m = LOAD64_LE( in );
|
||||
$m = \ParagonIE_Sodium_Core32_Int64::fromReverseString(self::substr($in, 0, 8));
|
||||
# v3 ^= m;
|
||||
$v[3] = $v[3]->xorInt64($m);
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
# v0 ^= m;
|
||||
$v[0] = $v[0]->xorInt64($m);
|
||||
$in = self::substr($in, 8);
|
||||
$left -= 8;
|
||||
}
|
||||
# switch( left )
|
||||
# {
|
||||
# case 7: b |= ( ( u64 )in[ 6] ) << 48;
|
||||
# case 6: b |= ( ( u64 )in[ 5] ) << 40;
|
||||
# case 5: b |= ( ( u64 )in[ 4] ) << 32;
|
||||
# case 4: b |= ( ( u64 )in[ 3] ) << 24;
|
||||
# case 3: b |= ( ( u64 )in[ 2] ) << 16;
|
||||
# case 2: b |= ( ( u64 )in[ 1] ) << 8;
|
||||
# case 1: b |= ( ( u64 )in[ 0] ); break;
|
||||
# case 0: break;
|
||||
# }
|
||||
switch ($left) {
|
||||
case 7:
|
||||
$b = $b->orInt64(\ParagonIE_Sodium_Core32_Int64::fromInts(0, self::chrToInt($in[6]) << 16));
|
||||
case 6:
|
||||
$b = $b->orInt64(\ParagonIE_Sodium_Core32_Int64::fromInts(0, self::chrToInt($in[5]) << 8));
|
||||
case 5:
|
||||
$b = $b->orInt64(\ParagonIE_Sodium_Core32_Int64::fromInts(0, self::chrToInt($in[4])));
|
||||
case 4:
|
||||
$b = $b->orInt64(\ParagonIE_Sodium_Core32_Int64::fromInts(self::chrToInt($in[3]) << 24, 0));
|
||||
case 3:
|
||||
$b = $b->orInt64(\ParagonIE_Sodium_Core32_Int64::fromInts(self::chrToInt($in[2]) << 16, 0));
|
||||
case 2:
|
||||
$b = $b->orInt64(\ParagonIE_Sodium_Core32_Int64::fromInts(self::chrToInt($in[1]) << 8, 0));
|
||||
case 1:
|
||||
$b = $b->orInt64(\ParagonIE_Sodium_Core32_Int64::fromInts(self::chrToInt($in[0]), 0));
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
# v3 ^= b;
|
||||
$v[3] = $v[3]->xorInt64($b);
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
# v0 ^= b;
|
||||
$v[0] = $v[0]->xorInt64($b);
|
||||
// Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation
|
||||
# v2 ^= 0xff;
|
||||
$v[2]->limbs[3] ^= 0xff;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
# b = v0 ^ v1 ^ v2 ^ v3;
|
||||
# STORE64_LE( out, b );
|
||||
return $v[0]->xorInt64($v[1])->xorInt64($v[2])->xorInt64($v[3])->toReverseString();
|
||||
}
|
||||
# v0 += v1;
|
||||
$v[0] = $v[0]->addInt64($v[1]);
|
||||
|
||||
# v1 = ROTL(v1, 13);
|
||||
$v[1] = $v[1]->rotateLeft(13);
|
||||
|
||||
# v1 ^= v0;
|
||||
$v[1] = $v[1]->xorInt64($v[0]);
|
||||
|
||||
# v0=ROTL(v0,32);
|
||||
$v[0] = $v[0]->rotateLeft(32);
|
||||
|
||||
# v2 += v3;
|
||||
$v[2] = $v[2]->addInt64($v[3]);
|
||||
|
||||
# v3=ROTL(v3,16);
|
||||
$v[3] = $v[3]->rotateLeft(16);
|
||||
|
||||
# v3 ^= v2;
|
||||
$v[3] = $v[3]->xorInt64($v[2]);
|
||||
|
||||
# v0 += v3;
|
||||
$v[0] = $v[0]->addInt64($v[3]);
|
||||
|
||||
# v3=ROTL(v3,21);
|
||||
$v[3] = $v[3]->rotateLeft(21);
|
||||
|
||||
# v3 ^= v0;
|
||||
$v[3] = $v[3]->xorInt64($v[0]);
|
||||
|
||||
# v2 += v1;
|
||||
$v[2] = $v[2]->addInt64($v[1]);
|
||||
|
||||
# v1=ROTL(v1,17);
|
||||
$v[1] = $v[1]->rotateLeft(17);
|
||||
|
||||
# v1 ^= v2;
|
||||
$v[1] = $v[1]->xorInt64($v[2]);
|
||||
|
||||
# v2=ROTL(v2,32)
|
||||
$v[2] = $v[2]->rotateLeft(32);
|
||||
|
||||
return $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_SodiumCompat_Core32_SipHash
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers
|
||||
* @param string $in
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function sipHash24($in, $key)
|
||||
{
|
||||
$inlen = self::strlen($in);
|
||||
|
||||
# /* "somepseudorandomlygeneratedbytes" */
|
||||
# u64 v0 = 0x736f6d6570736575ULL;
|
||||
# u64 v1 = 0x646f72616e646f6dULL;
|
||||
# u64 v2 = 0x6c7967656e657261ULL;
|
||||
# u64 v3 = 0x7465646279746573ULL;
|
||||
$v = array(
|
||||
new ParagonIE_Sodium_Core32_Int64(
|
||||
array(0x736f, 0x6d65, 0x7073, 0x6575)
|
||||
),
|
||||
new ParagonIE_Sodium_Core32_Int64(
|
||||
array(0x646f, 0x7261, 0x6e64, 0x6f6d)
|
||||
),
|
||||
new ParagonIE_Sodium_Core32_Int64(
|
||||
array(0x6c79, 0x6765, 0x6e65, 0x7261)
|
||||
),
|
||||
new ParagonIE_Sodium_Core32_Int64(
|
||||
array(0x7465, 0x6462, 0x7974, 0x6573)
|
||||
)
|
||||
);
|
||||
|
||||
# u64 k0 = LOAD64_LE( k );
|
||||
# u64 k1 = LOAD64_LE( k + 8 );
|
||||
$k = array(
|
||||
ParagonIE_Sodium_Core32_Int64::fromReverseString(
|
||||
self::substr($key, 0, 8)
|
||||
),
|
||||
ParagonIE_Sodium_Core32_Int64::fromReverseString(
|
||||
self::substr($key, 8, 8)
|
||||
)
|
||||
);
|
||||
|
||||
# b = ( ( u64 )inlen ) << 56;
|
||||
$b = new ParagonIE_Sodium_Core32_Int64(
|
||||
array(($inlen << 8) & 0xffff, 0, 0, 0)
|
||||
);
|
||||
|
||||
# v3 ^= k1;
|
||||
$v[3] = $v[3]->xorInt64($k[1]);
|
||||
# v2 ^= k0;
|
||||
$v[2] = $v[2]->xorInt64($k[0]);
|
||||
# v1 ^= k1;
|
||||
$v[1] = $v[1]->xorInt64($k[1]);
|
||||
# v0 ^= k0;
|
||||
$v[0] = $v[0]->xorInt64($k[0]);
|
||||
|
||||
$left = $inlen;
|
||||
# for ( ; in != end; in += 8 )
|
||||
while ($left >= 8) {
|
||||
# m = LOAD64_LE( in );
|
||||
$m = ParagonIE_Sodium_Core32_Int64::fromReverseString(
|
||||
self::substr($in, 0, 8)
|
||||
);
|
||||
|
||||
# v3 ^= m;
|
||||
$v[3] = $v[3]->xorInt64($m);
|
||||
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
|
||||
# v0 ^= m;
|
||||
$v[0] = $v[0]->xorInt64($m);
|
||||
|
||||
$in = self::substr($in, 8);
|
||||
$left -= 8;
|
||||
}
|
||||
|
||||
# switch( left )
|
||||
# {
|
||||
# case 7: b |= ( ( u64 )in[ 6] ) << 48;
|
||||
# case 6: b |= ( ( u64 )in[ 5] ) << 40;
|
||||
# case 5: b |= ( ( u64 )in[ 4] ) << 32;
|
||||
# case 4: b |= ( ( u64 )in[ 3] ) << 24;
|
||||
# case 3: b |= ( ( u64 )in[ 2] ) << 16;
|
||||
# case 2: b |= ( ( u64 )in[ 1] ) << 8;
|
||||
# case 1: b |= ( ( u64 )in[ 0] ); break;
|
||||
# case 0: break;
|
||||
# }
|
||||
switch ($left) {
|
||||
case 7:
|
||||
$b = $b->orInt64(
|
||||
ParagonIE_Sodium_Core32_Int64::fromInts(
|
||||
0, self::chrToInt($in[6]) << 16
|
||||
)
|
||||
);
|
||||
case 6:
|
||||
$b = $b->orInt64(
|
||||
ParagonIE_Sodium_Core32_Int64::fromInts(
|
||||
0, self::chrToInt($in[5]) << 8
|
||||
)
|
||||
);
|
||||
case 5:
|
||||
$b = $b->orInt64(
|
||||
ParagonIE_Sodium_Core32_Int64::fromInts(
|
||||
0, self::chrToInt($in[4])
|
||||
)
|
||||
);
|
||||
case 4:
|
||||
$b = $b->orInt64(
|
||||
ParagonIE_Sodium_Core32_Int64::fromInts(
|
||||
self::chrToInt($in[3]) << 24, 0
|
||||
)
|
||||
);
|
||||
case 3:
|
||||
$b = $b->orInt64(
|
||||
ParagonIE_Sodium_Core32_Int64::fromInts(
|
||||
self::chrToInt($in[2]) << 16, 0
|
||||
)
|
||||
);
|
||||
case 2:
|
||||
$b = $b->orInt64(
|
||||
ParagonIE_Sodium_Core32_Int64::fromInts(
|
||||
self::chrToInt($in[1]) << 8, 0
|
||||
)
|
||||
);
|
||||
case 1:
|
||||
$b = $b->orInt64(
|
||||
ParagonIE_Sodium_Core32_Int64::fromInts(
|
||||
self::chrToInt($in[0]), 0
|
||||
)
|
||||
);
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
# v3 ^= b;
|
||||
$v[3] = $v[3]->xorInt64($b);
|
||||
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
|
||||
# v0 ^= b;
|
||||
$v[0] = $v[0]->xorInt64($b);
|
||||
|
||||
// Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation
|
||||
# v2 ^= 0xff;
|
||||
$v[2]->limbs[3] ^= 0xff;
|
||||
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
# SIPROUND;
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
$v = self::sipRound($v);
|
||||
|
||||
# b = v0 ^ v1 ^ v2 ^ v3;
|
||||
# STORE64_LE( out, b );
|
||||
return $v[0]
|
||||
->xorInt64($v[1])
|
||||
->xorInt64($v[2])
|
||||
->xorInt64($v[3])
|
||||
->toReverseString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_Util', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_Util', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Util
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_Util extends \ParagonIE_Sodium_Core_Util
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Util
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core_Util
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_Util extends ParagonIE_Sodium_Core_Util
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,284 +1,345 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_X25519', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_X25519', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_X25519
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_X25519 extends ParagonIE_Sodium_Core32_Curve25519
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_X25519
|
||||
* Alters the objects passed to this method in place.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
|
||||
* @param int $b
|
||||
* @return void
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress MixedMethodCall
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_X25519 extends \ParagonIE_Sodium_Core32_Curve25519
|
||||
public static function fe_cswap(
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $f,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $g,
|
||||
$b = 0
|
||||
) {
|
||||
$f0 = (int) $f[0]->toInt();
|
||||
$f1 = (int) $f[1]->toInt();
|
||||
$f2 = (int) $f[2]->toInt();
|
||||
$f3 = (int) $f[3]->toInt();
|
||||
$f4 = (int) $f[4]->toInt();
|
||||
$f5 = (int) $f[5]->toInt();
|
||||
$f6 = (int) $f[6]->toInt();
|
||||
$f7 = (int) $f[7]->toInt();
|
||||
$f8 = (int) $f[8]->toInt();
|
||||
$f9 = (int) $f[9]->toInt();
|
||||
$g0 = (int) $g[0]->toInt();
|
||||
$g1 = (int) $g[1]->toInt();
|
||||
$g2 = (int) $g[2]->toInt();
|
||||
$g3 = (int) $g[3]->toInt();
|
||||
$g4 = (int) $g[4]->toInt();
|
||||
$g5 = (int) $g[5]->toInt();
|
||||
$g6 = (int) $g[6]->toInt();
|
||||
$g7 = (int) $g[7]->toInt();
|
||||
$g8 = (int) $g[8]->toInt();
|
||||
$g9 = (int) $g[9]->toInt();
|
||||
$b = -$b;
|
||||
/** @var int $x0 */
|
||||
$x0 = ($f0 ^ $g0) & $b;
|
||||
/** @var int $x1 */
|
||||
$x1 = ($f1 ^ $g1) & $b;
|
||||
/** @var int $x2 */
|
||||
$x2 = ($f2 ^ $g2) & $b;
|
||||
/** @var int $x3 */
|
||||
$x3 = ($f3 ^ $g3) & $b;
|
||||
/** @var int $x4 */
|
||||
$x4 = ($f4 ^ $g4) & $b;
|
||||
/** @var int $x5 */
|
||||
$x5 = ($f5 ^ $g5) & $b;
|
||||
/** @var int $x6 */
|
||||
$x6 = ($f6 ^ $g6) & $b;
|
||||
/** @var int $x7 */
|
||||
$x7 = ($f7 ^ $g7) & $b;
|
||||
/** @var int $x8 */
|
||||
$x8 = ($f8 ^ $g8) & $b;
|
||||
/** @var int $x9 */
|
||||
$x9 = ($f9 ^ $g9) & $b;
|
||||
$f[0] = ParagonIE_Sodium_Core32_Int32::fromInt($f0 ^ $x0);
|
||||
$f[1] = ParagonIE_Sodium_Core32_Int32::fromInt($f1 ^ $x1);
|
||||
$f[2] = ParagonIE_Sodium_Core32_Int32::fromInt($f2 ^ $x2);
|
||||
$f[3] = ParagonIE_Sodium_Core32_Int32::fromInt($f3 ^ $x3);
|
||||
$f[4] = ParagonIE_Sodium_Core32_Int32::fromInt($f4 ^ $x4);
|
||||
$f[5] = ParagonIE_Sodium_Core32_Int32::fromInt($f5 ^ $x5);
|
||||
$f[6] = ParagonIE_Sodium_Core32_Int32::fromInt($f6 ^ $x6);
|
||||
$f[7] = ParagonIE_Sodium_Core32_Int32::fromInt($f7 ^ $x7);
|
||||
$f[8] = ParagonIE_Sodium_Core32_Int32::fromInt($f8 ^ $x8);
|
||||
$f[9] = ParagonIE_Sodium_Core32_Int32::fromInt($f9 ^ $x9);
|
||||
$g[0] = ParagonIE_Sodium_Core32_Int32::fromInt($g0 ^ $x0);
|
||||
$g[1] = ParagonIE_Sodium_Core32_Int32::fromInt($g1 ^ $x1);
|
||||
$g[2] = ParagonIE_Sodium_Core32_Int32::fromInt($g2 ^ $x2);
|
||||
$g[3] = ParagonIE_Sodium_Core32_Int32::fromInt($g3 ^ $x3);
|
||||
$g[4] = ParagonIE_Sodium_Core32_Int32::fromInt($g4 ^ $x4);
|
||||
$g[5] = ParagonIE_Sodium_Core32_Int32::fromInt($g5 ^ $x5);
|
||||
$g[6] = ParagonIE_Sodium_Core32_Int32::fromInt($g6 ^ $x6);
|
||||
$g[7] = ParagonIE_Sodium_Core32_Int32::fromInt($g7 ^ $x7);
|
||||
$g[8] = ParagonIE_Sodium_Core32_Int32::fromInt($g8 ^ $x8);
|
||||
$g[9] = ParagonIE_Sodium_Core32_Int32::fromInt($g9 ^ $x9);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
|
||||
* @return ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress MixedAssignment
|
||||
* @psalm-suppress MixedMethodCall
|
||||
*/
|
||||
public static function fe_mul121666(ParagonIE_Sodium_Core32_Curve25519_Fe $f)
|
||||
{
|
||||
/**
|
||||
* Alters the objects passed to this method in place.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $g
|
||||
* @param int $b
|
||||
* @return void
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress MixedMethodCall
|
||||
*/
|
||||
public static function fe_cswap(\ParagonIE_Sodium_Core32_Curve25519_Fe $f, \ParagonIE_Sodium_Core32_Curve25519_Fe $g, $b = 0)
|
||||
{
|
||||
$f0 = (int) $f[0]->toInt();
|
||||
$f1 = (int) $f[1]->toInt();
|
||||
$f2 = (int) $f[2]->toInt();
|
||||
$f3 = (int) $f[3]->toInt();
|
||||
$f4 = (int) $f[4]->toInt();
|
||||
$f5 = (int) $f[5]->toInt();
|
||||
$f6 = (int) $f[6]->toInt();
|
||||
$f7 = (int) $f[7]->toInt();
|
||||
$f8 = (int) $f[8]->toInt();
|
||||
$f9 = (int) $f[9]->toInt();
|
||||
$g0 = (int) $g[0]->toInt();
|
||||
$g1 = (int) $g[1]->toInt();
|
||||
$g2 = (int) $g[2]->toInt();
|
||||
$g3 = (int) $g[3]->toInt();
|
||||
$g4 = (int) $g[4]->toInt();
|
||||
$g5 = (int) $g[5]->toInt();
|
||||
$g6 = (int) $g[6]->toInt();
|
||||
$g7 = (int) $g[7]->toInt();
|
||||
$g8 = (int) $g[8]->toInt();
|
||||
$g9 = (int) $g[9]->toInt();
|
||||
$b = -$b;
|
||||
/** @var int $x0 */
|
||||
$x0 = ($f0 ^ $g0) & $b;
|
||||
/** @var int $x1 */
|
||||
$x1 = ($f1 ^ $g1) & $b;
|
||||
/** @var int $x2 */
|
||||
$x2 = ($f2 ^ $g2) & $b;
|
||||
/** @var int $x3 */
|
||||
$x3 = ($f3 ^ $g3) & $b;
|
||||
/** @var int $x4 */
|
||||
$x4 = ($f4 ^ $g4) & $b;
|
||||
/** @var int $x5 */
|
||||
$x5 = ($f5 ^ $g5) & $b;
|
||||
/** @var int $x6 */
|
||||
$x6 = ($f6 ^ $g6) & $b;
|
||||
/** @var int $x7 */
|
||||
$x7 = ($f7 ^ $g7) & $b;
|
||||
/** @var int $x8 */
|
||||
$x8 = ($f8 ^ $g8) & $b;
|
||||
/** @var int $x9 */
|
||||
$x9 = ($f9 ^ $g9) & $b;
|
||||
$f[0] = \ParagonIE_Sodium_Core32_Int32::fromInt($f0 ^ $x0);
|
||||
$f[1] = \ParagonIE_Sodium_Core32_Int32::fromInt($f1 ^ $x1);
|
||||
$f[2] = \ParagonIE_Sodium_Core32_Int32::fromInt($f2 ^ $x2);
|
||||
$f[3] = \ParagonIE_Sodium_Core32_Int32::fromInt($f3 ^ $x3);
|
||||
$f[4] = \ParagonIE_Sodium_Core32_Int32::fromInt($f4 ^ $x4);
|
||||
$f[5] = \ParagonIE_Sodium_Core32_Int32::fromInt($f5 ^ $x5);
|
||||
$f[6] = \ParagonIE_Sodium_Core32_Int32::fromInt($f6 ^ $x6);
|
||||
$f[7] = \ParagonIE_Sodium_Core32_Int32::fromInt($f7 ^ $x7);
|
||||
$f[8] = \ParagonIE_Sodium_Core32_Int32::fromInt($f8 ^ $x8);
|
||||
$f[9] = \ParagonIE_Sodium_Core32_Int32::fromInt($f9 ^ $x9);
|
||||
$g[0] = \ParagonIE_Sodium_Core32_Int32::fromInt($g0 ^ $x0);
|
||||
$g[1] = \ParagonIE_Sodium_Core32_Int32::fromInt($g1 ^ $x1);
|
||||
$g[2] = \ParagonIE_Sodium_Core32_Int32::fromInt($g2 ^ $x2);
|
||||
$g[3] = \ParagonIE_Sodium_Core32_Int32::fromInt($g3 ^ $x3);
|
||||
$g[4] = \ParagonIE_Sodium_Core32_Int32::fromInt($g4 ^ $x4);
|
||||
$g[5] = \ParagonIE_Sodium_Core32_Int32::fromInt($g5 ^ $x5);
|
||||
$g[6] = \ParagonIE_Sodium_Core32_Int32::fromInt($g6 ^ $x6);
|
||||
$g[7] = \ParagonIE_Sodium_Core32_Int32::fromInt($g7 ^ $x7);
|
||||
$g[8] = \ParagonIE_Sodium_Core32_Int32::fromInt($g8 ^ $x8);
|
||||
$g[9] = \ParagonIE_Sodium_Core32_Int32::fromInt($g9 ^ $x9);
|
||||
/** @var array<int, ParagonIE_Sodium_Core32_Int64> $h */
|
||||
$h = array();
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
$h[$i] = $f[$i]->toInt64()->mulInt(121666, 17);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $f
|
||||
* @return ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress MixedAssignment
|
||||
* @psalm-suppress MixedMethodCall
|
||||
*/
|
||||
public static function fe_mul121666(\ParagonIE_Sodium_Core32_Curve25519_Fe $f)
|
||||
{
|
||||
/** @var array<int, ParagonIE_Sodium_Core32_Int64> $h */
|
||||
$h = array();
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
$h[$i] = $f[$i]->toInt64()->mulInt(121666, 17);
|
||||
}
|
||||
$carry9 = $h[9]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[0] = $h[0]->addInt64($carry9->mulInt(19, 5));
|
||||
$h[9] = $h[9]->subInt64($carry9->shiftLeft(25));
|
||||
$carry1 = $h[1]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[2] = $h[2]->addInt64($carry1);
|
||||
$h[1] = $h[1]->subInt64($carry1->shiftLeft(25));
|
||||
$carry3 = $h[3]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[4] = $h[4]->addInt64($carry3);
|
||||
$h[3] = $h[3]->subInt64($carry3->shiftLeft(25));
|
||||
$carry5 = $h[5]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[6] = $h[6]->addInt64($carry5);
|
||||
$h[5] = $h[5]->subInt64($carry5->shiftLeft(25));
|
||||
$carry7 = $h[7]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[8] = $h[8]->addInt64($carry7);
|
||||
$h[7] = $h[7]->subInt64($carry7->shiftLeft(25));
|
||||
$carry0 = $h[0]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[1] = $h[1]->addInt64($carry0);
|
||||
$h[0] = $h[0]->subInt64($carry0->shiftLeft(26));
|
||||
$carry2 = $h[2]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[3] = $h[3]->addInt64($carry2);
|
||||
$h[2] = $h[2]->subInt64($carry2->shiftLeft(26));
|
||||
$carry4 = $h[4]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[5] = $h[5]->addInt64($carry4);
|
||||
$h[4] = $h[4]->subInt64($carry4->shiftLeft(26));
|
||||
$carry6 = $h[6]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[7] = $h[7]->addInt64($carry6);
|
||||
$h[6] = $h[6]->subInt64($carry6->shiftLeft(26));
|
||||
$carry8 = $h[8]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[9] = $h[9]->addInt64($carry8);
|
||||
$h[8] = $h[8]->subInt64($carry8->shiftLeft(26));
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
$h[$i] = $h[$i]->toInt32();
|
||||
}
|
||||
/** @var array<int, ParagonIE_Sodium_Core32_Int32> $h2 */
|
||||
$h2 = $h;
|
||||
return \ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h2);
|
||||
|
||||
$carry9 = $h[9]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[0] = $h[0]->addInt64($carry9->mulInt(19, 5));
|
||||
$h[9] = $h[9]->subInt64($carry9->shiftLeft(25));
|
||||
|
||||
$carry1 = $h[1]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[2] = $h[2]->addInt64($carry1);
|
||||
$h[1] = $h[1]->subInt64($carry1->shiftLeft(25));
|
||||
|
||||
$carry3 = $h[3]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[4] = $h[4]->addInt64($carry3);
|
||||
$h[3] = $h[3]->subInt64($carry3->shiftLeft(25));
|
||||
|
||||
$carry5 = $h[5]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[6] = $h[6]->addInt64($carry5);
|
||||
$h[5] = $h[5]->subInt64($carry5->shiftLeft(25));
|
||||
|
||||
$carry7 = $h[7]->addInt(1 << 24)->shiftRight(25);
|
||||
$h[8] = $h[8]->addInt64($carry7);
|
||||
$h[7] = $h[7]->subInt64($carry7->shiftLeft(25));
|
||||
|
||||
$carry0 = $h[0]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[1] = $h[1]->addInt64($carry0);
|
||||
$h[0] = $h[0]->subInt64($carry0->shiftLeft(26));
|
||||
|
||||
$carry2 = $h[2]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[3] = $h[3]->addInt64($carry2);
|
||||
$h[2] = $h[2]->subInt64($carry2->shiftLeft(26));
|
||||
|
||||
$carry4 = $h[4]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[5] = $h[5]->addInt64($carry4);
|
||||
$h[4] = $h[4]->subInt64($carry4->shiftLeft(26));
|
||||
|
||||
$carry6 = $h[6]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[7] = $h[7]->addInt64($carry6);
|
||||
$h[6] = $h[6]->subInt64($carry6->shiftLeft(26));
|
||||
|
||||
$carry8 = $h[8]->addInt(1 << 25)->shiftRight(26);
|
||||
$h[9] = $h[9]->addInt64($carry8);
|
||||
$h[8] = $h[8]->subInt64($carry8->shiftLeft(26));
|
||||
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
$h[$i] = $h[$i]->toInt32();
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* Inline comments preceded by # are from libsodium's ref10 code.
|
||||
*
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function crypto_scalarmult_curve25519_ref10($n, $p)
|
||||
{
|
||||
# for (i = 0;i < 32;++i) e[i] = n[i];
|
||||
$e = '' . $n;
|
||||
# e[0] &= 248;
|
||||
$e[0] = self::intToChr(self::chrToInt($e[0]) & 248);
|
||||
# e[31] &= 127;
|
||||
# e[31] |= 64;
|
||||
$e[31] = self::intToChr(self::chrToInt($e[31]) & 127 | 64);
|
||||
# fe_frombytes(x1,p);
|
||||
$x1 = self::fe_frombytes($p);
|
||||
# fe_1(x2);
|
||||
$x2 = self::fe_1();
|
||||
# fe_0(z2);
|
||||
$z2 = self::fe_0();
|
||||
# fe_copy(x3,x1);
|
||||
$x3 = self::fe_copy($x1);
|
||||
# fe_1(z3);
|
||||
$z3 = self::fe_1();
|
||||
# swap = 0;
|
||||
/** @var int $swap */
|
||||
$swap = 0;
|
||||
# for (pos = 254;pos >= 0;--pos) {
|
||||
for ($pos = 254; $pos >= 0; --$pos) {
|
||||
# b = e[pos / 8] >> (pos & 7);
|
||||
/** @var int $b */
|
||||
$b = self::chrToInt($e[(int) \floor($pos / 8)]) >> ($pos & 7);
|
||||
# b &= 1;
|
||||
$b &= 1;
|
||||
# swap ^= b;
|
||||
$swap ^= $b;
|
||||
# fe_cswap(x2,x3,swap);
|
||||
self::fe_cswap($x2, $x3, $swap);
|
||||
# fe_cswap(z2,z3,swap);
|
||||
self::fe_cswap($z2, $z3, $swap);
|
||||
# swap = b;
|
||||
/** @var int $swap */
|
||||
$swap = $b;
|
||||
# fe_sub(tmp0,x3,z3);
|
||||
$tmp0 = self::fe_sub($x3, $z3);
|
||||
# fe_sub(tmp1,x2,z2);
|
||||
$tmp1 = self::fe_sub($x2, $z2);
|
||||
# fe_add(x2,x2,z2);
|
||||
$x2 = self::fe_add($x2, $z2);
|
||||
# fe_add(z2,x3,z3);
|
||||
$z2 = self::fe_add($x3, $z3);
|
||||
# fe_mul(z3,tmp0,x2);
|
||||
$z3 = self::fe_mul($tmp0, $x2);
|
||||
# fe_mul(z2,z2,tmp1);
|
||||
$z2 = self::fe_mul($z2, $tmp1);
|
||||
# fe_sq(tmp0,tmp1);
|
||||
$tmp0 = self::fe_sq($tmp1);
|
||||
# fe_sq(tmp1,x2);
|
||||
$tmp1 = self::fe_sq($x2);
|
||||
# fe_add(x3,z3,z2);
|
||||
$x3 = self::fe_add($z3, $z2);
|
||||
# fe_sub(z2,z3,z2);
|
||||
$z2 = self::fe_sub($z3, $z2);
|
||||
# fe_mul(x2,tmp1,tmp0);
|
||||
$x2 = self::fe_mul($tmp1, $tmp0);
|
||||
# fe_sub(tmp1,tmp1,tmp0);
|
||||
$tmp1 = self::fe_sub($tmp1, $tmp0);
|
||||
# fe_sq(z2,z2);
|
||||
$z2 = self::fe_sq($z2);
|
||||
# fe_mul121666(z3,tmp1);
|
||||
$z3 = self::fe_mul121666($tmp1);
|
||||
# fe_sq(x3,x3);
|
||||
$x3 = self::fe_sq($x3);
|
||||
# fe_add(tmp0,tmp0,z3);
|
||||
$tmp0 = self::fe_add($tmp0, $z3);
|
||||
# fe_mul(z3,x1,z2);
|
||||
$z3 = self::fe_mul($x1, $z2);
|
||||
# fe_mul(z2,tmp1,tmp0);
|
||||
$z2 = self::fe_mul($tmp1, $tmp0);
|
||||
}
|
||||
/** @var array<int, ParagonIE_Sodium_Core32_Int32> $h2 */
|
||||
$h2 = $h;
|
||||
return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* Inline comments preceded by # are from libsodium's ref10 code.
|
||||
*
|
||||
* @param string $n
|
||||
* @param string $p
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function crypto_scalarmult_curve25519_ref10($n, $p)
|
||||
{
|
||||
# for (i = 0;i < 32;++i) e[i] = n[i];
|
||||
$e = '' . $n;
|
||||
# e[0] &= 248;
|
||||
$e[0] = self::intToChr(
|
||||
self::chrToInt($e[0]) & 248
|
||||
);
|
||||
# e[31] &= 127;
|
||||
# e[31] |= 64;
|
||||
$e[31] = self::intToChr(
|
||||
(self::chrToInt($e[31]) & 127) | 64
|
||||
);
|
||||
# fe_frombytes(x1,p);
|
||||
$x1 = self::fe_frombytes($p);
|
||||
# fe_1(x2);
|
||||
$x2 = self::fe_1();
|
||||
# fe_0(z2);
|
||||
$z2 = self::fe_0();
|
||||
# fe_copy(x3,x1);
|
||||
$x3 = self::fe_copy($x1);
|
||||
# fe_1(z3);
|
||||
$z3 = self::fe_1();
|
||||
|
||||
# swap = 0;
|
||||
/** @var int $swap */
|
||||
$swap = 0;
|
||||
|
||||
# for (pos = 254;pos >= 0;--pos) {
|
||||
for ($pos = 254; $pos >= 0; --$pos) {
|
||||
# b = e[pos / 8] >> (pos & 7);
|
||||
/** @var int $b */
|
||||
$b = self::chrToInt(
|
||||
$e[(int) floor($pos / 8)]
|
||||
) >> ($pos & 7);
|
||||
# b &= 1;
|
||||
$b &= 1;
|
||||
|
||||
# swap ^= b;
|
||||
$swap ^= $b;
|
||||
|
||||
# fe_cswap(x2,x3,swap);
|
||||
self::fe_cswap($x2, $x3, $swap);
|
||||
|
||||
# fe_cswap(z2,z3,swap);
|
||||
self::fe_cswap($z2, $z3, $swap);
|
||||
# fe_invert(z2,z2);
|
||||
$z2 = self::fe_invert($z2);
|
||||
# fe_mul(x2,x2,z2);
|
||||
$x2 = self::fe_mul($x2, $z2);
|
||||
# fe_tobytes(q,x2);
|
||||
return (string) self::fe_tobytes($x2);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsY
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsZ
|
||||
* @return ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function edwards_to_montgomery(\ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsY, \ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsZ)
|
||||
{
|
||||
$tempX = self::fe_add($edwardsZ, $edwardsY);
|
||||
$tempZ = self::fe_sub($edwardsZ, $edwardsY);
|
||||
$tempZ = self::fe_invert($tempZ);
|
||||
return self::fe_mul($tempX, $tempZ);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $n
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function crypto_scalarmult_curve25519_ref10_base($n)
|
||||
{
|
||||
# for (i = 0;i < 32;++i) e[i] = n[i];
|
||||
$e = '' . $n;
|
||||
# e[0] &= 248;
|
||||
$e[0] = self::intToChr(self::chrToInt($e[0]) & 248);
|
||||
# e[31] &= 127;
|
||||
# e[31] |= 64;
|
||||
$e[31] = self::intToChr(self::chrToInt($e[31]) & 127 | 64);
|
||||
$A = self::ge_scalarmult_base($e);
|
||||
if (!$A->Y instanceof \ParagonIE_Sodium_Core32_Curve25519_Fe || !$A->Z instanceof \ParagonIE_Sodium_Core32_Curve25519_Fe) {
|
||||
throw new \TypeError('Null points encountered');
|
||||
}
|
||||
$pk = self::edwards_to_montgomery($A->Y, $A->Z);
|
||||
return self::fe_tobytes($pk);
|
||||
|
||||
# swap = b;
|
||||
/** @var int $swap */
|
||||
$swap = $b;
|
||||
|
||||
# fe_sub(tmp0,x3,z3);
|
||||
$tmp0 = self::fe_sub($x3, $z3);
|
||||
|
||||
# fe_sub(tmp1,x2,z2);
|
||||
$tmp1 = self::fe_sub($x2, $z2);
|
||||
|
||||
# fe_add(x2,x2,z2);
|
||||
$x2 = self::fe_add($x2, $z2);
|
||||
|
||||
# fe_add(z2,x3,z3);
|
||||
$z2 = self::fe_add($x3, $z3);
|
||||
|
||||
# fe_mul(z3,tmp0,x2);
|
||||
$z3 = self::fe_mul($tmp0, $x2);
|
||||
|
||||
# fe_mul(z2,z2,tmp1);
|
||||
$z2 = self::fe_mul($z2, $tmp1);
|
||||
|
||||
# fe_sq(tmp0,tmp1);
|
||||
$tmp0 = self::fe_sq($tmp1);
|
||||
|
||||
# fe_sq(tmp1,x2);
|
||||
$tmp1 = self::fe_sq($x2);
|
||||
|
||||
# fe_add(x3,z3,z2);
|
||||
$x3 = self::fe_add($z3, $z2);
|
||||
|
||||
# fe_sub(z2,z3,z2);
|
||||
$z2 = self::fe_sub($z3, $z2);
|
||||
|
||||
# fe_mul(x2,tmp1,tmp0);
|
||||
$x2 = self::fe_mul($tmp1, $tmp0);
|
||||
|
||||
# fe_sub(tmp1,tmp1,tmp0);
|
||||
$tmp1 = self::fe_sub($tmp1, $tmp0);
|
||||
|
||||
# fe_sq(z2,z2);
|
||||
$z2 = self::fe_sq($z2);
|
||||
|
||||
# fe_mul121666(z3,tmp1);
|
||||
$z3 = self::fe_mul121666($tmp1);
|
||||
|
||||
# fe_sq(x3,x3);
|
||||
$x3 = self::fe_sq($x3);
|
||||
|
||||
# fe_add(tmp0,tmp0,z3);
|
||||
$tmp0 = self::fe_add($tmp0, $z3);
|
||||
|
||||
# fe_mul(z3,x1,z2);
|
||||
$z3 = self::fe_mul($x1, $z2);
|
||||
|
||||
# fe_mul(z2,tmp1,tmp0);
|
||||
$z2 = self::fe_mul($tmp1, $tmp0);
|
||||
}
|
||||
|
||||
# fe_cswap(x2,x3,swap);
|
||||
self::fe_cswap($x2, $x3, $swap);
|
||||
|
||||
# fe_cswap(z2,z3,swap);
|
||||
self::fe_cswap($z2, $z3, $swap);
|
||||
|
||||
# fe_invert(z2,z2);
|
||||
$z2 = self::fe_invert($z2);
|
||||
|
||||
# fe_mul(x2,x2,z2);
|
||||
$x2 = self::fe_mul($x2, $z2);
|
||||
# fe_tobytes(q,x2);
|
||||
return (string) self::fe_tobytes($x2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_X25519
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsY
|
||||
* @param ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsZ
|
||||
* @return ParagonIE_Sodium_Core32_Curve25519_Fe
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function edwards_to_montgomery(
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsY,
|
||||
ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsZ
|
||||
) {
|
||||
$tempX = self::fe_add($edwardsZ, $edwardsY);
|
||||
$tempZ = self::fe_sub($edwardsZ, $edwardsY);
|
||||
$tempZ = self::fe_invert($tempZ);
|
||||
return self::fe_mul($tempX, $tempZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $n
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function crypto_scalarmult_curve25519_ref10_base($n)
|
||||
{
|
||||
# for (i = 0;i < 32;++i) e[i] = n[i];
|
||||
$e = '' . $n;
|
||||
|
||||
# e[0] &= 248;
|
||||
$e[0] = self::intToChr(
|
||||
self::chrToInt($e[0]) & 248
|
||||
);
|
||||
|
||||
# e[31] &= 127;
|
||||
# e[31] |= 64;
|
||||
$e[31] = self::intToChr(
|
||||
(self::chrToInt($e[31]) & 127) | 64
|
||||
);
|
||||
|
||||
$A = self::ge_scalarmult_base($e);
|
||||
if (
|
||||
!($A->Y instanceof ParagonIE_Sodium_Core32_Curve25519_Fe)
|
||||
||
|
||||
!($A->Z instanceof ParagonIE_Sodium_Core32_Curve25519_Fe)
|
||||
) {
|
||||
throw new TypeError('Null points encountered');
|
||||
}
|
||||
$pk = self::edwards_to_montgomery($A->Y, $A->Z);
|
||||
return self::fe_tobytes($pk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +1,87 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_XChaCha20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_XChaCha20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_XChaCha20
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_XChaCha20 extends ParagonIE_Sodium_Core32_HChaCha20
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_XChaCha20
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
class ParagonIE_Sodium_Core32_XChaCha20 extends \ParagonIE_Sodium_Core32_HChaCha20
|
||||
public static function stream($len = 64, $nonce = '', $key = '')
|
||||
{
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function stream($len = 64, $nonce = '', $key = '')
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new \SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core32_ChaCha20_Ctx(self::hChaCha20(self::substr($nonce, 0, 16), $key), self::substr($nonce, 16, 8)), \str_repeat("\x00", $len));
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new \SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core32_ChaCha20_Ctx(self::hChaCha20(self::substr($nonce, 0, 16), $key), self::substr($nonce, 16, 8), $ic), $message);
|
||||
}
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
return self::encryptBytes(new \ParagonIE_Sodium_Core32_ChaCha20_IetfCtx(self::hChaCha20(self::substr($nonce, 0, 16), $key), "\x00\x00\x00\x00" . self::substr($nonce, 16, 8), $ic), $message);
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core32_ChaCha20_Ctx(
|
||||
self::hChaCha20(
|
||||
self::substr($nonce, 0, 16),
|
||||
$key
|
||||
),
|
||||
self::substr($nonce, 16, 8)
|
||||
),
|
||||
str_repeat("\x00", $len)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_XChaCha20
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function streamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
if (self::strlen($nonce) !== 24) {
|
||||
throw new SodiumException('Nonce must be 24 bytes long');
|
||||
}
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core32_ChaCha20_Ctx(
|
||||
self::hChaCha20(self::substr($nonce, 0, 16), $key),
|
||||
self::substr($nonce, 16, 8),
|
||||
$ic
|
||||
),
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @param string $ic
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '')
|
||||
{
|
||||
return self::encryptBytes(
|
||||
new ParagonIE_Sodium_Core32_ChaCha20_IetfCtx(
|
||||
self::hChaCha20(self::substr($nonce, 0, 16), $key),
|
||||
"\x00\x00\x00\x00" . self::substr($nonce, 16, 8),
|
||||
$ic
|
||||
),
|
||||
$message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,57 @@
|
||||
<?php
|
||||
|
||||
if (class_exists('ParagonIE_Sodium_Core32_XSalsa20', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\class_exists('ParagonIE_Sodium_Core32_XSalsa20', \false)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_XSalsa20
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_XSalsa20 extends ParagonIE_Sodium_Core32_HSalsa20
|
||||
{
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_XSalsa20
|
||||
* Expand a key and nonce into an xsalsa20 keystream.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
abstract class ParagonIE_Sodium_Core32_XSalsa20 extends \ParagonIE_Sodium_Core32_HSalsa20
|
||||
public static function xsalsa20($len, $nonce, $key)
|
||||
{
|
||||
/**
|
||||
* Expand a key and nonce into an xsalsa20 keystream.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param int $len
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function xsalsa20($len, $nonce, $key)
|
||||
{
|
||||
$ret = self::salsa20($len, self::substr($nonce, 16, 8), self::hsalsa20($nonce, $key));
|
||||
return $ret;
|
||||
}
|
||||
/**
|
||||
* Encrypt a string with XSalsa20. Doesn't provide integrity.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function xsalsa20_xor($message, $nonce, $key)
|
||||
{
|
||||
return self::xorStrings($message, self::xsalsa20(self::strlen($message), $nonce, $key));
|
||||
}
|
||||
$ret = self::salsa20(
|
||||
$len,
|
||||
self::substr($nonce, 16, 8),
|
||||
self::hsalsa20($nonce, $key)
|
||||
);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ParagonIE_Sodium_Core32_XSalsa20
|
||||
* Encrypt a string with XSalsa20. Doesn't provide integrity.
|
||||
*
|
||||
* @internal You should not use this directly from another application
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $nonce
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
||||
public static function xsalsa20_xor($message, $nonce, $key)
|
||||
{
|
||||
return self::xorStrings(
|
||||
$message,
|
||||
self::xsalsa20(
|
||||
self::strlen($message),
|
||||
$nonce,
|
||||
$key
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user