@@ -22,12 +22,12 @@ import (
22
22
"io"
23
23
"math/big"
24
24
25
- "github.com/consensys/gnark-crypto/ecc/bn254"
26
25
cloudflare "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
26
+ gnark "github.com/ethereum/go-ethereum/crypto/bn256/gnark"
27
27
google "github.com/ethereum/go-ethereum/crypto/bn256/google"
28
28
)
29
29
30
- func getG1Points (input io.Reader ) (* cloudflare.G1 , * google.G1 , * bn254. G1Affine ) {
30
+ func getG1Points (input io.Reader ) (* cloudflare.G1 , * google.G1 , * gnark. G1 ) {
31
31
_ , xc , err := cloudflare .RandomG1 (input )
32
32
if err != nil {
33
33
// insufficient input
@@ -37,14 +37,14 @@ func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1, *bn254.G1Affine)
37
37
if _ , err := xg .Unmarshal (xc .Marshal ()); err != nil {
38
38
panic (fmt .Sprintf ("Could not marshal cloudflare -> google: %v" , err ))
39
39
}
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 {
42
42
panic (fmt .Sprintf ("Could not marshal cloudflare -> gnark: %v" , err ))
43
43
}
44
44
return xc , xg , xs
45
45
}
46
46
47
- func getG2Points (input io.Reader ) (* cloudflare.G2 , * google.G2 , * bn254. G2Affine ) {
47
+ func getG2Points (input io.Reader ) (* cloudflare.G2 , * google.G2 , * gnark. G2 ) {
48
48
_ , xc , err := cloudflare .RandomG2 (input )
49
49
if err != nil {
50
50
// insufficient input
@@ -54,14 +54,14 @@ func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine)
54
54
if _ , err := xg .Unmarshal (xc .Marshal ()); err != nil {
55
55
panic (fmt .Sprintf ("Could not marshal cloudflare -> google: %v" , err ))
56
56
}
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 {
59
59
panic (fmt .Sprintf ("Could not marshal cloudflare -> gnark: %v" , err ))
60
60
}
61
61
return xc , xg , xs
62
62
}
63
63
64
- // fuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
64
+ // fuzzAdd fuzzes bn256 addition between the Google, Cloudflare and Gnark libraries.
65
65
func fuzzAdd (data []byte ) int {
66
66
input := bytes .NewReader (data )
67
67
xc , xg , xs := getG1Points (input )
@@ -72,17 +72,16 @@ func fuzzAdd(data []byte) int {
72
72
if yc == nil {
73
73
return 0
74
74
}
75
- // Ensure both libs can parse the second curve point
75
+ // Ensure libs can parse the second curve point
76
76
// Add the two points and ensure they result in the same output
77
77
rc := new (cloudflare.G1 )
78
78
rc .Add (xc , yc )
79
79
80
80
rg := new (google.G1 )
81
81
rg .Add (xg , yg )
82
82
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 )
86
85
87
86
if ! bytes .Equal (rc .Marshal (), rg .Marshal ()) {
88
87
panic ("add mismatch: cloudflare/google" )
@@ -94,8 +93,8 @@ func fuzzAdd(data []byte) int {
94
93
return 1
95
94
}
96
95
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.
99
98
func fuzzMul (data []byte ) int {
100
99
input := bytes .NewReader (data )
101
100
pc , pg , ps := getG1Points (input )
@@ -122,15 +121,13 @@ func fuzzMul(data []byte) int {
122
121
rg := new (google.G1 )
123
122
rg .ScalarMult (pg , new (big.Int ).SetBytes (buf ))
124
123
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 ))
129
126
130
127
if ! bytes .Equal (rc .Marshal (), rg .Marshal ()) {
131
128
panic ("scalar mul mismatch: cloudflare/google" )
132
129
}
133
- if ! bytes .Equal (rc .Marshal (), rsAffine .Marshal ()) {
130
+ if ! bytes .Equal (rc .Marshal (), rs .Marshal ()) {
134
131
panic ("scalar mul mismatch: cloudflare/gnark" )
135
132
}
136
133
return 1
@@ -150,17 +147,26 @@ func fuzzPair(data []byte) int {
150
147
// Pair the two points and ensure they result in the same output
151
148
clPair := cloudflare .Pair (pc , tc ).Marshal ()
152
149
gPair := google .Pair (pg , tg ).Marshal ()
150
+ sPair := gnark .Pair (ps , ts ).Marshal ()
151
+
153
152
if ! bytes .Equal (clPair , gPair ) {
154
153
panic ("pairing mismatch: cloudflare/google" )
155
154
}
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" )
159
159
}
160
160
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
+ }
163
163
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)
164
170
u , _ := new (big.Int ).SetString ("0x44e992b44a6909f1" , 0 )
165
171
u_exp2 := new (big.Int ).Exp (u , big .NewInt (2 ), nil ) // u^2
166
172
u_6_exp2 := new (big.Int ).Mul (big .NewInt (6 ), u_exp2 ) // 6*u^2
@@ -170,14 +176,12 @@ func fuzzPair(data []byte) int {
170
176
u_2 := new (big.Int ).Mul (big .NewInt (2 ), u ) // 2*u
171
177
s := u_2 .Mul (u_2 , inner ) // 2*u(6*u^2 + 3*u + 1)
172
178
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 {
175
182
panic (err )
176
183
}
177
184
gRes = gRes .Exp (* gRes , s )
178
- if ! bytes .Equal (cPair .Marshal (), gRes .Marshal ()) {
179
- panic ("pairing mismatch: cloudflare/gnark" )
180
- }
181
185
182
- return 1
186
+ return gRes
183
187
}
0 commit comments