You are here

public static function ParagonIE_Sodium_Crypto32::aead_chacha20poly1305_ietf_decrypt in Automatic Updates 7

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

AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce)

@internal Do not use this directly. Use ParagonIE_Sodium_Compat.

Parameters

string $message:

string $ad:

string $nonce:

string $key:

Return value

string

Throws

SodiumException

TypeError

2 calls to ParagonIE_Sodium_Crypto32::aead_chacha20poly1305_ietf_decrypt()
ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt in vendor/paragonie/sodium_compat/src/Compat.php
Authenticated Encryption with Associated Data: Decryption
ParagonIE_Sodium_Crypto32::aead_xchacha20poly1305_ietf_decrypt in vendor/paragonie/sodium_compat/src/Crypto32.php
AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce)

File

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

Class

ParagonIE_Sodium_Crypto32
Class ParagonIE_Sodium_Crypto

Code

public static function aead_chacha20poly1305_ietf_decrypt($message = '', $ad = '', $nonce = '', $key = '') {

  /** @var int $adlen - Length of associated data */
  $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad);

  /** @var int $len - Length of message (ciphertext + MAC) */
  $len = ParagonIE_Sodium_Core32_Util::strlen($message);

  /** @var int  $clen - Length of ciphertext */
  $clen = $len - self::aead_chacha20poly1305_IETF_ABYTES;

  /** @var string The first block of the chacha20 keystream, used as a poly1305 key */
  $block0 = ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $nonce, $key);

  /** @var string $mac - Message authentication code */
  $mac = ParagonIE_Sodium_Core32_Util::substr($message, $len - self::aead_chacha20poly1305_IETF_ABYTES, self::aead_chacha20poly1305_IETF_ABYTES);

  /** @var string $ciphertext - The encrypted message (sans MAC) */
  $ciphertext = ParagonIE_Sodium_Core32_Util::substr($message, 0, $len - self::aead_chacha20poly1305_IETF_ABYTES);

  /* Recalculate the Poly1305 authentication tag (MAC): */
  $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0);
  try {
    ParagonIE_Sodium_Compat::memzero($block0);
  } catch (SodiumException $ex) {
    $block0 = null;
  }
  $state
    ->update($ad);
  $state
    ->update(str_repeat("\0", 0x10 - $adlen & 0xf));
  $state
    ->update($ciphertext);
  $state
    ->update(str_repeat("\0", 0x10 - $clen & 0xf));
  $state
    ->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen));
  $state
    ->update(ParagonIE_Sodium_Core32_Util::store64_le($clen));
  $computed_mac = $state
    ->finish();

  /* Compare the given MAC with the recalculated MAC: */
  if (!ParagonIE_Sodium_Core32_Util::verify_16($computed_mac, $mac)) {
    throw new SodiumException('Invalid MAC');
  }

  // Here, we know that the MAC is valid, so we decrypt and return the plaintext
  return ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc($ciphertext, $nonce, $key, ParagonIE_Sodium_Core32_Util::store64_le(1));
}