XChaCha20

Purpose

XChaCha20 is an unauthenticated stream cipher constructed using ChaCha20 and HChaCha20. It takes a 256-bit key and 192-bit nonce (number used only once) to encrypt/decrypt a message.

The 64-bit internal counter can be changed from the default of 0 to access any block without computing previous ones. However, it should generally not be touched.

You probably want XChaCha20-Poly1305 instead, which also ensures a message has not been tampered with. This class MUST only be used for custom constructions (e.g. Encrypt-then-MAC).

The nonce MUST NOT be repeated or reused with the same key. You MUST increment or randomly generate the nonce for each plaintext message encrypted using the same key.

Usage

Fill

Fills a span with pseudorandom bytes computed from a nonce and key. This can be used to compute the Poly1305 key for constructing XChaCha20-Poly1305.

XChaCha20.Fill(Span<byte> buffer, ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> key)

Exceptions

ArgumentOutOfRangeException

buffer has a length of 0.

ArgumentOutOfRangeException

nonce has a length not equal to NonceSize.

ArgumentOutOfRangeException

key has a length not equal to KeySize.

CryptographicException

Error computing pseudorandom bytes.

Encrypt

Fills a span with ciphertext computed from a plaintext message, nonce, and key.

XChaCha20.Encrypt(Span<byte> ciphertext, ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> key, ulong counter = 0)

Exceptions

ArgumentOutOfRangeException

ciphertext has a length not equal to plaintext.Length.

ArgumentOutOfRangeException

nonce has a length not equal to NonceSize.

ArgumentOutOfRangeException

key has a length not equal to KeySize.

CryptographicException

Encryption failed.

Decrypt

Fills a span with plaintext computed from a ciphertext message, nonce, and key.

XChaCha20.Decrypt(Span<byte> plaintext, ReadOnlySpan<byte> ciphertext, ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> key, ulong counter = 0)

Exceptions

ArgumentOutOfRangeException

plaintext has a length not equal to ciphertext.Length.

ArgumentOutOfRangeException

nonce has a length not equal to NonceSize.

ArgumentOutOfRangeException

key has a length not equal to KeySize.

CryptographicException

Decryption failed.

Constants

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

public const int KeySize = 32;
public const int NonceSize = 24;
public const int BlockSize = 64;

Notes

This is NOT an authenticated encryption algorithm. This class MUST only be used if you know what you are doing and apply authentication yourself using keyed BLAKE2b as a MAC.

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

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

Even with Encrypt-then-MAC, it is recommended to encrypt data in 16-64 KiB chunks instead of as a single plaintext message. Read the XChaCha20-Poly1305 Notes for more information.

Last updated