shadowforge

"Forge secrets in the shadows, shield them from quantum eyes — and from the eyes of states."
shadowforge is a quantum-resistant steganography toolkit for journalists, whistleblowers, and dissidents operating against nation-state adversaries.
It is a Rust reimplementation of shadowforge (Go), with PDF as a first-class citizen and a full suite of countermeasures designed specifically for the journalist-vs-nation-state threat model.
⚠️ Pre-Production Warning
This software has not been externally security audited. Use it as a supplementary layer alongside established tools (Signal, Tor, SecureDrop). See SECURITY.md and THREAT_MODEL.md.
Feature Matrix
| Feature | Go version | Rust version |
|---|---|---|
| LSB image steganography | ✅ | ✅ |
| DCT JPEG steganography | ✅ | ✅ |
| Palette steganography | ✅ | ✅ |
| LSB audio (WAV) | ✅ | ✅ |
| Phase encoding (DSSS) | ✅ | ✅ |
| Echo hiding | ✅ | ✅ |
| Zero-width text | ✅ | ✅ (grapheme-cluster-safe) |
| PDF embedding | ⚠️ afterthought | ✅ first-class |
| PDF content-stream LSB | ❌ | ✅ |
| PDF XMP metadata embedding | ❌ | ✅ |
| PDF shard-per-page pipeline | ❌ | ✅ |
| ML-KEM-1024 (NIST FIPS 203) | via CIRCL (CGo) | ✅ pure Rust |
| ML-DSA-87 (NIST FIPS 204) | via CIRCL (CGo) | ✅ pure Rust |
| Reed-Solomon K-of-N | ✅ | ✅ |
| 4 distribution patterns | ✅ | ✅ |
| Adversarial embedding optimisation | ❌ | ✅ |
| Camera model fingerprint matching | ❌ | ✅ |
| Compression-survivable embedding | ❌ | ✅ |
| Deniable dual-payload steganography | ❌ | ✅ |
| Panic wipe | ❌ | ✅ |
| Dead drop mode | ❌ | ✅ |
| Canary shard tripwires | ❌ | ✅ |
| Time-lock puzzle payloads | ❌ | ✅ |
| Stylometric fingerprint scrubbing | ❌ | ✅ |
| Corpus steganography (zero-modification) | ❌ | ✅ |
| Amnesiac mode (zero disk writes) | ❌ | ✅ |
| Geographic threshold distribution | ❌ | ✅ |
| Forensic watermark tripwires | ❌ | ✅ |
Quick Start
Installation
# From source (requires Rust 1.94.1)
PDF Support (Optional)
PDF page rasterisation requires the pdfium shared library. Without it, PDF content-stream and metadata steganography still work, but the render-to-PNG pipeline is unavailable.
# macOS (Apple Silicon)
|
# macOS (Intel)
|
# Linux (x86_64)
|
To persist the environment variable, add the export line to your shell
profile (~/.bashrc, ~/.zshrc, etc.).
Building with Features
shadowforge uses Cargo's optional feature system to control which capabilities are compiled in. This allows users to reduce the attack surface and dependencies by disabling features they don't need.
Available Features
| Feature | Default | Purpose |
|---|---|---|
pdf |
✅ | PDF embedding/extraction and page rasterisation (requires pdfium) |
corpus |
✅ | Corpus-based steganography (zero-modification cover selection) |
adaptive |
✅ | Adaptive embedding (STC-inspired steganalysis evasion) |
simd |
❌ | SIMD acceleration for Reed-Solomon (if available on platform) |
Disabling Features
By default, pdf, corpus, and adaptive are enabled. To build with fewer features:
# Disable all optional features
# Disable only PDF
# Enable SIMD in addition to defaults (for performance-critical deployments)
# Enable only SIMD without defaults
Installing from crates.io
When using shadowforge as a dependency:
# In your Cargo.toml
[]
= "0.3" # All default features enabled
# Or with specific features
= { = "0.3", = ["corpus"] }
# Or with no features
= { = "0.3", = false }
Installing the Binary with Features
# Install with all features (default)
# Install without PDF support
# Install from source with specific features
PDF Support (Optional)
PDF page rasterisation requires the pdfium shared library. Without it, PDF content-stream and metadata steganography still work, but the render-to-PNG pipeline is unavailable.
The build process will auto-detect pdfium if:
- Set via
PDFIUM_DYNAMIC_LIB_PATHenvironment variable - Found in a standard system library directory (
/usr/local/lib,/usr/lib,/usr/lib/x86_64-linux-gnu,/usr/lib/aarch64-linux-gnuon Linux/macOS;C:\Program Files\pdfium\libon Windows) - Found via the OS dynamic loader's configured library search paths
If pdfium is not found, the build will emit a warning with setup instructions.
To manually set up pdfium:
# macOS (Apple Silicon)
|
# macOS (Intel)
|
# Linux (x86_64)
|
Shell Completions
# Generate completions for your shell
Basic Usage
# Generate a key pair
# Embed a payload in an image (adaptive mode — defeats commodity steganalysis)
# Extract
# Deniable embedding (two payloads, one cover, plausible deniability)
# Analyse detectability before embedding
# Dead drop: encode for Instagram (survives platform recompression)
# Scrub stylometric fingerprints from a text payload
# Distribute across multiple covers with geographic manifest
# Zero-trace mode (no disk writes)
Architecture
Cargo workspace mono-repo — all crates live under crates/. The main
crate is crates/shadowforge, organised as Collapsed Hexagonal / DDD-lite
with four layers: domain/ (pure, no I/O), adapters/ (I/O and FFI),
application/ (thin orchestration), interface/ (CLI).
Seventeen bounded contexts live under domain/, sharing a single canonical
type vocabulary (domain/types.rs). Nothing is re-invented per context.
Future crates (shadowforge-web, shadowforge-api, etc.) add as new members
under crates/ — no restructuring required.
See the full architecture documentation for design rationale and bounded context details.
Threat Model
See THREAT_MODEL.md for the full threat model.
Adversary: Nation-state. Automated mass steganalysis, compelled decryption, traffic analysis, endpoint compromise, jurisdictional legal pressure, stylometric source identification.
Operational Security
Operational playbooks with step-by-step procedures for five common journalist scenarios are available in the source repository (clone to access). They cover border crossings, dead drops, geographic distribution, time-lock source protection, and zero-trace operation.
See docs/src/opsec/ after cloning.
Documentation
Full documentation is published at greysquirr3l.github.io/shadowforge-rs — covering CLI reference, threat model, architecture, and contributing guidelines.
Development
Test Coverage
453 tests across all adapter, domain, and application modules — 85% line coverage. Key module coverage:
| Module | Coverage |
|---|---|
application/services |
100% |
domain/types |
100% |
domain/analysis |
98.6% |
domain/crypto |
93.5% |
domain/distribution |
89.2% |
adapters/opsec |
88% |
adapters/media |
86.4% |
adapters/archive |
86% |
adapters/stego |
84.5% |
Coverage is enforced via cargo-tarpaulin with an 85% overall threshold
and a 90% threshold for domain::crypto.
See the contributing guide for full development setup instructions.
License
Apache License 2.0 — see LICENSE.
Acknowledgements
Built on the shoulders of: ml-kem, ml-dsa, reed-solomon-erasure, lopdf, pdfium-render, unicode-segmentation, zeroize, subtle.
Go version: greysquirr3l/shadowforge