We know by now that we can give a “succinct” proof of having performed a given computation. Typically though, that is not enough.
We’ll want to build our proving system in a parametrized way, so that we can prove that we performed a given computation, and that it output a certain value. As usual, an example can help:
the prover knows a certain “leaf” x, only known to herself, and she wants to prove that it belongs to a merkle tree that has a merkle root y (if you don’t know what a merkle tree is, well you should! It’s a fundamental tool, massively used in cryptocurrencies, check that out on wikipedia!). In our case, we don’t want to write a different circuit for each y, we’d like our zk-Snark to be generic, i.e. able to build a proof “bound” to some specific public data: the merkle root y.
This parametrization can be obtained by calculating some of the hidings connected to the public input variables only when running the verifier, and then check as usual that all the equations hold. At some point I may write a post about the actual implementation of the Pinocchio protocol, and we can look at this more closely; in any case what is important to understand now is that the circuits can be “generic”, i.e. the circuit can (and usually does) have one or more parameters (“public input”) that are not only known by the prover, but that have to be revealed and used in the verification process to verify the proof. This is very powerful in particular when the circuit implements a one-way function y=f(x): if y is known to the verifier, the prover can prove that she knows a secret x so that y=f(x), without revealing x.