ParagonIE\Halite\File::streamDecrypt PHP Method

streamDecrypt() private final static method

Stream decryption - Do not call directly
private final static streamDecrypt ( ReadOnlyFile $input, MutableFile $output, EncryptionKey $encKey, string $nonce, string $mac, Config $config, array &$chunk_macs ) : boolean
$input ReadOnlyFile
$output MutableFile
$encKey EncryptionKey
$nonce string
$mac string (hash context for BLAKE2b)
$config Config
$chunk_macs array
return boolean
    private static final function streamDecrypt(ReadOnlyFile $input, MutableFile $output, EncryptionKey $encKey, string $nonce, string $mac, Config $config, array &$chunk_macs) : bool
    {
        $start = $input->getPos();
        $cipher_end = $input->getSize() - $config->MAC_SIZE;
        // Begin the streaming decryption
        $input->reset($start);
        while ($input->remainingBytes() > $config->MAC_SIZE) {
            /**
             * Would a full BUFFER read put it past the end of the
             * ciphertext? If so, only return a portion of the file.
             */
            if ($input->getPos() + $config->BUFFER > $cipher_end) {
                $read = $input->readBytes($cipher_end - $input->getPos());
            } else {
                $read = $input->readBytes($config->BUFFER);
            }
            // Version 2+ uses a keyed BLAKE2b hash instead of HMAC
            \Sodium\crypto_generichash_update($mac, $read);
            $calcMAC = Util::safeStrcpy($mac);
            $calc = \Sodium\crypto_generichash_final($calcMAC, $config->MAC_SIZE);
            if (empty($chunk_macs)) {
                // Someone attempted to add a chunk at the end.
                throw new InvalidMessage('Invalid message authentication code');
            } else {
                $chunkMAC = \array_shift($chunk_macs);
                if (!\hash_equals($chunkMAC, $calc)) {
                    // This chunk was altered after the original MAC was verified
                    throw new InvalidMessage('Invalid message authentication code');
                }
            }
            // This is where the decryption actually occurs:
            $decrypted = \Sodium\crypto_stream_xor($read, $nonce, $encKey->getRawKeyMaterial());
            $output->writeBytes($decrypted);
            \Sodium\increment($nonce);
        }
        \Sodium\memzero($nonce);
        return true;
    }