You are here

public static function ParagonIE_Sodium_File::sign in Automatic Updates 8

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

Sign a file (rather than a string). Uses less memory than ParagonIE_Sodium_Compat::crypto_sign_detached(), but produces the same result.

Parameters

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

string $secretKey Secret signing key:

Return value

string Ed25519 signature

Throws

SodiumException

TypeError

File

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

Class

ParagonIE_Sodium_File
Class ParagonIE_Sodium_File

Code

public static function sign($filePath, $secretKey) {

  /* Type checks: */
  if (!is_string($filePath)) {
    throw new TypeError('Argument 1 must be a string, ' . gettype($filePath) . ' given.');
  }
  if (!is_string($secretKey)) {
    throw new TypeError('Argument 2 must be a string, ' . gettype($secretKey) . ' given.');
  }

  /* Input validation: */
  if (self::strlen($secretKey) !== ParagonIE_Sodium_Compat::CRYPTO_SIGN_SECRETKEYBYTES) {
    throw new TypeError('Argument 2 must be CRYPTO_SIGN_SECRETKEYBYTES bytes');
  }
  if (PHP_INT_SIZE === 4) {
    return self::sign_core32($filePath, $secretKey);
  }

  /** @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');
  }

  /** @var string $az */
  $az = hash('sha512', self::substr($secretKey, 0, 32), true);
  $az[0] = self::intToChr(self::chrToInt($az[0]) & 248);
  $az[31] = self::intToChr(self::chrToInt($az[31]) & 63 | 64);
  $hs = hash_init('sha512');
  hash_update($hs, self::substr($az, 32, 32));

  /** @var resource $hs */
  $hs = self::updateHashWithFile($hs, $fp, $size);

  /** @var string $nonceHash */
  $nonceHash = hash_final($hs, true);

  /** @var string $pk */
  $pk = self::substr($secretKey, 32, 32);

  /** @var string $nonce */
  $nonce = ParagonIE_Sodium_Core_Ed25519::sc_reduce($nonceHash) . self::substr($nonceHash, 32);

  /** @var string $sig */
  $sig = ParagonIE_Sodium_Core_Ed25519::ge_p3_tobytes(ParagonIE_Sodium_Core_Ed25519::ge_scalarmult_base($nonce));
  $hs = hash_init('sha512');
  hash_update($hs, self::substr($sig, 0, 32));
  hash_update($hs, self::substr($pk, 0, 32));

  /** @var resource $hs */
  $hs = self::updateHashWithFile($hs, $fp, $size);

  /** @var string $hramHash */
  $hramHash = hash_final($hs, true);

  /** @var string $hram */
  $hram = ParagonIE_Sodium_Core_Ed25519::sc_reduce($hramHash);

  /** @var string $sigAfter */
  $sigAfter = ParagonIE_Sodium_Core_Ed25519::sc_muladd($hram, $az, $nonce);

  /** @var string $sig */
  $sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32);
  try {
    ParagonIE_Sodium_Compat::memzero($az);
  } catch (SodiumException $ex) {
    $az = null;
  }
  fclose($fp);
  return $sig;
}