ChaCha20

Purpose

ChaCha20 is an unauthenticated stream cipher that uses a 256-bit key and 96-bit nonce (number used only once) to encrypt/decrypt a message.

The 32-bit internal counter can be changed from the default of 0 to 1 for constructing ChaCha20-Poly1305. Otherwise, it should generally be left alone.

You probably want ChaCha20-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 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 ChaCha20-Poly1305.

ChaCha20.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.

ChaCha20.Encrypt(Span<byte> ciphertext, ReadOnlySpan<byte> plaintext, ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> key, uint 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 or counter overflow prevented.

Decrypt

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

ChaCha20.Decrypt(Span<byte> plaintext, ReadOnlySpan<byte> ciphertext, ReadOnlySpan<byte> nonce, ReadOnlySpan<byte> key, uint 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 or counter overflow prevented.

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 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 ChaCha20-Poly1305 Notes for more information.

Last updated