Skip to content

Commit

Permalink
crypto, tests: update fuzzers to native go fuzzing (ethereum#28352)
Browse files Browse the repository at this point in the history
  • Loading branch information
gzliudan committed Dec 9, 2024
1 parent 8f57d6c commit f7b6ad6
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 147 deletions.
59 changes: 0 additions & 59 deletions crypto/blake2b/blake2b_f_fuzz.go

This file was deleted.

58 changes: 58 additions & 0 deletions crypto/blake2b/blake2b_f_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package blake2b

import (
"encoding/binary"
"fmt"
"reflect"
"testing"
Expand Down Expand Up @@ -57,3 +58,60 @@ var testVectorsF = []testVector{
},
},
}

func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}

func fuzz(data []byte) {
// Make sure the data confirms to the input model
if len(data) != 211 {
return
}
// Parse everything and call all the implementations
var (
rounds = binary.BigEndian.Uint16(data[0:2])

h [8]uint64
m [16]uint64
t [2]uint64
f uint64
)

for i := 0; i < 8; i++ {
offset := 2 + i*8
h[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
}
for i := 0; i < 16; i++ {
offset := 66 + i*8
m[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
}
t[0] = binary.LittleEndian.Uint64(data[194:202])
t[1] = binary.LittleEndian.Uint64(data[202:210])

if data[210]%2 == 1 { // Avoid spinning the fuzzer to hit 0/1
f = 0xFFFFFFFFFFFFFFFF
}

// Run the blake2b compression on all instruction sets and cross reference
want := h
fGeneric(&want, &m, t[0], t[1], f, uint64(rounds))

have := h
fSSE4(&have, &m, t[0], t[1], f, uint64(rounds))
if have != want {
panic("SSE4 mismatches generic algo")
}
have = h
fAVX(&have, &m, t[0], t[1], f, uint64(rounds))
if have != want {
panic("AVX mismatches generic algo")
}
have = h
fAVX2(&have, &m, t[0], t[1], f, uint64(rounds))
if have != want {
panic("AVX2 mismatches generic algo")
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017 The go-ethereum Authors
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
Expand All @@ -18,41 +18,51 @@ package bitutil

import (
"bytes"
"testing"

"github.com/XinFinOrg/XDPoSChain/common/bitutil"
)

// Fuzz implements a go-fuzz fuzzer method to test various encoding method
// invocations.
func Fuzz(data []byte) int {
if len(data) == 0 {
return 0
}
if data[0]%2 == 0 {
return fuzzEncode(data[1:])
}
return fuzzDecode(data[1:])
func FuzzEncoder(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzEncode(data)
})
}
func FuzzDecoder(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzDecode(data)
})
}

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

// fuzzDecode implements a go-fuzz fuzzer method to test the bit decoding and
// reencoding algorithm.
func fuzzDecode(data []byte) int {
func fuzzDecode(data []byte) {
blob, err := bitutil.DecompressBytes(data, 1024)
if err != nil {
return 0
return
}
// re-compress it (it's OK if the re-compressed differs from the
// original - the first input may not have been compressed at all)
comp := bitutil.CompressBytes(blob)
if len(comp) > len(blob) {
// After compression, it must be smaller or equal
panic("bad compression")
}
// But decompressing it once again should work
decomp, err := bitutil.DecompressBytes(data, 1024)
if err != nil {
panic(err)
}
if comp := bitutil.CompressBytes(blob); !bytes.Equal(comp, data) {
if !bytes.Equal(decomp, blob) {
panic("content mismatch")
}
return 1
}
10 changes: 5 additions & 5 deletions tests/fuzzers/bn256/bn256_fuzz.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine)
return xc, xg, xs
}

// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
func FuzzAdd(data []byte) int {
// fuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
func fuzzAdd(data []byte) int {
input := bytes.NewReader(data)
xc, xg, xs := getG1Points(input)
if xc == nil {
Expand Down Expand Up @@ -94,9 +94,9 @@ func FuzzAdd(data []byte) int {
return 1
}

// FuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
// fuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
// libraries.
func FuzzMul(data []byte) int {
func fuzzMul(data []byte) int {
input := bytes.NewReader(data)
pc, pg, ps := getG1Points(input)
if pc == nil {
Expand Down Expand Up @@ -136,7 +136,7 @@ func FuzzMul(data []byte) int {
return 1
}

func FuzzPair(data []byte) int {
func fuzzPair(data []byte) int {
input := bytes.NewReader(data)
pc, pg, ps := getG1Points(input)
if pc == nil {
Expand Down
143 changes: 143 additions & 0 deletions tests/fuzzers/rlp/rlp_fuzzer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Copyright 2019 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package rlp

import (
"bytes"
"fmt"
"math/big"

"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/rlp"
"github.com/holiman/uint256"
)

func decodeEncode(input []byte, val interface{}, i int) {
if err := rlp.DecodeBytes(input, val); err == nil {
output, err := rlp.EncodeToBytes(val)
if err != nil {
panic(err)
}
if !bytes.Equal(input, output) {
panic(fmt.Sprintf("case %d: encode-decode is not equal, \ninput : %x\noutput: %x", i, input, output))
}
}
}

func fuzz(input []byte) int {
if len(input) == 0 {
return 0
}
if len(input) > 500*1024 {
return 0
}

var i int
{
rlp.Split(input)
}
{
if elems, _, err := rlp.SplitList(input); err == nil {
rlp.CountValues(elems)
}
}

{
rlp.NewStream(bytes.NewReader(input), 0).Decode(new(interface{}))
}

{
decodeEncode(input, new(interface{}), i)
i++
}
{
var v struct {
Int uint
String string
Bytes []byte
}
decodeEncode(input, &v, i)
i++
}

{
type Types struct {
Bool bool
Raw rlp.RawValue
Slice []*Types
Iface []interface{}
}
var v Types
decodeEncode(input, &v, i)
i++
}
{
type AllTypes struct {
Int uint
String string
Bytes []byte
Bool bool
Raw rlp.RawValue
Slice []*AllTypes
Array [3]*AllTypes
Iface []interface{}
}
var v AllTypes
decodeEncode(input, &v, i)
i++
}
{
decodeEncode(input, [10]byte{}, i)
i++
}
{
var v struct {
Byte [10]byte
Rool [10]bool
}
decodeEncode(input, &v, i)
i++
}
{
var h types.Header
decodeEncode(input, &h, i)
i++
var b types.Block
decodeEncode(input, &b, i)
i++
var t types.Transaction
decodeEncode(input, &t, i)
i++
var txs types.Transactions
decodeEncode(input, &txs, i)
i++
var rs types.Receipts
decodeEncode(input, &rs, i)
}
{
i++
var v struct {
AnIntPtr *big.Int
AnInt big.Int
AnU256Ptr *uint256.Int
AnU256 uint256.Int
NotAnU256 [4]uint64
}
decodeEncode(input, &v, i)
}
return 1
}
Loading

0 comments on commit f7b6ad6

Please sign in to comment.