ECDSA Cryptographic Signature Library
raw JSON → 0.19.2 verified Tue May 12 auth: no python install: verified quickstart: verified
ecdsa is a pure Python implementation of Elliptic Curve Cryptography (ECC) supporting ECDSA (Elliptic Curve Digital Signature Algorithm), EdDSA (Edwards-curve Digital Signature Algorithm), and ECDH (Elliptic Curve Diffie-Hellman). It is actively maintained with several releases per year, providing a robust solution for digital signatures in Python applications. The current version is 0.19.2.
pip install ecdsa Common errors
error ModuleNotFoundError: No module named 'ecdsa' ↓
cause The 'ecdsa' library has not been installed in the Python environment, or the environment where the code is being run is different from where it was installed.
fix
Install the library using pip:
pip install ecdsa. error ImportError: cannot import name 'SECP256kl' from 'ecdsa' ↓
cause This error occurs due to a common typo when trying to import the SECP256k1 elliptic curve; the lowercase 'l' is used instead of the numeral '1'.
fix
Correct the curve name to 'SECP256k1':
from ecdsa import SECP256k1, SigningKey. error AttributeError: 'VerifyingKey' object has no attribute 'default_hashfunc' ↓
cause This error typically arises when attempting to verify a signature using an older method or when a `VerifyingKey` object has been incorrectly serialized and deserialized, leading to missing internal state, especially when `hashfunc` is not explicitly provided.
fix
When verifying, ensure you explicitly provide the
hashfunc argument, or use the VerifyingKey.from_string (or similar) method to properly reconstruct the key if it was serialized, and ensure compatibility with the library version. Example: verifying_key.verify(signature, message_hash, sigdecode=ecdsa.util.sigdecode_string, hashfunc=hashlib.sha256). error AttributeError: module 'ecdsa' has no attribute 'secp224k1' ↓
cause The `ecdsa` library does not directly expose all elliptic curves as top-level attributes or may not support specific curves like 'secp224k1' (often confused with 'secp224r1' or requiring a different curve instantiation method).
fix
Refer to the
ecdsa.curves module for available curves (e.g., ecdsa.NIST224p or ecdsa.SECP256k1) or use ecdsa.curves.Curve to define a custom curve if it's supported and parameters are known. error ecdsa.BadSignatureError ↓
cause This exception is raised when a signature cannot be successfully verified. Common reasons include incorrect message hashing, wrong public key, signature corruption, or mismatches in signature encoding formats (e.g., DER vs. raw R+S concatenation) or curve parameters between signing and verification processes.
fix
Ensure the message is hashed correctly before signing and verifying, the correct public key is used, and the signature encoding (e.g., DER) is consistently applied during both signing and verification. Double-check the elliptic curve used for key generation and signature operations.
Warnings
breaking CVE-2024-23342 (Minerva Timing Attack) affects P-256 curves in versions 0.18.0 and prior. This side-channel vulnerability allows attackers to leak the internal nonce via timing measurements, potentially leading to private key discovery. The maintainers consider side-channel attacks out of scope, and no fix is planned for this pure-Python implementation. ↓
fix For security-sensitive applications where side-channel resistance is critical, consider using a cryptographic library with constant-time implementations (e.g., `cryptography` library) or ensure your environment mitigates timing attacks.
breaking CVE-2026-33936 fixed a DER parsing issue where truncated buffers were not detected, which could lead to unexpected exceptions in functions like `SigningKey.from_der()` when parsing malformed data. ↓
fix Update to version 0.19.2 or later to ensure robust DER parsing and prevent potential DoS from malformed inputs. Carefully validate any DER-encoded inputs from untrusted sources.
gotcha When serializing keys using `to_pem()` or `to_der()`, in versions 0.16.0 and later, it is recommended to explicitly set `format="pkcs8"`. Not doing so will default to the legacy 'ssleay' format, which may not be the desired standard for modern applications or interoperability. ↓
fix Always specify `format="pkcs8"` when calling `to_pem()` or `to_der()` for private keys: `key.to_pem(format="pkcs8")`.
deprecated Official support for Python 3.3 and 3.4 was dropped starting from version 0.19.0 due to CI environment challenges. ↓
fix Upgrade to a currently supported Python version (e.g., Python 3.8 or newer).
gotcha The `to_string()` method, inherited from Python 2 naming conventions, actually returns `bytes` objects, not Python `str`. ↓
fix Handle the return value as `bytes` when using `to_string()`.
gotcha When deserializing keys using `SigningKey.from_string(s, curve)` or `VerifyingKey.from_string(s, curve)`, the `curve` parameter *must* be explicitly provided as the short string format does not embed curve information. If the wrong curve is provided, verification will fail or lead to incorrect keys. ↓
fix Ensure you store and provide the correct elliptic curve (e.g., `NIST256p`) when using `from_string()`.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.03s 19.0M
3.10 alpine (musl) - - 0.03s 19.0M
3.10 slim (glibc) wheel 1.6s 0.03s 20M
3.10 slim (glibc) - - 0.02s 20M
3.11 alpine (musl) wheel - 0.05s 21.2M
3.11 alpine (musl) - - 0.06s 21.2M
3.11 slim (glibc) wheel 1.7s 0.04s 22M
3.11 slim (glibc) - - 0.04s 22M
3.12 alpine (musl) wheel - 0.04s 13.0M
3.12 alpine (musl) - - 0.04s 13.0M
3.12 slim (glibc) wheel 1.6s 0.04s 14M
3.12 slim (glibc) - - 0.04s 14M
3.13 alpine (musl) wheel - 0.04s 12.7M
3.13 alpine (musl) - - 0.04s 12.6M
3.13 slim (glibc) wheel 1.5s 0.04s 13M
3.13 slim (glibc) - - 0.04s 13M
3.9 alpine (musl) wheel - 0.05s 18.5M
3.9 alpine (musl) - - 0.04s 18.5M
3.9 slim (glibc) wheel 1.9s 0.03s 19M
3.9 slim (glibc) - - 0.03s 19M
Imports
- SigningKey
from ecdsa import SigningKey - VerifyingKey
from ecdsa import VerifyingKey - NIST256p
from ecdsa import NIST256p - SECP256k1
from ecdsa import SECP256k1
Quickstart verified last tested: 2026-04-24
import hashlib
from ecdsa import SigningKey, NIST256p, VerifyingKey
# 1. Generate a private key using the NIST256p curve
sk = SigningKey.generate(curve=NIST256p)
print("Private Key (hex):", sk.to_string().hex())
# 2. Derive the public key
vk = sk.get_verifying_key()
print("Public Key (hex):", vk.to_string().hex())
# 3. Message to sign (must be bytes)
message = b"This is a test message to be signed."
# Hash the message before signing
message_hash = hashlib.sha256(message).digest()
# 4. Sign the message hash
signature = sk.sign_digest(message_hash)
print("Signature (hex):", signature.hex())
# 5. Verify the signature
try:
assert vk.verify_digest(signature, message_hash) == True
print("Signature is valid.")
except Exception as e:
print(f"Signature verification failed: {e}")