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