ecdsa.com

Lesson 7 of 7 · about 12 minutes

The real thing

Same six formulas, 256-bit numbers, real code in your browser. Sign, verify — and then work out why a genuine-looking signature refuses to pass.

Nothing new remains to learn. P-256 — also called secp256r1 or prime256v1 — is the same six formulas over a larger field, and this lesson is where you run them on the genuine article, in this browser, with an audited library rather than by hand.

P-256, the curve in most TLS certificates and passkeys
p = 2^256 - 2^224 + 2^192 + 2^96 - 1
a = -3
b = 5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6
    3bce3c3e 27d2604b
n = ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84
    f3b9cac2 fc632551          (the group order: ~1.16 * 10^77 points)

a private key is one integer below n
a public key is one point:      64 bytes
a signature is two integers:    64 bytes

The proportions are worth pausing on. An RSA key offering comparable security is 3072 bits — twelve times the size — and its signatures are twelve times larger too. That difference is why passkeys, modern TLS certificates, SSH keys and blockchain addresses all converged on elliptic curves.

Why real signatures fail

In practice, a signature that will not verify is almost never a broken curve. It is two programs disagreeing about something outside the mathematics. The short list, roughly in order of how often it happens:

  • The hash. One side used SHA-256, the other SHA-384 or SHA-512. Or one side hashed a value that had already been hashed. z differs, so everything after it differs.
  • The encoding. DER wraps r and s in an ASN.1 sequence with length bytes and sign padding; the raw form is just the two integers concatenated to fixed width. Feeding one to a parser expecting the other produces an error that mentions neither.
  • The message. A trailing newline, CRLF instead of LF, a different Unicode normalisation, JSON keys serialised in a different order. All of these change the bytes, and the bytes are what was signed.
  • The key. The wrong key in a rotating set, a key for a different curve, or a compressed point handed to code expecting an uncompressed one.

The exercise below gives you one of these to diagnose. You get the message, the public key and a signature that fails the ordinary check, plus a panel that lets you change one variable at a time. That last part is the actual skill: not knowing the answer in advance, but knowing how to isolate it. It is the same procedure the Error Explainer automates for library error messages.

Loading the elliptic-curve library…

What you now know

  • P-256 signing and verification are the toy formulas with a 256-bit prime.
  • A failed verification usually means a mismatch, not broken math: wrong hash, wrong message, wrong key or wrong encoding.
  • The fastest way to diagnose one is to change a single variable at a time and watch which change flips the result.