test/fuzzers: merge test/fuzz-stuff, small polishes

tests/fuzzers: simplify runtime-test
This commit is contained in:
Martin Holst Swende 2023-10-18 09:13:47 +02:00
parent a441e304d9
commit 50e9d7a312
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
7 changed files with 97 additions and 156 deletions

View file

@ -1,55 +0,0 @@
package blake2b
import (
"encoding/binary"
)
func fuzz(data []byte) int {
// Make sure the data confirms to the input model
if len(data) != 211 {
return 0
}
// 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")
}
return 1
}

View file

@ -1,17 +1,12 @@
package blake2b package blake2b
import ( import (
"encoding/binary"
"fmt" "fmt"
"reflect" "reflect"
"testing" "testing"
) )
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
func TestF(t *testing.T) { func TestF(t *testing.T) {
for i, test := range testVectorsF { for i, test := range testVectorsF {
t.Run(fmt.Sprintf("test vector %v", i), func(t *testing.T) { t.Run(fmt.Sprintf("test vector %v", i), func(t *testing.T) {
@ -63,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")
}
}

View file

@ -22,7 +22,7 @@ import (
"github.com/ethereum/go-ethereum/common/bitutil" "github.com/ethereum/go-ethereum/common/bitutil"
) )
// Fuzz implements a go-fuzz fuzzer method to test various encoding method // FuzzBitutil implements a go-fuzz fuzzer method to test various encoding method
// invocations. // invocations.
func FuzzBitutil(data []byte) int { func FuzzBitutil(data []byte) int {
if len(data) == 0 { if len(data) == 0 {

View file

@ -1,36 +0,0 @@
// Copyright 2017 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 runtime
import (
"github.com/ethereum/go-ethereum/core/vm/runtime"
)
// Fuzz is the basic entry point for the go-fuzz tool
//
// This returns 1 for valid parse:able/runnable code, 0
// for invalid opcode.
func fuzz(input []byte) int {
_, _, err := runtime.Execute(input, input, &runtime.Config{
GasLimit: 12000000,
})
// invalid opcode
if err != nil && len(err.Error()) > 6 && err.Error()[:7] == "invalid" {
return 0
}
return 1
}

View file

@ -16,10 +16,16 @@
package runtime package runtime
import "testing" import (
"testing"
"github.com/ethereum/go-ethereum/core/vm/runtime"
)
func Fuzz(f *testing.F) { func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) { f.Fuzz(func(t *testing.T, code, input []byte) {
fuzz(data) runtime.Execute(code, input, &runtime.Config{
GasLimit: 12000000,
})
}) })
} }

View file

@ -1,50 +0,0 @@
// Copyright 2021 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/>.
// build +gofuzz
package secp256k1
import (
"fmt"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
gofuzz "github.com/google/gofuzz"
)
func fuzz(input []byte) int {
var (
fuzzer = gofuzz.NewFromGoFuzz(input)
curveA = secp256k1.S256()
curveB = btcec.S256()
dataP1 []byte
dataP2 []byte
)
// first point
fuzzer.Fuzz(&dataP1)
x1, y1 := curveB.ScalarBaseMult(dataP1)
// second point
fuzzer.Fuzz(&dataP2)
x2, y2 := curveB.ScalarBaseMult(dataP2)
resAX, resAY := curveA.Add(x1, y1, x2, y2)
resBX, resBY := curveB.Add(x1, y1, x2, y2)
if resAX.Cmp(resBX) != 0 || resAY.Cmp(resBY) != 0 {
fmt.Printf("%s %s %s %s\n", x1, y1, x2, y2)
panic(fmt.Sprintf("Addition failed: geth: %s %s btcd: %s %s", resAX, resAY, resBX, resBY))
}
return 0
}

View file

@ -16,15 +16,39 @@
package secp256k1 package secp256k1
import "testing" import (
"fmt"
"testing"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
)
func TestFuzzer(t *testing.T) { func TestFuzzer(t *testing.T) {
test := "00000000N0000000/R00000000000000000U0000S0000000mkhP000000000000000U" a, b := "00000000N0000000/R0000000000000000", "0U0000S0000000mkhP000000000000000U"
fuzz([]byte(test)) fuzz([]byte(a), []byte(b))
} }
func Fuzz(f *testing.F) { func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) { f.Fuzz(func(t *testing.T, a, b []byte) {
fuzz(data) fuzz(a, b)
}) })
} }
func fuzz(dataP1, dataP2 []byte) int {
var (
curveA = secp256k1.S256()
curveB = btcec.S256()
)
// first point
x1, y1 := curveB.ScalarBaseMult(dataP1)
// second points
x2, y2 := curveB.ScalarBaseMult(dataP2)
resAX, resAY := curveA.Add(x1, y1, x2, y2)
resBX, resBY := curveB.Add(x1, y1, x2, y2)
if resAX.Cmp(resBX) != 0 || resAY.Cmp(resBY) != 0 {
fmt.Printf("%s %s %s %s\n", x1, y1, x2, y2)
panic(fmt.Sprintf("Addition failed: geth: %s %s btcd: %s %s", resAX, resAY, resBX, resBY))
}
return 0
}