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

Add an example that has a private input #157

Closed fosgate29 closed 2 years ago

fosgate29 commented 2 years ago

Cubic example is great and easy to follow. But lib should have an example that uses private secret visibility so it is easier to learn and understand the use of public and private

gbotrel commented 2 years ago

Hi @fosgate29 --> fair point, but doesn't examples/mimc does that? :

// Circuit defines a pre-image knowledge proof
// mimc(secret preImage) = public hash
type Circuit struct {
    // struct tag on a variable is optional
    // default uses variable name and secret visibility.
    PreImage frontend.Variable
    Hash     frontend.Variable `gnark:",public"`
}

If you have other ideas on how to improve "getting started" example or documentation, feel free to create an issue / start a discussion with us.

fosgate29 commented 2 years ago

Hi. Thanks @gbotrel. When I first started using Gnark, I went to the examples. It worked well. Then I tried and searched for the vk and proof and spent some thime before finding examples (I found in the documentation and it is clear there, but it isn't inside the examples). And I found some old examples using "private" and now it is secret modifier and it confused me also.

I had this kind of example in mind now:

type Circuit struct {
    PreImage frontend.Variable `gnark:",public"`
    Hash     frontend.Variable `gnark:",secret"`
}

and test code would be like this:

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

    pk, vk, err := groth16.Setup(r1cs)
    assert.NoError(err)

    {
        var witness Circuit

                witness.Hash.Assign("16130099170765464552823636852555369511329944820189892919423002775646948828469")
        witness.PreImage.Assign(35)

        // Generate Proof
        proof, err := groth16.Prove(r1cs, pk, &witness)

                //show how to use proof with correct input
                var witness2 Circuit
                witness2.PreImage.Assign(35)
        err = groth16.Verify(proof, vk, &witness2)
        assert.NoError(err)

        //example with a wrong input should fail
        var witness3 Circuit
                witness3.PreImage.Assign(42)
        err = groth16.Verify(proof, vk, &witness3)
        assert.Error(err)
    }
fosgate29 commented 2 years ago

And one more suggestion. I am also a solidity dev and I was looking forward to getting the examples results and verifying them in a smart contract. Maybe examples should have serialization and a demo of a working smart contract deployed on a testnet. I type go test and get a printed result and a smart contract address that I can easily send data (a,b and c) as input , send a tx and see it live on testnet. I could use Remix and run this demo. Maybe it is too much, but it was the steps I had some issues when I developed my zk project using Gnark.

gbotrel commented 2 years ago

play.gnark.io partially answers this ticket. As it evolves, we will try to add Ethereum specific functionalities to it.