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

groth16 Prove panic due to incomplete marshalling of ProvingKey #141

Closed myrade closed 3 years ago

myrade commented 3 years ago

After writing a ProvingKey to a bytes.Buffer and reading it back, groth16.Prove panics when trying to access InfinityA and InfinityB because they aren't handled by the corresponding marshaling functions. The formats []bool and int aren't supported by the gnark-crypto marshaller either.

Here's a minimal example that reproduces the behavior:


import (
    "bytes"
    "testing"

    "github.com/consensys/gnark-crypto/ecc"
    "github.com/consensys/gnark/backend"
    "github.com/consensys/gnark/backend/groth16"
    "github.com/consensys/gnark/frontend"
)

type Circuit struct {
    X frontend.Variable `gnark:"x"`
    Y frontend.Variable `gnark:",public"`
}

func (circuit *Circuit) Define(curveID ecc.ID, cs *frontend.ConstraintSystem) error {
    x3 := cs.Mul(circuit.X, circuit.X, circuit.X)
    cs.AssertIsEqual(circuit.Y, cs.Add(x3, circuit.X, 5))
    return nil
}

func TestCubicEquationMarshalled(t *testing.T) {
    assert := groth16.NewAssert(t)

    var cubicCircuit Circuit

    r1cs, err := frontend.Compile(ecc.BN254, backend.GROTH16, &cubicCircuit)
    assert.NoError(err)

    {
        var witness Circuit
        witness.X.Assign(3)
        witness.Y.Assign(35)

        pk, _, err := groth16.Setup(r1cs)
        assert.NoError(err, "generating public data should not have failed")

        buf := new(bytes.Buffer)
        _, err = pk.WriteTo(buf)
        assert.NoError(err, "writing proving key to buffer should not have failed")

        pkCopy := groth16.NewProvingKey(ecc.BN254)
        _, err = pkCopy.ReadFrom(buf)
        assert.NoError(err, "reading proving key back from buffer should not have failed")

        _, err = groth16.Prove(r1cs, pkCopy, &witness, nil)
        assert.NoError(err, "proving with good witness should not have failed")
    }

}
gbotrel commented 3 years ago

Thanks for raising this issue, should be fixed with this commit

myrade commented 3 years ago

Wonderful, thanks, that was unbelievably fast. Working great.