adv-mixer-3 report: header, status board, first rows (Q1 k=1..3 uniform, Q2 k=1, Q2b k=1, Q4 k=1..4 inside the band, SAT k=1 bound)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
8c830edaea
commit
0c3e4cb59c
1 changed files with 138 additions and 0 deletions
138
docs/analysis/cryptanalysis/report-mixer-3.md
Normal file
138
docs/analysis/cryptanalysis/report-mixer-3.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# Report: the statistical distinguisher and the round margin of M_r
|
||||
|
||||
Internal adversarial pass, not an independent review. Every sentence here that could be quoted in public carries
|
||||
that label. Lane adv-mixer-3, branch adv-mixer-3. First results 7 October 2026, 20:0x BST; rows are appended as
|
||||
they land.
|
||||
|
||||
## Header
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Target commit | 017e70376489251e18564c0abce7e466e606c8b3 (class v4 sub-version 3, object byte 7) |
|
||||
| Target | the mixer M_r (spec 01 section 1.8.4), class v4 (`V4_CLASS` = `MX8`): 72 applications per item, 8 between dependent cache reads |
|
||||
| Base commit | build/master 7a7caa34, merged 04c4d9bc; `git diff --quiet 017e7037 HEAD -- igneum-pow && echo IDENTICAL` prints IDENTICAL |
|
||||
| Harness | tools/attack/adv-mixer-3 (igneum-pow by path); binary sha256 bdd8432f6181bcc9e77885cf840c83e2a6ffe5ae027182a1d9181710bbb06e70 (commands index, sac, diff, lin, lin0, rx, cnf), identical on both boxes; v2 8153dbafa4540c796ae5a76e31258dbb1323724465aa4709d9cecd050dea5c40 adds sac0 |
|
||||
| SAT solver | CaDiCaL 3.0.1, built from the GitHub source into ~/adv-mixer-3-tools on each box (user directory, nothing system-wide) |
|
||||
| Boxes | igneum-build-1 (queue 01, 03, 05, 09) and igneum-build-2 (queue 02, 04, 06, 08), nice 10, cores 8 to 95, 64 threads per sweep; the boxes ran at load 160 to 460 on 96 cores throughout, so every wall time here is a loaded-box time |
|
||||
| Logs | /srv/builds/_adv-mixer-3/logs/ on each box (outside the worktree mirror); copies under docs/analysis/cryptanalysis/logs/adv-mixer-3/ on this branch |
|
||||
| Days | 20729 (genesis, 3 October 2026), 20733 (Devnet 3 epoch 0), plus 8 fixed day indices in queue 07 |
|
||||
| Band | 6 sigma at the sample count of each row; a cell beyond it is a distinguisher, a cell inside it is invisible to that row |
|
||||
|
||||
Plant rule: a tool is trusted once it has fired on a known-failed shape. Which shape fired is in each row.
|
||||
|
||||
## Status board
|
||||
|
||||
| Q | Method | Known-failed shape | Gate | Result (numbers) | Status |
|
||||
|---|---|---|---|---|---|
|
||||
| Q1 | exhaustive round-0 line-index census, all 2^32 t, k = 0..8 | k = 0 (the init: one bin holds 2^32, fired on both days) | chi-square z within 6, no empty bin | day 20729: uniform at k = 1 (z -1.13), 2 (z -0.68), 3 (z -0.39); later k below | RUNNING |
|
||||
| Q2 | single-bit avalanche, random states, 2^24 (and 2^27) states | `one` at k = 8 (fired: 1959 holes); `weak` fires at k = 1 only, not at k = 8 (see Q2) | no cell beyond 6 sigma | k = 1: 354 holes, 129,726 cells beyond 6 sigma, worst p = 1.000 | RUNNING |
|
||||
| Q2b | t-bit avalanche on the round-0 input (32 bits in), 2^24 (and 2^28) states | k = 0 (the init alone, fired: 12,439 holes) | no cell beyond 6 sigma | k = 1: 0 holes, 218 cells beyond 6 sigma, worst p = 0.7427 (t bit 31 to state bit 53), 18 line-index cells beyond 6 sigma | RUNNING |
|
||||
| Q3 | differential multiplicity, 576 low-weight input differences, 2^20 pairs each | `nomul` at k = 1 (fired: 17,289 deterministic output bits at 4,096 pairs) | no multiplicity 4 or more, no deterministic bit | pending the k = 1..4 rows | RUNNING |
|
||||
| Q4 | single-bit linear correlations, random states, 2^26 samples | k = 0 (the identity, fired: c = 1.0 on the diagonal) | no cell beyond 6 sigma (band 0.00073) | k = 1: worst c = -0.00056 (z -4.61); k = 2: 0.00058; k = 3: 0.00056; k = 4: -0.00056: all inside the band | PASS to k = 4 (BOUND), RUNNING to k = 8 |
|
||||
| Q4b | t-bit linear correlations on the round-0 input, 2^26 samples | k = 0 | no cell beyond 6 sigma | pending | RUNNING |
|
||||
| Q5 | rotational-XOR, rotations 1, 8, 16, 2^22 samples | `weak0` at k = 1 | no zero-difference word above 2 of N, no repeated difference above 3 | pending | RUNNING |
|
||||
| Q6 | SAT (CaDiCaL) on the round-0 input: find t with a given 22-bit index after k applications | k = 1 solved and verified | solve inside one hour per k, time against the honest 2^10 x k x 130 ops | k = 1: SATISFIABLE in 137 s wall (loaded box); model t = 0x49880000 verifies to the target 0x20eb79. Honest: 2^10 trials of one application is under a millisecond. The solver is already slower than brute force at k = 1 | PASS at k = 1 (BOUND); k = 2..4 RUNNING |
|
||||
| Q7 | days: 20733 on every row, 8 fixed day indices on Q1 and Q2 | as above | as above | day 20733 rows land below | RUNNING |
|
||||
| GPU | any GPU row | n/a | n/a | no GPU on either box | BLOCKED |
|
||||
|
||||
The round margin so far (internal adversarial pass, not an independent review): every single-bit statistic that
|
||||
reaches beyond k = 1 is listed with its k in the rows below. Where the table says "pending" the row is not yet in.
|
||||
|
||||
## Q1: the round-0 line-index census (exhaustive)
|
||||
|
||||
The input to round 0 is 8 fixed words K and 8 words affine in one 32-bit t, so the first line index is a map of
|
||||
32 bits to 22 bits and can be censused over its whole domain. For k applications with keys round_key(0..k-1):
|
||||
|
||||
Command (build-1), per k: `adv-mixer-3 index --day 20729 --apps k --threads 64`. Logs: index-20729-k<k>.log.
|
||||
|
||||
| Day | k | chi-square z (df 2^22 - 1) | empty bins | min | max | segment z | line z | s[0] bit balance worst z | verdict |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| 20729 | 0 | 6.2e12 | 4194303 | 0 | 2^32 | 7.8e11 | 2.4e10 | n/a | NON-UNIFORM (the plant: one bin) |
|
||||
| 20729 | 1 | -1.13 | 0 | 871 | 1191 | -2.00 | -0.26 | pending | uniform within the band |
|
||||
| 20729 | 2 | -0.68 | 0 | 874 | 1191 | 0.56 | -0.14 | pending | uniform |
|
||||
| 20729 | 3 | -0.39 | 0 | 853 | 1187 | -0.03 | -1.15 | pending | uniform |
|
||||
|
||||
Reading: after one application the 2^32 round-0 inputs already spread over the 2^22 lines as a uniform draw
|
||||
would (Poisson 1024 per bin: min 871, max 1191 are the expected extremes over 4 million bins). The multiply layer
|
||||
on the 8 affine words and one double round are enough for the line index as a histogram. This is a histogram
|
||||
test, not an independence test: Q2b measures whether individual t bits still leak into individual index bits.
|
||||
|
||||
## Q2: single-bit avalanche on random states (the regime of rounds 1 to 8)
|
||||
|
||||
Command (build-1), per k: `adv-mixer-3 sac --day 20729 --apps k --start 8 --states 2^24 --threads 64`.
|
||||
Keys round_key(8..8+k-1) (round 1's keys). Logs: sac-20729-k<k>.log.
|
||||
|
||||
Plants: `--plant one --apps 8` (one application in place of eight) fired with 1,959 holes and 89,129 cells
|
||||
beyond 6 sigma at 65,536 states. `--plant weak --apps 8` (MUL 1, RC 0, ROT 16) did NOT fire at k = 8: 0 holes,
|
||||
worst z 4.88. Eight double rounds of a constant-free ARX permutation on random 512-bit inputs diffuse fully, so
|
||||
"weak" is a known-failed shape at k = 1 only (a sibling's census fired it there; this lane's 4,096-state smoke
|
||||
run at k = 1 fired it too: 14,364 holes). The `one` plant is the firing check of this row.
|
||||
|
||||
| Day | k | states | holes | cells beyond 6 sigma | worst cell | worst p | line-index cells beyond 6 sigma (of 11,264) | verdict |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| 20729 | 1 | 2^24 | 354 | 129,726 | in 279 (word 8) to out 64 (word 2) | 1.0000 | 7,930 | DISTINGUISHED |
|
||||
|
||||
## Q2b: t-bit avalanche on the round-0 input
|
||||
|
||||
Command (build-1), per k: `adv-mixer-3 sac0 --day 20729 --apps k --states 2^24 --threads 64` (v2 binary).
|
||||
Logs: sac0-20729-k<k>.log. Plant k = 0 (the init alone) fired: 12,439 holes of 16,384 cells.
|
||||
|
||||
| Day | k | states | holes | cells beyond 6 sigma (of 16,384) | worst cell | worst p | line-index cells beyond 6 sigma (of 704) | verdict |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| 20729 | 1 | 2^24 | 0 | 218 | t bit 31 to state bit 53 (word 1) | 0.7427 | 18 | DISTINGUISHED |
|
||||
|
||||
## Q3: differential multiplicity
|
||||
|
||||
Command (build-1), per k: `adv-mixer-3 diff --day 20729 --apps k --start 8 --samples 2^20 --threads 64`.
|
||||
|
||||
Rows land here.
|
||||
|
||||
## Q4: single-bit linear correlations
|
||||
|
||||
Command (build-1), per k: `adv-mixer-3 lin --day 20729 --apps k --start 8 --samples 2^26 --threads 64`.
|
||||
Band: 6 sigma = 0.00073. Plant k = 0 fired (c = 1.0 on the 512 diagonal cells).
|
||||
|
||||
| Day | k | samples | worst c | worst z | cells beyond 6 sigma (of 262,144) | line-index worst z | output balance worst z | verdict |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| 20729 | 1 | 2^26 | -0.00056 | -4.61 | 0 | -3.72 | 3.82 | inside the band |
|
||||
| 20729 | 2 | 2^26 | 0.00058 | 4.73 | 0 | 4.09 | 3.47 | inside |
|
||||
| 20729 | 3 | 2^26 | 0.00056 | 4.61 | 0 | -3.95 | 3.17 | inside |
|
||||
| 20729 | 4 | 2^26 | -0.00056 | -4.61 | 0 | 4.18 | 3.08 | inside |
|
||||
|
||||
Reading: a single input bit and a single output bit have no measurable linear correlation after one application
|
||||
on random states. The worst z of 4.6 to 4.7 over 262,144 cells is what 262,144 draws of a standard normal give
|
||||
(expected maximum about 4.8). This is the single-bit mask family only; multi-bit masks are owed work.
|
||||
|
||||
## Q6: SAT on the round-0 input
|
||||
|
||||
Command (build-1, smoke run): `adv-mixer-3 cnf --day 20729 --apps 1 --t0 0x12345678 --out k1.cnf` then
|
||||
`cadical -q k1.cnf`. CNF: 33,873 variables, 112,328 clauses (Tseitin: t is 32 variables; each constant multiply
|
||||
is a shift-add chain of 32-bit ripple adders over the set bits of MUL; each quarter round four adders; rotations
|
||||
are wires; constants are folded). Result: `s SATISFIABLE`, 137.06 s wall on the loaded box; the model gives
|
||||
t = 0x49880000; `adv-mixer-3 verify --day 20729 --apps 1 --t 0x49880000` prints index 0x20eb79, the target.
|
||||
|
||||
Honest cost of the same task: about 2^10 random t each through one application, under 2^18 integer operations,
|
||||
under a millisecond on one core. The solver at k = 1 is five orders slower than the honest search. The queue 08
|
||||
rows (k = 1..4, both days, one-hour cap) land below.
|
||||
|
||||
## Box-hours
|
||||
|
||||
Rule changes during the pass (so the hours stay honest): 19:4x BST the build-server lane dropped the SIGSTOP
|
||||
yield-to-builds rule and set every sweep to nice 10 on cores 8 to 95; the same lane moved every log, pid file and
|
||||
CNF out of the worktree mirror into /srv/builds/_adv-mixer-3/. Both applied before the first sweep started.
|
||||
|
||||
| Step | Box | Start (UTC) | Wall | Note |
|
||||
|---|---|---|---|---|
|
||||
| Build harness (two builds, one fix) | build-1 | 18:36 | 29 s | |
|
||||
| Build harness | build-2 | 18:44 | 14 s | |
|
||||
| CaDiCaL from source | build-1, build-2 | 18:42, 18:44 | about 1 min each | |
|
||||
| Smoke plants and k = 1 SAT | build-1 | 18:38 | 3 min | |
|
||||
| Queue 01, 03, 05 | build-1 | 18:42 | running | |
|
||||
| Queue 02, 04, 06, 08 | build-2 | 18:47 | running | |
|
||||
| Queue 09 (sac0) | build-1 | 18:50 | running | |
|
||||
|
||||
## What a longer pass would add
|
||||
|
||||
Multi-bit linear masks and a MILP trail bound; the SAT model on the full 512-bit state with a cache-line XOR
|
||||
between applications; 2^30 states on the k that sits at the band. None of these is a reason to wait on the
|
||||
numbers above.
|
||||
Loading…
Reference in a new issue