166 lines
6.4 KiB
PHP
166 lines
6.4 KiB
PHP
<?php
|
|
require_once __DIR__ . "/../vendor/autoload.php";
|
|
|
|
use BN\BN;
|
|
|
|
class CurveTest extends \PHPUnit\Framework\TestCase {
|
|
public function test_should_work_with_example_curve() {
|
|
$curve = new \Elliptic\Curve\ShortCurve(array(
|
|
"p" => '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));
|
|
}
|
|
}
|