Content-adaptive JPEG steganography in Rust. Hides authenticated, encrypted payloads in DCT coefficients via J-UNIWARD cost + syndrome-trellis coding, sealed in an Argon2id + XChaCha20-Poly1305 + HMAC-SHA256 envelope.

v1.0.1 · JPEG-only · MIT or Apache-2.0
204 tests passing FORMAT_VERSION 4 audit follow-throughs closed no external review yet

What phantasm is — and what it isn't.

phantasm v1 is honest about its scope. The L2/L3 cryptographic envelope is where the security claim lives; the L1 layer (statistical undetectability of the JPEG itself) is explicitly scoped down.

What it is

An authenticated-encryption-into-a-JPEG tool. phantasm defends the confidentiality of a payload an adversary can see exists.

The cryptographic envelope (Argon2id KDF, XChaCha20-Poly1305 AEAD, HMAC-SHA256-16 permutation MAC, independent-extract HKDF key separation) is the load-bearing layer.

What it isn't

A plausible-deniability tool against a phantasm-aware adversary. The L1 layer degrades gracefully against off-the-shelf modern CNNs but fails against a CNN trained specifically on phantasm output.

If your threat model requires "the adversary should not be able to tell this image contains hidden data at all," phantasm is the wrong tool against a well-resourced ML adversary.

Three layers. Two are intact. One is honest.

phantasm's security has three independent layers. v1's posture rests on the strength of L2 and L3, with L1 explicitly scoped down.

L1 Detection — can an adversary tell the JPEG contains hidden data? scoped down

Off-the-shelf modern CNNs do not reliably detect phantasm J-UNIWARD output at typical payload (16.2% on JIN-SRNet vs 7.1% cover false-positive floor on the headline corpus). A phantasm-aware CNN — trained on actual phantasm stego output — does (96.8%+ at d500 scale). L1 is the weak layer and degrades gracefully against capable adversaries.

L2 Position recovery — can an adversary find the bits without the passphrase? intact

The position permutation is keyed by a ChaCha12 PRNG seeded from an Argon2id + HKDF derivation of (passphrase, image-derived salt). The realistic attack is passphrase brute force, gated by Argon2id at 256 MiB / t=3 / p=4 per attempt; the underlying ChaCha12 seed itself sits in a 2256 space and is computationally unreachable directly.

L3 AEAD decryption — can an adversary decrypt without the passphrase? intact

XChaCha20-Poly1305 with a 24-byte nonce, plus an HMAC-SHA256-16 permutation MAC over version || salt || nonce || ciphertext. The HMAC is verified before any payload parsing, so a wrong passphrase always returns AuthFailed cleanly — no oracle, no length-confusion. AEAD and HMAC keys are derived from the master key via two independent HKDF-extract calls (separate salts), so cross-key attacks are impossible by construction.

Measured, not estimated.

198-cover Picsum research corpus. QF=85, ~720px short-side, ~0.2 bpnzac payload, --cost-function j-uniward, h=10 trellis with the published DDE Lab H̃ tables.

Detector Cover false-positive phantasm J-UNIWARD detection
JIN-SRNet (Butora/Yousfi/Fridrich 2021, ImageNet+J-UNIWARD pretrained) 7.1% 16.2%
EffNet-B0 (Aletheia, ALASKA2 pretrained) 88.9% (cover-source mismatch) paired-evade

49.5% of phantasm J-UNIWARD stegos score lower P(stego) than their own cover. JIN-SRNet thinks the stego is more cover-like than the original, in half the samples.

Caveats applicable to every number above:
  1. Specific to the Picsum research corpus, ~720px JPEGs, QF=85, payload ~0.2 bpnzac. Other cover-source distributions, payload ratios, and detector training sets will produce different numbers.
  2. JIN-SRNet was trained at 0.4-0.6 bpnzac; phantasm at typical payload sits below the training distribution. Detection rises as payload approaches training distribution.
  3. These are off-the-shelf-detector numbers. Against a phantasm-aware adversary that has fine-tuned a CNN on phantasm output (5 passphrases per cover, ~2k pairs, EfficientNet-B0 on a 500-cover corpus), measured detection is 96.8%. The L1 layer does not defend against phantasm-aware ML.

What v1 actually composes.

Most steganography tools ship one or two of these. phantasm composes all five into a single integrated pipeline.

