@@ -22,12 +22,12 @@ import (
2222 "io"
2323 "math/big"
2424
25- "github.com/consensys/gnark-crypto/ecc/bn254"
2625 cloudflare "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
26+ gnark "github.com/ethereum/go-ethereum/crypto/bn256/gnark"
2727 google "github.com/ethereum/go-ethereum/crypto/bn256/google"
2828)
2929
30- func getG1Points (input io.Reader ) (* cloudflare.G1 , * google.G1 , * bn254. G1Affine ) {
30+ func getG1Points (input io.Reader ) (* cloudflare.G1 , * google.G1 , * gnark. G1 ) {
3131 _ , xc , err := cloudflare .RandomG1 (input )
3232 if err != nil {
3333 // insufficient input
@@ -37,14 +37,14 @@ func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1, *bn254.G1Affine)
3737 if _ , err := xg .Unmarshal (xc .Marshal ()); err != nil {
3838 panic (fmt .Sprintf ("Could not marshal cloudflare -> google: %v" , err ))
3939 }
40- xs := new (bn254. G1Affine )
41- if err := xs .Unmarshal (xc .Marshal ()); err != nil {
40+ xs := new (gnark. G1 )
41+ if _ , err := xs .Unmarshal (xc .Marshal ()); err != nil {
4242 panic (fmt .Sprintf ("Could not marshal cloudflare -> gnark: %v" , err ))
4343 }
4444 return xc , xg , xs
4545}
4646
47- func getG2Points (input io.Reader ) (* cloudflare.G2 , * google.G2 , * bn254. G2Affine ) {
47+ func getG2Points (input io.Reader ) (* cloudflare.G2 , * google.G2 , * gnark. G2 ) {
4848 _ , xc , err := cloudflare .RandomG2 (input )
4949 if err != nil {
5050 // insufficient input
@@ -54,14 +54,14 @@ func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine)
5454 if _ , err := xg .Unmarshal (xc .Marshal ()); err != nil {
5555 panic (fmt .Sprintf ("Could not marshal cloudflare -> google: %v" , err ))
5656 }
57- xs := new (bn254. G2Affine )
58- if err := xs .Unmarshal (xc .Marshal ()); err != nil {
57+ xs := new (gnark. G2 )
58+ if _ , err := xs .Unmarshal (xc .Marshal ()); err != nil {
5959 panic (fmt .Sprintf ("Could not marshal cloudflare -> gnark: %v" , err ))
6060 }
6161 return xc , xg , xs
6262}
6363
64- // fuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
64+ // fuzzAdd fuzzes bn256 addition between the Google, Cloudflare and Gnark libraries.
6565func fuzzAdd (data []byte ) int {
6666 input := bytes .NewReader (data )
6767 xc , xg , xs := getG1Points (input )
@@ -72,17 +72,16 @@ func fuzzAdd(data []byte) int {
7272 if yc == nil {
7373 return 0
7474 }
75- // Ensure both libs can parse the second curve point
75+ // Ensure libs can parse the second curve point
7676 // Add the two points and ensure they result in the same output
7777 rc := new (cloudflare.G1 )
7878 rc .Add (xc , yc )
7979
8080 rg := new (google.G1 )
8181 rg .Add (xg , yg )
8282
83- tmpX := new (bn254.G1Jac ).FromAffine (xs )
84- tmpY := new (bn254.G1Jac ).FromAffine (ys )
85- rs := new (bn254.G1Affine ).FromJacobian (tmpX .AddAssign (tmpY ))
83+ rs := new (gnark.G1 )
84+ rs .Add (xs , ys )
8685
8786 if ! bytes .Equal (rc .Marshal (), rg .Marshal ()) {
8887 panic ("add mismatch: cloudflare/google" )
@@ -94,8 +93,8 @@ func fuzzAdd(data []byte) int {
9493 return 1
9594}
9695
97- // fuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
98- // libraries.
96+ // fuzzMul fuzzes bn256 scalar multiplication between the Google, Cloudflare
97+ // and Gnark libraries.
9998func fuzzMul (data []byte ) int {
10099 input := bytes .NewReader (data )
101100 pc , pg , ps := getG1Points (input )
@@ -122,15 +121,13 @@ func fuzzMul(data []byte) int {
122121 rg := new (google.G1 )
123122 rg .ScalarMult (pg , new (big.Int ).SetBytes (buf ))
124123
125- rs := new (bn254.G1Jac )
126- psJac := new (bn254.G1Jac ).FromAffine (ps )
127- rs .ScalarMultiplication (psJac , new (big.Int ).SetBytes (buf ))
128- rsAffine := new (bn254.G1Affine ).FromJacobian (rs )
124+ rs := new (gnark.G1 )
125+ rs .ScalarMult (ps , new (big.Int ).SetBytes (buf ))
129126
130127 if ! bytes .Equal (rc .Marshal (), rg .Marshal ()) {
131128 panic ("scalar mul mismatch: cloudflare/google" )
132129 }
133- if ! bytes .Equal (rc .Marshal (), rsAffine .Marshal ()) {
130+ if ! bytes .Equal (rc .Marshal (), rs .Marshal ()) {
134131 panic ("scalar mul mismatch: cloudflare/gnark" )
135132 }
136133 return 1
@@ -150,17 +147,26 @@ func fuzzPair(data []byte) int {
150147 // Pair the two points and ensure they result in the same output
151148 clPair := cloudflare .Pair (pc , tc ).Marshal ()
152149 gPair := google .Pair (pg , tg ).Marshal ()
150+ sPair := gnark .Pair (ps , ts ).Marshal ()
151+
153152 if ! bytes .Equal (clPair , gPair ) {
154153 panic ("pairing mismatch: cloudflare/google" )
155154 }
156- cPair , err := bn254 .Pair ([]bn254.G1Affine {* ps }, []bn254.G2Affine {* ts })
157- if err != nil {
158- panic (fmt .Sprintf ("gnark/bn254 encountered error: %v" , err ))
155+
156+ normalizedClPair := normalizeGTToGnark (clPair ).Marshal ()
157+ if ! bytes .Equal (normalizedClPair , sPair ) {
158+ panic ("pairing mismatch: cloudflare/gnark" )
159159 }
160160
161- // gnark uses a different pairing algorithm which might produce
162- // different but also correct outputs, we need to scale the output by s
161+ return 1
162+ }
163163
164+ // normalizeGTToGnark scales a Cloudflare/Google GT element by `s`
165+ // so that it can be compared with a gnark GT point.
166+ //
167+ // For the definition of `s` see 3.5 in https://eprint.iacr.org/2015/192.pdf
168+ func normalizeGTToGnark (cloudflareOrGoogleGT []byte ) * gnark.GT {
169+ // Compute s = 2*u(6*u^2 + 3*u + 1)
164170 u , _ := new (big.Int ).SetString ("0x44e992b44a6909f1" , 0 )
165171 u_exp2 := new (big.Int ).Exp (u , big .NewInt (2 ), nil ) // u^2
166172 u_6_exp2 := new (big.Int ).Mul (big .NewInt (6 ), u_exp2 ) // 6*u^2
@@ -170,14 +176,12 @@ func fuzzPair(data []byte) int {
170176 u_2 := new (big.Int ).Mul (big .NewInt (2 ), u ) // 2*u
171177 s := u_2 .Mul (u_2 , inner ) // 2*u(6*u^2 + 3*u + 1)
172178
173- gRes := new (bn254.GT )
174- if err := gRes .SetBytes (clPair ); err != nil {
179+ // Scale the Cloudflare/Google GT element by `s`
180+ gRes := new (gnark.GT )
181+ if err := gRes .Unmarshal (cloudflareOrGoogleGT ); err != nil {
175182 panic (err )
176183 }
177184 gRes = gRes .Exp (* gRes , s )
178- if ! bytes .Equal (cPair .Marshal (), gRes .Marshal ()) {
179- panic ("pairing mismatch: cloudflare/gnark" )
180- }
181185
182- return 1
186+ return gRes
183187}
0 commit comments