# 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]}- Private keys start with
`-----BEGIN OPENSSH PRIVATE KEY-----`

- Private keys start with
**XML**^{[3]}

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]} 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} + a_{1} X Y + a_{3} Y = X ^{3} + a_{2} X ^{2} + a_{4} X + a_{6}*

For prime field Weierstrass Curves ** a_{1}**,

**and**

*a*_{3}**are always 0. For binary field Weierstrass Curves**

*a*_{2}**and**

*a*_{3}**are always 0 and**

*a*_{2}**is always 1.**

*a*_{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.

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