575 lines
61 KiB
Markdown
575 lines
61 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; the era VDF (F7 sub-row a) landed in the node on
|
|
7 October 2026 with the re-roll harness silent against it (0 of 6 cuts), so that precondition is met. 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; three applications: no differential trail at or below weight 29 to 35 and no linear at or below 24 to 28, four: 39 to 47 and 24, every job at its 7,200 s cap. Record `docs/analysis/attack-pass/f2-mixer.md` | PASS (effort-bounded) |
|
|
| 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 | 100,000 programs ranked, 50,000 timed cold one-core (worst 6.194 ms), the worst 200 re-timed and the worst 1,000 timed on the half-core proxy under the per-core lease (core 40 at 3,799.9 MHz): worst 8.708 ms (`attack-f6/87142`), 1.29 ms under the gate, every half-core reading under 9 ms; dr736 fails as it must (15.49). O-1.14 CLOSED on an i7-9700K (v4 6.334 ms cold max, dr736 10.04 fails). Ladder ceiling from the worst program on the half-core proxy: N about 300,000, so rung 2 admissible, rung 3 not. Record `docs/analysis/attack-pass/f6-verifier.md` | PASS |
|
|
| 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, R, pos and M uniform, planted cases fire); (c) 64-bit day-key seeding PASS (0 collisions in 2^17); (a) PASS with the era VDF in the node (era-vdf lane, fork era-vdf-node 394a5902 on release-0.3.20-node c4459193, behind era_vdf_activation_daa; master a4eaf766 carries the spec text, `docs/analysis/era-vdf-2026-10-07.md` and `tools/era-vdf/reroll.mjs`): against the real era cut on three fast-time nodes the re-roll harness fires with the VDF off (6 of 6 cuts) and is silent with it on (0 of 6; the adversary's 5.4 to 6.6 s evaluation against a 1 s block interval, the honest chain 3 to 10 blocks ahead, three nodes agreeing on every era seed); the delay is 517 s on the fastest prover measured (chiavdf NUDUPL over GMP, 208.8K squarings/s) at T = 108,000,000, 259x the 2 s window. Open, not a gate: the verify is 22 ms against the 10 ms target (O-4.6, 0.3.22). Record `docs/analysis/attack-pass/f7-era.md` | PASS (a, b, c) |
|
|
| 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. Phase E (6 Oct stream): 31 of 64 seeds over 1.2x, the lossy load-source class, AP-F8-1. Re-gate on sub-version 1 (8c728ca3, 0.3.20): 11 of 64 over 1.2x, worst 29.27x (p31), a constant delivered through an admitted writer or across the iteration boundary; three residual classes named; sub-version 2 (freshness fixpoint + dynamic source count) is the fix. F9's harness retired from the re-gate (counts the windows) | FINDING; sub-version 1 FAILS 11 of 64, sub-version 2 FAILS 9 of 64 (worst 4.82x; one low-entropy site per program, lineage-blind, the acceptance never ran the shadow: AP-F8-3); AP-F8-2 exhaustion FIXED-AND-PASSED at 8bdcbdd8; sub-version 3 is the target |
|
|
| 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 | (a) edges on generator 4 over 10^5 seeds: 34 disagreements in 105,064 candidates (29 const_bit, 4 bias, 1 lane_const), every one a one-bit or sampling-noise property moving the choice to an attempt both stand-ins accept, nothing in the attacker's favour: PASS; (b) hot-set search over 10^6 seeds: 11,696 passing programs (1.17%) concentrate 1% or more of reads on a hot set, worst 17.3%: FINDING, the same or-saturation load-source class as AP-F8-1 found by a second harness (F9-1 merged into AP-F8-1), re-gated on the amended stream; (c) grinding on the 5090: +0.004% at K = 2^14, ceiling +43%: PASS. Record `docs/analysis/attack-pass/f9-grind.md` | (a) PASS; (b) FINDING = AP-F8-1 class (10^6 seeds on the 6 Oct stream); the harness is retired from the re-gate (its metric counts the era's windows), F8's census re-gates; (c) PASS |
|
|
| 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.
|
|
|
|
Sub-row (a) CLOSED, 7 October 2026, 15:1x UK (the era-VDF lane, launched by the coordinator on this row's INCOMPLETE):
|
|
the era VDF is in the node (fork `era-vdf-node` 394a5902 on `release-0.3.20-node` c4459193, behind
|
|
`era_vdf_activation_daa`, never on any network until the project lead sets it per network; repo master a4eaf766 carries the spec
|
|
text, the record `docs/analysis/era-vdf-2026-10-07.md` and the harness `tools/era-vdf/reroll.mjs`, which attacks the
|
|
era cut directly now that the node takes `pow_era_blocks` and `pow_era_lead` from the override file). Against the
|
|
REAL era cut (era 120 DAA, lead 20 on the fast-time file, three nodes on igneum-build-2) the harness fires with the
|
|
VDF off (6 of 6 cuts: the adversary's block is the cut block and its hash the seed, known the instant it is built) and
|
|
is silent with it on (0 of 6 across six cuts: the adversary's 5.4 to 6.6 s evaluation with the node's own code against
|
|
a 1 s block interval, the honest chain 3 to 10 blocks ahead when it published, three nodes agreeing on every era seed,
|
|
the record ready at every era start). SOUND both ways. The production delay: 517 s on the fastest prover measured
|
|
(chiavdf NUDUPL over GMP, 208.8K squarings/s on the same core) at T = 108,000,000 squarings, 259x the 2 s window.
|
|
Freeze sentence (the era-VDF lane's, carried to the plan's owner): "The era seed E_n is the output of a one-hour
|
|
verifiable delay (class-group Wesolowski, 1,024-bit prime discriminant, T 108,000,000, scheme byte 0 with the
|
|
hash-chain fallback as byte 1) over the blue blocks of the day ending at the era's cut block; the attack pass's F7
|
|
re-roll harness fires against the stand-in and is silent against the delay, so the era draw procedure and the C_era
|
|
cut rule are frozen with the VDF in the node, behind era_vdf_activation_daa, never until set per network." Open, not
|
|
a gate of F7: the verify is 22 ms with the group held, against the 10 ms target (once per 180 days per importing
|
|
node; O-4.6's reducer or GMP behind a feature, 0.3.22). Logs `/srv/builds/igneum-wt-era-vdf/ev-harness-out/
|
|
reroll-vdf-{on,off}-5.json` on build-2. F7: PASS on all three sub-rows.
|
|
|
|
### 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).
|
|
|
|
AP-H2 (this lane's own, 7 October 2026, 13:3x and 14:5x UK, twice). Two census runs launched from the same crate's
|
|
`target/release` binary path on the box mirror: a rebuild of the crate at a new commit replaces the binary under a
|
|
run still in progress, and every chunk the run launches after that executes the new commit's code with the old run's
|
|
label (the 07a809a7 control's later chunks ran 8bdcbdd8; the ddacfbd3 class check's later chunks ran 017e7037). Both
|
|
runs were caught by their attempt histograms (attempts 32 and 35 under a cap of 32) and their contaminated chunks
|
|
discarded. Fix in the lane's launcher: `run-census-chain.sh` copies the binary into the run's own scratch directory
|
|
before the first chunk and runs from the copy, so a rebuild cannot reach a run in progress; a run's record names the
|
|
sha256 of the copy. Class check owed: the same rule for every lane's long run (the box's build runner could refuse to
|
|
replace a binary that a running process has open, or stamp the commit into the run's log at every chunk).
|
|
|
|
## 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.
|
|
The fraction is 3.0 percent (v5 lane, class-v5 45e29cb0; 384 of 100,000 draws redrawn in its census, 3.8e-3, against
|
|
F1's histogram where the 3.0 to 5.5 percent bins hold 397 of 100,000); the plan's 1.1 sentence carries the number.
|
|
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.
|
|
Second harness (F9 sub-row b, 10^6 seeds, 12:5x UK): the same class from the other side, the per-site address trace:
|
|
11,696 of 1,000,000 passing programs concentrate 1 percent or more of their reads on a hot set (worst 17.3 percent,
|
|
seed 842871, an `or`-written load source all-ones in 36 percent of evaluations), so F9-1 merges into AP-F8-1 and
|
|
F9's harness is the second re-gate of the amendment, run on the amended stream beside F8's 64-seed census.
|
|
Re-gate interim (7 October 2026, 13:2x to 13:5x UK, box 2): F8's 64-seed census at 2^24 nonces against the amended
|
|
stream (igneum-pow 8c728ca3, sub-version 1; pairing verified, the harness draws the devnet epoch-0 program as
|
|
1a4230699a6b9c60) at 30 of 64 seeds shows nine over 1.2x of the window model (p31 29.27x, p11 5.45x, p19 3.32x, p6
|
|
3.11x, p23 2.04x, p4 1.57x, p10 1.50x, p26 1.30x, p25 1.28x), p6's hottest item predicted from "site 13, r0,
|
|
all-ones, last writer a load at 12": a load-after-load chain (a hot address yields a fixed dataset word, which is the
|
|
next load's address), which the source rule admits because a load injects. Rule-level reading, checkable in code:
|
|
generator.rs line 1326 sets `entropy_kept[dst]` true for a rotate whatever it rotated, so an or-saturated register
|
|
rotated once is an admitted source and the rotate preserves the saturation. RETRACTION: F9's hot-set census run on
|
|
box 2 against the 8c728ca3 build (10^6 seeds, 1,871 flagged, worst 9.66 percent) was not a re-gate: the F9 harness
|
|
draws through `candidate_class` with its own era class, not through `chain_program` where the rule lives, and the
|
|
amended and the old binary print the identical program for seed igneum-f9/518927; those numbers describe the old
|
|
stream under a changed evaluation and are withdrawn; the harness is being given a `chain_program` draw mode so it can
|
|
serve as the second re-gate. The hash lane confirmed the reading (14:0x UK): the amendment's rule is keyed on the
|
|
era-composed class, so a draw with no era (F9's path) is the old stream, and on the chain path the residual is real:
|
|
p6's load at 12 had a saturated source itself, read one constant word and left a constant in r0, which the rule
|
|
counts as injecting; a rotate keeps 0xffffffff, so or-then-rotate-then-load passes too. Both are saturation delivered
|
|
through a writer that preserves it. Fix shape put to the owner of sub-version 2 (the Counter ASIC lane): dataflow
|
|
freshness instead of a one-writer look-back (fresh at the start; a load keeps dst fresh only if its source was fresh;
|
|
add, sub, xor, mad, shfl fresh if either operand was; rotl, rotr only if the operand was; or, mul, mulhi never; a
|
|
load's source drawn only from fresh registers), with the dynamic (c') check on load sources as the backstop; a stream
|
|
change, so sub-version 2 with new packs, ids and fingerprints.
|
|
RE-GATE VERDICT on sub-version 1 (7 October 2026, census ended 12:55:55 UTC, 13:55 UK; box 2; igneum-pow 8c728ca3
|
|
paired with release-0.3.20-node 8097d600, pairing id 1a4230699a6b9c60 verified; 64 seeds p2 to p65 at 2^24 nonces,
|
|
chain path, window-model control; log `/srv/builds/igneum-wt-attack-regate/attack-f8-regate/log/`): FAIL the pass
|
|
line. 53 of 64 seeds under 1.2x of the window model (0.9915x to 1.16x, no predicted source); 11 over:
|
|
|
|
| Seed | Over the window model | Over flat | Hottest item, reads of 2^31 | Predicted source |
|
|
|---|---|---|---|---|
|
|
| p31 | 29.27x | 31.99x | 0x74e2b8, 5,365,527 | site 4, r4, all-ones, last writer rotl at 3 |
|
|
| p11 | 5.45x | 6.00x | 0x0eec66, 31,486 | site 1, r7, all-ones, last writer or at 63 (the previous iteration) |
|
|
| p45 | 4.55x | 6.37x | 0x400000, 5,644 | site 1, r4, zero, last writer mulhi at 59 |
|
|
| p19 | 3.32x | 3.93x | 0x400000, 28,114 | site 37, r5, zero, last writer load at 32 |
|
|
| p6 | 3.11x | | 0x3bf40d, 13,792 | site 13, r0, all-ones, last writer load at 12 |
|
|
| p23 | 2.04x | 2.85x | 0x09dd36, 13,848 | site 16, r7, all-ones, last writer load at 14 |
|
|
| p4 | 1.57x | 2.11x | 353 reads | none (window tail) |
|
|
| p34 | 1.51x | 1.87x | 0x400000, 1,547 | site 23, r6, zero, last writer rotr at 12 |
|
|
| p10 | 1.50x | 1.65x | 353 reads | none (window tail) |
|
|
| p26 | 1.30x | 1.54x | 0x000000, 7,637 | site 10, r1, zero, last writer rotl at 2 |
|
|
| p25 | 1.28x | 1.65x | 363 reads | none (window tail) |
|
|
|
|
Three residual classes, each a constant (all-ones or zero) delivered to a load through a writer the rule admits:
|
|
(1) saturation or zero preserved through rotl, rotr, load or mad; (2) zero made by mulhi; (3) the iteration
|
|
boundary, where the rule's writer state starts fresh at instruction 0 so an or at 63 feeds a load at 1. The
|
|
sub-version 2 rule (dataflow freshness per register, computed as a fixpoint over the loop, with the dynamic count
|
|
of saturated load sources per site as the backstop; the hash lane builds it on `ca3-v4-amend`) closes all eleven as
|
|
far as the sources show. Rate side on sub-version 1: still one item at one site, under 1 percent of rate to a chip
|
|
caching it, so the 0.3.20 ship is safe on rate; the auditor's flag is what sub-version 2 removes. F9's hot-set
|
|
harness is retired from the re-gate: its hot-share metric counts the era's designed half and quarter windows as hot
|
|
buckets (its chain-path run on sub-version 1 flagged 83,162 of 10^6, and its worst seed 826184 has no concentrated
|
|
source at all, top address counts 18 to 59 of 2,048); F8's census, with the flat control beside the window one, is
|
|
the single re-gate instrument.
|
|
Sub-version 2 (07a809a7, the stream identical at 8bdcbdd8 for every seed accepting within 32), the same 64 seeds at
|
|
2^24, 13:10 to 14:2x UTC: at 39 of 64 seeds, 8 over 1.2x of the window model, worst p23 4.82x. Three are the window
|
|
model's tail (p4 1.22x, p8 1.38x, p10 1.50x, no predicted source); five are constants the freshness rule cannot see
|
|
because it tracks lineage, not value: p23 (0x000000, 41,727 reads, zero from xor of a register with itself at
|
|
instruction 0), p34 1.25x (sub of a register with itself), p15 2.57x (zero through rotl at 0), p18 2.50x and p19
|
|
3.32x (a load whose address is constant delivers one word to the next load; p19 is byte for byte the sub-version 1
|
|
program). (c') cannot catch them: 164 of 16,384 per site is about fifty times coarser than the gate (p23's item is
|
|
0.002 percent of all reads and still 4.8x at the top 0.1 percent). Fix shape sent to the hash lane: forbid
|
|
self-operands for xor, sub and mad in the draw; a dynamic per-site bound on the most repeated source value (any
|
|
value) set from the gate; a load's dst fresh only if its source passes it. Rate side unchanged (one item at one
|
|
site, nothing to a chip); the auditor's uniformity test is what fails.
|
|
Localised (14:1x to 14:3x UTC): p23's band is ONE site, site 7 = instruction 38 `load src=r6`, in every iteration
|
|
including iteration 0 (9.5 percent of that position's reads on the top 0.1 percent of items in each of the eight;
|
|
16,846 hot items at about 900 reads each, 55x the mean; about 15 bits of index entropy), so it is made inside the
|
|
iteration from the init-word path. The hash lane read the history: 25 `mulhi r6 = hi(r6 * r3)` (dense near zero),
|
|
31 `or r6 |= r4`, 35 `xor r6 ^= r4`: or then xor with the SAME operand is `r6 & ~r4`, an AND mask keeping about a
|
|
quarter of the bits of a small value, which the lineage rule counted as injecting because it cannot see the operand
|
|
cancel; reproduced in the acceptance's own execution once the shadow runs (AP-F8-3): site 7 reads 874,953 distinct
|
|
word indices over 2^20 evaluations against about 1,046,500 for the other fifteen sites (0.84 of uniform, 2.2 s) and
|
|
0.55 at 2^24 (35 s). Neither dataset- nor nonce-dependent: a rule reaches it. Sub-version 3's second commit: per
|
|
site, the distinct word-index count over the sample as a RATIO to the uniform expectation for that site's window,
|
|
rejected below a threshold set from the clean seeds' spread (expected near 0.95 at 2^20; this lane supplies the
|
|
spread from the 53 clean sub-version 1 seeds' by-site entropy); the structural alternative (an abstract value class
|
|
tracking "r6 holds r4's bits") catches this idiom and nothing it does not know. Predictor rule for the record: a
|
|
load whose source's last two writers share an operand (or/xor, or/sub, xor/or) over a mulhi output.
|
|
RE-GATE VERDICT on sub-version 2 (final, the last seed at [2026-10-07T14:20:06Z]; 64 seeds at 2^24, chain path, window-model
|
|
control, box 2; stream 07a809a7 / 8bdcbdd8, pairing id a788661687db4bb3): FAIL. 55 of 64 under 1.2x (0.9915x to
|
|
1.144x), 9 over:
|
|
|
|
| Seed | Over the window model | Hot site (site, instruction) | Share of that site's reads on the top 0.1 percent | Bucket entropy of uniform | Predicted source |
|
|
|---|---|---|---|---|---|
|
|
| p23 | 4.82x | 7, 38 | 9.43 percent | 0.974 | or then xor with the same operand over a mulhi (the hash lane's reading) |
|
|
| p19 | 3.32x | 15, 62 | 6.64 percent | 0.964 | zero through a load (unchanged from sub-version 1) |
|
|
| p15 | 2.57x | 2, 12 | 4.49 percent | 0.982 | zero through rotl at 0 |
|
|
| p18 | 2.50x | 6, 30 | 5.55 percent | 0.937 | all-ones through a load |
|
|
| p56 | 2.01x | 2, 10 | 3.34 percent | 0.994 | unattributed (new over sub-version 1) |
|
|
| p10 | 1.50x | 8, 28 | 2.04 percent | 0.979 | unattributed (identical to sub-version 1) |
|
|
| p8 | 1.38x | 14, 51 | 1.42 percent | 0.980 | unattributed |
|
|
| p34 | 1.25x | 1, 13 | 1.35 percent | 0.997 | one-bit value through sub |
|
|
| p4 | 1.22x | 1, 8 | 1.45 percent | 0.981 | unattributed (1.57x on sub-version 1) |
|
|
|
|
Every failing seed is one low-entropy load site. Clean-seed spread of the per-site bucket entropy (848 site rows of
|
|
sub-version 1's 53 clean seeds): min 0.9865, p1 0.9961, p5 0.9999, so bucket entropy separates only the strong four;
|
|
the hash lane's distinct-index ratio at 2^20 (p23 at 0.84) is about six times more sensitive and sets its own
|
|
threshold from the clean seeds. Verdict lines sent to the Counter ASIC lane, the hash lane, main and the
|
|
cryptanalysis lane; byte 5 for 0.3.21 stands on this evidence.
|
|
Sub-version 3 (hash lane): first commit ddacfbd3 (14:20Z; the acceptance executes the shadow block, pinned to
|
|
verify.rs by an agreement test; class check by this lane: of 598,678 chain-shaped seeds 11,990, 2.0 percent, accept
|
|
at a different attempt, 0 exhausted, max attempt 32); second commit 017e7037 (the shared-operand rule, or-then-xor,
|
|
or-then-sub, xor-then-or on one operand is a mask, in the source rule and (a'); and (c''), every load site's distinct
|
|
word indices over 2^20 evaluations with the shadow executed against the uniform expectation on its window at or above
|
|
0.98, the last test of the chosen candidate). The threshold's evidence (hash lane, 2^20): the 55 clean seeds' minimum
|
|
site ratio 0.9960, p1 0.9990, median 1.0000; the strong five p23 0.8361, p18 0.9274, p19 0.9335, p15 0.9432, p56
|
|
0.9654; floor 0.98 sits 0.015 from each side. At 2^24 the weak four (p34 0.9181, p4 0.9614, p8 0.9630, p10 0.9612)
|
|
share their value with two clean seeds (p44 0.9612, p52 0.9613), so the 2^24 stage is not taken and p4, p8, p10 and
|
|
p34 stay the open tail, unattributed. The ratio refuses about 4 percent of candidates that pass every other test
|
|
(4,099-program census at 017e7037: mean attempts 2.086 against 1.998, max 17, 0 lossy-sourced load sites of 65,584,
|
|
0 exhaustions; suite 103 of 103; devnet epoch-0 at attempt 1, id a785001687d8688a, pairing verified by this lane).
|
|
Status: FINDING-OPEN; sub-version 1 FAILS the re-gate (11 of 64); sub-version 2 FAILS it (9 of 64, worst 4.82x);
|
|
FIXED-AND-PASSED on the 64-seed verdict against sub-version 3 (the acceptance executing the shadow block, the
|
|
per-site distinct-index ratio rule, the cap and the last resort).
|
|
|
|
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.
|
|
|
|
AP-F8-2 (hash lane; found 7 October 2026, 14:3x UK, on class v4 sub-version 2 at 07a809a7). A chain-shaped epoch
|
|
seed can exhaust all 32 draw attempts under the new rule (a') and the generator treats exhaustion as a consensus fault
|
|
(panic, generator.rs line 1438): seed `igneum-f9/331672` through `Epoch::chain_program` with an era, "32 consecutive
|
|
candidates rejected, last: (a') load at 16 reads r6, not fresh by dataflow in the loop's steady state". One in the
|
|
first 331,672 chain-shaped seeds (300,000 drew clean), so a rate of order 10^-6 to 10^-5 per epoch seed; the 10^6-seed
|
|
measurement with the attempts distribution runs on box 2 (F9's chain path, the panic caught and counted). Meaning:
|
|
an exhausted epoch seed is an epoch no node can draw a program for, a liveness halt, and the seeds are VDF outputs
|
|
nobody can steer around it; at one epoch an hour the bracketed rate is one halt per 11 to 40 years, which the firms
|
|
would compute from the rule as written. Sub-version 1: 0 exhausted in 10^6 chain-shaped seeds. Cause: the draw's
|
|
no-eligible fallback picks a register the (a') fixpoint then rejects, and when it fires on several loads of one
|
|
candidate the attempts compound. Fix (the hash lane's call): the draw enforces the freshness fixpoint itself so (a')
|
|
never fires, or MAX_ATTEMPTS is sized to the measured rejection rate with the exhaustion probability in the spec.
|
|
Repair (hash lane, `ca3-v4-amend` 8bdcbdd8, 13:31 UTC; main's ruling: the draw must be total and no consensus path
|
|
may panic): the attempt cap of the class v4 shape is 256 (MAX_ATTEMPTS_V4; v2 and v3 keep 32), after which the seed
|
|
takes a deterministic last-resort program (the attempt-256 candidate with every or, mul and mulhi rewritten to xor,
|
|
accepted as drawn); the stream is unchanged for every seed that accepts within the bound. Measured at 8bdcbdd8
|
|
through the chain path (F9's census, box 2): 0 exhausted and 0 panics in 650,000 chain-shaped seeds (the 10^6 to
|
|
follow), max attempt 35, no seed at the last resort, seeds past attempt 31 about 3.2e-6 (5 in 1.55 million draws,
|
|
inside the (2/3)^32 = 2.3e-6 estimate), per-attempt rejection 0.67 (attempt histogram 232,235 / 155,322 / 103,509 /
|
|
68,858 / ...), mean about 2 attempts per seed; seed 331672 accepts at attempt 32. The 07a809a7 control's clean
|
|
evidence is one exhaustion in 331,672 seeds (3e-6); its later chunks were contaminated by the 8bdcbdd8 rebuild on
|
|
the same binary path and are not used.
|
|
Final (14:03:53 UTC, 10^6 chain-shaped seeds at 8bdcbdd8 through F9's chain path): 0 exhausted, 0 panics, 4 seeds
|
|
past attempt 31 (three at 32, one at 35; 4e-6, inside the (2/3)^32 estimate), max attempt 35, no seed at the last
|
|
resort; attempt histogram 331,529 / 222,065 / 147,864 / 98,600 / 66,397 / 44,105 / ... / 1 at 31 / 3 at 32 / 1 at 35,
|
|
a per-attempt rejection of 0.67 and a mean of 2.0 attempts per seed. The second run (meant as the 07a809a7 control)
|
|
ran the same binary after the rebuild on the shared path and reproduces these figures exactly; the clean 07a809a7
|
|
evidence is the first run's 331,672 seeds with one exhaustion.
|
|
Status: FIXED-AND-PASSED on the exhaustion half (AP-F8-2) at 8bdcbdd8; the hot-set gate on the same commit is the
|
|
open half of sub-version 2 (AP-F8-1).
|
|
|
|
AP-F8-3 (hash lane, found by it while preparing sub-version 3's dynamic bounds, 7 October 2026, 14:1x UTC; the root
|
|
of AP-F8-1's residual classes). `accept.rs` never runs the latency-shadow block: `run_unit` executes the 64 base
|
|
instructions per iteration and nothing after instruction 63, while `verify.rs` and every kernel run the shadow 27
|
|
times at the end of each iteration. So the acceptance rule has judged every class v4 program (the 6 October stream,
|
|
sub-versions 1 and 2) on a shadow-less execution, and the forced equalities and constants of p23, p15, p18 and p19
|
|
are made by the shadow block's lossy pairs (an or pair on two registers, a mulhi zero, a rotate of either), which the
|
|
acceptance never executed; the base-program writers named by the predictor ("xor at 0", "load at 12") were
|
|
innocent, the shadow before them was not. Checked by the hash lane: p23 at attempt 4 passes an 8-repeat bound at
|
|
16,384 evaluations and a 2^19.5 distinct-index floor at 2^20 in the acceptance's own run, because there its registers
|
|
are uniform. Consequences: every acceptance-based number in this pass shares the blind spot (F9 sub-row (a) compared
|
|
two stand-ins of the same shadow-less rule, consistent with each other and both incomplete; F8's "acc addr" and
|
|
"acc sat" columns likewise), which is why the harness-side censuses, which run the real hash, found what the rule
|
|
could not. Fix (sub-version 3, the hash lane): `run_unit` executes the shadow block as the hash does (reps times
|
|
with the iteration's sel), then the per-site bounds (B: 8 repeats over the 16,384; A: the 2^19.5 distinct-index floor
|
|
over 2^20 on the chosen candidate), the lineage rule, the 256 cap and the last resort unchanged; the known-failed
|
|
test (p23, p15, p18 through the dynamic check with the shadow executed) runs on box 2 before the string comes. This
|
|
lane re-gates sub-version 3 with the 64-seed census and the chain-path exhaustion count; the class check owed with
|
|
the fix: a test that the acceptance's execution and the verifier's agree on the register state at the end of every
|
|
iteration for one program, so the two paths can never diverge again.
|
|
Status: FINDING-OPEN; closes with sub-version 3's re-gate.
|
|
|
|
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.
|