CRACK Solution
Fletcher Gate
CRACK Fletcher-16 checksum

Prerequisites
Unlocks
FLETCH16
TechniqueFletcher-16 checksum
Rulenonzero
SampleFLETCH16
Walkthrough
Recover the accepted input below, then submit it to the CRACK verifier.
Reject Samples
- FLETCH17
- FLETCH15
- AAAAAAAA
- FLETCH1
- FLETCH166
Verifier Listing
; z3_fletcher: "Fletcher Gate". No byte is checked on its own. The routine
; runs a two-accumulator running checksum (Fletcher-16) over the whole input and
; gates on a single 16-bit value: s1 += c, then s2 += s1, each reduced mod 255.
; The packed digest is (s2 << 8) | s1, compared to 0x0C1F. Technique: Fletcher-16
; checksum. r0 = 1 on accept. Accept rule: nonzero.
;
; 8-BIT NOTE: Fletcher-16 is already two 8-BIT running sums (s1, s2 each in
; 0..254, reduced mod 255), so it maps onto the byte core with NO loss: the only
; "16-bit" part is PACKING them as (s2<<8)|s1, which is just two byte compares
; (high byte s2 == 0x0C, low byte s1 == 0x1F). Same algorithm, same difficulty.
;
; Adding (a + b) with a,b each 0..254 can reach 508, which overflows a byte, so
; the addmod helper recovers the lost carry by hand: if the byte add wrapped
; (result < a), the true value is result + 256 == result + 1 (mod 255); then a
; subtract-255 reduction brings it back into 0..254.
;
; sample "FLETCH16": s1 = 0x1F (31), s2 = 0x0C (12) -> digest 0x0C1F.
len r2
cmp r2, 8
jnz bad ; exactly 8 bytes
mov r3, 0 ; r3 = s1 (sum of bytes, mod 255)
mov r4, 0 ; r4 = s2 (sum of sums, mod 255)
mov r7, 0 ; index 0..7
floop: cmp r7, 8
jge final
ldb r6, [r7] ; r6 = input[r7]
; --- s1 = (s1 + c) mod 255 -----------------------------------------
; reduce c into 0..254 first so both operands are < 255
cmp r6, 255
jl addc
sub r6, 255 ; 255 -> 0
addc: mov r5, r3 ; r5 = old s1
add r5, r6 ; r5 = (s1 + c) mod 256
cmp r5, r3 ; wrapped iff result < old s1
jge s1red
inc r5 ; +256 == +1 (mod 255)
s1red: cmp r5, 255
jl s1ok
sub r5, 255
s1ok: mov r3, r5 ; r3 = new s1 in 0..254
; --- s2 = (s2 + s1) mod 255 ----------------------------------------
mov r5, r4 ; r5 = old s2
add r5, r3 ; r5 = (s2 + s1) mod 256
cmp r5, r4 ; wrapped iff result < old s2
jge s2red
inc r5 ; +256 == +1 (mod 255)
s2red: cmp r5, 255
jl s2ok
sub r5, 255
s2ok: mov r4, r5 ; r4 = new s2 in 0..254
inc r7
jmp floop
final: cmp r3, 0x1F ; low byte: s1 == 0x1F
jnz bad
cmp r4, 0x0C ; high byte: s2 == 0x0C
jnz bad
mov r0, 1
ret
bad: mov r0, 0
ret