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  }