AES-256 vs ChaCha20: which cipher does a VPN want?
Both are considered secure and neither has a practical break. The difference is speed on the hardware doing the work: AES is faster where the CPU has AES instructions, and ChaCha20 is faster in pure software, which describes most phones, routers and streaming devices.
5 min read
Both ciphers are used in production by everything that matters, both have survived extensive analysis, and neither has a practical attack against it. The choice between them is a performance question and a hardware question, not a security one. Anyone selling one as meaningfully safer than the other is selling something.
What each one is
AES is a block cipher standardised by NIST in 2001, operating on 128-bit blocks with a 128, 192 or 256-bit key. In a VPN it is almost always used in GCM mode, which provides authentication as well as encryption in one pass.
ChaCha20 is a stream cipher published by Daniel J. Bernstein in 2008, paired with the Poly1305 authenticator and standardised together in RFC 8439. It uses a 256-bit key and is designed to be fast and constant-time in software.
The hardware difference
This is the whole practical story.
Intel added AES-NI instructions in 2010, and ARMv8 added AES extensions. On a CPU with those, AES-GCM runs several times faster than any software implementation could, because the round function is a single instruction.
ChaCha20 has no such instruction anywhere. It was designed to be fast using only addition, rotation and XOR, which every CPU does well.
| Hardware | Faster |
|---|---|
| Modern x86 desktop or laptop | AES-GCM |
| Recent ARM phone or tablet | AES-GCM, usually |
| Older or budget ARM device | ChaCha20 |
| Most consumer routers | ChaCha20 |
| Streaming sticks and TV boxes | ChaCha20 |
| Microcontrollers and embedded | ChaCha20 |
The devices in the bottom half of that table are exactly the ones where a VPN's throughput is most likely to be limited by the CPU, which is why ChaCha20 matters more than the desktop benchmarks suggest.
The timing-attack argument
A software AES implementation typically uses lookup tables, and table lookups take different amounts of time depending on what is in cache. That leaks information about the key, and cache-timing attacks against software AES are well documented.
Hardware AES does not have this problem, and neither does ChaCha20, which is constant-time by construction.
The practical relevance for a VPN client on your own device is low — an attacker who can measure your cache timing is already running code on your machine. It matters more on shared infrastructure, and it is one of the reasons ChaCha20 is preferred where hardware AES is unavailable.
What each protocol does
WireGuard uses ChaCha20-Poly1305 exclusively, with no option. That is consistent with its design philosophy of removing negotiation entirely, and it is a good fit for its target hardware, since a router or a phone is where the CPU cost is felt.
OpenVPN negotiates from a list, typically AES-256-GCM and ChaCha20-Poly1305, with the faster one for the hardware usually winning.
TLS, and therefore HTTPS, negotiates the same two. If you have ever wondered what your browser picks, it is generally AES-GCM on desktop and ChaCha20 on mobile — the same split.
Key length, briefly
AES-256 versus AES-128 is a question people spend more time on than it deserves. AES-128 has no practical attack and a 128-bit key is beyond brute force by any foreseeable classical computer. AES-256 exists for margin and for regulatory requirements.
Grover's algorithm on a sufficiently large quantum computer would halve the effective key length, making AES-256 behave like AES-128 — which is still out of reach. Symmetric encryption is not where quantum computing threatens current cryptography; key exchange is.
What to do about it
Nothing, in most cases. Use whatever your client negotiates.
If you are tuning throughput on a slow device — a router, a TV box, a Raspberry Pi — and the protocol lets you choose, ChaCha20 is the right answer, and it is one reason WireGuard performs so well on the Android TV class of hardware.
Measure rather than assume. The speed test run on the actual device tells you more than any benchmark table, because the number that matters is what your hardware does with your line.
Why AES-GCM and ChaCha20-Poly1305 rather than the raw ciphers
Neither cipher is used alone. Both are paired with an authenticator, producing an AEAD construction: authenticated encryption with associated data.
The reason is that encryption without authentication is dangerous in ways that are not obvious. An attacker who cannot read a message can still flip bits in it, and with a stream cipher a flipped bit in the ciphertext is a flipped bit in the plaintext. Padding-oracle attacks against older CBC-mode constructions are the well-known example of what follows.
AEAD makes tampering detectable: any modification causes the authentication tag to fail and the packet to be discarded. Every current VPN protocol uses one, which is why you see the mode names rather than the bare cipher names in configuration files.
Nonce handling, which is where implementations go wrong
Both constructions require that a nonce is never reused with the same key. Reusing one is catastrophic — with GCM it can reveal the authentication key outright, not merely one message.
ChaCha20-Poly1305's 96-bit nonce and WireGuard's simple counter-based scheme make this easy to get right. AES-GCM's nonce is the same length and has been got wrong repeatedly in the wild, usually by generating it randomly at high volume and hitting a collision.
That is an argument about implementation risk rather than about the ciphers, and it is a real one when choosing what to build with.