ECDSA cryptographic signature library (pure python)
npx @tessl/cli install tessl/pypi-ecdsa@0.19.0A pure Python implementation of Elliptic Curve Cryptography (ECC) providing comprehensive support for ECDSA (Elliptic Curve Digital Signature Algorithm), EdDSA (Edwards-curve Digital Signature Algorithm), and ECDH (Elliptic Curve Diffie-Hellman) protocols. The library supports multiple cryptographic curves including NIST Suite B curves, Bitcoin's secp256k1, Brainpool curves, and Edwards curves for secure digital signing, signature verification, and key exchange operations.
pip install ecdsaimport ecdsaCommon imports for key operations:
from ecdsa import SigningKey, VerifyingKey, NIST256p, SECP256k1For specific functionality:
from ecdsa import ECDH, BadSignatureError
from ecdsa.util import sigencode_der, sigdecode_der, sigencode_string, sigdecode_string
from ecdsa.curves import Ed25519, BRAINPOOLP256r1from ecdsa import SigningKey, VerifyingKey, NIST256p, BadSignatureError
import hashlib
# Generate a new signing key
sk = SigningKey.generate(curve=NIST256p)
vk = sk.verifying_key
# Sign some data
message = b"Hello, world!"
signature = sk.sign(message, hashfunc=hashlib.sha256)
# Verify the signature
try:
vk.verify(signature, message, hashfunc=hashlib.sha256)
print("Signature is valid")
except BadSignatureError:
print("Invalid signature")
# Export keys
private_key_pem = sk.to_pem()
public_key_pem = vk.to_pem()
# Load keys from PEM
loaded_sk = SigningKey.from_pem(private_key_pem)
loaded_vk = VerifyingKey.from_pem(public_key_pem)The ecdsa library follows a layered architecture built around elliptic curve mathematics:
This design enables cryptographically secure operations while maintaining compatibility across Python 2.6+ and 3.6+ environments without external C dependencies.
Primary ECDSA/EdDSA functionality including key generation, digital signing, and signature verification with support for multiple hash functions, signature encodings, and deterministic signatures.
class SigningKey:
@classmethod
def generate(cls, curve=NIST192p, entropy=None, hashfunc=sha1): ...
@classmethod
def from_secret_exponent(cls, secexp, curve=NIST192p, hashfunc=sha1): ...
@classmethod
def from_string(cls, string, curve=NIST192p, hashfunc=sha1): ...
@classmethod
def from_pem(cls, string, hashfunc=sha1, valid_curve_encodings=None): ...
@classmethod
def from_der(cls, string, hashfunc=sha1, valid_curve_encodings=None): ...
def sign(self, data, entropy=None, hashfunc=None, sigencode=sigencode_string, k=None, allow_truncate=True): ...
def sign_deterministic(self, data, hashfunc=None, sigencode=sigencode_string, extra_entropy=b""): ...
def sign_digest(self, digest, entropy=None, sigencode=sigencode_string, k=None, allow_truncate=False): ...
def sign_digest_deterministic(self, digest, hashfunc=None, sigencode=sigencode_string, extra_entropy=b"", allow_truncate=False): ...
def sign_number(self, number, entropy=None, k=None): ...
def get_verifying_key(self): ...
def to_string(self): ...
def to_pem(self, point_encoding="uncompressed", format="ssleay", curve_parameters_encoding=None): ...
def to_der(self, point_encoding="uncompressed", format="ssleay", curve_parameters_encoding=None): ...
def to_ssh(self): ...
class VerifyingKey:
@classmethod
def from_public_point(cls, point, curve=NIST192p, hashfunc=sha1, validate_point=True): ...
@classmethod
def from_string(cls, string, curve=NIST192p, hashfunc=sha1, validate_point=True, valid_encodings=None): ...
@classmethod
def from_pem(cls, string, hashfunc=sha1, valid_encodings=None, valid_curve_encodings=None): ...
@classmethod
def from_der(cls, string, hashfunc=sha1, valid_encodings=None, valid_curve_encodings=None): ...
@classmethod
def from_public_key_recovery(cls, signature, data, curve, hashfunc=sha1, sigdecode=sigdecode_string, allow_truncate=True): ...
@classmethod
def from_public_key_recovery_with_digest(cls, signature, digest, curve, hashfunc=sha1, sigdecode=sigdecode_string, allow_truncate=False): ...
def verify(self, signature, data, hashfunc=None, sigdecode=sigdecode_string, allow_truncate=True): ...
def verify_digest(self, signature, digest, sigdecode=sigdecode_string, allow_truncate=False): ...
def precompute(self, lazy=False): ...
def to_string(self, encoding="raw"): ...
def to_pem(self, point_encoding="uncompressed", curve_parameters_encoding=None): ...
def to_der(self, point_encoding="uncompressed", curve_parameters_encoding=None): ...
def to_ssh(self): ...Elliptic Curve Diffie-Hellman key agreement protocol implementation for secure shared secret generation between parties using elliptic curve cryptography.
class ECDH:
def __init__(self, curve=None, private_key=None, public_key=None): ...
def set_curve(self, key_curve): ...
def generate_private_key(self): ...
def load_private_key(self, private_key): ...
def load_private_key_bytes(self, private_key): ...
def load_private_key_der(self, private_key_der): ...
def load_private_key_pem(self, private_key_pem): ...
def get_public_key(self): ...
def load_received_public_key(self, public_key): ...
def load_received_public_key_bytes(self, public_key_str, valid_encodings=None): ...
def load_received_public_key_der(self, public_key_der): ...
def load_received_public_key_pem(self, public_key_pem): ...
def generate_sharedsecret(self): ...
def generate_sharedsecret_bytes(self): ...Pre-defined elliptic curve parameters and mathematical operations supporting NIST Suite B curves, SECP curves, Brainpool curves, and Edwards curves for various cryptographic applications.
# NIST Curves
NIST192p: Curve
NIST224p: Curve
NIST256p: Curve
NIST384p: Curve
NIST521p: Curve
# SECP Curves
SECP256k1: Curve # Bitcoin curve
SECP112r1: Curve
SECP112r2: Curve
SECP128r1: Curve
SECP160r1: Curve
# Edwards Curves
Ed25519: Curve
Ed448: Curve
# Brainpool Curves (r1 series)
BRAINPOOLP160r1: Curve
BRAINPOOLP192r1: Curve
BRAINPOOLP224r1: Curve
BRAINPOOLP256r1: Curve
BRAINPOOLP320r1: Curve
BRAINPOOLP384r1: Curve
BRAINPOOLP512r1: Curve
# Brainpool Curves (t1 series)
BRAINPOOLP160t1: Curve
BRAINPOOLP192t1: Curve
BRAINPOOLP224t1: Curve
BRAINPOOLP256t1: Curve
BRAINPOOLP320t1: Curve
BRAINPOOLP384t1: Curve
BRAINPOOLP512t1: Curve
class Curve:
def to_der(self, encoding=None, point_encoding="uncompressed"): ...
def to_pem(self, encoding=None, point_encoding="uncompressed"): ...
# Curve utility functions
def find_curve(oid_curve): ...
def curve_by_name(name): ...
curves: list # List of all supported curve objectsCurves & Mathematical Foundation
Comprehensive encoding and decoding utilities for signature formats (DER, raw), key formats (PEM, DER, SSH), and ASN.1 structures used in elliptic curve cryptography.
# Signature encoding/decoding
def sigencode_der(r, s, order): ...
def sigencode_string(r, s, order): ...
def sigencode_strings(r, s, order): ...
def sigencode_string_canonize(r, s, order): ...
def sigencode_strings_canonize(r, s, order): ...
def sigencode_der_canonize(r, s, order): ...
def sigdecode_der(sig_der, order): ...
def sigdecode_string(signature, order): ...
def sigdecode_strings(rs_strings, order): ...
# DER encoding/decoding
def encode_sequence(*encoded_pieces): ...
def encode_integer(r): ...
def encode_octet_string(s): ...
def encode_bitstring(s, unused=0): ...
def encode_oid(first, second, *pieces): ...
def encode_constructed(tag, value): ...
def encode_implicit(tag, value, cls="context-specific"): ...
def remove_sequence(string): ...
def remove_integer(string): ...
def remove_octet_string(string): ...
def remove_bitstring(string, expect_unused=0): ...
def remove_object(string): ...
def remove_constructed(string): ...
# Number/string conversion
def number_to_string(num, order): ...
def number_to_string_crop(num, order): ...
def string_to_number(string): ...
def string_to_number_fixedlen(string, order): ...Edwards-curve Digital Signature Algorithm providing deterministic, high-performance signatures using Ed25519 and Ed448 curves with built-in resistance to side-channel attacks.
class PublicKey:
def __init__(self, generator, public_key, public_point=None): ...
def public_point(self): ...
def public_key(self): ...
def verify(self, data, signature): ...
class PrivateKey:
def __init__(self, generator, private_key): ...
def private_key(self): ...
def public_key(self): ...
def sign(self, data): ...
# Edwards curve parameters
curve_ed25519: CurveEdTw
generator_ed25519: PointEdwards
curve_ed448: CurveEdTw
generator_ed448: PointEdwardsNumber theory functions, polynomial operations, deterministic signature generation (RFC 6979), and low-level ECDSA mathematical operations for advanced cryptographic applications.
# Number theory operations
def gcd(*a): ...
def lcm(*a): ...
def jacobi(a, n): ...
def square_root_mod_prime(a, p): ...
def is_prime(n): ...
def next_prime(starting_value): ...
# RFC 6979 deterministic signatures
def generate_k(order, secexp, hash_func, data, retry_gen=0, extra_entropy=b""): ...
def bits2int(data, qlen): ...
def bits2octets(data, order): ...
# Low-level ECDSA classes
class Signature:
def recover_public_keys(self, hash, generator): ...
class Public_key:
def verifies(self, hash, signature): ...
class Private_key:
def sign(self, hash, k): ...
# Utility functions
def point_is_valid(generator, x, y): ...
def bit_length(x): ...
def orderlen(order): ...Mathematical Functions & Low-Level Operations
The library defines specific exception classes for different error conditions:
# Core signature and key exceptions
class BadSignatureError(Exception): ...
class BadDigestError(Exception): ...
class MalformedPointError(AssertionError): ...
# DER encoding/decoding exceptions
class UnexpectedDER(Exception): ...
# ECDH key exchange exceptions
class NoKeyError(Exception): ...
class NoCurveError(Exception): ...
class InvalidCurveError(Exception): ...
class InvalidSharedSecretError(Exception): ...
# Low-level ECDSA exceptions
class RSZeroError(RuntimeError): ...
class InvalidPointError(RuntimeError): ...
# Curve and mathematical exceptions
class UnknownCurveError(Exception): ...
# Number theory exceptions
class JacobiError(Exception): ...
class SquareRootError(Exception): ...
class NegativeExponentError(Exception): ...
# Utility exceptions
class MalformedSignature(Exception): ...__version__: str # Current package version