Verification plan
Written before any verifier code, per the working protocol for this artifact. Everything below is a commitment about what the two verifiers must do; if the implementation later disagrees with this plan, the plan is wrong and gets amended in place with a note, not silently.
What is being certified
A binary matrix over is the parity-check matrix of an code of covering radius iff its column multiset satisfies
Covering radius is exactly 2 iff additionally some syndrome is neither nor a single column. The four matrices to certify:
| file | provenance | ||
|---|---|---|---|
data/H_r10_n50.txt |
10 | 50 | the result; copied verbatim from ../compute/ |
data/kr_r10_n51.txt |
10 | 51 | Kaikkonen–Rosendahl 2003 baseline, rebuilt from the hex in arXiv:2511.02542 Thm 4.3 |
data/H_r18_n815.txt |
18 | 815 | QM at , built by verify/build_propagation.py |
data/H_r20_n1631.txt |
20 | 1631 | QM at , built by verify/build_propagation.py |
Exhaustive means exhaustive: syndromes at the top end, enumerated, no sampling, no early exit, no consulting a stored certificate.
Encoding convention (the one thing most likely to go wrong)
Two conventions collide here and they are reverses of each other.
- Repo convention (LSB-first). A column is an unsigned integer; bit
(counting from the least significant bit, ) is row of .
So the first identity column is the integer
1and the tenth is512. Used bycompute/H_r10_n50.txt, bycompute/witness_r10_n50.json, and by every.txtmatrix indata/. - Paper convention (MSB-first). In arXiv:2511.02542 Thm 4.3, the hex string
for a -row column has row 1 as the most significant of the ten bits:
1B601 1011 0110read top-to-bottom as rows 1..10.
The reconstruction of must therefore reverse the ten bits. A verifier that skips the reversal will report a spurious failure on the KR baseline only — the other three matrices never touch the paper's hex — which is a diagnostic worth stating out loud, because "only KR fails" means encoding, not mathematics.
Independent self-test of the reversal, taken from Thm 5.2(ii): the paper asserts
with ,
274, 254. Under the correct reversal this must come out
as .
The builder asserts this. It is a bit-order canary that costs nothing.
Verifier #1 — verify/verify.py (Python 3, stdlib only)
Reads a matrix .txt. Never reads a JSON certificate for the covering claim.
- Parse. Strip
#comments and blank lines. Require every remaining line to have the same number of whitespace-separated tokens, each in{0,1}. = number of lines, = tokens per line. Assemble column as (LSB-first). - Well-formedness. All columns nonzero; all pairwise distinct; every column . Shape matches the expected passed on the command line.
- Rank. Gaussian elimination on the integer columns (pivot = lowest set bit, XOR-reduce). Assert rank ; this is what makes the redundancy genuinely .
- Exhaustive coverage. Allocate an integer array
multof length initialised to 0. Incrementmult[0]once for the empty sum. Incrementmult[h]for each column . Incrementmult[h_i ^ h_j]for every unordered pair — all of them, no shortcuts. Then assertmin(mult) >= 1over the whole range. This is a full enumeration of by construction, and it yields the multiplicity data for free. - Radius exactly 2. Assert some has , . Since coverage already holds, the radius is not , hence exactly 2.
- Reporting. Multiplicity histogram over all syndromes (counting
the empty sum, singletons and unordered pairs as above); the pair-only
histogram restricted to the syndromes that are neither nor a column
(these are the ones that genuinely need a pair); the count of such syndromes;
the count with a unique pair representation (call these the forced-split
pairs — the two columns involved must land in distinct blocks of any
2-partition, so this number lower-bounds how constrained is); the
covering density as an exact
fractions.Fraction, printed reduced, alongside its decimal expansion. - Minimum distance and dependent triples. already follows from distinct-and-nonzero. Enumerate all triples — or equivalently all pairs with at index , which is the same set and cheaper — and report the count. iff that count is positive. Report the triples explicitly.
- Minimality (LO check). For each of the columns, delete it and
recount uncovered syndromes over the full range. Report the minimum
over all deletions. If that minimum is , no single column is
redundant and the set is a minimal 1-saturating set in ,
equivalently a locally optimal covering code. Implemented by decrementing
the shared
multarray rather than recomputing from scratch, then restoring it — and the restore is checked by re-asserting the total. - Partition checker (separate entry point,
--partition). Loadsdata/partition_p10.jsonfor the block assignment only, and re-derives the columns from the.txt. Cross-checks that the JSONcolumnslist equals the columns parsed from the matrix text as a set and in order. Then for every syndrome : if or , pass by definition (Def. 3.2 allows sums of 0 or 1 columns); otherwise require some pair withblock[i] != block[j]. Report the number of blocks and which syndromes, if any, fail.
Output is a stable, sorted, machine-readable dump (--emit-facts <path> writes
JSON) so the shell driver can assert on it and so the prose in NOTE.md can be
checked against it mechanically rather than by eye.
Verifier #2 — verify/verify.rs (Rust, no crates, rustc only)
Written after #1 exists but deliberately not a port of it. Sharing an encoding convention is unavoidable — that is the specification, not an implementation choice — but sharing an algorithm would make the pair redundant. So #2 differs where it can:
- Different coverage algorithm, opposite direction. #1 is pair-driven: walk
the pairs and mark what they hit. #2 is syndrome-driven: for
each , decide membership by scanning columns and
testing whether is in a
Vec<bool>membership table of size . These two agree only if the mathematics is right; a transcription error in one does not reproduce in the other. #2 additionally computes the multiplicity histogram by its own independent pair loop, and asserts its syndrome-driven verdict matches its own pair-driven multiplicities before it ever reports a number — an internal consistency check that #1 does not have. - Different rank routine. #1 reduces by lowest set bit; #2 does textbook column-echelon by highest set bit. Same answer, different pivot order.
- Different parser. #1 works row-wise then transposes; #2 accumulates directly into the column integers as it streams tokens.
- Different arithmetic for the density. #1 uses
fractions.Fraction; #2 reduces by an explicitu128gcdand prints numerator/denominator, then separately prints the decimal to 12 places by long division rather than by float. - Same partition check, but expressed as: build for each syndrome the set of block-pairs realising it, and require a non-diagonal one. #2 parses the partition JSON with a hand-rolled integer scanner (no serde), which is ugly but keeps the dependency surface at zero and means a malformed JSON is a hard error rather than a silent default.
Honest limitation, stated up front. Both verifiers were written in the same session by the same author. "Independent" here means: two languages, two algorithms, two parsers, two arithmetic paths, and no shared code or shared intermediate files. It does not mean two people. The one shared assumption that cannot be factored out is the LSB-first column encoding — and that assumption is itself pinned by the canary against the published paper. A third party re-deriving the columns under the opposite convention would get the bit-reverse of every column, which is an -linear relabelling of and therefore preserves every claim made here.
Builder — verify/build_propagation.py
Implements Construction QM (arXiv:2511.02542, Thm 4.1, eq. (4.2) and (4.4)) literally, from the paper, not from any prior script.
- Field arithmetic: by carry-less multiply and reduce, modulus
(
0x13) for and (0x25) for . Self-test before use: closure, commutativity, associativity of multiplication on all triples, distributivity, and existence and uniqueness of an inverse for every nonzero element. Cheap at and it catches a wrong modulus instantly. - Condition from (4.2): assert explicitly, as an
assert, for each tried; enumerate all satisfying it rather than assuming . - Indicators: exactly. Columns in distinct blocks must get distinct indicators, so the indicator sets are pairwise disjoint, and forces with . Feasible iff , which is exactly (4.2) again. Greedy allocator: one indicator per block first, then top up in block order to capacity. Deterministic; assert the resulting allocation is a partition of .
- Columns: for all including , giving columns per starting column. Plus : the columns , over the nonzero -bit vectors — i.e. the Hamming parity-check matrix in the bottom rows.
- Layout of the new rows, LSB-first: rows carry , rows carry , rows carry . Assert from (4.4).
- No RNG anywhere. Column order is fixed: first, then , matching (3.2).
- The resulting matrices then go through the full verifier, both of them. Nothing about QM is taken on trust from the theorem statement; the theorem tells us where to look and the exhaustive check is the proof of the instance.
Family table
Generated, not typed. From (4.2)/(4.4): a state is with and an upper bound on ; the length is . A step with parameter is legal iff , and produces with . Breadth-first from the seed , keeping for each reachable the smallest found, gives the reachable even honestly — including the gaps, which are real and must be shown as gaps. Closed form and asymptotic density both fall out and are asserted against the table.
Driver — run_all.sh
set -euo pipefail, deterministic, byte-identical across runs (no timestamps,
no paths outside the repo, sorted output, LC_ALL=C). Rebuilds the propagated
matrices from scratch into a temp dir and cmps them against the committed
copies, so a stale committed matrix is a hard failure. Runs both verifiers on
all four matrices, diffs their fact dumps, and asserts each hard-coded expected
value individually with a named failure message. Exit 0 only if everything
passes.