Lemma
math, backwards
the hook · proof without disclosure

How do you prove a coin is yours without showing the key that unlocks it?

A address is public — anyone can see it. The that authorizes spending must stay secret; whoever sees it can spend everything you have, forever. Yet every transaction is verified by thousands of strangers. How can the network be sure you signed this payment without ever learning the secret that authorizes all your payments?

The trick lives on a curve. Two operations: one easy in one direction and impossible in the other; one algebraic identity that only the secret-holder can produce but anyone can check. The widget below runs the entire dance with numbers small enough to verify by hand.

Widget — Sign & verify
curve · y² = x³ + 7 (mod 17)generator · G = (1, 5)order · n = 9
00448812121616GQ=5GR=7GV
signer · knows d
Q = 5G(12, 16)
R = 7G(2, 7)
r = R.x mod 92
s = (h + r·d)·k⁻¹ mod 97
signature (r, s) = (2, 7)
verifier · only knows h, (r, s), Q
u₁ = h·s⁻¹ mod 93
u₂ = r·s⁻¹ mod 98
u₁G + u₂Q = V(2, 7)
V.x mod 9 = 2·r = 2✓ valid
Drag d — only Q moves on the plot, never G. Anyone can compute 5G from d; nobody can recover d from Q = (12, 16) without trying every multiple. That's the one-way street the signature stands on. Drag h or k and watch both sides agree: the verifier never asks for d and yet arrives at V = R, so V.x ≡ r.
the arc
1

What needs to be true

Three properties at once: (a) only you can produce a valid signature for a given message, (b) anyone can check it, (c) checking it does not reveal what made it producible. No password scheme satisfies all three — passwords must be shown to be checked. We need a one-way function: easy in the producing direction, impossible in the recovering direction, with a clean algebraic identity tying the two together.

2

The one-way function — scalar multiplication on a curve

Take an y2=x3+7y² = x³ + 7 over a finite field. The points of this curve form a group: any two points have a sum, computed by the very chord-and-tangent construction that makes Bezout’s count work. Pick a generator GG; repeated addition gives : kG=G+G++GkG = G + G + ⋯ + G (k times).

Computing kGkG from (k,G)(k, G) takes about log2k\log₂ k additions (double-and-add). Recovering kk from (G,kG)(G, kG) is the problem; for cryptographic curves like , no algorithm is known that beats roughly n\sqrt{n} work, where n2256n ≈ 2²⁵⁶. That is the asymmetry the entire scheme stands on.

# Toy curve E: y² = x³ + 7 over F_17.
# Same shape (a=0, b=7) as secp256k1, microscopic prime.
P, A, B = 17, 0, 7
INF = None  # the point at infinity is the group identity

def add(P_, Q_):
    if P_ is INF: return Q_
    if Q_ is INF: return P_
    x1, y1 = P_; x2, y2 = Q_
    if x1 == x2 and (y1 + y2) % P == 0:
        return INF
    if P_ == Q_:
        lam = (3 * x1 * x1 + A) * pow(2 * y1, -1, P) % P
    else:
        lam = (y2 - y1) * pow(x2 - x1, -1, P) % P
    x3 = (lam * lam - x1 - x2) % P
    y3 = (lam * (x1 - x3) - y1) % P
    return (x3, y3)

def scalar_mul(k, P_):
    R = INF
    while k > 0:
        if k & 1: R = add(R, P_)
        P_ = add(P_, P_)
        k >>= 1
    return R

G = (1, 5)             # generator
N = 9                  # order of G — 9G = INF
scalar_mul(2, G)       # → (2, 10)
scalar_mul(3, G)       # → (5, 9)
scalar_mul(9, G)       # → None (= O)
3

Keys — the move that anyone can do, no one can undo

Pick a random integer d1,,n1d ∈ {1, …, n−1} and keep it secret — that is your . Compute Q=dGQ = dG and publish it — that is your . Anyone can compute QQ from dd in milliseconds. Nobody can recover dd from QQ in this universe.

In the widget, drag the private key d slider and watch Q hop around the curve while G stays fixed. Every dd in 1,,8{1, …, 8} lands on a different point of the subgroup. The puzzle: given the position of Q on the plot, can you tell which dd produced it without trying all eight? On the toy curve you can; on secp256k1 you cannot.

4

Sign — commit to the message, hide the key

The on a message hash hh is two numbers (r,s)(r, s). Pick a fresh random kk, compute R=kGR = kG, take r=R.xmodnr = R.x \mod n, and set s=(h+rd)k1modns = (h + r·d) · k⁻¹ \mod n. The k1k⁻¹ hides dd: with kk random and secret, ss looks random too. Without the nonce, two signatures from the same key would be a linear system in dd — anyone could solve it.

