Skip to main content
Version: 4.0

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-----
  • PKCS8 1
    • Keys start with -----BEGIN PRIVATE KEY----- or -----BEGIN ENCRYPTED PRIVATE KEY----- or -----BEGIN PUBLIC KEY-----
  • PuTTY 2
    • Public keys start off with ---- BEGIN SSH2 PUBLIC KEY ----
  • OpenSSH 2 3
    • Private keys start with -----BEGIN OPENSSH PRIVATE KEY-----
  • 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.

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 \phpseclib4\Crypt\Common\PublicKey and \phpseclib4\Crypt\Common\PrivateKey, respectively, parameters are an instance of phpseclib4\Crypt\EC\Parameters (which is what $key->getParameters() returns).

Supported Curves

The following curves are supported:

(SECG stands for Standards for Efficient Cryptography)

The full list of curves can be found at https://github.com/phpseclib/phpseclib/tree/4.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.

MontgomeryTwisted EdwardsWeierstrass
Individual CurvesCurve25519, Curve448Ed25519, Ed448everything else

All curves correspond to an equation. For Weierstrass Curves that equation has the following form:

Y2+a1XY+a3Y=X3+a2X2+a4X+a6Y^2 + a_1 XY + a_3 Y = X^3 + a_2 X^2 + a_4 X + a_6

For prime field Weierstrass Curves a1a_1, a3a_3 and a2a_2 are always 0. For binary field Weierstrass Curves a3a_3 and a2a_2 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 nominally supports both.

Montgomery and Twisted Edwards Curves do not have user-definable coefficients and therefore the concept of a "specified curve" is inapplicable.

Specified curves can be loaded and used and named curves can be saved as specified curves so long as you're saving the curve in either the PKCS1 or PKCS8 formats.

A named curve can be saved as a specified curve by doing PKCS1::useSpecifiedCurve() or PKCS8::useSpecifiedCurve(). One can switch back to saving named curves as named curves by doing PKCS1::useNamedCurve() or PKCS8::useNamedCurve().

A named curve can also be saved as a specified curve by doing $key->toString('PKCS8', ['namedCurve' => false]) or $key->toString('PKCS1', ['namedCurve' => false]).

EC::createKey() only supports the creation of named curves.

Creating Keys

Keys can be created thusly:

use phpseclib4\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, exposed via random_bytes().

Note that this applies to ECDSA only. EdDSA signatures (Ed25519, Ed448) are deterministic by design (see RFC8032 § 8.2 Randomness Considerations); the same (message, key) pair always produces the same signature.

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 \phpseclib4\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:

SetterGetter
withContextgetContext
withHashgetHash
withSignatureFormatgetSignatureFormat

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.

Calling sign() on a Curve25519 or Curve448 key will throw a BadMethodCallException; these Montgomery curves are for key agreement (ECDH) only. For signing on those security levels use Ed25519 or Ed448 instead.

Footnotes

  1. Supports both named and specified curves. 2

  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. 2

  3. Quoting the OpenSSH 6.5/6.5p1 (2014-01-30) changelog, "this format is used unconditionally for Ed25519 keys". Quoting the OpenSSH 9.6/9.6p1 (2023-12-18) changelog, "add support for reading ED25519 private keys in PEM PKCS8 format. Previously only the OpenSSH private key format was supported.".

  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.