We’re starting to see more and better software that implements various zero-knowledge techniques, which is great.
There are different types of code out there:
-
Proving systems that generate and verify proofs.
-
Frameworks that let us express the statements to prove.
-
Collections of helper routines and gadgets.
-
Applications that implement specific statements and are distributed to end-users.
There’s a parallel with classical software engineering to make:
- Machine architectures, 2. Languages and compilers, 3. Functions and libraries, 4. Executable programs.
Today, these layers tend to be tightly coupled, and we find multiple stacks, written in different languages, with their own approach to each issue. This does make sense for now, as a team of experts can produce multiple layers together and deliver a specific product.
But zero-knowledge proving has potential for a variety of applications; not just in specialised products, but as a new technique engineers can use in larger systems, as they do today with encryption, signatures, etc. Meanwhile, complexity and requirements will increase, and there will be more teams throughout the world working on zero-knowledge software. We might even see some kind of equivalent to JavaScript, included in many products to execute on many clients. If any of this is to happen, the ecosystem will exhibit more and more software engineering practices. A particular impact may come from thinking in terms of systems, components, and interfaces, which is generally beneficial in multiple ways:
-
Less effort required to build and review complex applications if it is made of components.
-
The ability to coordinate the efforts of multiple teams who agree on the interfaces between components.
-
More effective systems, as the most appropriate component can be chosen for each layer.
-
Quicker deployment of innovations, when a new technique can be implemented in one layer and integrated with existing tools.
-
Familiarity of concepts for non-specialists.
Some elements of system engineering do appear naturally in individual projects. Libsnark separates the proving systems from the gadgets through C++ interfaces. The implementation of Zcash Sapling looks a lot like a set of layers and components. In ZoKrates, the developer is exposed to the familiar concepts of programs being compiled and functions returning outputs from inputs; this independently of third-party proving systems and gadget libraries the compiler might support.
In this spirit, we put a lot of thoughts into how interoperability across today’s and tomorrow’s projects could work. We present a step in this direction as a proposal in the 2nd ZKProof standards workshop, which you can find at https://github.com/QED-it/zkinterface. Many thanks to all who did or will review and comment this proposal. Feel free to discuss here.