Skip to content

Commit f7b6ad6

Browse files
committed
crypto, tests: update fuzzers to native go fuzzing (ethereum#28352)
1 parent 8f57d6c commit f7b6ad6

File tree

9 files changed

+315
-147
lines changed

9 files changed

+315
-147
lines changed

crypto/blake2b/blake2b_f_fuzz.go

Lines changed: 0 additions & 59 deletions
This file was deleted.

crypto/blake2b/blake2b_f_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package blake2b
22

33
import (
4+
"encoding/binary"
45
"fmt"
56
"reflect"
67
"testing"
@@ -57,3 +58,60 @@ var testVectorsF = []testVector{
5758
},
5859
},
5960
}
61+
62+
func Fuzz(f *testing.F) {
63+
f.Fuzz(func(t *testing.T, data []byte) {
64+
fuzz(data)
65+
})
66+
}
67+
68+
func fuzz(data []byte) {
69+
// Make sure the data confirms to the input model
70+
if len(data) != 211 {
71+
return
72+
}
73+
// Parse everything and call all the implementations
74+
var (
75+
rounds = binary.BigEndian.Uint16(data[0:2])
76+
77+
h [8]uint64
78+
m [16]uint64
79+
t [2]uint64
80+
f uint64
81+
)
82+
83+
for i := 0; i < 8; i++ {
84+
offset := 2 + i*8
85+
h[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
86+
}
87+
for i := 0; i < 16; i++ {
88+
offset := 66 + i*8
89+
m[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
90+
}
91+
t[0] = binary.LittleEndian.Uint64(data[194:202])
92+
t[1] = binary.LittleEndian.Uint64(data[202:210])
93+
94+
if data[210]%2 == 1 { // Avoid spinning the fuzzer to hit 0/1
95+
f = 0xFFFFFFFFFFFFFFFF
96+
}
97+
98+
// Run the blake2b compression on all instruction sets and cross reference
99+
want := h
100+
fGeneric(&want, &m, t[0], t[1], f, uint64(rounds))
101+
102+
have := h
103+
fSSE4(&have, &m, t[0], t[1], f, uint64(rounds))
104+
if have != want {
105+
panic("SSE4 mismatches generic algo")
106+
}
107+
have = h
108+
fAVX(&have, &m, t[0], t[1], f, uint64(rounds))
109+
if have != want {
110+
panic("AVX mismatches generic algo")
111+
}
112+
have = h
113+
fAVX2(&have, &m, t[0], t[1], f, uint64(rounds))
114+
if have != want {
115+
panic("AVX2 mismatches generic algo")
116+
}
117+
}
Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2017 The go-ethereum Authors
1+
// Copyright 2023 The go-ethereum Authors
22
// This file is part of the go-ethereum library.
33
//
44
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -18,41 +18,51 @@ package bitutil
1818

1919
import (
2020
"bytes"
21+
"testing"
2122

2223
"github.com/XinFinOrg/XDPoSChain/common/bitutil"
2324
)
2425

25-
// Fuzz implements a go-fuzz fuzzer method to test various encoding method
26-
// invocations.
27-
func Fuzz(data []byte) int {
28-
if len(data) == 0 {
29-
return 0
30-
}
31-
if data[0]%2 == 0 {
32-
return fuzzEncode(data[1:])
33-
}
34-
return fuzzDecode(data[1:])
26+
func FuzzEncoder(f *testing.F) {
27+
f.Fuzz(func(t *testing.T, data []byte) {
28+
fuzzEncode(data)
29+
})
30+
}
31+
func FuzzDecoder(f *testing.F) {
32+
f.Fuzz(func(t *testing.T, data []byte) {
33+
fuzzDecode(data)
34+
})
3535
}
3636

3737
// fuzzEncode implements a go-fuzz fuzzer method to test the bitset encoding and
3838
// decoding algorithm.
39-
func fuzzEncode(data []byte) int {
39+
func fuzzEncode(data []byte) {
4040
proc, _ := bitutil.DecompressBytes(bitutil.CompressBytes(data), len(data))
4141
if !bytes.Equal(data, proc) {
4242
panic("content mismatch")
4343
}
44-
return 1
4544
}
4645

4746
// fuzzDecode implements a go-fuzz fuzzer method to test the bit decoding and
4847
// reencoding algorithm.
49-
func fuzzDecode(data []byte) int {
48+
func fuzzDecode(data []byte) {
5049
blob, err := bitutil.DecompressBytes(data, 1024)
5150
if err != nil {
52-
return 0
51+
return
52+
}
53+
// re-compress it (it's OK if the re-compressed differs from the
54+
// original - the first input may not have been compressed at all)
55+
comp := bitutil.CompressBytes(blob)
56+
if len(comp) > len(blob) {
57+
// After compression, it must be smaller or equal
58+
panic("bad compression")
59+
}
60+
// But decompressing it once again should work
61+
decomp, err := bitutil.DecompressBytes(data, 1024)
62+
if err != nil {
63+
panic(err)
5364
}
54-
if comp := bitutil.CompressBytes(blob); !bytes.Equal(comp, data) {
65+
if !bytes.Equal(decomp, blob) {
5566
panic("content mismatch")
5667
}
57-
return 1
5868
}

tests/fuzzers/bn256/bn256_fuzz.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine)
6161
return xc, xg, xs
6262
}
6363

64-
// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
65-
func FuzzAdd(data []byte) int {
64+
// fuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
65+
func fuzzAdd(data []byte) int {
6666
input := bytes.NewReader(data)
6767
xc, xg, xs := getG1Points(input)
6868
if xc == nil {
@@ -94,9 +94,9 @@ func FuzzAdd(data []byte) int {
9494
return 1
9595
}
9696

97-
// FuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
97+
// fuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
9898
// libraries.
99-
func FuzzMul(data []byte) int {
99+
func fuzzMul(data []byte) int {
100100
input := bytes.NewReader(data)
101101
pc, pg, ps := getG1Points(input)
102102
if pc == nil {
@@ -136,7 +136,7 @@ func FuzzMul(data []byte) int {
136136
return 1
137137
}
138138

139-
func FuzzPair(data []byte) int {
139+
func fuzzPair(data []byte) int {
140140
input := bytes.NewReader(data)
141141
pc, pg, ps := getG1Points(input)
142142
if pc == nil {

tests/fuzzers/rlp/rlp_fuzzer.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// Copyright 2019 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 rlp
18+
19+
import (
20+
"bytes"
21+
"fmt"
22+
"math/big"
23+
24+
"github.com/XinFinOrg/XDPoSChain/core/types"
25+
"github.com/XinFinOrg/XDPoSChain/rlp"
26+
"github.com/holiman/uint256"
27+
)
28+
29+
func decodeEncode(input []byte, val interface{}, i int) {
30+
if err := rlp.DecodeBytes(input, val); err == nil {
31+
output, err := rlp.EncodeToBytes(val)
32+
if err != nil {
33+
panic(err)
34+
}
35+
if !bytes.Equal(input, output) {
36+
panic(fmt.Sprintf("case %d: encode-decode is not equal, \ninput : %x\noutput: %x", i, input, output))
37+
}
38+
}
39+
}
40+
41+
func fuzz(input []byte) int {
42+
if len(input) == 0 {
43+
return 0
44+
}
45+
if len(input) > 500*1024 {
46+
return 0
47+
}
48+
49+
var i int
50+
{
51+
rlp.Split(input)
52+
}
53+
{
54+
if elems, _, err := rlp.SplitList(input); err == nil {
55+
rlp.CountValues(elems)
56+
}
57+
}
58+
59+
{
60+
rlp.NewStream(bytes.NewReader(input), 0).Decode(new(interface{}))
61+
}
62+
63+
{
64+
decodeEncode(input, new(interface{}), i)
65+
i++
66+
}
67+
{
68+
var v struct {
69+
Int uint
70+
String string
71+
Bytes []byte
72+
}
73+
decodeEncode(input, &v, i)
74+
i++
75+
}
76+
77+
{
78+
type Types struct {
79+
Bool bool
80+
Raw rlp.RawValue
81+
Slice []*Types
82+
Iface []interface{}
83+
}
84+
var v Types
85+
decodeEncode(input, &v, i)
86+
i++
87+
}
88+
{
89+
type AllTypes struct {
90+
Int uint
91+
String string
92+
Bytes []byte
93+
Bool bool
94+
Raw rlp.RawValue
95+
Slice []*AllTypes
96+
Array [3]*AllTypes
97+
Iface []interface{}
98+
}
99+
var v AllTypes
100+
decodeEncode(input, &v, i)
101+
i++
102+
}
103+
{
104+
decodeEncode(input, [10]byte{}, i)
105+
i++
106+
}
107+
{
108+
var v struct {
109+
Byte [10]byte
110+
Rool [10]bool
111+
}
112+
decodeEncode(input, &v, i)
113+
i++
114+
}
115+
{
116+
var h types.Header
117+
decodeEncode(input, &h, i)
118+
i++
119+
var b types.Block
120+
decodeEncode(input, &b, i)
121+
i++
122+
var t types.Transaction
123+
decodeEncode(input, &t, i)
124+
i++
125+
var txs types.Transactions
126+
decodeEncode(input, &txs, i)
127+
i++
128+
var rs types.Receipts
129+
decodeEncode(input, &rs, i)
130+
}
131+
{
132+
i++
133+
var v struct {
134+
AnIntPtr *big.Int
135+
AnInt big.Int
136+
AnU256Ptr *uint256.Int
137+
AnU256 uint256.Int
138+
NotAnU256 [4]uint64
139+
}
140+
decodeEncode(input, &v, i)
141+
}
142+
return 1
143+
}

0 commit comments

Comments
 (0)