iden3 / circom

zkSnark circuit compiler
GNU General Public License v3.0
1.28k stars 244 forks source link

Allow `main` to have tagged inputs #203

Closed erhant closed 11 months ago

erhant commented 1 year ago

Circom does not allow main component to be instantiated with a template that has tagged inputs. If the template has a tagged input, you will get the following error:

Main component cannot have inputs with tag

I believe main input tags are checked at this line.

This becomes a problem when I would like to test my sub-templates (i.e. unit testing). To test witness computations and assertions, I don't know any way other than instantiating the main component with that sub-template. The aforementioned error prevents me from testing sub-templates with tagged inputs.

I do not know the reasoning behind this check, but perhaps it could be better for the compiler to ignore the tagged inputs if the respective template is that of a main component instead?

You can zkrepl the following circuit to see the error yourself:

pragma circom 2.1.0;

template Square () {
    signal input {mytag} in;
    signal output out <== in * in;
}

component main = Square();

/* INPUT = {
    "in": "5"
} */
alrubio commented 11 months ago

Hi, thanks for your comment. All tags should be checked as they express required properties on the signals, and hence the programmer has to explicitly impose such tags if wanted, even for the main component. In case you want to test templates with tags, you have to create an auxiliary wrapper template that adds the needed tags. For instance, in your example, the simplest option is the following:

pragma circom 2.1.0;

template Square () {
    signal input {mytag} in;
    signal output out <== in * in;
}

template Square_Tag () {
    signal input in;
    signal {mytag} in_aux <== in;
    // if it is a tag with value, replace the above line by the following three
    // signal {mytag} in_aux;
    // in_aux.mytag = 0; //or the needed value
    // in_aux <== in;
    signal output out <== Square () (in_aux);
}

component main = Square_Tag();

/* INPUT = {
    "in": "5"
} */