Skip to content

Commit

Permalink
start of WycheProof tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Kerin authored and afk11 committed Dec 3, 2018
1 parent 9a3aca1 commit 55260fa
Show file tree
Hide file tree
Showing 27 changed files with 432 additions and 61 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "tests/import/wycheproof"]
path = tests/import/wycheproof
url = https://github.com/google/wycheproof
19 changes: 10 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@ matrix:
fast_finish: true

exclude:
# Disable phpunit test on 7.0, reenable with COVERAGE
# Disable standard phpunit test on 7.0, reenable with COVERAGE
- php: 7.0
env: PHPUNIT=true

# Disable standard phpunit test on 7.0, reenable with FULL
- php: 7.2
env: PHPUNIT=true
include:
# This reenables php7.0/phpunit test with COVERAGE
- php: 7.0
env: PHPUNIT=true COVERAGE_SHARDS=5 COVERAGE=true

# This runs phpcs on php7.0 - only code style
- php: 7.0
env: CODESTYLE=true

# This runs phpcs on php7.0 - only examples
# This reenables php7.0/phpunit test with extended tests (wycheproof)
- php: 7.2
env: FULL=true
# This runs phpcs on php7.0 - only code style and examples
- php: 7.0
env: EXAMPLES=true
env: CODESTYLE=true EXAMPLES=true

sudo: false

Expand All @@ -40,6 +40,7 @@ before_script:

script:
- if [ "${PHPUNIT}" = "true" ]; then make phpunit-ci; fi
- if [ "${FULL}" = "true" ]; then make phpunit-full-ci; fi
- if [ "${CODESTYLE}" = "true" ]; then make phpcs && echo "PHPCS OK"; fi
- if [ "${EXAMPLES}" = "true" ]; then make test-examples && echo "Examples OK"; fi

Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ test-examples:
phpunit-ci: pretest
vendor/bin/phpunit --coverage-text --coverage-clover=tests/output/coverage.clover

phpunit-full-ci: pretest
vendor/bin/phpunit -c phpunit.full.xml --coverage-text --coverage-clover=tests/output/coverage.clover

ifndef STRICT
STRICT = 0
endif
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
},
"autoload-dev": {
"psr-4": {
"Mdanter\\Ecc\\Tests\\": "tests/unit"
"Mdanter\\Ecc\\Tests\\": "tests/unit",
"Mdanter\\Ecc\\WycheProof\\": "tests/wycheproof"
}
}
}
30 changes: 30 additions & 0 deletions phpunit.full.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php" colors="true"
convertErrorsToExceptions="true" convertNoticesToExceptions="true"
convertWarningsToExceptions="true" processIsolation="false"
stopOnFailure="false">
<php>
<const name="PHPUNIT_DEBUG" value="false" />
<ini name="display_errors" value="On" />
<ini name="error_reporting" value="32767" />
</php>
<testsuites>
<testsuite name="WycheProof tests">
<directory suffix="Test.php">./tests/wycheproof</directory>
</testsuite>
<testsuite name="Unit tests">
<directory suffix="Test.php">./tests/unit</directory>
</testsuite>
</testsuites>
<logging>
<log type="coverage-html" target="./tests/output/Coverage/"
charset="UTF-8" yui="true" highlight="true" />
<log type="junit" target="./tests/output/Results/Results.xml"
logIncompleteSkipped="true" />
</logging>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
</phpunit>
9 changes: 5 additions & 4 deletions src/Crypto/EcDH/EcDH.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface;
use Mdanter\Ecc\Crypto\Key\PublicKeyInterface;
use Mdanter\Ecc\Exception\ExchangeException;
use Mdanter\Ecc\Math\GmpMathInterface;

