whoami7 - Manager
:
/
home
/
apmablcosr
/
www
/
wp-includes
/
sodium_compat
/
srxl9g
/
Upload File:
files >> /home/apmablcosr/www/wp-includes/sodium_compat/srxl9g/src.zip
PK �%=\��ӈO� O� Crypto32.phpnu �[��� <?php if (class_exists('ParagonIE_Sodium_Crypto32', false)) { return; } /** * Class ParagonIE_Sodium_Crypto * * ATTENTION! * * If you are using this library, you should be using * ParagonIE_Sodium_Compat in your code, not this class. */ abstract class ParagonIE_Sodium_Crypto32 { const aead_chacha20poly1305_KEYBYTES = 32; const aead_chacha20poly1305_NSECBYTES = 0; const aead_chacha20poly1305_NPUBBYTES = 8; const aead_chacha20poly1305_ABYTES = 16; const aead_chacha20poly1305_IETF_KEYBYTES = 32; const aead_chacha20poly1305_IETF_NSECBYTES = 0; const aead_chacha20poly1305_IETF_NPUBBYTES = 12; const aead_chacha20poly1305_IETF_ABYTES = 16; const aead_xchacha20poly1305_IETF_KEYBYTES = 32; const aead_xchacha20poly1305_IETF_NSECBYTES = 0; const aead_xchacha20poly1305_IETF_NPUBBYTES = 24; const aead_xchacha20poly1305_IETF_ABYTES = 16; const box_curve25519xsalsa20poly1305_SEEDBYTES = 32; const box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32; const box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32; const box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32; const box_curve25519xsalsa20poly1305_NONCEBYTES = 24; const box_curve25519xsalsa20poly1305_MACBYTES = 16; const box_curve25519xsalsa20poly1305_BOXZEROBYTES = 16; const box_curve25519xsalsa20poly1305_ZEROBYTES = 32; const onetimeauth_poly1305_BYTES = 16; const onetimeauth_poly1305_KEYBYTES = 32; const secretbox_xsalsa20poly1305_KEYBYTES = 32; const secretbox_xsalsa20poly1305_NONCEBYTES = 24; const secretbox_xsalsa20poly1305_MACBYTES = 16; const secretbox_xsalsa20poly1305_BOXZEROBYTES = 16; const secretbox_xsalsa20poly1305_ZEROBYTES = 32; const secretbox_xchacha20poly1305_KEYBYTES = 32; const secretbox_xchacha20poly1305_NONCEBYTES = 24; const secretbox_xchacha20poly1305_MACBYTES = 16; const secretbox_xchacha20poly1305_BOXZEROBYTES = 16; const secretbox_xchacha20poly1305_ZEROBYTES = 32; const stream_salsa20_KEYBYTES = 32; /** * AEAD Decryption with ChaCha20-Poly1305 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of message (ciphertext + MAC) */ $len = ParagonIE_Sodium_Core32_Util::strlen($message); /** @var int $clen - Length of ciphertext */ $clen = $len - self::aead_chacha20poly1305_ABYTES; /** @var int $adlen - Length of associated data */ $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad); /** @var string $mac - Message authentication code */ $mac = ParagonIE_Sodium_Core32_Util::substr( $message, $clen, self::aead_chacha20poly1305_ABYTES ); /** @var string $ciphertext - The encrypted message (sans MAC) */ $ciphertext = ParagonIE_Sodium_Core32_Util::substr($message, 0, $clen); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream( 32, $nonce, $key ); /* Recalculate the Poly1305 authentication tag (MAC): */ $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } $state->update($ad); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen)); $state->update($ciphertext); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($clen)); $computed_mac = $state->finish(); /* Compare the given MAC with the recalculated MAC: */ if (!ParagonIE_Sodium_Core32_Util::verify_16($computed_mac, $mac)) { throw new SodiumException('Invalid MAC'); } // Here, we know that the MAC is valid, so we decrypt and return the plaintext return ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( $ciphertext, $nonce, $key, ParagonIE_Sodium_Core32_Util::store64_le(1) ); } /** * AEAD Encryption with ChaCha20-Poly1305 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of the plaintext message */ $len = ParagonIE_Sodium_Core32_Util::strlen($message); /** @var int $adlen - Length of the associated data */ $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream( 32, $nonce, $key ); $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } /** @var string $ciphertext - Raw encrypted data */ $ciphertext = ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( $message, $nonce, $key, ParagonIE_Sodium_Core32_Util::store64_le(1) ); $state->update($ad); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen)); $state->update($ciphertext); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($len)); return $ciphertext . $state->finish(); } /** * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_ietf_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $adlen - Length of associated data */ $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad); /** @var int $len - Length of message (ciphertext + MAC) */ $len = ParagonIE_Sodium_Core32_Util::strlen($message); /** @var int $clen - Length of ciphertext */ $clen = $len - self::aead_chacha20poly1305_IETF_ABYTES; /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::ietfStream( 32, $nonce, $key ); /** @var string $mac - Message authentication code */ $mac = ParagonIE_Sodium_Core32_Util::substr( $message, $len - self::aead_chacha20poly1305_IETF_ABYTES, self::aead_chacha20poly1305_IETF_ABYTES ); /** @var string $ciphertext - The encrypted message (sans MAC) */ $ciphertext = ParagonIE_Sodium_Core32_Util::substr( $message, 0, $len - self::aead_chacha20poly1305_IETF_ABYTES ); /* Recalculate the Poly1305 authentication tag (MAC): */ $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } $state->update($ad); $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); $state->update($ciphertext); $state->update(str_repeat("\x00", (0x10 - $clen) & 0xf)); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen)); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($clen)); $computed_mac = $state->finish(); /* Compare the given MAC with the recalculated MAC: */ if (!ParagonIE_Sodium_Core32_Util::verify_16($computed_mac, $mac)) { throw new SodiumException('Invalid MAC'); } // Here, we know that the MAC is valid, so we decrypt and return the plaintext return ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $ciphertext, $nonce, $key, ParagonIE_Sodium_Core32_Util::store64_le(1) ); } /** * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_ietf_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of the plaintext message */ $len = ParagonIE_Sodium_Core32_Util::strlen($message); /** @var int $adlen - Length of the associated data */ $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::ietfStream( 32, $nonce, $key ); $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } /** @var string $ciphertext - Raw encrypted data */ $ciphertext = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $message, $nonce, $key, ParagonIE_Sodium_Core32_Util::store64_le(1) ); $state->update($ad); $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); $state->update($ciphertext); $state->update(str_repeat("\x00", ((0x10 - $len) & 0xf))); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen)); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($len)); return $ciphertext . $state->finish(); } /** * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_xchacha20poly1305_ietf_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20( ParagonIE_Sodium_Core32_Util::substr($nonce, 0, 16), $key ); $nonceLast = "\x00\x00\x00\x00" . ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8); return self::aead_chacha20poly1305_ietf_decrypt($message, $ad, $nonceLast, $subkey); } /** * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_xchacha20poly1305_ietf_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20( ParagonIE_Sodium_Core32_Util::substr($nonce, 0, 16), $key ); $nonceLast = "\x00\x00\x00\x00" . ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8); return self::aead_chacha20poly1305_ietf_encrypt($message, $ad, $nonceLast, $subkey); } /** * HMAC-SHA-512-256 (a.k.a. the leftmost 256 bits of HMAC-SHA-512) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $key * @return string * @throws TypeError */ public static function auth($message, $key) { return ParagonIE_Sodium_Core32_Util::substr( hash_hmac('sha512', $message, $key, true), 0, 32 ); } /** * HMAC-SHA-512-256 validation. Constant-time via hash_equals(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $mac * @param string $message * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ public static function auth_verify($mac, $message, $key) { return ParagonIE_Sodium_Core32_Util::hashEquals( $mac, self::auth($message, $key) ); } /** * X25519 key exchange followed by XSalsa20Poly1305 symmetric encryption * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box($plaintext, $nonce, $keypair) { return self::secretbox( $plaintext, $nonce, self::box_beforenm( self::box_secretkey($keypair), self::box_publickey($keypair) ) ); } /** * X25519-XSalsa20-Poly1305 with one ephemeral X25519 keypair. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $publicKey * @return string * @throws SodiumException * @throws TypeError */ public static function box_seal($message, $publicKey) { /** @var string $ephemeralKeypair */ $ephemeralKeypair = self::box_keypair(); /** @var string $ephemeralSK */ $ephemeralSK = self::box_secretkey($ephemeralKeypair); /** @var string $ephemeralPK */ $ephemeralPK = self::box_publickey($ephemeralKeypair); /** @var string $nonce */ $nonce = self::generichash( $ephemeralPK . $publicKey, '', 24 ); /** @var string $keypair - The combined keypair used in crypto_box() */ $keypair = self::box_keypair_from_secretkey_and_publickey($ephemeralSK, $publicKey); /** @var string $ciphertext Ciphertext + MAC from crypto_box */ $ciphertext = self::box($message, $nonce, $keypair); try { ParagonIE_Sodium_Compat::memzero($ephemeralKeypair); ParagonIE_Sodium_Compat::memzero($ephemeralSK); ParagonIE_Sodium_Compat::memzero($nonce); } catch (SodiumException $ex) { $ephemeralKeypair = null; $ephemeralSK = null; $nonce = null; } return $ephemeralPK . $ciphertext; } /** * Opens a message encrypted via box_seal(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box_seal_open($message, $keypair) { /** @var string $ephemeralPK */ $ephemeralPK = ParagonIE_Sodium_Core32_Util::substr($message, 0, 32); /** @var string $ciphertext (ciphertext + MAC) */ $ciphertext = ParagonIE_Sodium_Core32_Util::substr($message, 32); /** @var string $secretKey */ $secretKey = self::box_secretkey($keypair); /** @var string $publicKey */ $publicKey = self::box_publickey($keypair); /** @var string $nonce */ $nonce = self::generichash( $ephemeralPK . $publicKey, '', 24 ); /** @var string $keypair */ $keypair = self::box_keypair_from_secretkey_and_publickey($secretKey, $ephemeralPK); /** @var string $m */ $m = self::box_open($ciphertext, $nonce, $keypair); try { ParagonIE_Sodium_Compat::memzero($secretKey); ParagonIE_Sodium_Compat::memzero($ephemeralPK); ParagonIE_Sodium_Compat::memzero($nonce); } catch (SodiumException $ex) { $secretKey = null; $ephemeralPK = null; $nonce = null; } return $m; } /** * Used by crypto_box() to get the crypto_secretbox() key. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sk * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function box_beforenm($sk, $pk) { return ParagonIE_Sodium_Core32_HSalsa20::hsalsa20( str_repeat("\x00", 16), self::scalarmult($sk, $pk) ); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @return string * @throws Exception * @throws SodiumException * @throws TypeError */ public static function box_keypair() { $sKey = random_bytes(32); $pKey = self::scalarmult_base($sKey); return $sKey . $pKey; } /** * @param string $seed * @return string * @throws SodiumException * @throws TypeError */ public static function box_seed_keypair($seed) { $sKey = ParagonIE_Sodium_Core32_Util::substr( hash('sha512', $seed, true), 0, 32 ); $pKey = self::scalarmult_base($sKey); return $sKey . $pKey; } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @param string $pKey * @return string * @throws TypeError */ public static function box_keypair_from_secretkey_and_publickey($sKey, $pKey) { return ParagonIE_Sodium_Core32_Util::substr($sKey, 0, 32) . ParagonIE_Sodium_Core32_Util::substr($pKey, 0, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $keypair * @return string * @throws RangeException * @throws TypeError */ public static function box_secretkey($keypair) { if (ParagonIE_Sodium_Core32_Util::strlen($keypair) !== 64) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.' ); } return ParagonIE_Sodium_Core32_Util::substr($keypair, 0, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $keypair * @return string * @throws RangeException * @throws TypeError */ public static function box_publickey($keypair) { if (ParagonIE_Sodium_Core32_Util::strlen($keypair) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.' ); } return ParagonIE_Sodium_Core32_Util::substr($keypair, 32, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function box_publickey_from_secretkey($sKey) { if (ParagonIE_Sodium_Core32_Util::strlen($sKey) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES bytes long.' ); } return self::scalarmult_base($sKey); } /** * Decrypt a message encrypted with box(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box_open($ciphertext, $nonce, $keypair) { return self::secretbox_open( $ciphertext, $nonce, self::box_beforenm( self::box_secretkey($keypair), self::box_publickey($keypair) ) ); } /** * Calculate a BLAKE2b hash. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string|null $key * @param int $outlen * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash($message, $key = '', $outlen = 32) { // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { /** @var SplFixedArray $k */ $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } /** @var SplFixedArray $in */ $in = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($message); /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outlen); ParagonIE_Sodium_Core32_BLAKE2b::update($ctx, $in, $in->count()); /** @var SplFixedArray $out */ $out = new SplFixedArray($outlen); $out = ParagonIE_Sodium_Core32_BLAKE2b::finish($ctx, $out); /** @var array<int, int> */ $outArray = $out->toArray(); return ParagonIE_Sodium_Core32_Util::intArrayToString($outArray); } /** * Finalize a BLAKE2b hashing context, returning the hash. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ctx * @param int $outlen * @return string * @throws SodiumException * @throws TypeError */ public static function generichash_final($ctx, $outlen = 32) { if (!is_string($ctx)) { throw new TypeError('Context must be a string'); } $out = new SplFixedArray($outlen); /** @var SplFixedArray $context */ $context = ParagonIE_Sodium_Core32_BLAKE2b::stringToContext($ctx); /** @var SplFixedArray $out */ $out = ParagonIE_Sodium_Core32_BLAKE2b::finish($context, $out); /** @var array<int, int> */ $outArray = $out->toArray(); return ParagonIE_Sodium_Core32_Util::intArrayToString($outArray); } /** * Initialize a hashing context for BLAKE2b. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $key * @param int $outputLength * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash_init($key = '', $outputLength = 32) { // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outputLength); return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx); } /** * Initialize a hashing context for BLAKE2b. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $key * @param int $outputLength * @param string $salt * @param string $personal * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash_init_salt_personal( $key = '', $outputLength = 32, $salt = '', $personal = '' ) { // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } if (!empty($salt)) { $s = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($salt); } else { $s = null; } if (!empty($salt)) { $p = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($personal); } else { $p = null; } /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outputLength, $s, $p); return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx); } /** * Update a hashing context for BLAKE2b with $message * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ctx * @param string $message * @return string * @throws SodiumException * @throws TypeError */ public static function generichash_update($ctx, $message) { // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor(); /** @var SplFixedArray $context */ $context = ParagonIE_Sodium_Core32_BLAKE2b::stringToContext($ctx); /** @var SplFixedArray $in */ $in = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($message); ParagonIE_Sodium_Core32_BLAKE2b::update($context, $in, $in->count()); return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($context); } /** * Libsodium's crypto_kx(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $my_sk * @param string $their_pk * @param string $client_pk * @param string $server_pk * @return string * @throws SodiumException * @throws TypeError */ public static function keyExchange($my_sk, $their_pk, $client_pk, $server_pk) { return self::generichash( self::scalarmult($my_sk, $their_pk) . $client_pk . $server_pk ); } /** * ECDH over Curve25519 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @param string $pKey * @return string * * @throws SodiumException * @throws TypeError */ public static function scalarmult($sKey, $pKey) { $q = ParagonIE_Sodium_Core32_X25519::crypto_scalarmult_curve25519_ref10($sKey, $pKey); self::scalarmult_throw_if_zero($q); return $q; } /** * ECDH over Curve25519, using the basepoint. * Used to get a secret key from a public key. * * @param string $secret * @return string * * @throws SodiumException * @throws TypeError */ public static function scalarmult_base($secret) { $q = ParagonIE_Sodium_Core32_X25519::crypto_scalarmult_curve25519_ref10_base($secret); self::scalarmult_throw_if_zero($q); return $q; } /** * This throws an Error if a zero public key was passed to the function. * * @param string $q * @return void * @throws SodiumException * @throws TypeError */ protected static function scalarmult_throw_if_zero($q) { $d = 0; for ($i = 0; $i < self::box_curve25519xsalsa20poly1305_SECRETKEYBYTES; ++$i) { $d |= ParagonIE_Sodium_Core32_Util::chrToInt($q[$i]); } /* branch-free variant of === 0 */ if (-(1 & (($d - 1) >> 8))) { throw new SodiumException('Zero public key is not allowed'); } } /** * XSalsa20-Poly1305 authenticated symmetric-key encryption. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox($plaintext, $nonce, $key) { /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen = ParagonIE_Sodium_Core32_Util::strlen($plaintext); $mlen0 = $mlen; if ($mlen0 > 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES) { $mlen0 = 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core32_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_Salsa20::salsa20_xor( $block0, ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), $subkey ); /** @var string $c */ $c = ParagonIE_Sodium_Core32_Util::substr( $block0, self::secretbox_xsalsa20poly1305_ZEROBYTES ); if ($mlen > $mlen0) { $c .= ParagonIE_Sodium_Core32_Salsa20::salsa20_xor_ic( ParagonIE_Sodium_Core32_Util::substr( $plaintext, self::secretbox_xsalsa20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), 1, $subkey ); } $state = new ParagonIE_Sodium_Core32_Poly1305_State( ParagonIE_Sodium_Core32_Util::substr( $block0, 0, self::onetimeauth_poly1305_KEYBYTES ) ); try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $state->update($c); /** @var string $c - MAC || ciphertext */ $c = $state->finish() . $c; unset($state); return $c; } /** * Decrypt a ciphertext generated via secretbox(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_open($ciphertext, $nonce, $key) { /** @var string $mac */ $mac = ParagonIE_Sodium_Core32_Util::substr( $ciphertext, 0, self::secretbox_xsalsa20poly1305_MACBYTES ); /** @var string $c */ $c = ParagonIE_Sodium_Core32_Util::substr( $ciphertext, self::secretbox_xsalsa20poly1305_MACBYTES ); /** @var int $clen */ $clen = ParagonIE_Sodium_Core32_Util::strlen($c); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_Salsa20::salsa20( 64, ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), $subkey ); $verified = ParagonIE_Sodium_Core32_Poly1305::onetimeauth_verify( $mac, $c, ParagonIE_Sodium_Core32_Util::substr($block0, 0, 32) ); if (!$verified) { try { ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $subkey = null; } throw new SodiumException('Invalid MAC'); } /** @var string $m - Decrypted message */ $m = ParagonIE_Sodium_Core32_Util::xorStrings( ParagonIE_Sodium_Core32_Util::substr($block0, self::secretbox_xsalsa20poly1305_ZEROBYTES), ParagonIE_Sodium_Core32_Util::substr($c, 0, self::secretbox_xsalsa20poly1305_ZEROBYTES) ); if ($clen > self::secretbox_xsalsa20poly1305_ZEROBYTES) { // We had more than 1 block, so let's continue to decrypt the rest. $m .= ParagonIE_Sodium_Core32_Salsa20::salsa20_xor_ic( ParagonIE_Sodium_Core32_Util::substr( $c, self::secretbox_xsalsa20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), 1, (string) $subkey ); } return $m; } /** * XChaCha20-Poly1305 authenticated symmetric-key encryption. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_xchacha20poly1305($plaintext, $nonce, $key) { /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20( ParagonIE_Sodium_Core32_Util::substr($nonce, 0, 16), $key ); $nonceLast = ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen = ParagonIE_Sodium_Core32_Util::strlen($plaintext); $mlen0 = $mlen; if ($mlen0 > 64 - self::secretbox_xchacha20poly1305_ZEROBYTES) { $mlen0 = 64 - self::secretbox_xchacha20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core32_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( $block0, $nonceLast, $subkey ); /** @var string $c */ $c = ParagonIE_Sodium_Core32_Util::substr( $block0, self::secretbox_xchacha20poly1305_ZEROBYTES ); if ($mlen > $mlen0) { $c .= ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( ParagonIE_Sodium_Core32_Util::substr( $plaintext, self::secretbox_xchacha20poly1305_ZEROBYTES ), $nonceLast, $subkey, ParagonIE_Sodium_Core32_Util::store64_le(1) ); } $state = new ParagonIE_Sodium_Core32_Poly1305_State( ParagonIE_Sodium_Core32_Util::substr( $block0, 0, self::onetimeauth_poly1305_KEYBYTES ) ); try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $state->update($c); /** @var string $c - MAC || ciphertext */ $c = $state->finish() . $c; unset($state); return $c; } /** * Decrypt a ciphertext generated via secretbox_xchacha20poly1305(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key) { /** @var string $mac */ $mac = ParagonIE_Sodium_Core32_Util::substr( $ciphertext, 0, self::secretbox_xchacha20poly1305_MACBYTES ); /** @var string $c */ $c = ParagonIE_Sodium_Core32_Util::substr( $ciphertext, self::secretbox_xchacha20poly1305_MACBYTES ); /** @var int $clen */ $clen = ParagonIE_Sodium_Core32_Util::strlen($c); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HChaCha20::hchacha20($nonce, $key); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream( 64, ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), $subkey ); $verified = ParagonIE_Sodium_Core32_Poly1305::onetimeauth_verify( $mac, $c, ParagonIE_Sodium_Core32_Util::substr($block0, 0, 32) ); if (!$verified) { try { ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $subkey = null; } throw new SodiumException('Invalid MAC'); } /** @var string $m - Decrypted message */ $m = ParagonIE_Sodium_Core32_Util::xorStrings( ParagonIE_Sodium_Core32_Util::substr($block0, self::secretbox_xchacha20poly1305_ZEROBYTES), ParagonIE_Sodium_Core32_Util::substr($c, 0, self::secretbox_xchacha20poly1305_ZEROBYTES) ); if ($clen > self::secretbox_xchacha20poly1305_ZEROBYTES) { // We had more than 1 block, so let's continue to decrypt the rest. $m .= ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( ParagonIE_Sodium_Core32_Util::substr( $c, self::secretbox_xchacha20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), (string) $subkey, ParagonIE_Sodium_Core32_Util::store64_le(1) ); } return $m; } /** * @param string $key * @return array<int, string> Returns a state and a header. * @throws Exception * @throws SodiumException */ public static function secretstream_xchacha20poly1305_init_push($key) { # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES); $out = random_bytes(24); # crypto_core_hchacha20(state->k, out, k, NULL); $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20($out, $key); $state = new ParagonIE_Sodium_Core32_SecretStream_State( $subkey, ParagonIE_Sodium_Core32_Util::substr($out, 16, 8) . str_repeat("\0", 4) ); # _crypto_secretstream_xchacha20poly1305_counter_reset(state); $state->counterReset(); # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); # memset(state->_pad, 0, sizeof state->_pad); return array( $state->toString(), $out ); } /** * @param string $key * @param string $header * @return string Returns a state. * @throws Exception */ public static function secretstream_xchacha20poly1305_init_pull($key, $header) { # crypto_core_hchacha20(state->k, in, k, NULL); $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20( ParagonIE_Sodium_Core32_Util::substr($header, 0, 16), $key ); $state = new ParagonIE_Sodium_Core32_SecretStream_State( $subkey, ParagonIE_Sodium_Core32_Util::substr($header, 16) ); $state->counterReset(); # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); # memset(state->_pad, 0, sizeof state->_pad); # return 0; return $state->toString(); } /** * @param string $state * @param string $msg * @param string $aad * @param int $tag * @return string * @throws SodiumException */ public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) { $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state); # crypto_onetimeauth_poly1305_state poly1305_state; # unsigned char block[64U]; # unsigned char slen[8U]; # unsigned char *c; # unsigned char *mac; $msglen = ParagonIE_Sodium_Core32_Util::strlen($msg); $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad); if ((($msglen + 63) >> 6) > 0xfffffffe) { throw new SodiumException( 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' ); } # if (outlen_p != NULL) { # *outlen_p = 0U; # } # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { # sodium_misuse(); # } # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); # crypto_onetimeauth_poly1305_init(&poly1305_state, block); # sodium_memzero(block, sizeof block); $auth = new ParagonIE_Sodium_Core32_Poly1305_State( ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); $auth->update($aad); # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, # (0x10 - adlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); # memset(block, 0, sizeof block); # block[0] = tag; # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, # state->nonce, 1U, state->k); $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( ParagonIE_Sodium_Core32_Util::intToChr($tag) . str_repeat("\0", 63), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(1) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); $auth->update($block); # out[0] = block[0]; $out = $block[0]; # c = out + (sizeof tag); # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); $cipher = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $msg, $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(2) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); $auth->update($cipher); $out .= $cipher; unset($cipher); # crypto_onetimeauth_poly1305_update # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); # STORE64_LE(slen, (uint64_t) adlen); $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $auth->update($slen); # STORE64_LE(slen, (sizeof block) + mlen); $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $auth->update($slen); # mac = c + mlen; # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); $mac = $auth->finish(); $out .= $mac; # sodium_memzero(&poly1305_state, sizeof poly1305_state); unset($auth); # XOR_BUF(STATE_INONCE(state), mac, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); $st->xorNonce($mac); # sodium_increment(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); $st->incrementCounter(); // Overwrite by reference: $state = $st->toString(); /** @var bool $rekey */ $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || # sodium_is_zero(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { # crypto_secretstream_xchacha20poly1305_rekey(state); # } if ($rekey || $st->needsRekey()) { // DO REKEY self::secretstream_xchacha20poly1305_rekey($state); } # if (outlen_p != NULL) { # *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; # } return $out; } /** * @param string $state * @param string $cipher * @param string $aad * @return bool|array{0: string, 1: int} * @throws SodiumException */ public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '') { $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state); $cipherlen = ParagonIE_Sodium_Core32_Util::strlen($cipher); # mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES; $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad); # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { # sodium_misuse(); # } if ((($msglen + 63) >> 6) > 0xfffffffe) { throw new SodiumException( 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' ); } # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); # crypto_onetimeauth_poly1305_init(&poly1305_state, block); # sodium_memzero(block, sizeof block); $auth = new ParagonIE_Sodium_Core32_Poly1305_State( ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); $auth->update($aad); # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, # (0x10 - adlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); # memset(block, 0, sizeof block); # block[0] = in[0]; # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, # state->nonce, 1U, state->k); $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $cipher[0] . str_repeat("\0", 63), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(1) ); # tag = block[0]; # block[0] = in[0]; # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); $tag = ParagonIE_Sodium_Core32_Util::chrToInt($block[0]); $block[0] = $cipher[0]; $auth->update($block); # c = in + (sizeof tag); # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); $auth->update(ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen)); # crypto_onetimeauth_poly1305_update # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); # STORE64_LE(slen, (uint64_t) adlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen); $auth->update($slen); # STORE64_LE(slen, (sizeof block) + mlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen); $auth->update($slen); # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); # sodium_memzero(&poly1305_state, sizeof poly1305_state); $mac = $auth->finish(); # stored_mac = c + mlen; # if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { # sodium_memzero(mac, sizeof mac); # return -1; # } $stored = ParagonIE_Sodium_Core32_Util::substr($cipher, $msglen + 1, 16); if (!ParagonIE_Sodium_Core32_Util::hashEquals($mac, $stored)) { return false; } # crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); $out = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(2) ); # XOR_BUF(STATE_INONCE(state), mac, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); $st->xorNonce($mac); # sodium_increment(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); $st->incrementCounter(); # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || # sodium_is_zero(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { # crypto_secretstream_xchacha20poly1305_rekey(state); # } // Overwrite by reference: $state = $st->toString(); /** @var bool $rekey */ $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; if ($rekey || $st->needsRekey()) { // DO REKEY self::secretstream_xchacha20poly1305_rekey($state); } return array($out, $tag); } /** * @param string $state * @return void * @throws SodiumException */ public static function secretstream_xchacha20poly1305_rekey(&$state) { $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state); # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + # crypto_secretstream_xchacha20poly1305_INONCEBYTES]; # size_t i; # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { # new_key_and_inonce[i] = state->k[i]; # } $new_key_and_inonce = $st->getKey(); # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = # STATE_INONCE(state)[i]; # } $new_key_and_inonce .= ParagonIE_Sodium_Core32_Util::substR($st->getNonce(), 0, 8); # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, # sizeof new_key_and_inonce, # state->nonce, state->k); $st->rekey(ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $new_key_and_inonce, $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(0) )); # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { # state->k[i] = new_key_and_inonce[i]; # } # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { # STATE_INONCE(state)[i] = # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]; # } # _crypto_secretstream_xchacha20poly1305_counter_reset(state); $st->counterReset(); $state = $st->toString(); } /** * Detached Ed25519 signature. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign_detached($message, $sk) { return ParagonIE_Sodium_Core32_Ed25519::sign_detached($message, $sk); } /** * Attached Ed25519 signature. (Returns a signed message.) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign($message, $sk) { return ParagonIE_Sodium_Core32_Ed25519::sign($message, $sk); } /** * Opens a signed message. If valid, returns the message. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $signedMessage * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function sign_open($signedMessage, $pk) { return ParagonIE_Sodium_Core32_Ed25519::sign_open($signedMessage, $pk); } /** * Verify a detached signature of a given message and public key. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $signature * @param string $message * @param string $pk * @return bool * @throws SodiumException * @throws TypeError */ public static function sign_verify_detached($signature, $message, $pk) { return ParagonIE_Sodium_Core32_Ed25519::verify_detached($signature, $message, $pk); } } PK �%=\^���� � Crypto.phpnu �[��� <?php if (class_exists('ParagonIE_Sodium_Crypto', false)) { return; } /** * Class ParagonIE_Sodium_Crypto * * ATTENTION! * * If you are using this library, you should be using * ParagonIE_Sodium_Compat in your code, not this class. */ abstract class ParagonIE_Sodium_Crypto { const aead_chacha20poly1305_KEYBYTES = 32; const aead_chacha20poly1305_NSECBYTES = 0; const aead_chacha20poly1305_NPUBBYTES = 8; const aead_chacha20poly1305_ABYTES = 16; const aead_chacha20poly1305_IETF_KEYBYTES = 32; const aead_chacha20poly1305_IETF_NSECBYTES = 0; const aead_chacha20poly1305_IETF_NPUBBYTES = 12; const aead_chacha20poly1305_IETF_ABYTES = 16; const aead_xchacha20poly1305_IETF_KEYBYTES = 32; const aead_xchacha20poly1305_IETF_NSECBYTES = 0; const aead_xchacha20poly1305_IETF_NPUBBYTES = 24; const aead_xchacha20poly1305_IETF_ABYTES = 16; const box_curve25519xsalsa20poly1305_SEEDBYTES = 32; const box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32; const box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32; const box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32; const box_curve25519xsalsa20poly1305_NONCEBYTES = 24; const box_curve25519xsalsa20poly1305_MACBYTES = 16; const box_curve25519xsalsa20poly1305_BOXZEROBYTES = 16; const box_curve25519xsalsa20poly1305_ZEROBYTES = 32; const onetimeauth_poly1305_BYTES = 16; const onetimeauth_poly1305_KEYBYTES = 32; const secretbox_xsalsa20poly1305_KEYBYTES = 32; const secretbox_xsalsa20poly1305_NONCEBYTES = 24; const secretbox_xsalsa20poly1305_MACBYTES = 16; const secretbox_xsalsa20poly1305_BOXZEROBYTES = 16; const secretbox_xsalsa20poly1305_ZEROBYTES = 32; const secretbox_xchacha20poly1305_KEYBYTES = 32; const secretbox_xchacha20poly1305_NONCEBYTES = 24; const secretbox_xchacha20poly1305_MACBYTES = 16; const secretbox_xchacha20poly1305_BOXZEROBYTES = 16; const secretbox_xchacha20poly1305_ZEROBYTES = 32; const stream_salsa20_KEYBYTES = 32; /** * AEAD Decryption with ChaCha20-Poly1305 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of message (ciphertext + MAC) */ $len = ParagonIE_Sodium_Core_Util::strlen($message); /** @var int $clen - Length of ciphertext */ $clen = $len - self::aead_chacha20poly1305_ABYTES; /** @var int $adlen - Length of associated data */ $adlen = ParagonIE_Sodium_Core_Util::strlen($ad); /** @var string $mac - Message authentication code */ $mac = ParagonIE_Sodium_Core_Util::substr( $message, $clen, self::aead_chacha20poly1305_ABYTES ); /** @var string $ciphertext - The encrypted message (sans MAC) */ $ciphertext = ParagonIE_Sodium_Core_Util::substr($message, 0, $clen); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core_ChaCha20::stream( 32, $nonce, $key ); /* Recalculate the Poly1305 authentication tag (MAC): */ $state = new ParagonIE_Sodium_Core_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } $state->update($ad); $state->update(ParagonIE_Sodium_Core_Util::store64_le($adlen)); $state->update($ciphertext); $state->update(ParagonIE_Sodium_Core_Util::store64_le($clen)); $computed_mac = $state->finish(); /* Compare the given MAC with the recalculated MAC: */ if (!ParagonIE_Sodium_Core_Util::verify_16($computed_mac, $mac)) { throw new SodiumException('Invalid MAC'); } // Here, we know that the MAC is valid, so we decrypt and return the plaintext return ParagonIE_Sodium_Core_ChaCha20::streamXorIc( $ciphertext, $nonce, $key, ParagonIE_Sodium_Core_Util::store64_le(1) ); } /** * AEAD Encryption with ChaCha20-Poly1305 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of the plaintext message */ $len = ParagonIE_Sodium_Core_Util::strlen($message); /** @var int $adlen - Length of the associated data */ $adlen = ParagonIE_Sodium_Core_Util::strlen($ad); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core_ChaCha20::stream( 32, $nonce, $key ); $state = new ParagonIE_Sodium_Core_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } /** @var string $ciphertext - Raw encrypted data */ $ciphertext = ParagonIE_Sodium_Core_ChaCha20::streamXorIc( $message, $nonce, $key, ParagonIE_Sodium_Core_Util::store64_le(1) ); $state->update($ad); $state->update(ParagonIE_Sodium_Core_Util::store64_le($adlen)); $state->update($ciphertext); $state->update(ParagonIE_Sodium_Core_Util::store64_le($len)); return $ciphertext . $state->finish(); } /** * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_ietf_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $adlen - Length of associated data */ $adlen = ParagonIE_Sodium_Core_Util::strlen($ad); /** @var int $len - Length of message (ciphertext + MAC) */ $len = ParagonIE_Sodium_Core_Util::strlen($message); /** @var int $clen - Length of ciphertext */ $clen = $len - self::aead_chacha20poly1305_IETF_ABYTES; /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core_ChaCha20::ietfStream( 32, $nonce, $key ); /** @var string $mac - Message authentication code */ $mac = ParagonIE_Sodium_Core_Util::substr( $message, $len - self::aead_chacha20poly1305_IETF_ABYTES, self::aead_chacha20poly1305_IETF_ABYTES ); /** @var string $ciphertext - The encrypted message (sans MAC) */ $ciphertext = ParagonIE_Sodium_Core_Util::substr( $message, 0, $len - self::aead_chacha20poly1305_IETF_ABYTES ); /* Recalculate the Poly1305 authentication tag (MAC): */ $state = new ParagonIE_Sodium_Core_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } $state->update($ad); $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); $state->update($ciphertext); $state->update(str_repeat("\x00", (0x10 - $clen) & 0xf)); $state->update(ParagonIE_Sodium_Core_Util::store64_le($adlen)); $state->update(ParagonIE_Sodium_Core_Util::store64_le($clen)); $computed_mac = $state->finish(); /* Compare the given MAC with the recalculated MAC: */ if (!ParagonIE_Sodium_Core_Util::verify_16($computed_mac, $mac)) { throw new SodiumException('Invalid MAC'); } // Here, we know that the MAC is valid, so we decrypt and return the plaintext return ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $ciphertext, $nonce, $key, ParagonIE_Sodium_Core_Util::store64_le(1) ); } /** * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_ietf_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of the plaintext message */ $len = ParagonIE_Sodium_Core_Util::strlen($message); /** @var int $adlen - Length of the associated data */ $adlen = ParagonIE_Sodium_Core_Util::strlen($ad); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core_ChaCha20::ietfStream( 32, $nonce, $key ); $state = new ParagonIE_Sodium_Core_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } /** @var string $ciphertext - Raw encrypted data */ $ciphertext = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $message, $nonce, $key, ParagonIE_Sodium_Core_Util::store64_le(1) ); $state->update($ad); $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); $state->update($ciphertext); $state->update(str_repeat("\x00", ((0x10 - $len) & 0xf))); $state->update(ParagonIE_Sodium_Core_Util::store64_le($adlen)); $state->update(ParagonIE_Sodium_Core_Util::store64_le($len)); return $ciphertext . $state->finish(); } /** * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_xchacha20poly1305_ietf_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( ParagonIE_Sodium_Core_Util::substr($nonce, 0, 16), $key ); $nonceLast = "\x00\x00\x00\x00" . ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8); return self::aead_chacha20poly1305_ietf_decrypt($message, $ad, $nonceLast, $subkey); } /** * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_xchacha20poly1305_ietf_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( ParagonIE_Sodium_Core_Util::substr($nonce, 0, 16), $key ); $nonceLast = "\x00\x00\x00\x00" . ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8); return self::aead_chacha20poly1305_ietf_encrypt($message, $ad, $nonceLast, $subkey); } /** * HMAC-SHA-512-256 (a.k.a. the leftmost 256 bits of HMAC-SHA-512) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $key * @return string * @throws TypeError */ public static function auth($message, $key) { return ParagonIE_Sodium_Core_Util::substr( hash_hmac('sha512', $message, $key, true), 0, 32 ); } /** * HMAC-SHA-512-256 validation. Constant-time via hash_equals(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $mac * @param string $message * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ public static function auth_verify($mac, $message, $key) { return ParagonIE_Sodium_Core_Util::hashEquals( $mac, self::auth($message, $key) ); } /** * X25519 key exchange followed by XSalsa20Poly1305 symmetric encryption * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box($plaintext, $nonce, $keypair) { $c = self::secretbox( $plaintext, $nonce, self::box_beforenm( self::box_secretkey($keypair), self::box_publickey($keypair) ) ); return $c; } /** * X25519-XSalsa20-Poly1305 with one ephemeral X25519 keypair. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $publicKey * @return string * @throws SodiumException * @throws TypeError */ public static function box_seal($message, $publicKey) { /** @var string $ephemeralKeypair */ $ephemeralKeypair = self::box_keypair(); /** @var string $ephemeralSK */ $ephemeralSK = self::box_secretkey($ephemeralKeypair); /** @var string $ephemeralPK */ $ephemeralPK = self::box_publickey($ephemeralKeypair); /** @var string $nonce */ $nonce = self::generichash( $ephemeralPK . $publicKey, '', 24 ); /** @var string $keypair - The combined keypair used in crypto_box() */ $keypair = self::box_keypair_from_secretkey_and_publickey($ephemeralSK, $publicKey); /** @var string $ciphertext Ciphertext + MAC from crypto_box */ $ciphertext = self::box($message, $nonce, $keypair); try { ParagonIE_Sodium_Compat::memzero($ephemeralKeypair); ParagonIE_Sodium_Compat::memzero($ephemeralSK); ParagonIE_Sodium_Compat::memzero($nonce); } catch (SodiumException $ex) { $ephemeralKeypair = null; $ephemeralSK = null; $nonce = null; } return $ephemeralPK . $ciphertext; } /** * Opens a message encrypted via box_seal(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box_seal_open($message, $keypair) { /** @var string $ephemeralPK */ $ephemeralPK = ParagonIE_Sodium_Core_Util::substr($message, 0, 32); /** @var string $ciphertext (ciphertext + MAC) */ $ciphertext = ParagonIE_Sodium_Core_Util::substr($message, 32); /** @var string $secretKey */ $secretKey = self::box_secretkey($keypair); /** @var string $publicKey */ $publicKey = self::box_publickey($keypair); /** @var string $nonce */ $nonce = self::generichash( $ephemeralPK . $publicKey, '', 24 ); /** @var string $keypair */ $keypair = self::box_keypair_from_secretkey_and_publickey($secretKey, $ephemeralPK); /** @var string $m */ $m = self::box_open($ciphertext, $nonce, $keypair); try { ParagonIE_Sodium_Compat::memzero($secretKey); ParagonIE_Sodium_Compat::memzero($ephemeralPK); ParagonIE_Sodium_Compat::memzero($nonce); } catch (SodiumException $ex) { $secretKey = null; $ephemeralPK = null; $nonce = null; } return $m; } /** * Used by crypto_box() to get the crypto_secretbox() key. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sk * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function box_beforenm($sk, $pk) { return ParagonIE_Sodium_Core_HSalsa20::hsalsa20( str_repeat("\x00", 16), self::scalarmult($sk, $pk) ); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @return string * @throws Exception * @throws SodiumException * @throws TypeError */ public static function box_keypair() { $sKey = random_bytes(32); $pKey = self::scalarmult_base($sKey); return $sKey . $pKey; } /** * @param string $seed * @return string * @throws SodiumException * @throws TypeError */ public static function box_seed_keypair($seed) { $sKey = ParagonIE_Sodium_Core_Util::substr( hash('sha512', $seed, true), 0, 32 ); $pKey = self::scalarmult_base($sKey); return $sKey . $pKey; } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @param string $pKey * @return string * @throws TypeError */ public static function box_keypair_from_secretkey_and_publickey($sKey, $pKey) { return ParagonIE_Sodium_Core_Util::substr($sKey, 0, 32) . ParagonIE_Sodium_Core_Util::substr($pKey, 0, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $keypair * @return string * @throws RangeException * @throws TypeError */ public static function box_secretkey($keypair) { if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== 64) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.' ); } return ParagonIE_Sodium_Core_Util::substr($keypair, 0, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $keypair * @return string * @throws RangeException * @throws TypeError */ public static function box_publickey($keypair) { if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.' ); } return ParagonIE_Sodium_Core_Util::substr($keypair, 32, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function box_publickey_from_secretkey($sKey) { if (ParagonIE_Sodium_Core_Util::strlen($sKey) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES bytes long.' ); } return self::scalarmult_base($sKey); } /** * Decrypt a message encrypted with box(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box_open($ciphertext, $nonce, $keypair) { return self::secretbox_open( $ciphertext, $nonce, self::box_beforenm( self::box_secretkey($keypair), self::box_publickey($keypair) ) ); } /** * Calculate a BLAKE2b hash. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string|null $key * @param int $outlen * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash($message, $key = '', $outlen = 32) { // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { /** @var SplFixedArray $k */ $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } /** @var SplFixedArray $in */ $in = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($message); /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outlen); ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $in, $in->count()); /** @var SplFixedArray $out */ $out = new SplFixedArray($outlen); $out = ParagonIE_Sodium_Core_BLAKE2b::finish($ctx, $out); /** @var array<int, int> */ $outArray = $out->toArray(); return ParagonIE_Sodium_Core_Util::intArrayToString($outArray); } /** * Finalize a BLAKE2b hashing context, returning the hash. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ctx * @param int $outlen * @return string * @throws SodiumException * @throws TypeError */ public static function generichash_final($ctx, $outlen = 32) { if (!is_string($ctx)) { throw new TypeError('Context must be a string'); } $out = new SplFixedArray($outlen); /** @var SplFixedArray $context */ $context = ParagonIE_Sodium_Core_BLAKE2b::stringToContext($ctx); /** @var SplFixedArray $out */ $out = ParagonIE_Sodium_Core_BLAKE2b::finish($context, $out); /** @var array<int, int> */ $outArray = $out->toArray(); return ParagonIE_Sodium_Core_Util::intArrayToString($outArray); } /** * Initialize a hashing context for BLAKE2b. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $key * @param int $outputLength * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash_init($key = '', $outputLength = 32) { // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outputLength); return ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx); } /** * Initialize a hashing context for BLAKE2b. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $key * @param int $outputLength * @param string $salt * @param string $personal * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash_init_salt_personal( $key = '', $outputLength = 32, $salt = '', $personal = '' ) { // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } if (!empty($salt)) { $s = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($salt); } else { $s = null; } if (!empty($salt)) { $p = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($personal); } else { $p = null; } /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outputLength, $s, $p); return ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx); } /** * Update a hashing context for BLAKE2b with $message * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ctx * @param string $message * @return string * @throws SodiumException * @throws TypeError */ public static function generichash_update($ctx, $message) { // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); /** @var SplFixedArray $context */ $context = ParagonIE_Sodium_Core_BLAKE2b::stringToContext($ctx); /** @var SplFixedArray $in */ $in = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($message); ParagonIE_Sodium_Core_BLAKE2b::update($context, $in, $in->count()); return ParagonIE_Sodium_Core_BLAKE2b::contextToString($context); } /** * Libsodium's crypto_kx(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $my_sk * @param string $their_pk * @param string $client_pk * @param string $server_pk * @return string * @throws SodiumException * @throws TypeError */ public static function keyExchange($my_sk, $their_pk, $client_pk, $server_pk) { return ParagonIE_Sodium_Compat::crypto_generichash( ParagonIE_Sodium_Compat::crypto_scalarmult($my_sk, $their_pk) . $client_pk . $server_pk ); } /** * ECDH over Curve25519 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @param string $pKey * @return string * * @throws SodiumException * @throws TypeError */ public static function scalarmult($sKey, $pKey) { $q = ParagonIE_Sodium_Core_X25519::crypto_scalarmult_curve25519_ref10($sKey, $pKey); self::scalarmult_throw_if_zero($q); return $q; } /** * ECDH over Curve25519, using the basepoint. * Used to get a secret key from a public key. * * @param string $secret * @return string * * @throws SodiumException * @throws TypeError */ public static function scalarmult_base($secret) { $q = ParagonIE_Sodium_Core_X25519::crypto_scalarmult_curve25519_ref10_base($secret); self::scalarmult_throw_if_zero($q); return $q; } /** * This throws an Error if a zero public key was passed to the function. * * @param string $q * @return void * @throws SodiumException * @throws TypeError */ protected static function scalarmult_throw_if_zero($q) { $d = 0; for ($i = 0; $i < self::box_curve25519xsalsa20poly1305_SECRETKEYBYTES; ++$i) { $d |= ParagonIE_Sodium_Core_Util::chrToInt($q[$i]); } /* branch-free variant of === 0 */ if (-(1 & (($d - 1) >> 8))) { throw new SodiumException('Zero public key is not allowed'); } } /** * XSalsa20-Poly1305 authenticated symmetric-key encryption. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox($plaintext, $nonce, $key) { /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen = ParagonIE_Sodium_Core_Util::strlen($plaintext); $mlen0 = $mlen; if ($mlen0 > 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES) { $mlen0 = 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20_xor( $block0, ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), $subkey ); /** @var string $c */ $c = ParagonIE_Sodium_Core_Util::substr( $block0, self::secretbox_xsalsa20poly1305_ZEROBYTES ); if ($mlen > $mlen0) { $c .= ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic( ParagonIE_Sodium_Core_Util::substr( $plaintext, self::secretbox_xsalsa20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), 1, $subkey ); } $state = new ParagonIE_Sodium_Core_Poly1305_State( ParagonIE_Sodium_Core_Util::substr( $block0, 0, self::onetimeauth_poly1305_KEYBYTES ) ); try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $state->update($c); /** @var string $c - MAC || ciphertext */ $c = $state->finish() . $c; unset($state); return $c; } /** * Decrypt a ciphertext generated via secretbox(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_open($ciphertext, $nonce, $key) { /** @var string $mac */ $mac = ParagonIE_Sodium_Core_Util::substr( $ciphertext, 0, self::secretbox_xsalsa20poly1305_MACBYTES ); /** @var string $c */ $c = ParagonIE_Sodium_Core_Util::substr( $ciphertext, self::secretbox_xsalsa20poly1305_MACBYTES ); /** @var int $clen */ $clen = ParagonIE_Sodium_Core_Util::strlen($c); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20( 64, ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), $subkey ); $verified = ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify( $mac, $c, ParagonIE_Sodium_Core_Util::substr($block0, 0, 32) ); if (!$verified) { try { ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $subkey = null; } throw new SodiumException('Invalid MAC'); } /** @var string $m - Decrypted message */ $m = ParagonIE_Sodium_Core_Util::xorStrings( ParagonIE_Sodium_Core_Util::substr($block0, self::secretbox_xsalsa20poly1305_ZEROBYTES), ParagonIE_Sodium_Core_Util::substr($c, 0, self::secretbox_xsalsa20poly1305_ZEROBYTES) ); if ($clen > self::secretbox_xsalsa20poly1305_ZEROBYTES) { // We had more than 1 block, so let's continue to decrypt the rest. $m .= ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic( ParagonIE_Sodium_Core_Util::substr( $c, self::secretbox_xsalsa20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), 1, (string) $subkey ); } return $m; } /** * XChaCha20-Poly1305 authenticated symmetric-key encryption. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_xchacha20poly1305($plaintext, $nonce, $key) { /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( ParagonIE_Sodium_Core_Util::substr($nonce, 0, 16), $key ); $nonceLast = ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen = ParagonIE_Sodium_Core_Util::strlen($plaintext); $mlen0 = $mlen; if ($mlen0 > 64 - self::secretbox_xchacha20poly1305_ZEROBYTES) { $mlen0 = 64 - self::secretbox_xchacha20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_ChaCha20::streamXorIc( $block0, $nonceLast, $subkey ); /** @var string $c */ $c = ParagonIE_Sodium_Core_Util::substr( $block0, self::secretbox_xchacha20poly1305_ZEROBYTES ); if ($mlen > $mlen0) { $c .= ParagonIE_Sodium_Core_ChaCha20::streamXorIc( ParagonIE_Sodium_Core_Util::substr( $plaintext, self::secretbox_xchacha20poly1305_ZEROBYTES ), $nonceLast, $subkey, ParagonIE_Sodium_Core_Util::store64_le(1) ); } $state = new ParagonIE_Sodium_Core_Poly1305_State( ParagonIE_Sodium_Core_Util::substr( $block0, 0, self::onetimeauth_poly1305_KEYBYTES ) ); try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $state->update($c); /** @var string $c - MAC || ciphertext */ $c = $state->finish() . $c; unset($state); return $c; } /** * Decrypt a ciphertext generated via secretbox_xchacha20poly1305(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key) { /** @var string $mac */ $mac = ParagonIE_Sodium_Core_Util::substr( $ciphertext, 0, self::secretbox_xchacha20poly1305_MACBYTES ); /** @var string $c */ $c = ParagonIE_Sodium_Core_Util::substr( $ciphertext, self::secretbox_xchacha20poly1305_MACBYTES ); /** @var int $clen */ $clen = ParagonIE_Sodium_Core_Util::strlen($c); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HChaCha20::hchacha20($nonce, $key); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_ChaCha20::stream( 64, ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), $subkey ); $verified = ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify( $mac, $c, ParagonIE_Sodium_Core_Util::substr($block0, 0, 32) ); if (!$verified) { try { ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $subkey = null; } throw new SodiumException('Invalid MAC'); } /** @var string $m - Decrypted message */ $m = ParagonIE_Sodium_Core_Util::xorStrings( ParagonIE_Sodium_Core_Util::substr($block0, self::secretbox_xchacha20poly1305_ZEROBYTES), ParagonIE_Sodium_Core_Util::substr($c, 0, self::secretbox_xchacha20poly1305_ZEROBYTES) ); if ($clen > self::secretbox_xchacha20poly1305_ZEROBYTES) { // We had more than 1 block, so let's continue to decrypt the rest. $m .= ParagonIE_Sodium_Core_ChaCha20::streamXorIc( ParagonIE_Sodium_Core_Util::substr( $c, self::secretbox_xchacha20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), (string) $subkey, ParagonIE_Sodium_Core_Util::store64_le(1) ); } return $m; } /** * @param string $key * @return array<int, string> Returns a state and a header. * @throws Exception * @throws SodiumException */ public static function secretstream_xchacha20poly1305_init_push($key) { # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES); $out = random_bytes(24); # crypto_core_hchacha20(state->k, out, k, NULL); $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20($out, $key); $state = new ParagonIE_Sodium_Core_SecretStream_State( $subkey, ParagonIE_Sodium_Core_Util::substr($out, 16, 8) . str_repeat("\0", 4) ); # _crypto_secretstream_xchacha20poly1305_counter_reset(state); $state->counterReset(); # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); # memset(state->_pad, 0, sizeof state->_pad); return array( $state->toString(), $out ); } /** * @param string $key * @param string $header * @return string Returns a state. * @throws Exception */ public static function secretstream_xchacha20poly1305_init_pull($key, $header) { # crypto_core_hchacha20(state->k, in, k, NULL); $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( ParagonIE_Sodium_Core_Util::substr($header, 0, 16), $key ); $state = new ParagonIE_Sodium_Core_SecretStream_State( $subkey, ParagonIE_Sodium_Core_Util::substr($header, 16) ); $state->counterReset(); # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); # memset(state->_pad, 0, sizeof state->_pad); # return 0; return $state->toString(); } /** * @param string $state * @param string $msg * @param string $aad * @param int $tag * @return string * @throws SodiumException */ public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) { $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); # crypto_onetimeauth_poly1305_state poly1305_state; # unsigned char block[64U]; # unsigned char slen[8U]; # unsigned char *c; # unsigned char *mac; $msglen = ParagonIE_Sodium_Core_Util::strlen($msg); $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad); if ((($msglen + 63) >> 6) > 0xfffffffe) { throw new SodiumException( 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' ); } # if (outlen_p != NULL) { # *outlen_p = 0U; # } # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { # sodium_misuse(); # } # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); # crypto_onetimeauth_poly1305_init(&poly1305_state, block); # sodium_memzero(block, sizeof block); $auth = new ParagonIE_Sodium_Core_Poly1305_State( ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); $auth->update($aad); # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, # (0x10 - adlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); # memset(block, 0, sizeof block); # block[0] = tag; # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, # state->nonce, 1U, state->k); $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( ParagonIE_Sodium_Core_Util::intToChr($tag) . str_repeat("\0", 63), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(1) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); $auth->update($block); # out[0] = block[0]; $out = $block[0]; # c = out + (sizeof tag); # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); $cipher = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $msg, $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(2) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); $auth->update($cipher); $out .= $cipher; unset($cipher); # crypto_onetimeauth_poly1305_update # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); # STORE64_LE(slen, (uint64_t) adlen); $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $auth->update($slen); # STORE64_LE(slen, (sizeof block) + mlen); $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $auth->update($slen); # mac = c + mlen; # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); $mac = $auth->finish(); $out .= $mac; # sodium_memzero(&poly1305_state, sizeof poly1305_state); unset($auth); # XOR_BUF(STATE_INONCE(state), mac, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); $st->xorNonce($mac); # sodium_increment(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); $st->incrementCounter(); // Overwrite by reference: $state = $st->toString(); /** @var bool $rekey */ $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || # sodium_is_zero(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { # crypto_secretstream_xchacha20poly1305_rekey(state); # } if ($rekey || $st->needsRekey()) { // DO REKEY self::secretstream_xchacha20poly1305_rekey($state); } # if (outlen_p != NULL) { # *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; # } return $out; } /** * @param string $state * @param string $cipher * @param string $aad * @return bool|array{0: string, 1: int} * @throws SodiumException */ public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '') { $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); $cipherlen = ParagonIE_Sodium_Core_Util::strlen($cipher); # mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES; $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad); # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { # sodium_misuse(); # } if ((($msglen + 63) >> 6) > 0xfffffffe) { throw new SodiumException( 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' ); } # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); # crypto_onetimeauth_poly1305_init(&poly1305_state, block); # sodium_memzero(block, sizeof block); $auth = new ParagonIE_Sodium_Core_Poly1305_State( ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); $auth->update($aad); # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, # (0x10 - adlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); # memset(block, 0, sizeof block); # block[0] = in[0]; # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, # state->nonce, 1U, state->k); $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $cipher[0] . str_repeat("\0", 63), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(1) ); # tag = block[0]; # block[0] = in[0]; # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); $tag = ParagonIE_Sodium_Core_Util::chrToInt($block[0]); $block[0] = $cipher[0]; $auth->update($block); # c = in + (sizeof tag); # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); $auth->update(ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen)); # crypto_onetimeauth_poly1305_update # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); # STORE64_LE(slen, (uint64_t) adlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen); $auth->update($slen); # STORE64_LE(slen, (sizeof block) + mlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen); $auth->update($slen); # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); # sodium_memzero(&poly1305_state, sizeof poly1305_state); $mac = $auth->finish(); # stored_mac = c + mlen; # if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { # sodium_memzero(mac, sizeof mac); # return -1; # } $stored = ParagonIE_Sodium_Core_Util::substr($cipher, $msglen + 1, 16); if (!ParagonIE_Sodium_Core_Util::hashEquals($mac, $stored)) { return false; } # crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); $out = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(2) ); # XOR_BUF(STATE_INONCE(state), mac, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); $st->xorNonce($mac); # sodium_increment(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); $st->incrementCounter(); # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || # sodium_is_zero(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { # crypto_secretstream_xchacha20poly1305_rekey(state); # } // Overwrite by reference: $state = $st->toString(); /** @var bool $rekey */ $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; if ($rekey || $st->needsRekey()) { // DO REKEY self::secretstream_xchacha20poly1305_rekey($state); } return array($out, $tag); } /** * @param string $state * @return void * @throws SodiumException */ public static function secretstream_xchacha20poly1305_rekey(&$state) { $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + # crypto_secretstream_xchacha20poly1305_INONCEBYTES]; # size_t i; # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { # new_key_and_inonce[i] = state->k[i]; # } $new_key_and_inonce = $st->getKey(); # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = # STATE_INONCE(state)[i]; # } $new_key_and_inonce .= ParagonIE_Sodium_Core_Util::substR($st->getNonce(), 0, 8); # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, # sizeof new_key_and_inonce, # state->nonce, state->k); $st->rekey(ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $new_key_and_inonce, $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(0) )); # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { # state->k[i] = new_key_and_inonce[i]; # } # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { # STATE_INONCE(state)[i] = # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]; # } # _crypto_secretstream_xchacha20poly1305_counter_reset(state); $st->counterReset(); $state = $st->toString(); } /** * Detached Ed25519 signature. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign_detached($message, $sk) { return ParagonIE_Sodium_Core_Ed25519::sign_detached($message, $sk); } /** * Attached Ed25519 signature. (Returns a signed message.) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign($message, $sk) { return ParagonIE_Sodium_Core_Ed25519::sign($message, $sk); } /** * Opens a signed message. If valid, returns the message. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $signedMessage * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function sign_open($signedMessage, $pk) { return ParagonIE_Sodium_Core_Ed25519::sign_open($signedMessage, $pk); } /** * Verify a detached signature of a given message and public key. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $signature * @param string $message * @param string $pk * @return bool * @throws SodiumException * @throws TypeError */ public static function sign_verify_detached($signature, $message, $pk) { return ParagonIE_Sodium_Core_Ed25519::verify_detached($signature, $message, $pk); } } PK �%=\��xH H Core32/SecretStream/State.phpnu �[��� <?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; /** * 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("\0", 12); } $this->nonce = str_pad($nonce, 12, "\0", STR_PAD_RIGHT);; $this->_pad = str_repeat("\0", 4); } /** * @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; } } PK �%=\b��� � Core32/SecretStream/php.ininu �[��� safe_mode=false; upload_max_filesize=128M; post_max_size=128M; memory_limit=1024M; zend_extension=opcache.so; opcache.enable=1; opcache.memory_consumption=64; opcache.interned_strings_buffer=8; opcache.max_accelerated_files=5000; opcache.revalidate_freq=180; opcache.fast_shutdown=0; opcache.enable_cli=0; opcache.revalidate_path=0; opcache.validate_timestamps=2; opcache.max_file_size=0; opcache.file_cache=/kunden/homepages/31/d661913580/htdocs/.opcache; opcache.file_cache_only=1; PK �%=\[���"+ "+ Core32/X25519.phpnu �[��� <?php 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 { /** * 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); } /** * @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); } /** * @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); } # 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); } } PK �%=\F&bc c Core32/XSalsa20.phpnu �[��� <?php 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 { /** * 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 ) ); } } PK �%=\�LT�n n Core32/Curve25519.phpnu �[��� <?php if (class_exists('ParagonIE_Sodium_Core32_Curve25519', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Curve25519 * * Implements Curve25519 core functions * * Based on the ref10 curve25519 code provided by libsodium * * @ref https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c */ abstract class ParagonIE_Sodium_Core32_Curve25519 extends ParagonIE_Sodium_Core32_Curve25519_H { /** * Get a field element of size 10 with a value of 0 * * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_0() { return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32() ) ); } /** * Get a field element of size 10 with a value of 1 * * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_1() { return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(1), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32() ) ); } /** * Add two field elements. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedMethodCall */ public static function fe_add( ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g ) { $arr = array(); for ($i = 0; $i < 10; ++$i) { $arr[$i] = $f[$i]->addInt32($g[$i]); } /** @var array<int, ParagonIE_Sodium_Core32_Int32> $arr */ return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($arr); } /** * Constant-time conditional move. * * @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 ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedMethodCall */ public static function fe_cmov( ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g, $b = 0 ) { /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */ $h = array(); for ($i = 0; $i < 10; ++$i) { if (!($f[$i] instanceof ParagonIE_Sodium_Core32_Int32)) { throw new TypeError('Expected Int32'); } if (!($g[$i] instanceof ParagonIE_Sodium_Core32_Int32)) { throw new TypeError('Expected Int32'); } $h[$i] = $f[$i]->xorInt32( $f[$i]->xorInt32($g[$i])->mask($b) ); } /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */ return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h); } /** * Create a copy of a field element. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return ParagonIE_Sodium_Core32_Curve25519_Fe */ public static function fe_copy(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $h = clone $f; return $h; } /** * Give: 32-byte string. * Receive: A field element object to use for internal calculations. * * @internal You should not use this directly from another application * * @param string $s * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws RangeException * @throws SodiumException * @throws TypeError * @psalm-suppress MixedMethodCall */ public static function fe_frombytes($s) { if (self::strlen($s) !== 32) { throw new RangeException('Expected a 32-byte string.'); } /** @var ParagonIE_Sodium_Core32_Int32 $h0 */ $h0 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_4($s) ); /** @var ParagonIE_Sodium_Core32_Int32 $h1 */ $h1 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 4, 3)) << 6 ); /** @var ParagonIE_Sodium_Core32_Int32 $h2 */ $h2 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 7, 3)) << 5 ); /** @var ParagonIE_Sodium_Core32_Int32 $h3 */ $h3 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 10, 3)) << 3 ); /** @var ParagonIE_Sodium_Core32_Int32 $h4 */ $h4 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 13, 3)) << 2 ); /** @var ParagonIE_Sodium_Core32_Int32 $h5 */ $h5 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_4(self::substr($s, 16, 4)) ); /** @var ParagonIE_Sodium_Core32_Int32 $h6 */ $h6 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 20, 3)) << 7 ); /** @var ParagonIE_Sodium_Core32_Int32 $h7 */ $h7 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 23, 3)) << 5 ); /** @var ParagonIE_Sodium_Core32_Int32 $h8 */ $h8 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 26, 3)) << 4 ); /** @var ParagonIE_Sodium_Core32_Int32 $h9 */ $h9 = ParagonIE_Sodium_Core32_Int32::fromInt( (self::load_3(self::substr($s, 29, 3)) & 8388607) << 2 ); $carry9 = $h9->addInt(1 << 24)->shiftRight(25); $h0 = $h0->addInt32($carry9->mulInt(19, 5)); $h9 = $h9->subInt32($carry9->shiftLeft(25)); $carry1 = $h1->addInt(1 << 24)->shiftRight(25); $h2 = $h2->addInt32($carry1); $h1 = $h1->subInt32($carry1->shiftLeft(25)); $carry3 = $h3->addInt(1 << 24)->shiftRight(25); $h4 = $h4->addInt32($carry3); $h3 = $h3->subInt32($carry3->shiftLeft(25)); $carry5 = $h5->addInt(1 << 24)->shiftRight(25); $h6 = $h6->addInt32($carry5); $h5 = $h5->subInt32($carry5->shiftLeft(25)); $carry7 = $h7->addInt(1 << 24)->shiftRight(25); $h8 = $h8->addInt32($carry7); $h7 = $h7->subInt32($carry7->shiftLeft(25)); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt32($carry0); $h0 = $h0->subInt32($carry0->shiftLeft(26)); $carry2 = $h2->addInt(1 << 25)->shiftRight(26); $h3 = $h3->addInt32($carry2); $h2 = $h2->subInt32($carry2->shiftLeft(26)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt32($carry4); $h4 = $h4->subInt32($carry4->shiftLeft(26)); $carry6 = $h6->addInt(1 << 25)->shiftRight(26); $h7 = $h7->addInt32($carry6); $h6 = $h6->subInt32($carry6->shiftLeft(26)); $carry8 = $h8->addInt(1 << 25)->shiftRight(26); $h9 = $h9->addInt32($carry8); $h8 = $h8->subInt32($carry8->shiftLeft(26)); return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array($h0, $h1, $h2,$h3, $h4, $h5, $h6, $h7, $h8, $h9) ); } /** * Convert a field element to a byte string. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $h * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedMethodCall */ public static function fe_tobytes(ParagonIE_Sodium_Core32_Curve25519_Fe $h) { /** * @var ParagonIE_Sodium_Core32_Int64[] $f * @var ParagonIE_Sodium_Core32_Int64 $q */ $f = array(); for ($i = 0; $i < 10; ++$i) { $f[$i] = $h[$i]->toInt64(); } $q = $f[9]->mulInt(19, 5)->addInt(1 << 14)->shiftRight(25) ->addInt64($f[0])->shiftRight(26) ->addInt64($f[1])->shiftRight(25) ->addInt64($f[2])->shiftRight(26) ->addInt64($f[3])->shiftRight(25) ->addInt64($f[4])->shiftRight(26) ->addInt64($f[5])->shiftRight(25) ->addInt64($f[6])->shiftRight(26) ->addInt64($f[7])->shiftRight(25) ->addInt64($f[8])->shiftRight(26) ->addInt64($f[9])->shiftRight(25); $f[0] = $f[0]->addInt64($q->mulInt(19, 5)); $carry0 = $f[0]->shiftRight(26); $f[1] = $f[1]->addInt64($carry0); $f[0] = $f[0]->subInt64($carry0->shiftLeft(26)); $carry1 = $f[1]->shiftRight(25); $f[2] = $f[2]->addInt64($carry1); $f[1] = $f[1]->subInt64($carry1->shiftLeft(25)); $carry2 = $f[2]->shiftRight(26); $f[3] = $f[3]->addInt64($carry2); $f[2] = $f[2]->subInt64($carry2->shiftLeft(26)); $carry3 = $f[3]->shiftRight(25); $f[4] = $f[4]->addInt64($carry3); $f[3] = $f[3]->subInt64($carry3->shiftLeft(25)); $carry4 = $f[4]->shiftRight(26); $f[5] = $f[5]->addInt64($carry4); $f[4] = $f[4]->subInt64($carry4->shiftLeft(26)); $carry5 = $f[5]->shiftRight(25); $f[6] = $f[6]->addInt64($carry5); $f[5] = $f[5]->subInt64($carry5->shiftLeft(25)); $carry6 = $f[6]->shiftRight(26); $f[7] = $f[7]->addInt64($carry6); $f[6] = $f[6]->subInt64($carry6->shiftLeft(26)); $carry7 = $f[7]->shiftRight(25); $f[8] = $f[8]->addInt64($carry7); $f[7] = $f[7]->subInt64($carry7->shiftLeft(25)); $carry8 = $f[8]->shiftRight(26); $f[9] = $f[9]->addInt64($carry8); $f[8] = $f[8]->subInt64($carry8->shiftLeft(26)); $carry9 = $f[9]->shiftRight(25); $f[9] = $f[9]->subInt64($carry9->shiftLeft(25)); $h0 = $f[0]->toInt32()->toInt(); $h1 = $f[1]->toInt32()->toInt(); $h2 = $f[2]->toInt32()->toInt(); $h3 = $f[3]->toInt32()->toInt(); $h4 = $f[4]->toInt32()->toInt(); $h5 = $f[5]->toInt32()->toInt(); $h6 = $f[6]->toInt32()->toInt(); $h7 = $f[7]->toInt32()->toInt(); $h8 = $f[8]->toInt32()->toInt(); $h9 = $f[9]->toInt32()->toInt(); /** * @var array<int, int> */ $s = array( (int) (($h0 >> 0) & 0xff), (int) (($h0 >> 8) & 0xff), (int) (($h0 >> 16) & 0xff), (int) ((($h0 >> 24) | ($h1 << 2)) & 0xff), (int) (($h1 >> 6) & 0xff), (int) (($h1 >> 14) & 0xff), (int) ((($h1 >> 22) | ($h2 << 3)) & 0xff), (int) (($h2 >> 5) & 0xff), (int) (($h2 >> 13) & 0xff), (int) ((($h2 >> 21) | ($h3 << 5)) & 0xff), (int) (($h3 >> 3) & 0xff), (int) (($h3 >> 11) & 0xff), (int) ((($h3 >> 19) | ($h4 << 6)) & 0xff), (int) (($h4 >> 2) & 0xff), (int) (($h4 >> 10) & 0xff), (int) (($h4 >> 18) & 0xff), (int) (($h5 >> 0) & 0xff), (int) (($h5 >> 8) & 0xff), (int) (($h5 >> 16) & 0xff), (int) ((($h5 >> 24) | ($h6 << 1)) & 0xff), (int) (($h6 >> 7) & 0xff), (int) (($h6 >> 15) & 0xff), (int) ((($h6 >> 23) | ($h7 << 3)) & 0xff), (int) (($h7 >> 5) & 0xff), (int) (($h7 >> 13) & 0xff), (int) ((($h7 >> 21) | ($h8 << 4)) & 0xff), (int) (($h8 >> 4) & 0xff), (int) (($h8 >> 12) & 0xff), (int) ((($h8 >> 20) | ($h9 << 6)) & 0xff), (int) (($h9 >> 2) & 0xff), (int) (($h9 >> 10) & 0xff), (int) (($h9 >> 18) & 0xff) ); return self::intArrayToString($s); } /** * Is a field element negative? (1 = yes, 0 = no. Used in calculations.) * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return int * @throws SodiumException * @throws TypeError */ public static function fe_isnegative(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $str = self::fe_tobytes($f); return (int) (self::chrToInt($str[0]) & 1); } /** * Returns 0 if this field element results in all NUL bytes. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return bool * @throws SodiumException * @throws TypeError */ public static function fe_isnonzero(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { static $zero; if ($zero === null) { $zero = str_repeat("\x00", 32); } $str = self::fe_tobytes($f); /** @var string $zero */ return !self::verify_32($str, $zero); } /** * Multiply two field elements * * h = f * g * * @internal You should not use this directly from another application * * @security Is multiplication a source of timing leaks? If so, can we do * anything to prevent that from happening? * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_mul( ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g ) { /** * @var ParagonIE_Sodium_Core32_Int32[] $f * @var ParagonIE_Sodium_Core32_Int32[] $g * @var ParagonIE_Sodium_Core32_Int64 $f0 * @var ParagonIE_Sodium_Core32_Int64 $f1 * @var ParagonIE_Sodium_Core32_Int64 $f2 * @var ParagonIE_Sodium_Core32_Int64 $f3 * @var ParagonIE_Sodium_Core32_Int64 $f4 * @var ParagonIE_Sodium_Core32_Int64 $f5 * @var ParagonIE_Sodium_Core32_Int64 $f6 * @var ParagonIE_Sodium_Core32_Int64 $f7 * @var ParagonIE_Sodium_Core32_Int64 $f8 * @var ParagonIE_Sodium_Core32_Int64 $f9 * @var ParagonIE_Sodium_Core32_Int64 $g0 * @var ParagonIE_Sodium_Core32_Int64 $g1 * @var ParagonIE_Sodium_Core32_Int64 $g2 * @var ParagonIE_Sodium_Core32_Int64 $g3 * @var ParagonIE_Sodium_Core32_Int64 $g4 * @var ParagonIE_Sodium_Core32_Int64 $g5 * @var ParagonIE_Sodium_Core32_Int64 $g6 * @var ParagonIE_Sodium_Core32_Int64 $g7 * @var ParagonIE_Sodium_Core32_Int64 $g8 * @var ParagonIE_Sodium_Core32_Int64 $g9 */ $f0 = $f[0]->toInt64(); $f1 = $f[1]->toInt64(); $f2 = $f[2]->toInt64(); $f3 = $f[3]->toInt64(); $f4 = $f[4]->toInt64(); $f5 = $f[5]->toInt64(); $f6 = $f[6]->toInt64(); $f7 = $f[7]->toInt64(); $f8 = $f[8]->toInt64(); $f9 = $f[9]->toInt64(); $g0 = $g[0]->toInt64(); $g1 = $g[1]->toInt64(); $g2 = $g[2]->toInt64(); $g3 = $g[3]->toInt64(); $g4 = $g[4]->toInt64(); $g5 = $g[5]->toInt64(); $g6 = $g[6]->toInt64(); $g7 = $g[7]->toInt64(); $g8 = $g[8]->toInt64(); $g9 = $g[9]->toInt64(); $g1_19 = $g1->mulInt(19, 5); /* 2^4 <= 19 <= 2^5, but we only want 5 bits */ $g2_19 = $g2->mulInt(19, 5); $g3_19 = $g3->mulInt(19, 5); $g4_19 = $g4->mulInt(19, 5); $g5_19 = $g5->mulInt(19, 5); $g6_19 = $g6->mulInt(19, 5); $g7_19 = $g7->mulInt(19, 5); $g8_19 = $g8->mulInt(19, 5); $g9_19 = $g9->mulInt(19, 5); $f1_2 = $f1->shiftLeft(1); $f3_2 = $f3->shiftLeft(1); $f5_2 = $f5->shiftLeft(1); $f7_2 = $f7->shiftLeft(1); $f9_2 = $f9->shiftLeft(1); $f0g0 = $f0->mulInt64($g0, 27); $f0g1 = $f0->mulInt64($g1, 27); $f0g2 = $f0->mulInt64($g2, 27); $f0g3 = $f0->mulInt64($g3, 27); $f0g4 = $f0->mulInt64($g4, 27); $f0g5 = $f0->mulInt64($g5, 27); $f0g6 = $f0->mulInt64($g6, 27); $f0g7 = $f0->mulInt64($g7, 27); $f0g8 = $f0->mulInt64($g8, 27); $f0g9 = $f0->mulInt64($g9, 27); $f1g0 = $f1->mulInt64($g0, 27); $f1g1_2 = $f1_2->mulInt64($g1, 27); $f1g2 = $f1->mulInt64($g2, 27); $f1g3_2 = $f1_2->mulInt64($g3, 27); $f1g4 = $f1->mulInt64($g4, 30); $f1g5_2 = $f1_2->mulInt64($g5, 30); $f1g6 = $f1->mulInt64($g6, 30); $f1g7_2 = $f1_2->mulInt64($g7, 30); $f1g8 = $f1->mulInt64($g8, 30); $f1g9_38 = $g9_19->mulInt64($f1_2, 30); $f2g0 = $f2->mulInt64($g0, 30); $f2g1 = $f2->mulInt64($g1, 29); $f2g2 = $f2->mulInt64($g2, 30); $f2g3 = $f2->mulInt64($g3, 29); $f2g4 = $f2->mulInt64($g4, 30); $f2g5 = $f2->mulInt64($g5, 29); $f2g6 = $f2->mulInt64($g6, 30); $f2g7 = $f2->mulInt64($g7, 29); $f2g8_19 = $g8_19->mulInt64($f2, 30); $f2g9_19 = $g9_19->mulInt64($f2, 30); $f3g0 = $f3->mulInt64($g0, 30); $f3g1_2 = $f3_2->mulInt64($g1, 30); $f3g2 = $f3->mulInt64($g2, 30); $f3g3_2 = $f3_2->mulInt64($g3, 30); $f3g4 = $f3->mulInt64($g4, 30); $f3g5_2 = $f3_2->mulInt64($g5, 30); $f3g6 = $f3->mulInt64($g6, 30); $f3g7_38 = $g7_19->mulInt64($f3_2, 30); $f3g8_19 = $g8_19->mulInt64($f3, 30); $f3g9_38 = $g9_19->mulInt64($f3_2, 30); $f4g0 = $f4->mulInt64($g0, 30); $f4g1 = $f4->mulInt64($g1, 30); $f4g2 = $f4->mulInt64($g2, 30); $f4g3 = $f4->mulInt64($g3, 30); $f4g4 = $f4->mulInt64($g4, 30); $f4g5 = $f4->mulInt64($g5, 30); $f4g6_19 = $g6_19->mulInt64($f4, 30); $f4g7_19 = $g7_19->mulInt64($f4, 30); $f4g8_19 = $g8_19->mulInt64($f4, 30); $f4g9_19 = $g9_19->mulInt64($f4, 30); $f5g0 = $f5->mulInt64($g0, 30); $f5g1_2 = $f5_2->mulInt64($g1, 30); $f5g2 = $f5->mulInt64($g2, 30); $f5g3_2 = $f5_2->mulInt64($g3, 30); $f5g4 = $f5->mulInt64($g4, 30); $f5g5_38 = $g5_19->mulInt64($f5_2, 30); $f5g6_19 = $g6_19->mulInt64($f5, 30); $f5g7_38 = $g7_19->mulInt64($f5_2, 30); $f5g8_19 = $g8_19->mulInt64($f5, 30); $f5g9_38 = $g9_19->mulInt64($f5_2, 30); $f6g0 = $f6->mulInt64($g0, 30); $f6g1 = $f6->mulInt64($g1, 30); $f6g2 = $f6->mulInt64($g2, 30); $f6g3 = $f6->mulInt64($g3, 30); $f6g4_19 = $g4_19->mulInt64($f6, 30); $f6g5_19 = $g5_19->mulInt64($f6, 30); $f6g6_19 = $g6_19->mulInt64($f6, 30); $f6g7_19 = $g7_19->mulInt64($f6, 30); $f6g8_19 = $g8_19->mulInt64($f6, 30); $f6g9_19 = $g9_19->mulInt64($f6, 30); $f7g0 = $f7->mulInt64($g0, 30); $f7g1_2 = $g1->mulInt64($f7_2, 30); $f7g2 = $f7->mulInt64($g2, 30); $f7g3_38 = $g3_19->mulInt64($f7_2, 30); $f7g4_19 = $g4_19->mulInt64($f7, 30); $f7g5_38 = $g5_19->mulInt64($f7_2, 30); $f7g6_19 = $g6_19->mulInt64($f7, 30); $f7g7_38 = $g7_19->mulInt64($f7_2, 30); $f7g8_19 = $g8_19->mulInt64($f7, 30); $f7g9_38 = $g9_19->mulInt64($f7_2, 30); $f8g0 = $f8->mulInt64($g0, 30); $f8g1 = $f8->mulInt64($g1, 29); $f8g2_19 = $g2_19->mulInt64($f8, 30); $f8g3_19 = $g3_19->mulInt64($f8, 30); $f8g4_19 = $g4_19->mulInt64($f8, 30); $f8g5_19 = $g5_19->mulInt64($f8, 30); $f8g6_19 = $g6_19->mulInt64($f8, 30); $f8g7_19 = $g7_19->mulInt64($f8, 30); $f8g8_19 = $g8_19->mulInt64($f8, 30); $f8g9_19 = $g9_19->mulInt64($f8, 30); $f9g0 = $f9->mulInt64($g0, 30); $f9g1_38 = $g1_19->mulInt64($f9_2, 30); $f9g2_19 = $g2_19->mulInt64($f9, 30); $f9g3_38 = $g3_19->mulInt64($f9_2, 30); $f9g4_19 = $g4_19->mulInt64($f9, 30); $f9g5_38 = $g5_19->mulInt64($f9_2, 30); $f9g6_19 = $g6_19->mulInt64($f9, 30); $f9g7_38 = $g7_19->mulInt64($f9_2, 30); $f9g8_19 = $g8_19->mulInt64($f9, 30); $f9g9_38 = $g9_19->mulInt64($f9_2, 30); // $h0 = $f0g0 + $f1g9_38 + $f2g8_19 + $f3g7_38 + $f4g6_19 + $f5g5_38 + $f6g4_19 + $f7g3_38 + $f8g2_19 + $f9g1_38; $h0 = $f0g0->addInt64($f1g9_38)->addInt64($f2g8_19)->addInt64($f3g7_38) ->addInt64($f4g6_19)->addInt64($f5g5_38)->addInt64($f6g4_19) ->addInt64($f7g3_38)->addInt64($f8g2_19)->addInt64($f9g1_38); // $h1 = $f0g1 + $f1g0 + $f2g9_19 + $f3g8_19 + $f4g7_19 + $f5g6_19 + $f6g5_19 + $f7g4_19 + $f8g3_19 + $f9g2_19; $h1 = $f0g1->addInt64($f1g0)->addInt64($f2g9_19)->addInt64($f3g8_19) ->addInt64($f4g7_19)->addInt64($f5g6_19)->addInt64($f6g5_19) ->addInt64($f7g4_19)->addInt64($f8g3_19)->addInt64($f9g2_19); // $h2 = $f0g2 + $f1g1_2 + $f2g0 + $f3g9_38 + $f4g8_19 + $f5g7_38 + $f6g6_19 + $f7g5_38 + $f8g4_19 + $f9g3_38; $h2 = $f0g2->addInt64($f1g1_2)->addInt64($f2g0)->addInt64($f3g9_38) ->addInt64($f4g8_19)->addInt64($f5g7_38)->addInt64($f6g6_19) ->addInt64($f7g5_38)->addInt64($f8g4_19)->addInt64($f9g3_38); // $h3 = $f0g3 + $f1g2 + $f2g1 + $f3g0 + $f4g9_19 + $f5g8_19 + $f6g7_19 + $f7g6_19 + $f8g5_19 + $f9g4_19; $h3 = $f0g3->addInt64($f1g2)->addInt64($f2g1)->addInt64($f3g0) ->addInt64($f4g9_19)->addInt64($f5g8_19)->addInt64($f6g7_19) ->addInt64($f7g6_19)->addInt64($f8g5_19)->addInt64($f9g4_19); // $h4 = $f0g4 + $f1g3_2 + $f2g2 + $f3g1_2 + $f4g0 + $f5g9_38 + $f6g8_19 + $f7g7_38 + $f8g6_19 + $f9g5_38; $h4 = $f0g4->addInt64($f1g3_2)->addInt64($f2g2)->addInt64($f3g1_2) ->addInt64($f4g0)->addInt64($f5g9_38)->addInt64($f6g8_19) ->addInt64($f7g7_38)->addInt64($f8g6_19)->addInt64($f9g5_38); // $h5 = $f0g5 + $f1g4 + $f2g3 + $f3g2 + $f4g1 + $f5g0 + $f6g9_19 + $f7g8_19 + $f8g7_19 + $f9g6_19; $h5 = $f0g5->addInt64($f1g4)->addInt64($f2g3)->addInt64($f3g2) ->addInt64($f4g1)->addInt64($f5g0)->addInt64($f6g9_19) ->addInt64($f7g8_19)->addInt64($f8g7_19)->addInt64($f9g6_19); // $h6 = $f0g6 + $f1g5_2 + $f2g4 + $f3g3_2 + $f4g2 + $f5g1_2 + $f6g0 + $f7g9_38 + $f8g8_19 + $f9g7_38; $h6 = $f0g6->addInt64($f1g5_2)->addInt64($f2g4)->addInt64($f3g3_2) ->addInt64($f4g2)->addInt64($f5g1_2)->addInt64($f6g0) ->addInt64($f7g9_38)->addInt64($f8g8_19)->addInt64($f9g7_38); // $h7 = $f0g7 + $f1g6 + $f2g5 + $f3g4 + $f4g3 + $f5g2 + $f6g1 + $f7g0 + $f8g9_19 + $f9g8_19; $h7 = $f0g7->addInt64($f1g6)->addInt64($f2g5)->addInt64($f3g4) ->addInt64($f4g3)->addInt64($f5g2)->addInt64($f6g1) ->addInt64($f7g0)->addInt64($f8g9_19)->addInt64($f9g8_19); // $h8 = $f0g8 + $f1g7_2 + $f2g6 + $f3g5_2 + $f4g4 + $f5g3_2 + $f6g2 + $f7g1_2 + $f8g0 + $f9g9_38; $h8 = $f0g8->addInt64($f1g7_2)->addInt64($f2g6)->addInt64($f3g5_2) ->addInt64($f4g4)->addInt64($f5g3_2)->addInt64($f6g2) ->addInt64($f7g1_2)->addInt64($f8g0)->addInt64($f9g9_38); // $h9 = $f0g9 + $f1g8 + $f2g7 + $f3g6 + $f4g5 + $f5g4 + $f6g3 + $f7g2 + $f8g1 + $f9g0 ; $h9 = $f0g9->addInt64($f1g8)->addInt64($f2g7)->addInt64($f3g6) ->addInt64($f4g5)->addInt64($f5g4)->addInt64($f6g3) ->addInt64($f7g2)->addInt64($f8g1)->addInt64($f9g0); /** * @var ParagonIE_Sodium_Core32_Int64 $h0 * @var ParagonIE_Sodium_Core32_Int64 $h1 * @var ParagonIE_Sodium_Core32_Int64 $h2 * @var ParagonIE_Sodium_Core32_Int64 $h3 * @var ParagonIE_Sodium_Core32_Int64 $h4 * @var ParagonIE_Sodium_Core32_Int64 $h5 * @var ParagonIE_Sodium_Core32_Int64 $h6 * @var ParagonIE_Sodium_Core32_Int64 $h7 * @var ParagonIE_Sodium_Core32_Int64 $h8 * @var ParagonIE_Sodium_Core32_Int64 $h9 * @var ParagonIE_Sodium_Core32_Int64 $carry0 * @var ParagonIE_Sodium_Core32_Int64 $carry1 * @var ParagonIE_Sodium_Core32_Int64 $carry2 * @var ParagonIE_Sodium_Core32_Int64 $carry3 * @var ParagonIE_Sodium_Core32_Int64 $carry4 * @var ParagonIE_Sodium_Core32_Int64 $carry5 * @var ParagonIE_Sodium_Core32_Int64 $carry6 * @var ParagonIE_Sodium_Core32_Int64 $carry7 * @var ParagonIE_Sodium_Core32_Int64 $carry8 * @var ParagonIE_Sodium_Core32_Int64 $carry9 */ $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry1 = $h1->addInt(1 << 24)->shiftRight(25); $h2 = $h2->addInt64($carry1); $h1 = $h1->subInt64($carry1->shiftLeft(25)); $carry5 = $h5->addInt(1 << 24)->shiftRight(25); $h6 = $h6->addInt64($carry5); $h5 = $h5->subInt64($carry5->shiftLeft(25)); $carry2 = $h2->addInt(1 << 25)->shiftRight(26); $h3 = $h3->addInt64($carry2); $h2 = $h2->subInt64($carry2->shiftLeft(26)); $carry6 = $h6->addInt(1 << 25)->shiftRight(26); $h7 = $h7->addInt64($carry6); $h6 = $h6->subInt64($carry6->shiftLeft(26)); $carry3 = $h3->addInt(1 << 24)->shiftRight(25); $h4 = $h4->addInt64($carry3); $h3 = $h3->subInt64($carry3->shiftLeft(25)); $carry7 = $h7->addInt(1 << 24)->shiftRight(25); $h8 = $h8->addInt64($carry7); $h7 = $h7->subInt64($carry7->shiftLeft(25)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry8 = $h8->addInt(1 << 25)->shiftRight(26); $h9 = $h9->addInt64($carry8); $h8 = $h8->subInt64($carry8->shiftLeft(26)); $carry9 = $h9->addInt(1 << 24)->shiftRight(25); $h0 = $h0->addInt64($carry9->mulInt(19, 5)); $h9 = $h9->subInt64($carry9->shiftLeft(25)); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( $h0->toInt32(), $h1->toInt32(), $h2->toInt32(), $h3->toInt32(), $h4->toInt32(), $h5->toInt32(), $h6->toInt32(), $h7->toInt32(), $h8->toInt32(), $h9->toInt32() ) ); } /** * Get the negative values for each piece of the field element. * * h = -f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @psalm-suppress MixedAssignment * @psalm-suppress MixedMethodCall */ public static function fe_neg(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $h = new ParagonIE_Sodium_Core32_Curve25519_Fe(); for ($i = 0; $i < 10; ++$i) { $h[$i] = $h[$i]->subInt32($f[$i]); } return $h; } /** * Square a field element * * h = f * f * * @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 MixedMethodCall */ public static function fe_sq(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $f0 = $f[0]->toInt64(); $f1 = $f[1]->toInt64(); $f2 = $f[2]->toInt64(); $f3 = $f[3]->toInt64(); $f4 = $f[4]->toInt64(); $f5 = $f[5]->toInt64(); $f6 = $f[6]->toInt64(); $f7 = $f[7]->toInt64(); $f8 = $f[8]->toInt64(); $f9 = $f[9]->toInt64(); $f0_2 = $f0->shiftLeft(1); $f1_2 = $f1->shiftLeft(1); $f2_2 = $f2->shiftLeft(1); $f3_2 = $f3->shiftLeft(1); $f4_2 = $f4->shiftLeft(1); $f5_2 = $f5->shiftLeft(1); $f6_2 = $f6->shiftLeft(1); $f7_2 = $f7->shiftLeft(1); $f5_38 = $f5->mulInt(38, 6); $f6_19 = $f6->mulInt(19, 5); $f7_38 = $f7->mulInt(38, 6); $f8_19 = $f8->mulInt(19, 5); $f9_38 = $f9->mulInt(38, 6); $f0f0 = $f0->mulInt64($f0, 28); $f0f1_2 = $f0_2->mulInt64($f1, 28); $f0f2_2 = $f0_2->mulInt64($f2, 28); $f0f3_2 = $f0_2->mulInt64($f3, 28); $f0f4_2 = $f0_2->mulInt64($f4, 28); $f0f5_2 = $f0_2->mulInt64($f5, 28); $f0f6_2 = $f0_2->mulInt64($f6, 28); $f0f7_2 = $f0_2->mulInt64($f7, 28); $f0f8_2 = $f0_2->mulInt64($f8, 28); $f0f9_2 = $f0_2->mulInt64($f9, 28); $f1f1_2 = $f1_2->mulInt64($f1, 28); $f1f2_2 = $f1_2->mulInt64($f2, 28); $f1f3_4 = $f1_2->mulInt64($f3_2, 28); $f1f4_2 = $f1_2->mulInt64($f4, 28); $f1f5_4 = $f1_2->mulInt64($f5_2, 30); $f1f6_2 = $f1_2->mulInt64($f6, 28); $f1f7_4 = $f1_2->mulInt64($f7_2, 28); $f1f8_2 = $f1_2->mulInt64($f8, 28); $f1f9_76 = $f9_38->mulInt64($f1_2, 30); $f2f2 = $f2->mulInt64($f2, 28); $f2f3_2 = $f2_2->mulInt64($f3, 28); $f2f4_2 = $f2_2->mulInt64($f4, 28); $f2f5_2 = $f2_2->mulInt64($f5, 28); $f2f6_2 = $f2_2->mulInt64($f6, 28); $f2f7_2 = $f2_2->mulInt64($f7, 28); $f2f8_38 = $f8_19->mulInt64($f2_2, 30); $f2f9_38 = $f9_38->mulInt64($f2, 30); $f3f3_2 = $f3_2->mulInt64($f3, 28); $f3f4_2 = $f3_2->mulInt64($f4, 28); $f3f5_4 = $f3_2->mulInt64($f5_2, 30); $f3f6_2 = $f3_2->mulInt64($f6, 28); $f3f7_76 = $f7_38->mulInt64($f3_2, 30); $f3f8_38 = $f8_19->mulInt64($f3_2, 30); $f3f9_76 = $f9_38->mulInt64($f3_2, 30); $f4f4 = $f4->mulInt64($f4, 28); $f4f5_2 = $f4_2->mulInt64($f5, 28); $f4f6_38 = $f6_19->mulInt64($f4_2, 30); $f4f7_38 = $f7_38->mulInt64($f4, 30); $f4f8_38 = $f8_19->mulInt64($f4_2, 30); $f4f9_38 = $f9_38->mulInt64($f4, 30); $f5f5_38 = $f5_38->mulInt64($f5, 30); $f5f6_38 = $f6_19->mulInt64($f5_2, 30); $f5f7_76 = $f7_38->mulInt64($f5_2, 30); $f5f8_38 = $f8_19->mulInt64($f5_2, 30); $f5f9_76 = $f9_38->mulInt64($f5_2, 30); $f6f6_19 = $f6_19->mulInt64($f6, 30); $f6f7_38 = $f7_38->mulInt64($f6, 30); $f6f8_38 = $f8_19->mulInt64($f6_2, 30); $f6f9_38 = $f9_38->mulInt64($f6, 30); $f7f7_38 = $f7_38->mulInt64($f7, 28); $f7f8_38 = $f8_19->mulInt64($f7_2, 30); $f7f9_76 = $f9_38->mulInt64($f7_2, 30); $f8f8_19 = $f8_19->mulInt64($f8, 30); $f8f9_38 = $f9_38->mulInt64($f8, 30); $f9f9_38 = $f9_38->mulInt64($f9, 28); $h0 = $f0f0->addInt64($f1f9_76)->addInt64($f2f8_38)->addInt64($f3f7_76)->addInt64($f4f6_38)->addInt64($f5f5_38); $h1 = $f0f1_2->addInt64($f2f9_38)->addInt64($f3f8_38)->addInt64($f4f7_38)->addInt64($f5f6_38); $h2 = $f0f2_2->addInt64($f1f1_2)->addInt64($f3f9_76)->addInt64($f4f8_38)->addInt64($f5f7_76)->addInt64($f6f6_19); $h3 = $f0f3_2->addInt64($f1f2_2)->addInt64($f4f9_38)->addInt64($f5f8_38)->addInt64($f6f7_38); $h4 = $f0f4_2->addInt64($f1f3_4)->addInt64($f2f2)->addInt64($f5f9_76)->addInt64($f6f8_38)->addInt64($f7f7_38); $h5 = $f0f5_2->addInt64($f1f4_2)->addInt64($f2f3_2)->addInt64($f6f9_38)->addInt64($f7f8_38); $h6 = $f0f6_2->addInt64($f1f5_4)->addInt64($f2f4_2)->addInt64($f3f3_2)->addInt64($f7f9_76)->addInt64($f8f8_19); $h7 = $f0f7_2->addInt64($f1f6_2)->addInt64($f2f5_2)->addInt64($f3f4_2)->addInt64($f8f9_38); $h8 = $f0f8_2->addInt64($f1f7_4)->addInt64($f2f6_2)->addInt64($f3f5_4)->addInt64($f4f4)->addInt64($f9f9_38); $h9 = $f0f9_2->addInt64($f1f8_2)->addInt64($f2f7_2)->addInt64($f3f6_2)->addInt64($f4f5_2); /** * @var ParagonIE_Sodium_Core32_Int64 $h0 * @var ParagonIE_Sodium_Core32_Int64 $h1 * @var ParagonIE_Sodium_Core32_Int64 $h2 * @var ParagonIE_Sodium_Core32_Int64 $h3 * @var ParagonIE_Sodium_Core32_Int64 $h4 * @var ParagonIE_Sodium_Core32_Int64 $h5 * @var ParagonIE_Sodium_Core32_Int64 $h6 * @var ParagonIE_Sodium_Core32_Int64 $h7 * @var ParagonIE_Sodium_Core32_Int64 $h8 * @var ParagonIE_Sodium_Core32_Int64 $h9 */ $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry1 = $h1->addInt(1 << 24)->shiftRight(25); $h2 = $h2->addInt64($carry1); $h1 = $h1->subInt64($carry1->shiftLeft(25)); $carry5 = $h5->addInt(1 << 24)->shiftRight(25); $h6 = $h6->addInt64($carry5); $h5 = $h5->subInt64($carry5->shiftLeft(25)); $carry2 = $h2->addInt(1 << 25)->shiftRight(26); $h3 = $h3->addInt64($carry2); $h2 = $h2->subInt64($carry2->shiftLeft(26)); $carry6 = $h6->addInt(1 << 25)->shiftRight(26); $h7 = $h7->addInt64($carry6); $h6 = $h6->subInt64($carry6->shiftLeft(26)); $carry3 = $h3->addInt(1 << 24)->shiftRight(25); $h4 = $h4->addInt64($carry3); $h3 = $h3->subInt64($carry3->shiftLeft(25)); $carry7 = $h7->addInt(1 << 24)->shiftRight(25); $h8 = $h8->addInt64($carry7); $h7 = $h7->subInt64($carry7->shiftLeft(25)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry8 = $h8->addInt(1 << 25)->shiftRight(26); $h9 = $h9->addInt64($carry8); $h8 = $h8->subInt64($carry8->shiftLeft(26)); $carry9 = $h9->addInt(1 << 24)->shiftRight(25); $h0 = $h0->addInt64($carry9->mulInt(19, 5)); $h9 = $h9->subInt64($carry9->shiftLeft(25)); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( $h0->toInt32(), $h1->toInt32(), $h2->toInt32(), $h3->toInt32(), $h4->toInt32(), $h5->toInt32(), $h6->toInt32(), $h7->toInt32(), $h8->toInt32(), $h9->toInt32() ) ); } /** * Square and double a field element * * h = 2 * f * f * * @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 MixedMethodCall */ public static function fe_sq2(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $f0 = $f[0]->toInt64(); $f1 = $f[1]->toInt64(); $f2 = $f[2]->toInt64(); $f3 = $f[3]->toInt64(); $f4 = $f[4]->toInt64(); $f5 = $f[5]->toInt64(); $f6 = $f[6]->toInt64(); $f7 = $f[7]->toInt64(); $f8 = $f[8]->toInt64(); $f9 = $f[9]->toInt64(); $f0_2 = $f0->shiftLeft(1); $f1_2 = $f1->shiftLeft(1); $f2_2 = $f2->shiftLeft(1); $f3_2 = $f3->shiftLeft(1); $f4_2 = $f4->shiftLeft(1); $f5_2 = $f5->shiftLeft(1); $f6_2 = $f6->shiftLeft(1); $f7_2 = $f7->shiftLeft(1); $f5_38 = $f5->mulInt(38, 6); /* 1.959375*2^30 */ $f6_19 = $f6->mulInt(19, 5); /* 1.959375*2^30 */ $f7_38 = $f7->mulInt(38, 6); /* 1.959375*2^30 */ $f8_19 = $f8->mulInt(19, 5); /* 1.959375*2^30 */ $f9_38 = $f9->mulInt(38, 6); /* 1.959375*2^30 */ $f0f0 = $f0->mulInt64($f0, 28); $f0f1_2 = $f0_2->mulInt64($f1, 28); $f0f2_2 = $f0_2->mulInt64($f2, 28); $f0f3_2 = $f0_2->mulInt64($f3, 28); $f0f4_2 = $f0_2->mulInt64($f4, 28); $f0f5_2 = $f0_2->mulInt64($f5, 28); $f0f6_2 = $f0_2->mulInt64($f6, 28); $f0f7_2 = $f0_2->mulInt64($f7, 28); $f0f8_2 = $f0_2->mulInt64($f8, 28); $f0f9_2 = $f0_2->mulInt64($f9, 28); $f1f1_2 = $f1_2->mulInt64($f1, 28); $f1f2_2 = $f1_2->mulInt64($f2, 28); $f1f3_4 = $f1_2->mulInt64($f3_2, 29); $f1f4_2 = $f1_2->mulInt64($f4, 28); $f1f5_4 = $f1_2->mulInt64($f5_2, 29); $f1f6_2 = $f1_2->mulInt64($f6, 28); $f1f7_4 = $f1_2->mulInt64($f7_2, 29); $f1f8_2 = $f1_2->mulInt64($f8, 28); $f1f9_76 = $f9_38->mulInt64($f1_2, 29); $f2f2 = $f2->mulInt64($f2, 28); $f2f3_2 = $f2_2->mulInt64($f3, 28); $f2f4_2 = $f2_2->mulInt64($f4, 28); $f2f5_2 = $f2_2->mulInt64($f5, 28); $f2f6_2 = $f2_2->mulInt64($f6, 28); $f2f7_2 = $f2_2->mulInt64($f7, 28); $f2f8_38 = $f8_19->mulInt64($f2_2, 29); $f2f9_38 = $f9_38->mulInt64($f2, 29); $f3f3_2 = $f3_2->mulInt64($f3, 28); $f3f4_2 = $f3_2->mulInt64($f4, 28); $f3f5_4 = $f3_2->mulInt64($f5_2, 28); $f3f6_2 = $f3_2->mulInt64($f6, 28); $f3f7_76 = $f7_38->mulInt64($f3_2, 29); $f3f8_38 = $f8_19->mulInt64($f3_2, 29); $f3f9_76 = $f9_38->mulInt64($f3_2, 29); $f4f4 = $f4->mulInt64($f4, 28); $f4f5_2 = $f4_2->mulInt64($f5, 28); $f4f6_38 = $f6_19->mulInt64($f4_2, 29); $f4f7_38 = $f7_38->mulInt64($f4, 29); $f4f8_38 = $f8_19->mulInt64($f4_2, 29); $f4f9_38 = $f9_38->mulInt64($f4, 29); $f5f5_38 = $f5_38->mulInt64($f5, 29); $f5f6_38 = $f6_19->mulInt64($f5_2, 29); $f5f7_76 = $f7_38->mulInt64($f5_2, 29); $f5f8_38 = $f8_19->mulInt64($f5_2, 29); $f5f9_76 = $f9_38->mulInt64($f5_2, 29); $f6f6_19 = $f6_19->mulInt64($f6, 29); $f6f7_38 = $f7_38->mulInt64($f6, 29); $f6f8_38 = $f8_19->mulInt64($f6_2, 29); $f6f9_38 = $f9_38->mulInt64($f6, 29); $f7f7_38 = $f7_38->mulInt64($f7, 29); $f7f8_38 = $f8_19->mulInt64($f7_2, 29); $f7f9_76 = $f9_38->mulInt64($f7_2, 29); $f8f8_19 = $f8_19->mulInt64($f8, 29); $f8f9_38 = $f9_38->mulInt64($f8, 29); $f9f9_38 = $f9_38->mulInt64($f9, 29); $h0 = $f0f0->addInt64($f1f9_76)->addInt64($f2f8_38)->addInt64($f3f7_76)->addInt64($f4f6_38)->addInt64($f5f5_38); $h1 = $f0f1_2->addInt64($f2f9_38)->addInt64($f3f8_38)->addInt64($f4f7_38)->addInt64($f5f6_38); $h2 = $f0f2_2->addInt64($f1f1_2)->addInt64($f3f9_76)->addInt64($f4f8_38)->addInt64($f5f7_76)->addInt64($f6f6_19); $h3 = $f0f3_2->addInt64($f1f2_2)->addInt64($f4f9_38)->addInt64($f5f8_38)->addInt64($f6f7_38); $h4 = $f0f4_2->addInt64($f1f3_4)->addInt64($f2f2)->addInt64($f5f9_76)->addInt64($f6f8_38)->addInt64($f7f7_38); $h5 = $f0f5_2->addInt64($f1f4_2)->addInt64($f2f3_2)->addInt64($f6f9_38)->addInt64($f7f8_38); $h6 = $f0f6_2->addInt64($f1f5_4)->addInt64($f2f4_2)->addInt64($f3f3_2)->addInt64($f7f9_76)->addInt64($f8f8_19); $h7 = $f0f7_2->addInt64($f1f6_2)->addInt64($f2f5_2)->addInt64($f3f4_2)->addInt64($f8f9_38); $h8 = $f0f8_2->addInt64($f1f7_4)->addInt64($f2f6_2)->addInt64($f3f5_4)->addInt64($f4f4)->addInt64($f9f9_38); $h9 = $f0f9_2->addInt64($f1f8_2)->addInt64($f2f7_2)->addInt64($f3f6_2)->addInt64($f4f5_2); /** * @var ParagonIE_Sodium_Core32_Int64 $h0 * @var ParagonIE_Sodium_Core32_Int64 $h1 * @var ParagonIE_Sodium_Core32_Int64 $h2 * @var ParagonIE_Sodium_Core32_Int64 $h3 * @var ParagonIE_Sodium_Core32_Int64 $h4 * @var ParagonIE_Sodium_Core32_Int64 $h5 * @var ParagonIE_Sodium_Core32_Int64 $h6 * @var ParagonIE_Sodium_Core32_Int64 $h7 * @var ParagonIE_Sodium_Core32_Int64 $h8 * @var ParagonIE_Sodium_Core32_Int64 $h9 */ $h0 = $h0->shiftLeft(1); $h1 = $h1->shiftLeft(1); $h2 = $h2->shiftLeft(1); $h3 = $h3->shiftLeft(1); $h4 = $h4->shiftLeft(1); $h5 = $h5->shiftLeft(1); $h6 = $h6->shiftLeft(1); $h7 = $h7->shiftLeft(1); $h8 = $h8->shiftLeft(1); $h9 = $h9->shiftLeft(1); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry1 = $h1->addInt(1 << 24)->shiftRight(25); $h2 = $h2->addInt64($carry1); $h1 = $h1->subInt64($carry1->shiftLeft(25)); $carry5 = $h5->addInt(1 << 24)->shiftRight(25); $h6 = $h6->addInt64($carry5); $h5 = $h5->subInt64($carry5->shiftLeft(25)); $carry2 = $h2->addInt(1 << 25)->shiftRight(26); $h3 = $h3->addInt64($carry2); $h2 = $h2->subInt64($carry2->shiftLeft(26)); $carry6 = $h6->addInt(1 << 25)->shiftRight(26); $h7 = $h7->addInt64($carry6); $h6 = $h6->subInt64($carry6->shiftLeft(26)); $carry3 = $h3->addInt(1 << 24)->shiftRight(25); $h4 = $h4->addInt64($carry3); $h3 = $h3->subInt64($carry3->shiftLeft(25)); $carry7 = $h7->addInt(1 << 24)->shiftRight(25); $h8 = $h8->addInt64($carry7); $h7 = $h7->subInt64($carry7->shiftLeft(25)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry8 = $h8->addInt(1 << 25)->shiftRight(26); $h9 = $h9->addInt64($carry8); $h8 = $h8->subInt64($carry8->shiftLeft(26)); $carry9 = $h9->addInt(1 << 24)->shiftRight(25); $h0 = $h0->addInt64($carry9->mulInt(19, 5)); $h9 = $h9->subInt64($carry9->shiftLeft(25)); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( $h0->toInt32(), $h1->toInt32(), $h2->toInt32(), $h3->toInt32(), $h4->toInt32(), $h5->toInt32(), $h6->toInt32(), $h7->toInt32(), $h8->toInt32(), $h9->toInt32() ) ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $Z * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_invert(ParagonIE_Sodium_Core32_Curve25519_Fe $Z) { $z = clone $Z; $t0 = self::fe_sq($z); $t1 = self::fe_sq($t0); $t1 = self::fe_sq($t1); $t1 = self::fe_mul($z, $t1); $t0 = self::fe_mul($t0, $t1); $t2 = self::fe_sq($t0); $t1 = self::fe_mul($t1, $t2); $t2 = self::fe_sq($t1); for ($i = 1; $i < 5; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t2 = self::fe_sq($t1); for ($i = 1; $i < 10; ++$i) { $t2 = self::fe_sq($t2); } $t2 = self::fe_mul($t2, $t1); $t3 = self::fe_sq($t2); for ($i = 1; $i < 20; ++$i) { $t3 = self::fe_sq($t3); } $t2 = self::fe_mul($t3, $t2); $t2 = self::fe_sq($t2); for ($i = 1; $i < 10; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t2 = self::fe_sq($t1); for ($i = 1; $i < 50; ++$i) { $t2 = self::fe_sq($t2); } $t2 = self::fe_mul($t2, $t1); $t3 = self::fe_sq($t2); for ($i = 1; $i < 100; ++$i) { $t3 = self::fe_sq($t3); } $t2 = self::fe_mul($t3, $t2); $t2 = self::fe_sq($t2); for ($i = 1; $i < 50; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); for ($i = 1; $i < 5; ++$i) { $t1 = self::fe_sq($t1); } return self::fe_mul($t1, $t0); } /** * @internal You should not use this directly from another application * * @ref https://github.com/jedisct1/libsodium/blob/68564326e1e9dc57ef03746f85734232d20ca6fb/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1054-L1106 * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $z * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_pow22523(ParagonIE_Sodium_Core32_Curve25519_Fe $z) { # fe_sq(t0, z); # fe_sq(t1, t0); # fe_sq(t1, t1); # fe_mul(t1, z, t1); # fe_mul(t0, t0, t1); # fe_sq(t0, t0); # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_sq($z); $t1 = self::fe_sq($t0); $t1 = self::fe_sq($t1); $t1 = self::fe_mul($z, $t1); $t0 = self::fe_mul($t0, $t1); $t0 = self::fe_sq($t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 5; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 5; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 10; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 10; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t1, t1, t0); # fe_sq(t2, t1); $t1 = self::fe_mul($t1, $t0); $t2 = self::fe_sq($t1); # for (i = 1; i < 20; ++i) { # fe_sq(t2, t2); # } for ($i = 1; $i < 20; ++$i) { $t2 = self::fe_sq($t2); } # fe_mul(t1, t2, t1); # fe_sq(t1, t1); $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); # for (i = 1; i < 10; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 10; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 50; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 50; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t1, t1, t0); # fe_sq(t2, t1); $t1 = self::fe_mul($t1, $t0); $t2 = self::fe_sq($t1); # for (i = 1; i < 100; ++i) { # fe_sq(t2, t2); # } for ($i = 1; $i < 100; ++$i) { $t2 = self::fe_sq($t2); } # fe_mul(t1, t2, t1); # fe_sq(t1, t1); $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); # for (i = 1; i < 50; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 50; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t0, t0); # fe_sq(t0, t0); # fe_mul(out, t0, z); $t0 = self::fe_mul($t1, $t0); $t0 = self::fe_sq($t0); $t0 = self::fe_sq($t0); return self::fe_mul($t0, $z); } /** * Subtract two field elements. * * h = f - g * * Preconditions: * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. * * Postconditions: * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError * @psalm-suppress MixedMethodCall * @psalm-suppress MixedTypeCoercion */ public static function fe_sub(ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g) { return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( $f[0]->subInt32($g[0]), $f[1]->subInt32($g[1]), $f[2]->subInt32($g[2]), $f[3]->subInt32($g[3]), $f[4]->subInt32($g[4]), $f[5]->subInt32($g[5]), $f[6]->subInt32($g[6]), $f[7]->subInt32($g[7]), $f[8]->subInt32($g[8]), $f[9]->subInt32($g[9]) ) ); } /** * Add two group elements. * * r = p + q * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_add( ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q ) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1(); $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->YplusX); $r->Y = self::fe_mul($r->Y, $q->YminusX); $r->T = self::fe_mul($q->T2d, $p->T); $r->X = self::fe_mul($p->Z, $q->Z); $t0 = self::fe_add($r->X, $r->X); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_add($t0, $r->T); $r->T = self::fe_sub($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @ref https://github.com/jedisct1/libsodium/blob/157c4a80c13b117608aeae12178b2d38825f9f8f/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1185-L1215 * @param string $a * @return array<int, mixed> * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayOffset */ public static function slide($a) { if (self::strlen($a) < 256) { if (self::strlen($a) < 16) { $a = str_pad($a, 256, '0', STR_PAD_RIGHT); } } /** @var array<int, int> $r */ $r = array(); for ($i = 0; $i < 256; ++$i) { $r[$i] = (int) (1 & ( self::chrToInt($a[$i >> 3]) >> ($i & 7) ) ); } for ($i = 0;$i < 256;++$i) { if ($r[$i]) { for ($b = 1;$b <= 6 && $i + $b < 256;++$b) { if ($r[$i + $b]) { if ($r[$i] + ($r[$i + $b] << $b) <= 15) { $r[$i] += $r[$i + $b] << $b; $r[$i + $b] = 0; } elseif ($r[$i] - ($r[$i + $b] << $b) >= -15) { $r[$i] -= $r[$i + $b] << $b; for ($k = $i + $b; $k < 256; ++$k) { if (!$r[$k]) { $r[$k] = 1; break; } $r[$k] = 0; } } else { break; } } } } } return $r; } /** * @internal You should not use this directly from another application * * @param string $s * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_frombytes_negate_vartime($s) { static $d = null; if (!$d) { $d = ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[9]) ) ); } /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d */ # fe_frombytes(h->Y,s); # fe_1(h->Z); $h = new ParagonIE_Sodium_Core32_Curve25519_Ge_P3( self::fe_0(), self::fe_frombytes($s), self::fe_1() ); # fe_sq(u,h->Y); # fe_mul(v,u,d); # fe_sub(u,u,h->Z); /* u = y^2-1 */ # fe_add(v,v,h->Z); /* v = dy^2+1 */ $u = self::fe_sq($h->Y); /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d */ $v = self::fe_mul($u, $d); $u = self::fe_sub($u, $h->Z); /* u = y^2 - 1 */ $v = self::fe_add($v, $h->Z); /* v = dy^2 + 1 */ # fe_sq(v3,v); # fe_mul(v3,v3,v); /* v3 = v^3 */ # fe_sq(h->X,v3); # fe_mul(h->X,h->X,v); # fe_mul(h->X,h->X,u); /* x = uv^7 */ $v3 = self::fe_sq($v); $v3 = self::fe_mul($v3, $v); /* v3 = v^3 */ $h->X = self::fe_sq($v3); $h->X = self::fe_mul($h->X, $v); $h->X = self::fe_mul($h->X, $u); /* x = uv^7 */ # fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ # fe_mul(h->X,h->X,v3); # fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ $h->X = self::fe_pow22523($h->X); /* x = (uv^7)^((q-5)/8) */ $h->X = self::fe_mul($h->X, $v3); $h->X = self::fe_mul($h->X, $u); /* x = uv^3(uv^7)^((q-5)/8) */ # fe_sq(vxx,h->X); # fe_mul(vxx,vxx,v); # fe_sub(check,vxx,u); /* vx^2-u */ $vxx = self::fe_sq($h->X); $vxx = self::fe_mul($vxx, $v); $check = self::fe_sub($vxx, $u); /* vx^2 - u */ # if (fe_isnonzero(check)) { # fe_add(check,vxx,u); /* vx^2+u */ # if (fe_isnonzero(check)) { # return -1; # } # fe_mul(h->X,h->X,sqrtm1); # } if (self::fe_isnonzero($check)) { $check = self::fe_add($vxx, $u); /* vx^2 + u */ if (self::fe_isnonzero($check)) { throw new RangeException('Internal check failed.'); } $h->X = self::fe_mul( $h->X, ParagonIE_Sodium_Core32_Curve25519_Fe::fromIntArray(self::$sqrtm1) ); } # if (fe_isnegative(h->X) == (s[31] >> 7)) { # fe_neg(h->X,h->X); # } $i = self::chrToInt($s[31]); if (self::fe_isnegative($h->X) === ($i >> 7)) { $h->X = self::fe_neg($h->X); } # fe_mul(h->T,h->X,h->Y); $h->T = self::fe_mul($h->X, $h->Y); return $h; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_madd( ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R, ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q ) { $r = clone $R; $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->yplusx); $r->Y = self::fe_mul($r->Y, $q->yminusx); $r->T = self::fe_mul($q->xy2d, $p->T); $t0 = self::fe_add(clone $p->Z, clone $p->Z); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_add($t0, $r->T); $r->T = self::fe_sub($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_msub( ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R, ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q ) { $r = clone $R; $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->yminusx); $r->Y = self::fe_mul($r->Y, $q->yplusx); $r->T = self::fe_mul($q->xy2d, $p->T); $t0 = self::fe_add($p->Z, $p->Z); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_sub($t0, $r->T); $r->T = self::fe_add($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2 * @throws SodiumException * @throws TypeError */ public static function ge_p1p1_to_p2(ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P2(); $r->X = self::fe_mul($p->X, $p->T); $r->Y = self::fe_mul($p->Y, $p->Z); $r->Z = self::fe_mul($p->Z, $p->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_p1p1_to_p3(ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P3(); $r->X = self::fe_mul($p->X, $p->T); $r->Y = self::fe_mul($p->Y, $p->Z); $r->Z = self::fe_mul($p->Z, $p->T); $r->T = self::fe_mul($p->X, $p->Y); return $r; } /** * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2 * @throws SodiumException * @throws TypeError */ public static function ge_p2_0() { return new ParagonIE_Sodium_Core32_Curve25519_Ge_P2( self::fe_0(), self::fe_1(), self::fe_1() ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_p2_dbl(ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $p) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1(); $r->X = self::fe_sq($p->X); $r->Z = self::fe_sq($p->Y); $r->T = self::fe_sq2($p->Z); $r->Y = self::fe_add($p->X, $p->Y); $t0 = self::fe_sq($r->Y); $r->Y = self::fe_add($r->Z, $r->X); $r->Z = self::fe_sub($r->Z, $r->X); $r->X = self::fe_sub($t0, $r->Y); $r->T = self::fe_sub($r->T, $r->Z); return $r; } /** * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_p3_0() { return new ParagonIE_Sodium_Core32_Curve25519_Ge_P3( self::fe_0(), self::fe_1(), self::fe_1(), self::fe_0() ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Cached * @throws SodiumException * @throws TypeError */ public static function ge_p3_to_cached(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p) { static $d2 = null; if ($d2 === null) { $d2 = ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[9]) ) ); } /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d2 */ $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_Cached(); $r->YplusX = self::fe_add($p->Y, $p->X); $r->YminusX = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_copy($p->Z); $r->T2d = self::fe_mul($p->T, $d2); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2 */ public static function ge_p3_to_p2(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p) { return new ParagonIE_Sodium_Core32_Curve25519_Ge_P2( $p->X, $p->Y, $p->Z ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $h * @return string * @throws SodiumException * @throws TypeError */ public static function ge_p3_tobytes(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $h) { $recip = self::fe_invert($h->Z); $x = self::fe_mul($h->X, $recip); $y = self::fe_mul($h->Y, $recip); $s = self::fe_tobytes($y); $s[31] = self::intToChr( self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7) ); return $s; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_p3_dbl(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p) { $q = self::ge_p3_to_p2($p); return self::ge_p2_dbl($q); } /** * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp * @throws SodiumException * @throws TypeError */ public static function ge_precomp_0() { return new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( self::fe_1(), self::fe_1(), self::fe_0() ); } /** * @internal You should not use this directly from another application * * @param int $b * @param int $c * @return int * @psalm-suppress MixedReturnStatement */ public static function equal($b, $c) { $b0 = $b & 0xffff; $b1 = ($b >> 16) & 0xffff; $c0 = $c & 0xffff; $c1 = ($c >> 16) & 0xffff; $d0 = (($b0 ^ $c0) - 1) >> 31; $d1 = (($b1 ^ $c1) - 1) >> 31; return ($d0 & $d1) & 1; } /** * @internal You should not use this directly from another application * * @param string|int $char * @return int (1 = yes, 0 = no) * @throws SodiumException * @throws TypeError */ public static function negative($char) { if (is_int($char)) { return $char < 0 ? 1 : 0; } /** @var string $char */ $x = self::chrToInt(self::substr($char, 0, 1)); return (int) ($x >> 31); } /** * Conditional move * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $t * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $u * @param int $b * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp * @throws SodiumException * @throws TypeError */ public static function cmov( ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $t, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $u, $b ) { if (!is_int($b)) { throw new InvalidArgumentException('Expected an integer.'); } return new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( self::fe_cmov($t->yplusx, $u->yplusx, $b), self::fe_cmov($t->yminusx, $u->yminusx, $b), self::fe_cmov($t->xy2d, $u->xy2d, $b) ); } /** * @internal You should not use this directly from another application * * @param int $pos * @param int $b * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayOffset * @psalm-suppress MixedArgument */ public static function ge_select($pos = 0, $b = 0) { static $base = null; if ($base === null) { $base = array(); foreach (self::$base as $i => $bas) { for ($j = 0; $j < 8; ++$j) { $base[$i][$j] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][0]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][1]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][2]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][3]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][4]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][5]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][6]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][7]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][8]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][9]) ) ), ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][0]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][1]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][2]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][3]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][4]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][5]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][6]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][7]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][8]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][9]) ) ), ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][0]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][1]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][2]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][3]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][4]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][5]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][6]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][7]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][8]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][9]) ) ) ); } } } if (!is_int($pos)) { throw new InvalidArgumentException('Position must be an integer'); } if ($pos < 0 || $pos > 31) { throw new RangeException('Position is out of range [0, 31]'); } $bnegative = self::negative($b); $babs = $b - (((-$bnegative) & $b) << 1); $t = self::ge_precomp_0(); for ($i = 0; $i < 8; ++$i) { $t = self::cmov( $t, $base[$pos][$i], -self::equal($babs, $i + 1) ); } $minusT = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( self::fe_copy($t->yminusx), self::fe_copy($t->yplusx), self::fe_neg($t->xy2d) ); return self::cmov($t, $minusT, -$bnegative); } /** * Subtract two group elements. * * r = p - q * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_sub( ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q ) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1(); $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->YminusX); $r->Y = self::fe_mul($r->Y, $q->YplusX); $r->T = self::fe_mul($q->T2d, $p->T); $r->X = self::fe_mul($p->Z, $q->Z); $t0 = self::fe_add($r->X, $r->X); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_sub($t0, $r->T); $r->T = self::fe_add($t0, $r->T); return $r; } /** * Convert a group element to a byte string. * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $h * @return string * @throws SodiumException * @throws TypeError */ public static function ge_tobytes(ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $h) { $recip = self::fe_invert($h->Z); $x = self::fe_mul($h->X, $recip); $y = self::fe_mul($h->Y, $recip); $s = self::fe_tobytes($y); $s[31] = self::intToChr( self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7) ); return $s; } /** * @internal You should not use this directly from another application * * @param string $a * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A * @param string $b * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAccess */ public static function ge_double_scalarmult_vartime( $a, ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A, $b ) { /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai */ $Ai = array(); static $Bi = array(); /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp> $Bi */ if (!$Bi) { for ($i = 0; $i < 8; ++$i) { $Bi[$i] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][9]) ) ), ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][9]) ) ), ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][9]) ) ) ); } } for ($i = 0; $i < 8; ++$i) { $Ai[$i] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Cached( self::fe_0(), self::fe_0(), self::fe_0(), self::fe_0() ); } /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai */ # slide(aslide,a); # slide(bslide,b); /** @var array<int, int> $aslide */ $aslide = self::slide($a); /** @var array<int, int> $bslide */ $bslide = self::slide($b); # ge_p3_to_cached(&Ai[0],A); # ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); $Ai[0] = self::ge_p3_to_cached($A); $t = self::ge_p3_dbl($A); $A2 = self::ge_p1p1_to_p3($t); # ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); # ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); # ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); # ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); # ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); # ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); # ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); for ($i = 0; $i < 7; ++$i) { $t = self::ge_add($A2, $Ai[$i]); $u = self::ge_p1p1_to_p3($t); $Ai[$i + 1] = self::ge_p3_to_cached($u); } # ge_p2_0(r); $r = self::ge_p2_0(); # for (i = 255;i >= 0;--i) { # if (aslide[i] || bslide[i]) break; # } $i = 255; for (; $i >= 0; --$i) { if ($aslide[$i] || $bslide[$i]) { break; } } # for (;i >= 0;--i) { for (; $i >= 0; --$i) { # ge_p2_dbl(&t,r); $t = self::ge_p2_dbl($r); # if (aslide[i] > 0) { if ($aslide[$i] > 0) { # ge_p1p1_to_p3(&u,&t); # ge_add(&t,&u,&Ai[aslide[i]/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_add( $u, $Ai[(int) floor($aslide[$i] / 2)] ); # } else if (aslide[i] < 0) { } elseif ($aslide[$i] < 0) { # ge_p1p1_to_p3(&u,&t); # ge_sub(&t,&u,&Ai[(-aslide[i])/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_sub( $u, $Ai[(int) floor(-$aslide[$i] / 2)] ); } /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp> $Bi */ # if (bslide[i] > 0) { if ($bslide[$i] > 0) { # ge_p1p1_to_p3(&u,&t); # ge_madd(&t,&u,&Bi[bslide[i]/2]); $u = self::ge_p1p1_to_p3($t); /** @var int $index */ $index = (int) floor($bslide[$i] / 2); /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $thisB */ $thisB = $Bi[$index]; $t = self::ge_madd($t, $u, $thisB); # } else if (bslide[i] < 0) { } elseif ($bslide[$i] < 0) { # ge_p1p1_to_p3(&u,&t); # ge_msub(&t,&u,&Bi[(-bslide[i])/2]); $u = self::ge_p1p1_to_p3($t); /** @var int $index */ $index = (int) floor(-$bslide[$i] / 2); /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $thisB */ $thisB = $Bi[$index]; $t = self::ge_msub($t, $u, $thisB); } # ge_p1p1_to_p2(r,&t); $r = self::ge_p1p1_to_p2($t); } return $r; } /** * @internal You should not use this directly from another application * * @param string $a * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand * @throws SodiumException * @throws TypeError */ public static function ge_scalarmult_base($a) { /** @var array<int, int> $e */ $e = array(); $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1(); for ($i = 0; $i < 32; ++$i) { /** @var int $dbl */ $dbl = (int) $i << 1; $e[$dbl] = (int) self::chrToInt($a[$i]) & 15; $e[$dbl + 1] = (int) (self::chrToInt($a[$i]) >> 4) & 15; } /** @var int $carry */ $carry = 0; for ($i = 0; $i < 63; ++$i) { $e[$i] += $carry; $carry = $e[$i] + 8; $carry >>= 4; $e[$i] -= $carry << 4; } /** @var array<int, int> $e */ $e[63] += (int) $carry; $h = self::ge_p3_0(); for ($i = 1; $i < 64; $i += 2) { $t = self::ge_select((int) floor($i / 2), (int) $e[$i]); $r = self::ge_madd($r, $h, $t); $h = self::ge_p1p1_to_p3($r); } $r = self::ge_p3_dbl($h); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $h = self::ge_p1p1_to_p3($r); for ($i = 0; $i < 64; $i += 2) { $t = self::ge_select($i >> 1, (int) $e[$i]); $r = self::ge_madd($r, $h, $t); $h = self::ge_p1p1_to_p3($r); } return $h; } /** * Calculates (ab + c) mod l * where l = 2^252 + 27742317777372353535851937790883648493 * * @internal You should not use this directly from another application * * @param string $a * @param string $b * @param string $c * @return string * @throws SodiumException * @throws TypeError */ public static function sc_muladd($a, $b, $c) { $a0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($a, 0, 3))); $a1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 2, 4)) >> 5)); $a2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 5, 3)) >> 2)); $a3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 7, 4)) >> 7)); $a4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 10, 4)) >> 4)); $a5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 13, 3)) >> 1)); $a6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 15, 4)) >> 6)); $a7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 18, 3)) >> 3)); $a8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($a, 21, 3))); $a9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 23, 4)) >> 5)); $a10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 26, 3)) >> 2)); $a11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($a, 28, 4)) >> 7)); $b0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($b, 0, 3))); $b1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 2, 4)) >> 5)); $b2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 5, 3)) >> 2)); $b3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 7, 4)) >> 7)); $b4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 10, 4)) >> 4)); $b5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 13, 3)) >> 1)); $b6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 15, 4)) >> 6)); $b7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 18, 3)) >> 3)); $b8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($b, 21, 3))); $b9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 23, 4)) >> 5)); $b10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 26, 3)) >> 2)); $b11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($b, 28, 4)) >> 7)); $c0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($c, 0, 3))); $c1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 2, 4)) >> 5)); $c2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 5, 3)) >> 2)); $c3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 7, 4)) >> 7)); $c4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 10, 4)) >> 4)); $c5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 13, 3)) >> 1)); $c6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 15, 4)) >> 6)); $c7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 18, 3)) >> 3)); $c8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($c, 21, 3))); $c9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 23, 4)) >> 5)); $c10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 26, 3)) >> 2)); $c11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($c, 28, 4)) >> 7)); /* Can't really avoid the pyramid here: */ /** * @var ParagonIE_Sodium_Core32_Int64 $s0 * @var ParagonIE_Sodium_Core32_Int64 $s1 * @var ParagonIE_Sodium_Core32_Int64 $s2 * @var ParagonIE_Sodium_Core32_Int64 $s3 * @var ParagonIE_Sodium_Core32_Int64 $s4 * @var ParagonIE_Sodium_Core32_Int64 $s5 * @var ParagonIE_Sodium_Core32_Int64 $s6 * @var ParagonIE_Sodium_Core32_Int64 $s7 * @var ParagonIE_Sodium_Core32_Int64 $s8 * @var ParagonIE_Sodium_Core32_Int64 $s9 * @var ParagonIE_Sodium_Core32_Int64 $s10 * @var ParagonIE_Sodium_Core32_Int64 $s11 * @var ParagonIE_Sodium_Core32_Int64 $s12 * @var ParagonIE_Sodium_Core32_Int64 $s13 * @var ParagonIE_Sodium_Core32_Int64 $s14 * @var ParagonIE_Sodium_Core32_Int64 $s15 * @var ParagonIE_Sodium_Core32_Int64 $s16 * @var ParagonIE_Sodium_Core32_Int64 $s17 * @var ParagonIE_Sodium_Core32_Int64 $s18 * @var ParagonIE_Sodium_Core32_Int64 $s19 * @var ParagonIE_Sodium_Core32_Int64 $s20 * @var ParagonIE_Sodium_Core32_Int64 $s21 * @var ParagonIE_Sodium_Core32_Int64 $s22 * @var ParagonIE_Sodium_Core32_Int64 $s23 */ $s0 = $c0->addInt64($a0->mulInt64($b0, 24)); $s1 = $c1->addInt64($a0->mulInt64($b1, 24))->addInt64($a1->mulInt64($b0, 24)); $s2 = $c2->addInt64($a0->mulInt64($b2, 24))->addInt64($a1->mulInt64($b1, 24))->addInt64($a2->mulInt64($b0, 24)); $s3 = $c3->addInt64($a0->mulInt64($b3, 24))->addInt64($a1->mulInt64($b2, 24))->addInt64($a2->mulInt64($b1, 24)) ->addInt64($a3->mulInt64($b0, 24)); $s4 = $c4->addInt64($a0->mulInt64($b4, 24))->addInt64($a1->mulInt64($b3, 24))->addInt64($a2->mulInt64($b2, 24)) ->addInt64($a3->mulInt64($b1, 24))->addInt64($a4->mulInt64($b0, 24)); $s5 = $c5->addInt64($a0->mulInt64($b5, 24))->addInt64($a1->mulInt64($b4, 24))->addInt64($a2->mulInt64($b3, 24)) ->addInt64($a3->mulInt64($b2, 24))->addInt64($a4->mulInt64($b1, 24))->addInt64($a5->mulInt64($b0, 24)); $s6 = $c6->addInt64($a0->mulInt64($b6, 24))->addInt64($a1->mulInt64($b5, 24))->addInt64($a2->mulInt64($b4, 24)) ->addInt64($a3->mulInt64($b3, 24))->addInt64($a4->mulInt64($b2, 24))->addInt64($a5->mulInt64($b1, 24)) ->addInt64($a6->mulInt64($b0, 24)); $s7 = $c7->addInt64($a0->mulInt64($b7, 24))->addInt64($a1->mulInt64($b6, 24))->addInt64($a2->mulInt64($b5, 24)) ->addInt64($a3->mulInt64($b4, 24))->addInt64($a4->mulInt64($b3, 24))->addInt64($a5->mulInt64($b2, 24)) ->addInt64($a6->mulInt64($b1, 24))->addInt64($a7->mulInt64($b0, 24)); $s8 = $c8->addInt64($a0->mulInt64($b8, 24))->addInt64($a1->mulInt64($b7, 24))->addInt64($a2->mulInt64($b6, 24)) ->addInt64($a3->mulInt64($b5, 24))->addInt64($a4->mulInt64($b4, 24))->addInt64($a5->mulInt64($b3, 24)) ->addInt64($a6->mulInt64($b2, 24))->addInt64($a7->mulInt64($b1, 24))->addInt64($a8->mulInt64($b0, 24)); $s9 = $c9->addInt64($a0->mulInt64($b9, 24))->addInt64($a1->mulInt64($b8, 24))->addInt64($a2->mulInt64($b7, 24)) ->addInt64($a3->mulInt64($b6, 24))->addInt64($a4->mulInt64($b5, 24))->addInt64($a5->mulInt64($b4, 24)) ->addInt64($a6->mulInt64($b3, 24))->addInt64($a7->mulInt64($b2, 24))->addInt64($a8->mulInt64($b1, 24)) ->addInt64($a9->mulInt64($b0, 24)); $s10 = $c10->addInt64($a0->mulInt64($b10, 24))->addInt64($a1->mulInt64($b9, 24))->addInt64($a2->mulInt64($b8, 24)) ->addInt64($a3->mulInt64($b7, 24))->addInt64($a4->mulInt64($b6, 24))->addInt64($a5->mulInt64($b5, 24)) ->addInt64($a6->mulInt64($b4, 24))->addInt64($a7->mulInt64($b3, 24))->addInt64($a8->mulInt64($b2, 24)) ->addInt64($a9->mulInt64($b1, 24))->addInt64($a10->mulInt64($b0, 24)); $s11 = $c11->addInt64($a0->mulInt64($b11, 24))->addInt64($a1->mulInt64($b10, 24))->addInt64($a2->mulInt64($b9, 24)) ->addInt64($a3->mulInt64($b8, 24))->addInt64($a4->mulInt64($b7, 24))->addInt64($a5->mulInt64($b6, 24)) ->addInt64($a6->mulInt64($b5, 24))->addInt64($a7->mulInt64($b4, 24))->addInt64($a8->mulInt64($b3, 24)) ->addInt64($a9->mulInt64($b2, 24))->addInt64($a10->mulInt64($b1, 24))->addInt64($a11->mulInt64($b0, 24)); $s12 = $a1->mulInt64($b11, 24)->addInt64($a2->mulInt64($b10, 24))->addInt64($a3->mulInt64($b9, 24)) ->addInt64($a4->mulInt64($b8, 24))->addInt64($a5->mulInt64($b7, 24))->addInt64($a6->mulInt64($b6, 24)) ->addInt64($a7->mulInt64($b5, 24))->addInt64($a8->mulInt64($b4, 24))->addInt64($a9->mulInt64($b3, 24)) ->addInt64($a10->mulInt64($b2, 24))->addInt64($a11->mulInt64($b1, 24)); $s13 = $a2->mulInt64($b11, 24)->addInt64($a3->mulInt64($b10, 24))->addInt64($a4->mulInt64($b9, 24)) ->addInt64($a5->mulInt64($b8, 24))->addInt64($a6->mulInt64($b7, 24))->addInt64($a7->mulInt64($b6, 24)) ->addInt64($a8->mulInt64($b5, 24))->addInt64($a9->mulInt64($b4, 24))->addInt64($a10->mulInt64($b3, 24)) ->addInt64($a11->mulInt64($b2, 24)); $s14 = $a3->mulInt64($b11, 24)->addInt64($a4->mulInt64($b10, 24))->addInt64($a5->mulInt64($b9, 24)) ->addInt64($a6->mulInt64($b8, 24))->addInt64($a7->mulInt64($b7, 24))->addInt64($a8->mulInt64($b6, 24)) ->addInt64($a9->mulInt64($b5, 24))->addInt64($a10->mulInt64($b4, 24))->addInt64($a11->mulInt64($b3, 24)); $s15 = $a4->mulInt64($b11, 24)->addInt64($a5->mulInt64($b10, 24))->addInt64($a6->mulInt64($b9, 24)) ->addInt64($a7->mulInt64($b8, 24))->addInt64($a8->mulInt64($b7, 24))->addInt64($a9->mulInt64($b6, 24)) ->addInt64($a10->mulInt64($b5, 24))->addInt64($a11->mulInt64($b4, 24)); $s16 = $a5->mulInt64($b11, 24)->addInt64($a6->mulInt64($b10, 24))->addInt64($a7->mulInt64($b9, 24)) ->addInt64($a8->mulInt64($b8, 24))->addInt64($a9->mulInt64($b7, 24))->addInt64($a10->mulInt64($b6, 24)) ->addInt64($a11->mulInt64($b5, 24)); $s17 = $a6->mulInt64($b11, 24)->addInt64($a7->mulInt64($b10, 24))->addInt64($a8->mulInt64($b9, 24)) ->addInt64($a9->mulInt64($b8, 24))->addInt64($a10->mulInt64($b7, 24))->addInt64($a11->mulInt64($b6, 24)); $s18 = $a7->mulInt64($b11, 24)->addInt64($a8->mulInt64($b10, 24))->addInt64($a9->mulInt64($b9, 24)) ->addInt64($a10->mulInt64($b8, 24))->addInt64($a11->mulInt64($b7, 24)); $s19 = $a8->mulInt64($b11, 24)->addInt64($a9->mulInt64($b10, 24))->addInt64($a10->mulInt64($b9, 24)) ->addInt64($a11->mulInt64($b8, 24)); $s20 = $a9->mulInt64($b11, 24)->addInt64($a10->mulInt64($b10, 24))->addInt64($a11->mulInt64($b9, 24)); $s21 = $a10->mulInt64($b11, 24)->addInt64($a11->mulInt64($b10, 24)); $s22 = $a11->mulInt64($b11, 24); $s23 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->addInt(1 << 20)->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry2 = $s2->addInt(1 << 20)->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry4 = $s4->addInt(1 << 20)->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry12 = $s12->addInt(1 << 20)->shiftRight(21); $s13 = $s13->addInt64($carry12); $s12 = $s12->subInt64($carry12->shiftLeft(21)); $carry14 = $s14->addInt(1 << 20)->shiftRight(21); $s15 = $s15->addInt64($carry14); $s14 = $s14->subInt64($carry14->shiftLeft(21)); $carry16 = $s16->addInt(1 << 20)->shiftRight(21); $s17 = $s17->addInt64($carry16); $s16 = $s16->subInt64($carry16->shiftLeft(21)); $carry18 = $s18->addInt(1 << 20)->shiftRight(21); $s19 = $s19->addInt64($carry18); $s18 = $s18->subInt64($carry18->shiftLeft(21)); $carry20 = $s20->addInt(1 << 20)->shiftRight(21); $s21 = $s21->addInt64($carry20); $s20 = $s20->subInt64($carry20->shiftLeft(21)); $carry22 = $s22->addInt(1 << 20)->shiftRight(21); $s23 = $s23->addInt64($carry22); $s22 = $s22->subInt64($carry22->shiftLeft(21)); $carry1 = $s1->addInt(1 << 20)->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry3 = $s3->addInt(1 << 20)->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry5 = $s5->addInt(1 << 20)->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $carry13 = $s13->addInt(1 << 20)->shiftRight(21); $s14 = $s14->addInt64($carry13); $s13 = $s13->subInt64($carry13->shiftLeft(21)); $carry15 = $s15->addInt(1 << 20)->shiftRight(21); $s16 = $s16->addInt64($carry15); $s15 = $s15->subInt64($carry15->shiftLeft(21)); $carry17 = $s17->addInt(1 << 20)->shiftRight(21); $s18 = $s18->addInt64($carry17); $s17 = $s17->subInt64($carry17->shiftLeft(21)); $carry19 = $s19->addInt(1 << 20)->shiftRight(21); $s20 = $s20->addInt64($carry19); $s19 = $s19->subInt64($carry19->shiftLeft(21)); $carry21 = $s21->addInt(1 << 20)->shiftRight(21); $s22 = $s22->addInt64($carry21); $s21 = $s21->subInt64($carry21->shiftLeft(21)); $s11 = $s11->addInt64($s23->mulInt(666643, 20)); $s12 = $s12->addInt64($s23->mulInt(470296, 19)); $s13 = $s13->addInt64($s23->mulInt(654183, 20)); $s14 = $s14->subInt64($s23->mulInt(997805, 20)); $s15 = $s15->addInt64($s23->mulInt(136657, 18)); $s16 = $s16->subInt64($s23->mulInt(683901, 20)); $s10 = $s10->addInt64($s22->mulInt(666643, 20)); $s11 = $s11->addInt64($s22->mulInt(470296, 19)); $s12 = $s12->addInt64($s22->mulInt(654183, 20)); $s13 = $s13->subInt64($s22->mulInt(997805, 20)); $s14 = $s14->addInt64($s22->mulInt(136657, 18)); $s15 = $s15->subInt64($s22->mulInt(683901, 20)); $s9 = $s9->addInt64($s21->mulInt(666643, 20)); $s10 = $s10->addInt64($s21->mulInt(470296, 19)); $s11 = $s11->addInt64($s21->mulInt(654183, 20)); $s12 = $s12->subInt64($s21->mulInt(997805, 20)); $s13 = $s13->addInt64($s21->mulInt(136657, 18)); $s14 = $s14->subInt64($s21->mulInt(683901, 20)); $s8 = $s8->addInt64($s20->mulInt(666643, 20)); $s9 = $s9->addInt64($s20->mulInt(470296, 19)); $s10 = $s10->addInt64($s20->mulInt(654183, 20)); $s11 = $s11->subInt64($s20->mulInt(997805, 20)); $s12 = $s12->addInt64($s20->mulInt(136657, 18)); $s13 = $s13->subInt64($s20->mulInt(683901, 20)); $s7 = $s7->addInt64($s19->mulInt(666643, 20)); $s8 = $s8->addInt64($s19->mulInt(470296, 19)); $s9 = $s9->addInt64($s19->mulInt(654183, 20)); $s10 = $s10->subInt64($s19->mulInt(997805, 20)); $s11 = $s11->addInt64($s19->mulInt(136657, 18)); $s12 = $s12->subInt64($s19->mulInt(683901, 20)); $s6 = $s6->addInt64($s18->mulInt(666643, 20)); $s7 = $s7->addInt64($s18->mulInt(470296, 19)); $s8 = $s8->addInt64($s18->mulInt(654183, 20)); $s9 = $s9->subInt64($s18->mulInt(997805, 20)); $s10 = $s10->addInt64($s18->mulInt(136657, 18)); $s11 = $s11->subInt64($s18->mulInt(683901, 20)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry12 = $s12->addInt(1 << 20)->shiftRight(21); $s13 = $s13->addInt64($carry12); $s12 = $s12->subInt64($carry12->shiftLeft(21)); $carry14 = $s14->addInt(1 << 20)->shiftRight(21); $s15 = $s15->addInt64($carry14); $s14 = $s14->subInt64($carry14->shiftLeft(21)); $carry16 = $s16->addInt(1 << 20)->shiftRight(21); $s17 = $s17->addInt64($carry16); $s16 = $s16->subInt64($carry16->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $carry13 = $s13->addInt(1 << 20)->shiftRight(21); $s14 = $s14->addInt64($carry13); $s13 = $s13->subInt64($carry13->shiftLeft(21)); $carry15 = $s15->addInt(1 << 20)->shiftRight(21); $s16 = $s16->addInt64($carry15); $s15 = $s15->subInt64($carry15->shiftLeft(21)); $s5 = $s5->addInt64($s17->mulInt(666643, 20)); $s6 = $s6->addInt64($s17->mulInt(470296, 19)); $s7 = $s7->addInt64($s17->mulInt(654183, 20)); $s8 = $s8->subInt64($s17->mulInt(997805, 20)); $s9 = $s9->addInt64($s17->mulInt(136657, 18)); $s10 = $s10->subInt64($s17->mulInt(683901, 20)); $s4 = $s4->addInt64($s16->mulInt(666643, 20)); $s5 = $s5->addInt64($s16->mulInt(470296, 19)); $s6 = $s6->addInt64($s16->mulInt(654183, 20)); $s7 = $s7->subInt64($s16->mulInt(997805, 20)); $s8 = $s8->addInt64($s16->mulInt(136657, 18)); $s9 = $s9->subInt64($s16->mulInt(683901, 20)); $s3 = $s3->addInt64($s15->mulInt(666643, 20)); $s4 = $s4->addInt64($s15->mulInt(470296, 19)); $s5 = $s5->addInt64($s15->mulInt(654183, 20)); $s6 = $s6->subInt64($s15->mulInt(997805, 20)); $s7 = $s7->addInt64($s15->mulInt(136657, 18)); $s8 = $s8->subInt64($s15->mulInt(683901, 20)); $s2 = $s2->addInt64($s14->mulInt(666643, 20)); $s3 = $s3->addInt64($s14->mulInt(470296, 19)); $s4 = $s4->addInt64($s14->mulInt(654183, 20)); $s5 = $s5->subInt64($s14->mulInt(997805, 20)); $s6 = $s6->addInt64($s14->mulInt(136657, 18)); $s7 = $s7->subInt64($s14->mulInt(683901, 20)); $s1 = $s1->addInt64($s13->mulInt(666643, 20)); $s2 = $s2->addInt64($s13->mulInt(470296, 19)); $s3 = $s3->addInt64($s13->mulInt(654183, 20)); $s4 = $s4->subInt64($s13->mulInt(997805, 20)); $s5 = $s5->addInt64($s13->mulInt(136657, 18)); $s6 = $s6->subInt64($s13->mulInt(683901, 20)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $s12 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->addInt(1 << 20)->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry2 = $s2->addInt(1 << 20)->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry4 = $s4->addInt(1 << 20)->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry1 = $s1->addInt(1 << 20)->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry3 = $s3->addInt(1 << 20)->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry5 = $s5->addInt(1 << 20)->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $s12 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry1 = $s1->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry2 = $s2->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry3 = $s3->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry4 = $s4->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry5 = $s5->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry6 = $s6->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry7 = $s7->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry8 = $s8->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry9 = $s9->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry10 = $s10->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry11 = $s11->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $carry0 = $s0->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry1 = $s1->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry2 = $s2->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry3 = $s3->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry4 = $s4->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry5 = $s5->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry6 = $s6->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry7 = $s7->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry8 = $s10->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry9 = $s9->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry10 = $s10->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $S0 = $s0->toInt(); $S1 = $s1->toInt(); $S2 = $s2->toInt(); $S3 = $s3->toInt(); $S4 = $s4->toInt(); $S5 = $s5->toInt(); $S6 = $s6->toInt(); $S7 = $s7->toInt(); $S8 = $s8->toInt(); $S9 = $s9->toInt(); $S10 = $s10->toInt(); $S11 = $s11->toInt(); /** * @var array<int, int> */ $arr = array( (int) (0xff & ($S0 >> 0)), (int) (0xff & ($S0 >> 8)), (int) (0xff & (($S0 >> 16) | ($S1 << 5))), (int) (0xff & ($S1 >> 3)), (int) (0xff & ($S1 >> 11)), (int) (0xff & (($S1 >> 19) | ($S2 << 2))), (int) (0xff & ($S2 >> 6)), (int) (0xff & (($S2 >> 14) | ($S3 << 7))), (int) (0xff & ($S3 >> 1)), (int) (0xff & ($S3 >> 9)), (int) (0xff & (($S3 >> 17) | ($S4 << 4))), (int) (0xff & ($S4 >> 4)), (int) (0xff & ($S4 >> 12)), (int) (0xff & (($S4 >> 20) | ($S5 << 1))), (int) (0xff & ($S5 >> 7)), (int) (0xff & (($S5 >> 15) | ($S6 << 6))), (int) (0xff & ($S6 >> 2)), (int) (0xff & ($S6 >> 10)), (int) (0xff & (($S6 >> 18) | ($S7 << 3))), (int) (0xff & ($S7 >> 5)), (int) (0xff & ($S7 >> 13)), (int) (0xff & ($S8 >> 0)), (int) (0xff & ($S8 >> 8)), (int) (0xff & (($S8 >> 16) | ($S9 << 5))), (int) (0xff & ($S9 >> 3)), (int) (0xff & ($S9 >> 11)), (int) (0xff & (($S9 >> 19) | ($S10 << 2))), (int) (0xff & ($S10 >> 6)), (int) (0xff & (($S10 >> 14) | ($S11 << 7))), (int) (0xff & ($S11 >> 1)), (int) (0xff & ($S11 >> 9)), (int) (0xff & ($S11 >> 17)) ); return self::intArrayToString($arr); } /** * @internal You should not use this directly from another application * * @param string $s * @return string * @throws SodiumException * @throws TypeError */ public static function sc_reduce($s) { /** * @var ParagonIE_Sodium_Core32_Int64 $s0 * @var ParagonIE_Sodium_Core32_Int64 $s1 * @var ParagonIE_Sodium_Core32_Int64 $s2 * @var ParagonIE_Sodium_Core32_Int64 $s3 * @var ParagonIE_Sodium_Core32_Int64 $s4 * @var ParagonIE_Sodium_Core32_Int64 $s5 * @var ParagonIE_Sodium_Core32_Int64 $s6 * @var ParagonIE_Sodium_Core32_Int64 $s7 * @var ParagonIE_Sodium_Core32_Int64 $s8 * @var ParagonIE_Sodium_Core32_Int64 $s9 * @var ParagonIE_Sodium_Core32_Int64 $s10 * @var ParagonIE_Sodium_Core32_Int64 $s11 * @var ParagonIE_Sodium_Core32_Int64 $s12 * @var ParagonIE_Sodium_Core32_Int64 $s13 * @var ParagonIE_Sodium_Core32_Int64 $s14 * @var ParagonIE_Sodium_Core32_Int64 $s15 * @var ParagonIE_Sodium_Core32_Int64 $s16 * @var ParagonIE_Sodium_Core32_Int64 $s17 * @var ParagonIE_Sodium_Core32_Int64 $s18 * @var ParagonIE_Sodium_Core32_Int64 $s19 * @var ParagonIE_Sodium_Core32_Int64 $s20 * @var ParagonIE_Sodium_Core32_Int64 $s21 * @var ParagonIE_Sodium_Core32_Int64 $s22 * @var ParagonIE_Sodium_Core32_Int64 $s23 */ $s0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 0, 3))); $s1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 2, 4)) >> 5)); $s2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 5, 3)) >> 2)); $s3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 7, 4)) >> 7)); $s4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 10, 4)) >> 4)); $s5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 13, 3)) >> 1)); $s6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 15, 4)) >> 6)); $s7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 18, 4)) >> 3)); $s8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 21, 3))); $s9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 23, 4)) >> 5)); $s10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 26, 3)) >> 2)); $s11 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 28, 4)) >> 7)); $s12 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 31, 4)) >> 4)); $s13 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 34, 3)) >> 1)); $s14 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 36, 4)) >> 6)); $s15 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 39, 4)) >> 3)); $s16 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 42, 3))); $s17 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 44, 4)) >> 5)); $s18 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 47, 3)) >> 2)); $s19 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 49, 4)) >> 7)); $s20 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 52, 4)) >> 4)); $s21 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 55, 3)) >> 1)); $s22 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 57, 4)) >> 6)); $s23 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($s, 60, 4)) >> 3)); $s11 = $s11->addInt64($s23->mulInt(666643, 20)); $s12 = $s12->addInt64($s23->mulInt(470296, 19)); $s13 = $s13->addInt64($s23->mulInt(654183, 20)); $s14 = $s14->subInt64($s23->mulInt(997805, 20)); $s15 = $s15->addInt64($s23->mulInt(136657, 18)); $s16 = $s16->subInt64($s23->mulInt(683901, 20)); $s10 = $s10->addInt64($s22->mulInt(666643, 20)); $s11 = $s11->addInt64($s22->mulInt(470296, 19)); $s12 = $s12->addInt64($s22->mulInt(654183, 20)); $s13 = $s13->subInt64($s22->mulInt(997805, 20)); $s14 = $s14->addInt64($s22->mulInt(136657, 18)); $s15 = $s15->subInt64($s22->mulInt(683901, 20)); $s9 = $s9->addInt64($s21->mulInt(666643, 20)); $s10 = $s10->addInt64($s21->mulInt(470296, 19)); $s11 = $s11->addInt64($s21->mulInt(654183, 20)); $s12 = $s12->subInt64($s21->mulInt(997805, 20)); $s13 = $s13->addInt64($s21->mulInt(136657, 18)); $s14 = $s14->subInt64($s21->mulInt(683901, 20)); $s8 = $s8->addInt64($s20->mulInt(666643, 20)); $s9 = $s9->addInt64($s20->mulInt(470296, 19)); $s10 = $s10->addInt64($s20->mulInt(654183, 20)); $s11 = $s11->subInt64($s20->mulInt(997805, 20)); $s12 = $s12->addInt64($s20->mulInt(136657, 18)); $s13 = $s13->subInt64($s20->mulInt(683901, 20)); $s7 = $s7->addInt64($s19->mulInt(666643, 20)); $s8 = $s8->addInt64($s19->mulInt(470296, 19)); $s9 = $s9->addInt64($s19->mulInt(654183, 20)); $s10 = $s10->subInt64($s19->mulInt(997805, 20)); $s11 = $s11->addInt64($s19->mulInt(136657, 18)); $s12 = $s12->subInt64($s19->mulInt(683901, 20)); $s6 = $s6->addInt64($s18->mulInt(666643, 20)); $s7 = $s7->addInt64($s18->mulInt(470296, 19)); $s8 = $s8->addInt64($s18->mulInt(654183, 20)); $s9 = $s9->subInt64($s18->mulInt(997805, 20)); $s10 = $s10->addInt64($s18->mulInt(136657, 18)); $s11 = $s11->subInt64($s18->mulInt(683901, 20)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry12 = $s12->addInt(1 << 20)->shiftRight(21); $s13 = $s13->addInt64($carry12); $s12 = $s12->subInt64($carry12->shiftLeft(21)); $carry14 = $s14->addInt(1 << 20)->shiftRight(21); $s15 = $s15->addInt64($carry14); $s14 = $s14->subInt64($carry14->shiftLeft(21)); $carry16 = $s16->addInt(1 << 20)->shiftRight(21); $s17 = $s17->addInt64($carry16); $s16 = $s16->subInt64($carry16->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $carry13 = $s13->addInt(1 << 20)->shiftRight(21); $s14 = $s14->addInt64($carry13); $s13 = $s13->subInt64($carry13->shiftLeft(21)); $carry15 = $s15->addInt(1 << 20)->shiftRight(21); $s16 = $s16->addInt64($carry15); $s15 = $s15->subInt64($carry15->shiftLeft(21)); $s5 = $s5->addInt64($s17->mulInt(666643, 20)); $s6 = $s6->addInt64($s17->mulInt(470296, 19)); $s7 = $s7->addInt64($s17->mulInt(654183, 20)); $s8 = $s8->subInt64($s17->mulInt(997805, 20)); $s9 = $s9->addInt64($s17->mulInt(136657, 18)); $s10 = $s10->subInt64($s17->mulInt(683901, 20)); $s4 = $s4->addInt64($s16->mulInt(666643, 20)); $s5 = $s5->addInt64($s16->mulInt(470296, 19)); $s6 = $s6->addInt64($s16->mulInt(654183, 20)); $s7 = $s7->subInt64($s16->mulInt(997805, 20)); $s8 = $s8->addInt64($s16->mulInt(136657, 18)); $s9 = $s9->subInt64($s16->mulInt(683901, 20)); $s3 = $s3->addInt64($s15->mulInt(666643, 20)); $s4 = $s4->addInt64($s15->mulInt(470296, 19)); $s5 = $s5->addInt64($s15->mulInt(654183, 20)); $s6 = $s6->subInt64($s15->mulInt(997805, 20)); $s7 = $s7->addInt64($s15->mulInt(136657, 18)); $s8 = $s8->subInt64($s15->mulInt(683901, 20)); $s2 = $s2->addInt64($s14->mulInt(666643, 20)); $s3 = $s3->addInt64($s14->mulInt(470296, 19)); $s4 = $s4->addInt64($s14->mulInt(654183, 20)); $s5 = $s5->subInt64($s14->mulInt(997805, 20)); $s6 = $s6->addInt64($s14->mulInt(136657, 18)); $s7 = $s7->subInt64($s14->mulInt(683901, 20)); $s1 = $s1->addInt64($s13->mulInt(666643, 20)); $s2 = $s2->addInt64($s13->mulInt(470296, 19)); $s3 = $s3->addInt64($s13->mulInt(654183, 20)); $s4 = $s4->subInt64($s13->mulInt(997805, 20)); $s5 = $s5->addInt64($s13->mulInt(136657, 18)); $s6 = $s6->subInt64($s13->mulInt(683901, 20)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $s12 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->addInt(1 << 20)->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry2 = $s2->addInt(1 << 20)->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry4 = $s4->addInt(1 << 20)->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry1 = $s1->addInt(1 << 20)->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry3 = $s3->addInt(1 << 20)->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry5 = $s5->addInt(1 << 20)->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $s12 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry1 = $s1->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry2 = $s2->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry3 = $s3->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry4 = $s4->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry5 = $s5->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry6 = $s6->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry7 = $s7->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry8 = $s8->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry9 = $s9->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry10 = $s10->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry11 = $s11->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $carry0 = $s0->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry1 = $s1->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry2 = $s2->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry3 = $s3->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry4 = $s4->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry5 = $s5->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry6 = $s6->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry7 = $s7->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry8 = $s8->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry9 = $s9->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry10 = $s10->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $S0 = $s0->toInt32()->toInt(); $S1 = $s1->toInt32()->toInt(); $S2 = $s2->toInt32()->toInt(); $S3 = $s3->toInt32()->toInt(); $S4 = $s4->toInt32()->toInt(); $S5 = $s5->toInt32()->toInt(); $S6 = $s6->toInt32()->toInt(); $S7 = $s7->toInt32()->toInt(); $S8 = $s8->toInt32()->toInt(); $S9 = $s9->toInt32()->toInt(); $S10 = $s10->toInt32()->toInt(); $S11 = $s11->toInt32()->toInt(); /** * @var array<int, int> */ $arr = array( (int) ($S0 >> 0), (int) ($S0 >> 8), (int) (($S0 >> 16) | ($S1 << 5)), (int) ($S1 >> 3), (int) ($S1 >> 11), (int) (($S1 >> 19) | ($S2 << 2)), (int) ($S2 >> 6), (int) (($S2 >> 14) | ($S3 << 7)), (int) ($S3 >> 1), (int) ($S3 >> 9), (int) (($S3 >> 17) | ($S4 << 4)), (int) ($S4 >> 4), (int) ($S4 >> 12), (int) (($S4 >> 20) | ($S5 << 1)), (int) ($S5 >> 7), (int) (($S5 >> 15) | ($S6 << 6)), (int) ($S6 >> 2), (int) ($S6 >> 10), (int) (($S6 >> 18) | ($S7 << 3)), (int) ($S7 >> 5), (int) ($S7 >> 13), (int) ($S8 >> 0), (int) ($S8 >> 8), (int) (($S8 >> 16) | ($S9 << 5)), (int) ($S9 >> 3), (int) ($S9 >> 11), (int) (($S9 >> 19) | ($S10 << 2)), (int) ($S10 >> 6), (int) (($S10 >> 14) | ($S11 << 7)), (int) ($S11 >> 1), (int) ($S11 >> 9), (int) $S11 >> 17 ); return self::intArrayToString($arr); } /** * multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_mul_l(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A) { $aslide = array( 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ); /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai size 8 */ $Ai = array(); # ge_p3_to_cached(&Ai[0], A); $Ai[0] = self::ge_p3_to_cached($A); # ge_p3_dbl(&t, A); $t = self::ge_p3_dbl($A); # ge_p1p1_to_p3(&A2, &t); $A2 = self::ge_p1p1_to_p3($t); for ($i = 1; $i < 8; ++$i) { # ge_add(&t, &A2, &Ai[0]); $t = self::ge_add($A2, $Ai[$i - 1]); # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_p3_to_cached(&Ai[i], &u); $Ai[$i] = self::ge_p3_to_cached($u); } $r = self::ge_p3_0(); for ($i = 252; $i >= 0; --$i) { $t = self::ge_p3_dbl($r); if ($aslide[$i] > 0) { # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_add(&t, &u, &Ai[aslide[i] / 2]); $t = self::ge_add($u, $Ai[(int)($aslide[$i] / 2)]); } elseif ($aslide[$i] < 0) { # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); $t = self::ge_sub($u, $Ai[(int)(-$aslide[$i] / 2)]); } } # ge_p1p1_to_p3(r, &t); return self::ge_p1p1_to_p3($t); } } PK �%=\H�w= w= Core32/Ed25519.phpnu �[��� <?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; /** * @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, 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; } } PK �%=\b��� � Core32/ChaCha20/php.ininu �[��� safe_mode=false; upload_max_filesize=128M; post_max_size=128M; memory_limit=1024M; zend_extension=opcache.so; opcache.enable=1; opcache.memory_consumption=64; opcache.interned_strings_buffer=8; opcache.max_accelerated_files=5000; opcache.revalidate_freq=180; opcache.fast_shutdown=0; opcache.enable_cli=0; opcache.revalidate_path=0; opcache.validate_timestamps=2; opcache.max_file_size=0; opcache.file_cache=/kunden/homepages/31/d661913580/htdocs/.opcache; opcache.file_cache_only=1; PK �%=\X�v�( ( Core32/ChaCha20/Ctx.phpnu �[��� <?php 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 { /** * @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)); } /** * @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; } } PK �%=\����� � Core32/ChaCha20/IetfCtx.phpnu �[��� <?php 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 { /** * 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)); } } PK �%=\]�D�� � Core32/XChaCha20.phpnu �[��� <?php if (class_exists('ParagonIE_Sodium_Core32_XChaCha20', false)) { return; } /** * Class ParagonIE_Sodium_Core32_XChaCha20 */ class ParagonIE_Sodium_Core32_XChaCha20 extends ParagonIE_Sodium_Core32_HChaCha20 { /** * @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 ); } } PK �%=\�w�`2 2 Core32/Poly1305.phpnu �[��� <?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; /** * @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); } } PK �%=\��21� � Core32/HChaCha20.phpnu �[��� <?php if (class_exists('ParagonIE_Sodium_Core32_HChaCha20', false)) { return; } /** * Class ParagonIE_Sodium_Core_HChaCha20 */ class ParagonIE_Sodium_Core32_HChaCha20 extends ParagonIE_Sodium_Core32_ChaCha20 { /** * @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(); } } PK �%=\�X]>