Research-grade JPEG steganography with authenticated encryption, in Rust. v2 ships the AETHER macroblock channel adapter alongside the v1 J-UNIWARD STC pipeline — opt-in L1 stealth against phantasm-aware CNN steganalyzers. Argon2id + XChaCha20-Poly1305 + HMAC envelope shared by both modes.
The hero cycles each cover through three real embeds: the v1 J-UNIWARD pipeline and v2's two AETHER macroblock modes. Every overlay is diff data from the actual stego output, not a render — what you see is what extract sees.
phantasm ships two stealth postures in v2. The default v1 J-UNIWARD STC
pipeline keeps a visually-pristine cover but loses to phantasm-aware
CNNs. The opt-in --channel-adapter aether-mb-{8,16} modes
route through a spatial channel that defeats those CNNs at the cost
of a visibly channel-processed cover. Pick the trade-off your threat
model needs.
An authenticated-encryption-into-a-JPEG tool with two modes: v1 J-UNIWARD STC (default) for visual stealth, and v2 AETHER macroblock for L1 stealth against phantasm-aware CNN steganalyzers.
The cryptographic envelope (Argon2id KDF, XChaCha20-Poly1305 AEAD, HMAC-SHA256-16 permutation MAC, independent-extract HKDF key separation) is shared by both modes and is the load-bearing security layer.
v1 J-UNIWARD is not a plausible-deniability tool against an ML adversary — phantasm-aware CNNs detect it at >96 % AUC cross-corpus. v2 aether-mb addresses this at L1 but the stego is visibly Lanczos-resampled — a viewer sees a channel-processed photo, not a pristine cover.
Neither mode is a magical hidden-channel-against-state-actors primitive. Read the threat-model section in the README before deploying.
L2 and L3 are intact across both modes. L1 has two postures: v1 weak by design, v2 partial via opt-in channel.
v1 J-UNIWARD (default): off-the-shelf CNNs miss it (~16 % detect), phantasm-aware CNNs catch it (96.8 %+ AUC cross-corpus). v2 aether-mb (opt-in): AETHER channel drops phantasm-aware AUC to ≤ 0.55 off-the-shelf / 0.69 ± 0.05 corpus-aware adapted — partial-tier defeat at the cost of a visibly Lanczos-resampled cover. Per-attacker-tier numbers in the mode comparison below; macroblock-specific L1 not yet validated at scale (deferred to v2.1).
Position derivation is passphrase-keyed (ChaCha12 over an Argon2id-stretched
master in v1; HKDF-keyed quadrant signs in v2 macroblock). The realistic
attack is passphrase brute force; verifying any guess requires the AEAD
HMAC check, which gates on the Argon2id-stretched key
(256 MiB / t=3 / p=4 per attempt) regardless of which mode
produced the stego.
XChaCha20-Poly1305 + HMAC-SHA256-16 MAC over
version || salt || nonce || ciphertext. HMAC is verified
before any payload parsing — wrong passphrase always returns
AuthFailed cleanly, no oracle, no length-confusion. AEAD
and HMAC keys come from two independent HKDF-extract
calls so cross-key attacks are impossible by construction.
All three modes share the same AEAD envelope (L2 + L3 layers, both intact).
The columns differ on capacity, visible cover impact, and L1 detection
posture. v1 J-UNIWARD remains the default — omit --channel-adapter
and you get it.
| j-uniward (default v1) |
aether-mb-8 (v2 high-capacity) |
aether-mb-16 (v2 strong-survival) |
|
|---|---|---|---|
| CLI | (no flag) | --channel-adapter aether-mb-8 |
--channel-adapter aether-mb-16 |
| Modulation | DCT ±1 / J-UNIWARD + STC | spatial ±64, K=8 quadrant, rep 1 | spatial ±64, K=16 quadrant, rep 1 |
| Min cover | any JPEG (~256×256+) | 1080p square+ | 1080p square+ |
| Net payload @ 1080p | ~10 KB | ~1 KB | ~245 B |
| Net payload @ 4K | ~40 KB | ~4 KB | ~1 KB |
| Cover→stego PSNR | ~37 dB (visually pristine) | ~12 dB (visibly noisy) | ~12 dB (visibly noisy) |
| Off-the-shelf CNN | ~16% detect rate (≈0.55 AUC) | ≤ 0.55 AUC | ≤ 0.55 AUC |
| Un-adapted phantasm-aware | 96.8% AUC | ~0.50 – 0.55 AUC | ~0.50 – 0.55 AUC |
| Corpus-aware adapted | 96.8% AUC | 0.69 ± 0.05 AUC* | 0.69 ± 0.05 AUC* |
| Recovery (validated) | 100 % byte-perfect (standard) | 100 % @ 22×8 trials | 100 % @ 22×8 trials |
| Best for | large payloads, visual stealth, casual ML adversaries only | L1 stealth against ML adversaries, ~KB payloads on 1080p+ covers | L1 stealth + larger spatial averaging per bit (more channel-noise headroom) |
* AUCs measured on plain v1 J-UNIWARD payloads through the AETHER channel on Path B (BOSSbase 200 covers × 25 passphrases, 100/100 split, 5 seeds). Macroblock-modulated stegos haven't been L1-validated at the same scale yet; v2.1 will close that.
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.
The five v1 pillars carry over unchanged. v2 adds a sixth: the AETHER macroblock channel adapter — the first phantasm release with a working L1 defense.
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.
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.
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.
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.
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.
--channel-adapter aether-mb-{8,16}. Routes the embed
through Lanczos 1/3×↓↑ + UnsharpMask + JPEG QF=85 4:2:0 (the channel
that drops phantasm-aware CNN AUC 96.8 % → 0.69) with spread-spectrum
modulation at one cycle per K×K block. 176 / 176 byte-perfect
recovery across 22 covers × 8 passphrases. Macroblock-specific
L1 numbers deferred to v2.1.
Pre-built binaries for Linux (x86_64 / aarch64, glibc + musl) and macOS (Apple Silicon + Intel). Apt repository and Cargo source build also supported.
Install the signed apt repo, then install phantasm.
Build the latest tagged release via Rust's package manager.
Pre-built binaries for Linux and macOS, all major archs.
Clone and build yourself.
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.
v1's L1-scope-down isn't a default — it's a result. We ran five modify-and-re-encode defenses against attacker-aware CNN steganalyzers and they all closed negatively. The arc lives across GitHub branches with full per-experiment evaluation logs; the load-bearing finding is the operator-fingerprint hypothesis, hardened from the DOPPELGÄNGER post-mortem and confirmed against a faithful Rust port of Butora-Bas 2023's covariance-preserving side-informed embedding.
The integrated writeup — Four Lousy Ghosts: an autopsy of five refuted L1 defenses for JPEG steganography — lives at research.byexec.com with the full PDF on the papers page. Subsequent work continues there as the L1 frontier evolves.
| Codename | Hypothesis | Measured AUC | Verdict |
|---|---|---|---|
| HYDRA | ensemble-saliency-source assignment defeats cost-fingerprint | 0.76 - 0.78 | refuted (partial) |
| CHAMELEON | stochastic per-stego wet-fraction breaks keep-invariant features | 0.82 - 0.93 | refuted |
| DOPPELGÄNGER | variance-shaped costs from natural-cover sigma estimates | 0.99 - 1.00 | refuted (catastrophic) |
| PALIMPSEST | side-informed embedding aligned with natural rounding (Holub-Fridrich-Denemark 2014) | 0.99 | refuted |
| EIDOLON | covariance-preserving asymmetric ternary side-info (Butora-Bas 2023, faithful Rust port) | 0.99 - 1.00 | refuted (catastrophic) |
DOPPELGÄNGER's AUC ~1.00 was the most informative result in the arc. Read the post-mortem for the full extraction; the load-bearing claim:
"The detectable signature is not where phantasm modifies but the fact of modification — specifically, the statistical artifact of decode JPEG → modify integer DCT coefficient → re-encode JPEG. All three randomization defenses left this artifact intact and merely varied which positions carried it. CNNs learn the operator-level fingerprint and ignore the cost map."
PALIMPSEST then tested "what if we change how the modification relates to the natural rounding direction?" and confirmed the ceiling. EIDOLON, the most rigorous mathematical defense in the modify-and-re-encode paradigm — Butora-Bas's covariance-preserving asymmetric ternary side-informed embedding, ported bit-exact from the reference JEEP.py — also hit AUC ~1.00. The operator fingerprint dominates every cost-map and embedding-direction variation we have tested: WHERE-randomization (HYDRA / CHAMELEON / DOPPELGÄNGER), HOW-with-rounding (PALIMPSEST), and covariance-preservation (EIDOLON). What remains is to attack the modify-and-re-encode paradigm itself — research direction continues at research.byexec.com.
The phantasm-aware steganalysis CNNs that produced these AUC numbers are published as a GitHub Release artifact bundle: research-checkpoints-v1 — 244 MB across 20 PyTorch checkpoints. Includes the full per-architecture baselines (EfficientNet-B0 / SRNet / XuNet / ViT-Tiny / shallow-CNN), the phantasm-aware fine-tunes at N=200/1000/2000, the four experiment-specific attackers (HYDRA / CHAMELEON / DOPPELGÄNGER / PALIMPSEST), and the d500-scale 96.8%-AUC headline-corpus attacker.
Each checkpoint ships with its training-config JSON sidecar
(architecture, optimizer, learning rate, epochs, eval splits,
per-epoch AUC), an aggregated manifest.json, and an
SHA256SUMS file. The accompanying
CITATIONS.md
on main credits every architecture author whose work these models
instantiate (Tan & Le 2019 for EfficientNet; Boroumand,
Chen, Fridrich 2019 for SRNet; Xu, Wu, Shi 2016 for XuNet;
Dosovitskiy et al. 2021 for ViT) — please cite the original
authors if you use these in academic work.
External pretrained models (DDE Lab's JIN-SRNet, the Aletheia EfficientNet-B0) are NOT redistributed in this bundle — they're not ours to ship. CITATIONS.md links to their original sources.
Internal audits cover the v0.x codebase plus a verification round. v1.0.1 closed the audit follow-throughs left open at v0.4.0. v2.0.0 inherits those — the v1 STC pipeline is unchanged, and the v2 macroblock surface uses the same envelope. v2-specific audit work has not started.
| 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.
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.
phantasm is a composition of academic primitives — not a novel
contribution to any of them individually. If you cite phantasm in
academic work, please cite the original authors of the underlying
techniques. Full citations with abstracts and notes on how phantasm
uses each work live in
CITATIONS.md.
Software libraries (Rust crates) are credited in
CITATIONS.md
and the workspace Cargo.lock. External pretrained
models referenced but not redistributed (DDE Lab JIN-SRNet,
Aletheia EffNet-B0) are flagged in their respective entries.