Skip to content

Commit

Permalink
Merge pull request #26 from paragonie/better-curve-factory
Browse files Browse the repository at this point in the history
Better Factories
  • Loading branch information
paragonie-security authored May 1, 2024
2 parents db3be4b + 0a36f11 commit 3760009
Show file tree
Hide file tree
Showing 26 changed files with 406 additions and 42 deletions.
1 change: 1 addition & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
</projectFiles>
<issueHandlers>
<InvalidAttribute errorLevel="info" />
<UndefinedAttributeClass errorLevel="info" />
<UnnecessaryVarAnnotation errorLevel="info" />
<UnusedClass errorLevel="info" />
<UnusedProperty errorLevel="info" />
Expand Down
14 changes: 11 additions & 3 deletions src/Curves/SecgCurve.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ public function optimizedCurve256k1(): NamedCurveFp

/**
* @param ?RandomNumberGeneratorInterface $randomGenerator
* @param bool $optimized
* @return GeneratorPoint
*/
public function generator256k1(?RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = false): GeneratorPoint
{

if ($optimized) {
$curve = $this->optimizedCurve256k1();
} else {
Expand Down Expand Up @@ -205,10 +205,14 @@ public function curve256r1(): NamedCurveFp

/**
* @param ?RandomNumberGeneratorInterface $randomGenerator
* @param bool $optimized
* @return GeneratorPoint
*/
public function generator256r1(?RandomNumberGeneratorInterface $randomGenerator = null): GeneratorPoint
public function generator256r1(?RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = false): GeneratorPoint
{
if ($optimized) {
return (new NistCurve($this->adapter))->generator256($randomGenerator, true);
}
$curve = $this->curve256r1();

/** @var GMP $order */
Expand Down Expand Up @@ -240,10 +244,14 @@ public function curve384r1(): NamedCurveFp

/**
* @param ?RandomNumberGeneratorInterface $randomGenerator
* @param bool $optimized
* @return GeneratorPoint
*/
public function generator384r1(?RandomNumberGeneratorInterface $randomGenerator = null): GeneratorPoint
public function generator384r1(?RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = false): GeneratorPoint
{
if ($optimized) {
return (new NistCurve($this->adapter))->generator256($randomGenerator, true);
}
$curve = $this->curve384r1();

/** @var GMP $order */
Expand Down
61 changes: 61 additions & 0 deletions src/Curves/SecureBrainpoolCurve.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace Mdanter\Ecc\Curves;

use Mdanter\Ecc\Exception\InsecureCurveException;
use Mdanter\Ecc\Primitives\GeneratorPoint;
use Mdanter\Ecc\Random\RandomNumberGeneratorInterface;

class SecureBrainpoolCurve extends BrainpoolCurve
{
public function curve256r1(): NamedCurveFp
{
$curve = parent::curve256r1();
if (!$curve->isOpensslAvailable()) {
throw new InsecureCurveException('Cannot securely use non-optimized brainpoolP256r1 without OpenSSL support');
}
return $curve;
}

public function curve384r1(): NamedCurveFp
{
$curve = parent::curve384r1();
if (!$curve->isOpensslAvailable()) {
throw new InsecureCurveException('Cannot securely use non-optimized brainpoolP384r1 without OpenSSL support');
}
return $curve;
}

public function curve512r1(): NamedCurveFp
{
$curve = parent::curve512r1();
if (!$curve->isOpensslAvailable()) {
throw new InsecureCurveException('Cannot securely use non-optimized brainpoolP512r1 without OpenSSL support');
}
return $curve;
}

/**
* @inheritDoc
*/
public function generator256r1(RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = true): GeneratorPoint
{
return parent::generator256r1($randomGenerator, $optimized);
}

/**
* @inheritDoc
*/
public function generator384r1(RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = true): GeneratorPoint
{
return parent::generator384r1($randomGenerator, $optimized);
}

/**
* @inheritDoc
*/
public function generator512r1(RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = true): GeneratorPoint
{
return parent::generator512r1($randomGenerator, $optimized);
}
}
39 changes: 39 additions & 0 deletions src/Curves/SecureCurveFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Mdanter\Ecc\Curves;

use Mdanter\Ecc\Math\GmpMathInterface;
use Mdanter\Ecc\Math\MathAdapterFactory;

/**
* Similar to CurveFactory, but only returns secure implementations
*/
class SecureCurveFactory extends CurveFactory
{
/**
* @param GmpMathInterface $math
* @return NistCurve
*/
private static function getNistFactory(GmpMathInterface $math): NistCurve
{
return new SecureNistCurve($math);
}

/**
* @param GmpMathInterface $math
* @return BrainpoolCurve
*/
private static function getBrainpoolFactory(GmpMathInterface $math): BrainpoolCurve
{
return new SecureBrainpoolCurve($math);
}

/**
* @param GmpMathInterface $math
* @return SecgCurve
*/
private static function getSecpFactory(GmpMathInterface $math): SecgCurve
{
return new SecureSecgCurve($math);
}
}
116 changes: 116 additions & 0 deletions src/Curves/SecureNistCurve.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace Mdanter\Ecc\Curves;

use Mdanter\Ecc\Exception\InsecureCurveException;
use Mdanter\Ecc\Primitives\GeneratorPoint;
use Mdanter\Ecc\Random\RandomNumberGeneratorInterface;

/**
* Selects secure NIST curves
*/
class SecureNistCurve extends NistCurve
{
public function curve192(): NamedCurveFp
{
throw new InsecureCurveException('P-192 is not a secure elliptic curve');
}

public function curve224(): NamedCurveFp
{
throw new InsecureCurveException('P-224 is not a secure elliptic curve');
}

/**
* @return NamedCurveFp
* @throws InsecureCurveException
*/
public function curve256(): NamedCurveFp
{
$curve = parent::curve256();
if (!$curve->isOpensslAvailable()) {
throw new InsecureCurveException('Cannot securely use non-optimized P-256 without OpenSSL support');
}
return $curve;
}

/**
* @return NamedCurveFp
* @throws InsecureCurveException
*/
public function curve384(): NamedCurveFp
{
$curve = parent::curve384();
if (!$curve->isOpensslAvailable()) {
throw new InsecureCurveException('Cannot securely use non-optimized P-384 without OpenSSL support');
}
return $curve;
}

/**
* @return NamedCurveFp
* @throws InsecureCurveException
*/
public function curve521(): NamedCurveFp
{
$curve = parent::curve521();
if (!$curve->isOpensslAvailable()) {
throw new InsecureCurveException('Cannot securely use non-optimized P-521 without OpenSSL support');
}
return $curve;
}

/**
* @param RandomNumberGeneratorInterface|null $randomGenerator
* @throws InsecureCurveException
*/
public function generator192(?RandomNumberGeneratorInterface $randomGenerator = null): GeneratorPoint
{
throw new InsecureCurveException('P-192 is not a secure elliptic curve');
}

/**
* @param RandomNumberGeneratorInterface|null $randomGenerator
* @throws InsecureCurveException
*/
public function generator224(?RandomNumberGeneratorInterface $randomGenerator = null): GeneratorPoint
{
throw new InsecureCurveException('P-224 is not a secure elliptic curve');
}

/**
* Returns an NIST P-256 generator.
*
* @param ?RandomNumberGeneratorInterface $randomGenerator
* @param bool $optimized
* @return GeneratorPoint
*/
public function generator256(?RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = true): GeneratorPoint
{
return parent::generator256($randomGenerator, $optimized);
}

/**
* Returns an NIST P-384 generator.
*
* @param ?RandomNumberGeneratorInterface $randomGenerator
* @param bool $optimized
* @return GeneratorPoint
*/
public function generator384(?RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = true): GeneratorPoint
{
return parent::generator384($randomGenerator, $optimized);
}

/**
* Returns an NIST P-521 generator.
*
* @param ?RandomNumberGeneratorInterface $randomGenerator
* @param bool $optimized
* @return GeneratorPoint
*/
public function generator521(?RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = true): GeneratorPoint
{
return parent::generator521($randomGenerator, $optimized);
}
}
81 changes: 81 additions & 0 deletions src/Curves/SecureSecgCurve.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
namespace Mdanter\Ecc\Curves;

use Mdanter\Ecc\Exception\InsecureCurveException;
use Mdanter\Ecc\Primitives\GeneratorPoint;
use Mdanter\Ecc\Random\RandomNumberGeneratorInterface;

class SecureSecgCurve extends SecgCurve
{

public function curve112r1(): NamedCurveFp
{
throw new InsecureCurveException('secp112r1 is not a secure elliptic curve');
}

public function curve192k1(): NamedCurveFp
{
throw new InsecureCurveException('secp192r1 is not a secure elliptic curve');
}

/**
* @inheritDoc
*/
public function curve256k1(): NamedCurveFp
{
$curve = parent::curve256k1();
if (!$curve->isOpensslAvailable()) {
throw new InsecureCurveException('Cannot securely use non-optimized secp256k1 without OpenSSL support');
}
return $curve;
}

/**
* @inheritDoc
*/
public function curve256r1(): NamedCurveFp
{
$curve = parent::curve256r1();
if (!$curve->isOpensslAvailable()) {
throw new InsecureCurveException('Cannot securely use non-optimized secp256k1 without OpenSSL support');
}
return $curve;
}

/**
* @inheritDoc
*/
public function curve384r1(): NamedCurveFp
{
$curve = parent::curve384r1();
if (!$curve->isOpensslAvailable()) {
throw new InsecureCurveException('Cannot securely use non-optimized secp256k1 without OpenSSL support');
}
return $curve;
}

/**
* @inheritDoc
*/
public function generator256k1(?RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = true): GeneratorPoint
{
return parent::generator256k1($randomGenerator, $optimized);
}

/**
* @inheritDoc
*/
public function generator256r1(?RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = true): GeneratorPoint
{
return parent::generator256r1($randomGenerator, $optimized);
}

/**
* @inheritDoc
*/
public function generator384r1(?RandomNumberGeneratorInterface $randomGenerator = null, bool $optimized = true): GeneratorPoint
{
return parent::generator384r1($randomGenerator, $optimized);
}
}
Loading

0 comments on commit 3760009

Please sign in to comment.