Consensys / gnark

gnark is a fast zk-SNARK library that offers a high-level API to design circuits. The library is open source and developed under the Apache 2.0 license
https://hackmd.io/@gnark
Apache License 2.0
1.41k stars 361 forks source link

`api.AssertIsEqual` creates one redundant R1CS constraint in many cases #674

Open aybehrouz opened 1 year ago

aybehrouz commented 1 year ago

The following example shows that a redundant R1CS constraint is generated for a simple equation of the form p(x) * q(x) == 0, where p and q are linear:

https://play.gnark.io/?id=3qia1dcndg

This type of equations are very common.

Currently this issue causes selector.Mux and selector.Map to generate 3n+1 constraints instead of 2n+1.

ivokub commented 1 year ago

Yes, there are some cases where this happens. See also #242 and #243.

We could try adding some specialised methods into API, but it is kind of suboptimal. Better option would be to have some post-processing to merge and remove redundant constraints, but apparently it isn't trivial :/

aybehrouz commented 1 year ago

Thank you so much for the quick reply.

I just had another question. How can I print constraints like the playground? What function should I use?

ivokub commented 1 year ago

Like this:

ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit{})
if err != nil {
    panic(err)
}
ccst, ok := ccs.(constraint.R1CS)
if !ok {
    panic("not R1CS")
}
constraints, resolver := ccst.GetConstraints()
for i := 0; i < 100; i++ {
    fmt.Println("constraint", i, constraints[i].String(resolver))
}
gbotrel commented 1 year ago

Also: https://github.com/ConsenSys/gnark/issues/555

syntax is a bit changed on develop see this Example: https://github.com/ConsenSys/gnark/blob/c02da5f61944d13c557d2b390ca56d5a26c597a1/constraint/r1cs_test.go#L52

aybehrouz commented 1 year ago

Thanks a lot.