My Research
TL;DR: I'm interested in building compilers and PLs for privacy-preserving computation.
The style of privacy-preserving computation I'm interested in is Multiparty Computation (MPC): a class of cryptographic techniques in which mutually distrustful parties collaborate to compute a function without revealing their private inputs to the function. More specifically, a lot of my work deals with Fully Homomorphic Encryption (FHE), a particular MPC protocol that works by encrypting inputs and then performing computations on the ciphertexts. People care a lot about MPC—at least, I do—because it enables privacy-preserving computation, and has some really cool applications like secure machine learning or offloading analyses over sensitive data. Unfortunately, actually writing programs that use MPC in practice is really hard: even in the current state of the art, the cryptographic overhead is insane (like, several orders of magnitude slower than normal), and the programming model can be highly counterintuitive for non-cryptographers.
I'm a compiler person, and with compilers as my hammer, the world of MPC looks a lot like a nail: a compiler can abstract away all the messy details about the MPC programming model, and allow you to write programs in a comfortable, familiar language. A lot of classic MPC compilers take a very…80's-esque…approach to compilation (mechanically translating operations into their secure equivalents and doing very little optimization on top of this). My research focuses on building compilers that are MPC-aware: By knowing something about the MPC scheme we're targeting, we're able to automatically apply some really cool tricks from the depths of crypto literature! For example, in Coyote, I showed how, by considering the subtleties of the cost model for vectorization in some FHE schemes we can avoid a lot of the pitfalls that classic, SLP-style vectorizers run into (and, as an added benefit, automatically find really good data layouts!) In COIL, I demonstrated that because of the way branches work in MPC (they don't), we have to be really careful when translating programs with control flow. By playing some clever tricks involving remembering branching conditions, we can sometimes avoid doing unnecessary computation altogether!
Of course, we can take all this a step further. Instead of just designing compilers that target particular cryptosystems, we can make cryptosystems that are better compilation targets and then build the compilers (I'm calling this "compiler-cryptosystem codesign" because it sounds like "hardware-software codesign"). I started working towards this goal with COATL, where I showed that by replacing the fundamental unit of computation in CGGI (a particular style of FHE scheme) with a thing I called arithmetic lookup tables instead of the usual Boolean gates, we can build compilers that manage to express the same programs using fewer CGGI operations overall!
My research barely scratches the surface of what I think is possible in this space!
A question I've been thinking about recently is, what features should a cryptosystem support to make compiler writers' jobs easier? What are the right abstractions to use here at the protocol level? What about at the "language" level? Some really cool people have done some really cool work (like Viaduct, Taype) about designing better languages for MPC, but a lot of this is still pretty theoretical; how do we build actual, usable compilers for these languages?
People have recently been looking at running FHE on things like dedicated hardware accelerators; what would it take to write compilers that target these, instead of the usual FHE libraries?
Finally, cryptographers keep adding features to their FHE schemes that compilers don't really know how to use (my favorite examples of this are scheme switching and faster BFV bootstrapping). Someone should do something about that!!
If any of these questions sound interesting to you, or you have ideas or answers, please feel free to contact me!