# Why are zk-SNARKs possible, in layman's terms

zk-SNARK: Zero-Knowledge Succinct Non-interactive Argument of Knowledge

From the Ethereum blog:

One natural use case for the technology is in identity systems. For example, suppose that you want to prove to a system that you are (i) a citizen of a given country, and (ii) over 19 years old. Suppose that your government is technologically progressive, and issues cryptographically signed digital passports, which include a person’s name and date of birth as well as a private and public key. You would construct a function which takes a digital passport and a signature signed by the private key in the passport as input, and outputs 1 if both (i) the date of birth is before 1996, (ii) the passport was signed with the government’s public key, and (iii) the signature is correct, and outputs 0 otherwise. You would then make a zero-knowledge proof showing that you have an input that, when passed through this function, returns 1, and sign the proof with another private key that you want to use for your future interactions with this service. The service would verify the proof, and if the proof is correct it would accept messages signed with your private key as valid.

I bolded the parts which seem impossible to me intuitively. I found some research papers with very technical explanations, which I don't understand. Could someone explain why this is possible, in layman's terms? Intuitively it seems like there would be plenty of ways for the client to alter the program code in order to produce output which could be used to fake their identity.

Some documentation and code

Take it back a step, and consider a more simple zero knowledge proof.

A digital signature on an email can be thought of as a very specific, narrow example, of a zero knowledge proof. I (the 'prover') provide a message M, and a digital signature over M (hash of M, encrypted with my private key) to you.

You (the verifier) can hash M for yourself, decrypt my provided signature with my public key, and compare, and if they match, you've confirmed my signature. What you just did is verify the arithmetic "proof" I provided of the following NP statements:

I know the private key Q which corresponds with public key P I used Q to sign message M

You are now convinced that I know Q, without me having to reveal Q to you. All I had to do was give you proof I know Q, in the form of inputs (message M and its signature) and the function, which when fed those inputs, compares correctly.

That's a zero knowledge proof.

Conceptually, now replace "I know the private key Q" with "The government private key has signed a statement saying I am of legal age". The same logic applies.

With that idea of the "zk" part in mind, the "magic" of the "snark" part is that this can be generalized to any computable NP statement expressed logically as an arithmetic circuit.

In neither of these cases can the "client alter the program code." I find the digital signature analogy useful to keep in mind when trying to understand these.

• I thought that ZK means I don't have to reveal M to proof I know M. But the counterparty has to have M in your example. So what is ZK there? Jan 8 '17 at 7:18
• @Roland Kofler - The message M is an example to illustrate and clarify OP's question. In this analogy, "the ZK" is my private key "Q". I never reveal Q to you, but you are convinced I must know Q, for only with it could I produce the set of all three: M (the message), P (the public key), and the signed hash. All of which you can feed into a known function to convince yourself I must know Q, even though I've never shown you Q. Jan 8 '17 at 9:11
• I don't think the signature example is a zero-knowledge proof of knowing the private key. Once the verifier V has the signature he has learned more than just the fact that the prover knows the private key. Specifically, V can convince another verifier V' too that the prover knows the private key by just giving V' the signature. As I understand ZKPs, it should not be possible to take a proof you received to convince another person of that statement too. Feb 24 '17 at 16:55
• That is not true, zero-knowledge does not necessarily guarantees non-transferability, it's a different property. For example, publicly-verifiable non-interactive zero-knowledge proofs in the common reference string model are always transferable - but they can often be made non-transferable via appropriate techniques. Still, the protocol in the answer is not zero-knowledge, but for another reason: there is no way to simulate correct signing on arbitrary messages without the secret-key in general, hence zk cannot be proven. Jan 26 '18 at 9:10
• As Alin and Geoffroy have stated this answer does not describe a Zero-Knowledge proof but just a proof of knowledge. See en.wikipedia.org/wiki/Zero-knowledge_proof
– A1m
Mar 2 '18 at 18:36

When you have eliminated the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

If I find you in my dorm room and the door and windows are intact, I can only conclude that you somehow learned the entry code, because I do not know of any other way by which you could have entered my room without breaking the door or windows.

A ZK-SNARK for a function $f$ is similar: if you present a proof for the result $1$ which can pass the verification procedure, it necessarily means that you must know an $x$ such that $f(x) = 1$. This is because we do not know of any (efficient) way to generate such a proof if you do not know such a value $x$. In fact, we have a proof that being able to do this would imply being able to solve certain mathematical problems which are believed to be hard (you can think of factoring integers, although the problems used to construct SNARKs are more complicated). So when you say

Intuitively it seems like there would be plenty of ways for the client to alter the program code in order to produce output which could be used to fake their identity.

... there may or may not be, but we do not know of any and we consider it very unlikely (i.e., impossible, for all practical purposes).

Amendig the previous answer by fkraiem, let me focus on an example returning $1$.

Schnorr verification equation could be rewritten: $$g^{r} h^{-c} a^{-1} = 1$$ for a group generator $g$, Prover response $r$, Verifier challenge $c$, initial message of Prover $a$ and public key $h$ such that $h = g^x$ for some private key $x$. With this protocol, Prover calculates $r = x c + b$ and $a = g^b$ so that Verifier cant learn $x$ from data received.

Point is, without "knowing" the secret $x$, Prover can produce satisfying response with only negligible probability, defined by cardinality of challenge set, which could be the group order.

In this example, $1$ is group identity.

I wanted to take a stab at laymen's terms for this...

zk-SNARK protocols provide proof that a specified algorithm (or circuit) was run against some data. I want to prove I know public w and private x such that f(x, w) = 1, but I don't want to give you x. I input x and w into f and f spits out 1, while the zk-SNARK part of the protocol will generate a signature that says I just did all that with that public input and that output, so I must have a valid private input.

Another practical application I've seen described is that you want to know the mayoral candidate's DNA is not among the database of DNA found at crime scenes. The candidate naturally does not want to give everyone his DNA, so how can we know he's not in that database? You could design a zk-SNARK protocol where there is an algorithm that checks the input DNA against the database and outputs 1 if match and 0 if no match. You let the cops run that algorithm in private and then they come forward and present a zk-SNARK proof that shows they ran the algorithm and got output 0--this would reliably prove that the cops checked the database for his DNA and the output was no match.

So I think of it is as proof that I went through the circuit.

I found this very helpful: https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b

The polynomial generated by going through the circuit is then used to create a public and private key pair. When you run your input through the circuit the zk-SNARK protocol will give you a proof $\pi$ that has encrypted your private input and public input with the private key for that function. This is your proof that you went through the function with those inputs.