mirror of
https://github.com/danog/phpseclib.git
synced 2024-12-02 09:38:06 +01:00
EC: eliminate dynamic property from Ed25519/448 handling
This commit is contained in:
parent
0b3c6e27fc
commit
b1aef24a86
@ -156,6 +156,7 @@ abstract class AsymmetricKey
|
||||
}
|
||||
|
||||
$components['format'] = $format;
|
||||
$components['secret'] = isset($components['secret']) ? $components['secret'] : '';
|
||||
$comment = isset($components['comment']) ? $components['comment'] : null;
|
||||
$new = static::onLoad($components);
|
||||
$new->format = $format;
|
||||
@ -235,6 +236,7 @@ abstract class AsymmetricKey
|
||||
}
|
||||
|
||||
$components['format'] = $format;
|
||||
$components['secret'] = isset($components['secret']) ? $components['secret'] : '';
|
||||
|
||||
$new = static::onLoad($components);
|
||||
$new->format = $format;
|
||||
|
@ -50,7 +50,7 @@ abstract class JWK
|
||||
return $key;
|
||||
}
|
||||
|
||||
if (count($key->keys) != 1) {
|
||||
if (count($key->keys) != 1) {
|
||||
throw new \RuntimeException('Although the JWK key format supports multiple keys phpseclib does not');
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ namespace phpseclib3\Crypt\Common\Formats\Keys;
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Crypt\AES;
|
||||
use phpseclib3\Crypt\Random;
|
||||
use phpseclib3\Exception\UnsupportedFormatException;
|
||||
|
||||
/**
|
||||
* OpenSSH Formatted RSA Key Handler
|
||||
|
@ -27,11 +27,11 @@
|
||||
|
||||
namespace phpseclib3\Crypt\DSA\Formats\Keys;
|
||||
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor;
|
||||
use phpseclib3\File\ASN1;
|
||||
use phpseclib3\File\ASN1\Maps;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
|
||||
/**
|
||||
* PKCS#1 Formatted DSA Key Handler
|
||||
|
@ -170,7 +170,13 @@ abstract class EC extends AsymmetricKey
|
||||
$reflect->getShortName();
|
||||
|
||||
$curve = new $curve();
|
||||
$privatekey->dA = $dA = $curve->createRandomMultiplier();
|
||||
if ($curve instanceof TwistedEdwardsCurve) {
|
||||
$arr = $curve->extractSecret(Random::string($curve instanceof Ed448 ? 57 : 32));
|
||||
$privatekey->dA = $dA = $arr['dA'];
|
||||
$privatekey->secret = $arr['secret'];
|
||||
} else {
|
||||
$privatekey->dA = $dA = $curve->createRandomMultiplier();
|
||||
}
|
||||
if ($curve instanceof Curve25519 && self::$engines['libsodium']) {
|
||||
//$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000');
|
||||
//$QA = sodium_crypto_scalarmult($dA->toBytes(), $r);
|
||||
@ -220,6 +226,7 @@ abstract class EC extends AsymmetricKey
|
||||
|
||||
if (isset($components['dA'])) {
|
||||
$new->dA = $components['dA'];
|
||||
$new->secret = $components['secret'];
|
||||
}
|
||||
|
||||
if ($new->curve instanceof TwistedEdwardsCurve) {
|
||||
|
@ -156,7 +156,7 @@ class Ed25519 extends TwistedEdwards
|
||||
* Used by the various key handlers
|
||||
*
|
||||
* @param string $str
|
||||
* @return \phpseclib3\Math\PrimeField\Integer
|
||||
* @return array
|
||||
*/
|
||||
public function extractSecret($str)
|
||||
{
|
||||
@ -179,8 +179,10 @@ class Ed25519 extends TwistedEdwards
|
||||
// secret scalar s.
|
||||
$dA = new BigInteger($h, 256);
|
||||
|
||||
$dA->secret = $str;
|
||||
return $dA;
|
||||
return [
|
||||
'dA' => $dA,
|
||||
'secret' => $str
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,7 +211,7 @@ class Ed25519 extends TwistedEdwards
|
||||
*/
|
||||
public function createRandomMultiplier()
|
||||
{
|
||||
return $this->extractSecret(Random::string(32));
|
||||
return $this->extractSecret(Random::string(32))['dA'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,7 +97,7 @@ class Ed448 extends TwistedEdwards
|
||||
* Used by the various key handlers
|
||||
*
|
||||
* @param string $str
|
||||
* @return \phpseclib3\Math\PrimeField\Integer
|
||||
* @return array
|
||||
*/
|
||||
public function extractSecret($str)
|
||||
{
|
||||
@ -121,6 +121,11 @@ class Ed448 extends TwistedEdwards
|
||||
// secret scalar s.
|
||||
$dA = new BigInteger($h, 256);
|
||||
|
||||
return [
|
||||
'dA' => $dA,
|
||||
'secret' => $str
|
||||
];
|
||||
|
||||
$dA->secret = $str;
|
||||
return $dA;
|
||||
}
|
||||
@ -150,7 +155,7 @@ class Ed448 extends TwistedEdwards
|
||||
*/
|
||||
public function createRandomMultiplier()
|
||||
{
|
||||
return $this->extractSecret(Random::string(57));
|
||||
return $this->extractSecret(Random::string(57))['dA'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,15 +13,15 @@
|
||||
|
||||
namespace phpseclib3\Crypt\EC\Formats\Keys;
|
||||
|
||||
use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor;
|
||||
use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
|
||||
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
|
||||
use phpseclib3\Crypt\EC\Curves\Ed25519;
|
||||
use phpseclib3\Crypt\EC\Curves\secp256k1;
|
||||
use phpseclib3\Crypt\EC\Curves\secp256r1;
|
||||
use phpseclib3\Crypt\EC\Curves\secp384r1;
|
||||
use phpseclib3\Crypt\EC\Curves\secp521r1;
|
||||
use phpseclib3\Crypt\EC\Curves\secp256k1;
|
||||
use phpseclib3\Exception\UnsupportedCurveException;
|
||||
use phpseclib3\Math\BigInteger;
|
||||
|
||||
@ -71,15 +71,15 @@ abstract class JWK extends Progenitor
|
||||
}
|
||||
|
||||
$curve = '\phpseclib3\Crypt\EC\Curves\\' . str_replace('P-', 'nistp', $key->crv);
|
||||
$curve = new $curve;
|
||||
$curve = new $curve();
|
||||
|
||||
if ($curve instanceof TwistedEdwardsCurve) {
|
||||
$QA = self::extractPoint(Strings::base64url_decode($key->x), $curve);
|
||||
if (!isset($key->d)) {
|
||||
return compact('curve', 'QA');
|
||||
}
|
||||
$dA = $curve->extractSecret(Strings::base64url_decode($key->d));
|
||||
return compact('curve', 'dA', 'QA');
|
||||
$arr = $curve->extractSecret(Strings::base64url_decode($key->d));
|
||||
return compact('curve', 'QA') + $arr;
|
||||
}
|
||||
|
||||
$QA = [
|
||||
@ -173,16 +173,15 @@ abstract class JWK extends Progenitor
|
||||
* @param \phpseclib3\Math\BigInteger $privateKey
|
||||
* @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve
|
||||
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
|
||||
* @param string $secret optional
|
||||
* @param string $password optional
|
||||
* @param array $options optional
|
||||
* @return string
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = [])
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = [])
|
||||
{
|
||||
$key = self::savePublicKeyHelper($curve, $publicKey);
|
||||
$key['d'] = $curve instanceof TwistedEdwardsCurve ?
|
||||
$privateKey->secret :
|
||||
$privateKey->toBytes();
|
||||
$key['d'] = $curve instanceof TwistedEdwardsCurve ? $secret : $privateKey->toBytes();
|
||||
$key['d'] = Strings::base64url_encode($key['d']);
|
||||
|
||||
return self::wrapKey($key, $options);
|
||||
|
@ -86,10 +86,11 @@ abstract class MontgomeryPrivate
|
||||
* @param \phpseclib3\Math\BigInteger $privateKey
|
||||
* @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve
|
||||
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
|
||||
* @param string $secret optional
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $privateKey, MontgomeryCurve $curve, array $publicKey, $password = '')
|
||||
public static function savePrivateKey(BigInteger $privateKey, MontgomeryCurve $curve, array $publicKey, $secret = null, $password = '')
|
||||
{
|
||||
if (!empty($password) && is_string($password)) {
|
||||
throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption');
|
||||
|
@ -174,24 +174,25 @@ abstract class OpenSSH extends Progenitor
|
||||
* @param \phpseclib3\Math\BigInteger $privateKey
|
||||
* @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve
|
||||
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
|
||||
* @param string $secret optional
|
||||
* @param string $password optional
|
||||
* @param array $options optional
|
||||
* @return string
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = [])
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = [])
|
||||
{
|
||||
if ($curve instanceof Ed25519) {
|
||||
if (!isset($privateKey->secret)) {
|
||||
if (!isset($secret)) {
|
||||
throw new \RuntimeException('Private Key does not have a secret set');
|
||||
}
|
||||
if (strlen($privateKey->secret) != 32) {
|
||||
if (strlen($secret) != 32) {
|
||||
throw new \RuntimeException('Private Key secret is not of the correct length');
|
||||
}
|
||||
|
||||
$pubKey = $curve->encodePoint($publicKey);
|
||||
|
||||
$publicKey = Strings::packSSH2('ss', 'ssh-ed25519', $pubKey);
|
||||
$privateKey = Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $privateKey->secret . $pubKey);
|
||||
$privateKey = Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $secret . $pubKey);
|
||||
|
||||
return self::wrapPrivateKey($publicKey, $privateKey, $password, $options);
|
||||
}
|
||||
|
@ -165,11 +165,12 @@ abstract class PKCS1 extends Progenitor
|
||||
* @param \phpseclib3\Math\BigInteger $privateKey
|
||||
* @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve
|
||||
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
|
||||
* @param string $secret optional
|
||||
* @param string $password optional
|
||||
* @param array $options optional
|
||||
* @return string
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = [])
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = [])
|
||||
{
|
||||
self::initialize_static_variables();
|
||||
|
||||
|
@ -150,7 +150,9 @@ abstract class PKCS8 extends Progenitor
|
||||
if (substr($key['privateKey'], 0, 2) != "\x04\x20") {
|
||||
throw new \RuntimeException('The first two bytes of the private key field should be 0x0420');
|
||||
}
|
||||
$components['dA'] = $components['curve']->extractSecret(substr($key['privateKey'], 2));
|
||||
$arr = $components['curve']->extractSecret(substr($key['privateKey'], 2));
|
||||
$components['dA'] = $arr['dA'];
|
||||
$components['secret'] = $arr['secret'];
|
||||
}
|
||||
|
||||
if (isset($key['publicKey'])) {
|
||||
@ -205,11 +207,12 @@ abstract class PKCS8 extends Progenitor
|
||||
* @param \phpseclib3\Math\BigInteger $privateKey
|
||||
* @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve
|
||||
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
|
||||
* @param string $secret optional
|
||||
* @param string $password optional
|
||||
* @param array $options optional
|
||||
* @return string
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = '', array $options = [])
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = [])
|
||||
{
|
||||
self::initialize_static_variables();
|
||||
|
||||
@ -219,7 +222,7 @@ abstract class PKCS8 extends Progenitor
|
||||
|
||||
if ($curve instanceof TwistedEdwardsCurve) {
|
||||
return self::wrapPrivateKey(
|
||||
"\x04\x20" . $privateKey->secret,
|
||||
"\x04\x20" . $secret,
|
||||
[],
|
||||
null,
|
||||
$password,
|
||||
|
@ -70,7 +70,9 @@ abstract class PuTTY extends Progenitor
|
||||
if (Strings::shift($private, 4) != "\0\0\0\x20") {
|
||||
throw new \RuntimeException('Length of ssh-ed25519 key should be 32');
|
||||
}
|
||||
$components['dA'] = $components['curve']->extractSecret($private);
|
||||
$arr = $components['curve']->extractSecret($private);
|
||||
$components['dA'] = $arr['dA'];
|
||||
$components['secret'] = $arr['secret'];
|
||||
} else {
|
||||
list($components['dA']) = Strings::unpackSSH2('i', $private);
|
||||
$components['curve']->rangeCheck($components['dA']);
|
||||
@ -85,11 +87,12 @@ abstract class PuTTY extends Progenitor
|
||||
* @param \phpseclib3\Math\BigInteger $privateKey
|
||||
* @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve
|
||||
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
|
||||
* @param string $secret optional
|
||||
* @param string $password optional
|
||||
* @param array $options optional
|
||||
* @return string
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $password = false, array $options = [])
|
||||
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = false, array $options = [])
|
||||
{
|
||||
self::initialize_static_variables();
|
||||
|
||||
@ -109,7 +112,7 @@ abstract class PuTTY extends Progenitor
|
||||
}
|
||||
|
||||
$private = $curve instanceof TwistedEdwardsCurve ?
|
||||
Strings::packSSH2('s', $privateKey->secret) :
|
||||
Strings::packSSH2('s', $secret) :
|
||||
Strings::packSSH2('s', $private);
|
||||
|
||||
return self::wrapPrivateKey($public, $private, $name, $password, $options);
|
||||
|
@ -67,7 +67,9 @@ abstract class libsodium
|
||||
$curve = new Ed25519();
|
||||
$components = ['curve' => $curve];
|
||||
if (isset($private)) {
|
||||
$components['dA'] = $curve->extractSecret($private);
|
||||
$arr = $curve->extractSecret($private);
|
||||
$components['dA'] = $arr['dA'];
|
||||
$components['secret'] = $arr['secret'];
|
||||
}
|
||||
$components['QA'] = isset($public) ?
|
||||
self::extractPoint($public, $curve) :
|
||||
@ -94,20 +96,21 @@ abstract class libsodium
|
||||
* @param \phpseclib3\Math\BigInteger $privateKey
|
||||
* @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve
|
||||
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
|
||||
* @param string $secret optional
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, $password = '')
|
||||
public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, $secret = null, $password = '')
|
||||
{
|
||||
if (!isset($privateKey->secret)) {
|
||||
if (!isset($secret)) {
|
||||
throw new \RuntimeException('Private Key does not have a secret set');
|
||||
}
|
||||
if (strlen($privateKey->secret) != 32) {
|
||||
if (strlen($secret) != 32) {
|
||||
throw new \RuntimeException('Private Key secret is not of the correct length');
|
||||
}
|
||||
if (!empty($password) && is_string($password)) {
|
||||
throw new UnsupportedFormatException('libsodium private keys do not support encryption');
|
||||
}
|
||||
return $privateKey->secret . $curve->encodePoint($publicKey);
|
||||
return $secret . $curve->encodePoint($publicKey);
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,11 @@ class PrivateKey extends EC implements Common\PrivateKey
|
||||
*/
|
||||
protected $dA;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $secret;
|
||||
|
||||
/**
|
||||
* Multiplies an encoded point by the private key
|
||||
*
|
||||
@ -112,7 +117,7 @@ class PrivateKey extends EC implements Common\PrivateKey
|
||||
$curve = $this->curve;
|
||||
$hash = new Hash($curve::HASH);
|
||||
|
||||
$secret = substr($hash->hash($this->dA->secret), $curve::SIZE);
|
||||
$secret = substr($hash->hash($this->secret), $curve::SIZE);
|
||||
|
||||
if ($curve instanceof Ed25519) {
|
||||
$dom = !isset($this->context) ? '' :
|
||||
@ -217,7 +222,7 @@ class PrivateKey extends EC implements Common\PrivateKey
|
||||
{
|
||||
$type = self::validatePlugin('Keys', $type, 'savePrivateKey');
|
||||
|
||||
return $type::savePrivateKey($this->dA, $this->curve, $this->QA, $this->password, $options);
|
||||
return $type::savePrivateKey($this->dA, $this->curve, $this->QA, $this->secret, $this->password, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,9 @@ class Ed448PrivateKey
|
||||
}
|
||||
|
||||
$components = ['curve' => new Ed448()];
|
||||
$components['dA'] = $components['curve']->extractSecret($key);
|
||||
$arr = $components['curve']->extractSecret($key);
|
||||
$components['dA'] = $arr['dA'];
|
||||
$components['secret'] = $arr['secret'];
|
||||
$components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']);
|
||||
|
||||
return $components;
|
||||
|
Loading…
Reference in New Issue
Block a user