Introduction
ChaCha20-Poly1305 is the AEAD cipher that TLS 1.3 and SSH both use as a default, and for good reason: it is fast in software, constant-time by construction, and free of the timing side channels that plague AES on CPUs without hardware acceleration. This tool encrypts and decrypts with ChaCha20-Poly1305 and XChaCha20-Poly1305 using @noble/ciphers, entirely in your browser. Paste a 256-bit key, type your plaintext, and the ciphertext plus a 128-bit authentication tag appear instantly. No data leaves your device.
What this tool does
- Encrypt and decrypt with ChaCha20-Poly1305 (96-bit nonce, RFC 8439) or XChaCha20-Poly1305 (192-bit nonce, extended-nonce construction) using @noble/ciphers
- Accept a 32-byte (256-bit) key in hex or Base64 format, with strict length validation
- Auto-generate a cryptographically random nonce using the Web Crypto API, or let you paste a specific nonce in hex for decryption
- Output ciphertext as hex or Base64, with the 128-bit Poly1305 authentication tag appended to the ciphertext
- Detect tampering on decryption: if the tag does not verify, the tool reports an error instead of returning corrupted plaintext
- Run entirely client-side: plaintext, keys, and ciphertext never touch a server
How this tool works
The tool uses @noble/ciphers' `chacha20poly1305` and `xchacha20poly1305` functions. For ChaCha20-Poly1305, the nonce is 12 bytes (96 bits). For XChaCha20-Poly1305, the nonce is 24 bytes (192 bits). The key is always 32 bytes (256 bits). The tool validates the key length strictly and shows an error if you provide fewer or more bytes.
When encrypting, the tool encodes the plaintext as UTF-8, generates a random nonce of the correct length via `crypto.getRandomValues`, calls `encrypt`, and outputs the result as hex or Base64. The output includes the ciphertext followed by the 16-byte Poly1305 tag. The generated nonce is displayed so you can copy it for decryption.
When decrypting, the tool interprets the input as hex or Base64, reconstructs the cipher with the same key and nonce, and calls `decrypt`. If the Poly1305 tag does not verify, @noble/ciphers throws an error and the tool displays it rather than returning garbage. This is the core property of authenticated encryption: you either get the correct plaintext or you get nothing. Everything runs in the browser. The key and plaintext are never transmitted.
How ChaCha20-Poly1305 works (RFC 8439)
ChaCha20 is a stream cipher designed by Daniel J. Bernstein, described in ChaCha, a variant of Salsa20 (2008). It is an ARX cipher: each round consists of add-rotate-XOR operations on a 512-bit state arranged as a 4x4 matrix of 32-bit words. The state is initialized with four constants (`expand 32-byte k`), eight key words, two counter words, and two nonce words. Each double round applies a quarter-round function to the four columns, then to the four diagonals. ChaCha20 runs 20 rounds (10 double rounds) and XORs the output with the original state to produce a 64-byte keystream block.
Poly1305 is a one-time authenticator also designed by Bernstein, described in The Poly1305-AES message-authentication code (2005). It computes a polynomial evaluation over GF(2^130 - 5) using a one-time key derived from the ChaCha20 keystream, producing a 16-byte (128-bit) tag. RFC 8439 combines them in an AEAD construction: the Poly1305 key is taken from the first 32 bytes of the first ChaCha20 block, the ciphertext is authenticated along with any associated data, and the tag is appended to the ciphertext.
XChaCha20-Poly1305 uses an extended 192-bit nonce. The first 128 bits are processed through HChaCha20 (a reduced variant that outputs 256 bits) to derive a subkey, and the remaining 96 bits are used as the ChaCha20 nonce. This construction, documented in the IETF draft, allows random nonces without collision risk. With the 96-bit nonce of standard ChaCha20-Poly1305, you must track nonce counts carefully.
TLS 1.3 (RFC 8446) includes `TLS_CHACHA20_POLY1305_SHA256` as a mandatory cipher suite. ChaCha20-Poly1305 is preferred on ARM devices and older x86 CPUs without AES-NI because it is faster than AES-GCM in pure software and naturally constant-time.
How to use this tool
- Select a variant: XChaCha20-Poly1305 (24-byte nonce, recommended for ease of use) or ChaCha20-Poly1305 (12-byte nonce, RFC 8439 standard)
- Enter your 32-byte (256-bit) key in the Key field. Switch between Hex (64 characters) and Base64 (44 characters) format as needed
- For encryption, leave auto-generate nonce enabled. The tool creates a random nonce and displays it after encryption so you can save it for decryption
- For decryption, uncheck auto-generate and paste the nonce in hex that was used during encryption. The nonce length must match the variant (24 or 12 bytes)
- Type or paste your plaintext (for encryption) or ciphertext in hex/Base64 (for decryption) in the main input area
- Select output format: Hex or Base64. For encryption, the output is ciphertext plus the 16-byte Poly1305 tag
- Click Swap encrypt/decrypt to reverse the operation. If the tag does not verify on decryption, the tool shows an error
Real-world examples
Encrypting a message with XChaCha20-Poly1305
Input: `Launch codes: 7-3-9-2` with key `80a41547b1b8c8d7d7d7c1c1e1f1a1b1c1d1e1f101112131415161718191a1b1` (hex, 32 bytes). The tool generates a random 24-byte nonce, encrypts the 20-byte plaintext, and outputs 36 bytes (20 bytes ciphertext + 16 bytes tag) in hex. The displayed nonce must be saved alongside the ciphertext for decryption.
Detecting tampering with the authentication tag
Encrypt a message and copy the hex output. Change a single character in the middle of the ciphertext hex string, then switch to decrypt mode and paste the modified hex with the same key and nonce. The tool reports a tag verification error and refuses to output plaintext. This is the AEAD property: any modification to the ciphertext or associated data is detected before decryption completes.
Why nonce reuse breaks ChaCha20-Poly1305
Encrypt two different plaintexts with the same key and nonce. The tool generates the same keystream for both, so XORing the two ciphertexts produces the XOR of the two plaintexts. An attacker who knows one plaintext can recover the other. Worse, Poly1305 tag forgery becomes possible. This is why the tool warns against nonce reuse. XChaCha20's 192-bit nonce makes random generation safe, but with the 12-byte nonce you must use a counter or never repeat.
Comparison with similar methods
| Method | Complexity | Typical use |
|---|---|---|
| ChaCha20-Poly1305 (RFC 8439) | 20 rounds, 256-bit key, 96-bit nonce, ARX | TLS 1.3, SSH, WireGuard, mobile and ARM devices |
| XChaCha20-Poly1305 | HChaCha20 + 20 rounds, 192-bit nonce | Application-level encryption, random nonces safe |
| AES-256-GCM (SP 800-38D) | 14 rounds + GHASH, 256-bit key, 96-bit IV | TLS 1.3 on x86 with AES-NI, VPNs, disk encryption |
| AES-128-GCM (SP 800-38D) | 10 rounds + GHASH, 128-bit key, 96-bit IV | TLS 1.3 default, most web traffic |
| AES-256-CBC (SP 800-38A) | 14 rounds, no authentication | Legacy systems, requires separate HMAC |
Limitations or considerations
This tool does not support associated data (AAD). RFC 8439 defines AEAD with optional additional authenticated data that is covered by the tag but not encrypted. @noble/ciphers supports AAD via an `encrypt(plaintext, AAD)` call, but this tool's UI does not expose it. If you need AAD, use the Block Cipher tool with AES-GCM, which does accept AAD.
The tool does not implement key derivation. If you need to derive a 32-byte key from a password, use PBKDF2 or Argon2 first, then paste the derived key here. Never use a human-typed password directly as a ChaCha20 key.
Nonce reuse with the same key is catastrophic. ChaCha20 is a stream cipher: reusing a nonce produces the same keystream, and XORing two ciphertexts reveals the XOR of the plaintexts. Poly1305 tag forgery also becomes possible. The tool auto-generates a random nonce for each encryption, which is safe with XChaCha20's 192-bit nonce. If you use the 12-byte nonce variant, switch to a counter-based nonce strategy in production.
This is a browser implementation for education and testing. For production encryption at scale, use a vetted library like libsodium or the Web Crypto API. The Block Cipher tool provides AES-GCM via Web Crypto for authenticated encryption with hardware acceleration.
Frequently asked questions
What is the difference between ChaCha20-Poly1305 and XChaCha20-Poly1305?
The nonce length. ChaCha20-Poly1305 (RFC 8439) uses a 96-bit (12-byte) nonce. With 96 bits, you can encrypt roughly 2^32 messages per key before the birthday bound makes random nonce collision likely, so you need a counter. XChaCha20-Poly1305 uses a 192-bit (24-byte) nonce via the HChaCha20 subkey derivation. With 192 bits, random nonce generation is safe for practical purposes, so you do not need to track a counter.
Is ChaCha20 faster than AES?
It depends on the CPU. On x86 processors with AES-NI instructions, AES-GCM is faster because the hardware acceleration is hard to beat. On ARM devices, older x86 CPUs without AES-NI, and microcontrollers, ChaCha20 is faster because it is a pure software ARX design with no lookup tables. This is why mobile browsers and IoT devices prefer ChaCha20-Poly1305 in TLS 1.3.
What is the Poly1305 tag and why does it matter?
Poly1305 produces a 128-bit (16-byte) authentication tag that is appended to the ciphertext. On decryption, the tag is recomputed and compared. If even one bit of the ciphertext or associated data was modified, the tags will not match and decryption fails. This is what makes ChaCha20-Poly1305 an AEAD cipher: it provides both confidentiality and integrity, unlike CBC or CTR which are malleable.
Can I use this tool with a password instead of a key?
No. ChaCha20 requires a 32-byte (256-bit) key, not a password. If you want to encrypt with a password, derive a key first using PBKDF2 or Argon2, then paste the 32-byte derived key into this tool. Using a password directly as a key (padding or hashing it yourself) is insecure because passwords have low entropy.
Why does the tool show an error when I decrypt with the wrong key?
The Poly1305 tag is computed from the ciphertext and the key-derived one-time authenticator key. If you use the wrong key, the tag will not verify and @noble/ciphers throws an error. The tool displays this error rather than returning corrupted plaintext. This is the correct behavior for an AEAD cipher: failed authentication means no output.
Conclusion
ChaCha20-Poly1305 is the modern AEAD cipher of choice for software-only environments, used in TLS 1.3, SSH, WireGuard, and the libsodium library. This tool lets you encrypt and decrypt with both the RFC 8439 standard and the extended-nonce XChaCha20 variant, with the Poly1305 tag verified on every decryption. For AES-GCM with hardware acceleration, use the Block Cipher tool. For the educational round-by-round AES view, see the AES Encrypt / Decrypt tool. To derive a key from a password before encrypting, use PBKDF2 or Argon2.