github.com/consensys/gnark@v0.11.0/backend/groth16/bw6-761/verify.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 groth16 18 19 import ( 20 "errors" 21 "fmt" 22 "io" 23 "time" 24 25 "github.com/consensys/gnark-crypto/ecc" 26 curve "github.com/consensys/gnark-crypto/ecc/bw6-761" 27 "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" 28 "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/hash_to_field" 29 "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/pedersen" 30 "github.com/consensys/gnark-crypto/utils" 31 "github.com/consensys/gnark/backend" 32 "github.com/consensys/gnark/backend/solidity" 33 "github.com/consensys/gnark/constraint" 34 "github.com/consensys/gnark/logger" 35 ) 36 37 var ( 38 errPairingCheckFailed = errors.New("pairing doesn't match") 39 errCorrectSubgroupCheckFailed = errors.New("points in the proof are not in the correct subgroup") 40 ) 41 42 // Verify verifies a proof with given VerifyingKey and publicWitness 43 func Verify(proof *Proof, vk *VerifyingKey, publicWitness fr.Vector, opts ...backend.VerifierOption) error { 44 opt, err := backend.NewVerifierConfig(opts...) 45 if err != nil { 46 return fmt.Errorf("new verifier config: %w", err) 47 } 48 if opt.HashToFieldFn == nil { 49 opt.HashToFieldFn = hash_to_field.New([]byte(constraint.CommitmentDst)) 50 } 51 52 nbPublicVars := len(vk.G1.K) - len(vk.PublicAndCommitmentCommitted) 53 54 if len(publicWitness) != nbPublicVars-1 { 55 return fmt.Errorf("invalid witness size, got %d, expected %d (public - ONE_WIRE)", len(publicWitness), len(vk.G1.K)-1) 56 } 57 log := logger.Logger().With().Str("curve", vk.CurveID().String()).Str("backend", "groth16").Logger() 58 start := time.Now() 59 60 // check that the points in the proof are in the correct subgroup 61 if !proof.isValid() { 62 return errCorrectSubgroupCheckFailed 63 } 64 65 var doubleML curve.GT 66 chDone := make(chan error, 1) 67 68 // compute (eKrsδ, eArBs) 69 go func() { 70 var errML error 71 doubleML, errML = curve.MillerLoop([]curve.G1Affine{proof.Krs, proof.Ar}, []curve.G2Affine{vk.G2.deltaNeg, proof.Bs}) 72 chDone <- errML 73 close(chDone) 74 }() 75 76 maxNbPublicCommitted := 0 77 for _, s := range vk.PublicAndCommitmentCommitted { // iterate over commitments 78 maxNbPublicCommitted = utils.Max(maxNbPublicCommitted, len(s)) 79 } 80 commitmentsSerialized := make([]byte, len(vk.PublicAndCommitmentCommitted)*fr.Bytes) 81 commitmentPrehashSerialized := make([]byte, curve.SizeOfG1AffineUncompressed+maxNbPublicCommitted*fr.Bytes) 82 for i := range vk.PublicAndCommitmentCommitted { // solveCommitmentWire 83 copy(commitmentPrehashSerialized, proof.Commitments[i].Marshal()) 84 offset := curve.SizeOfG1AffineUncompressed 85 for j := range vk.PublicAndCommitmentCommitted[i] { 86 copy(commitmentPrehashSerialized[offset:], publicWitness[vk.PublicAndCommitmentCommitted[i][j]-1].Marshal()) 87 offset += fr.Bytes 88 } 89 opt.HashToFieldFn.Write(commitmentPrehashSerialized[:offset]) 90 hashBts := opt.HashToFieldFn.Sum(nil) 91 opt.HashToFieldFn.Reset() 92 nbBuf := fr.Bytes 93 if opt.HashToFieldFn.Size() < fr.Bytes { 94 nbBuf = opt.HashToFieldFn.Size() 95 } 96 var res fr.Element 97 res.SetBytes(hashBts[:nbBuf]) 98 publicWitness = append(publicWitness, res) 99 copy(commitmentsSerialized[i*fr.Bytes:], res.Marshal()) 100 } 101 if len(vk.CommitmentKeys) > 0 { 102 challenge, err := fr.Hash(commitmentsSerialized, []byte("G16-BSB22"), 1) 103 if err != nil { 104 return err 105 } 106 if err = pedersen.BatchVerifyMultiVk(vk.CommitmentKeys, proof.Commitments, []curve.G1Affine{proof.CommitmentPok}, challenge[0]); err != nil { 107 return err 108 } 109 } 110 111 // compute e(Σx.[Kvk(t)]1, -[γ]2) 112 var kSum curve.G1Jac 113 if _, err := kSum.MultiExp(vk.G1.K[1:], publicWitness, ecc.MultiExpConfig{}); err != nil { 114 return err 115 } 116 kSum.AddMixed(&vk.G1.K[0]) 117 118 for i := range proof.Commitments { 119 kSum.AddMixed(&proof.Commitments[i]) 120 } 121 122 var kSumAff curve.G1Affine 123 kSumAff.FromJacobian(&kSum) 124 125 right, err := curve.MillerLoop([]curve.G1Affine{kSumAff}, []curve.G2Affine{vk.G2.gammaNeg}) 126 if err != nil { 127 return err 128 } 129 130 // wait for (eKrsδ, eArBs) 131 if err := <-chDone; err != nil { 132 return err 133 } 134 135 right = curve.FinalExponentiation(&right, &doubleML) 136 if !vk.e.Equal(&right) { 137 return errPairingCheckFailed 138 } 139 140 log.Debug().Dur("took", time.Since(start)).Msg("verifier done") 141 return nil 142 } 143 144 // ExportSolidity not implemented for BW6-761 145 func (vk *VerifyingKey) ExportSolidity(w io.Writer, exportOpts ...solidity.ExportOption) error { 146 return errors.New("not implemented") 147 }