Here is the follow up of the ZKProof workshop on Zero Knowledge Programmability from the “freeform” sessions at Zcon1. I have compiled a set of notes and hope to see fruitful discussions.
In general we understand that Zero-knowledge applications would greatly benefit from on-the-fly feature extensibility, programmable queries and most often have a common underlying protocol that ensures security and interaction with external systems (such as blockchains). Building a community standard for such programmable model would benefit developers, researchers and the industry as a whole.
We spoke about several topics, but here are the main points (and see below for more concrete directions we took - also feel free to add or correct me).
Scripting languages for ZK have started to appear:
- ZEXE (see here for repository) is a scripting language (such as bitcoin but private) that enables fully programmable predicates within the transactions, while hiding the actual predicates (uses recursive composition). It does carry a large overhead in computation and validation.
- zkVM (see here for repository) is another scripting language designed specifically for programmable asset transfers. Mainly, zkVM transactions contain programmable constraints over encrypted data and assets, where the ZKP system is based on Bulletproofs, which can also create some overhead in computation.
- PayToVK is another method for programmability that was considered by the Zcash team (see here for the earlier discussions). It allows for scripting of different features without having to change the underlying protocol.
Different types of predicates to be modeled by the system:
- Some predicates must be public so that all players have the ability to verify correctly the statements, such as in the case of consensus verification / validation. These predicates are usually fixed (not programmable) so the model should be built on this premise.
- Other predicates can be private, so that players do not actually know what is the application that is being instanciated. This goes hand-in-hand with the idea of having transaction indistinguishability as a security requirement, and these predicates should be written on-the-fly and not be fixed within the underlying protocol.
The API abstraction level must be defined in order to ensure security at the language level, as well as the protocol level. Furthermore we want developers to be able to work with this API in an easy and efficient manner.
We agreed on a small set of basic requirements that such a scripting language must contain
- Language safety: implementing ZK constraints requires handling carefully the memory allocation, the types and values, etc… Each has their own subset of constraints that need to be met (a.k.a. a boolean needs to be checked inside the circuit).
- Protocol security: using cryptographic primitives entails ensuring specific security needs, such as collision resistance within membership proofs, or non-malleability for signatures and authentication. The language should remove from the developer as much of these assurances as possible.
- Understandable and efficient model: developers must be able to easily understand the model in question and the abstraction layers; as well as making sure that the efficiency of the system does not have too much of an overhead.
- Interoperability: we want to enable users to use their favourite front-end (constraints writing) or back-end (proving system) while reducing the overhead of further programming. One option could be using zkInterface, which allows for interoperability of these two and is another existing standards proposal (see the demo).
We threw out some initial ideas
- Transition functions: what if we defined a basic predicate that would prove privately that the state transitioned correctly, while enabling the user to define the state and some of the predicates within the transition.
4-Layer model: we can define several layers of abstraction, such as
- Application flow, which defines the highest-level API for the application, defines the underlying protocol and private consensus rules (fixed public predicates);
- Features definition, which allows the user to define the set of features needed for its specific application; including the interaction between the parties and the privacy needs (membership, authorize, etc…)
- Cryptographic gadgets, which defines what are the predicates needed to meet the needs of the features such as merkle trees, pedersen hashes, etc… (these are instantiated as gadgets that ensure secure implementation);
- Low-level constraints, which allow the user to define new gadgets from the most basic elements of types and fields, which are well specified, even within the constraint systems.
Please feel free to further the above ideas, add to the requirements and throw out more concepts and topics! We hope that this could eventually become a standards proposal.
[EDIT]: added PayToVK description under scripting languages, as per @Jon’s reply.