@@ -24,42 +24,77 @@ import (
2424 "github.com/ethereum/go-ethereum/core/vm"
2525)
2626
27- // The function must return
27+ const (
28+ blsG1Add = byte (10 )
29+ blsG1Mul = byte (11 )
30+ blsG1MultiExp = byte (12 )
31+ blsG2Add = byte (13 )
32+ blsG2Mul = byte (14 )
33+ blsG2MultiExp = byte (15 )
34+ blsPairing = byte (16 )
35+ blsMapG1 = byte (17 )
36+ blsMapG2 = byte (18 )
37+ )
38+
39+ func FuzzG1Add (data []byte ) int { return fuzz (blsG1Add , data ) }
40+ func FuzzG1Mul (data []byte ) int { return fuzz (blsG1Mul , data ) }
41+ func FuzzG1MultiExp (data []byte ) int { return fuzz (blsG1MultiExp , data ) }
42+ func FuzzG2Add (data []byte ) int { return fuzz (blsG2Add , data ) }
43+ func FuzzG2Mul (data []byte ) int { return fuzz (blsG2Mul , data ) }
44+ func FuzzG2MultiExp (data []byte ) int { return fuzz (blsG2MultiExp , data ) }
45+ func FuzzPairing (data []byte ) int { return fuzz (blsPairing , data ) }
46+ func FuzzMapG1 (data []byte ) int { return fuzz (blsMapG1 , data ) }
47+ func FuzzMapG2 (data []byte ) int { return fuzz (blsMapG2 , data ) }
48+
49+ func checkInput (id byte , inputLen int ) bool {
50+ switch id {
51+ case blsG1Add :
52+ return inputLen == 256
53+ case blsG1Mul :
54+ return inputLen == 160
55+ case blsG1MultiExp :
56+ return inputLen % 160 == 0
57+ case blsG2Add :
58+ return inputLen == 512
59+ case blsG2Mul :
60+ return inputLen == 288
61+ case blsG2MultiExp :
62+ return inputLen % 288 == 0
63+ case blsPairing :
64+ return inputLen % 384 == 0
65+ case blsMapG1 :
66+ return inputLen == 64
67+ case blsMapG2 :
68+ return inputLen == 128
69+ }
70+ panic ("programmer error" )
71+ }
72+
73+ // The fuzzer functions must return
2874// 1 if the fuzzer should increase priority of the
2975// given input during subsequent fuzzing (for example, the input is lexically
3076// correct and was parsed successfully);
3177// -1 if the input must not be added to corpus even if gives new coverage; and
3278// 0 otherwise
3379// other values are reserved for future use.
34- func Fuzz (data []byte ) int {
35-
36- // The bls ones are at 10 - 18
37- var precompiles = []vm.PrecompiledContract {
38- vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {10 })],
39- vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {11 })],
40- vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {12 })],
41- vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {13 })],
42- vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {14 })],
43- vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {15 })],
44- vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {16 })],
45- vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {17 })],
46- vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {18 })],
80+ func fuzz (id byte , data []byte ) int {
81+ // Even on bad input, it should not crash, so we still test the gas calc
82+ precompile := vm .PrecompiledContractsYoloV2 [common .BytesToAddress ([]byte {id })]
83+ gas := precompile .RequiredGas (data )
84+ if ! checkInput (id , len (data )) {
85+ return 0
86+ }
87+ // If the gas cost is too large (25M), bail out
88+ if gas > 25 * 1000 * 1000 {
89+ return 0
4790 }
48-
4991 cpy := make ([]byte , len (data ))
5092 copy (cpy , data )
51- var useful = false
52- for i , precompile := range precompiles {
53- precompile .RequiredGas (cpy )
54- if _ , err := precompile .Run (cpy ); err == nil {
55- useful = true
56- }
57- if ! bytes .Equal (cpy , data ) {
58- panic (fmt .Sprintf ("input data modified, precompile %d: %x %x" , i , data , cpy ))
59- }
93+ _ , err := precompile .Run (cpy )
94+ if ! bytes .Equal (cpy , data ) {
95+ panic (fmt .Sprintf ("input data modified, precompile %d: %x %x" , id , data , cpy ))
6096 }
61- if ! useful {
62- // Input not great
97+ if err != nil {
6398 return 0
6499 }
65100 return 1
0 commit comments