There are two mental models for designing a cryptosystem that offers end-to-end encryption to all of its users.
The first is the Signal model.
Predicated on Moxie’s notion that the ecosystem is moving, Signal (and similar apps) maintain some modicum of centralized control over the infrastructure and deployment of their app. While there are obvious downsides to this approach, it allows them to quickly roll out ecosystem-wide changes to their encryption protocols without having to deal with third-party clients falling behind.
The other is the federated model, which is embraced by Matrix, XMPP with OMEMO, and other encrypted chat apps and protocols.
This model can be attractive to a lot of people whose primary concern is data sovereignty rather than cryptographic protections. (Most security experts care about both aspects, but we differ in how they rank the two priorities relative to each other.)
As I examined in my criticisms of Matrix and XMPP+OMEMO, they kind of prove Moxie’s point about the ecosystem:
And this is personally a vexing observation, for two reasons:
(Aside from them mistakenly claiming to be Signal competitors, which I am not doing with my E2EE proposal or any implementations thereof.)
Fortunately, I have a solution to both annoyances that I intend to implement in my end-to-end encryption proposal.
Thus, I’d like to introduce Cryptographic Alacrity to the discussion.
Note: The term “crypto agility” was already coined by people who never learned from the alg=none vulnerability of JSON Web Tokens and think it’s A-okay to negotiate cryptographic primitives at run-time based on attacker-controllable inputs.
Because they got their foolish stink all over that term, I discarded it in favor of coining a new one. I apologize for the marginal increase in cognitive load this decision may cause in the future.
For readers who aren’t already familiar with the word “alacrity” from playing Dungeons & Dragons once upon a time, the Merriam-Webster dictionary defines Alacrity as:
promptness in response : cheerful readiness
Alacrity Definition & Meaning – Merriam Webster
When I describe a cryptography protocol as having “cryptographic alacrity”, I mean there is a built-in mechanism to enforce protocol upgrades in a timely manner, and stragglers (read: non-compliant implementations) will lose the ability to communicate with up-to-date softare.
Alacrity must be incorporated into a protocol at its design phase, specified clearly, and then enforced by the community through its protocol library implementations.
The primary difference between Alacrity and Agility is that Alacrity is implemented through protocol versions and a cryptographic mechanism for enforcing implementation freshness across the ecosystem, whereas Agility is about being able to hot-swap cryptographic primitives in response to novel cryptanalysis.
This probably still sounds a bit abstract to some of you.
To best explain what I mean, let’s look at a concrete example. Namely, how I plan on introducing Alacrity to my Fediverse E2EE design, and then enforcing it henceforth.
One level higher in the protocol than bulk message and/or media attachment encryption will be a Key Derivation Function. (Probably HKDF, probably as part of a Double Ratchet protocol or similar. I haven’t specified that layer just yet.)
Each invocation of HKDF will have a hard-coded 256-bit salt particular to the protocol version that is currently being used.
(What most people would think to pass as the salt in HKDF will instead be appended to the info parameter.)
The protocol version will additionally be used in a lot of other places (i.e., domain separation constants), but those are going to be predictable string values.
The salt will not be predictable until the new version is specified. I will likely tie it to the SHA256 hash of a Merkle root of a Federated Public Key Directory instance and the nickname for each protocol version.
Each library will have a small window (probably no more than 3 versions at any time) of acceptable protocol versions.
A new version will be specified, with a brand new KDF salt, every time we need to improve the protocol to address a security risk. Additionally, we will upgrade the protocol version at least once a year, even if no security risks have been found in the latest version of the protocol.
If your favorite client depends on a 4 year old version of the E2EE protocol library, you won’t be able to silently downgrade security for all of your conversation participants. Instead, you will be prevented from talking to most users, due to incompatible cryptography.
Let’s pretend, for the sake of argument, that we launch the first protocol version on January 1, 2025. And that’s when the first clients start to be built atop the libraries that speak the protocols.
Assuming no emergencies occur, after 9 months (i.e., by October 1, 2025), version 2 of the protocol will be specified. Libraries will be updated to support reading (but not sending) messages encrypted with protocol v2.
Then, on January 1, 2026 at midnight UTC–or a UNIX timestamp very close to this, at least–clients will start speaking protocol v2. Other clients can continue to read v1, but they should write v2.
This will occur every year on the same cadence, but with a twist: After clients are permitted to start writing v3, support for reading v1 MUST be removed from the codebase.
This mechanism will hold true even if the protocols are largely the same, aside from tweaked constants.
Alacrity allows third-party open source developers the capability of writing their own software (both clients and servers) without a significant risk of the Matrix and OMEMO problem (i.e., stale software being used years after it should have been deprecated).
By offering a sliding window of acceptable versions and scheduling planned version bumps to be about a year apart, we can minimize the risk of clock skew introducing outages.
Additionally, it provides third-party developers ample opportunity to keep their client software conformant to the specification.
It doesn’t completely eliminate the possibility of stale versions being used in silos. Especially if some developers choose malice. However, anyone who deviates from the herd to form their own cadre of legacy protocol users has deliberately or negligently accepted the compatibility risks.
Not easily, no.
This is the sort of mechanism that needs to be baked in from day one, and everyone needs to be onboard at the project’s inception.
Retroactively trying to make Matrix, XMPP, OpenPGP, etc. have Cryptographic Alacrity after the horses left the barn is an exercise in futility.
I’d love to help, but I’m already busy enough with work and my own projects.
If you’re designing a product that you intend to sell to the public, talk to a cryptography consulting firm. I can point you to several that are reputable, but most of them are pretty good.
If you’re designing something for the open source community, and don’t have the budget to hire professionals, I’ll respond to such inquiries when my time, energy, and emotional bandwidth is available to do so. No promises on a timeline, of course.
Header art also made by AJ.