Keys are a private scalar d in 1…n−1 and the public point Q = d·G, where G is the curve's base point and n its prime order. To sign a hash z the signer picks a secret nonce k, sets r to the x-coordinate of k·G modulo n and computes s = k⁻¹·(z + r·d) mod n; the verifier computes u₁ = z·s⁻¹ and u₂ = r·s⁻¹ and checks that the x-coordinate of u₁·G + u₂·Q equals r (FIPS 186-5 §6.4). The hash is truncated to the bit length of n, so SHA-512 with P-256 uses only its leftmost 256 bits.
Common identifiers: X.509 ecdsa-with-SHA256 is 1.2.840.10045.4.3.2 (SHA-384: …4.3.3, SHA-512: …4.3.4); JOSE ES256, ES384, ES512 and ES256K; COSE −7, −35, −36 and −47; TLS 1.3 ecdsa_secp256r1_sha256 (0x0403). The usual curves are P-256, P-384, P-521 and, for blockchains, secp256k1.
The same signature travels in two encodings: raw r‖s of fixed length (64 bytes for P-256; JOSE, WebCrypto, COSE) and an ASN.1 DER SEQUENCE of two INTEGERs (70–72 bytes for P-256; X.509, TLS, OpenSSL, Java). For every valid (r, s) the pair (r, n − s) also verifies, which is why blockchains require low-S signatures.
The nonce is the weak point: a repeated or slightly biased k reveals the private key, so modern libraries derive it deterministically (RFC 6979, approved by FIPS 186-5 §6.3.2) or hedge it. On one core of an Apple M4 Max, OpenSSL 3.6.5 makes about 87,000 P-256 signatures and 29,000 verifications per second. NIST IR 8547 (initial public draft) proposes disallowing ECDSA at every strength after 2035 because Shor's algorithm breaks it.