2026-07-03 07:44:40 +00:00
|
|
|
\chapter{Verifying a Field: The Full Campaign}
|
|
|
|
|
\label{ch:field}
|
|
|
|
|
|
|
|
|
|
\section{The summit statement}
|
|
|
|
|
|
|
|
|
|
Every thread so far --- specs as types, tactics, automation, $\Fp$,
|
|
|
|
|
primality, extraction, denotation --- was preparation for one theorem. In
|
|
|
|
|
the companion repositories it is called the \emph{field implementation
|
|
|
|
|
certificate}, and (lightly paraphrased) it says:
|
|
|
|
|
|
|
|
|
|
\begin{lstlisting}[language=Lean]
|
|
|
|
|
theorem fieldImplementation :
|
|
|
|
|
-- p is prime, so ZMod p is genuinely a field
|
|
|
|
|
Nat.Prime p
|
|
|
|
|
-- and for all bounded limb arrays, every operation's
|
|
|
|
|
-- commuting square closes:
|
|
|
|
|
∧ (∀ a b, Bnd a → Bnd b → AddSquare a b)
|
|
|
|
|
∧ (∀ a b, Bnd a → Bnd b → SubSquare a b)
|
|
|
|
|
∧ (∀ a b, Bnd a → Bnd b → MulSquare a b)
|
|
|
|
|
∧ (∀ a, Bnd a → SquareSquare a)
|
|
|
|
|
∧ (∀ a, Bnd a → InvertSquare a) -- Fermat chain: a^(p-2)
|
|
|
|
|
∧ ... -- reduce, negate, encode
|
|
|
|
|
\end{lstlisting}
|
|
|
|
|
|
|
|
|
|
One theorem, kernel-checked, quantified over \emph{every} input the
|
|
|
|
|
representation admits: the extracted dalek field arithmetic implements
|
|
|
|
|
$\Fp$. This chapter is the story of the campaign that proves it --- told
|
|
|
|
|
honestly, including the two places where the terrain fought back, because
|
|
|
|
|
the failures teach more than the victories.
|
|
|
|
|
|
|
|
|
|
\section{Order of battle}
|
|
|
|
|
|
|
|
|
|
You do not prove such a conjunction by heroism; you prove it by sequencing.
|
|
|
|
|
The campaign order in the real projects, and the reason for each position:
|
|
|
|
|
|
|
|
|
|
\begin{enumerate}[leftmargin=1.6em]
|
|
|
|
|
\item \textbf{Bounds lemmas first} --- pure \lean{omega} facts about limb
|
|
|
|
|
sizes, no denotation at all. Cheap, and everything depends on them.
|
|
|
|
|
\item \textbf{Primality} (Chapter~\ref{ch:prime}) --- independent of the
|
|
|
|
|
code entirely; it dignifies \lean{ZMod p} into a field.
|
|
|
|
|
\item \textbf{add, sub, negate} --- linear operations; the commuting squares
|
|
|
|
|
close with \lean{omega} plus the denotation unfolds. Confidence builders.
|
|
|
|
|
\item \textbf{reduce} --- the $\times 19$ fold in isolation. Proving it
|
|
|
|
|
alone, before mul uses it, halves the hardest proof's size.
|
|
|
|
|
\item \textbf{mul, square} --- the boss fight of Chapter~\ref{ch:denotation}:
|
|
|
|
|
column sums, carries, folds. Squaring is mul with algebraic shortcuts ---
|
|
|
|
|
a separate code path in dalek, hence a separate theorem. No shortcuts
|
|
|
|
|
in the proof: the \emph{code's} shortcut is precisely what needs checking.
|
|
|
|
|
\item \textbf{invert} --- the 254-squaring Fermat chain, verified as a
|
|
|
|
|
\lean{calc} of exponent bookkeeping on top of \code{mul}/\code{square}
|
|
|
|
|
specs, ending at $a^{p-2}$; Fermat's little theorem (Mathlib's) closes
|
|
|
|
|
the square.
|
|
|
|
|
\end{enumerate}
|
|
|
|
|
|
|
|
|
|
Notice the shape: \emph{each layer consumes only the specs of the layer
|
|
|
|
|
below}, never reaching into implementations. By step 6 you are doing exponent
|
|
|
|
|
arithmetic, blissfully ignorant of carries. That is the compositionality that
|
|
|
|
|
Chapter~\ref{ch:denotation}'s two-clause specs (bounds + value) were designed
|
|
|
|
|
to buy.
|
|
|
|
|
|
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}{why $16p$ --- auditing a design constant to the bit}
|
|
|
|
|
Step 3's subtraction hides the field layer's most quotable design
|
|
|
|
|
decision, and you can audit it completely. The problem: compute $a - b$
|
|
|
|
|
limb-wise in unsigned words, where limbs of $b$ may be as large as
|
|
|
|
|
$2^{54} - 1$ (the invariant's edge) while limbs of $a$ may be as small as
|
|
|
|
|
$0$. Unsigned subtraction would truncate (Chapter~\ref{ch:lean}); the fix
|
|
|
|
|
is to compute $a + (kp - b)$ for a suitable multiple $k$ of the prime ---
|
|
|
|
|
denotationally free, since $kp \equiv 0$ --- chosen so that every limb of
|
|
|
|
|
$kp - b$ stays positive. How large must $k$ be? The limb constants of
|
|
|
|
|
$kp$ scale the telescoped representation from Chapter~\ref{ch:denotation}:
|
|
|
|
|
\[
|
|
|
|
|
kP = \big(k(2^{51}-19),\; k(2^{51}-1),\; k(2^{51}-1),\; k(2^{51}-1),\;
|
|
|
|
|
k(2^{51}-1)\big),
|
|
|
|
|
\]
|
|
|
|
|
whose \emph{smallest} limb is $k(2^{51} - 19)$. Positivity of every limb
|
|
|
|
|
of $kp - b$ demands
|
|
|
|
|
\[
|
|
|
|
|
k\,(2^{51} - 19) \;\ge\; 2^{54} - 1 .
|
|
|
|
|
\]
|
|
|
|
|
Try the candidates, because powers of two are what the code wants:
|
|
|
|
|
\[
|
|
|
|
|
k = 8:\quad 8(2^{51}-19) = 2^{54} - 152 \;<\; 2^{54} - 1
|
|
|
|
|
\qquad\text{✗ fails, by 151;}
|
|
|
|
|
\]
|
|
|
|
|
\[
|
|
|
|
|
k = 16:\quad 16(2^{51}-19) = 2^{55} - 304 \;\ge\; 2^{54} - 1
|
|
|
|
|
\qquad\text{✓ with } 2^{54} - 303 \text{ to spare.}
|
|
|
|
|
\]
|
|
|
|
|
So $16$ is the \emph{least} power of two that works --- $8$ misses by a
|
|
|
|
|
margin of $151$, invisible to any test that doesn't drive a limb of $b$
|
|
|
|
|
within $151$ of the very top of its envelope. Two more checks complete
|
|
|
|
|
the audit: the result's limbs are bounded by
|
|
|
|
|
$2^{54} + 2^{55} < 2^{56} < 2^{64}$ (no overflow on the additive side ✓),
|
|
|
|
|
and the denotation shifts by exactly $16p \equiv 0$ ✓. In the shipped
|
|
|
|
|
proof this box is one lemma with three \lean{omega} obligations; in the
|
|
|
|
|
git history of more than one real crypto library, the analogous constant
|
|
|
|
|
is a patched CVE. Now you know how to tell which side of that line a
|
|
|
|
|
codebase is on.
|
|
|
|
|
\end{worked}
|
|
|
|
|
|
|
|
|
|
\begin{worked}{verifying the inversion chain's bookkeeping --- all 265 steps}
|
|
|
|
|
Step 6 sounds heroic --- verify a hand-crafted chain of $254$ squarings
|
|
|
|
|
and $11$ multiplications computes $a^{p-2}$ --- until you see that the
|
|
|
|
|
whole verification is \emph{exponent arithmetic}, and the exponents obey
|
|
|
|
|
one identity you can check at every scale. The chain builds values
|
|
|
|
|
$a^{e}$ for a cascade of exponents $e$; squaring doubles $e$, multiplying
|
|
|
|
|
adds them. The dalek chain's opening moves:
|
|
|
|
|
\[
|
|
|
|
|
\begin{array}{lcl}
|
|
|
|
|
z_2 = a^2 & & e = 2\\
|
|
|
|
|
z_9 = (z_2)^{2^2} \cdot a & & e = 2\cdot 4 + 1 = 9\\
|
|
|
|
|
z_{11} = z_9 \cdot z_2 & & e = 9 + 2 = 11\\
|
|
|
|
|
z_{2^5-1} = (z_{11})^{2} \cdot z_9 & & e = 22 + 9 = 31 = 2^5 - 1 .
|
|
|
|
|
\end{array}
|
|
|
|
|
\]
|
|
|
|
|
From $31 = 2^5 - 1$ the chain climbs by a doubling ladder whose single
|
|
|
|
|
identity you should verify once symbolically:
|
|
|
|
|
\[
|
|
|
|
|
(2^k - 1)\cdot 2^k + (2^k - 1) \;=\; 2^{2k} - 1
|
|
|
|
|
\qquad\text{(``shift a block of $k$ ones up by $k$ and fill'').}
|
|
|
|
|
\]
|
|
|
|
|
Check it at $k=5$: $31 \cdot 32 + 31 = 992 + 31 = 1023 = 2^{10}-1$ ✓.
|
|
|
|
|
The ladder then assembles mixed blocks the same way:
|
|
|
|
|
$2^{10}-1 \to 2^{20}-1 \to 2^{40}-1$, then
|
|
|
|
|
$(2^{40}-1)2^{10} + (2^{10}-1) = 2^{50}-1$, then
|
|
|
|
|
$2^{100}-1 \to 2^{200}-1$, then
|
|
|
|
|
$(2^{200}-1)2^{50} + (2^{50}-1) = 2^{250}-1$. Final move: shift five and
|
|
|
|
|
add the stashed $z_{11}$:
|
|
|
|
|
\[
|
|
|
|
|
(2^{250}-1)\cdot 2^{5} + 11 \;=\; 2^{255} - 32 + 11 \;=\; 2^{255} - 21
|
|
|
|
|
\;=\; p - 2 . \qquad ✓
|
|
|
|
|
\]
|
|
|
|
|
Every line above is hand-checkable, and together they \emph{are} the
|
|
|
|
|
correctness of the inversion chain --- modulo only ``squaring squares and
|
|
|
|
|
multiplication adds exponents,'' which is the already-proven \code{mul}
|
|
|
|
|
and \code{square} specs feeding Fermat (Chapter~\ref{ch:modular}). Count
|
|
|
|
|
the cost while you are here. Squarings, stage by stage:
|
|
|
|
|
$1$ (to $z_2$) $+\,2$ (to $z_9$) $+\,1$ (to $z_{31}$) $+\,5+10+20$ (to
|
|
|
|
|
$2^{10},2^{20},2^{40}$) $+\,10$ (to $2^{50}$) $+\,50+100$ (to
|
|
|
|
|
$2^{100},2^{200}$) $+\,50$ (to $2^{250}$) $+\,5$ (final shift)
|
|
|
|
|
$= 254$. Multiplications: one per block-join --- count the ``$\cdot$''s
|
|
|
|
|
above --- exactly $11$. The advertised $254 + 11$ is not folklore; you
|
|
|
|
|
just audited it. That is the point of this box: ``verify 265 field
|
|
|
|
|
operations'' collapsed into ten lines of exponent algebra a patient
|
|
|
|
|
undergraduate audits over coffee.
|
|
|
|
|
\end{worked}
|
|
|
|
|
|
2026-07-03 07:44:40 +00:00
|
|
|
\section{Dispatches from the terrain}
|
|
|
|
|
|
|
|
|
|
\textbf{The wall that was really there.} Partway up, one proof style hit a
|
|
|
|
|
genuine limit of the tool: correctness certificates for \code{mul}-scale
|
|
|
|
|
goals, when handed to a general decision procedure in one monolithic call,
|
|
|
|
|
generate internal certificates with coefficients on the order of $2^{256}$
|
|
|
|
|
--- and checking them can exhaust the proof checker's memory. One such call,
|
|
|
|
|
during the development of the Pasta field proofs, consumed twelve gigabytes
|
|
|
|
|
and crashed the machine (Chapter~\ref{ch:automation} told you this story
|
|
|
|
|
from the tactic side). The cure was never cleverness --- it was
|
|
|
|
|
\emph{decomposition}: isolate each carry step as its own small lemma with a
|
|
|
|
|
tiny context, prove the value identity with \lean{linear_combination}
|
|
|
|
|
(a tactic that checks a \emph{stated} linear certificate rather than
|
|
|
|
|
searching for one), and let the big theorem be an assembly of small
|
|
|
|
|
checked parts. The same discipline, plus hard memory caps on the checker
|
|
|
|
|
process, became house infrastructure.
|
|
|
|
|
|
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}{the wall, quantified --- why the monolithic proof dies}
|
|
|
|
|
The memory catastrophe is not mystical; you can estimate it on one page,
|
|
|
|
|
and the estimate teaches the cure. When a decision procedure like
|
|
|
|
|
\lean{omega} proves a linear goal, it does not just say ``true'' --- it
|
|
|
|
|
emits a \emph{certificate}: a linear combination of the hypotheses with
|
|
|
|
|
explicit integer coefficients that the kernel then re-checks
|
|
|
|
|
(Chapter~\ref{ch:prime}'s find/check split, again). Now count what a
|
|
|
|
|
\emph{monolithic} field-multiplication goal hands it. The goal relates
|
|
|
|
|
quantities at wildly different scales: raw limbs ($\sim 2^{51}$), column
|
|
|
|
|
sums ($\sim 2^{111}$), folded values ($\sim 2^{116}$), and the final
|
|
|
|
|
positional stack, whose top weight is $2^{204}$ --- so eliminating
|
|
|
|
|
variables across the whole system produces certificate coefficients up
|
|
|
|
|
to the \emph{products} of these scales: numbers of order $2^{256}$ to
|
|
|
|
|
$2^{512}$, i.e.\ integers of $80$--$150$ decimal digits. Per
|
|
|
|
|
coefficient that is only tens of bytes --- but the elimination is
|
|
|
|
|
quadratic-ish in the hypothesis count: with $\sim 60$ hypotheses (five
|
|
|
|
|
limbs each for two inputs, nine columns, nine carries, plus bounds for
|
|
|
|
|
everything), the certificate and the kernel's intermediate terms
|
|
|
|
|
multiply into \emph{millions} of big-number nodes, each participating
|
|
|
|
|
in further products. Twelve gigabytes is not even surprising once you
|
|
|
|
|
draw the multiplication table of scales --- and this estimate, run
|
|
|
|
|
\emph{before} the tactic, is how the wall gets predicted rather than
|
|
|
|
|
hit.
|
|
|
|
|
|
|
|
|
|
The cure now reads directly off the arithmetic: cut the elimination
|
|
|
|
|
range. Prove each carry step as its \emph{own} lemma with only its own
|
|
|
|
|
few hypotheses in scope (coefficients stay near the step's own scale);
|
|
|
|
|
where a large linear identity is genuinely needed, state it yourself
|
|
|
|
|
and let \lean{linear_combination} \emph{check} your stated certificate
|
|
|
|
|
instead of searching for one (checking is cheap; finding at scale was
|
|
|
|
|
the memory bomb). The companion repos' rule --- no blanket automation
|
|
|
|
|
in fat contexts --- is this box, written as policy. And note the shape
|
|
|
|
|
of the lesson: it is the \emph{same} headroom discipline as the code's
|
|
|
|
|
(bound your intermediates, spend your budget consciously), applied one
|
|
|
|
|
level up, to the proof itself.
|
|
|
|
|
\end{worked}
|
|
|
|
|
|
2026-07-03 07:44:40 +00:00
|
|
|
\begin{aha}
|
|
|
|
|
There is a deep symmetry in that fix worth savoring: the \emph{proof} was
|
|
|
|
|
restructured exactly the way the \emph{code} was --- into small steps with
|
|
|
|
|
controlled intermediate size. Delayed carries in the implementation; small
|
|
|
|
|
lemmas in the verification. Bounded limbs; bounded contexts. Good proofs and
|
|
|
|
|
good fast code turn out to obey the same engineering aesthetics. This is not
|
|
|
|
|
a coincidence; both are fighting combinatorial growth with structure.
|
|
|
|
|
\end{aha}
|
|
|
|
|
|
|
|
|
|
\textbf{Four forks, one method, real divergence.} The companion projects
|
|
|
|
|
verify not just upstream \code{curve25519-dalek} but three production forks
|
|
|
|
|
(Solana's, RISC~Zero's, Betrusted's) --- each against \emph{its own}
|
|
|
|
|
extraction. Worth it? The audit found the forks implement the same
|
|
|
|
|
constant-time conditional selection three different ways (a \code{subtle}
|
|
|
|
|
crate trait, a volatile-read \code{black_box}, a hand-rolled arithmetic
|
|
|
|
|
mask), and one fork reorders instructions in point doubling. All correct ---
|
|
|
|
|
\emph{provably}, now --- but the divergence is exactly the kind of thing
|
|
|
|
|
that silently breaks when someone ``harmonizes'' code during a rebase.
|
|
|
|
|
Per-fork verification is not pedantry; it is how you notice that ``the same
|
|
|
|
|
library'' isn't.
|
|
|
|
|
|
|
|
|
|
\begin{pitfall}
|
|
|
|
|
A verified fork is verified \emph{at a commit}. Change one line of
|
|
|
|
|
arithmetic and the certificate is stale --- that is a feature (the proof
|
|
|
|
|
\emph{should} break when the code changes), but it means verification is a
|
|
|
|
|
\emph{process wired into maintenance}, not a trophy. The companion repos
|
|
|
|
|
ship \code{check.sh} scripts that re-extract and re-verify from scratch;
|
|
|
|
|
treat those as the project's pulse, not as CI decoration.
|
|
|
|
|
\end{pitfall}
|
|
|
|
|
|
|
|
|
|
\section{Reading a certificate like a professional}
|
|
|
|
|
|
|
|
|
|
Suppose a stranger hands you a repository claiming ``formally verified
|
|
|
|
|
field arithmetic.'' Chapter~\ref{ch:honesty} gives you the full audit
|
|
|
|
|
protocol, but the field-layer questions you can already ask are these:
|
|
|
|
|
|
|
|
|
|
\begin{itemize}[leftmargin=1.4em]
|
|
|
|
|
\item \textbf{What is denoted?} Find the denotation function. Does it map
|
|
|
|
|
the \emph{extracted} representation (good) or a hand-written lookalike
|
|
|
|
|
(Chapter~\ref{ch:rust}'s hole)?
|
|
|
|
|
\item \textbf{Is the square complete?} Value equation \emph{and} bounds
|
|
|
|
|
propagation \emph{and} the \lean{.ok} clause --- a spec that assumes
|
|
|
|
|
success proves nothing about overflow.
|
|
|
|
|
\item \textbf{Is the quantifier honest?} \lean{∀ a b} with bounds
|
|
|
|
|
hypotheses, or a handful of \lean{example}s on constants dressed up as
|
|
|
|
|
coverage?
|
|
|
|
|
\item \textbf{Does anything say \lean{sorry}?} One \lean{sorry} anywhere in
|
|
|
|
|
the dependency chain and the certificate is decorative. The checker will
|
|
|
|
|
tell you; ask it.
|
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
|
|
\begin{tryit}
|
|
|
|
|
Do the audit for real: open \code{dalek-ed25519-verified}, find the
|
|
|
|
|
denotation, pick the \code{sub} spec, and check the three clauses against
|
|
|
|
|
the list above. Then run the repo's \code{check.sh} and watch the whole
|
|
|
|
|
pyramid rebuild. Total time: one coffee. Skill acquired: permanent.
|
|
|
|
|
\end{tryit}
|
|
|
|
|
|
|
|
|
|
\section*{Exercises}
|
|
|
|
|
|
|
|
|
|
\exercise{Field subtraction in dalek computes $a - b$ as
|
|
|
|
|
$a + (16p - b)$ limb-wise (adding a multiple of $p$ keeps limbs positive ---
|
|
|
|
|
recall \lean{Nat} truncation!). State the commuting square for \code{sub}
|
|
|
|
|
including the exact multiple-of-$p$ fact you would need as a lemma, and
|
|
|
|
|
explain why $16p$ rather than $p$.}
|
|
|
|
|
|
|
|
|
|
\exercise{The Fermat inversion chain computes $a^{p-2}$ via 254 squarings
|
|
|
|
|
and 11 multiplications. Verify the exponent bookkeeping for the first three
|
|
|
|
|
steps of dalek's actual chain: $a^2$, $a^{9} = (a^2)^{2\cdot 2} \cdot a$,
|
|
|
|
|
$a^{11} = a^9 \cdot a^2$. (The full chain is exercise-by-induction: each
|
|
|
|
|
step's exponent is a sum of previous ones --- addition-chain arithmetic.)}
|
|
|
|
|
|
|
|
|
|
\exercise{(Discussion) Step 5 refuses to trust the squaring shortcut and
|
|
|
|
|
verifies \code{square} separately from \code{mul}. A colleague argues
|
|
|
|
|
``square is just \code{mul a a}, reuse the theorem.'' What, concretely,
|
|
|
|
|
would that argument miss about the code under verification?}
|
|
|
|
|
|
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
|
|
|
\section*{Solutions and pathways}
|
|
|
|
|
\solutionsintro
|
|
|
|
|
|
|
|
|
|
\solhead{10.1}
|
|
|
|
|
\pathway Assemble from parts you own: the two-clause spec shape
|
|
|
|
|
(Chapter~\ref{ch:denotation}), the multiple-of-$p$ freedom (the telescope
|
|
|
|
|
worked example), and the positivity audit (this chapter's $16p$ worked
|
|
|
|
|
example). The exercise is really asking you to \emph{compose} them into
|
|
|
|
|
one statement.
|
|
|
|
|
\answer The commuting square for \code{sub}, with the lemma named:
|
|
|
|
|
\[
|
|
|
|
|
\mathrm{Bnd54}(a) \to \mathrm{Bnd54}(b) \to
|
|
|
|
|
\exists c,\; \code{sub}\,a\,b = \mathtt{.ok}\ c \;\wedge\;
|
|
|
|
|
\mathrm{Bnd56}(c) \;\wedge\; \denote{c} = \denote{a} - \denote{b},
|
|
|
|
|
\]
|
|
|
|
|
resting on the lemma $\denote{16P} = 16p \equiv 0 \pmod p$ (the
|
|
|
|
|
telescope, scaled by $16$), which justifies
|
|
|
|
|
$\denote{a + (16P - b)} = \denote{a} + 0 - \denote{b}$. Why $16$ and not
|
|
|
|
|
$p$ itself (i.e.\ $k = 1$): positivity of every limb of $kP - b$ requires
|
|
|
|
|
the \emph{smallest} limb constant, $k(2^{51}-19)$, to dominate the
|
|
|
|
|
\emph{largest} allowed limb of $b$, $2^{54}-1$; $k = 1$ gives
|
|
|
|
|
$2^{51}-19 \ll 2^{54}$ --- hopeless --- and even $k = 8$ falls $151$
|
|
|
|
|
short, as the worked example computed. First power of two that clears
|
|
|
|
|
the bar: $16$.
|
|
|
|
|
|
|
|
|
|
\solhead{10.2}
|
|
|
|
|
\pathway Squaring doubles the exponent; multiplying adds. Track only
|
|
|
|
|
exponents and check each claimed identity by substitution --- the field
|
|
|
|
|
elements are irrelevant to the bookkeeping, which is the insight that
|
|
|
|
|
makes the whole verification tractable.
|
|
|
|
|
\answer $a^2$: exponent $2$ ✓ (one squaring).
|
|
|
|
|
$a^9 = (a^2)^{2\cdot 2} \cdot a$: squaring $z_2$ twice gives exponent
|
|
|
|
|
$2 \cdot 2 \cdot 2 = 8$; multiplying by $a$ adds $1$: exponent $9$ ✓
|
|
|
|
|
(two squarings, one multiplication).
|
|
|
|
|
$a^{11} = a^9 \cdot a^2$: $9 + 2 = 11$ ✓ (one multiplication).
|
|
|
|
|
The induction that carries the rest: each ladder stage claims
|
|
|
|
|
$(2^j - 1)\cdot 2^k + (2^k - 1) = 2^{j+k} - 1$ for the block sizes
|
|
|
|
|
$(j,k)$ it uses --- verify it once in general:
|
|
|
|
|
$(2^j - 1)2^k + 2^k - 1 = 2^{j+k} - 2^k + 2^k - 1 = 2^{j+k} - 1$ ✓ ---
|
|
|
|
|
and every remaining line of the chain is an instance. Addition-chain
|
|
|
|
|
verification in full: substitute, cancel, done.
|
|
|
|
|
|
|
|
|
|
\solhead{10.3}
|
|
|
|
|
\pathway Ask what \emph{differs between the two code paths}, not between
|
|
|
|
|
the two mathematical functions. The math of \code{square a} and
|
|
|
|
|
\code{mul a a} agree; the \emph{instructions} do not.
|
|
|
|
|
\answer Three concrete misses. (1) \code{square} is a \emph{different
|
|
|
|
|
routine}: it exploits symmetry ($a_i a_j$ appears twice for $i \neq j$,
|
|
|
|
|
so it computes $2 a_i a_j$ once), which changes the column expressions,
|
|
|
|
|
the constant factors, and therefore the \emph{bounds} --- the doubled
|
|
|
|
|
terms eat one extra headroom bit that \code{mul}'s proof never had to
|
|
|
|
|
account for. (2) A bug in that symmetry trick --- the classic one is a
|
|
|
|
|
missing factor of $2$ on exactly one cross term --- lives \emph{only} in
|
|
|
|
|
\code{square}'s code path; a theorem about \code{mul} quantifies over
|
|
|
|
|
\code{mul}'s instructions and says nothing about it. (3) Even the
|
|
|
|
|
\lean{.ok} clause differs: overflow behavior depends on the actual
|
|
|
|
|
intermediate expressions, not on the mathematical value. The one-line
|
|
|
|
|
summary for design reviews: \emph{we verify code paths, not functions ---
|
|
|
|
|
if the optimizer wrote a second path, the verifier owes a second
|
|
|
|
|
theorem}. (This is also exactly why the four forks each got their own
|
|
|
|
|
proofs: same math, four instruction streams.)
|
|
|
|
|
|
2026-07-03 07:44:40 +00:00
|
|
|
\begin{checkpoint}
|
|
|
|
|
You should now be able to: state the field implementation certificate and
|
|
|
|
|
every quantifier in it; recite the campaign order and justify why bounds
|
|
|
|
|
and \code{reduce} come early; tell the memory-wall story and its
|
|
|
|
|
decomposition moral; and audit a stranger's field-layer claim with four
|
|
|
|
|
pointed questions.
|
|
|
|
|
\end{checkpoint}
|