Skip to content

Commit

Permalink
Merge pull request #1068 from Consensys/fix/recorded-scs
Browse files Browse the repository at this point in the history
fix: scs add/mul when recorded constraint is 0
  • Loading branch information
yelhousni authored Mar 5, 2024
2 parents 7cfcd5a + 833fd73 commit 22d2c33
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
8 changes: 8 additions & 0 deletions frontend/cs/scs/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ func (builder *builder) Mul(i1, i2 frontend.Variable, in ...frontend.Variable) f
if len(vars) == 0 {
return builder.cs.ToBigInt(k)
}
if k.IsZero() {
return 0
}
for i := range vars {
if vars[i].Coeff.IsZero() {
return 0
}
}
l := builder.mulConstant(vars[0], k)

return builder.splitProd(l, vars[1:])
Expand Down
68 changes: 63 additions & 5 deletions frontend/cs/scs/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,6 @@ func (c *IssueDiv0Circuit) Define(api frontend.API) error {
func TestExistDiv0(t *testing.T) {
assert := test.NewAssert(t)
ccs, err := frontend.Compile(ecc.BN254.ScalarField(), scs.NewBuilder, &IssueDiv0Circuit{})
if err != nil {
t.Fatal(err)
}
assert.NoError(err)
w, err := frontend.NewWitness(&IssueDiv0Circuit{
A1: 11, B1: 21,
Expand All @@ -150,9 +147,70 @@ func TestExistDiv0(t *testing.T) {
Res7: 0, Res8: 55,
}, ecc.BN254.ScalarField())
assert.NoError(err)
solution, err := ccs.Solve(w)
_, err = ccs.Solve(w)
assert.NoError(err)
_ = solution
}

type IssueDiv0Circuit2 struct {
A1, B1 frontend.Variable

Res1, Res2 frontend.Variable
}

func (c *IssueDiv0Circuit2) Define(api frontend.API) error {
// case 1
b1 := api.Mul(0, c.A1)
b2 := api.Mul(4, c.B1)
t1 := api.Mul(b1, b2)

b3 := api.Mul(2, c.A1)
b4 := api.Mul(5, c.B1)
t2 := api.Mul(b3, b4)

// test solver
api.AssertIsEqual(t1, c.Res1)
api.AssertIsEqual(t2, c.Res2)
return nil
}

func TestExistDiv02(t *testing.T) {
assert := test.NewAssert(t)
ccs, err := frontend.Compile(ecc.BN254.ScalarField(), scs.NewBuilder, &IssueDiv0Circuit2{})
assert.NoError(err)
w, err := frontend.NewWitness(&IssueDiv0Circuit2{
A1: 11, B1: 21,
Res1: 0, Res2: 2310,
}, ecc.BN254.ScalarField())
assert.NoError(err)
_, err = ccs.Solve(w)
assert.NoError(err)
}

type TestZeroMulNoConstraintCircuit struct {
A, B frontend.Variable
}

func (c *TestZeroMulNoConstraintCircuit) Define(api frontend.API) error {
// case 1
t1 := api.Mul(0, c.A)
t2 := api.Mul(t1, c.B)

t3 := api.Sub(c.A, c.A)
t4 := api.Mul(3, t3)

// test solver
api.AssertIsEqual(t2, 0)
api.AssertIsEqual(t4, 0)
return nil
}

func TestZeroMulNoConstraint(t *testing.T) {
assert := test.NewAssert(t)
ccs, err := frontend.Compile(ecc.BN254.ScalarField(), scs.NewBuilder, &TestZeroMulNoConstraintCircuit{})
assert.NoError(err)
if ccs.GetNbConstraints() != 0 {
t.Fatal("expected 0 constraints")
}
}

type mulAccFastTrackCircuit struct {
Expand Down

0 comments on commit 22d2c33

Please sign in to comment.