Signal, Trust on First Use
Trevor Perrin’s talk on the TextSecure protocol, what the world now knows as the Signal Protocol, is one of the best things I’ve watched on applied cryptography. He spends most of it on authentication, which gets a lot less attention than the ratchet does.
The discussion around Signal tends to focus on the Double Ratchet, which combines Diffie-Hellman and symmetric ratchets to give you forward and future secrecy. It’s clever and it deserves the attention it gets. But the part I keep coming back to is how the protocol handles authentication, and how honest Perrin is about what authentication can realistically achieve.
Where encryption stops
Signal encrypts messages with keys derived from X3DH (an extended Diffie-Hellman handshake that can set up a session while the other party is offline) and the Double Ratchet. Compromise the long-term keys and past messages stay protected, and future sessions recover once fresh ephemeral keys come into play.
None of that tells you you’re encrypting to the right person. If the key server hands you a malicious public key you’ll happily encrypt a perfectly secure message straight to an attacker. Authentication is a separate problem, and a harder one, because it’s the one place you can’t keep the user out of.
Usable security
PGP tried to solve this with manual key verification and webs of trust. It worked for experts, and it never got near mass adoption, because the process asked far too much of everybody else.
Signal’s answer was to make the encryption invisible. Key generation, prekeys, rotation, session setup, all of it happens without the user thinking about any of it. You install the app and your messages are encrypted.
You can’t pull the same trick with authentication. As Perrin points out, at some stage the user has to be involved, so the question becomes what you do when you already know most people will never complete a verification ceremony.
One option is to insist on it anyway. No verification, no secure channel. In practice that means only a small subset of users get protection, and those users then become identifiable as the security-conscious ones, which is a bad outcome for them.
Signal went the other way and encrypted everything by default, with verification left optional. Everyone gets encrypted transport. Some people scan QR codes or compare fingerprints, most don’t, and an observer can’t tell which is which.
Trust on first use
The first time you fetch a contact’s key you take it and store it. If it changes later you get a warning.
It’s imperfect and I don’t want to oversell it, plenty of people will click straight through that warning without reading a word of it. But the friction lands in the right place. The initial key gets recorded silently and only a change interrupts anybody, so what you’re aiming for is that a suspicious key change gets noticed some of the time, by somebody.
Stronger guarantees are there if you want them, scan the QR code out of band. Skipping it doesn’t weaken the encryption, it means you’re trusting the key directory, and for most conversations that’s a trade I’d take without much thought.
Cryptographic engineering
The primitives here are all well understood. What’s impressive is how they’re composed into something that survives real conditions: asynchronous delivery, key exhaustion, multiple devices, group chats, servers you’d rather not have to trust. I’ve sat in enough design reviews where a scheme that was perfectly sound on the whiteboard fell apart on the second or third of those.
The authentication story shows that gap better than anything else in the protocol does. Signal encrypted everything. The verification is still in the app if you want it, and most people never open that screen. It protects them anyway, because an attacker doesn’t get to know which people those are.