# ECC

ECC (Elliptic Curve Cryptography) is a modern and efficient type of public key cryptography. Its security is based on the difficulty to solve discrete logarithms on the field defined by specific equations computed over a curve.

ECC can be used to create digital signatures or to perform a key exchange.

Compared to traditional algorithms like RSA, an ECC key is significantly smaller at the same security level. For instance, a 3072-bit RSA key takes 768 bytes whereas the equally strong NIST P-256 private key only takes 32 bytes (that is, 256 bits).

With this module you can generate new ECC keys:

    >>> from Crypto.PublicKey import ECC
    >>>
    >>> mykey = ECC.generate(curve='p256')

export an ECC private key and protect it with a password, so that it is resistant to brute force attacks:

    >>> pwd = b'secret'
    >>> with open("myprivatekey.pem", "wt") as f:
    >>>     data = mykey.export_key(format='PEM'
                                    passphrase=pwd,
                                    protection='PBKDF2WithHMAC-SHA512AndAES256-CBC',
                                    prot_params={'iteration_count':131072})
    >>>     f.write(data)

and reimport it later:

    >>> pwd = b'secret'
    >>> with open("myprivatekey.pem", "rt") as f:
    >>>     data = f.read()
    >>>     mykey = ECC.import_key(data, pwd)

