github.com/cloudflare/circl@v1.5.0/math/fp448/fuzzer.go (about)

     1  //go:build gofuzz
     2  // +build gofuzz
     3  
     4  // How to run the fuzzer:
     5  //
     6  //	$ go get -u github.com/dvyukov/go-fuzz/go-fuzz
     7  //	$ go get -u github.com/dvyukov/go-fuzz/go-fuzz-build
     8  //	$ go-fuzz-build -libfuzzer -func FuzzReduction -o lib.a
     9  //	$ clang -fsanitize=fuzzer lib.a -o fu.exe
    10  //	$ ./fu.exe
    11  package fp448
    12  
    13  import (
    14  	"encoding/binary"
    15  	"fmt"
    16  	"math/big"
    17  
    18  	"github.com/cloudflare/circl/internal/conv"
    19  )
    20  
    21  // FuzzReduction is a fuzzer target for red64 function, which reduces t
    22  // (112 bits) to a number t' (56 bits) congruent modulo p448.
    23  func FuzzReduction(data []byte) int {
    24  	if len(data) != 2*Size {
    25  		return -1
    26  	}
    27  	var got, want Elt
    28  	var lo, hi [7]uint64
    29  	a := data[:Size]
    30  	b := data[Size:]
    31  	lo[0] = binary.LittleEndian.Uint64(a[0*8 : 1*8])
    32  	lo[1] = binary.LittleEndian.Uint64(a[1*8 : 2*8])
    33  	lo[2] = binary.LittleEndian.Uint64(a[2*8 : 3*8])
    34  	lo[3] = binary.LittleEndian.Uint64(a[3*8 : 4*8])
    35  	lo[4] = binary.LittleEndian.Uint64(a[4*8 : 5*8])
    36  	lo[5] = binary.LittleEndian.Uint64(a[5*8 : 6*8])
    37  	lo[6] = binary.LittleEndian.Uint64(a[6*8 : 7*8])
    38  
    39  	hi[0] = binary.LittleEndian.Uint64(b[0*8 : 1*8])
    40  	hi[1] = binary.LittleEndian.Uint64(b[1*8 : 2*8])
    41  	hi[2] = binary.LittleEndian.Uint64(b[2*8 : 3*8])
    42  	hi[3] = binary.LittleEndian.Uint64(b[3*8 : 4*8])
    43  	hi[4] = binary.LittleEndian.Uint64(b[4*8 : 5*8])
    44  	hi[5] = binary.LittleEndian.Uint64(b[5*8 : 6*8])
    45  	hi[6] = binary.LittleEndian.Uint64(b[6*8 : 7*8])
    46  
    47  	red64(&got, &lo, &hi)
    48  
    49  	t := conv.BytesLe2BigInt(data[:2*Size])
    50  
    51  	two448 := big.NewInt(1)
    52  	two448.Lsh(two448, 448) // 2^448
    53  	mask448 := big.NewInt(1)
    54  	mask448.Sub(two448, mask448) // 2^448-1
    55  	two224plus1 := big.NewInt(1)
    56  	two224plus1.Lsh(two224plus1, 224)
    57  	two224plus1.Add(two224plus1, big.NewInt(1)) // 2^224+1
    58  
    59  	var loBig, hiBig big.Int
    60  	for t.Cmp(two448) >= 0 {
    61  		loBig.And(t, mask448)
    62  		hiBig.Rsh(t, 448)
    63  		t.Mul(&hiBig, two224plus1)
    64  		t.Add(t, &loBig)
    65  	}
    66  	conv.BigInt2BytesLe(want[:], t)
    67  
    68  	if got != want {
    69  		fmt.Printf("in:   %v\n", conv.BytesLe2BigInt(data[:2*Size]))
    70  		fmt.Printf("got:  %v\n", got)
    71  		fmt.Printf("want: %v\n", want)
    72  		panic("error found")
    73  	}
    74  	return 1
    75  }