ECC stands for elliptic curve cryptography, a family of public-key methods that match RSA security with keys many times shorter. A 256-bit curve key gives about 128 bits of security, the same level NIST SP 800-57 assigns to a 3072-bit RSA key. The most deployed curve is NIST P-256, also named secp256r1 or prime256v1.
An elliptic curve over a prime field is the set of points (x, y) satisfying y^2 = x^3 + ax + b mod p, plus a point at infinity. Points can be added, and repeated addition of a fixed base point G gives scalar multiplication. A private key is a random integer d. The public key is the point Q = d times G.
Computing Q from d is fast. Recovering d from Q and G is the elliptic curve discrete logarithm problem, and no known classical method solves it quickly on a well-chosen curve. This is why the keys can be short. Standards define named curves so both sides agree on p, a, b, G and the group order.
The toy script below uses the curve y^2 = x^3 + 2x + 2 over the prime 17 with base point G = (5, 1), which has 19 points in its group. It prints k times G for a few k, and k = 19 returns the point at infinity, shown as None.
p, a = 17, 2
def add(P, Q):
if P is None: return Q
if Q is None: return P
if P[0] == Q[0] and (P[1] + Q[1]) % p == 0: return None
if P == Q: l = (3 * P[0] ** 2 + a) * pow(2 * P[1], -1, p) % p
else: l = (Q[1] - P[1]) * pow(Q[0] - P[0], -1, p) % p
x = (l * l - P[0] - Q[0]) % p
return (x, (l * (P[0] - x) - P[1]) % p)
def mul(k, P):
R = None
for _ in range(k): R = add(R, P)
return R
G = (5, 1)
for k in (1, 2, 7, 18, 19, 20):
print(k, mul(k, G))
1 (5, 1)
2 (6, 3)
7 (0, 6)
18 (5, 16)
19 None
20 (5, 1)
The sequence repeats after 19 steps, so the toy private key 7 gives the public point (0, 6). A real curve works the same way but has a group order near 2^256.
A 256-bit ECC key is as strong as a 3072-bit RSA key, and the public point is only 65 bytes. NIST SP 800-57 lists ECC sizes of 224 to 255 bits for 112-bit security, 256 to 383 for 128, 384 to 511 for 192 and 512 or more for 256. RFC 5480 pairs those levels with secp256r1, secp384r1 and secp521r1. Measured with the Python cryptography package, the uncompressed public point is 65, 97 and 133 bytes for those three curves, and the compressed form is 33, 49 and 67 bytes.