github.com/consensys/gnark-crypto@v0.14.0/ecc/bn254/g2_test.go (about) 1 // Copyright 2020 Consensys Software Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Code generated by consensys/gnark-crypto DO NOT EDIT 16 17 package bn254 18 19 import ( 20 "fmt" 21 "math/big" 22 "math/rand/v2" 23 "testing" 24 25 "github.com/consensys/gnark-crypto/ecc/bn254/internal/fptower" 26 27 "github.com/consensys/gnark-crypto/ecc/bn254/fr" 28 "github.com/leanovate/gopter" 29 "github.com/leanovate/gopter/prop" 30 ) 31 32 func TestG2AffineEndomorphism(t *testing.T) { 33 t.Parallel() 34 parameters := gopter.DefaultTestParameters() 35 if testing.Short() { 36 parameters.MinSuccessfulTests = nbFuzzShort 37 } else { 38 parameters.MinSuccessfulTests = nbFuzz 39 } 40 41 properties := gopter.NewProperties(parameters) 42 43 properties.Property("[BN254] check that phi(P) = lambdaGLV * P", prop.ForAll( 44 func(a fptower.E2) bool { 45 var p, res1, res2 G2Jac 46 g := MapToG2(a) 47 p.FromAffine(&g) 48 res1.phi(&p) 49 res2.mulWindowed(&p, &lambdaGLV) 50 51 return p.IsInSubGroup() && res1.Equal(&res2) 52 }, 53 GenE2(), 54 )) 55 56 properties.Property("[BN254] check that phi^2(P) + phi(P) + P = 0", prop.ForAll( 57 func(a fptower.E2) bool { 58 var p, res, tmp G2Jac 59 g := MapToG2(a) 60 p.FromAffine(&g) 61 tmp.phi(&p) 62 res.phi(&tmp). 63 AddAssign(&tmp). 64 AddAssign(&p) 65 66 return res.Z.IsZero() 67 }, 68 GenE2(), 69 )) 70 71 properties.Property("[BN254] check that psi^2(P) = -phi(P)", prop.ForAll( 72 func(a fptower.E2) bool { 73 var p, res1, res2 G2Jac 74 g := MapToG2(a) 75 p.FromAffine(&g) 76 res1.psi(&p).psi(&res1).Neg(&res1) 77 res2.phi(&p) 78 79 return p.IsInSubGroup() && res1.Equal(&res2) 80 }, 81 GenE2(), 82 )) 83 84 properties.TestingRun(t, gopter.ConsoleReporter(false)) 85 } 86 87 func TestG2AffineIsOnCurve(t *testing.T) { 88 t.Parallel() 89 parameters := gopter.DefaultTestParameters() 90 if testing.Short() { 91 parameters.MinSuccessfulTests = nbFuzzShort 92 } else { 93 parameters.MinSuccessfulTests = nbFuzz 94 } 95 96 properties := gopter.NewProperties(parameters) 97 98 properties.Property("[BN254] g2Gen (affine) should be on the curve", prop.ForAll( 99 func(a fptower.E2) bool { 100 var op1, op2 G2Affine 101 op1.FromJacobian(&g2Gen) 102 op2.Set(&op1) 103 op2.Y.Mul(&op2.Y, &a) 104 return op1.IsOnCurve() && !op2.IsOnCurve() 105 }, 106 GenE2(), 107 )) 108 109 properties.Property("[BN254] g2Gen (Jacobian) should be on the curve", prop.ForAll( 110 func(a fptower.E2) bool { 111 var op1, op2, op3 G2Jac 112 op1.Set(&g2Gen) 113 op3.Set(&g2Gen) 114 115 op2 = fuzzG2Jac(&g2Gen, a) 116 op3.Y.Mul(&op3.Y, &a) 117 return op1.IsOnCurve() && op2.IsOnCurve() && !op3.IsOnCurve() 118 }, 119 GenE2(), 120 )) 121 122 properties.Property("[BN254] IsInSubGroup and MulBy subgroup order should be the same", prop.ForAll( 123 func(a fptower.E2) bool { 124 var op1, op2 G2Jac 125 op1 = fuzzG2Jac(&g2Gen, a) 126 _r := fr.Modulus() 127 op2.ScalarMultiplication(&op1, _r) 128 return op1.IsInSubGroup() && op2.Z.IsZero() 129 }, 130 GenE2(), 131 )) 132 133 properties.TestingRun(t, gopter.ConsoleReporter(false)) 134 } 135 136 func TestG2AffineConversions(t *testing.T) { 137 t.Parallel() 138 parameters := gopter.DefaultTestParameters() 139 if testing.Short() { 140 parameters.MinSuccessfulTests = nbFuzzShort 141 } else { 142 parameters.MinSuccessfulTests = nbFuzz 143 } 144 145 properties := gopter.NewProperties(parameters) 146 147 properties.Property("[BN254] Affine representation should be independent of the Jacobian representative", prop.ForAll( 148 func(a fptower.E2) bool { 149 g := fuzzG2Jac(&g2Gen, a) 150 var op1 G2Affine 151 op1.FromJacobian(&g) 152 return op1.X.Equal(&g2Gen.X) && op1.Y.Equal(&g2Gen.Y) 153 }, 154 GenE2(), 155 )) 156 157 properties.Property("[BN254] Affine representation should be independent of a Extended Jacobian representative", prop.ForAll( 158 func(a fptower.E2) bool { 159 var g g2JacExtended 160 g.X.Set(&g2Gen.X) 161 g.Y.Set(&g2Gen.Y) 162 g.ZZ.Set(&g2Gen.Z) 163 g.ZZZ.Set(&g2Gen.Z) 164 gfuzz := fuzzg2JacExtended(&g, a) 165 166 var op1 G2Affine 167 op1.fromJacExtended(&gfuzz) 168 return op1.X.Equal(&g2Gen.X) && op1.Y.Equal(&g2Gen.Y) 169 }, 170 GenE2(), 171 )) 172 173 properties.Property("[BN254] Jacobian representation should be the same as the affine representative", prop.ForAll( 174 func(a fptower.E2) bool { 175 var g G2Jac 176 var op1 G2Affine 177 op1.X.Set(&g2Gen.X) 178 op1.Y.Set(&g2Gen.Y) 179 180 var one fptower.E2 181 one.SetOne() 182 183 g.FromAffine(&op1) 184 185 return g.X.Equal(&g2Gen.X) && g.Y.Equal(&g2Gen.Y) && g.Z.Equal(&one) 186 }, 187 GenE2(), 188 )) 189 190 properties.Property("[BN254] Converting affine symbol for infinity to Jacobian should output correct infinity in Jacobian", prop.ForAll( 191 func() bool { 192 var g G2Affine 193 g.X.SetZero() 194 g.Y.SetZero() 195 var op1 G2Jac 196 op1.FromAffine(&g) 197 var one, zero fptower.E2 198 one.SetOne() 199 return op1.X.Equal(&one) && op1.Y.Equal(&one) && op1.Z.Equal(&zero) 200 }, 201 )) 202 203 properties.Property("[BN254] Converting infinity in extended Jacobian to affine should output infinity symbol in Affine", prop.ForAll( 204 func() bool { 205 var g G2Affine 206 var op1 g2JacExtended 207 var zero fptower.E2 208 op1.X.Set(&g2Gen.X) 209 op1.Y.Set(&g2Gen.Y) 210 g.fromJacExtended(&op1) 211 return g.X.Equal(&zero) && g.Y.Equal(&zero) 212 }, 213 )) 214 215 properties.Property("[BN254] Converting infinity in extended Jacobian to Jacobian should output infinity in Jacobian", prop.ForAll( 216 func() bool { 217 var g G2Jac 218 var op1 g2JacExtended 219 var zero, one fptower.E2 220 one.SetOne() 221 op1.X.Set(&g2Gen.X) 222 op1.Y.Set(&g2Gen.Y) 223 g.fromJacExtended(&op1) 224 return g.X.Equal(&one) && g.Y.Equal(&one) && g.Z.Equal(&zero) 225 }, 226 )) 227 228 properties.Property("[BN254] [Jacobian] Two representatives of the same class should be equal", prop.ForAll( 229 func(a, b fptower.E2) bool { 230 op1 := fuzzG2Jac(&g2Gen, a) 231 op2 := fuzzG2Jac(&g2Gen, b) 232 return op1.Equal(&op2) 233 }, 234 GenE2(), 235 GenE2(), 236 )) 237 238 properties.TestingRun(t, gopter.ConsoleReporter(false)) 239 } 240 241 func TestG2AffineOps(t *testing.T) { 242 t.Parallel() 243 parameters := gopter.DefaultTestParameters() 244 parameters.MinSuccessfulTests = 10 245 246 properties := gopter.NewProperties(parameters) 247 248 genScalar := GenFr() 249 250 properties.Property("[BN254] Add(P,-P) should return the point at infinity", prop.ForAll( 251 func(s fr.Element) bool { 252 var op1, op2 G2Affine 253 var sInt big.Int 254 g := g2GenAff 255 s.BigInt(&sInt) 256 op1.ScalarMultiplication(&g, &sInt) 257 op2.Neg(&op1) 258 259 op1.Add(&op1, &op2) 260 return op1.IsInfinity() 261 262 }, 263 GenFr(), 264 )) 265 266 properties.Property("[BN254] Add(P,0) and Add(0,P) should return P", prop.ForAll( 267 func(s fr.Element) bool { 268 var op1, op2 G2Affine 269 var sInt big.Int 270 g := g2GenAff 271 s.BigInt(&sInt) 272 op1.ScalarMultiplication(&g, &sInt) 273 op2.setInfinity() 274 275 op1.Add(&op1, &op2) 276 op2.Add(&op2, &op1) 277 return op1.Equal(&op2) 278 279 }, 280 GenFr(), 281 )) 282 283 properties.Property("[BN254] Add should call double when adding the same point", prop.ForAll( 284 func(s fr.Element) bool { 285 var op1, op2 G2Affine 286 var sInt big.Int 287 g := g2GenAff 288 s.BigInt(&sInt) 289 op1.ScalarMultiplication(&g, &sInt) 290 291 op2.Double(&op1) 292 op1.Add(&op1, &op1) 293 return op1.Equal(&op2) 294 295 }, 296 GenFr(), 297 )) 298 299 properties.Property("[BN254] [2]G = double(G) + G - G", prop.ForAll( 300 func(s fr.Element) bool { 301 var sInt big.Int 302 g := g2GenAff 303 s.BigInt(&sInt) 304 g.ScalarMultiplication(&g, &sInt) 305 var op1, op2 G2Affine 306 op1.ScalarMultiplication(&g, big.NewInt(2)) 307 op2.Double(&g) 308 op2.Add(&op2, &g) 309 op2.Sub(&op2, &g) 310 return op1.Equal(&op2) 311 }, 312 GenFr(), 313 )) 314 315 properties.Property("[BN254] [-s]G = -[s]G", prop.ForAll( 316 func(s fr.Element) bool { 317 g := g2GenAff 318 var gj G2Jac 319 var nbs, bs big.Int 320 s.BigInt(&bs) 321 nbs.Neg(&bs) 322 323 var res = true 324 325 // mulGLV 326 { 327 var op1, op2 G2Affine 328 op1.ScalarMultiplication(&g, &bs).Neg(&op1) 329 op2.ScalarMultiplication(&g, &nbs) 330 res = res && op1.Equal(&op2) 331 } 332 333 // mulWindowed 334 { 335 var op1, op2 G2Jac 336 op1.mulWindowed(&gj, &bs).Neg(&op1) 337 op2.mulWindowed(&gj, &nbs) 338 res = res && op1.Equal(&op2) 339 } 340 341 return res 342 }, 343 GenFr(), 344 )) 345 346 properties.Property("[BN254] [Jacobian] Add should call double when adding the same point", prop.ForAll( 347 func(a, b fptower.E2) bool { 348 fop1 := fuzzG2Jac(&g2Gen, a) 349 fop2 := fuzzG2Jac(&g2Gen, b) 350 var op1, op2 G2Jac 351 op1.Set(&fop1).AddAssign(&fop2) 352 op2.Double(&fop2) 353 return op1.Equal(&op2) 354 }, 355 GenE2(), 356 GenE2(), 357 )) 358 359 properties.Property("[BN254] [Jacobian] Adding the opposite of a point to itself should output inf", prop.ForAll( 360 func(a, b fptower.E2) bool { 361 fop1 := fuzzG2Jac(&g2Gen, a) 362 fop2 := fuzzG2Jac(&g2Gen, b) 363 fop2.Neg(&fop2) 364 fop1.AddAssign(&fop2) 365 return fop1.Equal(&g2Infinity) 366 }, 367 GenE2(), 368 GenE2(), 369 )) 370 371 properties.Property("[BN254] [Jacobian] Adding the inf to a point should not modify the point", prop.ForAll( 372 func(a fptower.E2) bool { 373 fop1 := fuzzG2Jac(&g2Gen, a) 374 fop1.AddAssign(&g2Infinity) 375 var op2 G2Jac 376 op2.Set(&g2Infinity) 377 op2.AddAssign(&g2Gen) 378 return fop1.Equal(&g2Gen) && op2.Equal(&g2Gen) 379 }, 380 GenE2(), 381 )) 382 383 properties.Property("[BN254] [Jacobian Extended] addMixed (-G) should equal subMixed(G)", prop.ForAll( 384 func(a fptower.E2) bool { 385 fop1 := fuzzG2Jac(&g2Gen, a) 386 var p1, p1Neg G2Affine 387 p1.FromJacobian(&fop1) 388 p1Neg = p1 389 p1Neg.Y.Neg(&p1Neg.Y) 390 var o1, o2 g2JacExtended 391 o1.addMixed(&p1Neg) 392 o2.subMixed(&p1) 393 394 return o1.X.Equal(&o2.X) && 395 o1.Y.Equal(&o2.Y) && 396 o1.ZZ.Equal(&o2.ZZ) && 397 o1.ZZZ.Equal(&o2.ZZZ) 398 }, 399 GenE2(), 400 )) 401 402 properties.Property("[BN254] [Jacobian Extended] doubleMixed (-G) should equal doubleNegMixed(G)", prop.ForAll( 403 func(a fptower.E2) bool { 404 fop1 := fuzzG2Jac(&g2Gen, a) 405 var p1, p1Neg G2Affine 406 p1.FromJacobian(&fop1) 407 p1Neg = p1 408 p1Neg.Y.Neg(&p1Neg.Y) 409 var o1, o2 g2JacExtended 410 o1.doubleMixed(&p1Neg) 411 o2.doubleNegMixed(&p1) 412 413 return o1.X.Equal(&o2.X) && 414 o1.Y.Equal(&o2.Y) && 415 o1.ZZ.Equal(&o2.ZZ) && 416 o1.ZZZ.Equal(&o2.ZZZ) 417 }, 418 GenE2(), 419 )) 420 421 properties.Property("[BN254] [Jacobian] Addmix the negation to itself should output 0", prop.ForAll( 422 func(a fptower.E2) bool { 423 fop1 := fuzzG2Jac(&g2Gen, a) 424 fop1.Neg(&fop1) 425 var op2 G2Affine 426 op2.FromJacobian(&g2Gen) 427 fop1.AddMixed(&op2) 428 return fop1.Equal(&g2Infinity) 429 }, 430 GenE2(), 431 )) 432 433 properties.Property("[BN254] scalar multiplication (double and add) should depend only on the scalar mod r", prop.ForAll( 434 func(s fr.Element) bool { 435 436 r := fr.Modulus() 437 var g G2Jac 438 g.ScalarMultiplication(&g2Gen, r) 439 440 var scalar, blindedScalar, rminusone big.Int 441 var op1, op2, op3, gneg G2Jac 442 rminusone.SetUint64(1).Sub(r, &rminusone) 443 op3.mulWindowed(&g2Gen, &rminusone) 444 gneg.Neg(&g2Gen) 445 s.BigInt(&scalar) 446 blindedScalar.Mul(&scalar, r).Add(&blindedScalar, &scalar) 447 op1.mulWindowed(&g2Gen, &scalar) 448 op2.mulWindowed(&g2Gen, &blindedScalar) 449 450 return op1.Equal(&op2) && g.Equal(&g2Infinity) && !op1.Equal(&g2Infinity) && gneg.Equal(&op3) 451 452 }, 453 genScalar, 454 )) 455 456 properties.Property("[BN254] psi should map points from E' to itself", prop.ForAll( 457 func() bool { 458 var a G2Jac 459 a.psi(&g2Gen) 460 return a.IsOnCurve() && !a.Equal(&g2Gen) 461 }, 462 )) 463 464 properties.Property("[BN254] scalar multiplication (GLV) should depend only on the scalar mod r", prop.ForAll( 465 func(s fr.Element) bool { 466 467 r := fr.Modulus() 468 var g G2Jac 469 g.mulGLV(&g2Gen, r) 470 471 var scalar, blindedScalar, rminusone big.Int 472 var op1, op2, op3, gneg G2Jac 473 rminusone.SetUint64(1).Sub(r, &rminusone) 474 op3.ScalarMultiplication(&g2Gen, &rminusone) 475 gneg.Neg(&g2Gen) 476 s.BigInt(&scalar) 477 blindedScalar.Mul(&scalar, r).Add(&blindedScalar, &scalar) 478 op1.ScalarMultiplication(&g2Gen, &scalar) 479 op2.ScalarMultiplication(&g2Gen, &blindedScalar) 480 481 return op1.Equal(&op2) && g.Equal(&g2Infinity) && !op1.Equal(&g2Infinity) && gneg.Equal(&op3) 482 483 }, 484 genScalar, 485 )) 486 487 properties.Property("[BN254] GLV and Double and Add should output the same result", prop.ForAll( 488 func(s fr.Element) bool { 489 490 var r big.Int 491 var op1, op2 G2Jac 492 s.BigInt(&r) 493 op1.mulWindowed(&g2Gen, &r) 494 op2.mulGLV(&g2Gen, &r) 495 return op1.Equal(&op2) && !op1.Equal(&g2Infinity) 496 497 }, 498 genScalar, 499 )) 500 501 properties.TestingRun(t, gopter.ConsoleReporter(false)) 502 } 503 504 func TestG2AffineCofactorCleaning(t *testing.T) { 505 t.Parallel() 506 parameters := gopter.DefaultTestParameters() 507 if testing.Short() { 508 parameters.MinSuccessfulTests = nbFuzzShort 509 } else { 510 parameters.MinSuccessfulTests = nbFuzz 511 } 512 513 properties := gopter.NewProperties(parameters) 514 515 properties.Property("[BN254] Clearing the cofactor of a random point should set it in the r-torsion", prop.ForAll( 516 func() bool { 517 var a, x, b fptower.E2 518 a.SetRandom() 519 520 x.Square(&a).Mul(&x, &a).Add(&x, &bTwistCurveCoeff) 521 for x.Legendre() != 1 { 522 a.SetRandom() 523 x.Square(&a).Mul(&x, &a).Add(&x, &bTwistCurveCoeff) 524 } 525 526 b.Sqrt(&x) 527 var point, pointCleared, infinity G2Jac 528 point.X.Set(&a) 529 point.Y.Set(&b) 530 point.Z.SetOne() 531 pointCleared.ClearCofactor(&point) 532 infinity.Set(&g2Infinity) 533 return point.IsOnCurve() && pointCleared.IsInSubGroup() && !pointCleared.Equal(&infinity) 534 }, 535 )) 536 properties.TestingRun(t, gopter.ConsoleReporter(false)) 537 538 } 539 540 func TestG2AffineBatchScalarMultiplication(t *testing.T) { 541 542 parameters := gopter.DefaultTestParameters() 543 if testing.Short() { 544 parameters.MinSuccessfulTests = nbFuzzShort 545 } else { 546 parameters.MinSuccessfulTests = nbFuzzShort 547 } 548 549 properties := gopter.NewProperties(parameters) 550 551 genScalar := GenFr() 552 553 // size of the multiExps 554 const nbSamples = 10 555 556 properties.Property("[BN254] BatchScalarMultiplication should be consistent with individual scalar multiplications", prop.ForAll( 557 func(mixer fr.Element) bool { 558 // mixer ensures that all the words of a fpElement are set 559 var sampleScalars [nbSamples]fr.Element 560 561 for i := 1; i <= nbSamples; i++ { 562 sampleScalars[i-1].SetUint64(uint64(i)). 563 Mul(&sampleScalars[i-1], &mixer) 564 } 565 566 result := BatchScalarMultiplicationG2(&g2GenAff, sampleScalars[:]) 567 568 if len(result) != len(sampleScalars) { 569 return false 570 } 571 572 for i := 0; i < len(result); i++ { 573 var expectedJac G2Jac 574 var expected G2Affine 575 var b big.Int 576 expectedJac.ScalarMultiplication(&g2Gen, sampleScalars[i].BigInt(&b)) 577 expected.FromJacobian(&expectedJac) 578 if !result[i].Equal(&expected) { 579 return false 580 } 581 } 582 return true 583 }, 584 genScalar, 585 )) 586 587 properties.TestingRun(t, gopter.ConsoleReporter(false)) 588 } 589 590 // ------------------------------------------------------------ 591 // benches 592 593 func BenchmarkG2JacIsInSubGroup(b *testing.B) { 594 var a G2Jac 595 a.Set(&g2Gen) 596 b.ResetTimer() 597 for i := 0; i < b.N; i++ { 598 a.IsInSubGroup() 599 } 600 601 } 602 603 func BenchmarkG2JacEqual(b *testing.B) { 604 var scalar fptower.E2 605 if _, err := scalar.SetRandom(); err != nil { 606 b.Fatalf("failed to set scalar: %s", err) 607 } 608 609 var a G2Jac 610 a.ScalarMultiplication(&g2Gen, big.NewInt(42)) 611 612 b.Run("equal", func(b *testing.B) { 613 var scalarSquared fptower.E2 614 scalarSquared.Square(&scalar) 615 616 aZScaled := a 617 aZScaled.X.Mul(&aZScaled.X, &scalarSquared) 618 aZScaled.Y.Mul(&aZScaled.Y, &scalarSquared).Mul(&aZScaled.Y, &scalar) 619 aZScaled.Z.Mul(&aZScaled.Z, &scalar) 620 621 // Check the setup. 622 if !a.Equal(&aZScaled) { 623 b.Fatalf("invalid test setup") 624 } 625 626 b.ResetTimer() 627 for i := 0; i < b.N; i++ { 628 a.Equal(&aZScaled) 629 } 630 }) 631 632 b.Run("not equal", func(b *testing.B) { 633 var aPlus1 G2Jac 634 aPlus1.AddAssign(&g2Gen) 635 636 // Check the setup. 637 if a.Equal(&aPlus1) { 638 b.Fatalf("invalid test setup") 639 } 640 641 b.ResetTimer() 642 for i := 0; i < b.N; i++ { 643 a.Equal(&aPlus1) 644 } 645 }) 646 } 647 648 func BenchmarkBatchAddG2Affine(b *testing.B) { 649 650 var P, R pG2AffineC16 651 var RR ppG2AffineC16 652 ridx := make([]int, len(P)) 653 654 // TODO P == R may produce skewed benches 655 fillBenchBasesG2(P[:]) 656 fillBenchBasesG2(R[:]) 657 658 for i := 0; i < len(ridx); i++ { 659 ridx[i] = i 660 } 661 662 // random permute 663 rand.Shuffle(len(ridx), func(i, j int) { ridx[i], ridx[j] = ridx[j], ridx[i] }) 664 665 for i, ri := range ridx { 666 RR[i] = &R[ri] 667 } 668 669 b.ResetTimer() 670 for i := 0; i < b.N; i++ { 671 batchAddG2Affine[pG2AffineC16, ppG2AffineC16, cG2AffineC16](&RR, &P, len(P)) 672 } 673 } 674 675 func BenchmarkG2AffineBatchScalarMultiplication(b *testing.B) { 676 // ensure every words of the scalars are filled 677 var mixer fr.Element 678 mixer.SetString("7716837800905789770901243404444209691916730933998574719964609384059111546487") 679 680 const pow = 15 681 const nbSamples = 1 << pow 682 683 var sampleScalars [nbSamples]fr.Element 684 685 for i := 1; i <= nbSamples; i++ { 686 sampleScalars[i-1].SetUint64(uint64(i)). 687 Mul(&sampleScalars[i-1], &mixer) 688 } 689 690 for i := 5; i <= pow; i++ { 691 using := 1 << i 692 693 b.Run(fmt.Sprintf("%d points", using), func(b *testing.B) { 694 b.ResetTimer() 695 for j := 0; j < b.N; j++ { 696 _ = BatchScalarMultiplicationG2(&g2GenAff, sampleScalars[:using]) 697 } 698 }) 699 } 700 } 701 702 func BenchmarkG2JacScalarMultiplication(b *testing.B) { 703 704 var scalar big.Int 705 r := fr.Modulus() 706 scalar.SetString("5243587517512619047944770508185965837690552500527637822603658699938581184513", 10) 707 scalar.Add(&scalar, r) 708 709 var doubleAndAdd G2Jac 710 711 b.Run("double and add", func(b *testing.B) { 712 b.ResetTimer() 713 for j := 0; j < b.N; j++ { 714 doubleAndAdd.mulWindowed(&g2Gen, &scalar) 715 } 716 }) 717 718 var glv G2Jac 719 b.Run("GLV", func(b *testing.B) { 720 b.ResetTimer() 721 for j := 0; j < b.N; j++ { 722 glv.mulGLV(&g2Gen, &scalar) 723 } 724 }) 725 726 } 727 728 func BenchmarkG2AffineCofactorClearing(b *testing.B) { 729 var a G2Jac 730 a.Set(&g2Gen) 731 for i := 0; i < b.N; i++ { 732 a.ClearCofactor(&a) 733 } 734 } 735 736 func BenchmarkG2JacAdd(b *testing.B) { 737 var a G2Jac 738 a.Double(&g2Gen) 739 b.ResetTimer() 740 for i := 0; i < b.N; i++ { 741 a.AddAssign(&g2Gen) 742 } 743 } 744 745 func BenchmarkG2JacAddMixed(b *testing.B) { 746 var a G2Jac 747 a.Double(&g2Gen) 748 749 var c G2Affine 750 c.FromJacobian(&g2Gen) 751 b.ResetTimer() 752 for i := 0; i < b.N; i++ { 753 a.AddMixed(&c) 754 } 755 756 } 757 758 func BenchmarkG2JacDouble(b *testing.B) { 759 var a G2Jac 760 a.Set(&g2Gen) 761 b.ResetTimer() 762 for i := 0; i < b.N; i++ { 763 a.DoubleAssign() 764 } 765 766 } 767 768 func BenchmarkG2JacExtAddMixed(b *testing.B) { 769 var a g2JacExtended 770 a.doubleMixed(&g2GenAff) 771 772 var c G2Affine 773 c.FromJacobian(&g2Gen) 774 b.ResetTimer() 775 for i := 0; i < b.N; i++ { 776 a.addMixed(&c) 777 } 778 } 779 780 func BenchmarkG2JacExtSubMixed(b *testing.B) { 781 var a g2JacExtended 782 a.doubleMixed(&g2GenAff) 783 784 var c G2Affine 785 c.FromJacobian(&g2Gen) 786 b.ResetTimer() 787 for i := 0; i < b.N; i++ { 788 a.subMixed(&c) 789 } 790 } 791 792 func BenchmarkG2JacExtDoubleMixed(b *testing.B) { 793 var a g2JacExtended 794 a.doubleMixed(&g2GenAff) 795 796 var c G2Affine 797 c.FromJacobian(&g2Gen) 798 b.ResetTimer() 799 for i := 0; i < b.N; i++ { 800 a.doubleMixed(&c) 801 } 802 } 803 804 func BenchmarkG2JacExtDoubleNegMixed(b *testing.B) { 805 var a g2JacExtended 806 a.doubleMixed(&g2GenAff) 807 808 var c G2Affine 809 c.FromJacobian(&g2Gen) 810 b.ResetTimer() 811 for i := 0; i < b.N; i++ { 812 a.doubleNegMixed(&c) 813 } 814 } 815 816 func BenchmarkG2JacExtAdd(b *testing.B) { 817 var a, c g2JacExtended 818 a.doubleMixed(&g2GenAff) 819 c.double(&a) 820 821 b.ResetTimer() 822 for i := 0; i < b.N; i++ { 823 a.add(&c) 824 } 825 } 826 827 func BenchmarkG2JacExtDouble(b *testing.B) { 828 var a g2JacExtended 829 a.doubleMixed(&g2GenAff) 830 831 b.ResetTimer() 832 for i := 0; i < b.N; i++ { 833 a.double(&a) 834 } 835 } 836 837 func BenchmarkG2AffineAdd(b *testing.B) { 838 var a G2Affine 839 a.Double(&g2GenAff) 840 b.ResetTimer() 841 for i := 0; i < b.N; i++ { 842 a.Add(&a, &g2GenAff) 843 } 844 } 845 846 func BenchmarkG2AffineDouble(b *testing.B) { 847 var a G2Affine 848 a.Double(&g2GenAff) 849 b.ResetTimer() 850 for i := 0; i < b.N; i++ { 851 a.Double(&a) 852 } 853 } 854 855 func fuzzG2Jac(p *G2Jac, f fptower.E2) G2Jac { 856 var res G2Jac 857 res.X.Mul(&p.X, &f).Mul(&res.X, &f) 858 res.Y.Mul(&p.Y, &f).Mul(&res.Y, &f).Mul(&res.Y, &f) 859 res.Z.Mul(&p.Z, &f) 860 return res 861 } 862 863 func fuzzg2JacExtended(p *g2JacExtended, f fptower.E2) g2JacExtended { 864 var res g2JacExtended 865 var ff, fff fptower.E2 866 ff.Square(&f) 867 fff.Mul(&ff, &f) 868 res.X.Mul(&p.X, &ff) 869 res.Y.Mul(&p.Y, &fff) 870 res.ZZ.Mul(&p.ZZ, &ff) 871 res.ZZZ.Mul(&p.ZZZ, &fff) 872 return res 873 }