$ cat writeup.md…
$ cat writeup.md…
asisctf2026
Task: recover a ChaCha20Poly1305 key derived from five hidden 32x32 invertible matrices over GF(2), published only through 112 obfuscated matrix-subspace boxes. Solution: pair the special boxes by low-rank characteristic-polynomial invariants, solve simultaneous intertwiner equations on the two rank-25 elements, and rebuild the canonical key material to decrypt.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Provided archive:
linchan.txz
The archive extracts to linchan/linchan.py and linchan/output.txt. The goal is to recover the hidden matrices well enough to reproduce the challenge key derivation and decrypt the final ChaCha20Poly1305 ciphertext.
Reading linchan.py shows the real structure of the problem:
32x32 over GF(2)S are generatedC and its conjugate D = S C S^{-1}112 public boxesshake_256(b"linchan-v2/key\0" + sorted(_f(S_i))), where _f canonicalizes a matrix up to inverse and transposeThe important consequence is that I did not need to reconstruct full hidden subspaces. The useful signal was much smaller: among the 112 boxes, exactly 10 are special, and each of those contains exactly two nonzero combinations of rank 25.
Those special boxes pair as:
(1, 92)(32, 44)(47, 106)(49, 60)(82, 86)For a special box with the two rank-25 elements A and B, the tuple of invariants based on
charpoly(A)charpoly(B)charpoly(A + B)charpoly(AB)matches exactly with its true partner box. That gives the correct five pairings without recovering the whole subspace structure.
Once a true pair is known, recover the secret conjugator by solving the simultaneous intertwiner system over GF(2):
X A_i = B_i X
...
$ grep --similar