zkApp Tooling: The Present and Future of Programmable Privacy

zkApp Tooling: The Present and Future of Programmable Privacy

Written by
Daniel Tao
Date published
April 12, 2023

Fog of war games. Currency mixers. ZK-rollups. Dark pools.People are realizing how powerful zero knowledge proofs are - and you too can use this power!I'll teach you everything you need to know about zkApp tooling so you too can harness this power for yourself.👇

image

1/ But first, why are Zero Knowledge Proofs (ZKPs) so powerful?

ZKPs are private by default, forcing developers to much more intentional about what user data they expose.

If you're still skeptical about ZKPs - check out this thread by @varunshenoy_! It'll change your mind.

@mentions

2/ As an example, and used ZKPs to shuffle a card on-chain without any trusted parties. ZKPs allowed players to submit proof they had shuffled correctly without revealing anything about the shuffle's result!

image

3/ Using these circuits to shuffle cards, it becomes possible to deploy an anonymous and decentralized version of any card game on-chain. This means truly anonymous poker, blackjack, etc, are possible to build!... I'm not saying anyone should do that. Please don't go to jail.

image

@mentions4/ So you've been convinced of the power of ZKPs and want to start building ASAP. But you might feel like a zero knowledge goof - where do you even get started?????Like any project, you'll need to start by choosing a tech stack for your zkApp.

@mentions5/ Outside of web3 stack choices (web framework, backend(?), underlying chain), you'll need:- a frontend domain specific language (DSL) or library- a backend proof system.These are constrained by where your prover and verifier are going to be deployed. Let's dig deeper!

image

@mentions

6/ At its most abstract, the goal of the frontend of a ZKP system is to allow developers to express knowledge about some private or public input.

@mentions7/ Developers use a higher-level DSL like 's Circom, , , or , or a library like or to encode these constraints. 's halo2 or 's plonky2 have you write arithmetic gates directly!

@mentions

8/ Like normal programming languages, these solutions tradeoff between lower-level control and abstraction. (See:

)

image
image

@mentions9/ halo2 and plonky2 don't even have frontend DSLs, so they have devs defining arithmetic gates directly.On the other end of the spectrum, Noir aims to resemble Rust as much as possible, abstracting away as much cryptography as possible.Circom is somewhere in the middle.

image
image

@mentions10/ Once devs have defined the constraints which make up a circuit in the language, they can "compile" the circuit. The exact process depends on your language and proof system, but you end up with two distinct but important bits of code: a prover and a verifier.

image

@mentions

11/ This is where the second tech stack choice - your backend proof system - matters. Here, the cryptographers come out to play.

(I suggest:

&

if you want to explore more.)

image
image
image

@mentions

12/ If you're interested in diving deeper into this process (but maybe not all the way to field theory) at all, I recommend another of 's threads on this exact topic!

@mentions

13/ But for this thread, we can black-box proof systems. All you need to understand is that they make tradeoffs between the following:

  • Proof size
  • Proof generation speed/cost
  • Verification speed
  • Setup (i.e. trusted setup, ex:

)

  • Expressiveness
image

@mentions14/ In practice, your proof generation speed doesn't matter as much, so the most important factor is the cost to verify proofs on your target chain.This is because of the gas costs and size limits of contracts. Sometimes generated verifier contracts are too big to even deploy!

image

@mentions15/ In cases where you're verifying off-chain, you should first select for tooling based on support for generating provers and verifiers in your desired target environment (i.e. browser/Node backend, Rust microservice, Go game client, etc), and then based on personal preference!

@mentions

16/ Once you have prover and verifier, you can call them from other code.

For example, you could build an anonymous voting app by calling the prover in the browser to generate a membership proof and verifying it in a node backend, like

!

image

@mentions

17/ Or, you can generate provers in Rust and verifiers in solidity, and call the provers in a optimized game client and the verifiers in on-chain game contracts like 's

client and

's contracts.

The possibilities are endless...

@mentions18/ ...but as mentioned before, the limits of environments like the browser (performance) or the EVM (gas costs and fixed max contract size), as well as the presence or lack of tooling support, complicate this ideal.

image

@mentions

19/ Also, sometimes language and proof systems combos are exclusive to specific chains.

Languages like and

are designed for

and

respectively, allowing for performance improvements via vertical integration.

image

@mentions20/ Additionally, a language's compiler pretty much always only supports one proof system!For instance, Noir's compiler barretenberg currently only supports Plonk. Circom is the rare exception, supporting Groth16, Plonk and experimentally, FFlonk.

image

@mentions

21/ This means you have less freedom to choose your tech than you'd like.

Maybe you want to use Plonky2 because of its recursion and performance characteristics, but you want to use a DSL because you don't want to directly write gates. Unfortunately, that tooling doesn't exist.

@mentions

22/ Other times, maybe you're completely satisfied with the frontend lang and proof system, but there is no implementation of a prover/verifier generator for your target environment.

You can imagine many such cases of missing tooling for every step of the dev process!

@mentions23/ To sum up, while ZKPs are powerful, there's a lot of problems with developing them.- Desirable environments (like the EVM) are hard to target- Needing a specific environment/proof system with specific performance characteristics severely limits your choice of tooling

@mentions

24/ But don't worry - these problems are well known and smart people are hacking on them!

Let's briefly talk about a few directions tackling these problems.

@mentions

25/ One interesting direction is optimizing EVM verifier codegen. For example, wrote a Groth16 verifier generator. Nothing is stopping people from writing codegen to produce verifiers in Huff for other proof systems as well.

image

@mentions

26/ Generated Huff verifiers are smaller than Solidity verifiers, and are 10-20% more gas efficient on each verify.

This means generating verifiers in Huff allows you to deploy more complex circuits with more constraints.

Also, the verification gas savings add up over time.

@mentions

27/ Another important direction is improving tooling for devs. For example, and other devs at Project Sophon have put out a plugin for Circom, and has put out a similar plugin for Noir.

image
image

@mentions

28/ Aside from build tooling, teams are even improving framework and library tooling! For example, aims to build a higher-level on-chain game engine on simil:ar to what 's

does for the EVM.

image
image

@mentions29/ Right now, the state of ZKP tooling is akin to web3 development 1 or 2 years ago, before projects like and .But even compared to 6 months ago, the developer experience has improved so much, and will continue to improve, lowering the barrier of entry!

@mentions30/ The last direction I want to tease is work being done in decoupling frontend DSLs and backend proof systems in ZKP compilers.This is a technical and nuanced topic which I hope to save for a future thread, but here's a project to give you a taste of what's to come.

image

@mentions

31/ The project is Nova Scotia by , which targets Circom to 's recursive proof system Nova.

Clearly frontend DSLs and backend proving systems need not be subject to developer lock-in the way they are now.

@mentions32/ ZKPs are clearly powerful, but there's also still a lot of work to be done building out the tooling to enable developers to easily build and deploy them.Hopefully, I've helped point you in the right direction so you can get started building ZKPs or even help build tooling!

@mentions

33/ Some interesting resources for learning more:

's

's

and

's

's

image
image
image
image
image

@mentions

34/ Want to chat about or hack on zkApp tooling? My DMs are open!

Or follow me here or at

- I'm currently hacking on libraries for Circom and Typescript with

which helps address tooling problems for JS and TS devs.

image

@mentions35/ Thanks to everyone who took a look at drafts of this thread., , , ,, , and .Y'all are the reason this thread has more grace than a dilapidated walrus.

@mentions36/ Down to read more research at the frontier from researchers?Check out more content from us here: twitter.com/i/lists/162053…