github.com/consensys/gnark@v0.11.0/internal/generator/backend/template/zkpschemes/groth16/mpcsetup/setup_test.go.tmpl (about) 1 import ( 2 "testing" 3 4 {{- template "import_fr" . }} 5 {{- template "import_curve" . }} 6 {{- template "import_backend_cs" . }} 7 8 "github.com/consensys/gnark/backend/groth16" 9 "github.com/consensys/gnark/frontend" 10 "github.com/consensys/gnark/frontend/cs/r1cs" 11 "github.com/consensys/gnark/std/hash/mimc" 12 "github.com/stretchr/testify/require" 13 14 native_mimc "github.com/consensys/gnark-crypto/ecc/{{toLower .Curve}}/fr/mimc" 15 ) 16 17 func TestSetupCircuit(t *testing.T) { 18 {{- if ne (toLower .Curve) "bn254" }} 19 if testing.Short() { 20 t.Skip() 21 } 22 {{- end}} 23 const ( 24 nContributionsPhase1 = 3 25 nContributionsPhase2 = 3 26 power = 9 27 ) 28 29 assert := require.New(t) 30 31 srs1 := InitPhase1(power) 32 33 // Make and verify contributions for phase1 34 for i := 1; i < nContributionsPhase1; i++ { 35 // we clone test purposes; but in practice, participant will receive a []byte, deserialize it, 36 // add his contribution and send back to coordinator. 37 prev := srs1.clone() 38 39 srs1.Contribute() 40 assert.NoError(VerifyPhase1(&prev, &srs1)) 41 } 42 43 // Compile the circuit 44 var myCircuit Circuit 45 ccs, err := frontend.Compile(curve.ID.ScalarField(), r1cs.NewBuilder, &myCircuit) 46 assert.NoError(err) 47 48 var evals Phase2Evaluations 49 r1cs := ccs.(*cs.R1CS) 50 51 // Prepare for phase-2 52 srs2, evals := InitPhase2(r1cs, &srs1) 53 54 // Make and verify contributions for phase1 55 for i := 1; i < nContributionsPhase2; i++ { 56 // we clone for test purposes; but in practice, participant will receive a []byte, deserialize it, 57 // add his contribution and send back to coordinator. 58 prev := srs2.clone() 59 60 srs2.Contribute() 61 assert.NoError(VerifyPhase2(&prev, &srs2)) 62 } 63 64 // Extract the proving and verifying keys 65 pk, vk := ExtractKeys(&srs1, &srs2, &evals, ccs.GetNbConstraints()) 66 67 // Build the witness 68 var preImage, hash fr.Element 69 { 70 m := native_mimc.NewMiMC() 71 m.Write(preImage.Marshal()) 72 hash.SetBytes(m.Sum(nil)) 73 } 74 75 witness, err := frontend.NewWitness(&Circuit{PreImage: preImage, Hash: hash}, curve.ID.ScalarField()) 76 assert.NoError(err) 77 78 pubWitness, err := witness.Public() 79 assert.NoError(err) 80 81 // groth16: ensure proof is verified 82 proof, err := groth16.Prove(ccs, &pk, witness) 83 assert.NoError(err) 84 85 err = groth16.Verify(proof, &vk, pubWitness) 86 assert.NoError(err) 87 } 88 89 func BenchmarkPhase1(b *testing.B) { 90 const power = 14 91 92 b.Run("init", func(b *testing.B) { 93 b.ResetTimer() 94 for i := 0; i < b.N; i++ { 95 _ = InitPhase1(power) 96 } 97 }) 98 99 b.Run("contrib", func(b *testing.B) { 100 srs1 := InitPhase1(power) 101 b.ResetTimer() 102 for i := 0; i < b.N; i++ { 103 srs1.Contribute() 104 } 105 }) 106 107 } 108 109 func BenchmarkPhase2(b *testing.B) { 110 const power = 14 111 srs1 := InitPhase1(power) 112 srs1.Contribute() 113 114 var myCircuit Circuit 115 ccs, err := frontend.Compile(curve.ID.ScalarField(), r1cs.NewBuilder, &myCircuit) 116 if err != nil { 117 b.Fatal(err) 118 } 119 120 r1cs := ccs.(*cs.R1CS) 121 122 b.Run("init", func(b *testing.B) { 123 b.ResetTimer() 124 for i := 0; i < b.N; i++ { 125 _, _ = InitPhase2(r1cs, &srs1) 126 } 127 }) 128 129 b.Run("contrib", func(b *testing.B) { 130 srs2, _ := InitPhase2(r1cs, &srs1) 131 b.ResetTimer() 132 for i := 0; i < b.N; i++ { 133 srs2.Contribute() 134 } 135 }) 136 137 } 138 139 // Circuit defines a pre-image knowledge proof 140 // mimc(secret preImage) = public hash 141 type Circuit struct { 142 PreImage frontend.Variable 143 Hash frontend.Variable `gnark:",public"` 144 } 145 146 // Define declares the circuit's constraints 147 // Hash = mimc(PreImage) 148 func (circuit *Circuit) Define(api frontend.API) error { 149 // hash function 150 mimc, _ := mimc.NewMiMC(api) 151 152 // specify constraints 153 mimc.Write(circuit.PreImage) 154 api.AssertIsEqual(circuit.Hash, mimc.Sum()) 155 156 return nil 157 } 158 159 func (phase1 *Phase1) clone() Phase1 { 160 r := Phase1{} 161 r.Parameters.G1.Tau = append(r.Parameters.G1.Tau, phase1.Parameters.G1.Tau...) 162 r.Parameters.G1.AlphaTau = append(r.Parameters.G1.AlphaTau, phase1.Parameters.G1.AlphaTau...) 163 r.Parameters.G1.BetaTau = append(r.Parameters.G1.BetaTau, phase1.Parameters.G1.BetaTau...) 164 165 r.Parameters.G2.Tau = append(r.Parameters.G2.Tau, phase1.Parameters.G2.Tau...) 166 r.Parameters.G2.Beta = phase1.Parameters.G2.Beta 167 168 r.PublicKeys = phase1.PublicKeys 169 r.Hash = append(r.Hash, phase1.Hash...) 170 171 return r 172 } 173 174 func (phase2 *Phase2) clone() Phase2 { 175 r := Phase2{} 176 r.Parameters.G1.Delta = phase2.Parameters.G1.Delta 177 r.Parameters.G1.L = append(r.Parameters.G1.L, phase2.Parameters.G1.L...) 178 r.Parameters.G1.Z = append(r.Parameters.G1.Z, phase2.Parameters.G1.Z...) 179 r.Parameters.G2.Delta = phase2.Parameters.G2.Delta 180 r.PublicKey = phase2.PublicKey 181 r.Hash = append(r.Hash, phase2.Hash...) 182 183 return r 184 }