CRACK Solution
VALID SERIAL
CRACK checkdigit keygen

Prerequisites
Unlocks
1234565
Techniquecheckdigit keygen
Rulenonzero
Sample1234565
Walkthrough
Recover the accepted input below, then submit it to the CRACK verifier.
Reject Samples
- 1234560
- 1234566
- 1111111
- 9999999
- 1234565X
- ABCDEFG
Verifier Listing
; t05_checkdigit: keygen-style serial check (a Luhn-flavored check digit done
; with 8-bit hand-math). The serial is 7 ASCII digits: 6 body digits then a
; trailing CHECK digit. With alternating weights 1,3,1,3,1,3 the weighted sum of
; the body, taken mod 10, must equal the check digit.
;
; The 8-bit ceiling forces the design choice: a raw weighted sum can exceed 255,
; so we keep the running total REDUCED mod 10 as we go (an inner subtract-10 loop)
; rather than summing wide then dividing. That is the explicit-carry hand-math the
; core is built around. r0 = 1 on accept. Accept rule: nonzero.
;
; sample "1234565": body 123456, weighted sum 45, 45 mod 10 = 5 = the check digit.
len r2
cmp r2, 7
jnz bad ; exactly 7 digits
; --- validate every char is an ASCII digit 0x30..0x39 -------------
mov r7, 0
dchk: cmp r7, r2
jge sum0
ldb r0, [r7]
cmp r0, 0x30
jl bad
cmp r0, 0x39
jg bad
inc r7
jmp dchk
; --- weighted sum of the 6 body digits, kept mod 10 ---------------
sum0: mov r3, 0 ; r3 = running sum (always 0..9)
mov r7, 0 ; index 0..5
mov r4, 1 ; r4 = current weight (toggles 1 <-> 3)
wloop: cmp r7, 6
jge final
ldb r0, [r7]
sub r0, 0x30 ; ASCII -> digit value 0..9
mov r5, r0 ; r5 = digit
; r6 = weight * digit (max 3*9 = 27, fits a byte)
mov r6, 0
mov r1, r4 ; loop weight times, adding the digit
mulw: cmp r1, 0
jz addt
add r6, r5
dec r1
jmp mulw
addt: add r3, r6 ; running sum += term (max 9 + 27 = 36)
red: cmp r3, 10 ; reduce mod 10 by repeated subtraction
jl nextw
sub r3, 10
jmp red
nextw: ; toggle weight 1 <-> 3 (3: (w: 1) maps 1->3, 3->1)
cmp r4, 1
jz w3
mov r4, 1
jmp adv
w3: mov r4, 3
adv: inc r7
jmp wloop
; --- compare the computed check digit to the 7th input digit ------
final: mov r7, 6
ldb r0, [r7]
sub r0, 0x30 ; the supplied check digit value
cmp r0, r3
jnz bad
mov r0, 1
ret
bad: mov r0, 0
ret