ChaCha20-Poly1305
ChaCha20-Poly1305 is the modern AEAD pair: ChaCha20 stream cipher + Poly1305 MAC. It runs in constant time without hardware acceleration — the right pick on mobile, embedded, and any CPU without AES-NI.
ChaCha20-Poly1305 in libsodium
EXAMPLE
// Browser / Node — via libsodium-wrappers
import sodium from 'libsodium-wrappers';
await sodium.ready;
// 1. Generate a key (or store + retrieve one safely)
const key = sodium.crypto_aead_chacha20poly1305_ietf_keygen();
function encrypt(plaintext, key, aad) {
const nonce = sodium.randombytes_buf(
sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES, // 12 bytes
);
const ct = sodium.crypto_aead_chacha20poly1305_ietf_encrypt(
plaintext, aad, null, nonce, key,
);
return { nonce, ct };
}
function decrypt({ nonce, ct }, key, aad) {
return sodium.crypto_aead_chacha20poly1305_ietf_decrypt(
null, ct, aad, nonce, key,
);
}
const aad = sodium.from_string('user-42');
const { nonce, ct } = encrypt(sodium.from_string('balance:1000'), key, aad);
console.log(sodium.to_string(decrypt({ nonce, ct }, key, aad)));
// Same rules as AES-GCM:
// • Never reuse a nonce with the same key.
// • AAD authenticates but doesn't encrypt — use it for IDs, headers.
// • Decrypt failure throws — never silently return partial output.
Why it matters
When you can’t guarantee hardware AES (mobile, IoT, WASM), ChaCha20-Poly1305 outperforms AES-GCM. TLS 1.3, WireGuard, and modern SSH all reach for it.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// libsodium
const sodium = await require('libsodium-wrappers').ready;
const key = sodium.crypto_aead_chacha20poly1305_ietf_keygen();
const nonce = sodium.randombytes_buf(12);
const ct = sodium.crypto_aead_chacha20poly1305_ietf_encrypt('hi', null, null, nonce, key);
Try it Yourself »
Discussion
Loading…