You are here

public static function ParagonIE_Sodium_Crypto32::secretbox_xchacha20poly1305_open in Automatic Updates 8

Same name and namespace in other branches
  1. 7 vendor/paragonie/sodium_compat/src/Crypto32.php \ParagonIE_Sodium_Crypto32::secretbox_xchacha20poly1305_open()

Decrypt a ciphertext generated via secretbox_xchacha20poly1305().

@internal Do not use this directly. Use ParagonIE_Sodium_Compat.

Parameters

string $ciphertext:

string $nonce:

string $key:

Return value

string

Throws

SodiumException

TypeError

1 call to ParagonIE_Sodium_Crypto32::secretbox_xchacha20poly1305_open()
ParagonIE_Sodium_Compat::crypto_secretbox_xchacha20poly1305_open in vendor/paragonie/sodium_compat/src/Compat.php
Decrypts a message previously encrypted with crypto_secretbox_xchacha20poly1305().

File

vendor/paragonie/sodium_compat/src/Crypto32.php, line 1171

Class

ParagonIE_Sodium_Crypto32
Class ParagonIE_Sodium_Crypto

Code

public static function secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key) {

  /** @var string $mac */
  $mac = ParagonIE_Sodium_Core32_Util::substr($ciphertext, 0, self::secretbox_xchacha20poly1305_MACBYTES);

  /** @var string $c */
  $c = ParagonIE_Sodium_Core32_Util::substr($ciphertext, self::secretbox_xchacha20poly1305_MACBYTES);

  /** @var int $clen */
  $clen = ParagonIE_Sodium_Core32_Util::strlen($c);

  /** @var string $subkey */
  $subkey = ParagonIE_Sodium_Core32_HChaCha20::hchacha20($nonce, $key);

  /** @var string $block0 */
  $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream(64, ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), $subkey);
  $verified = ParagonIE_Sodium_Core32_Poly1305::onetimeauth_verify($mac, $c, ParagonIE_Sodium_Core32_Util::substr($block0, 0, 32));
  if (!$verified) {
    try {
      ParagonIE_Sodium_Compat::memzero($subkey);
    } catch (SodiumException $ex) {
      $subkey = null;
    }
    throw new SodiumException('Invalid MAC');
  }

  /** @var string $m - Decrypted message */
  $m = ParagonIE_Sodium_Core32_Util::xorStrings(ParagonIE_Sodium_Core32_Util::substr($block0, self::secretbox_xchacha20poly1305_ZEROBYTES), ParagonIE_Sodium_Core32_Util::substr($c, 0, self::secretbox_xchacha20poly1305_ZEROBYTES));
  if ($clen > self::secretbox_xchacha20poly1305_ZEROBYTES) {

    // We had more than 1 block, so let's continue to decrypt the rest.
    $m .= ParagonIE_Sodium_Core32_ChaCha20::streamXorIc(ParagonIE_Sodium_Core32_Util::substr($c, self::secretbox_xchacha20poly1305_ZEROBYTES), ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), (string) $subkey, ParagonIE_Sodium_Core32_Util::store64_le(1));
  }
  return $m;
}