In the widget, the signer panel shows the equations live. Drag d, h, or k and the signature recomputes. Note the line labelled verifier · only knows h, (r, s), Q: the boundary between what leaves the signing device and what stays in it.

# Sign a message hash with private key d, nonce k.
def sign(d, h, k):
    R = scalar_mul(k, G)
    r = R[0] % N
    s = (h + r * d) * pow(k, -1, N) % N
    if r == 0 or s == 0:
        raise ValueError("retry with another k")
    return r, s

# Toy: d = 5 (private), h = 3 (message hash), k = 7 (nonce)
sign(5, 3, 7)  # → (2, 7)
5

Verify — the identity that holds iff you knew the key

The verifier is given hh, (r,s)(r, s), and QQ — nothing else. Compute u1=hs1modnu₁ = h · s⁻¹ \mod n, u2=rs1modnu₂ = r · s⁻¹ \mod n, then V=u1G+u2QV = u₁G + u₂Q. Accept the signature iff V.xr(modn)V.x ≡ r (\mod n). Watch the algebra:

V = u₁·G + u₂·Q
= (h/s)·G + (r/s)·dG
= ((h + r·d)/s)·G                       ← group up by G
= ((h + r·d) · k / (h + r·d))·G        ← s = (h + r·d)/k
= k·G
= R                                      ← so V.x = R.x = r ✓

The line s=(h+rd)/ks = (h + r·d)/k hides dd from anyone who only sees (r,s,h,Q)(r, s, h, Q); the same line, plugged into V=u1G+u2QV = u₁G + u₂Q, makes VV exactly equal RR. The verifier never recovers dd and yet arrives at the same point the signer used. That coincidence — produced only by knowing dd, checked without — is the signature of the entire scheme, in both senses of the word.

# Verify uses only public information: h, (r, s), Q.
def verify(h, r, s, Q):
    s_inv = pow(s, -1, N)
    u1 = h * s_inv % N
    u2 = r * s_inv % N
    V = add(scalar_mul(u1, G), scalar_mul(u2, Q))
    return V is not INF and V[0] % N == r

Q = scalar_mul(5, G)            # public key matching d = 5
verify(3, 2, 7, Q)              # → True

# The algebra: V = u1·G + u2·Q
#                = (h/s)G + (r/s)·dG
#                = ((h + r·d)/s)·G
#                = ((h + r·d) · k / (h + r·d))·G   # because s = (h+r·d)/k
#                = k·G = R.   So V.x mod N = r.
# Verifier never sees d. The identity holds iff signer knew d.
6

secp256k1 — the same algorithm, bigger numbers

Bitcoin runs the same group law and the same ECDSA equations on : y2=x3+7y² = x³ + 7 over the prime p=2256232977p = 2²⁵⁶ − 2³² − 977. The widget above is a microscopic version: 17 instead of 22562²⁵⁶, subgroup order 9 instead of  2256~2²⁵⁶. The algorithm is identical. The only thing that scales is the gap between multiplying (still O(logk)O(\log k)) and recovering (now  2128~2¹²⁸). That gap is the only reason your wallet is safe.

now break it

The math is sound; the implementation is where it dies. ECDSA requires a fresh, uniformly random nonce kk for every signature. Reuse kk across two different messages and an attacker recovers dd with eighth-grade algebra: d=(s1h2s2h1)/(r(s2s1))d = (s₁·h₂ − s₂·h₁) / (r·(s₂ − s₁)) — a one-line wallet drainer. Sony’s PlayStation 3 firmware (2010) reused kk; their master signing key fell out in days. Bitcoin wallets have lost coins to non-uniform RNG drift the same way. The discrete-log gap is unbreakable by mathematics; the nonce is breakable by code.

Sign with d. Verify without d. A signature is a number you can only produce by knowing the key, and anyone can check by walking around it. Same key authorizes and refuses to be revealed.

exercises · 손으로 풀기
1scalar multiplication by handno calculator

On y2=x3+7(mod17)y² = x³ + 7 (\mod 17) with G=(1,5)G = (1, 5), compute 3G using the chord-and-tangent group law: first 2G by doubling, then add G. Verify your answer against the widget.

2sign by hand

With d = 3, h = 4, k = 2, produce the ECDSA signature (r,s)(r, s). You may use 2G=(2,10)2G = (2, 10) from exercise 1. Confirm in the widget by setting d, h, k to these values.

3verify by hand

You receive h = 4, signature (r, s) = (2, 5), and public key Q=3G=(5,9)Q = 3G = (5, 9). Run the verifier equations: compute u₁, u₂, then V = u₁G + u₂Q, and check V.x mod 9 = r.

4the forger's frustration