01

Content-adaptive cost

J-UNIWARD (Holub & Fridrich 2014). Wavelet-domain relative-distortion cost computed from the spatial-domain decoding of the cover. Prefers modifications in textured regions over smooth regions.

02

Syndrome-trellis coding

Published DDE Lab H̃ tables (Filler 2011) for h ∈ [7, 12], w ∈ [2, 20]. Conditional-probability double-layer decomposition at 0.995× bits/L1. Property-tested across 200 seeds + asymmetric cost regimes.

03

Modern AEAD envelope

Argon2id (256 MiB, t=3, p=4) + XChaCha20-Poly1305 + HMAC-SHA256-16 + independent-extract HKDF key separation. Envelope FORMAT_VERSION 4. Fast-fail wrong-passphrase returns AuthFailed before any length parsing.

04

Channel adapter experimental

MINICER (Minimum-Iterative Coefficient Error Robust per-coefficient stabilization) + ROAST (Robust Overflow Alleviation for STego) + Reed-Solomon ECC for share-and-recompress survival on the Twitter profile. End-to-end recovery under image-crate QF=85 round-trip is not yet reliable at default RS parameters.

05

Hash-guard

Marks coefficients whose modification would flip the selected perceptual-hash bits as wet-paper, preserving the cover's pHash or dHash through embed. Three sensitivity tiers + wet-paper STC constraint.

Install phantasm.

Pre-built binaries for Linux (x86_64 / aarch64, glibc + musl) and macOS (Apple Silicon + Intel). Apt repository and Cargo source build also supported.

Debian / Ubuntu (apt)

Install the signed apt repo, then install phantasm.

curl -fsSL https://repo.x86-64.com/exec.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/exec.gpg
echo "deb [signed-by=/etc/apt/keyrings/exec.gpg] https://repo.x86-64.com stable main" | sudo tee /etc/apt/sources.list.d/exec.list
sudo apt update && sudo apt install phantasm

Cargo (from source)

Build the latest tagged release via Rust's package manager.

cargo install --git https://github.com/exec/phantasm phantasm-cli

Direct download

Pre-built binaries for Linux and macOS, all major archs.

github.com/exec/phantasm/releases →

From source

Clone and build yourself.

git clone https://github.com/exec/phantasm
cd phantasm && cargo build --release

Quickstart

Embed and extract using --passphrase-env to keep secrets out of argv:

# Embed
PASS="correct horse battery staple" \
  phantasm embed \
    --input cover.jpg \
    --payload secret.txt \
    --passphrase-env PASS \
    --output stego.jpg

# Extract
PASS="correct horse battery staple" \
  phantasm extract \
    --input stego.jpg \
    --passphrase-env PASS \
    --output recovered.txt

--passphrase <literal> exists for ergonomic testing, but exposes the passphrase via /proc/<pid>/cmdline. Use --passphrase-env or --passphrase-fd in production.

Audit-grade, not assurance-grade.

Internal audits cover the v0.x codebase plus a verification round. v1.0.1 closes the audit follow-throughs that were left open at v0.4.0.

Finding Severity v1 status
STC syndrome boundary check medium (false alarm) confirmed correct
Same-source HMAC/AEAD keys low (theoretical) closed — independent-extract HKDF
Double-layer encoder coupling low (most subtle) closed — property-based test added
DCT-I vs DCT-II in hash_guard low (numerical) closed — verified DCT-II orthonormal, locked in by test
PRNG fallback untested info closed — structural-properties + determinism tests
PNG decoder unused info closed — PNG removed entirely from v1
CLI passphrase exposure medium closed in v0.3 (--passphrase-env, --passphrase-fd)

The audits also document several INFO/LOW findings that are documented design choices rather than fix-targets — effective_height stub semantics, HMAC-pre-decryption pre-check rationale, locations-key HKDF + Argon2id chain design, payload-auth scope trade-off, salt stability against adversarial covers. See audits/ for the full inventory and rationale.

No external commercial security review

The cryptographic primitives are used via established crates (argon2, chacha20poly1305, sha2, hkdf, hmac) and the composition is reviewed in the audits above — but it has not been examined by a paid third-party firm. Treat phantasm v1 accordingly. If your threat model requires production-grade assurance, commission a dedicated review before deploying.