public static function ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_pull in Automatic Updates 7
Same name and namespace in other branches
- 8 vendor/paragonie/sodium_compat/src/Crypto32.php \ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_pull()
Parameters
string $state:
string $cipher:
string $aad:
Return value
bool|array{0: string, 1: int}
Throws
SodiumException
1 call to ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_pull()
- ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_pull in vendor/
paragonie/ sodium_compat/ src/ Compat.php
File
- vendor/
paragonie/ sodium_compat/ src/ Crypto32.php, line 1426
Class
- ParagonIE_Sodium_Crypto32
- Class ParagonIE_Sodium_Crypto
Code
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,
);
}