Cwtch is still experimental software, and we have plenty of open questions about turning it into an application that meets our increasingly higher standards for anonymity, privacy and consent. It is no small feat and requires constantly evaluating our assumptions and previous expectations.
As we finally approach a Cwtch Beta, I want to take the opportunity to look back, with hindsight and fresh eyes, in order to understand where we go next.
A Pre-history of Tapir
Tapir began as an effort to extract the cryptographic and networking core from Cwtch into a small repository that could be reviewed and used independently. At that time Cwtch was still powered by a variant of the Ricochet protocol.
As amazing as Ricochet was when it first came out, it had started to show its age, with the main authentication protocol rooted in v2 onion services breaking certain aspects of offline deniability, and the unidirectional connections impacting performance on non-desktop devices.
We had already made major changes to the authentication protocol, introducing support for v3 onion services and a 3DH handshake to both not-break offline-deniability and generate a session key that would implicitly authenticate (in addition to encrypting) the connection as long as both peers considered the channel open.
The next pain point was then with Ricochet-style unidirectional channels in a group-messaging environment. In addition to performance in mobile environments, our vision for a protocol didn’t fit well with the structured setup and teardown of channels.
Finally, libricochet-go was tightly bound into Tor. As great as Tor onion services are, one day we all hope to be able to replace them with something that provides even stronger metadata resistance properties. Anything new therefore needs to provide a path forward for alternative integrations of Anonymous Communication Networks (ACNs).
And so, Tiny Anonymous Peer (Tapir) was born.
Nearly 2 years on from the initial commit, I think now is a good time to make explicit some observations that we have made over the course of building Tapir.
There is more to anonymity now than anonymous communication networks
Cwtch was a direct spin-off of my OnionScan research, an evaluation into how the people who build and rely on anonymous services fail. The goal of Cwtch has always been about providing a truly decentralized protocol platform for others to build on.
Even in the mid-2010s that consideration was tied explicitly to web servers, web applications and secure messengers, and to a lesser extent integration with other protocols like Bitcoin.
In recent years that has significantly changed. Cryptocurrencies and the services built on them have become a core part of life in many spaces. It is likely in the next few years that we will see a rise in services built on top of these ecosystems. Regardless of the specific anonymity guarantees of any individual service, the less-centralized approach taken by many cryptocurrencies presents an opportunity to provides anonymous access to them, and as such I would like Tapir to be in a place where such integrations can be safe and secure.
That observation results in a need to rethink the scope of Tapir. It is likely no longer prudent to think solely in terms of integration with ACNs but also integration with cryptocurrency nodes, light wallets, decentralized exchanges and decentralized social spaces.
Integrations will need to be sensitive to the privacy properties of the services, and provide ways to allow people to understand what information they may be exposing about themselves in a harm-reductive setting - to undertake actions with informed consent.
Go is a hard language to build secure applications in.
Go doesn’t have a great ecosystem of cryptographic libraries. At one point there were at least 3 different ed25519 implementations across Tapir dependencies: the standard library implementation, the extra25519 library (providing key conversion), and an additional implementation in the Bine library for integrating with Tor.
The ever-changing go vendoring/modules system also left a security impact. When the extra25519 library was removed from github, it not only broke our ability to build Tapir, but also left us with the unfortunate task of implementing that behaviour ourselves (although we were thankfully able to get rid of (most) of an ed25519 implementation in the process).
A sketch of the future…
Finally, and relating to the last point, it is undeniable that a large amount of great cryptographic engineering talent is being invested in the Rust ecosystem and not in the Go ecosystem. Libraries like dalek-crypto, merlin, swanky and our own fuzzytags all benefit from Rust’s strong type system and powerful abstractions to produce strong guarantees on safety and misuse resistance.
Right now Cwtch is mostly locked out of that talent. Cwtch can’t benefit from the safety or performance provided by those libraries.
To bridge that gap, we have already started to write new libraries (like fuzzytags) in Rust, and we have been engaged in various small experiments to see how we can begin to integrate rust into newer parts of Tapir and Cwtch.
Having now spent a significant amount of time working in Rust, going back to Go feels like driving without a seatbelt, which is not where I want to be when developing or providing safety critical cryptographic applications.
Rust certainly has downsides: fighting the borrow checker has almost become a rite of passage for newcomers and has given the language an air of unapproachability, and because it is newer, libraries and integrations are often lacking features, or in many cases contain bugs that haven’t had the benefit of years of use.
As an example of that last point, while experimenting with rust implementations of various parts of Tapir I’ve had to patch a Socks5 library that was dropping data, and a Tor interfacing library that could not start onion services.
Nevertheless, the ability to rely on a strong cryptographic ecosystem, to benefit from strong abstractions like const-generics, zero-cost abstractions, misuse-resistant constructions like the typestate pattern, fearless concurrency powered by strong ownership, powerful and safe macros, and everything else that rust provides makes that tradeoff a tempting one.
Enforcing consent requires strong tooling…
The beta version of Cwtch will offer a conservative approach to risk management. It will be light on features, but what features it has will have been extensively evaluated to ensure they provide as much metadata resistance as possible. This results in a core baseline of privacy for messaging (and not much else).
Once that is done, the challenge will be take the lessons we have learned over the last few years and construct a framework that permits management of greater risks, that allows people to selectively relax only as much anonymity and privacy as is necessary to carry out their goals, and to understand these choices before making them.
Such a vision is bigger than any one organization, system or tool. It requires a reassessment of how we build open ecosystems, how we evaluate trust and relationships and how we integrate services. Mostly, it requires support. There is always more work to do, more properties to formalize, more foundations to lay, and more possibilities to explore.