private static final function streamEncrypt(ReadOnlyFile $input, MutableFile $output, EncryptionKey $encKey, string $nonce, string $mac, Config $config) : int
{
$initHash = $input->getHash();
// Begin the streaming decryption
$size = $input->getSize();
$written = 0;
while ($input->remainingBytes() > 0) {
$read = $input->readBytes($input->getPos() + $config->BUFFER > $size ? $size - $input->getPos() : $config->BUFFER);
$encrypted = \Sodium\crypto_stream_xor($read, $nonce, $encKey->getRawKeyMaterial());
\Sodium\crypto_generichash_update($mac, $encrypted);
$written += $output->writeBytes($encrypted);
\Sodium\increment($nonce);
}
\Sodium\memzero($nonce);
// Check that our input file was not modified before we MAC it
if (!\hash_equals($input->getHash(), $initHash)) {
throw new FileModified('Read-only file has been modified since it was opened for reading');
}
$written += $output->writeBytes(\Sodium\crypto_generichash_final($mac, $config->MAC_SIZE), $config->MAC_SIZE);
return $written;
}