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