CRACK Solution
Keystream
CRACK LCG keystream XOR

Prerequisites
LF5RKEY
TechniqueLCG keystream XOR
Rulenonzero
SampleLF5RKEY
Walkthrough
Recover the accepted input below, then submit it to the CRACK verifier.
Reject Samples
- LF5RKEX
- KEYLF5R
- AAAAAAA
- LF5RKEYZ
Verifier Listing
; z3_keystream: "Keystream". Each byte is XOR'd with a different key, but the
; keys aren't stored: a tiny LCG generates them. k0 = 0x6B, and after each byte
; k = (k*5 + 0x1F) & 0xFF. The masked byte is compared to a stored target;
; recover the keystream and peel it off. Technique: LCG keystream XOR. This fits
; the 8-bit core exactly (the LCG already runs mod 256). r0 = 1 on accept.
; Accept rule: nonzero.
;
; keystream = 6B 5A AD 22 71 8A 39 ; targets = 27 70 18 52 54 FF 98 ; answer LF5RKEY.
;
; The seven targets are inline immediates (no key table to read); the keystream
; is regenerated in r4 by the LCG and XOR'd into each byte before the compare.
len r2
cmp r2, 7
jnz bad ; exactly 7 bytes
mov r4, 0x6B ; r4 = current key (LCG state, starts at the seed)
; position 0
mov r7, 0
ldb r0, [r7]
xor r0, r4
cmp r0, 0x27
jnz bad
mov r5, r4
shl r5, 2
add r5, r4
add r5, 0x1F
mov r4, r5 ; k = k*5 + 0x1F -> 0x5A
; position 1
inc r7
ldb r0, [r7]
xor r0, r4
cmp r0, 0x70
jnz bad
mov r5, r4
shl r5, 2
add r5, r4
add r5, 0x1F
mov r4, r5 ; -> 0xAD
; position 2
inc r7
ldb r0, [r7]
xor r0, r4
cmp r0, 0x18
jnz bad
mov r5, r4
shl r5, 2
add r5, r4
add r5, 0x1F
mov r4, r5 ; -> 0x22
; position 3
inc r7
ldb r0, [r7]
xor r0, r4
cmp r0, 0x52
jnz bad
mov r5, r4
shl r5, 2
add r5, r4
add r5, 0x1F
mov r4, r5 ; -> 0x71
; position 4
inc r7
ldb r0, [r7]
xor r0, r4
cmp r0, 0x54
jnz bad
mov r5, r4
shl r5, 2
add r5, r4
add r5, 0x1F
mov r4, r5 ; -> 0x8A
; position 5
inc r7
ldb r0, [r7]
xor r0, r4
cmp r0, 0xFF
jnz bad
mov r5, r4
shl r5, 2
add r5, r4
add r5, 0x1F
mov r4, r5 ; -> 0x39
; position 6 (last; no further LCG step needed)
inc r7
ldb r0, [r7]
xor r0, r4
cmp r0, 0x98
jnz bad
mov r0, 1
ret
bad: mov r0, 0
ret