github.com/ethereum/go-ethereum@v1.14.3/tests/fuzzers/bls12381/precompile_fuzzer.go (about) 1 // Copyright 2020 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 package bls 18 19 import ( 20 "bytes" 21 "fmt" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/core/vm" 25 ) 26 27 const ( 28 blsG1Add = byte(11) 29 blsG1Mul = byte(12) 30 blsG1MultiExp = byte(13) 31 blsG2Add = byte(14) 32 blsG2Mul = byte(15) 33 blsG2MultiExp = byte(16) 34 blsPairing = byte(17) 35 blsMapG1 = byte(18) 36 blsMapG2 = byte(19) 37 ) 38 39 func checkInput(id byte, inputLen int) bool { 40 switch id { 41 case blsG1Add: 42 return inputLen == 256 43 case blsG1Mul: 44 return inputLen == 160 45 case blsG1MultiExp: 46 return inputLen%160 == 0 47 case blsG2Add: 48 return inputLen == 512 49 case blsG2Mul: 50 return inputLen == 288 51 case blsG2MultiExp: 52 return inputLen%288 == 0 53 case blsPairing: 54 return inputLen%384 == 0 55 case blsMapG1: 56 return inputLen == 64 57 case blsMapG2: 58 return inputLen == 128 59 } 60 panic("programmer error") 61 } 62 63 // The function must return 64 // 65 // - 1 if the fuzzer should increase priority of the 66 // given input during subsequent fuzzing (for example, the input is lexically 67 // correct and was parsed successfully); 68 // - -1 if the input must not be added to corpus even if gives new coverage; and 69 // - 0 otherwise 70 // 71 // other values are reserved for future use. 72 func fuzz(id byte, data []byte) int { 73 // Even on bad input, it should not crash, so we still test the gas calc 74 precompile := vm.PrecompiledContractsBLS[common.BytesToAddress([]byte{id})] 75 gas := precompile.RequiredGas(data) 76 if !checkInput(id, len(data)) { 77 return 0 78 } 79 // If the gas cost is too large (25M), bail out 80 if gas > 25*1000*1000 { 81 return 0 82 } 83 cpy := make([]byte, len(data)) 84 copy(cpy, data) 85 _, err := precompile.Run(cpy) 86 if !bytes.Equal(cpy, data) { 87 panic(fmt.Sprintf("input data modified, precompile %d: %x %x", id, data, cpy)) 88 } 89 if err != nil { 90 return 0 91 } 92 return 1 93 }