Grey Code

Eh4x CTFby smothy

#808080 - Grey Code Challenge

Category: Miscellaneous Points: 413 Author: seyya Flag Format: CTF{...}

Challenge Description

gray code ? nah grey code

Binary string: 0010111100011010000101111111110110010010000100010111011001000110010000011111101101100111010000010101011001111110010000000111010001111110010000011

The challenge provides a web app at http://chall.ehax.in:8076/ featuring an interactive Binary Wheel Decoder — a 5-ring, 32-slice circular disc that must be configured as a valid Gray code before decoding.

Solution

Step 1: Understand the Web App

The web app has three components:

  1. A wheel with 5 rings (inner to outer) and 32 slices (0-31) — each cell is a 0/1 toggle
  2. A validation endpoint (/api/validate-wheel) that checks the wheel is a valid Gray code (adjacent slices differ by exactly 1 bit)
  3. A decode endpoint (/api/decode) that takes the binary input + validated wheel and returns decoded text

The character set maps slice numbers 0-31 to: A-Z @ # _ { } &

Step 2: Find the Right Wheel Rotation

A standard 5-bit reflected binary Gray code (slice n = n ^ (n >> 1)) validates successfully but decodes to:

GXJBKVI_DGSHI&KSIWAZIV_AL}VHC

Since the flag must start with CTF{, we check the offset:

  • G(6) → C(2): difference of -4
  • X(23) → T(19): difference of -4
  • J(9) → F(5): difference of -4
  • B(1) → {(29): 1 - 4 = -3 ≡ 29 mod 32 = {

Every character is shifted by exactly -4 positions (mod 32). The wheel needs to be rotated by 4 positions.

Step 3: Build the Rotated Wheel

python
wheel = []
for s in range(32):
    gray_val = ((s + 4) % 32) ^ (((s + 4) % 32) >> 1)
    bits = format(gray_val, '05b')
    wheel.append(bits)

This rotation preserves the Gray code property (adjacent slices still differ by 1 bit) because Gray code is cyclic.

Step 4: Decode

bash
curl -s -X POST "http://chall.ehax.in:8076/api/decode" \
  -H "Content-Type: application/json" \
  -d '{"binaryInput": "00101111000110100001011111111101100100100001000101110110010001100100000111111011011001110100000101010110011111100100000001110100011111100100000 11", "wheelData": [<rotated wheel>]}'

Flag

CTF{GREY&CODE#GOES_VERY_H@RD}

(Reads as: "GREY CODE GOES VERY HARD")

Key Takeaways

  • Gray code discs are cyclic — rotating the code assignment still produces a valid Gray code
  • The standard reflected binary Gray code is just ONE of many valid configurations; the challenge required finding the correct rotation offset
  • The offset could be deduced by comparing the known flag prefix CTF{ against the standard decode output and computing the consistent shift