CRACK Solution

Luhn Lock

CRACK Luhn checksum validator

In-game screenshot of Luhn Lock
In-game view
FamilyCRACK Graph0.602 DifficultyMedium Ring04 IDz3_luhn

Prerequisites

SCRAMBLER

Unlocks

ROTATE RING

Accepted input 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