2026-07-03 07:44:40 +00:00
|
|
|
\chapter{Why Verify? The Bug That Testing Cannot Find}
|
|
|
|
|
\label{ch:why}
|
|
|
|
|
|
|
|
|
|
\section{A story about one carry bit}
|
|
|
|
|
|
book overhaul moves 1+2: the minute-one artifact, and cold-open surgery on ch1
From the 7-reader didactic audit (control/BOOK-OVERHAUL-PLAN.md). The two
highest-leverage moves per the cold-open reader and the panel's most-repeated
finding.
MOVE 1 — the reader touches the real thing in minute one. The panel's single
loudest note: a book that teaches "demand verification" gave the reader
nothing to verify for twelve chapters. Now: the title page names
ltl.zkdefi.org (19 entries, one post-quantum, "verify every entry yourself by
the last chapter"); the preface opens on that page instead of a generic power
claim; ch1 gains a try-it box after the pyramid pointing at entries 13-16 and
18. And ch7's broken promise is honored — it invited "check one leaf" while
never printing the 71-digit Q; the exact Q from P25519.lean is now on the
page, no hidden digits (render-verified against the repo).
MOVE 2 — ch1 cold open. Per the cold reader who hooked at line 13 and wobbled
by line 31: the first worked box (a log10 re-derivation of a punch the prose
already landed) collapses to four lines, the mechanics pushed to Exercise 1.1
— getting the reader ~30 lines sooner to the headroom box, the genuinely novel
bit. The vague "In 2014, researchers…" opener becomes the actual bug: a
two-line diff captioned as the entire defect, anchored to the real Fiat-Crypto
S&P 2019 lineage (no fabricated CVE). Competitor roll-call → footnote.
Syllabus roadmap → a second-person promise ("by Chapter 7 you will have handed
a kernel a certificate…"). "Why Lean" vendor bullets → reader-inheritance
voice ("you start on a million lines of proved mathematics").
Builds here: tectonic, 116 pages, zero errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-07 22:14:43 +00:00
|
|
|
Here is the entire bug that this book exists because of:
|
|
|
|
|
|
|
|
|
|
\begin{lstlisting}
|
|
|
|
|
h[4] += carry; // propagate the top limb's overflow
|
|
|
|
|
- // (missing: one more conditional subtraction of p)
|
|
|
|
|
+ if (h[4] >= LIMB_CAP) h[4] -= LIMB_CAP, h[0] += 19;
|
|
|
|
|
\end{lstlisting}
|
|
|
|
|
|
|
|
|
|
\noindent One missing line. A field-arithmetic routine that forgets a single
|
|
|
|
|
final carry is correct on \emph{almost every} input --- not most, almost
|
|
|
|
|
\emph{all} of them, in a precise sense --- and silently wrong on the rare
|
|
|
|
|
ones where that last carry would have fired. Bugs of exactly this species
|
|
|
|
|
were found in deployed elliptic-curve code and became the motivating
|
|
|
|
|
disaster behind a whole line of verification research (the Fiat-Cryptography
|
|
|
|
|
project, Erbsen et al., IEEE S\&P 2019 --- a direct ancestor of the work this
|
|
|
|
|
book teaches). A representative one produced a wrong answer with probability
|
|
|
|
|
on the order of $2^{-64}$ per random input.
|
2026-07-03 07:44:40 +00:00
|
|
|
|
|
|
|
|
Pause on that number. If you tested this function a billion times per second,
|
|
|
|
|
around the clock, you should expect to wait \emph{centuries} before a random
|
|
|
|
|
test happens to catch the bug. Every unit test passes. Every integration test
|
|
|
|
|
passes. Fuzzers shrug. The code ships.
|
|
|
|
|
|
|
|
|
|
\begin{pitfall}
|
|
|
|
|
``It passed all the tests'' means: it worked on the inputs we tried. For a
|
|
|
|
|
32-bit function there are four billion inputs and exhaustive testing is
|
|
|
|
|
feasible. A field element in Ed25519 is $255$ bits. The number of input
|
|
|
|
|
\emph{pairs} to a two-argument field operation is about $10^{153}$ --- more
|
|
|
|
|
than the square of the number of atoms in the observable universe. Testing
|
|
|
|
|
samples a raindrop from that ocean.
|
|
|
|
|
\end{pitfall}
|
|
|
|
|
|
book overhaul moves 1+2: the minute-one artifact, and cold-open surgery on ch1
From the 7-reader didactic audit (control/BOOK-OVERHAUL-PLAN.md). The two
highest-leverage moves per the cold-open reader and the panel's most-repeated
finding.
MOVE 1 — the reader touches the real thing in minute one. The panel's single
loudest note: a book that teaches "demand verification" gave the reader
nothing to verify for twelve chapters. Now: the title page names
ltl.zkdefi.org (19 entries, one post-quantum, "verify every entry yourself by
the last chapter"); the preface opens on that page instead of a generic power
claim; ch1 gains a try-it box after the pyramid pointing at entries 13-16 and
18. And ch7's broken promise is honored — it invited "check one leaf" while
never printing the 71-digit Q; the exact Q from P25519.lean is now on the
page, no hidden digits (render-verified against the repo).
MOVE 2 — ch1 cold open. Per the cold reader who hooked at line 13 and wobbled
by line 31: the first worked box (a log10 re-derivation of a punch the prose
already landed) collapses to four lines, the mechanics pushed to Exercise 1.1
— getting the reader ~30 lines sooner to the headroom box, the genuinely novel
bit. The vague "In 2014, researchers…" opener becomes the actual bug: a
two-line diff captioned as the entire defect, anchored to the real Fiat-Crypto
S&P 2019 lineage (no fabricated CVE). Competitor roll-call → footnote.
Syllabus roadmap → a second-person promise ("by Chapter 7 you will have handed
a kernel a certificate…"). "Why Lean" vendor bullets → reader-inheritance
voice ("you start on a million lines of proved mathematics").
Builds here: tectonic, 116 pages, zero errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-07 22:14:43 +00:00
|
|
|
\begin{worked}{feel what $2^{-64}$ means}
|
|
|
|
|
One hit per $2^{64}$ trials, and $2^{64} \approx 1.8 \times 10^{19}$. At a
|
|
|
|
|
billion tests a second that is $1.8 \times 10^{10}$ seconds to expect a
|
|
|
|
|
single failure --- about \textbf{580 years}. So a test farm hammering this
|
|
|
|
|
function a \emph{billion} times per second, started when Copernicus
|
|
|
|
|
published, would be expected to see the bug for the first time about now.
|
|
|
|
|
And that is the \emph{optimistic} case: carry bugs cluster in exactly the
|
|
|
|
|
corners uniform sampling underweights, so in practice you wait longer than
|
|
|
|
|
the calendar of the universe. (The one-line $\log_{10}$ derivation behind
|
|
|
|
|
``580 years,'' and the far more hopeless arithmetic for the full 510-bit
|
|
|
|
|
space of input \emph{pairs}, are Exercise~1.1 --- worth doing, because the
|
|
|
|
|
number that falls out has more digits than the universe has atoms.)
|
Major didactic overhaul: pen-and-paper worked examples + in-book solution pathways, 2x volume (53 -> 106 pages)
- pen-and-paper worked examples in all 12 chapters, using the REAL
constants throughout: 2^-64 waiting-time arithmetic, headroom budgets,
hand type-checking, rfl traces, full goal-state boards, the column-sum
audit at 2^54, inverting 19 mod p via Euclid, the x19 fold at real
weights, denoting p itself (telescope), the 16p audit (8 fails by 151),
the 254+11 inversion-chain bookkeeping, the substitution test, sizing
the 28-vs-1000 extraction, cofactor/torsion arithmetic, and the full
Bernstein-Lange completeness derivation
- CORRECTNESS FIX: ch7 asserted a false factorization of p-1; replaced
with the computationally verified p-1 = 2^2 * 3 * 65147 * Q (Q 71-digit
prime), witness w=2 verified for all four Pratt conditions
- every chapter's exercises now followed immediately by 'Solutions and
pathways' (pathway first, then answer), incl. new exercises
- NEW Interlude: a complete two-clause verification done entirely by
hand, then mapped line-by-line onto the compiled Lean proof
- NEW appendices: A pen-and-paper toolkit (8 recipe cards + drills +
answers), B guided walkthroughs of every exercise-file hole, C tour of
the real repositories; plus glossary, instructor notes, 13-week plan
- preamble: worked-example box, solution macros, math-safe inline code
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 08:55:00 +00:00
|
|
|
\end{worked}
|
|
|
|
|
|
2026-07-03 07:44:40 +00:00
|
|
|
Why does cryptographic code have bugs of exactly this shape? Because of how it
|
|
|
|
|
must be written. To be fast and resistant to timing attacks, real
|
|
|
|
|
implementations represent a 255-bit number in several machine-word
|
|
|
|
|
\emph{limbs} (we will spend happy hours with limbs in
|
|
|
|
|
Chapter~\ref{ch:denotation}) and postpone expensive carry propagation as long
|
|
|
|
|
as possible. The rare inputs where a deferred carry finally overflows are
|
|
|
|
|
precisely the inputs no test generator stumbles on. The bug lives in the gap
|
|
|
|
|
between ``the arithmetic we meant'' and ``the arithmetic we wrote,'' and that
|
|
|
|
|
gap is only visible on a set of inputs of measure nearly zero.
|
|
|
|
|
|
Major didactic overhaul: pen-and-paper worked examples + in-book solution pathways, 2x volume (53 -> 106 pages)
- pen-and-paper worked examples in all 12 chapters, using the REAL
constants throughout: 2^-64 waiting-time arithmetic, headroom budgets,
hand type-checking, rfl traces, full goal-state boards, the column-sum
audit at 2^54, inverting 19 mod p via Euclid, the x19 fold at real
weights, denoting p itself (telescope), the 16p audit (8 fails by 151),
the 254+11 inversion-chain bookkeeping, the substitution test, sizing
the 28-vs-1000 extraction, cofactor/torsion arithmetic, and the full
Bernstein-Lange completeness derivation
- CORRECTNESS FIX: ch7 asserted a false factorization of p-1; replaced
with the computationally verified p-1 = 2^2 * 3 * 65147 * Q (Q 71-digit
prime), witness w=2 verified for all four Pratt conditions
- every chapter's exercises now followed immediately by 'Solutions and
pathways' (pathway first, then answer), incl. new exercises
- NEW Interlude: a complete two-clause verification done entirely by
hand, then mapped line-by-line onto the compiled Lean proof
- NEW appendices: A pen-and-paper toolkit (8 recipe cards + drills +
answers), B guided walkthroughs of every exercise-file hole, C tour of
the real repositories; plus glossary, instructor notes, 13-week plan
- preamble: worked-example box, solution macros, math-safe inline code
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 08:55:00 +00:00
|
|
|
\begin{worked}{where exactly the danger zone sits --- the headroom budget}
|
|
|
|
|
You can locate the habitat of every delayed-carry bug with one line of
|
|
|
|
|
arithmetic, using the real Ed25519 parameters. The implementation stores a
|
|
|
|
|
field element as five limbs, each meant to carry $51$ bits of payload, in
|
|
|
|
|
$64$-bit machine words. The slack between payload and word is the
|
|
|
|
|
\emph{headroom}:
|
|
|
|
|
\[
|
|
|
|
|
64 - 51 = 13 \text{ bits of headroom per limb.}
|
|
|
|
|
\]
|
|
|
|
|
Adding two elements limb-wise adds their limbs, so a freshly reduced limb
|
|
|
|
|
(value $< 2^{51}$) can absorb additions --- but each addition can roughly
|
|
|
|
|
double the limb, i.e.\ spend up to one bit of headroom. How many lazy
|
|
|
|
|
additions before a limb can reach the $64$-bit cliff? We need
|
|
|
|
|
\[
|
|
|
|
|
k \cdot (2^{51}-1) \;<\; 2^{64}
|
|
|
|
|
\qquad\Longleftrightarrow\qquad
|
|
|
|
|
k \;\le\; \frac{2^{64}}{2^{51}} = 2^{13} = 8192 .
|
|
|
|
|
\]
|
|
|
|
|
So the code may skip carry propagation for thousands of additions --- a huge
|
|
|
|
|
performance win --- \emph{provided someone, somewhere, is counting}. The
|
|
|
|
|
2014-species bug is precisely a miscount: a code path where the running
|
|
|
|
|
total of spent headroom exceeds the budget on inputs shaped just so. Notice
|
|
|
|
|
what kind of fact the budget is: a \emph{quantified arithmetic invariant}
|
|
|
|
|
(``for all reachable values, limb $< 2^{51+j}$ after $j$ additions'') ---
|
|
|
|
|
exactly the kind of statement a test cannot establish and a proof assistant
|
|
|
|
|
eats for breakfast. When Chapter~\ref{ch:field} makes ``bounds clauses''
|
|
|
|
|
feel bureaucratic, remember this box: the bounds clause \emph{is} the
|
|
|
|
|
headroom count, and the headroom count is where the bodies were buried.
|
|
|
|
|
\end{worked}
|
|
|
|
|
|
2026-07-03 07:44:40 +00:00
|
|
|
And in cryptography, ``rare wrong answer'' does not mean ``rare small
|
book overhaul moves 1+2: the minute-one artifact, and cold-open surgery on ch1
From the 7-reader didactic audit (control/BOOK-OVERHAUL-PLAN.md). The two
highest-leverage moves per the cold-open reader and the panel's most-repeated
finding.
MOVE 1 — the reader touches the real thing in minute one. The panel's single
loudest note: a book that teaches "demand verification" gave the reader
nothing to verify for twelve chapters. Now: the title page names
ltl.zkdefi.org (19 entries, one post-quantum, "verify every entry yourself by
the last chapter"); the preface opens on that page instead of a generic power
claim; ch1 gains a try-it box after the pyramid pointing at entries 13-16 and
18. And ch7's broken promise is honored — it invited "check one leaf" while
never printing the 71-digit Q; the exact Q from P25519.lean is now on the
page, no hidden digits (render-verified against the repo).
MOVE 2 — ch1 cold open. Per the cold reader who hooked at line 13 and wobbled
by line 31: the first worked box (a log10 re-derivation of a punch the prose
already landed) collapses to four lines, the mechanics pushed to Exercise 1.1
— getting the reader ~30 lines sooner to the headroom box, the genuinely novel
bit. The vague "In 2014, researchers…" opener becomes the actual bug: a
two-line diff captioned as the entire defect, anchored to the real Fiat-Crypto
S&P 2019 lineage (no fabricated CVE). Competitor roll-call → footnote.
Syllabus roadmap → a second-person promise ("by Chapter 7 you will have handed
a kernel a certificate…"). "Why Lean" vendor bullets → reader-inheritance
voice ("you start on a million lines of proved mathematics").
Builds here: tectonic, 116 pages, zero errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-07 22:14:43 +00:00
|
|
|
glitch.'' Wrong field arithmetic can leak the private key itself: published
|
|
|
|
|
attacks in the ``invalid-curve'' and fault-injection families turn a
|
|
|
|
|
\emph{single} faulty group operation into full key recovery --- the attacker
|
|
|
|
|
feeds inputs engineered to land in the buggy corner, and reads the secret
|
|
|
|
|
off the wrong answers. The stakes are not a corrupted pixel; they are every
|
|
|
|
|
signature your machine has ever made, and every one it ever will.
|
2026-07-03 07:44:40 +00:00
|
|
|
|
|
|
|
|
\section{There is another way}
|
|
|
|
|
|
|
|
|
|
What if, instead of sampling inputs, we could make a statement about
|
|
|
|
|
\emph{all} of them --- and have a machine check that statement with the same
|
|
|
|
|
rigor a compiler checks syntax?
|
|
|
|
|
|
|
|
|
|
\begin{bigidea}
|
|
|
|
|
A \textbf{formal proof of correctness} is a mathematical argument, written in
|
|
|
|
|
a language precise enough for a computer to verify, that a program satisfies
|
|
|
|
|
its specification on \emph{every} input. Not sampled. Not probabilistic.
|
|
|
|
|
Every input, forever, or the proof does not check.
|
|
|
|
|
\end{bigidea}
|
|
|
|
|
|
|
|
|
|
The tool that checks such arguments is called a \emph{proof assistant}. This
|
|
|
|
|
book uses \textbf{Lean~4}, a modern proof assistant that is also a
|
book overhaul moves 1+2: the minute-one artifact, and cold-open surgery on ch1
From the 7-reader didactic audit (control/BOOK-OVERHAUL-PLAN.md). The two
highest-leverage moves per the cold-open reader and the panel's most-repeated
finding.
MOVE 1 — the reader touches the real thing in minute one. The panel's single
loudest note: a book that teaches "demand verification" gave the reader
nothing to verify for twelve chapters. Now: the title page names
ltl.zkdefi.org (19 entries, one post-quantum, "verify every entry yourself by
the last chapter"); the preface opens on that page instead of a generic power
claim; ch1 gains a try-it box after the pyramid pointing at entries 13-16 and
18. And ch7's broken promise is honored — it invited "check one leaf" while
never printing the 71-digit Q; the exact Q from P25519.lean is now on the
page, no hidden digits (render-verified against the repo).
MOVE 2 — ch1 cold open. Per the cold reader who hooked at line 13 and wobbled
by line 31: the first worked box (a log10 re-derivation of a punch the prose
already landed) collapses to four lines, the mechanics pushed to Exercise 1.1
— getting the reader ~30 lines sooner to the headroom box, the genuinely novel
bit. The vague "In 2014, researchers…" opener becomes the actual bug: a
two-line diff captioned as the entire defect, anchored to the real Fiat-Crypto
S&P 2019 lineage (no fabricated CVE). Competitor roll-call → footnote.
Syllabus roadmap → a second-person promise ("by Chapter 7 you will have handed
a kernel a certificate…"). "Why Lean" vendor bullets → reader-inheritance
voice ("you start on a million lines of proved mathematics").
Builds here: tectonic, 116 pages, zero errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-07 22:14:43 +00:00
|
|
|
full-fledged programming language.\footnote{You may have heard of Rocq
|
|
|
|
|
(formerly Coq), Isabelle/HOL, or Agda. The ideas in this book transfer to
|
|
|
|
|
all of them; only the syntax differs. We pick Lean~4 for reasons that will
|
|
|
|
|
be concrete by the end of this chapter.}
|
2026-07-03 07:44:40 +00:00
|
|
|
|
|
|
|
|
A proof assistant is built around a small, paranoid core called the
|
|
|
|
|
\emph{kernel}. Everything you will learn in this book --- clever tactics,
|
|
|
|
|
powerful automation, beautiful notation --- is scaffolding whose only job is
|
|
|
|
|
to produce a proof object the kernel accepts. The kernel is a few thousand
|
|
|
|
|
lines of code that does one thing: check that each step of a proof follows
|
|
|
|
|
from the previous ones by a fixed set of rules. If the kernel accepts, the
|
|
|
|
|
theorem holds. If it does not, no amount of confidence, seniority, or good
|
|
|
|
|
intentions makes the program correct.
|
|
|
|
|
|
|
|
|
|
\begin{aha}
|
|
|
|
|
Here is the emotional core of formal verification, and it is worth
|
|
|
|
|
internalizing early: \textbf{the proof assistant is not your examiner, it is
|
|
|
|
|
your collaborator}. It never gets tired, never skips a case, never says
|
|
|
|
|
``obviously.'' Every hour you spend arguing with it is an hour a bug did not
|
|
|
|
|
survive. People who love proof assistants love them the way climbers love a
|
|
|
|
|
good belayer.
|
|
|
|
|
\end{aha}
|
|
|
|
|
|
|
|
|
|
\section{What we will actually verify}
|
|
|
|
|
|
|
|
|
|
This book is not a tour of toy examples. It is the curriculum companion to a
|
|
|
|
|
set of real verification projects in which the arithmetic core of
|
|
|
|
|
\textbf{Ed25519} --- the elliptic-curve signature scheme used by SSH, Signal,
|
|
|
|
|
TLS, and most cryptocurrency systems --- was machine-checked in Lean~4,
|
|
|
|
|
starting from the actual Rust source code of the
|
|
|
|
|
\code{curve25519-dalek} library and several of its production forks.
|
|
|
|
|
|
|
|
|
|
The proofs are organized as a pyramid. Each layer states the correctness of
|
|
|
|
|
one abstraction level and rests on the layer beneath it:
|
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tikzpicture}[
|
|
|
|
|
lay/.style={draw=ink2,thick,rounded corners=2pt,align=center,minimum height=0.95cm},
|
|
|
|
|
note/.style={font=\small\color{ink2},align=left,anchor=west}
|
|
|
|
|
]
|
|
|
|
|
\node[lay,fill=accentsoft,minimum width=2.8cm] (sig) at (0,3.45) {\textbf{Signature}\\[-2pt]\small EdDSA verify};
|
|
|
|
|
\node[lay,fill=warnsoft,minimum width=5.2cm] (sca) at (0,2.3) {\textbf{Scalar arithmetic mod $\boldsymbol{\ell}$}};
|
|
|
|
|
\node[lay,fill=provensoft,minimum width=7.6cm] (grp) at (0,1.15) {\textbf{Group law} \small (twisted Edwards points)};
|
|
|
|
|
\node[lay,fill=codebg,minimum width=10cm] (fld) at (0,0) {\textbf{Field arithmetic in $\Fp$}, \small $p = 2^{255}-19$};
|
|
|
|
|
\node[note] at (5.6,0) {limbs, carries, multiplication};
|
|
|
|
|
\node[note] at (5.6,1.15) {point addition is complete \& correct};
|
|
|
|
|
\node[note] at (5.6,2.3) {the group order $\ell$, reduction};
|
Accuracy sweep: bring the book to the proven four-tier apex state
The companion repos completed their signature apex (phases 1+2: four
button-enforced tiers up to "accept <=> decompress(R) = [k](-A)+[s]B as
points") and the scalar layer long ago crossed the kernel frontier - but
the book still taught the pre-campaign state, including one real
inaccuracy of the class coherence pass 3 purged from the repo READMEs:
ch12's apex section and audit-drill solution described the COFACTORED
equation (8sB = 8R + 8kA) with SIMD backends in the trusted base -
neither matches the proven certificates (canonical-R byte equality,
serial path pinned and proven, SHA-512 an oracle with NO assumed
properties).
Fixed:
- ch12: pyramid status diagram (scalar + signature rows now "done"),
the scalar-frontier paragraph (the wall was crossed, and how), the
apex section (future tense -> the proven four-tier statement, honest
trusted base), the "extend the pyramid" bullet (scalar -> pasta curve
layer; CONTRIBUTING files never existed - now points at the control
repo's METHOD/TIERS), exercise 12.2(c) solution (which lineage the
cofactored robustness belongs to), exercise 12.3 + solution (audit
the REAL certificate).
- ch01: framing diagram states the equation actually proven
(sB = R + kA from raw bytes, not the cofactored form).
- glossary: Cofactor entry says which verifiers check which equation.
- ch11: the companion repos' posture is stronger than the ideal-hash
example - no hash properties assumed at all, backend question
eliminated rather than assumed.
- ch08: extraction notes (one merged universe; extract-scalar.sh was
retired in coherence pass 3; SIMD scoped out, not assumed).
- repo tour appendix: floor plan, reading order (item 5 now tours the
apex capstone), Phase 3b described.
- README: companion table rows say "the complete pyramid" with the
four-tier apex; honesty ledger records this 2026-07-06 re-audit.
main.pdf rebuilt from the updated sources (106 pages, zero errors,
build-pass4.log retained).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 05:46:27 +00:00
|
|
|
\node[note] at (5.6,3.45) {the equation $sB = R + kA$,\\ checked from the raw bytes};
|
2026-07-03 07:44:40 +00:00
|
|
|
\end{tikzpicture}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
book overhaul moves 1+2: the minute-one artifact, and cold-open surgery on ch1
From the 7-reader didactic audit (control/BOOK-OVERHAUL-PLAN.md). The two
highest-leverage moves per the cold-open reader and the panel's most-repeated
finding.
MOVE 1 — the reader touches the real thing in minute one. The panel's single
loudest note: a book that teaches "demand verification" gave the reader
nothing to verify for twelve chapters. Now: the title page names
ltl.zkdefi.org (19 entries, one post-quantum, "verify every entry yourself by
the last chapter"); the preface opens on that page instead of a generic power
claim; ch1 gains a try-it box after the pyramid pointing at entries 13-16 and
18. And ch7's broken promise is honored — it invited "check one leaf" while
never printing the 71-digit Q; the exact Q from P25519.lean is now on the
page, no hidden digits (render-verified against the repo).
MOVE 2 — ch1 cold open. Per the cold reader who hooked at line 13 and wobbled
by line 31: the first worked box (a log10 re-derivation of a punch the prose
already landed) collapses to four lines, the mechanics pushed to Exercise 1.1
— getting the reader ~30 lines sooner to the headroom box, the genuinely novel
bit. The vague "In 2014, researchers…" opener becomes the actual bug: a
two-line diff captioned as the entire defect, anchored to the real Fiat-Crypto
S&P 2019 lineage (no fabricated CVE). Competitor roll-call → footnote.
Syllabus roadmap → a second-person promise ("by Chapter 7 you will have handed
a kernel a certificate…"). "Why Lean" vendor bullets → reader-inheritance
voice ("you start on a million lines of proved mathematics").
Builds here: tectonic, 116 pages, zero errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-07 22:14:43 +00:00
|
|
|
\begin{tryit}
|
|
|
|
|
Before you read another word, go and touch the thing this book is about. Open
|
|
|
|
|
\textbf{\code{ltl.zkdefi.org}} on any device. You are looking at a public,
|
|
|
|
|
append-only log of machine-checked proofs --- 19 entries, each one a claim of
|
|
|
|
|
the form ``this exact version of this software was verified, resting on
|
|
|
|
|
exactly these assumptions.'' Entries 13--16 are the four Ed25519 libraries
|
|
|
|
|
whose pyramid you see above. Entry~18 is the first \emph{post-quantum} entry
|
|
|
|
|
in the log. You cannot read the proofs yet --- that is what the next twelve
|
|
|
|
|
chapters are for --- but you can already see that they are real, public, and
|
|
|
|
|
checkable by a stranger with a stock laptop. That stranger is who you are
|
|
|
|
|
becoming.
|
|
|
|
|
\end{tryit}
|
|
|
|
|
|
2026-07-03 07:44:40 +00:00
|
|
|
By the end of this book you will be able to read --- and extend --- the real
|
book overhaul moves 1+2: the minute-one artifact, and cold-open surgery on ch1
From the 7-reader didactic audit (control/BOOK-OVERHAUL-PLAN.md). The two
highest-leverage moves per the cold-open reader and the panel's most-repeated
finding.
MOVE 1 — the reader touches the real thing in minute one. The panel's single
loudest note: a book that teaches "demand verification" gave the reader
nothing to verify for twelve chapters. Now: the title page names
ltl.zkdefi.org (19 entries, one post-quantum, "verify every entry yourself by
the last chapter"); the preface opens on that page instead of a generic power
claim; ch1 gains a try-it box after the pyramid pointing at entries 13-16 and
18. And ch7's broken promise is honored — it invited "check one leaf" while
never printing the 71-digit Q; the exact Q from P25519.lean is now on the
page, no hidden digits (render-verified against the repo).
MOVE 2 — ch1 cold open. Per the cold reader who hooked at line 13 and wobbled
by line 31: the first worked box (a log10 re-derivation of a punch the prose
already landed) collapses to four lines, the mechanics pushed to Exercise 1.1
— getting the reader ~30 lines sooner to the headroom box, the genuinely novel
bit. The vague "In 2014, researchers…" opener becomes the actual bug: a
two-line diff captioned as the entire defect, anchored to the real Fiat-Crypto
S&P 2019 lineage (no fabricated CVE). Competitor roll-call → footnote.
Syllabus roadmap → a second-person promise ("by Chapter 7 you will have handed
a kernel a certificate…"). "Why Lean" vendor bullets → reader-inheritance
voice ("you start on a million lines of proved mathematics").
Builds here: tectonic, 116 pages, zero errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-07 22:14:43 +00:00
|
|
|
proofs at every layer of this pyramid. To make that concrete, here is what
|
|
|
|
|
you will personally be able to \emph{do}, and roughly when: by Chapter~7 you
|
|
|
|
|
will have handed a paranoid kernel a certificate that a 77-digit number is
|
|
|
|
|
prime, and watched it agree; by Chapter~9 you will read real Rust translated
|
|
|
|
|
into Lean and understand the one idea (the \emph{denotation function}) that
|
|
|
|
|
makes the translation trustworthy; by Chapter~12 you will stand on the apex
|
|
|
|
|
and read the signature-verification theorem for the actual code in your SSH
|
|
|
|
|
client. The chapters between here and there earn each of those, in order ---
|
|
|
|
|
Lean itself first, then the mathematics, then the bridge from real code, then
|
|
|
|
|
the climb.
|
2026-07-03 07:44:40 +00:00
|
|
|
|
Didactic mentorship revision: the ratchet rule, stated and honored
The owner's requirement, now the book's explicit contract (new "ratchet
rule" box in chapter 1): every load-bearing idea is worked at least
twice - once at napkin scale (mod 13, inverses by scanning) and once at
REAL scale, the actual 77-digit Ed25519 constants printed in full with
no digits hidden and no artificial zeros; where raw size genuinely
exceeds paper (a 77-digit square root), the book says so and teaches
witness-auditing instead of pretending.
Socratic audit result: chapters 1-11 already honor the rule (verified
rung by rung - e.g. ch6 pairs the Z/12 clock with 19^-1 mod the real p;
ch7 pairs Pratt-for-97 with costing the real certificate; ch8 runs the
extracted model at the real envelope edge). The gaps were ch12's three
summit rungs, which had NO numeric examples at all. Filled:
- Group law: "running the addition law by hand - napkin curve, then the
real one". Doubling (2,4)->(10,11) mod 13 in full; then the real base
point with x1, y1 printed in 5-digit groups, the first machine step
certified as x1*y1 = q*p + u with the 77-digit witness q printed, and
the student auditing it by casting out nines AND elevens (both clocks
close: 3=3, 1=1). Lands on the real 2B coordinates.
- Scalars: the cycle felt on the napkin curve first (order 16, so
21P = 5P) before the real prime ell.
- Apex: "decompression, run twice". Encode/decode (10,11) as "(11,
even)" mod 13 - x^2 = 3/9 = 9, roots {3,10}, parity picks 10; then
the real compressed base point: all 32 bytes printed (58 66...66),
byte 31 = 0x66 sign-bit read, y_B printed in full, and the
no-shortcuts full-size hand verification 5*y_B - 4 = 4*p, both
78-digit sides printed for digit-by-digit comparison. The square
root honestly declared machine territory, with the witness-checked
certificate named.
- New paper exercise 12.4 (+pathway/solution): encode & decompress
3P = (6,10) solo - the wrong root lands on -3P, one bit doing real
cryptographic work.
Every printed constant machine-verified before typesetting (base point
on-curve, q*p+u exact, 5y-4 = 4p exact, 2B on-curve, toy order 16).
PDF rebuilt: 109 pages, zero errors. Honesty ledger records the
revision.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 07:31:11 +00:00
|
|
|
\begin{bigidea}
|
|
|
|
|
\textbf{The ratchet rule of this book.} Every load-bearing idea is worked
|
|
|
|
|
at least twice: once at \emph{napkin scale} (a modulus like $13$, numbers
|
|
|
|
|
you can invert by scanning), and once at \emph{real scale} --- the actual
|
|
|
|
|
77-digit constants of Ed25519, printed in full, with no digits hidden and
|
|
|
|
|
no artificial zeros. The napkin run teaches the moves; the real-size run
|
|
|
|
|
proves the moves are the whole story, because they are \emph{identical} ---
|
|
|
|
|
only the digits get longer, and wherever raw size genuinely exceeds paper
|
|
|
|
|
(a 77-digit square root, say) the book says so explicitly and shows you
|
|
|
|
|
how to audit the machine's work instead (witnesses, small clocks,
|
|
|
|
|
certificates). If a step ever feels like a leap, back up one worked
|
|
|
|
|
example: the missing rung is there, at the smaller size.
|
|
|
|
|
\end{bigidea}
|
|
|
|
|
|
2026-07-03 07:44:40 +00:00
|
|
|
\section{Proofs versus tests: the honest comparison}
|
|
|
|
|
|
|
|
|
|
Formal verification is not magic, and this book will never pretend otherwise.
|
|
|
|
|
It is worth being precise, right now, about what a machine-checked proof does
|
|
|
|
|
and does not give you.
|
|
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
|
\begin{tabular}{@{}p{0.44\linewidth}p{0.48\linewidth}@{}}
|
|
|
|
|
\toprule
|
|
|
|
|
\textbf{Testing} & \textbf{Proving} \\
|
|
|
|
|
\midrule
|
|
|
|
|
Checks sampled inputs & Checks \emph{all} inputs \\
|
|
|
|
|
Cheap to start, cheap to run & Expensive to write, cheap to re-check \\
|
|
|
|
|
Finds bugs & Establishes their absence (w.r.t.\ the spec) \\
|
|
|
|
|
Trusts nothing & Trusts the spec, the model, the kernel \\
|
|
|
|
|
Silent about \emph{why} code is right & The proof \emph{is} the why \\
|
|
|
|
|
\bottomrule
|
|
|
|
|
\end{tabular}
|
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
|
|
That word \emph{spec} in the right column is the fine print, and it matters
|
|
|
|
|
enormously. A proof shows that code satisfies a specification. If the
|
|
|
|
|
specification says the wrong thing --- or says nothing, or is accidentally
|
|
|
|
|
trivial --- the proof is worthless no matter how green the checkmark. A
|
|
|
|
|
recurring theme of this book (it gets its own chapter,
|
|
|
|
|
Chapter~\ref{ch:honesty}) is how to read a verification claim skeptically:
|
|
|
|
|
What exactly was proven? Against which model of the code? Resting on which
|
|
|
|
|
axioms?
|
|
|
|
|
|
|
|
|
|
\begin{aha}
|
|
|
|
|
The most dangerous artifact in formal methods is not a wrong proof --- the
|
|
|
|
|
kernel prevents those. It is a \emph{correct proof of the wrong statement}.
|
|
|
|
|
Learning to smell those is as important as learning to write proofs at all.
|
|
|
|
|
\end{aha}
|
|
|
|
|
|
|
|
|
|
\section{Why Lean, and why now}
|
|
|
|
|
|
|
|
|
|
Twenty years ago, verifying real cryptographic C or Rust code was a heroic,
|
book overhaul moves 1+2: the minute-one artifact, and cold-open surgery on ch1
From the 7-reader didactic audit (control/BOOK-OVERHAUL-PLAN.md). The two
highest-leverage moves per the cold-open reader and the panel's most-repeated
finding.
MOVE 1 — the reader touches the real thing in minute one. The panel's single
loudest note: a book that teaches "demand verification" gave the reader
nothing to verify for twelve chapters. Now: the title page names
ltl.zkdefi.org (19 entries, one post-quantum, "verify every entry yourself by
the last chapter"); the preface opens on that page instead of a generic power
claim; ch1 gains a try-it box after the pyramid pointing at entries 13-16 and
18. And ch7's broken promise is honored — it invited "check one leaf" while
never printing the 71-digit Q; the exact Q from P25519.lean is now on the
page, no hidden digits (render-verified against the repo).
MOVE 2 — ch1 cold open. Per the cold reader who hooked at line 13 and wobbled
by line 31: the first worked box (a log10 re-derivation of a punch the prose
already landed) collapses to four lines, the mechanics pushed to Exercise 1.1
— getting the reader ~30 lines sooner to the headroom box, the genuinely novel
bit. The vague "In 2014, researchers…" opener becomes the actual bug: a
two-line diff captioned as the entire defect, anchored to the real Fiat-Crypto
S&P 2019 lineage (no fabricated CVE). Competitor roll-call → footnote.
Syllabus roadmap → a second-person promise ("by Chapter 7 you will have handed
a kernel a certificate…"). "Why Lean" vendor bullets → reader-inheritance
voice ("you start on a million lines of proved mathematics").
Builds here: tectonic, 116 pages, zero errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-07 22:14:43 +00:00
|
|
|
multi-year effort. Three things changed --- and each one is an advantage
|
|
|
|
|
\emph{you} inherit the moment you start:
|
2026-07-03 07:44:40 +00:00
|
|
|
|
|
|
|
|
\begin{enumerate}[leftmargin=1.6em]
|
book overhaul moves 1+2: the minute-one artifact, and cold-open surgery on ch1
From the 7-reader didactic audit (control/BOOK-OVERHAUL-PLAN.md). The two
highest-leverage moves per the cold-open reader and the panel's most-repeated
finding.
MOVE 1 — the reader touches the real thing in minute one. The panel's single
loudest note: a book that teaches "demand verification" gave the reader
nothing to verify for twelve chapters. Now: the title page names
ltl.zkdefi.org (19 entries, one post-quantum, "verify every entry yourself by
the last chapter"); the preface opens on that page instead of a generic power
claim; ch1 gains a try-it box after the pyramid pointing at entries 13-16 and
18. And ch7's broken promise is honored — it invited "check one leaf" while
never printing the 71-digit Q; the exact Q from P25519.lean is now on the
page, no hidden digits (render-verified against the repo).
MOVE 2 — ch1 cold open. Per the cold reader who hooked at line 13 and wobbled
by line 31: the first worked box (a log10 re-derivation of a punch the prose
already landed) collapses to four lines, the mechanics pushed to Exercise 1.1
— getting the reader ~30 lines sooner to the headroom box, the genuinely novel
bit. The vague "In 2014, researchers…" opener becomes the actual bug: a
two-line diff captioned as the entire defect, anchored to the real Fiat-Crypto
S&P 2019 lineage (no fabricated CVE). Competitor roll-call → footnote.
Syllabus roadmap → a second-person promise ("by Chapter 7 you will have handed
a kernel a certificate…"). "Why Lean" vendor bullets → reader-inheritance
voice ("you start on a million lines of proved mathematics").
Builds here: tectonic, 116 pages, zero errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-07 22:14:43 +00:00
|
|
|
\item \textbf{You start on a million lines of proved mathematics.} Lean~4
|
|
|
|
|
ships with \emph{Mathlib} --- finite fields, elliptic curves, number theory,
|
|
|
|
|
already formalized and checked. You do not build the tower from bare axioms;
|
|
|
|
|
you walk onto a finished floor and add one room.
|
|
|
|
|
\item \textbf{You verify the code that ships, not a story about it.} Tools
|
|
|
|
|
called \emph{Charon} and \emph{Aeneas} mechanically translate real Rust into
|
|
|
|
|
Lean, so what you reason about is \emph{derived} from the deployed source
|
|
|
|
|
rather than hand-copied by someone who might have copied it wrong
|
|
|
|
|
(Chapter~\ref{ch:rust}). This is the difference between verifying software
|
|
|
|
|
and verifying an essay about software.
|
|
|
|
|
\item \textbf{The machine does the boring 90\%.} Decision procedures like
|
|
|
|
|
\lean{omega} and \lean{decide} dispatch the routine arithmetic goals on
|
|
|
|
|
their own, so your attention goes to the 10\% that is actually interesting
|
|
|
|
|
--- the part where the real idea lives.
|
2026-07-03 07:44:40 +00:00
|
|
|
\end{enumerate}
|
|
|
|
|
|
|
|
|
|
None of this made verification \emph{easy}. It made verification
|
|
|
|
|
\emph{possible for a well-prepared person in finite time} --- and preparing
|
|
|
|
|
you is exactly what this book is for.
|
|
|
|
|
|
|
|
|
|
\begin{tryit}
|
|
|
|
|
You do not need anything installed yet, but if you want to run code from
|
|
|
|
|
Chapter~2 onward, install Lean now. One command:
|
|
|
|
|
\begin{lstlisting}
|
|
|
|
|
curl https://elan.lean-lang.org/elan-init.sh -sSf | sh
|
|
|
|
|
\end{lstlisting}
|
|
|
|
|
Then open the \code{exercises/} folder of this repository in VS~Code with the
|
|
|
|
|
\emph{Lean 4} extension. The orange progress bar you will see is the proof
|
|
|
|
|
checker working through the file --- your new collaborator saying hello.
|
|
|
|
|
\end{tryit}
|
|
|
|
|
|
|
|
|
|
\section*{Exercises}
|
|
|
|
|
|
|
|
|
|
\exercise{A function takes two 255-bit inputs and is buggy on exactly one
|
|
|
|
|
input pair. Assume you can test $10^{9}$ random pairs per second. Estimate the
|
|
|
|
|
expected time to find the bug by random testing, in multiples of the age of
|
|
|
|
|
the universe ($\approx 4\times10^{17}$ seconds). You may approximate freely;
|
|
|
|
|
the point is the order of magnitude.}
|
|
|
|
|
|
|
|
|
|
\exercise{Give an example, from your own programming experience, of a bug that
|
|
|
|
|
survived a test suite. What property would a specification have needed to
|
|
|
|
|
state in order to exclude it?}
|
|
|
|
|
|
|
|
|
|
\exercise{(Discussion) A colleague says: ``Our crypto library is audited by
|
|
|
|
|
three firms every year; formal verification is redundant.'' Name one class of
|
|
|
|
|
defect audits are better at than proofs, and one class where proofs are
|
|
|
|
|
strictly stronger.}
|
|
|
|
|
|
Major didactic overhaul: pen-and-paper worked examples + in-book solution pathways, 2x volume (53 -> 106 pages)
- pen-and-paper worked examples in all 12 chapters, using the REAL
constants throughout: 2^-64 waiting-time arithmetic, headroom budgets,
hand type-checking, rfl traces, full goal-state boards, the column-sum
audit at 2^54, inverting 19 mod p via Euclid, the x19 fold at real
weights, denoting p itself (telescope), the 16p audit (8 fails by 151),
the 254+11 inversion-chain bookkeeping, the substitution test, sizing
the 28-vs-1000 extraction, cofactor/torsion arithmetic, and the full
Bernstein-Lange completeness derivation
- CORRECTNESS FIX: ch7 asserted a false factorization of p-1; replaced
with the computationally verified p-1 = 2^2 * 3 * 65147 * Q (Q 71-digit
prime), witness w=2 verified for all four Pratt conditions
- every chapter's exercises now followed immediately by 'Solutions and
pathways' (pathway first, then answer), incl. new exercises
- NEW Interlude: a complete two-clause verification done entirely by
hand, then mapped line-by-line onto the compiled Lean proof
- NEW appendices: A pen-and-paper toolkit (8 recipe cards + drills +
answers), B guided walkthroughs of every exercise-file hole, C tour of
the real repositories; plus glossary, instructor notes, 13-week plan
- preamble: worked-example box, solution macros, math-safe inline code
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 08:55:00 +00:00
|
|
|
\exercise{Redo the headroom budget for a hypothetical radix-$26$
|
|
|
|
|
representation on $32$-bit words (ten limbs of $26$ bits for a 255-bit
|
|
|
|
|
value, a real design used on small CPUs). How many bits of headroom per
|
|
|
|
|
limb? How many lazy additions fit in the budget? Compare with the
|
|
|
|
|
radix-51/64-bit numbers and state which design must reduce more often.}
|
|
|
|
|
|
|
|
|
|
\section*{Solutions and pathways}
|
|
|
|
|
\solutionsintro
|
|
|
|
|
|
|
|
|
|
\solhead{1.1}
|
|
|
|
|
\pathway The only inputs that reveal the bug form a set of size $1$ inside
|
|
|
|
|
a set of size $2^{510}$, so a uniformly random test hits it with
|
|
|
|
|
probability $2^{-510}$; expected number of trials is $2^{510}$ (waiting
|
|
|
|
|
time of a geometric distribution). Then it is the Chapter-1 conversion
|
|
|
|
|
drill: powers of two $\to$ powers of ten $\to$ seconds $\to$ universes.
|
|
|
|
|
\answer Expected trials $2^{510} \approx 10^{153.5}$. At $10^9$ per second:
|
|
|
|
|
$10^{153.5 - 9} = 10^{144.5}$ seconds. Divide by the age of the universe,
|
|
|
|
|
$4 \times 10^{17}$ s:
|
|
|
|
|
\[
|
|
|
|
|
\frac{10^{144.5}}{4 \times 10^{17}} \approx 10^{126.9}
|
|
|
|
|
\quad\text{--- about } 10^{127} \text{ universe-ages.}
|
|
|
|
|
\]
|
|
|
|
|
Any answer within a few orders of magnitude is ``correct'': the lesson is
|
|
|
|
|
that no engineering factor (faster farms, smarter fuzzing schedules) dents
|
|
|
|
|
a number with $127$ digits of margin.
|
|
|
|
|
|
|
|
|
|
\solhead{1.2}
|
|
|
|
|
\pathway Pick a bug whose trigger was a \emph{property of the input}, not a
|
|
|
|
|
coding typo --- those are the ones a spec excludes. Then ask: what is the
|
|
|
|
|
universally quantified sentence that is false in the buggy program?
|
|
|
|
|
\answer (Model answer.) A JSON parser that crashed on deeply nested arrays
|
|
|
|
|
survived a big test suite: no test nested past depth $50$. The
|
|
|
|
|
specification that excludes it must \emph{quantify over all inputs}:
|
|
|
|
|
``for every input string, the parser terminates and returns either a value
|
|
|
|
|
or a well-formed error'' --- termination-for-all is exactly what the tests
|
|
|
|
|
never said. The general shape to remember: test suites assert
|
|
|
|
|
$P(x_1), \dots, P(x_n)$; specifications assert $\forall x,\, P(x)$; bugs
|
|
|
|
|
live in the gap.
|
|
|
|
|
|
|
|
|
|
\solhead{1.3}
|
|
|
|
|
\pathway Sort defect classes by \emph{whether their badness is expressible
|
|
|
|
|
as a violated formal property of the code}. Audits see things that are not
|
|
|
|
|
properties of the code; proofs cover input space no human can.
|
|
|
|
|
\answer Audits win at: flaws in the \emph{specification itself} and its
|
|
|
|
|
surroundings --- wrong protocol choice, misuse-prone APIs, side channels
|
|
|
|
|
outside the model, deployment and key-handling practice. A proof of the
|
|
|
|
|
wrong spec passes; a good auditor smells that the spec is wrong. Proofs are
|
|
|
|
|
strictly stronger at: input-space coverage for the stated property ---
|
|
|
|
|
carry bugs, overflow corners, algebraic edge cases on a measure-zero slice.
|
|
|
|
|
The honest synthesis: audits examine the \emph{claim}, proofs guarantee the
|
|
|
|
|
\emph{claim's body}. A serious system wants both, aimed at their targets.
|
|
|
|
|
|
|
|
|
|
\solhead{1.4}
|
|
|
|
|
\pathway Same two lines as the worked example, new constants: headroom
|
|
|
|
|
$= \text{word} - \text{radix}$; budget $= 2^{\text{headroom}}$.
|
|
|
|
|
\answer Headroom $32 - 26 = 6$ bits, so at most $2^{32}/2^{26} = 2^{6} =
|
|
|
|
|
64$ lazy additions --- against $8192$ for radix-51/64-bit, a budget $128$
|
|
|
|
|
times tighter. The radix-26 design must interleave reductions far more
|
|
|
|
|
often, and its correctness argument has $128$ times less slack for
|
|
|
|
|
miscounting --- one concrete reason ports of crypto code to small targets
|
|
|
|
|
are disproportionately bug-prone, and why per-fork verification
|
|
|
|
|
(Chapter~\ref{ch:field}) is not paranoia.
|
|
|
|
|
|
2026-07-03 07:44:40 +00:00
|
|
|
\begin{checkpoint}
|
|
|
|
|
Before moving on, you should be able to explain to a friend:
|
|
|
|
|
(1) why testing fundamentally cannot establish correctness of a 255-bit
|
|
|
|
|
arithmetic function; (2) what a proof assistant's kernel is and why its small
|
|
|
|
|
size matters; (3) what a proof of correctness actually promises --- and the
|
|
|
|
|
role the specification plays in that promise.
|
|
|
|
|
\end{checkpoint}
|