You can also export the public key, which is not sensitive:

    >>> with open("mypublickey.pem", "wbt) as f:
    >>>     data = mykey.public_key().export_key()

Curve | Strings accepted for the `curve` API parameter
--- | ---
NIST P-192 | `'NIST P-192'`, `'p192'`, `'P-192'`, `'prime192v1'`, `'secp192r1'`
NIST P-224 | `'NIST P-224'`, `'p224'`, `'P-224'`, `'prime224v1'`, `'secp224r1'`
NIST P-256 | `'NIST P-256'`, `'p256'`, `'P-256'`, `'prime256v1'`, `'secp256r1'`
NIST P-384 | `'NIST P-384'`, `'p384'`, `'P-384'`, `'prime384v1'`, `'secp384r1'`
NIST P-521 | `'NIST P-521'`, `'p521'`, `'P-521'`, `'prime521v1'`, `'secp521r1'`
Ed25519 | `'ed25519'`, `'Ed25519'`
Ed448 | `'ed448'`, `'Ed448'`

For more information about each NIST curve see FIPS 186-4, Section D.1.2.

The Ed25519 and the Ed448 curves are defined in RFC8032.

The ECC key can be used to perform or verify signatures, using the modules `Crypto.Signature.DSS` (ECDSA; NIST curves only) or `Crypto.Signature.eddsa` (EdDSA; Ed25519 and Ed448 curve only).

class Crypto.PublicKey.ECC.EccKey(**kwargs)

  Class defining an ECC key. Do not instantiate directly. Use `generate()`, `construct()` or `import_key()` instead.

  Variables:

    - curve (string) – The name of the curve as defined in the ECC table.

    - pointQ (`EccPoint`) – an ECC point representating the public component.

    - d (integer) – A scalar that represents the private component in NIST P curves. It is smaller than the order of the generator point.

    - seed (bytes) – A seed that representats the private component in EdDSA curves (Ed25519, 32 bytes; Ed448, 57 bytes).

  export_key(**kwargs)

    Export this ECC key.

    Parameters:

      - format (string) –

        The output format:

        - `'DER'`. The key will be encoded in ASN.1 DER format (binary). For a public key, the ASN.1 `subjectPublicKeyInfo` structure defined in RFC5480 will be used. For a private key, the ASN.1 `ECPrivateKey` structure defined in RFC5915 is used instead (possibly within a PKCS#8 envelope, see the `use_pkcs8` flag below).

        - `'PEM'`. The key will be encoded in a PEM envelope (ASCII).

        - `'OpenSSH'`. The key will be encoded in the OpenSSH format (ASCII, public keys only).

        - `'SEC1'`. The public key (i.e., the EC point) will be encoded into `bytes` according to Section 2.3.3 of SEC1 (which is a subset of the older X9.62 ITU standard). Only for NIST P-curves.

        - `'raw'`. The public key will be encoded as `bytes`, without any metadata.

          - For NIST P-curves: equivalent to `'SEC1'`.

          - For EdDSA curves: `bytes` in the format defined in RFC8032.

      - passphrase (bytes or string) – (Private keys only) The passphrase to protect the private key.

      - use_pkcs8 (boolean) –

        (Private keys only) If `True` (default and recommended), the PKCS#8 representation will be used. It must be `True` for EdDSA curves.

        If `False` and a passphrase is present, the obsolete PEM encryption will be used.

      - protection (string) – When a private key is exported with password-protection and PKCS#8 (both `DER` and `PEM` formats), this parameter MUST be present, For all possible protection schemes, refer to the encryption parameters of PKCS#8. It is recommended to use `'PBKDF2WithHMAC-SHA5126AndAES128-CBC'`.

      - compress (boolean) –

        If `True`, the method returns a more compact representation of the public key, with the X-coordinate only.

        If `False` (default), the method returns the full public key.

        This parameter is ignored for EdDSA curves, as compression is mandatory.

      - prot_params (dict) – When a private key is exported with password-protection and PKCS#8 (both `DER` and `PEM` formats), this dictionary contains the parameters to use to derive the encryption key from the passphrase. For all possible values, refer to the encryption parameters of PKCS#8. The recommendation is to use `{'iteration_count':21000}` for PBKDF2, and `{'iteration_count':131072}` for scrypt.

    Warning

    If you don’t provide a passphrase, the private key will be exported in the clear!

    Note

    When exporting a private key with password-protection and PKCS#8 (both `DER` and `PEM` formats), any extra parameters to `export_key()` will be passed to `Crypto.IO.PKCS8`.

    Returns:

      A multi-line string (for `'PEM'` and `'OpenSSH'`) or `bytes` (for `'DER'`, `'SEC1'`, and `'raw'`) with the encoded key.

  has_private()

    `True` if this key can be used for making signatures or decrypting data.

  public_key()

    A matching ECC public key.

    Returns:

      a new `EccKey` object

class Crypto.PublicKey.ECC.EccPoint(x, y, curve='p256')

  A class to model a point on an Elliptic Curve.

  The class supports operators for:

  - Adding two points: `R = S + T`

  - In-place addition: `S += T`

  - Negating a point: `R = -T`

  - Comparing two points: `if S == T: ...` or `if S != T: ...`

  - Multiplying a point by a scalar: `R = S*k`

  - In-place multiplication by a scalar: `T *= k`

  Variables:

    - x (integer) – The affine X-coordinate of the ECC point

    - y (integer) – The affine Y-coordinate of the ECC point

    - xy – The tuple with affine X- and Y- coordinates

  copy()

    Return a copy of this point.

  double()

    Double this point (in-place operation).

    Returns:

      This same object (to enable chaining).

  is_point_at_infinity()

    `True` if this is the point-at-infinity.

  point_at_infinity()

    Return the point-at-infinity for the curve.

  size_in_bits()

    Size of each coordinate, in bits.

  size_in_bytes()

    Size of each coordinate, in bytes.

exception Crypto.PublicKey.ECC.UnsupportedEccFeature

Crypto.PublicKey.ECC.construct(**kwargs)

  Build a new ECC key (private or public) starting from some base components.

  In most cases, you will already have an existing key which you can read in with `import_key()` instead of this function.

  Parameters:

    - curve (string) – Mandatory. The name of the elliptic curve, as defined in the ECC table.

    - d (integer) – Mandatory for a private key and a NIST P-curve (e.g., P-256): the integer in the range `[1..order-1]` that represents the key.

    - seed (bytes) – Mandatory for a private key and an EdDSA curve. It must be 32 bytes for Ed25519, and 57 bytes for Ed448.

    - point_x (integer) – Mandatory for a public key: the X coordinate (affine) of the ECC point.

    - point_y (integer) – Mandatory for a public key: the Y coordinate (affine) of the ECC point.

  Returns:

    a new ECC key object

  Return type:

    `EccKey`

Crypto.PublicKey.ECC.generate(**kwargs)

  Generate a new private key on the given curve.

  Parameters:

    - curve (string) – Mandatory. It must be a curve name defined in the ECC table.

    - randfunc (callable) – Optional. The RNG to read randomness from. If `None`, `Crypto.Random.get_random_bytes()` is used.

Crypto.PublicKey.ECC.import_key(encoded, passphrase=None, curve_name=None)

  Import an ECC key (public or private).

  Parameters:

    - encoded (bytes or multi-line string) –

      The ECC key to import. The function will try to automatically detect the right format.

      Supported formats for an ECC public key:

      - X.509 certificate: binary (DER) or ASCII (PEM).

      - X.509 `subjectPublicKeyInfo`: binary (DER) or ASCII (PEM).

      - SEC1 (or X9.62), as `bytes`. NIST P curves only. You must also provide the `curve_name` (with a value from the ECC table)

      - OpenSSH line, defined in RFC5656 and RFC8709 (ASCII). This is normally the content of files like `~/.ssh/id_ecdsa.pub`.

      Supported formats for an ECC private key:

      - A binary `ECPrivateKey` structure, as defined in RFC5915 (DER). NIST P curves only.

      - A PKCS#8 structure (or the more recent Asymmetric Key Package, RFC5958): binary (DER) or ASCII (PEM).

      - OpenSSH 6.5 and newer versions (ASCII).

      Private keys can be in the clear or password-protected.

      For details about the PEM encoding, see RFC1421/RFC1423.

    - passphrase (byte string) – The passphrase to use for decrypting a private key. Encryption may be applied protected at the PEM level (not recommended) or at the PKCS#8 level (recommended). This parameter is ignored if the key in input is not encrypted.

    - curve_name (string) – For a SEC1 encoding only. This is the name of the curve, as defined in the ECC table.

  Note

  To import EdDSA private and public keys, when encoded as raw `bytes`, use:

  - `Crypto.Signature.eddsa.import_public_key()`, or

  - `Crypto.Signature.eddsa.import_private_key()`.

  Returns:

    a new ECC key object

  Return type:

    `EccKey`

  Raises:

    ValueError – when the given key cannot be parsed (possibly because the pass phrase is wrong).