π XChaCha20-Poly1305
The XChaCha20Poly1305 API in LibSodium.Net provides authenticated encryption with associated data (AEAD) and extended nonce support (192-bit), making it safer for use in systems where nonce reuse is a concern. It supports both combined and detached encryption modes, and allows manual or automatic nonce handling through a unified API.
π§ Based on libsodium's XChaCha20-Poly1305 construction
βΉοΈ See also: API Reference forXChaCha20Poly1305
π Features
- Authenticated encryption with associated data (AEAD).
- 24-byte nonce (192-bit) minimizes risk of nonce reuse.
- Combined and detached mode support through a single API.
- Optional
additionalDatafor protocol-level authentication. - Manual or automatic nonce handling.
Span<T>-based API for high performance and low allocations.
β¨ Encrypting and Decrypting Messages
Use the Encrypt and Decrypt methods to perform authenticated encryption. The mode is determined by the presence of the optional mac parameter.
π Combined Mode (Auto Nonce, No AAD)
Span<byte> key = stackalloc byte[XChaCha20Poly1305.KeyLen];
RandomGenerator.Fill(key);
var plaintext = Encoding.UTF8.GetBytes("Auto nonce test");
Span<byte> ciphertext = stackalloc byte[plaintext.Length + XChaCha20Poly1305.MacLen + XChaCha20Poly1305.NonceLen];
XChaCha20Poly1305.Encrypt(ciphertext, plaintext, key);
Span<byte> decrypted = stackalloc byte[plaintext.Length];
XChaCha20Poly1305.Decrypt(decrypted, ciphertext, key);
Console.WriteLine(Encoding.UTF8.GetString(decrypted));
π Combined Mode (Manual Nonce with AAD)
Span<byte> key = stackalloc byte[XChaCha20Poly1305.KeyLen];
Span<byte> nonce = stackalloc byte[XChaCha20Poly1305.NonceLen];
RandomGenerator.Fill(key);
RandomGenerator.Fill(nonce);
var plaintext = Encoding.UTF8.GetBytes("With AAD and nonce");
Span<byte> ciphertext = stackalloc byte[plaintext.Length + XChaCha20Poly1305.MacLen];
Span<byte> aad = Encoding.UTF8.GetBytes("metadata");
XChaCha20Poly1305.Encrypt(ciphertext, plaintext, key, aad: aad, nonce: nonce);
Span<byte> decrypted = stackalloc byte[plaintext.Length];
XChaCha20Poly1305.Decrypt(decrypted, ciphertext, key, aad: aad, nonce: nonce);
Console.WriteLine(Encoding.UTF8.GetString(decrypted));
π Detached Mode (Manual Nonce)
Span<byte> key = stackalloc byte[XChaCha20Poly1305.KeyLen];
Span<byte> nonce = stackalloc byte[XChaCha20Poly1305.NonceLen];
RandomGenerator.Fill(key);
RandomGenerator.Fill(nonce);
var plaintext = Encoding.UTF8.GetBytes("Detached encryption");
Span<byte> ciphertext = stackalloc byte[plaintext.Length];
Span<byte> mac = stackalloc byte[XChaCha20Poly1305.MacLen];
XChaCha20Poly1305.Encrypt(ciphertext, plaintext, key, mac, nonce: nonce);
Span<byte> decrypted = stackalloc byte[plaintext.Length];
XChaCha20Poly1305.Decrypt(decrypted, ciphertext, key, mac, nonce: nonce);
Console.WriteLine(Encoding.UTF8.GetString(decrypted));
β οΈ Error Handling
ArgumentExceptionβ invalid input sizes.LibSodiumExceptionβ authentication failed (tampered data).
π Notes
- Nonce must be exactly 24 bytes.
- Auto-nonce is prepended to ciphertext for easy reuse.
- Buffers must have space for output (e.g., ciphertext includes MAC and possibly nonce). It can be longer than needed.
EncryptandDecryptautomatically choose combined or detached mode depending on the presence of themacparameter.- Use
RandomGenerator.Fill()to safely generate keys and nonces. - AAD is optional but recommended for additional authentication context.