CurveTest.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. require_once __DIR__ . "/../vendor/autoload.php";
  3. use BN\BN;
  4. class CurveTest extends \PHPUnit\Framework\TestCase {
  5. public function test_should_work_with_example_curve() {
  6. $curve = new \Elliptic\Curve\ShortCurve(array(
  7. "p" => '1d',
  8. "a" => '4',
  9. "b" => '14'
  10. ));
  11. $p = $curve->point('18', '16');
  12. $this->assertTrue($p->validate());
  13. $this->assertTrue($p->dbl()->validate());
  14. $this->assertTrue($p->dbl()->add($p)->validate());
  15. $this->assertTrue($p->dbl()->add($p->dbl())->validate());
  16. $this->assertTrue($p->dbl()->add($p->dbl())->eq($p->add($p)->add($p)->add($p)));
  17. }
  18. public function test_should_work_with_secp112k1() {
  19. $curve = new \Elliptic\Curve\ShortCurve(array(
  20. "p" => 'db7c 2abf62e3 5e668076 bead208b',
  21. "a" => 'db7c 2abf62e3 5e668076 bead2088',
  22. "b" => '659e f8ba0439 16eede89 11702b22'
  23. ));
  24. $p = $curve->point(
  25. '0948 7239995a 5ee76b55 f9c2f098',
  26. 'a89c e5af8724 c0a23e0e 0ff77500');
  27. $this->assertTrue($p->validate());
  28. $this->assertTrue($p->dbl()->validate());
  29. }
  30. public function test_should_work_with_secp256k1() {
  31. $curve = new \Elliptic\Curve\ShortCurve(array(
  32. "p" => 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ' .
  33. 'fffffc2f',
  34. "a" => '0',
  35. "b" => '7',
  36. "n" => 'ffffffff ffffffff ffffffff fffffffe ' .
  37. 'baaedce6 af48a03b bfd25e8c d0364141',
  38. "g" => [
  39. '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
  40. '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'
  41. ]
  42. ));
  43. $p = $curve->point(
  44. '79be667e f9dcbbac 55a06295 ce870b07 029bfcdb 2dce28d9 59f2815b 16f81798',
  45. '483ada77 26a3c465 5da4fbfc 0e1108a8 fd17b448 a6855419 9c47d08f fb10d4b8'
  46. );
  47. $this->assertTrue($p->validate());
  48. $this->assertTrue($p->dbl()->validate());
  49. $this->assertTrue($p->toJ()->dbl()->toP()->validate());
  50. $this->assertTrue($p->mul(new BN('79be667e f9dcbbac 55a06295 ce870b07', 16))->validate());
  51. $j = $p->toJ();
  52. $this->assertTrue($j->trpl()->eq($j->dbl()->add($j)));
  53. // Endomorphism test
  54. $this->assertNotNull($curve->endo);
  55. $this->assertEquals(
  56. $curve->endo["beta"]->fromRed()->toString(16),
  57. '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee');
  58. $this->assertEquals(
  59. $curve->endo["lambda"]->toString(16),
  60. '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72');
  61. $k = new BN('1234567890123456789012345678901234', 16);
  62. $split = $curve->_endoSplit($k);
  63. $testK = $split["k1"]->add($split["k2"]->mul($curve->endo["lambda"]))->umod($curve->n);
  64. $this->assertEquals($testK->toString(16), $k->toString(16));
  65. }
  66. public function test_should_compute_this_problematic_secp256k1_multiplication() {
  67. $curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
  68. $g1 = $curve->g; // precomputed g
  69. $this->assertNotNull($g1->precomputed);
  70. $g2 = $curve->point($g1->getX(), $g1->getY()); // not precomputed g
  71. $this->assertNull($g2->precomputed);
  72. $a = new BN(
  73. '6d1229a6b24c2e775c062870ad26bc261051e0198c67203167273c7c62538846', 16);
  74. $p1 = $g1->mul($a);
  75. $p2 = $g2->mul($a);
  76. $this->assertTrue($p1->eq($p2));
  77. }
  78. public function test_should_not_use_fixed_NAF_when_k_is_too_large() {
  79. $curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
  80. $g1 = $curve->g; // precomputed g
  81. $this->assertNotNull($g1->precomputed);
  82. $g2 = $curve->point($g1->getX(), $g1->getY()); // not precomputed g
  83. $this->assertNull($g2->precomputed);
  84. $a = new BN(
  85. '6d1229a6b24c2e775c062870ad26bc26' .
  86. '1051e0198c67203167273c7c6253884612345678',
  87. 16);
  88. $p1 = $g1->mul($a);
  89. $p2 = $g2->mul($a);
  90. $this->assertTrue($p1->eq($p2));
  91. }
  92. public function test_should_not_fail_on_secp256k1_regression() {
  93. $curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
  94. $k1 = new BN(
  95. '32efeba414cd0c830aed727749e816a01c471831536fd2fce28c56b54f5a3bb1', 16);
  96. $k2 = new BN(
  97. '5f2e49b5d64e53f9811545434706cde4de528af97bfd49fde1f6cf792ee37a8c', 16);
  98. $p1 = $curve->g->mul($k1);
  99. $p2 = $curve->g->mul($k2);
  100. // 2 + 2 + 1 = 2 + 1 + 2
  101. $two = $p2->dbl();
  102. $five = $two->dbl()->add($p2);
  103. $three = $two->add($p2);
  104. $maybeFive = $three->add($two);
  105. $this->assertTrue($maybeFive->eq($five));
  106. $p1 = $p1->mul($k2);
  107. $p2 = $p2->mul($k1);
  108. $this->assertTrue($p1->validate());
  109. $this->assertTrue($p2->validate());
  110. $this->assertTrue($p1->eq($p2));
  111. }
  112. public function test_should_correctly_double_the_affine_point_on_secp256k1() {
  113. $bad = new ArrayObject(array(
  114. "x" => '026a2073b1ef6fab47ace18e60e728a05180a82755bbcec9a0abc08ad9f7a3d4',
  115. "y" => '9cd8cb48c3281596139f147c1364a3ede88d3f310fdb0eb98c924e599ca1b3c9',
  116. "z" => 'd78587ad45e4102f48b54b5d85598296e069ce6085002e169c6bad78ddc6d9bd'
  117. ), ArrayObject::ARRAY_AS_PROPS);
  118. $good = new ArrayObject(array(
  119. "x" => 'e7789226739ac2eb3c7ccb2a9a910066beeed86cdb4e0f8a7fee8eeb29dc7016',
  120. "y" => '4b76b191fd6d47d07828ea965e275b76d0e3e0196cd5056d38384fbb819f9fcb',
  121. "z" => 'cbf8d99056618ba132d6145b904eee1ce566e0feedb9595139c45f84e90cfa7d'
  122. ), ArrayObject::ARRAY_AS_PROPS);
  123. $curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
  124. $bad = $curve->jpoint($bad->x, $bad->y, $bad->z);
  125. $good = $curve->jpoint($good->x, $good->y, $good->z);
  126. // They are the same points
  127. $this->assertTrue($bad->add($good->neg())->isInfinity());
  128. // But doubling borks them out
  129. $this->assertTrue($bad->dbl()->add($good->dbl()->neg())->isInfinity());
  130. }
  131. public function test_should_store_precomputed_values_correctly_on_negation() {
  132. $curve = \Elliptic\Curves::getCurve("secp256k1")->curve;
  133. $p = $curve->g->mul('2');
  134. $p->precompute();
  135. $neg = $p->neg(true);
  136. $neg2 = $neg->neg(true);
  137. $this->assertTrue($p->eq($neg2));
  138. }
  139. }