Elliptic Curves
Loading and saving keys is discussed in Public Keys: Overview.
Supported Formats
- PKCS1 [1]
- Keys start with
-----BEGIN EC PRIVATE KEY-----
or-----BEGIN EC PARAMETERS-----
- Keys start with
- PKCS8 [1]
- Keys start with
-----BEGIN PRIVATE KEY-----
or-----BEGIN ENCRYPTED PRIVATE KEY-----
or-----BEGIN PUBLIC KEY-----
- Keys start with
- PuTTY [2]
- Public keys start off with
---- BEGIN SSH2 PUBLIC KEY ----
- Public keys start off with
- OpenSSH [2][3]
- Private keys start with
-----BEGIN OPENSSH PRIVATE KEY-----
- Private keys start with
- JWK [4]
- XML [5]
A more in-depth discussion of the common formats can be found in Common Key Formats. See Sample EC Keys for actual samples.
[1] Supports both named and specified curves.
[2] The only curves supported by these formats are as follows:
nistp256 (alias: secp256r1, prime256v1)
nistp384 (alias: secp384r1)
nistp521 (alias: secp521r1)
Ed25519
The first three are the required curves of RFC5656 and the last one is specified in draft-ietf-curdle-ssh-ed25519-02.
Specified curves are not supported - only named curves.
[3] Quoting the OpenSSH 6.5/6.5p1 (2014-01-30) changelog, "this format is used unconditionally for Ed25519 keys". No newer version of OpenSSH, as of this writing, seems to change this.
[4] The only curves supported by this format are as follows:
nistp256 (alias: secp256r1, prime256v1)
nistp384 (alias: secp384r1)
nistp521 (alias: secp521r1)
secp256k1
Ed25519 (as an OKP key)
Ed448 (as an OKP key)
[5] Supports regular ECKeyValues and RFC4050 formatted ECKeyValues. Supports named curves and has expiremental specified prime curve support. Specified binary curves are not supported at all.
Parameters
Parameters consist of either the curve name or the curve parameters. They correspond to ECParameters in RFC5480.
PKCS1 is the only format that supports Parameters. They can be extracted from a private or public key by doing $key->getParameters()
.
Whereas public and private keys are instances of \phpseclib3\Crypt\Common\PublicKey
and \phpseclib3\Crypt\Common\PrivateKey
, respectively, parameters are an instance of phpseclib3\Crypt\EC\Parameters
(which is what $key->getParameters()
returns).
Supported Curves
The following curves are supported:
- Curve448
- Curve25519
- Ed448
- Ed25519
- Brainpool curves
- SECG prime field curves, which includes, most notably:
- NIST P-256 (the most popular curve)
- secp256k1 (used by BitCoin)
- SECG binary field curves
- these curves are rarely used and as such have not been as highly optimized as the prime field curves
(SECG stands for Standards for Efficient Cryptography)
The full list of curves can be found at https://github.com/phpseclib/phpseclib/tree/3.0/phpseclib/Crypt/EC/Curves
Named vs Specified Curves
To understand the difference between named and specified curves it first helps to understand that there are multiple "classes" of curves.
Montgomery | Twisted Edwards | Weierstrass | |
---|---|---|---|
Individual Curves | Curve25519, Curve448 | Ed25519, Ed448 | everything else |
All curves correspond to an equation. For Weierstrass Curves that equation has the following form:
Y 2 + a1 X Y + a3 Y = X 3 + a2 X 2 + a4 X + a6
For prime field Weierstrass Curves a1, a3 and a2 are always 0. For binary field Weierstrass Curves a3 and a2 are always 0 and a1 is always 1.
The remaining variables can be specified either explicitly, using a Specified Curve or implictly by invoking a Named Curve. phpseclib supports both.
Montgomery and Twisted Edwards Curves do not have user-definable coefficients and therefore the concept of a "specified curve" is inapplicable.
Named curves are the default. Specified curves can be enabled by doing PKCS1::useSpecifiedCurve()
or PKCS8::useSpecifiedCurve()
. Named curves can be specified by doing PKCS1::useNamedCurve()
or PKCS8::useSpecifiedCurve()
.
Specified curves can also be enabled by doing $key->toString('PKCS8', ['namedCurve' => false])
or $key->toString('PKCS1', ['namedCurve' => false])
.
Creating Keys
Keys can be created thusly:
use phpseclib3\Crypt\EC;
$private = EC::createKey('Ed25519');
$public = $private->getPublicKey();
Creating / Verifying Signatures
Signatures can be created / verified thusly:
//$private = $private->withSignatureFormat('ASN1');
$signature = $private->sign($message);
echo $private->getPublicKey()->verify($message, $signature) ?
'valid signature' :
'invalid signature';
The signatures generated are not deterministic, as discussed in RFC6979. Such determinism is chiefly of benefit when a CSPRNG is not available and with PHP there is one that's available.
Signatures have two components - r and s. How these two components are combined to a single string depends on the signature format being employed.
ASN1
This is the default format. ASN1-formatted signatures employee the format discussed in RFC3279. This is the format used by X.509 certificates.
SSH2
SSH2-formatted signatures employee the format discussed in RFC4253 or (for Ed25519) draft-ietf-curdle-ssh-ed25519-02.
IEEE
This format used with JSON Web Signatures (JWS; see RFC7515#page-45), JavaScript's Web Cryptography API, et al. SubtleCrypto: sign() method - Web APIs | MDN explains why IEEE is used as the name:
This encoding was also proposed by the IEEE 1363-2000 standard, and is sometimes referred to as the IEEE P1363 format. It differs from the X.509 signature structure, which is the default format produced by some tools and libraries such as OpenSSL.
In the case of JSON Web Signatures the signature should also be passed through \phpseclib3\Common\Functions\Strings::base64url_encode()
.
Raw
Returns an array with r and s as keys.
Key Attributes
$key->getCurve()
returns either a string with the name of the curve or an array containing the keys specified parameters.
$key->getLength()
returns the length of the modulo, in bits.
All the with
methods have corresponding get
methods as follows:
Setter | Getter |
---|---|
withContext | getContext |
withHash | getHash |
withSignatureFormat | getSignatureFormat |
While withHash
accepts strings, getHash
returns a Hash object (that can be cast to a string via __toString).
withContext
is only usable with Ed25519 and Ed448. withHash
does not work for Curve25519, Curve448, Ed25519 or Ed448.