ECDSA stands for Elliptic Curve Digital Signature Algorithm, a signature scheme that turns a message hash and a private key into two integers, r and s. It is the elliptic curve version of DSA, specified in FIPS 186-5, and it is widely used in TLS certificates, JWT ES256 tokens and SSH. Every signature also needs a fresh secret number called k.
The signer hashes the message, for example with SHA-256, and picks a random k between 1 and n-1, where n is the order of the curve group. It computes the point k times G and takes the x coordinate modulo n as r. It then calculates s from k, the hash, r and the private key. The signature is the pair (r, s).
The verifier uses the public key, r, s and the hash to rebuild a point and checks that its x coordinate matches r. Each of r and s has the size of the curve order, so a P-256 signature holds 2 times 32 = 64 bytes of data.
The randomness of k is the sensitive part. RFC 6979 describes a deterministic variant that derives k from the private key and the message, and FIPS 186-5 approves it as deterministic ECDSA. The verifier cannot tell the difference. The script below signs the message "sample" with the RFC 6979 P-256 test key and compares with that RFC's published r and s.
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
x=0xC9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721
k=ec.derive_private_key(x, ec.SECP256R1())
alg=ec.ECDSA(hashes.SHA256(), deterministic_signing=True)
sig=k.sign(b"sample", alg)
r,s=decode_dss_signature(sig)
print("r =", format(r,'064X'))
print("s =", format(s,'064X'))
print("same twice:", k.sign(b"sample", alg)==sig)
rnd=ec.ECDSA(hashes.SHA256())
a,b=k.sign(b"sample", rnd),k.sign(b"sample", rnd)
print("random k, same twice:", a==b)
r = EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716
s = F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8
same twice: True
random k, same twice: False
A P-256 ECDSA signature is 64 bytes as a raw r and s pair, and 70 to 72 bytes in the DER encoding that OpenSSL and X.509 use. DER wraps r and s as two ASN.1 integers, and each gets a leading zero byte when its top bit is set. That makes 72 bytes the maximum for P-256, and the two random-k signatures in the run above came out at 71 and 72 bytes. JWT ES256 uses the raw 64-byte form, so DER output must be converted.