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.
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.
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.
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.
phantasm's security has three independent layers. v1's posture rests on the strength of L2 and L3, with L1 explicitly 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.
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.
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.
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.
Most steganography tools ship one or two of these. phantasm composes all five into a single integrated pipeline.
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.
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.
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.
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.