github.com/consensys/gnark@v0.11.0/backend/groth16/bn254/mpcsetup/setup_test.go (about)

     1  // Copyright 2020 ConsenSys Software Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Code generated by gnark DO NOT EDIT
    16  
    17  package mpcsetup
    18  
    19  import (
    20  	curve "github.com/consensys/gnark-crypto/ecc/bn254"
    21  	"github.com/consensys/gnark-crypto/ecc/bn254/fr"
    22  	cs "github.com/consensys/gnark/constraint/bn254"
    23  	"testing"
    24  
    25  	"github.com/consensys/gnark/backend/groth16"
    26  	"github.com/consensys/gnark/frontend"
    27  	"github.com/consensys/gnark/frontend/cs/r1cs"
    28  	"github.com/consensys/gnark/std/hash/mimc"
    29  	"github.com/stretchr/testify/require"
    30  
    31  	native_mimc "github.com/consensys/gnark-crypto/ecc/bn254/fr/mimc"
    32  )
    33  
    34  func TestSetupCircuit(t *testing.T) {
    35  	const (
    36  		nContributionsPhase1 = 3
    37  		nContributionsPhase2 = 3
    38  		power                = 9
    39  	)
    40  
    41  	assert := require.New(t)
    42  
    43  	srs1 := InitPhase1(power)
    44  
    45  	// Make and verify contributions for phase1
    46  	for i := 1; i < nContributionsPhase1; i++ {
    47  		// we clone test purposes; but in practice, participant will receive a []byte, deserialize it,
    48  		// add his contribution and send back to coordinator.
    49  		prev := srs1.clone()
    50  
    51  		srs1.Contribute()
    52  		assert.NoError(VerifyPhase1(&prev, &srs1))
    53  	}
    54  
    55  	// Compile the circuit
    56  	var myCircuit Circuit
    57  	ccs, err := frontend.Compile(curve.ID.ScalarField(), r1cs.NewBuilder, &myCircuit)
    58  	assert.NoError(err)
    59  
    60  	var evals Phase2Evaluations
    61  	r1cs := ccs.(*cs.R1CS)
    62  
    63  	// Prepare for phase-2
    64  	srs2, evals := InitPhase2(r1cs, &srs1)
    65  
    66  	// Make and verify contributions for phase1
    67  	for i := 1; i < nContributionsPhase2; i++ {
    68  		// we clone for test purposes; but in practice, participant will receive a []byte, deserialize it,
    69  		// add his contribution and send back to coordinator.
    70  		prev := srs2.clone()
    71  
    72  		srs2.Contribute()
    73  		assert.NoError(VerifyPhase2(&prev, &srs2))
    74  	}
    75  
    76  	// Extract the proving and verifying keys
    77  	pk, vk := ExtractKeys(&srs1, &srs2, &evals, ccs.GetNbConstraints())
    78  
    79  	// Build the witness
    80  	var preImage, hash fr.Element
    81  	{
    82  		m := native_mimc.NewMiMC()
    83  		m.Write(preImage.Marshal())
    84  		hash.SetBytes(m.Sum(nil))
    85  	}
    86  
    87  	witness, err := frontend.NewWitness(&Circuit{PreImage: preImage, Hash: hash}, curve.ID.ScalarField())
    88  	assert.NoError(err)
    89  
    90  	pubWitness, err := witness.Public()
    91  	assert.NoError(err)
    92  
    93  	// groth16: ensure proof is verified
    94  	proof, err := groth16.Prove(ccs, &pk, witness)
    95  	assert.NoError(err)
    96  
    97  	err = groth16.Verify(proof, &vk, pubWitness)
    98  	assert.NoError(err)
    99  }
   100  
   101  func BenchmarkPhase1(b *testing.B) {
   102  	const power = 14
   103  
   104  	b.Run("init", func(b *testing.B) {
   105  		b.ResetTimer()
   106  		for i := 0; i < b.N; i++ {
   107  			_ = InitPhase1(power)
   108  		}
   109  	})
   110  
   111  	b.Run("contrib", func(b *testing.B) {
   112  		srs1 := InitPhase1(power)
   113  		b.ResetTimer()
   114  		for i := 0; i < b.N; i++ {
   115  			srs1.Contribute()
   116  		}
   117  	})
   118  
   119  }
   120  
   121  func BenchmarkPhase2(b *testing.B) {
   122  	const power = 14
   123  	srs1 := InitPhase1(power)
   124  	srs1.Contribute()
   125  
   126  	var myCircuit Circuit
   127  	ccs, err := frontend.Compile(curve.ID.ScalarField(), r1cs.NewBuilder, &myCircuit)
   128  	if err != nil {
   129  		b.Fatal(err)
   130  	}
   131  
   132  	r1cs := ccs.(*cs.R1CS)
   133  
   134  	b.Run("init", func(b *testing.B) {
   135  		b.ResetTimer()
   136  		for i := 0; i < b.N; i++ {
   137  			_, _ = InitPhase2(r1cs, &srs1)
   138  		}
   139  	})
   140  
   141  	b.Run("contrib", func(b *testing.B) {
   142  		srs2, _ := InitPhase2(r1cs, &srs1)
   143  		b.ResetTimer()
   144  		for i := 0; i < b.N; i++ {
   145  			srs2.Contribute()
   146  		}
   147  	})
   148  
   149  }
   150  
   151  // Circuit defines a pre-image knowledge proof
   152  // mimc(secret preImage) = public hash
   153  type Circuit struct {
   154  	PreImage frontend.Variable
   155  	Hash     frontend.Variable `gnark:",public"`
   156  }
   157  
   158  // Define declares the circuit's constraints
   159  // Hash = mimc(PreImage)
   160  func (circuit *Circuit) Define(api frontend.API) error {
   161  	// hash function
   162  	mimc, _ := mimc.NewMiMC(api)
   163  
   164  	// specify constraints
   165  	mimc.Write(circuit.PreImage)
   166  	api.AssertIsEqual(circuit.Hash, mimc.Sum())
   167  
   168  	return nil
   169  }
   170  
   171  func (phase1 *Phase1) clone() Phase1 {
   172  	r := Phase1{}
   173  	r.Parameters.G1.Tau = append(r.Parameters.G1.Tau, phase1.Parameters.G1.Tau...)
   174  	r.Parameters.G1.AlphaTau = append(r.Parameters.G1.AlphaTau, phase1.Parameters.G1.AlphaTau...)
   175  	r.Parameters.G1.BetaTau = append(r.Parameters.G1.BetaTau, phase1.Parameters.G1.BetaTau...)
   176  
   177  	r.Parameters.G2.Tau = append(r.Parameters.G2.Tau, phase1.Parameters.G2.Tau...)
   178  	r.Parameters.G2.Beta = phase1.Parameters.G2.Beta
   179  
   180  	r.PublicKeys = phase1.PublicKeys
   181  	r.Hash = append(r.Hash, phase1.Hash...)
   182  
   183  	return r
   184  }
   185  
   186  func (phase2 *Phase2) clone() Phase2 {
   187  	r := Phase2{}
   188  	r.Parameters.G1.Delta = phase2.Parameters.G1.Delta
   189  	r.Parameters.G1.L = append(r.Parameters.G1.L, phase2.Parameters.G1.L...)
   190  	r.Parameters.G1.Z = append(r.Parameters.G1.Z, phase2.Parameters.G1.Z...)
   191  	r.Parameters.G2.Delta = phase2.Parameters.G2.Delta
   192  	r.PublicKey = phase2.PublicKey
   193  	r.Hash = append(r.Hash, phase2.Hash...)
   194  
   195  	return r
   196  }