'1d', "a" => '4', "b" => '14' )); $p = $curve->point('18', '16'); $this->assertTrue($p->validate()); $this->assertTrue($p->dbl()->validate()); $this->assertTrue($p->dbl()->add($p)->validate()); $this->assertTrue($p->dbl()->add($p->dbl())->validate()); $this->assertTrue($p->dbl()->add($p->dbl())->eq($p->add($p)->add($p)->add($p))); } public function test_should_work_with_secp112k1() { $curve = new \Elliptic\Curve\ShortCurve(array( "p" => 'db7c 2abf62e3 5e668076 bead208b', "a" => 'db7c 2abf62e3 5e668076 bead2088', "b" => '659e f8ba0439 16eede89 11702b22' )); $p = $curve->point( '0948 7239995a 5ee76b55 f9c2f098', 'a89c e5af8724 c0a23e0e 0ff77500'); $this->assertTrue($p->validate()); $this->assertTrue($p->dbl()->validate()); } public function test_should_work_with_secp256k1() { $curve = new \Elliptic\Curve\ShortCurve(array( "p" => 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ' . 'fffffc2f', "a" => '0', "b" => '7', "n" => 'ffffffff ffffffff ffffffff fffffffe ' . 'baaedce6 af48a03b bfd25e8c d0364141', "g" => [ '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8' ] )); $p = $curve->point( '79be667e f9dcbbac 55a06295 ce870b07 029bfcdb 2dce28d9 59f2815b 16f81798', '483ada77 26a3c465 5da4fbfc 0e1108a8 fd17b448 a6855419 9c47d08f fb10d4b8' ); $this->assertTrue($p->validate()); $this->assertTrue($p->dbl()->validate()); $this->assertTrue($p->toJ()->dbl()->toP()->validate()); $this->assertTrue($p->mul(new BN('79be667e f9dcbbac 55a06295 ce870b07', 16))->validate()); $j = $p->toJ(); $this->assertTrue($j->trpl()->eq($j->dbl()->add($j))); // Endomorphism test $this->assertNotNull($curve->endo); $this->assertEquals( $curve->endo["beta"]->fromRed()->toString(16), '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'); $this->assertEquals( $curve->endo["lambda"]->toString(16), '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72'); $k = new BN('1234567890123456789012345678901234', 16); $split = $curve->_endoSplit($k); $testK = $split["k1"]->add($split["k2"]->mul($curve->endo["lambda"]))->umod($curve->n); $this->assertEquals($testK->toString(16), $k->toString(16)); } public function test_should_compute_this_problematic_secp256k1_multiplication() { $curve = \Elliptic\Curves::getCurve("secp256k1")->curve; $g1 = $curve->g; // precomputed g $this->assertNotNull($g1->precomputed); $g2 = $curve->point($g1->getX(), $g1->getY()); // not precomputed g $this->assertNull($g2->precomputed); $a = new BN( '6d1229a6b24c2e775c062870ad26bc261051e0198c67203167273c7c62538846', 16); $p1 = $g1->mul($a); $p2 = $g2->mul($a); $this->assertTrue($p1->eq($p2)); } public function test_should_not_use_fixed_NAF_when_k_is_too_large() { $curve = \Elliptic\Curves::getCurve("secp256k1")->curve; $g1 = $curve->g; // precomputed g $this->assertNotNull($g1->precomputed); $g2 = $curve->point($g1->getX(), $g1->getY()); // not precomputed g $this->assertNull($g2->precomputed); $a = new BN( '6d1229a6b24c2e775c062870ad26bc26' . '1051e0198c67203167273c7c6253884612345678', 16); $p1 = $g1->mul($a); $p2 = $g2->mul($a); $this->assertTrue($p1->eq($p2)); } public function test_should_not_fail_on_secp256k1_regression() { $curve = \Elliptic\Curves::getCurve("secp256k1")->curve; $k1 = new BN( '32efeba414cd0c830aed727749e816a01c471831536fd2fce28c56b54f5a3bb1', 16); $k2 = new BN( '5f2e49b5d64e53f9811545434706cde4de528af97bfd49fde1f6cf792ee37a8c', 16); $p1 = $curve->g->mul($k1); $p2 = $curve->g->mul($k2); // 2 + 2 + 1 = 2 + 1 + 2 $two = $p2->dbl(); $five = $two->dbl()->add($p2); $three = $two->add($p2); $maybeFive = $three->add($two); $this->assertTrue($maybeFive->eq($five)); $p1 = $p1->mul($k2); $p2 = $p2->mul($k1); $this->assertTrue($p1->validate()); $this->assertTrue($p2->validate()); $this->assertTrue($p1->eq($p2)); } public function test_should_correctly_double_the_affine_point_on_secp256k1() { $bad = new ArrayObject(array( "x" => '026a2073b1ef6fab47ace18e60e728a05180a82755bbcec9a0abc08ad9f7a3d4', "y" => '9cd8cb48c3281596139f147c1364a3ede88d3f310fdb0eb98c924e599ca1b3c9', "z" => 'd78587ad45e4102f48b54b5d85598296e069ce6085002e169c6bad78ddc6d9bd' ), ArrayObject::ARRAY_AS_PROPS); $good = new ArrayObject(array( "x" => 'e7789226739ac2eb3c7ccb2a9a910066beeed86cdb4e0f8a7fee8eeb29dc7016', "y" => '4b76b191fd6d47d07828ea965e275b76d0e3e0196cd5056d38384fbb819f9fcb', "z" => 'cbf8d99056618ba132d6145b904eee1ce566e0feedb9595139c45f84e90cfa7d' ), ArrayObject::ARRAY_AS_PROPS); $curve = \Elliptic\Curves::getCurve("secp256k1")->curve; $bad = $curve->jpoint($bad->x, $bad->y, $bad->z); $good = $curve->jpoint($good->x, $good->y, $good->z); // They are the same points $this->assertTrue($bad->add($good->neg())->isInfinity()); // But doubling borks them out $this->assertTrue($bad->dbl()->add($good->dbl()->neg())->isInfinity()); } public function test_should_store_precomputed_values_correctly_on_negation() { $curve = \Elliptic\Curves::getCurve("secp256k1")->curve; $p = $curve->g->mul('2'); $p->precompute(); $neg = $p->neg(true); $neg2 = $neg->neg(true); $this->assertTrue($p->eq($neg2)); } }