WhatsApp recently announced that client communications are now end-to-end encrypted using Open Whisper System’s “Signal Protocol” (previously Axolotl). This has received quite a bit of press lately due to WhatsApp's massive user base, along with the controversial going dark debates. Less importantly, the crypto-nerd in me loves Signal. Because of all of this, I thought I would write a blog series on some of Signal's design decisions that I feel are well-designed.
Before diving into designing a protocol, it is crucial to understand the underlying design constraints. The Signal Protocol is designed to provide deniable and forward-secret asynchronous communications on mobile devices. While this is not a comprehensive list of all constraints, it does highlight several important design considerations. For the first blog post in this series, I will speak to some observations on why the Signal protocol is a great mobile-friendly end-to-end messaging protocol.
When compared to high-uptime servers, mobile devices are network- and hardware-constrained. A mobile-friendly end-to-end (e2e) protocol needs to minimize computational effort, network usage, and network reliance when reading and sending messages
One method of minimizing network reliance is to decrease the size of packets and/or limit messages that need a network round-trip. The Signal protocol approached this constraint in a few ways. To decrease packet size, message structures are serialized using protobufs. Protobufs have some advantages over more common data serialization methods (e.g. XML, JSON). Notably, the serialization process is faster and the serialized output is smaller.
Another network-related optimization is the Signal Protocol’s asynchronous method of encrypting messages under a shared key. This could be done rather simply (ignoring authenticity of the public key for now) by using a PGP-style public/private keypair. But this lacks a forward-and future-secrecy because in the most common case, Alice is only using a single keypair for an long period of time. In order to achieve *-secret network-tolerant asynchronous key exchanges, the Signal Protocol uses Trevor Perrin’s “double ratchet” (previously “Axolotl Ratchet”) algorithm. In the Signal Protocol, the first time Alice sends Bob a message, Alice must ask a key server for a “prekey”. In the Signal Protocol, these prekeys are signed by a user’s long-term identity key and they represent one-half of a DH key agreement. Alice can use Bob’s prekey to compute a shared secret (i.e. Alice computes the other half of the DH exchange). When Alice sends Bob a message, in addition to sending the encrypted message and relevant metadata, she also sends a new prekey. Then, whenever Bob happens to receive Alice’s message, Bob has everything he needs to compute the shared secret for message decryption. In addition, Bob can now compute a new shared secret using the prekey Alice sent with the message without any network round trips!
Furthermore, the Signal protocol leverages Curve25519 for all asymmetric cryptographic operations. Not only does Curve25519’s design meet several important elliptic curve security properties, but Curve25519 follows djb’s design motif of high-speed cryptography.
Signal isn’t perfect (but what is?) but has some really nice cryptographic properties that makes it a great option for reasonably secure end-to-end encrypted messaging. The next post in this series will talk about how Signal Protocol provides deniability.
Update: Read part 2 of this series, which covers my thoughts on Signal Deniability