CRACK Solution

FNV License

CRACK FNV-1a keygen

In-game screenshot of FNV License
In-game view
FamilyCRACK Graph0.905 DifficultyHard Ring05 IDz4_fnv1a_keygen

Prerequisites

Tiny Machine

Unlocks

THE EXCHANGE

Accepted input 11114
TechniqueFNV-1a keygen Rulenonzero Sample11114

Walkthrough

Recover the accepted input below, then submit it to the CRACK verifier.

Reject Samples

  • 11113
  • 11115
  • 11014
  • 21114
  • 1114
  • 111140
  • 1111A
Verifier Listing
; z4_fnv1a_keygen: "FNV License". A username and serial keygen built on the FNV-1a
; hash. One valid serial per username. The hash seeds an accumulator with the
; offset basis, then per username byte does XOR-the-byte-IN-then-MULTIPLY-by-the-
; prime (the XOR-before-multiply order is the "1a" tell that separates it from
; FNV-1). Reverse it, run the hash over your name, format the serial. Technique:
; FNV-1a keygen. r0 = 1 on accept. Accept rule: nonzero.
;
; 8-BIT NOTE: the source idea is FNV-1a-32 (basis 0x811C9DC5, prime 0x01000193).
; The core runs the SAME construction truncated to 8 bits: the accumulator is one
; byte seeded with the basis low byte 0xC5, and each step is acc = (acc ^ c) then
; acc = (acc * 0x93) & 0xFF (the prime low byte). Same recognition cues
; (XOR-then-multiply, the prime in the mul).
;
; SERIAL FORMAT (widened so the answer is not a single brute-forceable byte): a
; five-digit serial. The first three digits are the FNV value; the last two are
; its mod-97 self-check, the same value-plus-check shape as z2_keygen_mod97. The
; username is BAKED as constants. Keyed to "dojo" (0x64 0x6F 0x6A 0x6F): the 8-bit
; FNV-1a is 111, and 111 mod 97 is 14, so the one valid serial is "11114".

        ; ================= compute 8-bit FNV-1a over the baked username =====
        mov   r3, 0xC5      ; r3 = accumulator (offset-basis low byte)

        xor   r3, 0x64      ; 'd' : XOR the byte in FIRST
        mul   r3, 0x93      ;       then multiply by the prime (& 0xFF)
        xor   r3, 0x6F      ; 'o'
        mul   r3, 0x93
        xor   r3, 0x6A      ; 'j'
        mul   r3, 0x93
        xor   r3, 0x6F      ; 'o'
        mul   r3, 0x93      ; r3 now holds FNV-1a("dojo") == 111 (0x6F)

        ; ================= validate the five-digit serial ==================
        ; PPP = the FNV value, CC = FNV mod 97. For "dojo": 111 then 14 -> "11114".
        len   r2
        cmp   r2, 5
        jnz   bad

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

        ; --- parse the 3-digit primary in r6, compare to the FNV ----------
pp:     mov   r6, 0
        mov   r7, 0
ppl:    cmp   r7, 3
        jge   ppd
        ldb   r0, [r7]
        sub   r0, 0x30
        mul   r6, 10
        add   r6, r0
        inc   r7
        jmp   ppl
ppd:    cmp   r6, r3
        jnz   bad

        ; --- check = FNV mod 97 (subtract loop) ---------------------------
        mov   r5, r3
cmod:   cmp   r5, 97
        jl    havec
        sub   r5, 97
        jmp   cmod
havec:  ; r5 = FNV mod 97

        ; --- parse the 2-digit supplied check in r6, compare --------------
        mov   r6, 0
        mov   r7, 3
cpl:    cmp   r7, 5
        jge   cpd
        ldb   r0, [r7]
        sub   r0, 0x30
        mul   r6, 10
        add   r6, r0
        inc   r7
        jmp   cpl
cpd:    cmp   r6, r5
        jnz   bad

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