github.com/phillinzzz/newBsc@v1.1.6/tests/fuzzers/bls12381/bls12381_fuzz.go (about) 1 // Copyright 2021 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // +build gofuzz 18 19 package bls 20 21 import ( 22 "bytes" 23 "crypto/rand" 24 "fmt" 25 "io" 26 "math/big" 27 28 gnark "github.com/consensys/gnark-crypto/ecc/bls12-381" 29 "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" 30 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" 31 "github.com/phillinzzz/newBsc/crypto/bls12381" 32 ) 33 34 func FuzzCrossPairing(data []byte) int { 35 input := bytes.NewReader(data) 36 37 // get random G1 points 38 kpG1, cpG1, err := getG1Points(input) 39 if err != nil { 40 return 0 41 } 42 43 // get random G2 points 44 kpG2, cpG2, err := getG2Points(input) 45 if err != nil { 46 return 0 47 } 48 49 // compute pairing using geth 50 engine := bls12381.NewPairingEngine() 51 engine.AddPair(kpG1, kpG2) 52 kResult := engine.Result() 53 54 // compute pairing using gnark 55 cResult, err := gnark.Pair([]gnark.G1Affine{*cpG1}, []gnark.G2Affine{*cpG2}) 56 if err != nil { 57 panic(fmt.Sprintf("gnark/bls12381 encountered error: %v", err)) 58 } 59 60 // compare result 61 if !(bytes.Equal(cResult.Marshal(), bls12381.NewGT().ToBytes(kResult))) { 62 panic("pairing mismatch gnark / geth ") 63 } 64 65 return 1 66 } 67 68 func FuzzCrossG1Add(data []byte) int { 69 input := bytes.NewReader(data) 70 71 // get random G1 points 72 kp1, cp1, err := getG1Points(input) 73 if err != nil { 74 return 0 75 } 76 77 // get random G1 points 78 kp2, cp2, err := getG1Points(input) 79 if err != nil { 80 return 0 81 } 82 83 // compute kp = kp1 + kp2 84 g1 := bls12381.NewG1() 85 kp := bls12381.PointG1{} 86 g1.Add(&kp, kp1, kp2) 87 88 // compute cp = cp1 + cp2 89 _cp1 := new(gnark.G1Jac).FromAffine(cp1) 90 _cp2 := new(gnark.G1Jac).FromAffine(cp2) 91 cp := new(gnark.G1Affine).FromJacobian(_cp1.AddAssign(_cp2)) 92 93 // compare result 94 if !(bytes.Equal(cp.Marshal(), g1.ToBytes(&kp))) { 95 panic("G1 point addition mismatch gnark / geth ") 96 } 97 98 return 1 99 } 100 101 func FuzzCrossG2Add(data []byte) int { 102 input := bytes.NewReader(data) 103 104 // get random G2 points 105 kp1, cp1, err := getG2Points(input) 106 if err != nil { 107 return 0 108 } 109 110 // get random G2 points 111 kp2, cp2, err := getG2Points(input) 112 if err != nil { 113 return 0 114 } 115 116 // compute kp = kp1 + kp2 117 g2 := bls12381.NewG2() 118 kp := bls12381.PointG2{} 119 g2.Add(&kp, kp1, kp2) 120 121 // compute cp = cp1 + cp2 122 _cp1 := new(gnark.G2Jac).FromAffine(cp1) 123 _cp2 := new(gnark.G2Jac).FromAffine(cp2) 124 cp := new(gnark.G2Affine).FromJacobian(_cp1.AddAssign(_cp2)) 125 126 // compare result 127 if !(bytes.Equal(cp.Marshal(), g2.ToBytes(&kp))) { 128 panic("G2 point addition mismatch gnark / geth ") 129 } 130 131 return 1 132 } 133 134 func FuzzCrossG1MultiExp(data []byte) int { 135 var ( 136 input = bytes.NewReader(data) 137 gethScalars []*big.Int 138 gnarkScalars []fr.Element 139 gethPoints []*bls12381.PointG1 140 gnarkPoints []gnark.G1Affine 141 ) 142 // n random scalars (max 17) 143 for i := 0; i < 17; i++ { 144 // note that geth/crypto/bls12381 works only with scalars <= 32bytes 145 s, err := randomScalar(input, fr.Modulus()) 146 if err != nil { 147 break 148 } 149 // get a random G1 point as basis 150 kp1, cp1, err := getG1Points(input) 151 if err != nil { 152 break 153 } 154 gethScalars = append(gethScalars, s) 155 var gnarkScalar = &fr.Element{} 156 gnarkScalar = gnarkScalar.SetBigInt(s).FromMont() 157 gnarkScalars = append(gnarkScalars, *gnarkScalar) 158 159 gethPoints = append(gethPoints, new(bls12381.PointG1).Set(kp1)) 160 gnarkPoints = append(gnarkPoints, *cp1) 161 } 162 if len(gethScalars) == 0{ 163 return 0 164 } 165 // compute multi exponentiation 166 g1 := bls12381.NewG1() 167 kp := bls12381.PointG1{} 168 if _, err := g1.MultiExp(&kp, gethPoints, gethScalars); err != nil { 169 panic(fmt.Sprintf("G1 multi exponentiation errored (geth): %v", err)) 170 } 171 // note that geth/crypto/bls12381.MultiExp mutates the scalars slice (and sets all the scalars to zero) 172 173 // gnark multi exp 174 cp := new(gnark.G1Affine) 175 cp.MultiExp(gnarkPoints, gnarkScalars) 176 177 // compare result 178 if !(bytes.Equal(cp.Marshal(), g1.ToBytes(&kp))) { 179 panic("G1 multi exponentiation mismatch gnark / geth ") 180 } 181 182 return 1 183 } 184 185 func getG1Points(input io.Reader) (*bls12381.PointG1, *gnark.G1Affine, error) { 186 // sample a random scalar 187 s, err := randomScalar(input, fp.Modulus()) 188 if err != nil { 189 return nil, nil, err 190 } 191 192 // compute a random point 193 cp := new(gnark.G1Affine) 194 _, _, g1Gen, _ := gnark.Generators() 195 cp.ScalarMultiplication(&g1Gen, s) 196 cpBytes := cp.Marshal() 197 198 // marshal gnark point -> geth point 199 g1 := bls12381.NewG1() 200 kp, err := g1.FromBytes(cpBytes) 201 if err != nil { 202 panic(fmt.Sprintf("Could not marshal gnark.G1 -> geth.G1: %v", err)) 203 } 204 if !bytes.Equal(g1.ToBytes(kp), cpBytes) { 205 panic("bytes(gnark.G1) != bytes(geth.G1)") 206 } 207 208 return kp, cp, nil 209 } 210 211 func getG2Points(input io.Reader) (*bls12381.PointG2, *gnark.G2Affine, error) { 212 // sample a random scalar 213 s, err := randomScalar(input, fp.Modulus()) 214 if err != nil { 215 return nil, nil, err 216 } 217 218 // compute a random point 219 cp := new(gnark.G2Affine) 220 _, _, _, g2Gen := gnark.Generators() 221 cp.ScalarMultiplication(&g2Gen, s) 222 cpBytes := cp.Marshal() 223 224 // marshal gnark point -> geth point 225 g2 := bls12381.NewG2() 226 kp, err := g2.FromBytes(cpBytes) 227 if err != nil { 228 panic(fmt.Sprintf("Could not marshal gnark.G2 -> geth.G2: %v", err)) 229 } 230 if !bytes.Equal(g2.ToBytes(kp), cpBytes) { 231 panic("bytes(gnark.G2) != bytes(geth.G2)") 232 } 233 234 return kp, cp, nil 235 } 236 237 func randomScalar(r io.Reader, max *big.Int) (k *big.Int, err error) { 238 for { 239 k, err = rand.Int(r, max) 240 if err != nil || k.Sign() > 0 { 241 return 242 } 243 } 244 }