igneum/docs/analysis/attack-pass-2026-10.md
2026-10-07 10:15:58 +00:00

376 lines
40 KiB
Markdown

# Internal attack pass before the freeze (F1 to F10)
The internal cryptanalysis pass of `docs/plans/cryptanalysis.md` section 4.2, run before the freeze tag
`cryptanalysis-target-1`, so the paid engagement confirms rather than discovers. the project lead's word, 7 October 2026:
"make sure they find ZERO flaws". Every finding is ours, fixed and re-gated, before any firm starts.
Target: the hash class the chain runs after 0.3.15's flip, `igneum-pow` generator v4 `V4_CLASS` = `mx8+sh256x27`
(`LoadClass::MX8`, `ShadowClass { instrs: 256, reps: 27 }`), the acceptance rule, the verifier, the era draw,
the latency-shadow dataset and ladder, the chip and FPGA cost model. Scope and gates are section 1.1 and 1.4 of
the plan, the same tests the firm is held to.
Lane: attack-pass, worktree `igneum-wt-attack`, branch `attack-pass` from `origin/master` `ab99e5e3`.
Binary built on igneum-build-1 (ELF x86-64, `igneum-pow` 0.2.0, sha256 6d2867...1a9ebe5) and run there under
the box's slots; model and era work from `sim/horizon/algorithm/model.py` and `infra/fast-time/`. Each row below
carries the method, the known-failed shape where one exists, the result with numbers, and PASS, RUNNING,
BLOCKED or FINDING. The freeze tag waits on every row reading PASS or FIXED-AND-PASSED, and on the era VDF (F7 sub-row a) landing in
the node with F7's re-roll harness reading 0 re-rolls against it. Main checks every number
against the log before quoting it to the project lead.
## Status board
| # | Attack | Gate (same as 1.4) | Result so far | Status |
|---|---|---|---|---|
| F1 | Shadow block compressibility and shortcut search | no compression of the shadow block beyond the honest compiler's simplification, measured against that compiler on the same program; the 27 repetitions never fewer than 27x (coordinator's ruling 7 Oct 2026, 12:3x UK; the plan's gate (1) and row F1 carry the same) | 10^4 and 10^5 class v4 programs: saved instructions mean 0.62%, max 5.078% at 10^5 (1 of 100,000 over 5%, 0 over 10%); nothing folds or dedupes across the 27 passes; every saving is local peephole algebra that clang -O3 removes from the honest kernel too (IR counts match on the worst programs), so against the compiler the compression is 0; 0 mismatches in 2 x 10^5 differential and verifier checks, z3 window proofs 0 counterexamples. AP-F1-1 routed to the v5 list as a shadow redundancy bound. Record `docs/analysis/attack-pass/f1-shadow.md` | PASS; AP-F1-1 on the v5 list |
| F2 | Mixer round margin (SAT/MILP, 1 to 4 keyed applications) | no distinguisher or shortcut beyond 2 of the 8 applications | one application characterised (differential weight 10 to 12, linear 1, verified on the real code on three days); two applications: no trail at or below weight 20 to 24 within 7,200 s per job, the MSB and LSB families die at two; rotational-XOR no bias at one application; the multiply layer folds on 0 of 2^20 inputs, k applications cost k; k = 3, 4 general jobs closing on the box. Record `docs/analysis/attack-pass/f2-mixer.md` | PASS (effort-bounded; k = 3, 4 lines pending) |
| F3 | Chained cache j+1 bound and storage-vs-recompute curve | no derivation under j+1 blocks; curve monotone; f=1 point unchanged | 0 of 64 and 0 of 1,024 lines under j+1 (exhaustive closure search, cross-checked by exhaustive pebbling at 10 lines, 10,240 pairs, 0 mismatches); both planted broken chains fire; curve monotone at both op counts; f=1 point 9,360 ops per item unchanged. Record `docs/analysis/attack-pass/f3-cache.md` | PASS |
| F4 | Weak-day census over 2^24 day keys | fraction of days with gain over 1.1x under 2^-20 | PASS against M2 (DSP-bound datapath): 0 of 2^28 days over 1.1x; planted weak days fire; every ROT and RC class 0. Bound finding AP-F4-1 on M1 (LUT adders): 5,476 of 2^24 days (3.26e-4) over 1.1x as the tail of a sum, no weak class; worst public-calendar day 29,337 at 1.121x, at most 12.1% more rate that day for a per-day LUT FPGA, 0 for any chip; redraw rule (NAF sum under 163 rejected) routed to the next class. Record `docs/analysis/attack-pass/f4-weakday.md` | PASS (v4); AP-F4-1 routed to the next class |
| F5 | Chip-model sweep + AWS F2 FPGA hour | evidence row 17 holds across the sweep; FPGA row under 27 M reads/s/W | sweep: 2.1x at k=1 GDDR7 reproduces, 3.2x at k=0.5, 4.1x at k=0.3 (matches ledger M32); FPGA row 2.3 to 2.9 G/s, 10 to 20 M reads/s/W (literature). FINDING: the k=0.33 figure is framed as the X9's measured core (M32) and a "measured class" (ladder branch §5a); the X9 was withdrawn before launch and never benchmarked. F2 hour SKIPPED: no AWS account | FIXED-AND-PASSED (sweep PASS; AP-F5-1 fixed and re-gated 7 Oct 2026: chip section re-run 2.1x at k=1 unchanged, identity grep 0 hits, site lane concurred); F2 hour SKIPPED-BY-DECISION (the project lead, 7 Oct 2026, 09:5x UK; plan 4.2 row F5 is the sweep only at 3714c2a0; the FPGA row stays the JEDEC-ceiling model row labelled unmeasured) |
| F6 | Verifier worst case over 10^5 programs + O-1.14 laptop run | worst program under 10 ms cold on the half-core proxy and the laptop | O-1.14 CLOSED on an i7-9700K (v4 6.006 ms avg, 6.334 cold max; dr736 10.04 fails as it must). Box search: 100,000 programs drawn and ranked, 50,000 timed cold on the one-core proxy (min / median / p99 / max 4.610 / 4.948 / 5.606 / 6.194 ms, `attack-f6/48484`); half-core re-times of the worst (batches B and C) queued, starved of the exclusive hold by back-to-back shared holders (F2's runner now stopped to free it); carried at the genesis ratio the worst would read 10.3 ms, at the additive cost 9.66 ms, so batch C decides | INCOMPLETE (batch C decides; re-armed) |
| F7 | Era-draw bias harness + 2^20 era-seed census | no re-roll inside the publish window; no era class with gain over 1.1x over 2^-20 | (b) census PASS at 2^24 seeds: no class over 1.1x, stride bijective on all draws, R, pos and M uniform (chi-square 38.5 on 30 dof), op-weight corners 1.0x, planted cases fire; (c) 64-bit day-key seeding PASS as the spec intends, 0 collisions in 2^17; (a) re-roll harness INCOMPLETE by the plan's allowance: the node's era seed is a plain chain block hash (`seed_below`), the cut is grindable with one block of hash at no delay (1 of 6 epochs) and immune past one block interval (0 of 6), and the 1-hour VDF of spec 4.4 is not in the node; the era-VDF lane builds it with `reroll.mjs` as its gate. Record `docs/analysis/attack-pass/f7-era.md`; the harness's three devnet-980 nodes stopped by pid at 12:1x UK | PASS (b, c); INCOMPLETE (a) pending the era VDF, a freeze precondition |
| F8 | Uniformity censuses (line-index 2^28, distinct lines, cross-hash histogram) | uniform within the window model of spec 1.13.1, layer 8; the excess beyond it within 6 sigma over 64 seeds; no hot set under 1% of items beyond the model | line index PASS at 2^28 (max +5.61 sigma, control +5.61). Phase E, 64 seeds at 2^18 nonces: 31 of 64 over 1.2x of the window model (median 1.17x, p90 2.70x, max 13.09x), 23 with a hot item, the lossy-source class across the stream. AP-F8-1 resolved to a mechanism: the window null gives 1.39x at the top 0.1% (not 4.05x); the rest is a lossy LOAD SOURCE (an `or` writer feeding site 15's load; the all-ones source is item 0xca5b92, 7 of 7 next-hottest predicted), a fault class in the acceptance rule's blind spot carried by 96.6% of v4 programs; hot-set bound at most 1.067x under rule (c); no v4 change, v5 generator item with phase E as its gate; phase E (64 seeds) pending | FINDING (mechanism ours; fix ships in 0.3.20 (the feature node) on `ca3-v4-amend`, re-gate by this lane's 64-seed census) |
| F9 | Acceptance edges (39) + header grinding on an RTX 5090 | zero passing programs with a hot set under 1%; grinding gain under 1% of rate | (c) grinding on the 5090 pod: +0.004% of rate at K = 2^14 (141.62 vs 141.61 MH/s, sd 0.003, 5 rounds) at 11.7 hashes of search per hash, ceiling +43%: PASS; (a) edges on generator 4 running in parts (21,007 agreeing so far); (b) hot-set search over 10^6 seeds running in parts (about half done) | (c) PASS; (a), (b) RUNNING on the box |
| F10 | Ladder signal monotonicity harness | no step without 90% over 7 windows in either direction | known-fail fails, known pass passes; new cases on the exact-share driver: 89% up holds (no step), 89 then 90% down with restarts steps only at 90% after the 7-window cool-down, the floor holds under 100% down (never below rung 0); decision per seed block memoised, identical after a restart, never differs between nodes; 19 of 19 checks per case. Two items to main, not findings: a stale commit string in the ladder lane's igneumd, and proof-synced nodes deciding rung 0 until the witness lands (a precondition line for spec 01). Record `docs/analysis/attack-pass/f10-ladder.md` | PASS |
## The rows
### F1. Shadow block compressibility and shortcut search (hash lane)
Method: over 10^4 class v4 programs, constant folding, dead-register elimination, common subexpressions across the
27 repetitions, linear sub-block detection, SAT equivalence on reduced blocks; the minimum op count per program
against N. Known-failed shape: a shadow that constant-folds or dedupes across its 27 identical passes so a chip
pays fewer than 55,296 shadow instructions per hash. Entry point: `igneum-pow show --program-class v4` prints the
256-instruction shadow (op mix add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12 on the
genesis seed). Gate: best compressed block within 5% of N on every program; no program over 10% compressible.
Result: RUNNING. What a failure moves: an acceptance-rule line for the shadow block (rule (c) runs the block),
packs re-cut.
### F2. Mixer round margin (hash lane, on the box)
Method: SAT or MILP differential and linear search on 1 to 4 keyed applications with drawn rotations; rotational-XOR
on the ARX layer; the fold of the multiply layer across applications checked algebraically. Known-failed shape: a
differential or linear trail or an algebraic fold that distinguishes or shortcuts more than 2 of the 8 applications
between dependent reads. Gate: no distinguisher or shortcut beyond 2 of the 8 applications. Result: RUNNING (prior
`ca2-mixer` evidence to be re-gated). What a failure moves: `mixer_mult` 16 or a shape change; verifier re-measured.
### F3. Chained cache j+1 bound and storage-vs-recompute curve (hash lane, on the box)
Method: exhaustive search on a 2^10-line model segment for a line derivable without an earlier line; the curve from
f = 1/64 to 1 in ops per item. Known-failed shape: a line (s, j) computable in fewer than j+1 block evaluations
without an earlier line (the MTP address-steering break shape). Gate: no derivation under j+1 blocks; curve monotone;
f=1 point unchanged. Result, 7 October 2026, 09:10 to 09:12 UK on the box (`docs/analysis/attack-pass/f3-cache.md`; logs
`/srv/builds/igneum-wt-attack/attack-f3/r1-*.log`): PASS on all three clauses. The chain extracted from
`Cache::fill_segment` (verified equal to the code on 16 of 16 key and segment pairs; `block == chacha_block` on
100,000 random inputs) has line j fed by line j - 1 only; the exhaustive closure search finds 0 of 64 and 0 of
1,024 lines under j + 1 (every line costs exactly j + 1), cross-checked by an exhaustive pebbling search at 10
lines (10,240 configuration and target pairs, 0 mismatches). The two planted chains fire: `skip2` (63 of 64 under
j + 1) and `nofeed` (every line in 1 block). The curve over stored cache lines is monotone non-increasing from
f = 1/64 to 1 at 608 (counted) and 700 (MEMHARD.md) ops per block; the f = 1 point is 9,360 ops per item,
41.7 MH/s at the 50 T op/s budget, unchanged. `ca2-cache` was the hot-table experiment, not a chain analysis, so
there was nothing to re-gate. Observation (coordinator and the F3 record, not a finding): `funding.md` B2 rank 2
prices the trade-off at the naive placement; the optimal placement of every 8th line costs 3.17 blocks per read,
not 3.5, and 16.0 at f = 1/64, not 31.5 (brute force over 4,426,165,368 sets at n = 8); the chip stays worse than
the full mirror at every f under 1, so the verdict stands, and a `chacha_block` shortcut in chaining mode stays
the paid question (Lot A and B). What a failure would have moved: the chain construction (a second feed-forward or
a cross-segment tie).
### F4. Weak-day census over 2^24 day keys (hash lane, on the box)
Method: 2^24 day keys through `MixParams::with_shape`; the ROT classes (all equal, complementary pairs, small
amounts), MUL low weight, RC structure, each per-day gain measured on the box verifier. Known-failed shape: a day
key whose drawn ROT/MUL/RC gives a fixed datapath a gain over 1.1x (the "weaker authorized parameters" class,
Kudelski 2019). Gate: the fraction of days with any gain over 1.1x under 2^-20. Result: RUNNING. What a failure
moves: a rejection-and-redraw rule on the draws.
### F5. Chip-model sweep and the FPGA hour (algorithm lane)
Method: `sim/horizon/algorithm/model.py` over k 0.2 to 1.5, tFAW 12 and 28 ns, HBM4 2.3 and 21.4 G reads per
stack, amortisation 1 to 3 years, electricity USD 0.05 to 0.15 per kWh; and the AWS F2 hour replacing the FPGA
ceiling row with a measurement. Known-failed shape: an input of the published model that, when corrected, lifts the
f=1 chip's per-joule edge over the 5090 above the published 2.1x at k=1.
Gate: the published sentence (evidence row 17) holds across the sweep; the FPGA row under 27 M reads/s/W.
Result (sweep): PASS on the numbers. The model's measured-anchor column (GDDR7, the 5090 reads 82% of its ceiling)
gives the f=1 chip's v4 per-joule edge over the RTX 5090 bench row as 4.1x / 3.2x / 2.1x / 1.5x at k = 0.3 / 0.5 /
1 / 1.5. At k = 1 the figure is 2.1x, and 3.9x at k about 0.33, which matches `fud-ledger.md` M32. The higher HBM3
and HBM4 columns rest on an 8-activate per 12 ns window that JEDEC HBM2 timings (4 per 28 ns) do not support; the
model already states GDDR7 is the column to quote. One wording gap: `evidence.md` row 17 says "brings it to about
2x", which is a floor that holds at k about 0.9 and above but understates the edge at lower k (3.2x at k = 0.5). The
accurate statement is M32's, 2.1x at k = 1 with the k range beside it. The sweep's numbers stand; the finding is the
X9 framing below.
FPGA row: the HBM2 FPGA ceiling is 2.3 to 2.9 G reads/s (measured Shuhai U280, FCCM 2020, equal to the JEDEC
tFAW-bound 2.3 G/s), 10 to 21 M reads/s/W at 115 to 150 W, 0.30 to 0.47x of the 5090 per watt. Under the 27 M
reads/s/W gate. The AWS F2 hour is SKIPPED-BY-DECISION (the project lead, 7 October 2026, 09:5x UK: not needed for now, not blocked;
plan 4.2 row F5 at commit 3714c2a0 on branch cryptanalysis is the chip-model sweep only, 4 h, the algorithm lane).
There is also no AWS account or `aws` CLI on this Mac. The FPGA row stays the JEDEC-ceiling model row labelled
unmeasured; Lot C prices it from the reads-in-flight model; the firm is told the F2 measurement was not run.
FINDING (X9 framing), owning lane algorithm and hash (the ladder lane is closed, so ours): the published numbers
already carry 2.1x at k = 1 beside 3.9x at k about 0.33 (`fud-ledger.md` M32, recalibrated under X35). The error is
the framing. M32 calls the k = 0.33 figure "the X9's core" and the `ladder` branch's `latency-ladder.md` section 5a
calls k about 0.33 a "measured class". Bitmain's Antminer X9 (RandomX ASIC, 1 MH/s, 2,472 W, about USD 5,600) was
announced and, per pcpraha.cz ("Antminer X9 canceled: Bitmain withdraws model from market before launch") and
r/MoneroMining, withdrawn before launch. Its implied core efficiency (k about 0.33) is a CLAIMED datasheet figure
from a design that never shipped and was never benchmarked, not a measured calibration point. It is carried as the
pessimistic bound, not a calibration. This collides with the merged ledger X34 ("RandomX has a shipping chip;
correct every sentence that said otherwise"): if the X9 was withdrawn, X34's correction is itself wrong and must be
reversed. Confirmed from primary sources (coordinator, 7 October 2026): pre-orders opened 26 December 2025 (shipments
scheduled for July 2026), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent
benchmark, Bitmain never published a cancellation (its shop lists it as sold out), and the box was commodity Sophgo
SG2044 server SoCs with an AES accelerator and 60-plus DRAM sticks, no tapeout; its claimed edge about 2x per joule
over a tuned Zen 4 part, about 3x over a stock desktop CPU. Re-cut applied the same day: `evidence.md` row 17 (claim
and measured cells) and `fud-ledger.md` M32's answer paragraph on attack-pass, and the ladder design doc section 5a
on branch `attack-ladder-5a` from the ladder tip 7003f9f5 (the `ladder` branch is checked out by another lane, so
the fix rides its own branch for the ladder owner to take). The served-text rows (X34 reversal, X36) belong to the
site lane, which confirmed the wording agrees. What a finding moves
(plan 4.2 F5): the sentence re-cut before the freeze so the firms attack the corrected model. The re-cut, once the
fact is confirmed: k about 0.33 labelled a claimed pessimistic bound from a withdrawn design everywhere it appears;
2.1x at k = 1 on the GDDR7 measured anchor kept as the headline with the k range beside it; k itself unmeasured
until Lot C produces it. This row reads FIXED-AND-PASSED only after the re-cut and its re-gate.
Economic row the withdrawal implies: a recompute chip at a 3x fixed-function factor against a CPU and GPU fleet
must recover its NRE (low to mid seven figures at a modern node, `chip-model-v3.md`) and carry a fork threat (a
class change at 95% miner signal can redraw the datapath the chip bakes in). The X9 at 2.47 J per KH against a
RandomX CPU fleet did not clear that bar at Monero's hash and price; the same arithmetic against Igneum's class v4,
with the shadow block and the automatic era draw as extra firmware risk, is why the chip model's verdict is a
deliverable and not a courtesy (plan 2.3). The confirmed reading: a box with a 2x to 3x per-joule edge and no NRE (commodity SoCs) was withdrawn rather than
face a 1.5x re-tune of RandomX, so the tapeout economics of a 3x chip against Igneum are worse than the X9's. This
row is the pessimistic case, not a measured gain.
### F6. Verifier worst case (algorithm lane)
Method: 10^5 class v4 programs timed on the box one-core and half-core proxies for the slowest warp (base program
and shadow block), plus the O-1.14 laptop run (the Windows `igneum-pow` build on the box, the relay, `bench
--warps 50`). Known-failed shape: a drawn program whose verifier warp exceeds 10 ms cold (the acceptance rule bounds
the miner's side, not the verifier's; `dr736` already FAILs at 10.51 ms cold one-core, but it is not the shipping
class). Gate: the worst program under 10 ms cold on the half-core proxy and on the laptop.
O-1.14 route (coordinator, 7 October 2026, 10:1x UK): no US laptop is due, so the laptop run is replaced by a
rented 2019-class CPU host through the fleet agent, capped at two hours of rent; the Linux `igneum-pow` from the box
(the same binary as the proxies) runs `bench --warps 50` for v2, mx8, mx8+sh256x27, dr368 and dr736 (the
known-fail) on it; INCOMPLETE with the numbers so far if the cap lands first. The Windows exe was also built on the
box for the day a laptop appears (1,009,675 bytes, sha256 fbed7538...e6c9). Outcome, 09:40 UK: no 2019-class CPU
host stood up. Vast accepted and dropped five CPU-class rents within 30 s each (i7-9700K, i5-8500, Xeon W-2133 and
W-2123) under the account's automatic new-account spend limit (support ticket open since 6 October), and RunPod has
no 2019-class CPU pod; so O-1.14 reads INCOMPLETE on the box proxies today and stays a precondition of the freeze.
Next try: the US laptop when it registers on the relay (the exe is ready), or Vast once the spend limit lifts; the
bench script is staged and runs in minutes. Correction, 10:4x UK (fleet agent): the provider dropped nothing; every
rent stood up and ran, hidden by Vast's instance listing cap of 25 rows on an account holding 38, so the hosts sat
idle and were destroyed. The fallback is re-rented under the same word (i7-9700K class, two-hour cap from its start,
read by id); the result replaces this line when it lands.
O-1.14 RESULT, 7 October 2026, 09:49 UK, Vast instance 54613164, Intel Core i7-9700K (2019 desktop core, Coffee Lake,
read at 4,170 MHz during the run, 31 GB DDR4, Ubuntu 24.04), the box-built Linux `igneum-pow` (sha256 6d286783...),
`bench --seed igneum-genesis --day 2026-10-03 --warps 50` on one core (`taskset -c 1`), the host otherwise idle; log
`docs/analysis/attack-pass/o114-i7-9700K-2026-10-07.log`:
| Class | Cold max (ms per warp) | Average of 50 (ms) | Gate 10 ms | Box one-core cold | Box half-core |
|---|---|---|---|---|---|
| v2 | 1.582 | 1.280 | pass | 1.30 | n/a |
| mx8 (class v3) | 5.394 | 5.267 | pass | 4.67 | 7.56 |
| mx8+sh256x27 (class v4, the target) | 6.334 | 6.006 | pass, 3.7 ms of headroom | 5.06 | 8.23 |
| dr368 | 5.540 | 5.426 | pass | 5.32 | 8.16 |
| dr736 (the known-fail) | 10.290 | 10.042 | FAIL, as it must | 10.51 | 15.49 |
Cache fill 276 ms on the 9700K core (box 361 ms, M5 Max 175 to 181 ms). The 2019 desktop core sits between the box's
two proxies as the arithmetic predicted (1.2x the box one-core cold on v4, 0.77x the half-core); the known-fail
fires on it. A 2019 laptop core at 3.5 GHz reads about 15 to 20 percent slower than this desktop part (approximate,
clock ratio), so about 7.0 to 7.6 ms on v4, still under 10 ms. Consequences: a 2019-class node verifying class v4
spends 0.6 percent of one core at 1 bps and 6 percent at 10 bps; a header flood needs about 160 invalid headers a
second to saturate one such core; a pool verifies about 160 shares a second per core; IBD of 108,000 headers is
about 11 minutes of one core. The implied ladder ceiling on this core: the shadow costs 0.74 ms per 55,296
instructions (v4 minus mx8), so the 4.0 ms of headroom buys about 300,000 more shadow instructions, N about 650,000
counted ops at the 1.83 convention (approximate), against 370,000 on the half-core proxy and 1,060,000 on the
2.5x rule; the half-core proxy stays the standing pessimistic rule and the ladder's ceiling should be taken from
it, not from this desktop part. O-1.14 is CLOSED on a real 2019-class core for the genesis program; the F6 row
still owes the 10^5-program worst case before it reads PASS.
Result (average, verified on the box): class v4 `mx8+sh256x27` runs 4.90 to 5.06 ms per warp cold on one EPYC
9454P core (nice 19, taskset), 8.23 ms on the half-core proxy (both SMT siblings busy). Under 10 ms. Status
RUNNING: the 10^5-program worst-case search and the O-1.14 laptop relay run are owed before the row reads PASS.
What a failure moves: an acceptance-rule bound on verifier cost; the ladder's ceiling set from the measured core.
### F7. Era-draw bias harness and census (node lane harness, hash lane census)
Method: the fast-time 3-node network (`infra/fast-time/`) with an adversary withholding or publishing the last blue
block before C_era(n) to re-roll the draw; a census of 2^20 era seeds for stride, ROT and weight-perturbation
classes with gain over 1.1x; the 64-bit seeding of the day-key stream against the spec's intent. Known-failed shape:
a re-roll of the era draw inside the 2 s publish window, or an era class (stride bijection, all-equal ROT, low-weight
M) with a chip gain. Gate: no re-roll inside the publish window; no era class with gain over 1.1x at a fraction over
2^-20; the draw's input set as the spec states it.
Result (full record `docs/analysis/attack-pass/f7-era.md`; harness `tools/attack/f7-era/`). Census: 2^20 and 2^24 era
seeds through `generator::era_draw` over `V3_ALLOWED` (the chain's path), classified; the planted known-fail/known-pass
of the classifier fired and the sound draw raised nothing. No era class with gain over 1.1x at any fraction (the richest
is M = 1 at 1.0034x, absent in 2^24; every class over 2^-20 is 1.0000x to 1.0007x); the stride is a bijection on every
sample (0 even M), R and pos and the M bits uniform; the op-weight corners (15 to 31 of 75) are 1.0x against the GPU, 0
memory effect. The 64-bit day-key seeding is the spec's intent (spec 1.8.4); 2^16 days are all distinct, birthday 2^-33.
Harness: the 3-node fast-time network (`reroll.mjs`, ports 29800+, suffix 980) with an adversary holding the last block
before the cut; known-pass (`--vdf-ms 0`) fires at 1 of 6 cuts (seed = adversary block), known-fail (`--vdf-ms 5000`)
is silent at 0 of 6, both SOUND. The node has no era VDF yet (`seed_below` is a plain block hash, era-layout.md section
8), so the harness cannot show the real 2 s-window gate; the era draw's grinding resistance rests on the 1-hour VDF of
spec 4.4 (re-roll needs a 1,800x evaluator, spec 4.6 gives 300x; forge needs 20 days of 100% hash). Verdict: census PASS,
64-bit seeding PASS, harness INCOMPLETE with the written argument. Logs on igneum-build-1
`/srv/builds/igneum-wt-attack/attack-f7/census-2p24.log`, `census-2p20.log`, `reroll-knownpass.log`, `reroll-knownfail.log`.
What a failure moves: the draw procedure or the C_era cut rule; a redraw rule for the era stream.
### F8. Uniformity censuses (hash lane, on the box)
Method: the line-index distribution over 2^28 derivations; distinct lines per hash and per warp on 10^6 nonces of
three programs; the cross-hash item histogram of one epoch. Gate: the largest bucket within 6 sigma of uniform; no
hot set under 1% of items. Result: RUNNING. What a failure moves: the mask or the fold; packs re-cut.
### F9. Acceptance edges and header grinding (hash lane; one PC 2 job)
Method: the 39 edge disagreements reproduced and bounded; a search over 10^6 seeds for programs that pass rule (c)
with a hot set under 1%; the header-grinding search cost against its DRAM-locality gain measured on PC 2's RTX 5090
(one job through `tools/build-job.mjs`). Known-failed shape: a seed grind that steers a program to a hot cache set
for DRAM locality, or an edge where the closed-form stand-in disagrees with the live verifier in the attacker's
favour. Gate: zero passing programs with a hot set under 1%; the grinding gain under 1% of rate at any search cost.
Result: the `accept` path reproduces per-seed verdicts (genesis seed: 1 candidate ACCEPTED, bias max 54, 0
saturated). The header-grinding cost-versus-gain measurement needs a 5090. Status BLOCKED on the go decision: use
PC 2's 5090 through a relay run job only if PC 2 is online and mining is unaffected, else a rented pod under the
standing fleet budget. What a failure moves: the closed-form stand-in replaced by the live verdict at the edges; a
locality term in rule (c).
### F10. Ladder signal monotonicity (node lane)
Method: the fast-time harness with a weight that steps the ladder down and never up, and an 89% signal; the step
rule's monotonicity and its memoisation per seed block. Known-failed shape: a chip owner stepping the ladder down
(cheaper N) without the 90% threshold, or a step registered under 90%. Gate: no step without 90% over 7 windows in
either direction; a step down needs the same. Result: RUNNING. What a failure moves: the step rule's text in spec 01
before the ladder is frozen.
## Operating hazards found by the pass
AP-H1 (box scratch cleaned by builds; found by F3, 7 October 2026, 10:0x UK). `infra/build-server/remote-run.sh`
line 71 runs `git clean -qfd -e target -e 'target-*' ...` on `/srv/builds/<worktree>` before every remote build, so
an untracked box scratch directory of one row (a venv, a log dir, a crate's `tools/attack/*/target`) is deleted by
the next build from any row. F3 protected its own directory through the box mirror's `.git/info/exclude`; the lane
then added `attack-*/`, `target-attack-*/`, `tools/attack/` and `.build-remote.log` to that file at 10:1x UK, after
which `git clean -fdn` on the mirror lists nothing (the clean has no `-x`, so the exclude file applies). The class
check is owed to the build-server lane: the clean line should spare a lane's declared scratch prefix (`-e 'attack-*'`
style, or read a per-worktree exclude list), and a CI check should fail a remote-run.sh whose clean line lacks it.
OPEN until that check lands (CLAUDE.md: a rule row closes only with its check).
## Ledger rows
AP-F1-1 (hash lane; ruling asked). At 10^5 class v4 programs one program (`attack-f1/37341`) compresses by 5.078
percent (13 of 256 shadow instructions per pass), 0.078 points over the gate's first clause, on 1 of 100,000; every
other program is within 5 percent and none over 10. The saving is the same local shape as on every program (a
register written twice from one source with no write between), nothing crosses a pass, and clang -O3 removes the
same instructions from the honest kernel (IR counts match the harness on the worst programs), so a chip gains nothing
relative to a card: no shortcut. The gate as written counts honest-compiler simplification as compressibility. Two
ways to close: re-word gate (1) and row F1 to "compressible beyond the honest compiler's own simplification" (the
firms then attack chip-relative compression, which is the question), or a shadow-draw redundancy bound in the next
class (reject a shadow with over 12 peephole-removable instructions per pass, rejection about 1e-5; class v4 is on
the live vote). Ruling (coordinator, 7 October 2026, 12:3x UK): both. Gate (1) and row F1 re-worded to "no
compression of the shadow block beyond the honest compiler's simplification, measured against that compiler on the
same program" (sent to the cryptanalysis lane for the plan and the firms' brief), under which the 5.078 percent
letter miss at honest-compiler parity is a PASS; and a shadow redundancy bound on the v5 generator's list beside
AP-F4-1 and AP-F8-1 (the generator refuses a shadow block whose honest-compiler simplification exceeds a stated
fraction; the v5 lane sets the fraction from F1's census), gated by F1's harness on 64 seeds of the v5 stream.
Status: F1 PASS; AP-F1-1 FIXED-AND-PASSED against v5 once the bound is in the v5 generator and F1's census passes.
AP-F5-1 (algorithm and hash lane, ours; the ladder lane is closed). The k about 0.33 chip-efficiency figure is
framed as a measured calibration ("the X9's core", `fud-ledger.md` M32 L172; "measured class", `ladder` branch
`docs/design/latency-ladder.md` section 5a). The Antminer X9 was withdrawn before launch and never benchmarked, so
k about 0.33 is a claimed datasheet bound, not a measurement. This also puts the merged ledger X34 ("RandomX has a
shipping chip") in question. Fix owed, held until the coordinator's research agent confirms the withdrawal and the
no-benchmark fact: relabel k about 0.33 as a claimed pessimistic bound from a withdrawn design in `evidence.md` row
17, `fud-ledger.md` M32 and the `ladder` branch; reverse X34 if the withdrawal is confirmed; keep 2.1x at k = 1 on
the GDDR7 measured anchor as the headline with the k range beside it. Re-gate after the re-cut. Status: FIXED on the docs rows (evidence 17, M32, ladder 5a on branch attack-ladder-5a d3cb17b6; attack-pass
rebased on master a3678789 after X36); FIXED-AND-PASSED once the site lane's X34/X36 served rows are confirmed in
one voice (no objection received) and the sweep is re-run against the re-cut sentence (the numbers are unchanged, so
the re-gate is the identity check and one `model.py --section chip` run against the new wording). Re-gate done 7 October 2026, 09:5x UK: the 5090
bench row still reads 5.7x / 4.1x / 3.2x / 2.1x / 1.5x (v3; v4 at k = 0.3 / 0.5 / 1 / 1.5), identity grep 0 hits
over 290 export files, the site lane confirmed the served text agrees. AP-F5-1: FIXED-AND-PASSED.
AP-F8-1 (hash lane; the generator fix is the Counter ASIC lane's on the v4 seam, routed 7 October 2026, 10:3x UK).
The class v4 item read map is not uniform. F8 phase D, one program, 2^26 nonces: the top 0.1 percent of items take
0.520 percent of reads against 0.115 percent for the uniform control (4.05x); the top 1 percent take 2.49 percent
(1.37x); one item (0xca5b92) takes 78,479 reads, 153x the mean; read site 15 feeds 6.37 percent of its reads into
that 0.1 percent in all 8 iterations; the excess grows with N as a real skew does. Sized: a chip caching the hot
0.1 percent in SRAM serves about 0.5 percent of reads from cache, so the shortcut is under one percent of rate today;
an auditor flags a non-uniform read map in a design that claims uniform random reads, and site 15's index derivation
is the cause to name. Fix asked: per-site index whitening or a rejected class above a bound. Re-gate: the top
0.1 percent within 1.2x of the control over 2^26 nonces on every one of 64 seeds, with F8's harness against the
Counter ASIC lane's branch. Phase E (the 64-program census) decides whether it is one program or the class.
Framing from the Counter ASIC lane (the generator's owner, 7 October 2026, 10:5x UK): class v4's item map is not
designed to be uniform per program. Layer 8 (spec 01 section 1.13.1) gives each load site k_off = below(3), so a
site reads the whole dataset, a half or a quarter under the era's stride and interleave; a quarter-window site
concentrates 4x on its quarter by design, which is the 4.05x at the top 0.1 percent, and the windows exist so a
chip's SRAM mirror must hold the whole dataset every hour (the Counter ASIC 2.0 windows-union census). The right
control is therefore the window model from the program's own 16 draws, reported beside the uniform control (what an
auditor sees first); the number that must be explained is the single item 0xca5b92 at 153x the mean (window
coincidence under the era mapping with a stated tail, or a low-entropy index source at site 15, which would be a
fault). The lane reproduces with F8's harness on branch `ca3-v4-uniform`, waits for phase E, re-prices the chip
consequence (a 0.1 percent hot-set cache, about 1.7 MB of SRAM, serving 0.5 percent of reads: under one percent of
rate) and changes the generator only on a fault beyond the model, since v4 is on the live devnet's vote. F8 was
re-briefed to carry both controls and the per-site table. Raised to the coordinator: plan 1.4 gate (4) and row F8
say "within 6 sigma of uniform"; if the design is windowed, the gate text must say "uniform within the window model
of spec 1.13.1" before the freeze tag, or every reviewer files the windows as a finding on day one.
Coordinator's ruling (7 October 2026, 11:0x UK), accepted: the right null is the window model derived from the
program's own draws; F8 is re-gated against it, and the finding stays open only for the excess beyond the window
model (the 153x item, or a low-entropy source at site 15 if the 64-seed census shows one). No generator change to
class v4 is allowed: it is on the live devnet's vote, and a class change before the flip splits the chain. If the
census shows a real fault it goes to the coordinator priced; otherwise the record carries the documented null and
the hot-set bound (a 0.1 percent cache, about 1.7 MB of SRAM, under one percent of rate) goes into the next class.
Gate wording settled (coordinator, 11:2x UK): plan 1.4 gate (4) and row F8 now read "uniform within the window
model of spec 1.13.1, layer 8; the excess beyond it within 6 sigma over 64 seeds", carried into the plan's scope
text by the cryptanalysis lane so the firms are briefed on the windows before they start.
Mechanism (hash lane, branch `ca3-v4-uniform` 095f84a7, `docs/analysis/ca3-v4-uniform.md`, harness
`tools/ca3-v4-uniform`, 7 October 2026, 12:3x UK): the windows-union null (a Poisson mixture at 416 / 288 / 736 / 608
reads per item by quarter from the program's 16 draws) moves the top 0.1 percent from 0.115 to 0.160 percent, 1.39x,
not 4.05x; every per-site row of F8's attribution except site 15 is the window model. The rest is the LOAD SOURCE:
site 15 is the load at 63 reading r6, whose last writer is `or` at 61 (r6 = r6 | r4), so the source is all-ones with
probability about (3/4)^32 per read; under the era map x = 0xffffffff is item 0xca5b92, the hottest item exactly, and
the next seven hottest are the seven one-zero-bit sources whose zero survives the window mask (7 of 7); the measured
count fixes the bias at p = 0.7585 per bit. The class: a load whose source's last writer is lossy (or: 0.30 percent
of a site's reads on 0.1 percent of values; mul, trailing zeros: 1.07; mulhi: 0.79; an or of an or: about 4.5).
Static census of 1,024 chain-shaped v4 programs: 96.6 percent carry a lossy-sourced load (48.5 percent or, 4.9
percent an or chain, 73 percent mul, 64 percent mulhi); predicted S_0.1 median 0.45, 90th 0.88, 99th 5.3, max 9.8
percent; p1 / p2 / p3 predicted 0.58 / 0.32 / 4.72 against measured 0.52 / 0.27 / 4.60. The fault sits in the
acceptance rule's blind spot: part (a) takes any write as fresh, part (c) counts saturation on final values only.
Consequence: the 1.2x-against-window gate fails 96.6 percent of today's programs, so it is withdrawn as a v4 gate and
becomes the v5 generator item's gate (draw a load's source from registers whose last writer injects; a dynamic check
counting saturated load sources), with F8's phase E as its test. Chip side: the top 0.1 percent of items is 1.07 MB
of SRAM (0.53 mm^2, about USD 0.25) serving 0.52 percent of p1's reads and 4.6 percent of p3's, at most 1.005x and
1.048x in rate; the ceiling under rule (c)'s 120-of-128 floor is one site repeating its item in all 8 iterations,
6.25 percent of reads, 1.067x. That 1.067x is the v4 hot-set bound the record carries. No generator change to v4;
the hash lane takes the two flip options priced to main.
Ruling (the project lead, 7 October 2026, 15:2x UK): option A, the class v4 amendment ships in 0.3.20, the feature node (0.3.19 is the app-only cut on the unchanged 0.3.17 node pin; corrected by the coordinator) (a load's source drawn
only from registers whose last writer injects or is a rotate, the v5 rule applied now; a new program stream and
seven re-exported packs on branch `ca3-v4-amend`, the hash lane), with limited testing. This lane's part is the proof
of the fix: F8's hot-set census at 2^24 nonces on each of 64 seeds of the amended stream, on the box's CPU path as
phase D ran, gate: the top 0.1 percent of items within 1.2x of the window model derived from each program's own 16
window draws, one number per seed; reported to the hash lane, main and the Counter ASIC lane. The amended stream has
no lossy-sourced load by construction, so a seed over 1.2x there is a finding against the model's own tail, not the
fault, and the record says which.
Status: FINDING-OPEN: mechanism found and ours; FIXED-AND-PASSED on the 64-seed verdict against `ca3-v4-amend`.
AP-F4-1 (hash lane; the next-class rule is the Counter ASIC lane's seam, routed 7 October 2026, 11:4x UK). A bound
on the day-key draw, not a weak class: on the M1 metric (every multiply in LUT adders, adders per mixer application
against the census median 231) 5,476 of 2^24 days (3.26e-4) and 87,426 of 2^28 (3.26e-4) gain over 1.1x, the tail
of a sum the exact convolution predicts to 0.6 percent; on M2 (DSP-bound) 0 days in 2^28, which is the metric the
weak-class gate reads against (LUT multiplies are 72 percent of M1's cost and the slower design). Worst day in 2^24:
chain day 4,819,563 (NAF sum 149, cost 197, 1.173x); worst in the public calendar: chain day 29,337 (23.6 years in,
NAF sum 158, cost 206, 1.121x, M2 1.000x), reproduced through `igneum-pow export` (memhard.h equal to the harness).
Priced: at most 12.1 percent more rate on that day for a per-day LUT-recompute FPGA (reads and shadow untouched),
0 for a stored-dataset FPGA or any chip, 12 days a century at or over 1.1x (0.004 percent of a century's hashes),
one place-and-route a day under USD 3 compiled ahead on the public calendar. Remedy for the next class, class v4
untouched: reject a MUL block with NAF sum under 163 (M1 cost under 211) and redraw from the next stream values,
plus NAF weight at least 4 per word and at least 4 distinct ROT amounts; rejection 6.1e-4 per day; first calendar
redraw day 22,633; no pack changes. Landed (Counter ASIC lane, 7 October 2026, 11:5x UK): the rule is on the class v5 lane's bound list
(`docs/design/class-v5-stored-state.md` section 11) with F4's harness as its gate, re-gated by this lane against the
v5 branch once its `accept.rs` carries it. The brief's rank 3 (funding.md B2, the untested all-equal ROT draw of
MEMHARD.md) now reads "a bounded tail, measured", with the F4 record as the source.
Status: F4 PASS against v4; AP-F4-1 FIXED-AND-PASSED against v5 once the lane's accept.rs carries the rule and the
census passes against it.
Any further finding is logged here and in `docs/fud-ledger.md` with its owning lane (hash and algorithm: fixed in
`igneum-pow` behind a test and re-gated; node: the node lane, relay agent) before the row is marked FIXED-AND-PASSED.