$ Forensics: Queen Roselia's Diamond

BITSCTF 2026 By TaklaMan
Flag: BITSCTF{qr_bu7_n07_7h47_qr}

Constructed the flag from all the Visible parts from the Image

svd_comp7.png

Source Data

Input file:

  • queen_roselias_diamond/challenge_stego.tif

Intermediate source images used by the SVD step:

  • queen_roselias_diamond/byte0.pngqueen_roselias_diamond/byte7.png

These byte*.png planes represent byte-lanes extracted from the TIFF pixel payload (8 bytes per pixel for float64 storage).

Method Used

sved_comp7.png was created by performing SVD across the set of 8 byte-plane images.

Exact processing logic

  1. Load byte0.pngbyte7.png as grayscale arrays.
  2. Stack into matrix form:
    • shape before flattening: (8, H, W)
    • shape for SVD: (8, H*W)
  3. Mean-center each plane (subtract per-plane mean).
  4. Run SVD:
    • A = U * S * Vt
  5. Take component index 7 (8th component), reshape Vt[7] back to (H, W).
  6. Normalize to [0,255] and save as:
    • svd_comp7.png
  7. Also saved inverted companion image (255 - component) as:
    • svd_comp7_inv.png

Reproducible Program

import numpy as np
from PIL import Image

base = "/home/taklaman/Downloads/queen_roselias_diamond"

# 1) Load byte planes
imgs = []
for i in range(8):
    p = f"{base}/byte{i}.png"
    imgs.append(np.array(Image.open(p).convert("L"), dtype=np.float32))

# 2) Stack and flatten
X = np.stack(imgs, axis=0)          # (8, H, W)
k, h, w = X.shape
A = X.reshape(k, -1)                # (8, H*W)

# 3) Mean-center each plane
A = A - A.mean(axis=1, keepdims=True)

# 4) SVD
U, S, Vt = np.linalg.svd(A, full_matrices=False)

# 5) Component 7 -> image
comp7 = Vt[7].reshape(h, w)

# 6) Normalize to 8-bit
m = comp7 - comp7.min()
m = m / (m.max() + 1e-9)
out = (m * 255).astype(np.uint8)

# 7) Save
Image.fromarray(out).save(f"{base}/svd_comp7.png")
Image.fromarray(255 - out).save(f"{base}/svd_comp7_inv.png")

print("Saved:")
print(f"- {base}/svd_comp7.png")
print(f"- {base}/svd_comp7_inv.png")