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