github.com/consensys/gnark@v0.11.0/internal/generator/backend/template/zkpschemes/groth16/tests/groth16.commitment.go.tmpl (about) 1 import ( 2 "testing" 3 "fmt" 4 5 "github.com/consensys/gnark-crypto/ecc" 6 "github.com/consensys/gnark/backend/groth16" 7 "github.com/consensys/gnark/backend/witness" 8 "github.com/consensys/gnark/constraint" 9 "github.com/consensys/gnark/frontend" 10 "github.com/consensys/gnark/frontend/cs/r1cs" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 type singleSecretCommittedCircuit struct { 15 One frontend.Variable 16 } 17 18 func (c *singleSecretCommittedCircuit) Define(api frontend.API) error { 19 api.AssertIsEqual(c.One, 1) 20 commitCompiler, ok := api.Compiler().(frontend.Committer) 21 if !ok { 22 return fmt.Errorf("compiler does not commit") 23 } 24 commit, err := commitCompiler.Commit(c.One) 25 if err != nil { 26 return err 27 } 28 api.AssertIsDifferent(commit, 0) 29 return nil 30 } 31 32 func setup(t *testing.T, circuit frontend.Circuit) (constraint.ConstraintSystem, groth16.ProvingKey, groth16.VerifyingKey) { 33 _r1cs, err := frontend.Compile(ecc.{{.CurveID}}.ScalarField(), r1cs.NewBuilder, circuit) 34 assert.NoError(t, err) 35 36 pk, vk, err := groth16.Setup(_r1cs) 37 assert.NoError(t, err) 38 39 return _r1cs, pk, vk 40 } 41 42 func prove(t *testing.T, assignment frontend.Circuit, cs constraint.ConstraintSystem, pk groth16.ProvingKey) (witness.Witness, groth16.Proof) { 43 _witness, err := frontend.NewWitness(assignment, ecc.{{.CurveID}}.ScalarField()) 44 assert.NoError(t, err) 45 46 proof, err := groth16.Prove(cs, pk, _witness) 47 assert.NoError(t, err) 48 49 public, err := _witness.Public() 50 assert.NoError(t, err) 51 return public, proof 52 } 53 54 func test(t *testing.T, circuit frontend.Circuit, assignment frontend.Circuit) { 55 56 _r1cs, pk, vk := setup(t, circuit) 57 58 public, proof := prove(t, assignment, _r1cs, pk) 59 60 assert.NoError(t, groth16.Verify(proof, vk, public)) 61 } 62 63 func TestSingleSecretCommitted(t *testing.T) { 64 circuit := singleSecretCommittedCircuit{} 65 assignment := singleSecretCommittedCircuit{One: 1} 66 test(t, &circuit, &assignment) 67 } 68 69 type noCommitmentCircuit struct { // to see if unadulterated groth16 is still correct 70 One frontend.Variable 71 } 72 73 func (c *noCommitmentCircuit) Define(api frontend.API) error { 74 api.AssertIsEqual(c.One, 1) 75 return nil 76 } 77 78 func TestNoCommitmentCircuit(t *testing.T) { 79 circuit := noCommitmentCircuit{} 80 assignment := noCommitmentCircuit{One: 1} 81 82 test(t, &circuit, &assignment) 83 } 84 85 // Just to see if the A,B,C values are computed correctly 86 type singleSecretFauxCommitmentCircuit struct { 87 One frontend.Variable `gnark:",public"` 88 Commitment frontend.Variable `gnark:",public"` 89 } 90 91 func (c *singleSecretFauxCommitmentCircuit) Define(api frontend.API) error { 92 api.AssertIsEqual(c.One, 1) 93 api.AssertIsDifferent(c.Commitment, 0) 94 return nil 95 } 96 97 func TestSingleSecretFauxCommitmentCircuit(t *testing.T) { 98 test(t, &singleSecretFauxCommitmentCircuit{}, &singleSecretFauxCommitmentCircuit{ 99 One: 1, 100 Commitment: 2, 101 }) 102 } 103 104 type oneSecretOnePublicCommittedCircuit struct { 105 One frontend.Variable 106 Two frontend.Variable `gnark:",public"` 107 } 108 109 func (c *oneSecretOnePublicCommittedCircuit) Define(api frontend.API) error { 110 commitCompiler, ok := api.Compiler().(frontend.Committer) 111 if !ok { 112 return fmt.Errorf("compiler does not commit") 113 } 114 commit, err := commitCompiler.Commit(c.One, c.Two) 115 if err != nil { 116 return err 117 } 118 119 // constrain vars 120 api.AssertIsDifferent(commit, 0) 121 api.AssertIsEqual(c.One, 1) 122 api.AssertIsEqual(c.Two, 2) 123 124 return nil 125 } 126 127 func TestOneSecretOnePublicCommitted(t *testing.T) { 128 test(t, &oneSecretOnePublicCommittedCircuit{}, &oneSecretOnePublicCommittedCircuit{ 129 One: 1, 130 Two: 2, 131 }) 132 } 133 134 type twoSecretCommitmentsCircuit struct { 135 One frontend.Variable 136 Two frontend.Variable 137 } 138 139 func (c *twoSecretCommitmentsCircuit) Define(api frontend.API) error { 140 commitCompiler, ok := api.Compiler().(frontend.Committer) 141 if !ok { 142 return fmt.Errorf("compiler does not commit") 143 } 144 commit1, err := commitCompiler.Commit(c.One) 145 if err != nil { 146 return err 147 } 148 commit2, err := commitCompiler.Commit(c.Two) 149 if err != nil { 150 return err 151 } 152 // constrain vars 153 api.AssertIsDifferent(commit1, 0) 154 api.AssertIsDifferent(commit2, 0) 155 return nil 156 } 157 158 func TestTwoSecretCommitments(t *testing.T) { 159 test(t, &twoSecretCommitmentsCircuit{}, &twoSecretCommitmentsCircuit{ 160 One: 1, 161 Two: 2, 162 }) 163 }