Compiling Gnark proover using Tinygo

Q: Is the zkEVM using Gnark as zk framework? Is it possible to compile the Gnark prover using Tinygo?

So far, as I understand for the zkEVM you need keccak and ecdsa verification (over secp256k1), but I’m not able to find these cryptographic primitives implemented on the Gnark repository. Is there some other repository am I missing?

I’m interested in this cause we are working on a Voting system currently based on Circom, but we are evaluating other zk frameworks and Gnark looks like a very good choice.


A: We have Keccak and ECDSA over secp255k1, but right now on develop branch only. We have also compiled very small parts of gnark into WASM using Tinygo, but it requires quite a lot of manual tweaking to avoid including Go runtime. And we need to do it to get very small binaries. Otherwise, if we include it the size of binaries is several (even ten) MBs. And the perf increase is also significant. For comparison, a subroutine was 2x faster than arkworks compiled to WASM.

WASM speed Announcing the Inaugural ZPrize Competition Results | ZPrize Blog
ECDSA gnark/std/signature/ecdsa at develop · ConsenSys/gnark · GitHub
Keccak gnark/std/permutation/keccakf at develop · ConsenSys/gnark · GitHub

But we aren’t currently aiming to have full compatibility with Tinygo. It’s quite an overhead from the development point of view. So right now even if compiling works, the resulting prover will be a factor slower than with Tinygo-specific optimisations


Q: Regarding the wasm compiled binary using Go (not tinygo), where can I find the instructions to compile it? I suppose you are stripping debug symbols and so on in order to reduce the size.


A: Here 2022-entries/Makefile at main · z-prize/2022-entries · GitHub. You can see we are using leaking gc here but it actually doesn’t leak memory as we are using static allocation for variables. And this is a very small subset of what is needed compared to a full prover for ECDSA, but could theoretically be done similarly.
2022-entries/ at main · z-prize/2022-entries · GitHub


Q: That makefile you sent is interesting, but it uses tinygo and modified libraries, which I believe are not gonna be maintained.

I’m asking for the way you use to compile WASM from Go (if any). If I do the standard way, the binary size is 13MB, which is too large.

I can see here a couple of wasm binaries which are pretty small (about 1M)
Are these compiled with tinygo using something similar to the Makefile you shared or it is compiled using Go, but tuning the parameters?


A: Right now the options are using Go compiler or using Tinygo. Go compiler compiles imo directly to WASM without external IR (IR being intermediate representation, something use to represent parsed source code). The playground source code is here We are using Go directly.

However, the playground actually doesn’t embed full prover. The WASM program only solves the circuit (computes the full witness), but omits actual proving as it was really slow for demonstration purposes.


Hey, the gnark playground repository is private.

Good news is that Gnark prover and verifier compile out-of-the-box on the last tinygo (currently on dev branch). See the comment on this issue: github[.]com/ConsenSys/gnark/issues/74


Hello, firstly, thank you for this beautiful library!

I have two questions:

Firstly, I couldn’t figure out how to use mod operation with gnark between 2 frontend.Variable or converting circuit input to big.Int will also solve my problem. In circom:

Var xer = balance % r_prime;
What is the equivalent of this in the gnark circuit?

Secondly, I have written and compiled my circuit in circom, now I have my r1cs and witness. Is it possible to use gnark only as a prover and also can I generate my witness from my r1cs (or sym etc.) of circom circuit, using gnark?

Thank you!!

1 Like

Hi please check Custom Modulus & External R1CS · ConsenSys/gnark · Discussion #595 · GitHub it is all covered there


No it is not. That discussion writer is also me.

1 Like

Please check the last reply on the github discussion