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