/**
Expand Down Expand Up @@ -135,7 +136,7 @@ private function calculateKey()
// public key instance for the shared secret using our generator.
$this->secretKey = $this->senderKey->getPoint()->getPublicKeyFrom($point->getX(), $point->getY());
} catch (\Exception $e) {
throw new \RuntimeException("Invalid ECDH exchange");
throw new ExchangeException("Invalid ECDH exchange", 0, $e);
}
}
}
Expand All @@ -152,17 +153,17 @@ private function checkExchangeState()
}

if ($this->senderKey === null) {
throw new \RuntimeException('Sender key not set.');
throw new ExchangeException('Sender key not set.');
}

if ($this->recipientKey === null) {
throw new \RuntimeException('Recipient key not set.');
throw new ExchangeException('Recipient key not set.');
}

// Check the point exists on our curve.
$point = $this->recipientKey->getPoint();
if (!$this->senderKey->getPoint()->getCurve()->contains($point->getX(), $point->getY())) {
throw new \RuntimeException("Invalid ECDH exchange - Point does not exist on our curve");
throw new ExchangeException("Invalid ECDH exchange - Point does not exist on our curve");
}
}
}
17 changes: 10 additions & 7 deletions src/Crypto/Key/PublicKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* ***********************************************************************
*/

use Mdanter\Ecc\Exception\PublicKeyException;
use Mdanter\Ecc\Math\GmpMathInterface;
use Mdanter\Ecc\Primitives\CurveFpInterface;
use Mdanter\Ecc\Primitives\GeneratorPoint;
Expand Down Expand Up @@ -67,8 +68,6 @@ class PublicKey implements PublicKeyInterface
* @param GmpMathInterface $adapter
* @param GeneratorPoint $generator
* @param PointInterface $point
* @throws \LogicException
* @throws \RuntimeException
*/
public function __construct(GmpMathInterface $adapter, GeneratorPoint $generator, PointInterface $point)
{
Expand All @@ -77,19 +76,23 @@ public function __construct(GmpMathInterface $adapter, GeneratorPoint $generator
$this->point = $point;
$this->adapter = $adapter;

$n = $generator->getOrder();
// step 1: not point at infinity.
if ($point->isInfinity()) {
throw new PublicKeyException($generator, $point, "Cannot use point at infinity for public key");
}

if ($adapter->cmp($point->getX(), gmp_init(0, 10)) < 0 || $adapter->cmp($n, $point->getX()) <= 0
|| $adapter->cmp($point->getY(), gmp_init(0, 10)) < 0 || $adapter->cmp($n, $point->getY()) <= 0
// step 2 full & partial public key validation routine
if ($adapter->cmp($point->getX(), gmp_init(0, 10)) < 0 || $adapter->cmp($this->curve->getPrime(), $point->getX()) < 0
|| $adapter->cmp($point->getY(), gmp_init(0, 10)) < 0 || $adapter->cmp($this->curve->getPrime(), $point->getY()) < 0
) {
throw new \RuntimeException("Generator point has x and y out of range.");
throw new PublicKeyException($generator, $point, "Point has x and y out of range.");
}

// Sanity check. Point (x,y) values are qualified against it's
// generator and curve. Here we ensure the Point and Generator
// are the same.
if (!$generator->getCurve()->equals($point->getCurve())) {
throw new \RuntimeException("Curve for given point not in common with GeneratorPoint");
throw new PublicKeyException($generator, $point, "Curve for given point not in common with GeneratorPoint");
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/Exception/EccException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Mdanter\Ecc\Exception;

class EccException extends \Exception
{

}
9 changes: 9 additions & 0 deletions src/Exception/ExchangeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Mdanter\Ecc\Exception;

class ExchangeException extends EccException
{

}
9 changes: 9 additions & 0 deletions src/Exception/NumberTheoryException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Mdanter\Ecc\Exception;

class NumberTheoryException extends EccException
{

}
9 changes: 9 additions & 0 deletions src/Exception/PointException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Mdanter\Ecc\Exception;

class PointException extends EccException
{

}
14 changes: 14 additions & 0 deletions src/Exception/PointNotOnCurveException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);

namespace Mdanter\Ecc\Exception;

use Mdanter\Ecc\Primitives\CurveFpInterface;

class PointNotOnCurveException extends PointException
{
public function __construct(\GMP $x, \GMP $y, CurveFpInterface $curve)
{
parent::__construct("Curve " . $curve . " does not contain point (" . gmp_strval($x, 10) . ", " . gmp_strval($y, 10) . ")");
}
}
9 changes: 9 additions & 0 deletions src/Exception/PointRecoveryException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Mdanter\Ecc\Exception;

class PointRecoveryException extends PointException
{

}
38 changes: 38 additions & 0 deletions src/Exception/PublicKeyException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);

namespace Mdanter\Ecc\Exception;

use Mdanter\Ecc\Primitives\GeneratorPoint;
use Mdanter\Ecc\Primitives\PointInterface;
use Throwable;

class PublicKeyException extends EccException
{
/**
* @var GeneratorPoint
*/
private $G;

/**
* @var PointInterface
*/
private $point;

public function __construct(GeneratorPoint $G, PointInterface $point, string $message = "", int $code = 0, Throwable $previous = null)
{
$this->G = $G;
$this->point = $point;
parent::__construct($message, $code, $previous);
}

public function getGenerator(): GeneratorPoint
{
return $this->G;
}

public function getPoint(): PointInterface
{
return $this->point;
}
}
9 changes: 9 additions & 0 deletions src/Exception/SquareRootException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Mdanter\Ecc\Exception;

class SquareRootException extends NumberTheoryException
{

}
11 changes: 7 additions & 4 deletions src/Math/NumberTheory.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
* @author Matyas Danter
*/

use Mdanter\Ecc\Exception\NumberTheoryException;
use Mdanter\Ecc\Exception\SquareRootException;

/**
* Rewritten to take a MathAdaptor to handle different environments. Has
* some desireable functions for public key compression/recovery.
Expand Down Expand Up @@ -88,7 +91,7 @@ public function polynomialReduceMod(array $poly, array $polymod, \GMP $p): array
return $poly;
}

throw new \InvalidArgumentException('Unable to calculate polynomialReduceMod');
throw new NumberTheoryException('Unable to calculate polynomialReduceMod');
}

/**
Expand Down Expand Up @@ -164,7 +167,7 @@ public function polynomialPowMod(array $base, \GMP $exponent, array $polymod, \G
return $s;
}

throw new \InvalidArgumentException('Unable to calculate polynomialPowMod');
throw new NumberTheoryException('Unable to calculate polynomialPowMod');
}

/**
Expand All @@ -190,7 +193,7 @@ public function squareRootModP(\GMP $a, \GMP $p): \GMP

$jac = $math->jacobi($a, $p);
if ($jac === -1) {
throw new \LogicException($math->toString($a)." has no square root modulo ".$math->toString($p));
throw new SquareRootException("{$math->toString($a)} has no square root modulo {$math->toString($p)}");
}

if ($math->equals($math->mod($p, $four), gmp_init(3, 10))) {
Expand Down Expand Up @@ -259,6 +262,6 @@ public function squareRootModP(\GMP $a, \GMP $p): \GMP
}
}

throw new \InvalidArgumentException('Unable to calculate square root mod p!');
throw new SquareRootException('Unable to calculate square root mod p!');
}
}
22 changes: 14 additions & 8 deletions src/Primitives/CurveFp.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
*************************************************************************/
namespace Mdanter\Ecc\Primitives;

use Mdanter\Ecc\Exception\PointRecoveryException;
use Mdanter\Ecc\Exception\SquareRootException;
use Mdanter\Ecc\Math\GmpMathInterface;
use Mdanter\Ecc\Math\ModularArithmetic;
use Mdanter\Ecc\Random\RandomNumberGeneratorInterface;
Expand Down Expand Up @@ -114,16 +116,20 @@ public function recoverYfromX(bool $wasOdd, \GMP $xCoord): \GMP
$math = $this->adapter;
$prime = $this->getPrime();

$root = $this->adapter->getNumberTheory()->squareRootModP(
$math->add(
try {
$root = $this->adapter->getNumberTheory()->squareRootModP(
$math->add(
$this->modAdapter->pow($xCoord, gmp_init(3, 10)),
$math->mul($this->getA(), $xCoord)
$math->add(
$this->modAdapter->pow($xCoord, gmp_init(3, 10)),
$math->mul($this->getA(), $xCoord)
),
$this->getB()
),
$this->getB()
),
$prime
);
$prime
);
} catch (SquareRootException $e) {
throw new PointRecoveryException("Failed to recover y coordinate for point", 0, $e);
}

if ($math->equals($math->mod($root, gmp_init(2, 10)), gmp_init(1)) === $wasOdd) {
return $root;
Expand Down
Loading

0 comments on commit 55260fa

Please sign in to comment.