{"id":2893,"library":"coincurve","title":"Coincurve: secp256k1 Elliptic Curve Operations","description":"Coincurve is a Python library providing fast and secure bindings for libsecp256k1, the highly optimized C library used by Bitcoin Core for elliptic curve cryptography operations. It offers a clean, easy-to-use API for tasks like key generation, signing, and verification. The current version is 21.0.0, and it maintains frequent updates to libsecp256k1.","status":"active","version":"21.0.0","language":"en","source_language":"en","source_url":"https://github.com/ofek/coincurve","tags":["cryptography","secp256k1","elliptic curve","bitcoin","ethereum"],"install":[{"cmd":"pip install coincurve","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"For generating private keys and signing messages.","symbol":"PrivateKey","correct":"from coincurve import PrivateKey"},{"note":"For handling public keys and verifying signatures.","symbol":"PublicKey","correct":"from coincurve import PublicKey"},{"note":"The function is available directly under the top-level `coincurve` module, not a submodule like `ecdsa`.","wrong":"from coincurve.ecdsa import verify_signature","symbol":"verify_signature","correct":"from coincurve import verify_signature"}],"quickstart":{"code":"import os\nfrom coincurve import PrivateKey, verify_signature\nimport hashlib\n\n# 1. Generate a new private key (or use an existing one)\nprivate_key = PrivateKey()\n\n# Get the corresponding public key\npublic_key = private_key.public_key.format(compressed=True)\nprint(f\"Public Key (compressed): {public_key.hex()}\")\n\n# 2. Define a message to sign (must be hashed to 32 bytes for signing)\nmessage_str = \"Hello, Coincurve!\"\nmessage_hash = hashlib.sha256(message_str.encode('utf-8')).digest()\nprint(f\"Message hash: {message_hash.hex()}\")\n\n# 3. Sign the message\nsignature = private_key.sign(message_hash)\nprint(f\"Signature (DER-encoded): {signature.hex()}\")\n\n# 4. Verify the signature using the public key and message hash\nis_valid = verify_signature(signature, message_hash, public_key)\n\nif is_valid:\n    print(\"Signature is valid!\")\nelse:\n    print(\"Signature is INVALID.\")\n\n# Example of direct verification via PublicKey object (also works)\n# is_valid_direct = private_key.public_key.verify(signature, message_hash)\n# print(f\"Signature is valid (direct Public Key method): {is_valid_direct}\")","lang":"python","description":"This quickstart demonstrates how to generate a secp256k1 private key, derive its public key, sign a hashed message, and verify the signature using `coincurve`. Note that `private_key.sign()` produces a DER-encoded signature expected by `verify_signature`."},"warnings":[{"fix":"Upgrade Python to 3.9 or newer. Alternatively, pin `coincurve<21.0.0` if Python upgrade is not feasible.","message":"Python 3.8 support was dropped in `coincurve` version 21.0.0. Users on Python 3.8 or older must upgrade their Python environment or use an earlier `coincurve` version.","severity":"breaking","affected_versions":">=21.0.0"},{"fix":"Ensure CMake is installed and discoverable in your build environment. For standard `pip install`, no explicit action is usually required.","message":"CMake is a build dependency starting from `coincurve` version 20.0.0. While `pip` typically handles this for standard installations by fetching `cmake` from PyPI, redistributors or users building from source in custom environments will need to ensure CMake is available.","severity":"breaking","affected_versions":">=20.0.0"},{"fix":"Upgrade to a 64-bit Windows environment or pin `coincurve<20.0.0`.","message":"Binary wheels for Windows 32-bit are no longer built as of `coincurve` version 20.0.0. Users on Windows 32-bit systems will need to compile from source (which requires appropriate build tools and dependencies) or use an older version.","severity":"breaking","affected_versions":">=20.0.0"},{"fix":"Use `PrivateKey.sign()` when verifying with `coincurve.verify_signature()`. If you need recoverable signatures, verify them using `PublicKey.verify()` if applicable, or recover the public key first and then verify (more complex).","message":"The `PrivateKey.sign_recoverable()` method produces a 65-byte compact signature, which is NOT compatible with the module-level `coincurve.verify_signature()` function that expects a DER-encoded signature (produced by `PrivateKey.sign()`). Attempting to verify a recoverable signature with `verify_signature()` will raise a `ValueError`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Pin your `coincurve` dependency to `coincurve==20.0.0` or `coincurve!=21.0.0` until a patched version is released. Or, consider updating to a newer working version if available.","message":"A packaging issue in `coincurve==21.0.0` (specifically a missing LICENSE file in the `cffi` distribution during build) can lead to installation failures when `coincurve` is a dependency of another package. This was observed with `ccxt`.","severity":"gotcha","affected_versions":"21.0.0"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}