iden3 / circom

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

Error Occurring with Circom Compiler When Generating C++ WTNS Generator #209

Closed MingyuHeTKS closed 11 months ago

MingyuHeTKS commented 1 year ago

Error Occurring with Circom Compiler When Generating C++ WTNS Generator

Problem Description

There appears to be an issue with the compiler's handling of the following:

// ...
bits[(counter + j) \ BitsChunk()][BitsChunk() - 1 - ((counter + j) % BitsChunk())] <== n2B[i].out[bits_args[i] - j - 1];
// ...

When generating a WTNS file using the C++ WTNS generator, the subsequent proof fails verification. Throughout the entire process from creating the WTNS file to generating the proof, no error messages were displayed.

It has been confirmed that the correct zkey file was used. Moreover, WTNS files generated using wasm pass the verification successfully.

The issue seems to arise specifically when the circuit size is sufficiently large.

The faulty WTNS files contain a significant number of zeros.

Preliminary Analysis for Reference

Occasionally in the generated C++ code, both (counter + j) \ BitsChunk() and BitsChunk() - 1 - ((counter + j) % BitsChunk()) are stored in the same C++ variable. This seems to result in the generation of invalid WTNS files.

clararod9 commented 12 months ago

Hi, thanks for reporting and for your analysis, it is really helpful :-) Can you provide us with the full circom circuit so we can recreate the bug?

MingyuHeTKS commented 11 months ago

I wrote a new circuit to recreate the bug. Please check the //!

circuit.circom

pragma circom 2.1.6;

template Test(arg_count, bits_args, bits_chunk, max_chunk_per_req){
    signal bits[max_chunk_per_req][bits_chunk];
    var counter = 0;
    for(var i = 0; i < arg_count; i++){
        for(var j = 0; j < bits_args[i]; j++)
            bits[(counter + j) \ bits_chunk][(counter + j) % bits_chunk] <== 0;
        counter = counter + bits_args[i];
    }
}

component main = Test(8, [8, 32, 16, 40, 40, 40, 32, 32], 96, 9);

circuit.cpp

//... line 172
Fr_add(&expaux[1],&lvar[11],&lvar[13]); // line circom 8
Fr_idiv(&expaux[0],&expaux[1],&circuitConstants[4]); // line circom 8
Fr_add(&expaux[1],&lvar[11],&lvar[13]); // line circom 8
Fr_mod(&expaux[0],&expaux[1],&circuitConstants[4]); // line circom 8 //! (&expaux[0]) -> (&expaux[3])?
{
    PFrElement aux_dest = &signalValues[mySignalStart + (((96 * Fr_toInt(&expaux[0])) + (1 * Fr_toInt(&expaux[0]))) + 0)]; //! (the 2nd &expaux[0]) -> (&expaux[3])?
    // load src
    // end load src
    Fr_copy(aux_dest,&circuitConstants[6]);
}
//...
clararod9 commented 11 months ago

Thanks! We have solved this issue in the last commit, let us know if the current solution is working for you. Thank you for reporting this bug