# ZoKrates static setup issue All the Groth16 circuits compiled with ZoKrates result in partially the same `verification.key` and `proving.key` when `setup` command is run. We try to explain here why this problem occurs for `verification.key`. The same goes for `proving.key` but it's easier for the `verification.key` file because it is human-readable. ## Groth16: Verification equation $$ e(A,B)=VK_{\alpha,\beta}\cdot e(VK_{\gamma_{abc}},VK_{\gamma})\cdot e(C,VK_{\delta}) $$ where $\pi=(A,B,C)$ is a proof and $VK=(VK_{\alpha,\beta},VK_{\gamma_{abc}},VK_{\gamma},VK_{\delta})$ a verification key. $VK_{\alpha,\beta}=e(VK_{\alpha},VK_{\beta}), VK_{\gamma}$ and $VK_{\delta}$ are independant from the public inputs $\phi_i$ while $VK_{\gamma_{abc}}=VK_0+\sum_{i=0}^m\phi_i\cdot VK_i$ In ZoKrates, a `verification.key` looks like ``` { "alpha": [ "0x1936c240636390dc823e3a728e94b208eb53c6756d81da57ec3425e05d43ac10", "0x2d70ff78e8216bf29d58923a686d9738278b8ce2fd822e197c85b09286d15566" ], "beta": [ [ "0x2b4daf047abe2e7f0b311118c1b963b63695dc0d769cea78849604434de055bf", "0x29c13ecb6f33dbc4b3b8a02e2e255511ce4c26a8a2f299efcc94caf2de4fce00" ], [ "0x1da9020008df7f549751f8a251af3b2dc4a2ad3e0870de54acaedd9fc1b47e17", "0x25ea0d7e2b29de431b86a943db30dbf4d98f68df9ca8a9628d14d1591e817d90" ] ], "gamma": [ [ "0x011016e22ae045444f50fb80f246ec486c7e02af09132cd38c4fcf484983e4f2", "0x00e83c788c2878d1d5eba3ed49b0d81e4c0487dedc3e4d1c2baab5833785b62f" ], [ "0x05eb89e741ed5b5d611cebf92d1ed02cd6f3311089f0d400df7d9ced5a48fd41", "0x132a90a3b0d369ccd66e2a5ba04a935e44d8ad5dca93a76bba592a578130a911" ] ], "delta": [ [ "0x065f6a3323a2abffd621fc263f348eb914904b68d5897729ae34a6b9d33f0852", "0x0c3b60f59d3bd50328a04c0ff6d979199685d0526f89f6ac29d6174ce24707a2" ], [ "0x26e7ebce2b44efef6b6315938e33f0a8ecc82dbad635c9efa681ed85bbb59982", "0x12e0f3721230a0f38f6c9913048d5230fd2615ef3ff7f6ee4b20dfe0bdea1a86" ] ], "gamma_abc": [ [ "0x0a73f507c2f38b0bb5214020f9fc93a931daa209515bbe6865f8a6f1a8926d89", "0x1321dab017eec8c93f1acb8d8112574000231da226ca3b6afe9f3b0a30c59858" ], [ "0x0f52794466b3d949009601462ddbbc45fd6f7a7c4928ac3f669f6907cc8370e1", "0x06877a62f65bcb38ad25d0ba9f647d040e239e0f0d270905027064e5fae31709" ], [ "0x1ae58f3084a03b5dede7b245c9dac41c6d5f91f9bb0ae4b051c0d73277941242", "0x24b45e3af32c84130edbe93f68c5d8768e90595cad27143c466881a7f0cb158b" ] ] } ``` where one can match \begin{align} VK_{\alpha} &\rightarrow \,\,\,"alpha"\\ VK_{\beta} &\rightarrow \,\,\,"beta"\\ VK_{\gamma} &\rightarrow \,\,\,"gamma"\\ VK_{\delta} &\rightarrow \,\,\,"delta"\\ VK_{\gamma_{abc}} &\rightarrow \,\,\,"gamma\_abc" \end{align} For all circuits it seems that "$alpha$", "$beta$", "$gamma$" and "$delta$" are the same while only "$gamma\_abc$" is different. ## Intuitive explanation **Note: this is an imprecise and incomplete explanation of Groth16 but sufficient for this write-up.** The goal is to verify a QAP equation of the form $$A(x)\cdot B(x)=C(x)+H(x)\cdot Z(x)$$ at some random point $\tau$ (*Schwartz-Zippel lemma*), where $A, B, C$ come from the R1CS circuit and $Z$ is the minimal polynomial $Z(x)=\sum_i(x-s_i)$ (independant from the R1CS circuit but related to its size). After commiting these polynomials to random points on an elliptic curve $$e.g.\,\, A(\tau)\mapsto A(\tau)\cdot G$$one can verify the QAP in the exponents via pairings $$e(A(\tau)\cdot G,B(\tau)\cdot G)=e(C(\tau)\cdot G,G)\cdot e(H(\tau)\cdot G, Z(\tau)\cdot G)$$ which boils down to $$T^{A(\tau)\cdot B(\tau)}=T^{C(\tau)+H(\tau)\cdot Z(\tau)}$$ for some constant $T$. Additional mandatory steps in Groth16 are ommitted, but one can already spot that \begin{align} \pi &\rightsquigarrow (A(\tau)\cdot G, B(\tau)\cdot G, C(\tau)\cdot G)\\ VK_{\gamma_{abc}} &\rightsquigarrow H(\tau)\cdot G\\\\ VK_{\delta} &\rightsquigarrow G\\ VK_{\gamma} &\rightsquigarrow Z(\tau)\cdot G\\ VK_{\alpha}\\ VK_{\beta} \end{align} Note that $VK_{\alpha}, VK_{\beta}, VK_{\delta}$ and $VK_{\gamma}$ are independent from the public inputs. Thus, they are only related to the randomness of the setup. A closer look at ZoKrates [source code](https://github.com/Zokrates/ZoKrates/blob/b0a0dd265fb59053eb3396cd6f940844b1c7b692/zokrates_core/src/proof_system/bellman/mod.rs#L195) shows that the randomness in the setup comes from a ChaCha-based RNG seeded with a static key (`let rng = &mut ChaChaRng::new_unseeded();`). This RNG is used then to generate the setup in `Bellman` library. This was raised in this this [github issue](https://github.com/Zokrates/ZoKrates/issues/632) and solved in this [PR](https://github.com/Zokrates/ZoKrates/pull/738). Note that this problem doesn't occur for GM17 and PGHR13 proving schemes because ZoKrates uses `libsnark` for these systems.