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 }