This might be a newbie question:
From the doc, it says that signals are part of the circuit while variables are similar to variables in other programming language. But for verifiable computation, I'd assume that the computations done on variables would also be verified and therefore be part of the circuit. In this sense, can I see signals as the interface of the template while the variables as the internal states? If so, what are the differences between internal signals and variables?
Or when should one use variable and when should one use signal?
I have the same questions for functions v.s. templates. Why do we need both instead of one? When should one use function and when should one use template?
My fundamental confusion is that I thought circom would produce a circuit encapsulating everything defined in the circom files. But the language defined two types of constructs (variable/function vs signal/template) with one being more restrictive than the other, and it cites "being part of the circuit" as the reason for signal/template to be more restrictive, making it sounds like variables/functions are not part of the circuit.
Thanks!
I think I can answer my own question now. (with help from this post https://dev.to/spalladino/a-beginners-intro-to-coding-zero-knowledge-proofs-c56#:~:text=For%20instance%2C%20Circom%20only%20allows,be%20the%20set%20of%20constraints.)
Apparently I thought that the entirety of the program will be verified, but in reality circom let the programmer decide *which part of the program will be verified. The circom file has 1. the execution portion "<--" and 2. the verification portion "===". Execution is not automatically verified unless coupled with verification specifications.
This allows the programmer to write complex executions that are not verified and put verification at the interface to verify the relation between the inputs and the outputs.
I'm still trying to wrap my head around why this is a good idea. It opens up the possibility of under-constrained computation and makes the computation less trustworthy, it is also harder to write because now I need to think hard on how to write the constraints. The benefit of this is that the program is more expressive.
Would love to know how this design choice affect the technology's effectiveness in large projects. Is it easy to avoid under-constrained computation in large project, what's the dev experience in writing two programs (execution + verification) at once for large projects, etc.