CRACK Solution

Square Deal

CRACK sum-of-squares checksum keygen

In-game screenshot of Square Deal
In-game view
FamilyCRACK Graph0.903 DifficultyHard Ring05 IDz6_sumsq
Accepted input 37213
Techniquesum-of-squares checksum keygen Rulenonzero Sample37213

Walkthrough

The check digit on this serial is not a tally and not a weighted tally. Each body digit is squared first, then the squares are summed and folded to one digit. Square, add, fold, and forge a serial that agrees with itself.

Check digit equals (sum of the squared body digits) mod 10. Square each of the four body digits, add them, reduce mod 10, and that is the fifth digit.

Hints

  • HINT 1: The serial is five digits: four body digits and a check digit. Look at how each digit is multiplied by itself.
  • HINT 2: Sum the four squares, then subtract 10 repeatedly until under 10. That remainder is the required check digit.
  • HINT 3: For 3721 the squares are 9, 49, 4, 1 summing to 63, and 63 mod 10 is 3, so 37213 passes.

Reject Samples

  • 37214
  • 37212
  • 37223
  • 47213
  • 3721
  • 372130
  • ABCDE
Verifier Listing
; z6_sumsq: "Square Deal". A serial validator whose check digit is not a plain
; sum and not a weighted sum: it is the sum of the SQUARES of the body digits,
; reduced mod 10. The serial is five ASCII digits, four body digits then a trailing
; check digit. Square each body digit (d times d), add the squares, reduce the
; total mod 10 by repeated subtraction, and the result must equal the check digit.
; Squaring is what makes a single wrong digit ripple: changing one body digit by
; one shifts its square by an odd amount, so the check mod 10 always moves. To
; crack it, pick a body, sum the squares, take mod 10, append it. Technique: sum-
; of-squares checksum keygen. r0 = 1 on accept; rule: nonzero.
;
; sample "37213": 3*3 + 7*7 + 2*2 + 1*1 = 9 + 49 + 4 + 1 = 63, 63 mod 10 = 3.

        len   r2
        cmp   r2, 5
        jnz   bad           ; five ASCII digits: DDDD C

        ; every char must be a digit 0x30..0x39
        mov   r7, 0
dchk:   cmp   r7, 5
        jge   sum0
        ldb   r0, [r7]
        cmp   r0, 0x30
        jl    bad
        cmp   r0, 0x39
        jg    bad
        inc   r7
        jmp   dchk

        ; --- r3 = sum of squares of the 4 body digits, reduced mod 10: sum0:   mov   r3, 0
        mov   r7, 0
sloop:  cmp   r7, 4
        jge   final
        ldb   r0, [r7]
        sub   r0, 0x30      ; digit value 0..9
        mov   r6, r0
        mul   r6, r0        ; r6 = digit squared (max 81, fits a byte)
        add   r3, r6        ; running total (max so far well under 256)
red:    cmp   r3, 10        ; keep the total reduced mod 10
        jl    nextd
        sub   r3, 10
        jmp   red
nextd:  inc   r7
        jmp   sloop

        ; --- compare to the supplied check digit -----------------------
final:  mov   r7, 4
        ldb   r0, [r7]
        sub   r0, 0x30
        cmp   r0, r3
        jnz   bad

        mov   r0, 1
        ret
bad:    mov   r0, 0
        ret