github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/tests/fuzzers/bn256/bn256_fuzz.go (about) 1 // Copyright 2018 Péter Szilágyi. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be found 3 // in the LICENSE file. 4 5 //go:build gofuzz 6 // +build gofuzz 7 8 package bn256 9 10 import ( 11 "bytes" 12 "fmt" 13 "io" 14 "math/big" 15 16 "github.com/consensys/gnark-crypto/ecc/bn254" 17 18 cloudflare "github.com/scroll-tech/go-ethereum/crypto/bn256/cloudflare" 19 google "github.com/scroll-tech/go-ethereum/crypto/bn256/google" 20 ) 21 22 func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1, *bn254.G1Affine) { 23 _, xc, err := cloudflare.RandomG1(input) 24 if err != nil { 25 // insufficient input 26 return nil, nil, nil 27 } 28 xg := new(google.G1) 29 if _, err := xg.Unmarshal(xc.Marshal()); err != nil { 30 panic(fmt.Sprintf("Could not marshal cloudflare -> google: %v", err)) 31 } 32 xs := new(bn254.G1Affine) 33 if err := xs.Unmarshal(xc.Marshal()); err != nil { 34 panic(fmt.Sprintf("Could not marshal cloudflare -> gnark: %v", err)) 35 } 36 return xc, xg, xs 37 } 38 39 func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine) { 40 _, xc, err := cloudflare.RandomG2(input) 41 if err != nil { 42 // insufficient input 43 return nil, nil, nil 44 } 45 xg := new(google.G2) 46 if _, err := xg.Unmarshal(xc.Marshal()); err != nil { 47 panic(fmt.Sprintf("Could not marshal cloudflare -> google: %v", err)) 48 } 49 xs := new(bn254.G2Affine) 50 if err := xs.Unmarshal(xc.Marshal()); err != nil { 51 panic(fmt.Sprintf("Could not marshal cloudflare -> gnark: %v", err)) 52 } 53 return xc, xg, xs 54 } 55 56 // FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries. 57 func FuzzAdd(data []byte) int { 58 input := bytes.NewReader(data) 59 xc, xg, xs := getG1Points(input) 60 if xc == nil { 61 return 0 62 } 63 yc, yg, ys := getG1Points(input) 64 if yc == nil { 65 return 0 66 } 67 // Ensure both libs can parse the second curve point 68 // Add the two points and ensure they result in the same output 69 rc := new(cloudflare.G1) 70 rc.Add(xc, yc) 71 72 rg := new(google.G1) 73 rg.Add(xg, yg) 74 75 tmpX := new(bn254.G1Jac).FromAffine(xs) 76 tmpY := new(bn254.G1Jac).FromAffine(ys) 77 rs := new(bn254.G1Affine).FromJacobian(tmpX.AddAssign(tmpY)) 78 79 if !bytes.Equal(rc.Marshal(), rg.Marshal()) { 80 panic("add mismatch: cloudflare/google") 81 } 82 83 if !bytes.Equal(rc.Marshal(), rs.Marshal()) { 84 panic("add mismatch: cloudflare/gnark") 85 } 86 return 1 87 } 88 89 // FuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare 90 // libraries. 91 func FuzzMul(data []byte) int { 92 input := bytes.NewReader(data) 93 pc, pg, ps := getG1Points(input) 94 if pc == nil { 95 return 0 96 } 97 // Add the two points and ensure they result in the same output 98 remaining := input.Len() 99 if remaining == 0 { 100 return 0 101 } 102 if remaining > 128 { 103 // The evm only ever uses 32 byte integers, we need to cap this otherwise 104 // we run into slow exec. A 236Kb byte integer cause oss-fuzz to report it as slow. 105 // 128 bytes should be fine though 106 return 0 107 } 108 buf := make([]byte, remaining) 109 input.Read(buf) 110 111 rc := new(cloudflare.G1) 112 rc.ScalarMult(pc, new(big.Int).SetBytes(buf)) 113 114 rg := new(google.G1) 115 rg.ScalarMult(pg, new(big.Int).SetBytes(buf)) 116 117 rs := new(bn254.G1Jac) 118 psJac := new(bn254.G1Jac).FromAffine(ps) 119 rs.ScalarMultiplication(psJac, new(big.Int).SetBytes(buf)) 120 rsAffine := new(bn254.G1Affine).FromJacobian(rs) 121 122 if !bytes.Equal(rc.Marshal(), rg.Marshal()) { 123 panic("scalar mul mismatch: cloudflare/google") 124 } 125 if !bytes.Equal(rc.Marshal(), rsAffine.Marshal()) { 126 panic("scalar mul mismatch: cloudflare/gnark") 127 } 128 return 1 129 } 130 131 func FuzzPair(data []byte) int { 132 input := bytes.NewReader(data) 133 pc, pg, ps := getG1Points(input) 134 if pc == nil { 135 return 0 136 } 137 tc, tg, ts := getG2Points(input) 138 if tc == nil { 139 return 0 140 } 141 142 // Pair the two points and ensure they result in the same output 143 clPair := cloudflare.Pair(pc, tc).Marshal() 144 gPair := google.Pair(pg, tg).Marshal() 145 if !bytes.Equal(clPair, gPair) { 146 panic("pairing mismatch: cloudflare/google") 147 } 148 149 cPair, err := bn254.Pair([]bn254.G1Affine{*ps}, []bn254.G2Affine{*ts}) 150 if err != nil { 151 panic(fmt.Sprintf("gnark/bn254 encountered error: %v", err)) 152 } 153 if !bytes.Equal(clPair, cPair.Marshal()) { 154 panic("pairing mismatch: cloudflare/gnark") 155 } 156 157 return 1 158 }