CRACK Solution
Luhn Lock
CRACK Luhn checksum validator

Prerequisites
Unlocks
1337000002
TechniqueLuhn checksum validator
Rulenonzero
Sample1337000002
Walkthrough
Recover the accepted input below, then submit it to the CRACK verifier.
Reject Samples
- 1337000003
- 1337000000
- 123456789X
- 133700000
- 13370000022
- ABCDEFGHIJ
Verifier Listing
; z3_luhn: "Luhn Lock". A product-key validator that accepts any 10-digit
; serial passing the Luhn checksum (the credit-card algorithm). From the right,
; every second digit is doubled (and has 9 subtracted if the result is over 9);
; sum every digit; require the total divisible by 10. Technique: Luhn checksum
; validator. Fits the 8-bit core cleanly (the running sum maxes near 90).
; r0 = 1 on accept. Accept rule: nonzero.
;
; sample "1337000002" passes Luhn; any valid 10-digit Luhn serial is accepted.
;
; "doubled" positions: walking from the LEFT with index i, position (n-1-i) from
; the right is odd <=> i is even (n = 10). So even indices (0,2,4,6,8) are doubled.
len r2
cmp r2, 10
jnz bad ; exactly 10 characters
mov r3, 0 ; r3 = running Luhn sum
mov r7, 0 ; r7 = index 0..9
lloop: cmp r7, 10
jge final
ldb r0, [r7]
; every char must be an ASCII digit 0x30..0x39
cmp r0, 0x30
jl bad
cmp r0, 0x39
jg bad
sub r0, 0x30 ; r0 = digit value 0..9
; double on even indices (these are the "every second from the right")
mov r4, r7
and r4, 1 ; r4 = index parity
cmp r4, 0
jnz addit ; odd index -> add the digit as-is
add r0, r0 ; double the digit (0..18)
cmp r0, 9
jle addit
sub r0, 9 ; cast out nine
addit: add r3, r0 ; sum += contribution
inc r7
jmp lloop
; --- require the total to be a multiple of 10 ----------------------
final: cmp r3, 10 ; reduce mod 10 by repeated subtraction
jl test0
sub r3, 10
jmp final
test0: cmp r3, 0
jnz bad
mov r0, 1
ret
bad: mov r0, 0
ret