iden3/circom

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

MingyuHeTKS opened this issue · 3 comments

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.

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?

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]);
}
//...

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