Text steganography demo driven by next-token distributions
Project description
Ghostext
Ghostext is a text steganography demo. It encrypts your message first, then hides the ciphertext inside language-model token choices so the same model, prompt, passphrase, and seed can recover it later.
Quick start
Install from PyPI with local-LLM support:
pip install ghostext[llm]
Run a quick encode/decode round-trip check:
ghostext encode \
--prompt 'Write a short, natural paragraph about a quiet evening walk.' \
--passphrase demo-pass \
--message 'Attack at Dawn!' \
| ghostext decode \
--prompt 'Write a short, natural paragraph about a quiet evening walk.' \
--passphrase demo-pass
See all command options:
ghostext --help
ghostext encode --help
ghostext decode --help
ghostext benchmark --help
On the first run, Ghostext will:
- look for a local model from
--model-path - otherwise check
GHOSTEXT_MODEL_PATHorGHOSTEXT_LLAMA_MODEL_PATH - otherwise download the default GGUF model to
~/.cache/ghostext/models/qwen35-2b-q4ks/
The default model is:
- model id:
Qwen/Qwen3.5-2B - repo:
bartowski/Qwen_Qwen3.5-2B-GGUF - file:
Qwen_Qwen3.5-2B-Q4_K_S.gguf
Everyday usage
Most of the time, encode only needs these arguments:
ghostext encode \
--prompt '请写一段自然、连贯、简短的中文段落,描写傍晚散步时看到的街景。' \
--passphrase 'river-pass' \
--message '今晚七点在河边老地方见。'
decode reads the stego text from stdin by default, so a shell pipe stays short too:
ghostext encode \
--prompt 'Write a short, natural paragraph about a quiet evening walk.' \
--passphrase demo-pass \
--message 'Attack at Dawn!' \
| ghostext decode \
--prompt 'Write a short, natural paragraph about a quiet evening walk.' \
--passphrase demo-pass
If you want to keep the generated text:
ghostext encode \
--prompt 'Write a short, natural paragraph about a quiet evening walk.' \
--passphrase demo-pass \
--message 'Attack at Dawn!' \
> stego.txt
ghostext decode \
--prompt 'Write a short, natural paragraph about a quiet evening walk.' \
--passphrase demo-pass \
--text-file stego.txt
Defaults You No Longer Need To Tune
The CLI now comes with a real-model preset so users usually do not need to care about:
--seedunless you want a custom shared seed--ctx-size--batch-size--top-p--max-candidates--min-entropy-bits--totfreq
The current default preset is:
- backend:
llama-cpp - seed:
7 - ctx size:
4096 - batch size:
128 - top-p:
0.995 - max candidates:
64 - min entropy bits:
0.0 - total frequency:
4096
These are the values used when you do not override them.
Common overrides
Use a model you already have:
ghostext encode \
--model-path /abs/path/to/model.gguf \
--prompt 'Write a short paragraph about a quiet evening walk.' \
--passphrase demo-pass \
--message 'Attack at Dawn!' \
| ghostext decode \
--model-path /abs/path/to/model.gguf \
--prompt 'Write a short paragraph about a quiet evening walk.' \
--passphrase demo-pass
Change the default download directory:
GHOSTEXT_MODEL_DIR=/data/ghostext-models \
ghostext encode \
--prompt 'Write a short paragraph about a quiet evening walk.' \
--passphrase demo-pass \
--message 'Attack at Dawn!' \
| GHOSTEXT_MODEL_DIR=/data/ghostext-models \
ghostext decode \
--prompt 'Write a short paragraph about a quiet evening walk.' \
--passphrase demo-pass
Show structured metadata:
ghostext encode \
--json \
--prompt 'Write a short paragraph about a quiet evening walk.' \
--passphrase demo-pass \
--message 'Attack at Dawn!'
Disable logs when you want fully quiet output:
ghostext encode \
--quiet \
--prompt 'Write a short paragraph about a quiet evening walk.' \
--passphrase demo-pass \
--message 'Attack at Dawn!'
Simple benchmark
Run a quick benchmark to measure:
encode latencydecode latencyencode bits/tokenppl
Use the local LLM backend (llama-cpp) with the same prompt/passphrase/message shown in the quick start:
ghostext benchmark \
--backend llama-cpp \
--prompt 'Write a short, natural paragraph about a quiet evening walk.' \
--passphrase demo-pass \
--message 'Attack at Dawn!' \
--runs 3 \
--json
More detail
Use spec.md if you want the protocol-level design and implementation notes. The README is intentionally optimized for getting from install to a working round-trip as quickly as possible.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ghostext-0.1.2.tar.gz.
File metadata
- Download URL: ghostext-0.1.2.tar.gz
- Upload date:
- Size: 35.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5461d5b97910883e14345219e09156b5ec78ac467e5268c51168ead061314de0
|
|
| MD5 |
a21ec7ff8c0058d1a774c151f1816a03
|
|
| BLAKE2b-256 |
2d2a999e6cea2a1862f31dd2aaf505db41d4254963956e8f62f94fa40f3e5f02
|
File details
Details for the file ghostext-0.1.2-py3-none-any.whl.
File metadata
- Download URL: ghostext-0.1.2-py3-none-any.whl
- Upload date:
- Size: 31.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b32b7cc016fcafdc183d62b86f4f539d8126112839741b9a4d90215a3401328
|
|
| MD5 |
41037482f08dcdaaada996ca16bfa321
|
|
| BLAKE2b-256 |
5d27de3a14413693bcc853bea3ee9e0ee5e3d80dc8b8e0fd5bc0bc473f936570
|