A forger doesn’t know d, but tries to invent a signature (r,s)(r', s') for some message hash hh and a target public key Q. Explain — without proof, just the structure — why almost any guess fails the verify check. What would the forger have to know to succeed?

why this isn't taught this way

Cryptography textbooks usually open ECDSA with the verification equation — u1G+u2Q=Ru₁G + u₂Q = R — already on the page, asking the reader to accept it. Lemma walks the door the other way: why would the verifier ever arrive at RR without knowing dd? The answer rebuilds the algebra from the one-way street (multiply easy, divide hard) up. The textbook hides the asymmetry; the asymmetry is the point.

glossary · used on this page · 9
Bitcoin (BTC)·비트코인
A digital currency launched in 2009 by an anonymous figure 'Satoshi Nakamoto'. New coins are released on a fixed schedule that halves every ~4 years.
private key·개인키
A secret integer the owner keeps. In ECDSA on a curve with generator `G` and subgroup order `n`, the private key `d` is a random element of `{1, …, n-1}`. The owner uses `d` to produce signatures; everyone else uses the matching public key `Q = dG` to verify them. Whoever learns `d` can sign on the owner's behalf indefinitely — that is the entire reason it must never leave the device.
elliptic curve·타원곡선
A curve of the form `y² = x³ + ax + b` (with `4a³ + 27b² ≠ 0`, so the curve has no cusps or self-intersections). When taken over a finite field `F_p`, the affine solutions plus a single _point at infinity_ form a finite abelian group under the chord-and-tangent construction inherited from Bezout's theorem. ECDSA, EdDSA, and most modern public-key cryptography stand on this group. Bitcoin uses the specific curve `y² = x³ + 7` over the prime `p = 2²⁵⁶ − 2³² − 977`, called secp256k1.
scalar multiplication·스칼라 곱셈
Repeated point addition on an elliptic curve: `kP = P + P + ⋯ + P` (k times). Computing `kP` from `(k, P)` is fast — double-and-add finishes in `O(log k)` group operations. Recovering `k` from `(P, kP)` is the discrete logarithm problem and is believed to take exponentially many group operations. This asymmetry — easy to multiply, hard to undo — is the entire cryptographic content of every elliptic-curve scheme: keys, signatures, key exchange.
discrete logarithm·이산 로그
The problem: given a group element `g` of known order and another element `h` known to lie in the cyclic subgroup `⟨g⟩`, find the integer `x` such that `g^x = h` (or in additive notation on a curve, `xG = Q`). For elliptic curves chosen carefully — like secp256k1 — the best known algorithms still take roughly `√n` group operations, where `n` is the subgroup order. With `n ≈ 2²⁵⁶`, that is about `2¹²⁸` operations — far beyond what any current or near-future computer can do.
secp256k1·secp256k1
The specific elliptic curve Bitcoin uses for keys and signatures: `y² = x³ + 7` over the prime field `F_p` with `p = 2²⁵⁶ − 2³² − 977`. Generator `G` and subgroup order `n` are fixed constants in the standard. The curve is defined by `secg.org` (Standards for Efficient Cryptography Group), spec named `secp256k1`. Same group law and same ECDSA equations as any toy elliptic curve — only the numbers are bigger. The 256-bit prime makes `√n ≈ 2¹²⁸` discrete-log work intractable.
public key·공개키
The point `Q = dG` on the curve, where `d` is the private key and `G` is the generator. Computing `Q` from `d` is fast (repeated point addition); recovering `d` from `Q` is the discrete logarithm problem and is believed to be infeasible at scale. The owner publishes `Q` freely — it identifies them on the network without revealing `d`. Bitcoin addresses are derived from the public key by hashing.
digital signature·디지털 서명
A short value `(r, s)` produced by the owner of a private key `d` over a message hash `h`, such that anyone with the matching public key `Q = dG` can verify the signature without learning `d`. In ECDSA, the signer picks a random nonce `k`, computes `R = kG`, sets `r = R.x mod n`, and `s = (h + r·d) · k⁻¹ mod n`. The verifier computes `u₁ = h/s`, `u₂ = r/s`, then checks that `(u₁G + u₂Q).x ≡ r (mod n)` — an equality that holds if and only if the signer knew `d`.
nonce·nonce
A "number used once." In ECDSA, every signature requires a fresh random integer `k` from `{1, …, n-1}`, used to compute `R = kG` and then discarded. The nonce hides the private key inside `s = (h + r·d)·k⁻¹`: with `k` random, `s` looks random too. Two failures are catastrophic. (1) If `k` repeats across two signatures with the same key, anyone can solve a small linear system and recover `d`. (2) If `k` is predictable (weak RNG), the same recovery applies. Real wallets now derive `k` deterministically from the message and `d` so it cannot leak by accident.