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