You are here

public static function ParagonIE_Sodium_File::generichash in Automatic Updates 8

Same name and namespace in other branches
  1. 7 vendor/paragonie/sodium_compat/src/File.php \ParagonIE_Sodium_File::generichash()

Calculate the BLAKE2b hash of a file.

@psalm-suppress FailedTypeResolution

Parameters

string $filePath Absolute path to a file on the filesystem:

string|null $key BLAKE2b key:

int $outputLength Length of hash output:

Return value

string BLAKE2b hash

Throws

SodiumException

TypeError

File

vendor/paragonie/sodium_compat/src/File.php, line 352

Class

ParagonIE_Sodium_File
Class ParagonIE_Sodium_File

Code

public static function generichash($filePath, $key = '', $outputLength = 32) {

  /* Type checks: */
  if (!is_string($filePath)) {
    throw new TypeError('Argument 1 must be a string, ' . gettype($filePath) . ' given.');
  }
  if (!is_string($key)) {
    if (is_null($key)) {
      $key = '';
    }
    else {
      throw new TypeError('Argument 2 must be a string, ' . gettype($key) . ' given.');
    }
  }
  if (!is_int($outputLength)) {
    if (!is_numeric($outputLength)) {
      throw new TypeError('Argument 3 must be an integer, ' . gettype($outputLength) . ' given.');
    }
    $outputLength = (int) $outputLength;
  }

  /* Input validation: */
  if (!empty($key)) {
    if (self::strlen($key) < ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MIN) {
      throw new TypeError('Argument 2 must be at least CRYPTO_GENERICHASH_KEYBYTES_MIN bytes');
    }
    if (self::strlen($key) > ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MAX) {
      throw new TypeError('Argument 2 must be at most CRYPTO_GENERICHASH_KEYBYTES_MAX bytes');
    }
  }
  if ($outputLength < ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MIN) {
    throw new SodiumException('Argument 3 must be at least CRYPTO_GENERICHASH_BYTES_MIN');
  }
  if ($outputLength > ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MAX) {
    throw new SodiumException('Argument 3 must be at least CRYPTO_GENERICHASH_BYTES_MAX');
  }

  /** @var int $size */
  $size = filesize($filePath);
  if (!is_int($size)) {
    throw new SodiumException('Could not obtain the file size');
  }

  /** @var resource $fp */
  $fp = fopen($filePath, 'rb');
  if (!is_resource($fp)) {
    throw new SodiumException('Could not open input file for reading');
  }
  $ctx = ParagonIE_Sodium_Compat::crypto_generichash_init($key, $outputLength);
  while ($size > 0) {
    $blockSize = $size > 64 ? 64 : $size;
    $read = fread($fp, $blockSize);
    if (!is_string($read)) {
      throw new SodiumException('Could not read input file');
    }
    ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $read);
    $size -= $blockSize;
  }
  fclose($fp);
  return ParagonIE_Sodium_Compat::crypto_generichash_final($ctx, $outputLength);
}