A hackme puzzle built on a one-instruction CPU (OISC) that uses only the NOR operation. Originally created by Alexander Demin in 2011, based on the NORCPU concept by Alexander Peslyak.
The project is a compiler and emulator for a virtual CPU whose only instruction is NOR (bitwise NOT-OR on two 16-bit words). All higher-level operations — MOV, ADD, XOR, PUSH/POP, CALL/RET, branching — are built as macros that expand into sequences of NOR instructions.
The script:
- Compiles a password-checking program from macro calls into a flat array of 16-bit words (code + data in a single address space, max 65535 words).
- Runs the program in the built-in emulator to verify correctness.
- Emits a self-contained HTML/JavaScript page (
norcpu.html) that embeds the compiled memory image and runs the same NOR CPU in the browser.
The challenge: given only the HTML page, figure out the password that produces the secret magic message.
cpu.py— NOR CPU primitives: all macros (NOR, MOV, ADD, XOR, MUL3, etc.), architectural registers, and code/data segment management. Imported withfrom cpu import *by program modules.program_hash.py— hash-based password check (one-way, brute-force only). Folds all input characters into a 16-bit accumulator viaacc = (acc + ch) * 3 + K, then compares against a compile-time expected hash.program_xor.py— original XOR per-character password check (reversible). Each input character is XORed with a rolling mask and compared against a stored encoded password.norcpu.py— compiler, emulator, CLI entry point, and HTML generator. Selects the program algorithm via-aflag.norcpu_test.py— pytest tests covering both algorithms.
# Generate both algorithms
just generate
# Or individually
just hash
just xor
# Direct invocation
uv run norcpu.py --password "MySecret" --secret-code "You win!" -a hash
uv run norcpu.py --password "MySecret" --secret-code "You win!" -a xorThis compiles the program, performs a test run to verify the password produces the expected secret code, and generates:
norcpu.asm— the compiled assembly listingnorcpu-{algo}.html— the standalone hackme challenge pagenorcpu-{algo}-visual.html— memory access visualizer (256x256 grid of cells)
The password is not stored in memory. Instead, a one-way hash is computed at compile time and embedded as an immediate value. At runtime, the same hash is computed over user input and compared. Knowing the algorithm does not help recover the password — only brute force works.
acc = seed
for ch in input:
acc = (acc + ch) & 0xFFFF
acc = (acc * 3 + K) & 0xFFFF
if acc != expected_hash or len(input) != expected_len:
failBoth the password and the secret code are stored in memory pre-encoded: each character is XORed with a rolling 16-bit mask. The password can be recovered by reversing the XOR operations.
mask = password.xor_mask
cmp_flag = 0
for i in range(len(password)):
ch = input[i] ^ mask
stored = encoded_password[i] # == password[i] ^ mask
cmp_flag |= ch ^ stored # zero iff input[i] == password[i]
mask = (mask * 3 + password.add_const) & 0xFFFFOn correct password, the secret code is decrypted by XORing stored bytes with a rolling mask (double XOR recovers plaintext):
mask = code.xor_mask
for i in range(len(code)):
output[i] = encoded_code[i] ^ mask
mask = (mask * 3 + code.add_const) & 0xFFFFDownload and open in a browser:
The visualizer shows a 256x256 grid where each cell represents one of the 65536 memory addresses. As the CPU executes, cells are colored by access type:
- Blue — instruction fetch (cells at i, i+1, i+2); darker shade means more repeated accesses (hot loops appear nearly black)
- Green — operand read (cells at addresses a, b)
- Yellow — result write (cell at address r)
- Red — the exit register cell when execution halts
With a wrong password only ~25% of memory lights up (comparison loop only). With the correct password ~99.7% is reached (both comparison and decoding loops).
uv run pytest