Geralt
  • Introduction
  • Random data
  • Constant time
  • Secure memory
  • Encoding
  • Padding
  • Hashing
  • Message authentication
  • Password hashing
  • Key derivation
  • Authenticated encryption
    • Stream and file encryption
    • AEGIS-128L
    • AEGIS-256
    • ChaCha20-Poly1305
    • XChaCha20-Poly1305
  • Key exchange
  • Digital signatures
  • Advanced
    • Validation
    • Concat
    • ChaCha20
    • XChaCha20
    • HChaCha20
    • Poly1305
    • Ed25519 to X25519
Powered by GitBook
On this page
  • Purpose
  • Usage
  • Encrypt
  • Decrypt
  • Constants
  • Notes
  1. Authenticated encryption

ChaCha20-Poly1305

Last updated 1 year ago

Purpose

is an authenticated encryption with associated data (AEAD) scheme. It encrypts a plaintext message using a 256-bit key and 96-bit nonce (number used only once) before computing a tag over the ciphertext and associated data.

The associated data is useful for authenticating file headers, version numbers, timestamps, counters, and so on. It can be used to prevent and . It is not encrypted nor part of the ciphertext. It must be reproduceable or stored somewhere for decryption to be possible.

For decryption, the tag is first verified for the given inputs, which detects tampering and incorrect parameters. If verification fails, an error is returned. Otherwise, the ciphertext is decrypted and plaintext is returned.

Use if you want random nonces with the same key.

For encryption, the nonce MUST NOT be repeated or reused with the same key. You MUST the nonce for each plaintext message encrypted using the same key.

Usage

Encrypt

Fills a span with ciphertext and an appended tag computed from a plaintext message, nonce, key, and optional associated data.

ChaCha20Poly1305.Encrypt(Span<byte> ciphertext, ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> key, ReadOnlySpan<byte> associatedData = default)

Exceptions

ciphertext has a length not equal to plaintext.Length + TagSize.

nonce has a length not equal to NonceSize.

key has a length not equal to KeySize.

Encryption failed.

Decrypt

Verifies that the tag appended to the ciphertext is correct for the given inputs. If verification fails, an exception is thrown. Otherwise, it fills a span with the decrypted ciphertext.

ChaCha20Poly1305.Decrypt(Span<byte> plaintext, ReadOnlySpan<byte> ciphertext, ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> key, ReadOnlySpan<byte> associatedData = default)

Exceptions

plaintext has a length not equal to ciphertext.Length - TagSize.

ciphertext has a length less than TagSize.

nonce has a length not equal to NonceSize.

key has a length not equal to KeySize.

Invalid authentication tag for the given inputs.

Constants

These are used for validation and/or save you defining your own constants.

public const int KeySize = 32;
public const int NonceSize = 12;
public const int TagSize = 16;

Notes

Encrypting data in 16-64 KiB chunks instead of as a single plaintext message is recommended to keep memory usage low and detect corrupted chunks early. Unfortunately, it is difficult to get right. You MUST ensure that chunks cannot be:

  1. Truncated

  2. Removed

  3. Reordered

  4. Duplicated

If decryption fails midway through a stream due to tampering or corruption, erase the previous plaintext outputs from memory and/or disk and throw an error.

  1. A ciphertext message can be decrypted under multiple keys without an error.

  2. An attacker who knows the key can find different messages that lead to the same tag.

If you intend to feed multiple variable-length inputs into the associated data, beware of . Please read the page for more information.

The key MUST be uniformly random. It can either be or the output of a . Furthermore, it SHOULD be rotated periodically (e.g. a different key per file).

1 and 2 can be accomplished by including the length of all the ciphertext chunks added together in the associated data of the first chunk. Alternatively, you can use the construction.

3 and 4 can be resolved by using a nonce or by including the previous tag in the associated data of the next chunk.

As a general rule, avoid compression before encryption. It can and has been the cause of .

ChaCha20-Poly1305 is NOT .

This can enable in scenarios where keys can be adversarial. For example, when an attacker can submit a ciphertext encrypted using a password to a server that knows the encryption key (an oracle).

The best fix is to switch to as outlined in that link.

ChaCha20-Poly1305
confused deputy attacks
replay attacks
XChaCha20-Poly1305
increment
ArgumentOutOfRangeException
ArgumentOutOfRangeException
ArgumentOutOfRangeException
CryptographicException
ArgumentOutOfRangeException
ArgumentOutOfRangeException
ArgumentOutOfRangeException
ArgumentOutOfRangeException
CryptographicException
canonicalization attacks
Concat
randomly generated
KDF
STREAM
counter
leak information
several attacks
key- or message-committing
attacks
Encrypt-then-MAC