Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bn256: added consensys/gurvy bn256 implementation #21812

Merged
merged 2 commits into from
Feb 3, 2021

Conversation

MariusVanDerWijden
Copy link
Member

@MariusVanDerWijden MariusVanDerWijden commented Nov 10, 2020

This pr adds consensys' gurvy bn256 variant into the code for differential fuzzing.
Since it is specially built with the correct parameters we don't need to vendor it.

@holiman
Copy link
Contributor

holiman commented Nov 10, 2020

For this we need to wait for Consensys/gnark-crypto#17.

It's merged

@MariusVanDerWijden
Copy link
Member Author

Well then I know what to work on next :D

@@ -2,14 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.

// +build gofuzz
//
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: add the build flags back in

@holiman
Copy link
Contributor

holiman commented Nov 10, 2020

The fuzzers only do essentially random fuzzing without structure which means ~ 1 in 80 million tests produces a valid input to add or mulexp, the pairing is probably even worse

Also, it's super-picky about input -- essentially disqualifyiing everything that is not exactly the correct size. A more forgiving implementation could instead read input in chunks of required_size, and loop over the chunks. Don't know many cases are discarded for the reason over being 'too large', but might be a couple

@holiman
Copy link
Contributor

holiman commented Nov 10, 2020

Maybe let's do something like this too:

diff --git a/crypto/bn256/bn256_fuzz.go b/crypto/bn256/bn256_fuzz.go
index 6aa1421170..dda80ff149 100644
--- a/crypto/bn256/bn256_fuzz.go
+++ b/crypto/bn256/bn256_fuzz.go
@@ -8,42 +8,44 @@ package bn256
 
 import (
 	"bytes"
+	"fmt"
+	"io"
 	"math/big"
 
 	cloudflare "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
 	google "github.com/ethereum/go-ethereum/crypto/bn256/google"
 )
 
-// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
-func FuzzAdd(data []byte) int {
-	// Ensure we have enough data in the first place
-	if len(data) != 128 {
-		return 0
+func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1) {
+	xc, err := cloudflare.RandomG1()
+	if err != nil {
+		// insufficient input
+		return nil, nil
+	}
+	dat, err := xc.MarshalText()
+	if err != nil {
+		panic("marshalling failed")
 	}
-	// Ensure both libs can parse the first curve point
-	xc := new(cloudflare.G1)
-	_, errc := xc.Unmarshal(data[:64])
-
 	xg := new(google.G1)
-	_, errg := xg.Unmarshal(data[:64])
-
-	if (errc == nil) != (errg == nil) {
-		panic("parse mismatch")
-	} else if errc != nil {
-		return 0
+	if _, err := xg.Unmarshal(dat); err != nil {
+		panic(fmt.Sprintf("Could not marshal couldflare -> google:", err))
 	}
-	// Ensure both libs can parse the second curve point
-	yc := new(cloudflare.G1)
-	_, errc = yc.Unmarshal(data[64:])
+	return xc, xg
 
-	yg := new(google.G1)
-	_, errg = yg.Unmarshal(data[64:])
+}
 
-	if (errc == nil) != (errg == nil) {
-		panic("parse mismatch")
-	} else if errc != nil {
+// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
+func FuzzAdd(data []byte) int {
+	input := bytes.NewReader(data)
+	xc, xg := getG1Points(input)
+	if xc == nil {
 		return 0
 	}
+	yc, yg := getG1Points(input)
+	if yc == nil {
+		return 0
+	}
+	// Ensure both libs can parse the second curve point
 	// Add the two points and ensure they result in the same output
 	rc := new(cloudflare.G1)
 	rc.Add(xc, yc)

@holiman
Copy link
Contributor

holiman commented Nov 10, 2020

Or let me make an alternative PR about that first... ?

@MariusVanDerWijden
Copy link
Member Author

I think that should be an alternative pr @holiman (that could get merged in first)
Gurvy is still pretty rough around the edges so I think we should give it another month or two before putting it in

@holiman
Copy link
Contributor

holiman commented Nov 10, 2020

#21815

@gbotrel
Copy link
Contributor

gbotrel commented Dec 10, 2020

@MariusVanDerWijden hi :) . gurvy on develop should be 100% compatible with google and cloudflare implementations, including subgroup checks during deserialization.

We're making a pass on the pairing APIs so that they are easily compatible with the EVM precompiles . Then we will merge in master and ping you (in few days).

@MariusVanDerWijden
Copy link
Member Author

Perfect! thank you very much @gbotrel

@MariusVanDerWijden
Copy link
Member Author

One problem we currently face is that gurvy uses go-ethereum internally creating a dependency cycle which is technically not problematic. However it results in gurvy pulling in 116 additional dependencies. gurvy uses the go-ethereum packages crypto/bn256/cloudflare and crypto/bn256/google to test against in bn256/interop_test.go

@DGKSK8LIFE
Copy link

Hmm. Sounds like this is inherent to Gurvy, right? So seems like there's nothing you can really do here? @MariusVanDerWijden

@gbotrel
Copy link
Contributor

gbotrel commented Jan 4, 2021

@MariusVanDerWijden this issue should be fixed, using gurvy@v0.3.7 should work, let me know if you have other issues, happy to help.

@holiman
Copy link
Contributor

holiman commented Jan 25, 2021

@MariusVanDerWijden is this still WIP or good to go?

@MariusVanDerWijden
Copy link
Member Author

I think its good to go, will rebase once more

@MariusVanDerWijden MariusVanDerWijden changed the title WIP: bn256: added gurvy variant bn256: added consensys/gurvy bn256 implementation Jan 25, 2021
@gbotrel
Copy link
Contributor

gbotrel commented Feb 1, 2021

@MariusVanDerWijden can you make gurvy point to v0.3.8 in the go.mod? @yelhousni merged some algorithmic / performance improvement to the pairing (& multi-pairing) (+ benchmarks )

Cheers,

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but please look into the go.mod changes

go.mod Outdated
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498
github.com/edsrzf/mmap-go v1.0.0
github.com/fatih/color v1.3.0
github.com/fatih/color v1.7.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are probably not actual changes related to this pr, are they? Might need a rebase ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's super weird, whenever I run go test ./... it just updates the go-mod with some unrelated changes. I removed them now by hand

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants