PackageTrack
Sign in Get early access

paragonie/ecc

PHP Elliptic Curve Cryptography library

v2.6.0 903K downloads/mo #3558 most downloaded on Packagist paragonie/phpecc

What this package is like to depend on

Last release 3 days ago

20 Aug 2026

Ships on a steady schedule

a new release about every 9 months

Nearly every release is documented

notes for 8 of 8 stable releases

Nothing withdrawn

no release was ever pulled

2 years old

8 releases · first in 2024

1 release in the last 12 months

see the full history below

Release timeline

8 releases · Apr 2024 to Aug 2026
2025 2026
Release Pre-release

Releases

latest 8
  1. v2.6.0 20 Aug 2026
    Release notes

    What's Changed

    Full Changelog: v2.5.0...v2.6.0

    Open source →
  2. v2.5.0 19 Jul 2025
    Release notes

    The most important thing for most users is that PHP 8.4 deprecation warnings will no longer be emitted by this library.

    However, we did introduce a deprecation of our own: The SchnorrSignature class is now deprecated and has been replaced
    by an identical class called SchnorrSigner. Code that used the old name will continue to function until the next
    major version release.

    What's New

    SchnorrSigner - signWithKey(), verifyWithKey()

    The Schnorr implementation we adopted in v2.4.0 didn't blend in seamlessly with the rest of the PHPECC user experience,
    so now there are two new methods, signWithKey() and verifyWithKey(), that expect key objects rather than hexadecimal
    encoded strings.

    $schnorr = new \Mdanter\Ecc\Crypto\Signature\SchnorrSigner();
    
    $signature = $schnorr->signWithKey($privateKey, $message);
    
    var_dump(get_class($signature));
    // string(38) "Mdanter\Ecc\Crypto\Signature\Signature"
    
    $valid = $schnorr->verifyWithKey($publicKey, $message);
    if (!$valid) {
        die("invalid signature");
    }

    Pull Requests Since Version 2.4.0

    • Fix SchnorrSignature gmp_hexval to always return 64-character hex strings by @kawax in #34
    • Update Schnorr test vectors by @1ma in #33
    • restore missing Schnorr test by @1ma in #38
    Open source →
  3. v2.4.0 21 Jan 2025
    Release notes

    What's Changed

    New Contributors

    Full Changelog: v2.3.0...v2.4.0

    Open source →
  4. v2.3.0 01 May 2024
    Release notes

    Rapid Development Should Be Over For Now

    As of v2.3.0, we feel comfortable with the security of PHP ECC, so we removed the ugly notice from the README. So the pace of release should slow down considerably (unless something breaks, of course).

    Naturally, this means there are significant changes since v2.2.0. Let's get into them.

    EccFactory Rejects Insecure Curves By Default

    This is documented in the README, but for the sake of convenience:

    The EccFactory class will, by default, only allow you to instantiate secure elliptic curves.
    An elliptic curve is considered secure if one or more of the following is true:

    1. If we can depend on OpenSSL to provide its implementation, we will. This is considered secure.
    2. If we have an optimized constant-time implementation, it is secure.
    3. If the elliptic curve discrete logarithm problem (ECDLP) for the curve has a security level in
      equivalent to less than 120 bits, it is considered insecure. (We do not provide constant-time
      implementations for these curves, so step 2 should already fail these curves.)
    4. Otherwise, it is considered insecure. EccFactory will not allow them by default.

    To bypass this guard-rail, simply pass true to the second argument, like so:

    <?php
    use Mdanter\Ecc\EccFactory;
    use Mdanter\Ecc\Math\GmpMath;
    
    $adapter = new GmpMath();
    // This will throw an InsecureCurveException:
    // $p192 = EccFactory::getNistCurves($adapter)->generator192();
    
    // This will succeed:
    $p192 = EccFactory::getNistCurves($adapter, true)->generator192();
    
    // This will also succeed, without any special considerations:
    $p256 = EccFactory::getNistCurves()->generator256();

    This means if you previously followed the examples and used EccFactory to get your elliptic curves, great news! You're protected by default.

    Unfortunately, if you were selecting insecure curves for whatever reason, upgrading to v2.3.0 will cause your application to throw an InsecureCurveException now. You can pass true to the second argument of the appropriate static method to disable this guard-rail, but why do that when you could instead use a more secure algorithm?

    The choice is ultimately yours. We just have strong opinions on which is the better one.

    Added Support for the Brainpool Curves

    Not all of them, mind you. Only brainpoolP256r1, brainpoolP384r1, and brainpoolP512r1.

    (German PHP software developers rejoice! You can now comply with your government's Technical Guideline BSI TR-03111 technical requirements for elliptic curve cryptography with this library.)

    Added Secure Factories

    While EccFactory seems the be the primary way that other developers were utilizing PHP ECC in their software, we took the liberty of also creating SecureCurveFactory, which extends CurveFactory and throws exceptions if you ask for something insecure.

    • Curves with an ECDLP security of less than 120 bits are always considered insecure.
    • If you do not request our optimized constant-time implementation, your calls to SecureCurveFactory mey still succeed on some environments where ext-openssl can provide secure cryptography. Specifically, PHP 8.1+ with OpenSSL 3.0+ ought to work. Otherwise, it will throw an exception, because insecure cryptography is not tolerated by that API.

    We care a lot about misuse resistance and avoiding accidental foot-bullets.

    For your convenience, there's also SecureNistCurve, SecureSecgCurve, and even SecureBrainpoolCurve in the same namespace as CurveFactory and SecureCurveFactory.

    Open source →
  5. v2.2.0 30 Apr 2024
    Release notes

    Performance and Security Enhancements

    • Implemented constant-time complete point arithmetic for secp256k1
    • Implemented constant-time complete point arithmetic for NIST P-521
    • PHP 8.2+: most public API parameters are marked as SensitiveParameter
    • PHP 8.1+ with OpenSSL v3+: PHPECC will now prefer OpenSSL if it's available.

    To disable OpenSSL for a specific operation, you can call disableOpenssl() on the
    Signer, EcDH, or NamedCurveFp classes. To re-enable OpenSSL, the enableOpenssl()
    method is provided.

    $curve = $bobPublicKey->getCurve();
    $curve->disableOpenssl();

    Note: Due to an issue reported by @mayestik1 in #20 we are no longer specifying a replace
    directive in our composer.json for mdanter/ecc,

    Open source →
  6. v2.1.0 28 Apr 2024
    Release notes

    Introduced hardened implementations of NIST P-256 and NIST P-384.

    This implementations assumes that bigint multiplication is constant-time. On most hardware, this is a good assumption. BearSSL has good documentation on the hardware where this assumption is false. The odds are good that you're running PHP on hardware that uses constant-time multiplication.

    Despite being PHP implementations of constant-time code, the performance hit for using these curves is minimal. There is probably some opportunity for further optimizations.

    We do not force the use of our implementation by default, due to the minor performance hit it does have. To use the new code:

      $nistFactory = EccFactory::getNistCurves($adapter);
    
    - $g256 = $nistFactory->generator256($rng);
    + $g256 = $nistFactory->generator256($rng, true);
    
    - $g384 = $nistFactory->generator384$rng);
    + $g384 = $nistFactory->generator384($rng, true);
    
    - $p256 = $nistFactory->curve256();
    + $p256 = $nistFactory->optimizedCurve256();
    
    - $p384 = $nistFactory->curve384();
    + $p384 = $nistFactory->optimizedCurve384();

    We will update EasyECC to use this API in the next release.

    Open source →
  7. v2.0.1 24 Apr 2024
    Release notes

    The NVD Description for CVE-2024-33851 is Incorrect.

    The vulnerability is present in all versions of mdanter/ecc. If you have not migrated to our fork, you are vulnerable.

    CVE-2024-33851 vulnerability was fixed in v2.0.1 of our fork of their code. The wording of the CVE description implies we introduced it. That is incorrect.

    See also: our pull request to correct these details.

    Original release notes below

    Thanks to @xabbuh in #7, we now prevent namespace conflicts by replacing mdanter/ecc in our Composer config.

    Security Fixes

    Branch-based timing leak in Point addition

    All previous versions of PHPECC contained a snippet of code that acted like this (pseudocode):

    if ($pointA->x === $pointB->x) {
        if ($pointA->y === $pointB->y) {
            return $pointA->double();    
        } else {
            return $pointA->getCurve()->pointAtInfinity();
        }
    }

    This is a textbook branch-based timing side-channel: The point-doubling calculation takes
    much longer than returning a point at infinity (which is basically initialized to zero).

    To alleviate this, we used a conditional swap. Now the point doubling is always calculated,
    and only used if needed.

    When both points are public keys, this doesn't leak anything useful to an attacker. However,
    this loop is also used in point addition as part of scalar multiplication.

    This occurs in two places that may be concerning to PHPECC users:

    1. Shared secret calculation in EcDH
    2. Calculating a public key from a secret key

    If an attacker can influence many values for X to match, but Y to differ, they may be able to leak
    intermediate values from the Montgomery ladder by observing the runtime of the algorithm.

    Note:

    The current implementation still branches on if X is equal, but doesn't leak whether Y is equal
    too. The branch may seem like a risk, but the comparison that leads to the branch is constant-time.
    You cannot get a higher resolution viewpoint into the bits or bytes being compared; you only
    learn the end result.

    Based on this, an attacker has a 1/n chance (where n is the order of the curve) of learning anything
    useful. The risk of such leakage is about as high as guessing a random AES key correctly for most
    curves.

    Open source →
  8. v2.0.0 24 Apr 2024
    Release notes

    Version 2.0.0 is the inaugural release for Paragon Initiative Enterprise's fork of phpecc.

    We raised the minimum PHP version to 7.1 in order to make PHP 8.4 support possible.

    Security Fixes

    ECDSA Canonicalization

    We introduced a mechanism for mitigating malleable ECDSA signatures.
    This is especially important for cryptocurrency-adjacent projects (which the most popular
    users of phpecc are) to prevent double-spend attacks.

    The Signer class now takes an optional second boolean argument. Setting this to true will
    have two effects:

    1. When signing, if the resulting signature (R, S) has S larger than half the order of the
      elliptic curve group (n), the signature will instead be (R, n - S).
    2. When verifying a signature (R, S), if S is larger than half the order of the elliptic
      curve group, it will return false instead of true, even if the signature is otherwise
      valid.

    We recommend setting the second argument to true, but this may break backwards compatibility
    with messages signed with an older or misconfigured library. Therefore, we did not enable it
    by default.

    Constant-Time Signer

    Prior to our fork, when generating a new ECDSA signature, the GMPMath adapter was used.
    This class wraps the GNU Multiple Precision arithmetic library (GMP), which does not aim to
    provide constant-time implementations of algorithms.

    An attacker capable of triggering many signatures and studying the time it takes to perform
    each operation would be able to leak the secret number, k, and thereby learn the private key.

    EcDH Timing Leaks

    Prior to our fork, when calculating a shared secret using the EcDH class, the scalar-point
    multiplication was based on the arithmetic defined by the Point class.

    Even though the previous version of the library implemented a Montgomery ladder, the add(),
    mul(), and getDouble() methods on the Point class were not constant-time. This means
    that your ECDH private keys were leaking information about each bit of your private key
    through a timing side-channel.

    We fixed this by using a ConstantTimeMath implementation for all arithmetic, rather than
    relying on GMP's algorithm implementations.

    New Features

    • IEEE-P1363 Signature Format
    • ConstantTimeMath, which extends GMPMath and provides constant-time implementations of
      some algorithms needed for elliptic curve cryptography

    Migration Guide

    Replace mdanter/ecc or phpecc/phpecc in your composer.json with the following:

    {
      "require": {
        /* ... */
        "paragonie/ecc": "^2"
        /* ... */
      }
    }

    Run composer update after you have made your changes.

    Next, make sure any time your code instantiates a Signer object, set the second
    constructor argument to true. Also, consider using ConstantTimeMath for any
    code that generates a signature.

    + use Mdanter\Ecc\Math\ConstantTimeMath;
    
    - $signer = new Signer(new GMPMath());
    + $signer = new Signer(new ConstantTimeMath(), true);

    Everything else should be a drop-in replacement.

    Open source →

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive