github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/fr/pedersen/example_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 consensys/gnark-crypto DO NOT EDIT
    16  
    17  package pedersen
    18  
    19  import (
    20  	"crypto/rand"
    21  	"fmt"
    22  
    23  	"github.com/consensys/gnark-crypto/ecc"
    24  	curve "github.com/consensys/gnark-crypto/ecc/bls12-381"
    25  	"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
    26  )
    27  
    28  // This example demonstrates how to use the Pedersen commitment scheme
    29  // to commit to a set of values and prove knowledge of the committed values.
    30  //
    31  // Does not perform any batching or multi-proof optimization.
    32  func Example_singleProof() {
    33  	const nbElem = 4
    34  	// create a proving key with independent basis elements
    35  	var buf [32]byte
    36  	basis := make([]curve.G1Affine, nbElem)
    37  	for i := range basis {
    38  		_, err := rand.Read(buf[:])
    39  		if err != nil {
    40  			panic(err)
    41  		}
    42  		// we use hash-to-curve to avoid linear dependencies between basis elements
    43  		basis[i], err = curve.HashToG1(buf[:], []byte(fmt.Sprintf("basis %d", i)))
    44  		if err != nil {
    45  			panic(err)
    46  		}
    47  	}
    48  	// create a proving and verifying key. NB! Must be done using MPC
    49  	pks, vk, err := Setup([][]curve.G1Affine{basis})
    50  	if err != nil {
    51  		panic(err)
    52  	}
    53  	// currently we only have a single proving key
    54  	pk := pks[0]
    55  	toCommit := make([]fr.Element, nbElem)
    56  	for i := range toCommit {
    57  		toCommit[i].SetRandom()
    58  	}
    59  	// commit to the values
    60  	commitment, err := pk.Commit(toCommit)
    61  	if err != nil {
    62  		panic(err)
    63  	}
    64  	// prove knowledge of the committed values
    65  	pok, err := pk.ProveKnowledge(toCommit)
    66  	if err != nil {
    67  		panic(err)
    68  	}
    69  	// verify the proof
    70  	if err := vk.Verify(commitment, pok); err != nil {
    71  		panic(err)
    72  	}
    73  
    74  	fmt.Println("verified")
    75  	// output: verified
    76  }
    77  
    78  // This example shows how to batch the commitment and proof generation.
    79  func ExampleBatchProve() {
    80  	const nbPks = 3
    81  	const nbElem = 4
    82  	// create a proving key with independent basis elements
    83  	var buf [32]byte
    84  	basis := make([][]curve.G1Affine, nbPks)
    85  	for i := range basis {
    86  		basis[i] = make([]curve.G1Affine, nbElem)
    87  		for j := range basis[i] {
    88  			_, err := rand.Read(buf[:])
    89  			if err != nil {
    90  				panic(err)
    91  			}
    92  			// we use hash-to-curve to avoid linear dependencies between basis elements
    93  			basis[i][j], err = curve.HashToG1(buf[:], []byte(fmt.Sprintf("basis %d", i)))
    94  			if err != nil {
    95  				panic(err)
    96  			}
    97  		}
    98  	}
    99  	// create a proving and verifying key. NB! Must be done using MPC
   100  	pks, vk, err := Setup(basis)
   101  	if err != nil {
   102  		panic(err)
   103  	}
   104  	// generate random values to commit to
   105  	toCommit := make([][]fr.Element, nbPks)
   106  	for i := range toCommit {
   107  		toCommit[i] = make([]fr.Element, nbElem)
   108  		for j := range toCommit[i] {
   109  			toCommit[i][j].SetRandom()
   110  		}
   111  	}
   112  	// commit to the values
   113  	commitments := make([]curve.G1Affine, nbPks)
   114  	for i := range commitments {
   115  		commitments[i], err = pks[i].Commit(toCommit[i])
   116  		if err != nil {
   117  			panic(err)
   118  		}
   119  	}
   120  	// combination coefficient is randomly sampled by the verifier. NB! In non-interactive protocol use Fiat-Shamir!
   121  	var combinationCoeff fr.Element
   122  	combinationCoeff.SetRandom()
   123  	proof, err := BatchProve(pks, toCommit, combinationCoeff)
   124  	if err != nil {
   125  		panic(err)
   126  	}
   127  	// fold the commitments
   128  	foldedCommitment, err := new(curve.G1Affine).Fold(commitments, combinationCoeff, ecc.MultiExpConfig{NbTasks: 1})
   129  	if err != nil {
   130  		panic(err)
   131  	}
   132  	// verify the proof
   133  	if err := vk.Verify(*foldedCommitment, proof); err != nil {
   134  		panic(err)
   135  	}
   136  	fmt.Println("verified")
   137  
   138  	// Output: verified
   139  }
   140  
   141  // This example shows how to batch verify multiple proofs using multiple
   142  // verifying keys.
   143  func ExampleBatchVerifyMultiVk() {
   144  	const nbPks = 3
   145  	const nbElem = 4
   146  	// create a proving key with independent basis elements
   147  	var buf [32]byte
   148  	basis := make([][]curve.G1Affine, nbPks)
   149  	for i := range basis {
   150  		basis[i] = make([]curve.G1Affine, nbElem)
   151  		for j := range basis[i] {
   152  			_, err := rand.Read(buf[:])
   153  			if err != nil {
   154  				panic(err)
   155  			}
   156  			// we use hash-to-curve to avoid linear dependencies between basis elements
   157  			basis[i][j], err = curve.HashToG1(buf[:], []byte(fmt.Sprintf("basis %d", i)))
   158  			if err != nil {
   159  				panic(err)
   160  			}
   161  		}
   162  	}
   163  	// we create independent proving keys (different sigmas) with same G2
   164  	// g2Point does not have to be generated in a trusted manner
   165  	_, _, _, g2Point := curve.Generators()
   166  	pks := make([]ProvingKey, nbPks)
   167  	vks := make([]VerifyingKey, nbPks)
   168  	for i := range basis {
   169  		pkss, vkss, err := Setup(basis[i:i+1], WithG2Point(g2Point))
   170  		if err != nil {
   171  			panic(err)
   172  		}
   173  		pks[i] = pkss[0]
   174  		vks[i] = vkss
   175  	}
   176  	// generate random values to commit to
   177  	toCommit := make([][]fr.Element, nbPks)
   178  	for i := range toCommit {
   179  		toCommit[i] = make([]fr.Element, nbElem)
   180  		for j := range toCommit[i] {
   181  			toCommit[i][j].SetRandom()
   182  		}
   183  	}
   184  	// commit to the values
   185  	commitments := make([]curve.G1Affine, nbPks)
   186  	for i := range commitments {
   187  		var err error
   188  		commitments[i], err = pks[i].Commit(toCommit[i])
   189  		if err != nil {
   190  			panic(err)
   191  		}
   192  	}
   193  	// prove the commitments
   194  	proofs := make([]curve.G1Affine, nbPks)
   195  	for i := range proofs {
   196  		var err error
   197  		proofs[i], err = pks[i].ProveKnowledge(toCommit[i])
   198  		if err != nil {
   199  			panic(err)
   200  		}
   201  	}
   202  	// combination coefficient is randomly sampled by the verifier. NB! In non-interactive protocol use Fiat-Shamir!
   203  	var combinationCoeff fr.Element
   204  	combinationCoeff.SetRandom()
   205  	// batch verify the proofs
   206  	if err := BatchVerifyMultiVk(vks, commitments, proofs, combinationCoeff); err != nil {
   207  		panic(err)
   208  	}
   209  
   210  	// alternatively, we can also provide the folded proof
   211  	foldedProof, err := new(curve.G1Affine).Fold(proofs, combinationCoeff, ecc.MultiExpConfig{NbTasks: 1})
   212  	if err != nil {
   213  		panic(err)
   214  	}
   215  	if err := BatchVerifyMultiVk(vks, commitments, []curve.G1Affine{*foldedProof}, combinationCoeff); err != nil {
   216  		panic(err)
   217  	}
   218  
   219  	fmt.Println("verified")
   220  	// Output: verified
   221  }