github.com/ethereum/go-ethereum@v1.16.1/crypto/bn256/gnark/pairing.go (about) 1 package bn256 2 3 import ( 4 "github.com/consensys/gnark-crypto/ecc/bn254" 5 ) 6 7 // PairingCheck computes the following relation: ∏ᵢ e(Pᵢ, Qᵢ) =? 1 8 // 9 // To explain why gnark returns a (bool, error): 10 // 11 // - If the function `e` does not return a result then internally 12 // an error is returned. 13 // - If `e` returns a result, then error will be nil, 14 // but if this value is not `1` then the boolean value will be false 15 // 16 // We therefore check for an error, and return false if its non-nil and 17 // then return the value of the boolean if not. 18 func PairingCheck(a_ []*G1, b_ []*G2) bool { 19 a := getInnerG1s(a_) 20 b := getInnerG2s(b_) 21 22 // Assume that len(a) == len(b) 23 // 24 // The pairing function will return 25 // false, if this is not the case. 26 size := len(a) 27 28 // Check if input is empty -- gnark will 29 // return false on an empty input, however 30 // the ossified behavior is to return true 31 // on an empty input, so we add this if statement. 32 if size == 0 { 33 return true 34 } 35 36 ok, err := bn254.PairingCheck(a, b) 37 if err != nil { 38 return false 39 } 40 return ok 41 } 42 43 // getInnerG1s gets the inner gnark G1 elements. 44 // 45 // These methods are used for two reasons: 46 // 47 // - We use a new type `G1`, so we need to convert from 48 // []*G1 to []*bn254.G1Affine 49 // - The gnark API accepts slices of values and not slices of 50 // pointers to values, so we need to return []bn254.G1Affine 51 // instead of []*bn254.G1Affine. 52 func getInnerG1s(pointerSlice []*G1) []bn254.G1Affine { 53 gnarkValues := make([]bn254.G1Affine, 0, len(pointerSlice)) 54 for _, ptr := range pointerSlice { 55 if ptr != nil { 56 gnarkValues = append(gnarkValues, ptr.inner) 57 } 58 } 59 return gnarkValues 60 } 61 62 // getInnerG2s gets the inner gnark G2 elements. 63 // 64 // The rationale for this method is the same as `getInnerG1s`. 65 func getInnerG2s(pointerSlice []*G2) []bn254.G2Affine { 66 gnarkValues := make([]bn254.G2Affine, 0, len(pointerSlice)) 67 for _, ptr := range pointerSlice { 68 if ptr != nil { 69 gnarkValues = append(gnarkValues, ptr.inner) 70 } 71 } 72 return gnarkValues 73 }