How It Works

This page describes the technical implementation of Stegstr's steganographic pipeline: how data is hidden in images, encrypted, and exchanged.

Steganography: DWT (Haar 2D)

Stegstr uses Discrete Wavelet Transform (Haar 2D) steganography rather than raw pixel LSB. This offers better robustness and visual quality.

Payload Format (Raw Layer)

The data embedded in the image has this structure:

If the payload is decrypted, it is UTF-8 JSON:

{ "version": 1, "events": [ ... ] }

The events array contains Nostr-style events: kind 1 (notes), kind 4 (DMs), kind 0 (profiles), and others. This is the Stegstr bundle.

Encryption Layer

Before being embedded, the bundle is typically encrypted. Two modes:

Open (Any Stegstr user)

Recipients (Specific pubkeys only)

Detect Flow

When you load an image with Detect:

  1. Load PNG, crop to even dimensions (required for DWT).
  2. Decode payload from DWT (full image first; if not found, scan 256×256 tiles with step 128).
  3. Parse magic and length, extract payload bytes.
  4. If payload starts with STEGSTR1, decrypt (app key or recipients envelope).
  5. Parse JSON bundle, merge events into the feed (and DMs).

Embed Flow

When you save to an image with Embed:

  1. Collect current events from the feed and local store (notes, DMs, profiles, etc.).
  2. Serialize to JSON: { "version": 1, "events": [...] }.
  3. Encrypt (open or recipients mode).
  4. Prepend magic + 4-byte length, embed into cover image via DWT (tile-based).
  5. Save as PNG.

Image Requirements