iden3 / circom

zkSnark circuit compiler
GNU General Public License v3.0
1.25k stars 232 forks source link

The problem of circom compiler bottom layer algorithm #271

Open MJJ-Shuai opened 1 month ago

MJJ-Shuai commented 1 month ago
static inline void add_l1nl2n(PFrElement r, PFrElement a, PFrElement b)
{
    r->type = Fr_LONG;

    Fr_rawAdd(r->longVal, a->longVal, b->longVal);
}
void Fr_rawAdd(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB)
{
    uint64_t carry = mpn_add_n(pRawResult, pRawA, pRawB, Fr_N64);

    if(carry || mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
    {
        mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
    }
}

I noticed that circom, when dealing with the addition of two long and non-Montgomery-type data, only does one subtraction for the overflow result to try to get the result after modulo, but if the result is much larger than 2p, won't it appear that the result is not in the finite domain?