#!/usr/bin/env python3 """CodeShell.kr — Fold (Crypto, 100p) solver. Spec (fold-v1.txt): p is a permutation of [0..7]; for i=0..5: sum((i+1)*(j+1)*p[j] for j) % 257 == targets[i]; sha256(bytes(p)) confirms the permutation. stream = SHA256(b"FOLD/v1" || bytes(p) || byte(n))[:8] x = ciphertext block with bytes placed back from positions p[j] plaintext[j] = x[j] XOR stream[j] Usage: uv run python solvers/fold.py """
deffind_perm(): for p in itertools.permutations(range(8)): ifall( sum((i + 1) * (j + 1) * p[j] for j inrange(8)) % 257 == TARGETS[i] for i inrange(6) ): if hashlib.sha256(bytes(p)).hexdigest() == SHA: return p raise SystemExit("no permutation matched")
defdecrypt(p, ct): out = bytearray() for n inrange(len(ct) // 8): block = ct[n * 8:(n + 1) * 8] stream = hashlib.sha256(b"FOLD/v1" + bytes(p) + bytes([n])).digest()[:8] x = bytearray(8) for j inrange(8): x[j] = block[p[j]] # x[j] takes the byte at position p[j] out += bytes(a ^ b for a, b inzip(x, stream)) returnbytes(out)
defmain(): p = find_perm() print(f"perm={p} sha256-ok") pt = decrypt(p, CT) # strip PKCS#7 pad = pt[-1] assert1 <= pad <= 8and pt[-pad:] == bytes([pad]) * pad print(f"plaintext: {pt!r} -> {pt[:-pad].decode()}")