CRACK Solution
Substitution Box
CRACK affine substitution (multiply + mask)

Prerequisites
Unlocks
SUBST88
Techniqueaffine substitution (multiply + mask)
Rulenonzero
SampleSUBST88
Walkthrough
Recover the accepted input below, then submit it to the CRACK verifier.
Reject Samples
- SUBST89
- subst88
- SUBST8
- SUBST888
- BOXMAP1
Verifier Listing
; z2_affine_sub: affine (multiply-mask) substitution cipher, per position.
; Each input byte is multiplied by 0x4D (77) and the low 8 bits are kept; the
; product is compared to a stored target at each of 7 positions. Because 77 is
; odd it has a modular inverse mod 256 (77 * 133 = 1 mod 256), so the map is a
; true reversible substitution: c = (target * 133) mod 256. Inverting the seven
; targets recovers SUBST88. r0 = 1 on accept; rule: nonzero.
;
; Maps cleanly to the 8-bit core: mul already wraps mod 256, which IS the
; "multiply and keep the low byte" the original did with mul + uxtb.
; Targets 0xF7 0x91 0xDA 0xF7 0x44 0xD8 0xD8 = (c * 0x4D) & 0xFF of "SUBST88".
len r2
cmp r2, 7
jnz bad
mov r7, 0
loop: cmp r7, 7
jge ok
ldb r0, [r7]
mul r0, 0x4D ; multiply by 77, low byte kept (mul wraps mod 256)
cmp r7, 0
jz t0
cmp r7, 1
jz t1
cmp r7, 2
jz t2
cmp r7, 3
jz t3
cmp r7, 4
jz t4
cmp r7, 5
jz t5
mov r1, 0xD8 ; position 6
jmp chk
t0: mov r1, 0xF7
jmp chk
t1: mov r1, 0x91
jmp chk
t2: mov r1, 0xDA
jmp chk
t3: mov r1, 0xF7
jmp chk
t4: mov r1, 0x44
jmp chk
t5: mov r1, 0xD8
chk: cmp r0, r1
jnz bad
inc r7
jmp loop
ok: mov r0, 1
ret
bad: mov r0, 0
ret