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