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