It is strange to think that less than two months have passed since the last time I wrote here. In this short period, I learned about languages and libraries (Rust, TypeScript, React, Tailwind CSS, etc.), containerization and deployment (Docker, fly.io, Azure, etc.), aspects of HTTP (MIME types, CORS, etc.) and software in general (RNG’s, WebAssembly, WebPack, NGINX, etc.).
I have been focusing mainly on two things. On the one hand, I worked on our Secure Multi-Party Computation (SMPC) engine. I will tell you more about my experience with it after its release, which will happen during the next week! On the other hand, I worked on Encryptle, our word-guessing game that will allow you to see the SMPC engine in action. I will tell you more about it below.
So, what is Encryptle? It is a privacy-preserving version of New York Times’s popular game Wordle, running on top of our SMPC engine. Encryptle plays just like the regular Wordle: the user types in a five-letter word and is told for each letter whether the secret word (that changes daily) contains that letter and, if so, whether it is in the right place. The difference lies on the way this information is computed. In the original Wordle (and in other versions thereof), the user’s guess is sent over to the server, where it is compared to the secret word. In Encryptle neither the server has access to the user’s guesses, nor the user to the server’s word of the day (except by correctly guessing it, of course). The two words are never actually compared! This might sound impossible, but it is precisely what Secure Multi-Party Computation brings to the table: the possibility of collaborating over data (in this case, the guess and the solution) while keeping it private. Server and client only share encrypted messages (hence the name), keeping the actual letters hidden from both parties. Soon, we will tell you more about how our engine achieves this: stay tuned!
At the end of the last post, I said that I knew how to start working on what would eventually become Encryptle. Indeed, it didn’t take long to develop the very first iteration of the game. It ran on the command-line and used ASCII codes instead of letters—hence being hilariously difficult—but it ran on top of the SMPC engine nevertheless! I was very happy and eager to improve on it.
With the support of my colleagues, I got it to use letters and moved on to the next challenge: having the server randomly select a word from a list. This might sound very simple, but there’s a catch: we needed the randomness to be synchronized. In other words, we needed to have one word per day, regardless of how many servers would run the app and of whether they were restarted. Since, evidently, we also needed the word to remain secret, we could not use any easily crackable logic.
These complexities got me thinking of how we take for granted that we can instruct a machine to do something at random. As users of computers, we don’t even notice how conceptually bizarre this idea is. A computer is a machine and will only do what we tell it to. Just as a car won’t turn “at random,” so a computer won’t spit out data “at random.” Behind what seemed to be a very simple step, lied this extremely interesting conceptual puzzle. This would be enough to keep us entertained for a long time discussing the very notion of randomness and how it relates to determinism. But part of the beauty of software development is that we are forced to have a down-to-earth approach to philosophical and conceptual problems (which, if I may venture, makes it a great place from which to tackle philosophical discussions). It turns out we don’t actually tell a computer to select something at random, but rather give it some data—the seed—and complex instructions on how to select something based on it. As long as the seed remains inaccessible, it is virtually impossible to know how the data is being generated and we get our desired “randomness.” In the standard cases, we use a seed provided by the operating system that represents some physical state of our machine. This is exactly what we couldn’t use in our case. And luckily so, as it led me to learn and think about Random Number Generators (RNGs).
Once we started working on the frontend of our app, we realized that there are many Wordle (so to say) clones. We found this repository, providing one such clone under an MIT license and decided to use it, adapting it to our particular needs. This proved to be an amazing learning opportunity. At first, the idea of adapting a whole app to something for which it had not been built was overwhelming and I failed to see how it could be put together with our engine. After a very useful pair programming session, however, I learned how to overcome this difficulty and also how I could tackle similar situations in the future. As time went by, I got more familiar with the code and started being able to fix frontend issues by myself, which was very rewarding.
Encryptle was a very fun project to work on. It allowed me to learn about all sorts of things, from React, TypeScript, and (easy to neglect) CSS animations to WebAssembly, MIME types, Docker, and deployment solutions, among others. I got all the support I needed, but also felt like I was given enough space to try things out on my own. I am quite proud of the result and hope that people can have fun with the game while also learning about SMPC. It is just a matter of days until that is possible. At SINE, we are very excited about the release of our SMPC engine and hope we can get you on board! I will be writing here again when it happens!