@@ -151,17 +151,34 @@ func FuzzPair(data []byte) int {
151
151
}
152
152
153
153
// Pair the two points and ensure they result in the same output
154
- clPair := cloudflare .Pair (pc , tc ).Marshal ()
154
+ clPair := cloudflare .Pair (pc , tc ).Marshal () // e_cloudflare(P, Q)
155
155
gPair := google .Pair (pg , tg ).Marshal ()
156
156
if ! bytes .Equal (clPair , gPair ) {
157
157
panic ("pairing mismatch: cloudflare/google" )
158
158
}
159
-
160
- cPair , err := bn254 .Pair ([]bn254.G1Affine {* ps }, []bn254.G2Affine {* ts })
159
+ cPair , err := bn254 .Pair ([]bn254.G1Affine {* ps }, []bn254.G2Affine {* ts }) // e_gnark(-P, Q)
161
160
if err != nil {
162
161
panic (fmt .Sprintf ("gnark/bn254 encountered error: %v" , err ))
163
162
}
164
- if ! bytes .Equal (clPair , cPair .Marshal ()) {
163
+
164
+ // gnark uses a different pairing algorithm which might produce
165
+ // different but also correct outputs, we need to scale the output by s
166
+
167
+ u , _ := new (big.Int ).SetString ("0x44e992b44a6909f1" , 0 )
168
+ u_exp2 := new (big.Int ).Exp (u , big .NewInt (2 ), nil ) // u^2
169
+ u_6_exp2 := new (big.Int ).Mul (big .NewInt (6 ), u_exp2 ) // 6*u^2
170
+ u_3 := new (big.Int ).Mul (big .NewInt (3 ), u ) // 3*u
171
+ inner := u_6_exp2 .Add (u_6_exp2 , u_3 ) // 6*u^2 + 3*u
172
+ inner .Add (inner , big .NewInt (1 )) // 6*u^2 + 3*u + 1
173
+ u_2 := new (big.Int ).Mul (big .NewInt (2 ), u ) // 2*u
174
+ s := u_2 .Mul (u_2 , inner ) // 2*u(6*u^2 + 3*u + 1)
175
+
176
+ gRes := new (bn254.GT )
177
+ if err := gRes .SetBytes (clPair ); err != nil {
178
+ panic (err )
179
+ }
180
+ gRes = gRes .Exp (* gRes , s )
181
+ if ! bytes .Equal (cPair .Marshal (), gRes .Marshal ()) {
165
182
panic ("pairing mismatch: cloudflare/gnark" )
166
183
}
167
184
0 commit comments