How WireGuard actually works
Most VPN marketing describes encryption as a wall. It is closer to an envelope: something wraps each packet before it leaves your device and unwraps it at the other end. What matters is who can open the envelope, what is written on the outside, and how much machinery is involved in agreeing the whole scheme.
WireGuard's answer to the last question is: as little as possible.
Everything below is checkable against the WireGuard whitepaper and the protocol specification. The last section is about us, and it is checkable too.
The size argument is the security argument
The whitepaper's own figure is that the Linux implementation is under 4,000 lines of code, excluding the cryptographic primitives. The usual comparison, as The Register put it in 2018, is roughly 100,000 lines for OpenVPN plus another 500,000 for the OpenSSL it depends on, and around 400,000 for StrongSwan, the key-exchange half of a typical Linux IPsec setup. The counts are approximate and the comparison is not entirely fair, since the larger codebases do more. The gap is still two orders of magnitude.
That is not a performance boast. It is an auditability claim. Four thousand lines can be read end to end by one competent person in a few days. Half a million cannot be read by anyone, which means nobody has, which means the security of the thing rests on the absence of reports rather than the presence of review.
Heartbleed is the standard illustration, and the dates bear it out. The flawed code was committed to OpenSSL on 31 December 2011, shipped in version 1.0.1 on 14 March 2012, and disclosed on 7 April 2014. Just over two years in released software, on the library a large share of the internet used for TLS. Nobody was being careless. There was too much surface for anyone to see all of it.
No negotiation, therefore no downgrade
Older VPN protocols negotiate. The client offers a list of ciphers, the server picks one, and the two agree on parameters before any data moves. That flexibility is where a large share of TLS and IPsec vulnerabilities have lived: an attacker who can influence the negotiation can often push both sides onto the weakest option they both support.
WireGuard does not negotiate. The construction is named in the specification as
Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s, and the
primitives are fixed:
| Purpose | Primitive |
|---|---|
| Authenticated encryption | ChaCha20-Poly1305 |
| Key exchange | Curve25519 |
| Hashing and keyed hashing | BLAKE2s |
| Key derivation | HKDF |
| Hashtable keys | SipHash24 |
There is no cipher list, so there is nothing to downgrade. The cost is real and worth stating: if one of those primitives is ever broken, WireGuard does not gracefully fall back. It needs a new protocol version, and everyone has to update. That is a deliberate trade of flexibility for a much smaller attack surface.
A note for anyone comparing marketing pages. WireGuard does not use AES-256. A VPN advertising "AES-256 military-grade encryption" alongside WireGuard is either running something else or does not know what it ships. ChaCha20 is not weaker. In software it is usually faster, because it does not depend on hardware AES instructions.
The handshake
WireGuard uses the IK pattern from the Noise Protocol Framework. The whitepaper describes it as a single round-trip key exchange: the initiator sends one message, the responder sends one back, and the initiator can send data. Each peer knows the other's public key in advance, so identity is established by the handshake rather than by certificates, and there is no PKI to misconfigure.
Three properties fall out of that design and all matter more than they sound.
It is silent by default. The specification is explicit that the server does not even respond at all to an unauthorized client. Every handshake message carries a MAC keyed on the responder's public key, so a peer has to already know who it is talking to in order to get any reply. To a port scanner, a WireGuard endpoint is indistinguishable from a closed port. Nothing announces "a VPN lives here."
Sessions rekey. The whitepaper's timer table sets Rekey-After-Time at 120 seconds and Reject-After-Time at 180, so a session key is replaced after two minutes of use and refused after three. Each handshake generates fresh ephemeral Curve25519 keys, which is what gives the protocol forward secrecy: recovering a peer's long-term private key does not let anyone decrypt traffic they captured earlier, because the session keys that actually encrypted it were derived from ephemeral material that has since been zeroed.
Identity is hidden on the wire. The initiator's static public key is sent encrypted inside the first message, not in the clear. The whitepaper lists identity hiding among the handshake's properties alongside forward secrecy and resistance to key-compromise impersonation.
Cryptokey routing
This is WireGuard's genuinely novel idea and the one worth understanding, because it is also where the privacy question for a commercial VPN lives.
In most VPNs, routing and authentication are separate systems: one decides where a packet goes, another decides whether you are allowed. WireGuard fuses them. The whitepaper states the principle as an association between a peer public key and a tunnel source IP address. Each peer's public key is bound to a set of allowed IP addresses. An outgoing packet is encrypted for whichever peer's allowed set contains its destination. An incoming packet, once decrypted and authenticated under a given key, must carry a source address from that key's allowed set, or it is dropped.
The consequence: an authenticated peer cannot spoof another peer's address. The routing table is the access control list. There is no second system to get wrong, and a firewall rule on the tunnel interface can trust the source address it sees.
Roaming
A WireGuard peer is identified by its key, not its address. The whitepaper compares this to Mosh: the far end uses the outer source address of the most recent authenticated packet as the place to send replies. Move from wifi to mobile data and the tunnel continues. No reconnect, no renegotiation.
Why it is fast, and what it costs
On Linux, WireGuard runs in the kernel. It was merged for Linux 5.6, released 29 March 2020, and has shipped by default in every kernel since. Packets are not copied back and forth to a userspace daemon, and the whitepaper's design goals include allocating no resources in response to an incoming packet.
Userspace implementations exist for everything else.
wireguard-go is the reference,
and boringtun is Cloudflare's Rust
implementation. Most non-Linux clients use one of them. They
are slower than the kernel module, though usually still faster than OpenVPN.
It is UDP only. There is no TCP mode, which is correct, because tunnelling TCP inside TCP behaves badly under packet loss. It also means WireGuard is easier to block than protocols that can hide inside TLS on port 443. Providers work around that with obfuscation layers. The base protocol makes no attempt to look like anything else, and a network that wants to drop it can.
The part most write-ups leave out
WireGuard was designed as a general-purpose tunnel between peers that already know each other's keys. A commercial VPN is a particular case of that: one peer is a server with thousands of strangers on the other side, and the strangers change constantly. That mismatch creates a real privacy problem, and it comes straight out of cryptokey routing.
The server has to hold a table mapping each public key to an assigned internal IP. Without it, the server cannot decide which allowed set an incoming packet must match. Whatever a provider's policy says, that table exists on every WireGuard exit, because the protocol cannot run without it.
Two things follow.
First, the table is a record. In the naive deployment it is persistent, it identifies a device for as long as the key is registered, and it is exactly the kind of state a no-logs provider should think carefully about. A row in it does not say where you went or when. It does say that this device belongs to this account and uses this internal address.
Second, the internal address is a handle. Mullvad's reason for rotating WireGuard keys automatically, in their own words, is to make it harder to track and fingerprint a single user by figuring out their tunnel IP, which is bound to the WireGuard key. Their no-logging policy lists what they store for a WireGuard configuration as exactly three fields: account number, public key, tunnel address. Proton takes the opposite view on rotation, arguing it adds little because the keys that encrypt traffic are the per-session ones WireGuard already rotates, and instead revokes the stored keys when you log out. IVPN deletes its device session records on logout.
Every serious WireGuard provider has had to engineer around the table somehow: rotation, revocation on logout, in-memory peer lists, short-lived keys. The approaches differ and the arguments between them are real. What they share is that someone looked at the table and made a decision about it.
A provider that has not thought about it has a device-to-internal-IP mapping sitting on disk, whatever its privacy policy says. This is a fair question to ask any VPN running WireGuard, and the answer tells you more than the protocol name does.
Our answer
We would rather answer that question than invite it, so here is ours. We are pre-launch, so this describes what is built, not what has been tested under load or audited by anyone. Judge it accordingly.
The key is generated on your device. Our clients and the web account page generate the keypair locally and send us the public half alone. The private key is written to the device's keychain or stays in the browser, and no request to our API carries it.
We hold a device record, and here is all of it. For every device you register: a name, the public key, the internal address assigned to it, when it was created, and whether it is active. The name is two random words we pick, "Silent Fox" or similar; you do not supply it and cannot change it, so it never carries yours. That record exists for as long as the device does. You can delete a device from the account page, and deleting it removes the row.
What the record does not hold. It has fields for a chosen country, city or server. The clients we ship do not set them: a device is registered with its public key alone, and the server you connect to is chosen at connection time and not written down. Room in a schema for a location preference is a decision we have not made, not data we keep. If that changes, this list changes.
The exits read that table. They do not write to it. Each server pulls the list of active public keys and their internal addresses for the scopes it serves. Connecting, disconnecting, moving between networks and transferring data write nothing back. Whether a device is connected right now, and to which server, lives in memory on that server and nowhere else.
No connection history exists, and a test says so. We hold no connection timestamps, no connection counts and no source IP addresses against an account. The fields that could have held two of those once existed in our schema, unwritten; we removed them and added a test that fails the build if either name comes back. That is a smaller promise than "no logs" and a more checkable one.
What this does not do. The internal address is stable for the life of the device, so the fingerprinting concern Mullvad rotates keys to blunt applies to us for as long as you keep a device registered. Deleting and re-registering a device gets you a new key and a new address; nothing does it for you yet. The table also means that a valid legal demand naming an account could be answered with that account's public keys and internal addresses. It could not be answered with where you went or when, because that is not written anywhere.
That is the whole table, stated plainly. The question above is one we think every WireGuard provider should be asked. Ask us again at launch.
FAQ
What encryption does WireGuard use?
ChaCha20-Poly1305 for authenticated encryption, Curve25519 for key exchange, BLAKE2s for hashing, and HKDF for key derivation. These are fixed by the protocol and cannot be negotiated.
Is WireGuard more secure than OpenVPN?
It has a much smaller attack surface, under 4,000 lines of code against the hundreds of thousands in OpenVPN plus OpenSSL, and it removes cipher negotiation, which has been a recurring source of vulnerabilities. Both are considered secure when correctly configured. WireGuard is substantially easier to configure correctly.
Does WireGuard use AES-256?
No. It uses ChaCha20-Poly1305. A service advertising AES-256 with WireGuard is describing something other than what it ships.
Is WireGuard faster?
Usually, especially on Linux, where it has run in the kernel since version 5.6. The gap narrows with the userspace implementations other platforms use.
Does WireGuard log anything by itself?
The protocol writes no logs. But cryptokey routing requires every server to hold a table mapping public keys to internal IP addresses, and how a provider handles that table determines whether a persistent record of your device exists.
What does LookerVPN store for a WireGuard device?
A two-word name we generate, the public key, the assigned internal address, its creation date and its status, for as long as the device is registered. No location preference: the clients register a key alone, and the server you use is not written down. The private key is generated on your device and never sent to us. Nothing is written when you connect.
LookerVPN Team
Writes for The Looker Dispatch on privacy, threat research, and how the modern web actually works.
Detach your identity from your fingerprint.
LookerVPN won't stop the canvas test. It will stop it from being linked to your name.