github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/crypto/bn256/bn256_fuzz.go (about)

     1  // Copyright 2018 Péter Szilágyi. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license that can be found
     3  // in the LICENSE file.
     4  
     5  // +build gofuzz
     6  
     7  package bn256
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"io"
    13  	"math/big"
    14  
    15  	cloudflare "github.com/kisexp/xdchain/crypto/bn256/cloudflare"
    16  	google "github.com/kisexp/xdchain/crypto/bn256/google"
    17  )
    18  
    19  func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1) {
    20  	_, xc, err := cloudflare.RandomG1(input)
    21  	if err != nil {
    22  		// insufficient input
    23  		return nil, nil
    24  	}
    25  	xg := new(google.G1)
    26  	if _, err := xg.Unmarshal(xc.Marshal()); err != nil {
    27  		panic(fmt.Sprintf("Could not marshal cloudflare -> google:", err))
    28  	}
    29  	return xc, xg
    30  }
    31  
    32  func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2) {
    33  	_, xc, err := cloudflare.RandomG2(input)
    34  	if err != nil {
    35  		// insufficient input
    36  		return nil, nil
    37  	}
    38  	xg := new(google.G2)
    39  	if _, err := xg.Unmarshal(xc.Marshal()); err != nil {
    40  		panic(fmt.Sprintf("Could not marshal cloudflare -> google:", err))
    41  	}
    42  	return xc, xg
    43  }
    44  
    45  // FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
    46  func FuzzAdd(data []byte) int {
    47  	input := bytes.NewReader(data)
    48  	xc, xg := getG1Points(input)
    49  	if xc == nil {
    50  		return 0
    51  	}
    52  	yc, yg := getG1Points(input)
    53  	if yc == nil {
    54  		return 0
    55  	}
    56  	// Ensure both libs can parse the second curve point
    57  	// Add the two points and ensure they result in the same output
    58  	rc := new(cloudflare.G1)
    59  	rc.Add(xc, yc)
    60  
    61  	rg := new(google.G1)
    62  	rg.Add(xg, yg)
    63  
    64  	if !bytes.Equal(rc.Marshal(), rg.Marshal()) {
    65  		panic("add mismatch")
    66  	}
    67  	return 1
    68  }
    69  
    70  // FuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
    71  // libraries.
    72  func FuzzMul(data []byte) int {
    73  	input := bytes.NewReader(data)
    74  	pc, pg := getG1Points(input)
    75  	if pc == nil {
    76  		return 0
    77  	}
    78  	// Add the two points and ensure they result in the same output
    79  	remaining := input.Len()
    80  	if remaining == 0 {
    81  		return 0
    82  	}
    83  	if remaining > 128 {
    84  		// The evm only ever uses 32 byte integers, we need to cap this otherwise
    85  		// we run into slow exec. A 236Kb byte integer cause oss-fuzz to report it as slow.
    86  		// 128 bytes should be fine though
    87  		return 0
    88  	}
    89  	buf := make([]byte, remaining)
    90  	input.Read(buf)
    91  
    92  	rc := new(cloudflare.G1)
    93  	rc.ScalarMult(pc, new(big.Int).SetBytes(buf))
    94  
    95  	rg := new(google.G1)
    96  	rg.ScalarMult(pg, new(big.Int).SetBytes(buf))
    97  
    98  	if !bytes.Equal(rc.Marshal(), rg.Marshal()) {
    99  		panic("scalar mul mismatch")
   100  	}
   101  	return 1
   102  }
   103  
   104  func FuzzPair(data []byte) int {
   105  	input := bytes.NewReader(data)
   106  	pc, pg := getG1Points(input)
   107  	if pc == nil {
   108  		return 0
   109  	}
   110  	tc, tg := getG2Points(input)
   111  	if tc == nil {
   112  		return 0
   113  	}
   114  	// Pair the two points and ensure thet result in the same output
   115  	if cloudflare.PairingCheck([]*cloudflare.G1{pc}, []*cloudflare.G2{tc}) != google.PairingCheck([]*google.G1{pg}, []*google.G2{tg}) {
   116  		panic("pair mismatch")
   117  	}
   118  	return 1
   119  }