133
vendor/github.com/holiman/uint256/fuzz.go
generated
vendored
Normal file
133
vendor/github.com/holiman/uint256/fuzz.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// uint256: Fixed size 256-bit math library
|
||||
// Copyright 2020 uint256 Authors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// +build gofuzz
|
||||
|
||||
package uint256
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
opUdivrem = 0
|
||||
opMul = 1
|
||||
opLsh = 2
|
||||
opAdd = 4
|
||||
opSub = 5
|
||||
)
|
||||
|
||||
type opFunc func(*Int, *Int, *Int) *Int
|
||||
type bigFunc func(*big.Int, *big.Int, *big.Int) *big.Int
|
||||
|
||||
func crash(op opFunc, x, y Int, msg string) {
|
||||
fn := runtime.FuncForPC(reflect.ValueOf(op).Pointer())
|
||||
fnName := fn.Name()
|
||||
fnFile, fnLine := fn.FileLine(fn.Entry())
|
||||
panic(fmt.Sprintf("%s\nfor %s (%s:%d)\nx: %x\ny: %x", msg, fnName, fnFile, fnLine, &x, &y))
|
||||
}
|
||||
|
||||
func checkOp(op opFunc, bigOp bigFunc, x, y Int) {
|
||||
origX := x
|
||||
origY := y
|
||||
|
||||
var result Int
|
||||
ret := op(&result, &x, &y)
|
||||
if ret != &result {
|
||||
crash(op, x, y, "returned not the pointer receiver")
|
||||
}
|
||||
if x != origX {
|
||||
crash(op, x, y, "first argument modified")
|
||||
}
|
||||
if y != origY {
|
||||
crash(op, x, y, "second argument modified")
|
||||
}
|
||||
|
||||
expected, _ := FromBig(bigOp(new(big.Int), x.ToBig(), y.ToBig()))
|
||||
if result != *expected {
|
||||
crash(op, x, y, "unexpected result")
|
||||
}
|
||||
|
||||
// Test again when the receiver is not zero.
|
||||
var garbage Int
|
||||
garbage.Xor(&x, &y)
|
||||
ret = op(&garbage, &x, &y)
|
||||
if ret != &garbage {
|
||||
crash(op, x, y, "returned not the pointer receiver")
|
||||
}
|
||||
if garbage != *expected {
|
||||
crash(op, x, y, "unexpected result")
|
||||
}
|
||||
if x != origX {
|
||||
crash(op, x, y, "first argument modified")
|
||||
}
|
||||
if y != origY {
|
||||
crash(op, x, y, "second argument modified")
|
||||
}
|
||||
|
||||
// Test again with the receiver aliasing arguments.
|
||||
ret = op(&x, &x, &y)
|
||||
if ret != &x {
|
||||
crash(op, x, y, "returned not the pointer receiver")
|
||||
}
|
||||
if x != *expected {
|
||||
crash(op, x, y, "unexpected result")
|
||||
}
|
||||
|
||||
ret = op(&y, &origX, &y)
|
||||
if ret != &y {
|
||||
crash(op, x, y, "returned not the pointer receiver")
|
||||
}
|
||||
if y != *expected {
|
||||
crash(op, x, y, "unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
if len(data) != 65 {
|
||||
return 0
|
||||
}
|
||||
|
||||
op := data[0]
|
||||
|
||||
var x, y Int
|
||||
x.SetBytes(data[1:33])
|
||||
y.SetBytes(data[33:])
|
||||
|
||||
switch op {
|
||||
case opUdivrem:
|
||||
if y.IsZero() {
|
||||
return 0
|
||||
}
|
||||
checkOp((*Int).Div, (*big.Int).Div, x, y)
|
||||
checkOp((*Int).Mod, (*big.Int).Mod, x, y)
|
||||
|
||||
case opMul:
|
||||
checkOp((*Int).Mul, (*big.Int).Mul, x, y)
|
||||
|
||||
case opLsh:
|
||||
lsh := func(z, x, y *Int) *Int {
|
||||
return z.Lsh(x, uint(y[0]))
|
||||
}
|
||||
bigLsh := func(z, x, y *big.Int) *big.Int {
|
||||
n := uint(y.Uint64())
|
||||
if n > 256 {
|
||||
n = 256
|
||||
}
|
||||
return z.Lsh(x, n)
|
||||
}
|
||||
checkOp(lsh, bigLsh, x, y)
|
||||
|
||||
case opAdd:
|
||||
checkOp((*Int).Add, (*big.Int).Add, x, y)
|
||||
|
||||
case opSub:
|
||||
checkOp((*Int).Sub, (*big.Int).Sub, x, y)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user