diff --git a/phpseclib/Crypt/EC/BaseCurves/Base.php b/phpseclib/Crypt/EC/BaseCurves/Base.php index 6102c063..f1b33025 100644 --- a/phpseclib/Crypt/EC/BaseCurves/Base.php +++ b/phpseclib/Crypt/EC/BaseCurves/Base.php @@ -15,7 +15,6 @@ namespace phpseclib3\Crypt\EC\BaseCurves; -use phpseclib3\Math\Common\FiniteField; use phpseclib3\Math\BigInteger; /** @@ -66,7 +65,7 @@ abstract class Base } /** - * Converts a BigInteger to a FiniteField integer + * Converts a BigInteger to a \phpseclib3\Math\FiniteField\Integer integer * * @return object */ @@ -105,7 +104,7 @@ abstract class Base * * @return array */ - public function multiplyPoint(array $p, FiniteField\Integer $d) + public function multiplyPoint(array $p, BigInteger $d) { $alreadyInternal = isset($p[2]); $r = $alreadyInternal ? @@ -125,7 +124,7 @@ abstract class Base /** * Creates a random scalar multiplier * - * @return FiniteField + * @return BigInteger */ public function createRandomMultiplier() { @@ -134,8 +133,25 @@ abstract class Base $one = new BigInteger(1); } - $dA = BigInteger::randomRange($one, $this->order->subtract($one)); - return $this->factory->newInteger($dA); + return BigInteger::randomRange($one, $this->order->subtract($one)); + } + + /** + * Performs range check + */ + public function rangeCheck(BigInteger $x) + { + static $zero; + if (!isset($zero)) { + $zero = new BigInteger(); + } + + if (!isset($this->order)) { + throw new \RuntimeException('setOrder needs to be called before this method'); + } + if ($x->compare($this->order) > 0 || $x->compare($zero) <= 0) { + throw new \RangeException('x must be between 1 and the order of the curve'); + } } /** diff --git a/phpseclib/Crypt/EC/BaseCurves/Montgomery.php b/phpseclib/Crypt/EC/BaseCurves/Montgomery.php index b4bba650..49693745 100644 --- a/phpseclib/Crypt/EC/BaseCurves/Montgomery.php +++ b/phpseclib/Crypt/EC/BaseCurves/Montgomery.php @@ -26,7 +26,6 @@ namespace phpseclib3\Crypt\EC\BaseCurves; -use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Common\Functions\Strings; use phpseclib3\Math\PrimeField; use phpseclib3\Math\BigInteger; @@ -222,7 +221,7 @@ class Montgomery extends Base * * @return array */ - public function multiplyPoint(array $p, Integer $d) + public function multiplyPoint(array $p, BigInteger $d) { $p1 = [$this->one, $this->zero]; $alreadyInternal = isset($x[1]); diff --git a/phpseclib/Crypt/EC/Curves/Curve25519.php b/phpseclib/Crypt/EC/Curves/Curve25519.php index 06842d8c..7a71fbf3 100644 --- a/phpseclib/Crypt/EC/Curves/Curve25519.php +++ b/phpseclib/Crypt/EC/Curves/Curve25519.php @@ -15,7 +15,6 @@ namespace phpseclib3\Crypt\EC\Curves; -use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Crypt\EC\BaseCurves\Montgomery; use phpseclib3\Math\BigInteger; @@ -48,7 +47,7 @@ class Curve25519 extends Montgomery * * @return array */ - public function multiplyPoint(array $p, Integer $d) + public function multiplyPoint(array $p, BigInteger $d) { //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); //return [$this->factory->newInteger(new BigInteger($r, 256))]; @@ -57,8 +56,28 @@ class Curve25519 extends Montgomery $d&= "\xF8" . str_repeat("\xFF", 30) . "\x7F"; $d = strrev($d); $d|= "\x40"; - $d = $this->factory->newInteger(new BigInteger($d, -256)); + $d = new BigInteger($d, -256); return parent::multiplyPoint($p, $d); } + + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + return BigInteger::random(256); + } + + /** + * Performs range check + */ + public function rangeCheck(BigInteger $x) + { + if ($x->getLength() > 256 || $x->isNegative()) { + throw new \RangeException('x must be a positive integer less than 256 bytes in length'); + } + } } \ No newline at end of file diff --git a/phpseclib/Crypt/EC/Curves/Curve448.php b/phpseclib/Crypt/EC/Curves/Curve448.php index 7dcf7084..f3508ace 100644 --- a/phpseclib/Crypt/EC/Curves/Curve448.php +++ b/phpseclib/Crypt/EC/Curves/Curve448.php @@ -15,7 +15,6 @@ namespace phpseclib3\Crypt\EC\Curves; -use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Crypt\EC\BaseCurves\Montgomery; use phpseclib3\Math\BigInteger; @@ -55,7 +54,7 @@ class Curve448 extends Montgomery * * @return array */ - public function multiplyPoint(array $p, Integer $d) + public function multiplyPoint(array $p, BigInteger $d) { //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); //return [$this->factory->newInteger(new BigInteger($r, 256))]; @@ -64,8 +63,28 @@ class Curve448 extends Montgomery $d[0] = $d[0] & "\xFC"; $d = strrev($d); $d|= "\x80"; - $d = $this->factory->newInteger(new BigInteger($d, 256)); + $d = new BigInteger($d, 256); return parent::multiplyPoint($p, $d); } + + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + return BigInteger::random(446); + } + + /** + * Performs range check + */ + public function rangeCheck(BigInteger $x) + { + if ($x->getLength() > 448 || $x->isNegative()) { + throw new \RangeException('x must be a positive integer less than 446 bytes in length'); + } + } } \ No newline at end of file diff --git a/phpseclib/Crypt/EC/Curves/Ed25519.php b/phpseclib/Crypt/EC/Curves/Ed25519.php index a34494ce..ebbc8648 100644 --- a/phpseclib/Crypt/EC/Curves/Ed25519.php +++ b/phpseclib/Crypt/EC/Curves/Ed25519.php @@ -180,7 +180,6 @@ class Ed25519 extends TwistedEdwards // 3. Interpret the buffer as the little-endian integer, forming a // secret scalar s. $dA = new BigInteger($h, 256); - $dA = $this->factory->newInteger($dA); $dA->secret = $str; return $dA; diff --git a/phpseclib/Crypt/EC/Curves/Ed448.php b/phpseclib/Crypt/EC/Curves/Ed448.php index 80ed33a8..53704e7b 100644 --- a/phpseclib/Crypt/EC/Curves/Ed448.php +++ b/phpseclib/Crypt/EC/Curves/Ed448.php @@ -118,7 +118,6 @@ class Ed448 extends TwistedEdwards // 3. Interpret the buffer as the little-endian integer, forming a // secret scalar s. $dA = new BigInteger($h, 256); - $dA = $this->factory->newInteger($dA); $dA->secret = $str; return $dA; diff --git a/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php b/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php index b0c85010..92420ba1 100644 --- a/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php +++ b/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php @@ -25,7 +25,6 @@ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Curve448; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Math\BigInteger; use phpseclib3\Exception\UnsupportedFormatException; @@ -67,7 +66,8 @@ abstract class MontgomeryPrivate } $components = ['curve' => $curve]; - $components['dA'] = $components['curve']->convertInteger(new BigInteger($key, 256)); + $components['dA'] = new BigInteger($key, 256); + $curve->rangeCheck($components['dA']); // note that EC::getEncodedCoordinates does some additional "magic" (it does strrev on the result) $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); @@ -91,13 +91,13 @@ abstract class MontgomeryPrivate * Convert a private key to the appropriate format. * * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Math\BigInteger $privateKey * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $password optional * @return string */ - public static function savePrivateKey(Integer $privateKey, MontgomeryCurve $curve, array $publicKey, $password = '') + public static function savePrivateKey(BigInteger $privateKey, MontgomeryCurve $curve, array $publicKey, $password = '') { if (!empty($password) && is_string($password)) { throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption'); diff --git a/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php b/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php index 5372e11b..fed992b4 100644 --- a/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php +++ b/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php @@ -24,7 +24,6 @@ use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Math\Common\FiniteField\Integer; /** * OpenSSH Formatted EC Key Handler @@ -75,9 +74,10 @@ abstract class OpenSSH extends Progenitor } list($curveName, $publicKey, $privateKey, $comment) = Strings::unpackSSH2('ssis', $paddedKey); $curve = self::loadCurveByParam(['namedCurve' => $curveName]); + $curve->rangeCheck($privateKey); return [ 'curve' => $curve, - 'dA' => $curve->convertInteger($privateKey), + 'dA' => $privateKey, 'QA' => self::extractPoint("\0$publicKey", $curve), 'comment' => $comment ]; @@ -179,14 +179,14 @@ abstract class OpenSSH extends Progenitor * Convert a private key to the appropriate format. * * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Math\BigInteger $privateKey * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $password optional * @param array $options optional * @return string */ - public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) { if ($curve instanceof Ed25519) { if (!isset($privateKey->secret)) { diff --git a/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php b/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php index b28492bc..1aae7d94 100644 --- a/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php +++ b/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php @@ -27,7 +27,6 @@ namespace phpseclib3\Crypt\EC\Formats\Keys; -use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; @@ -107,8 +106,8 @@ abstract class PKCS1 extends Progenitor $components['curve'] = $ecParams; } - $temp = new BigInteger($ecPrivate['privateKey'], 256); - $components['dA'] = $components['curve']->convertInteger($temp); + $components['dA'] = new BigInteger($ecPrivate['privateKey'], 256); + $components['curve']->rangeCheck($components['dA']); $components['QA'] = isset($ecPrivate['publicKey']) ? self::extractPoint($ecPrivate['publicKey'], $components['curve']) : $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); @@ -138,8 +137,7 @@ abstract class PKCS1 extends Progenitor $components = []; $components['curve'] = self::loadCurveByParam($key['parameters']); - $temp = new BigInteger($key['privateKey'], 256); - $components['dA'] = $components['curve']->convertInteger($temp); + $components['dA'] = new BigInteger($key['privateKey'], 256); $components['QA'] = isset($ecPrivate['publicKey']) ? self::extractPoint($ecPrivate['publicKey'], $components['curve']) : $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); @@ -172,14 +170,14 @@ abstract class PKCS1 extends Progenitor * Convert a private key to the appropriate format. * * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Math\BigInteger $privateKey * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $password optional * @param array $options optional * @return string */ - public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) { self::initialize_static_variables(); diff --git a/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php b/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php index e6a3d59f..3546fc4a 100644 --- a/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php +++ b/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php @@ -32,7 +32,6 @@ use phpseclib3\File\ASN1\Maps; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Curves\Ed448; use phpseclib3\Exception\UnsupportedCurveException; @@ -126,8 +125,8 @@ abstract class PKCS8 extends Progenitor throw new \RuntimeException('The PKCS8 parameter field does not match the private key parameter field'); } - $temp = new BigInteger($key['privateKey'], 256); - $components['dA'] = $components['curve']->convertInteger($temp); + $components['dA'] = new BigInteger($key['privateKey'], 256); + $components['curve']->rangeCheck($components['dA']); $components['QA'] = isset($key['publicKey']) ? self::extractPoint($key['publicKey'], $components['curve']) : $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); @@ -206,14 +205,14 @@ abstract class PKCS8 extends Progenitor * Convert a private key to the appropriate format. * * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Math\BigInteger $privateKey * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $password optional * @param array $options optional * @return string */ - public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = []) { self::initialize_static_variables(); diff --git a/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php b/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php index 181ab76c..c6b2bd37 100644 --- a/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php +++ b/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php @@ -20,7 +20,6 @@ use phpseclib3\Math\BigInteger; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; /** @@ -81,8 +80,8 @@ abstract class PuTTY extends Progenitor } $components['dA'] = $components['curve']->extractSecret($private); } else { - list($temp) = Strings::unpackSSH2('i', $private); - $components['dA'] = $components['curve']->convertInteger($temp); + list($components['dA']) = Strings::unpackSSH2('i', $private); + $components['curve']->rangeCheck($components['dA']); } return $components; @@ -92,14 +91,14 @@ abstract class PuTTY extends Progenitor * Convert a private key to the appropriate format. * * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Math\BigInteger $privateKey * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $password optional * @param array $options optional * @return string */ - public static function savePrivateKey(Integer $privateKey, BaseCurve $curve, array $publicKey, $password = false, array $options = []) + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = false, array $options = []) { self::initialize_static_variables(); diff --git a/phpseclib/Crypt/EC/Formats/Keys/libsodium.php b/phpseclib/Crypt/EC/Formats/Keys/libsodium.php index 02fc06aa..666de0b5 100644 --- a/phpseclib/Crypt/EC/Formats/Keys/libsodium.php +++ b/phpseclib/Crypt/EC/Formats/Keys/libsodium.php @@ -20,7 +20,7 @@ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Math\BigInteger; use phpseclib3\Exception\UnsupportedFormatException; /** @@ -99,13 +99,13 @@ abstract class libsodium * Convert a private key to the appropriate format. * * @access public - * @param \phpseclib3\Math\Common\FiniteField\Integer $privateKey + * @param \phpseclib3\Math\BigInteger $privateKey * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $password optional * @return string */ - public static function savePrivateKey(Integer $privateKey, Ed25519 $curve, array $publicKey, $password = '') + public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, $password = '') { if (!isset($privateKey->secret)) { throw new \RuntimeException('Private Key does not have a secret set'); diff --git a/phpseclib/Crypt/EC/PrivateKey.php b/phpseclib/Crypt/EC/PrivateKey.php index 4ffa5fdf..345660fc 100644 --- a/phpseclib/Crypt/EC/PrivateKey.php +++ b/phpseclib/Crypt/EC/PrivateKey.php @@ -95,8 +95,7 @@ class PrivateKey extends EC implements Common\PrivateKey throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); } - $dA = $this->dA->toBigInteger(); - + $dA = $this->dA; $order = $this->curve->getOrder(); $shortFormat = $this->shortFormat; @@ -132,7 +131,7 @@ class PrivateKey extends EC implements Common\PrivateKey $r = strrev($r); $r = new BigInteger($r, 256); list(, $r) = $r->divide($order); - $R = $curve->multiplyPoint($curve->getBasePoint(), $curve->convertInteger($r)); + $R = $curve->multiplyPoint($curve->getBasePoint(), $r); $R = $curve->encodePoint($R); $k = $hash->hash($dom . $R . $A . $message); $k = strrev($k); @@ -172,7 +171,7 @@ class PrivateKey extends EC implements Common\PrivateKey while (true) { $k = BigInteger::randomRange(self::$one, $order->subtract(self::$one)); - list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $this->curve->convertInteger($k)); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); $x = $x->toBigInteger(); list(, $r) = $x->divide($order); if ($r->equals(self::$zero)) { @@ -199,7 +198,7 @@ class PrivateKey extends EC implements Common\PrivateKey $h1 = $this->hash->hash($message); $k = $this->computek($h1); - list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $this->curve->convertInteger($k)); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); $x = $x->toBigInteger(); list(, $r) = $x->divide($this->q); $kinv = $k->modInverse($this->q); diff --git a/phpseclib/Crypt/EC/PublicKey.php b/phpseclib/Crypt/EC/PublicKey.php index 2cb92ab6..ac85e04a 100644 --- a/phpseclib/Crypt/EC/PublicKey.php +++ b/phpseclib/Crypt/EC/PublicKey.php @@ -108,8 +108,8 @@ class PublicKey extends EC implements Common\PublicKey $qa = $curve->convertToInternal($this->QA); - $lhs = $curve->multiplyPoint($curve->getBasePoint(), $curve->convertInteger($S)); - $rhs = $curve->multiplyPoint($qa, $curve->convertInteger($k)); + $lhs = $curve->multiplyPoint($curve->getBasePoint(), $S); + $rhs = $curve->multiplyPoint($qa, $k); $rhs = $curve->addPoint($rhs, $R); $rhs = $curve->convertToAffine($rhs); diff --git a/tests/Unit/Crypt/EC/KeyTest.php b/tests/Unit/Crypt/EC/KeyTest.php index 7d72102c..02629dbe 100644 --- a/tests/Unit/Crypt/EC/KeyTest.php +++ b/tests/Unit/Crypt/EC/KeyTest.php @@ -125,12 +125,20 @@ AFLpken6rN6lOEIeyNLdD097 // openssl ecparam -name sect113r1 -genkey -noout -out sect113r1.pem public function testBinaryPKCS1PrivateKey() { - $key = PublicKeyLoader::load($expected = '-----BEGIN EC PRIVATE KEY----- + $key = PublicKeyLoader::load('-----BEGIN EC PRIVATE KEY----- MEECAQEEDwBZdP4eSzKk/uQa6jdtfKAHBgUrgQQABKEiAyAABAHqCoNb++mK5qvE c4rCzQEuI19czqvXpEPcAWSXew== -----END EC PRIVATE KEY-----'); $this->assertSameNL('sect113r1', $key->getCurve()); + // the difference between this and the above key is that + // the privateKey part of the above key has a leading null + // byte whereas this one doesn't + $expected = '-----BEGIN EC PRIVATE KEY----- +MEACAQEEDll0/h5LMqT+5BrqN218oAcGBSuBBAAEoSIDIAAEAeoKg1v76Yrmq8Rz +isLNAS4jX1zOq9ekQ9wBZJd7 +-----END EC PRIVATE KEY-----'; + PKCS1::useNamedCurve(); $this->assertSameNL($expected, $key->toString('PKCS1')); } @@ -151,12 +159,14 @@ WwCpKNBUcVeiHme609Dv/g== // the above key has the (optional) seed for the verifiably // random function whereas the following key does not. // also, in the above key the cofactor (1; optional) is - // included whereas in the following key it is not + // included whereas in the following key it is not; + // finally, in the above the privateKey has a leading null + // byte whereas it doesn't in the following key $expected = '-----BEGIN EC PRIVATE KEY----- -MIGxAgEBBA8AuSc4BeeyYTq9rbSDuL2gdzB1AgEBMBwGByqGSM49AQIwEQIBcQYJ -KoZIzj0BAgMCAgEJMCAEDjCIJQym58f+ZJzoWCD3BA7ovuTT4iYHRBiL4OnHIwQf -BACdc2FvNfSrFAfXNWLBDwClKDAneVjuhNExXtMYhgIPAQAAAAAAAADZzOyKOeVv -oSIDIAAEAULtznTLu7D6K4d4wK1bAKko0FRxV6IeZ7rT0O/+ +MIGwAgEBBA65JzgF57JhOr2ttIO4vaB3MHUCAQEwHAYHKoZIzj0BAjARAgFxBgkq +hkjOPQECAwICAQkwIAQOMIglDKbnx/5knOhYIPcEDui+5NPiJgdEGIvg6ccjBB8E +AJ1zYW819KsUB9c1YsEPAKUoMCd5WO6E0TFe0xiGAg8BAAAAAAAAANnM7Io55W+h +IgMgAAQBQu3OdMu7sPorh3jArVsAqSjQVHFXoh5nutPQ7/4= -----END EC PRIVATE KEY-----'; PKCS1::useSpecifiedCurve(); $this->assertSameNL($expected, $key->toString('PKCS1')); @@ -167,12 +177,20 @@ oSIDIAAEAULtznTLu7D6K4d4wK1bAKko0FRxV6IeZ7rT0O/+ // sect113r1's reduction polynomial is a trinomial public function testBinaryPKCS8PrivateKey() { - $key = PublicKeyLoader::load($expected = '-----BEGIN PRIVATE KEY----- + $key = PublicKeyLoader::load('-----BEGIN PRIVATE KEY----- MFECAQAwEAYHKoZIzj0CAQYFK4EEAAQEOjA4AgEBBA8A5OuqAY8HYoFOaz9mE6mh IgMgAAQASF3rOTPXvH0QdRBvsrMBdLMf27yd8AWABrZTxvI= -----END PRIVATE KEY-----'); $this->assertSameNL('sect113r1', $key->getCurve()); + // the difference between this and the above key is that + // the privateKey part of the above key has a leading null + // byte whereas this one doesn't + $expected = '-----BEGIN PRIVATE KEY----- +MFACAQAwEAYHKoZIzj0CAQYFK4EEAAQEOTA3AgEBBA7k66oBjwdigU5rP2YTqaEi +AyAABABIXes5M9e8fRB1EG+yswF0sx/bvJ3wBYAGtlPG8g== +-----END PRIVATE KEY-----'; + PKCS8::useNamedCurve(); $this->assertSameNL($expected, $key->toString('PKCS8')); } @@ -194,11 +212,11 @@ AAQA9xdWGJ6vV23+vkdq0C8BLJVg5E3amMyf/5keGa4= // explanation of the differences between the above key // and the following key $expected = '-----BEGIN PRIVATE KEY----- -MIHCAgEAMIGABgcqhkjOPQIBMHUCAQEwHAYHKoZIzj0BAjARAgFxBgkqhkjOPQEC +MIHBAgEAMIGABgcqhkjOPQIBMHUCAQEwHAYHKoZIzj0BAjARAgFxBgkqhkjOPQEC AwICAQkwIAQOMIglDKbnx/5knOhYIPcEDui+5NPiJgdEGIvg6ccjBB8EAJ1zYW81 -9KsUB9c1YsEPAKUoMCd5WO6E0TFe0xiGAg8BAAAAAAAAANnM7Io55W8EOjA4AgEB -BA8AXtfDMRsRTx8snPbWHquhIgMgAAQA9xdWGJ6vV23+vkdq0C8BLJVg5E3amMyf -/5keGa4= +9KsUB9c1YsEPAKUoMCd5WO6E0TFe0xiGAg8BAAAAAAAAANnM7Io55W8EOTA3AgEB +BA5e18MxGxFPHyyc9tYeq6EiAyAABAD3F1YYnq9Xbf6+R2rQLwEslWDkTdqYzJ// +mR4Zrg== -----END PRIVATE KEY-----'; PKCS8::useSpecifiedCurve(); $this->assertSameNL($expected, $key->toString('PKCS8')); @@ -507,4 +525,50 @@ lEIq93iMVzIArjGaKrFDAAAADHJvb3RAdmFncmFudAE= $this->assertTrue($key->verify('zzz', $sig)); $this->assertTrue($key->withSignatureFormat('SSH2')->verify('zzz', $sig2)); } + + /** + * @group github1712 + */ + public function testKeyTooLarge() + { + $this->expectException('RangeException'); + + $key = '-----BEGIN PRIVATE KEY----- +MIIEDwIBADATBgcqhkjOPQIBBggqhkjOPQMBBwSCA/MwggPvAgEBBIID6P////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////8= +-----END PRIVATE KEY-----'; + + $private = EC::loadFormat('PKCS8', $key); + } + + /** + * @group github1712 + */ + public function testLargeCurve25519Key() + { + $raw = pack('H*', '8426220e7a57dc8d685d3966e3a23600e32563ce6033e07d0c89dbb5bd296577'); + $key = EC::loadFormat('MontgomeryPrivate', $raw); + + $this->assertSameNL($raw, $key->toString('MontgomeryPrivate')); + } }