Implementation of modern image steganographic algorithms
Project description
conseal
Python package, containing implementations of modern image steganographic algorithms.
:warning: The package only simulates the embedding, which is useful for steganalysis research. We do not provide any end-to-end steganography method.
Installation
Simply install the package with pip3
pip3 install conseal
or using the cloned repository
git clone https://github.com/uibk-uncover/conseal/
cd conseal
pip3 install .
Contents
| Steganography method | Domain | Reference |
|---|---|---|
| F5 | JPEG | Reference |
| nsF5: no-shrinkage F5 | JPEG | Reference |
| EBS: entropy block steganography | JPEG | Reference |
| UERD: uniform embedding revisited distortion | JPEG | Reference |
| J-UNIWARD: JPEG-domain universal wavelet relative distortion | JPEG | Reference |
| LSB: least significant bit | Spatial / JPEG | |
| HILL: high-low-low | Spatial | Reference |
| HUGO: highly undetectable stego | Spatial | Reference |
| MiPOD: minimizing the power of optimal detector | Spatial | Reference |
| S-UNIWARD: spatial-domain universal wavelet relative distortion | spatial | Reference |
| WOW: wavelet obtained weights | spatial | Reference |
Usage
Import the library in Python 3
import conseal as cl
This package currently contains the three JPEG steganography methods J-UNIWARD, UERD, and nsF5. The following examples show how to embed a JPEG cover image cover.jpeg with an embedding rate of 0.4 bits per non-zero AC coefficient (bpnzAC):
- F5
# load cover
jpeg = jpeglib.read_dct("cover.jpeg")
# embed F5 0.4 bpnzAC
jpeg.Y = cl.F5.simulate_single_channel(
y0=jpeg.Y,
alpha=0.4,
seed=12345)
# save result as stego image
jpeg.write_dct("stego.jpeg")
- nsF5
# load cover
jpeg = jpeglib.read_dct("cover.jpeg")
# embed nsF5 0.4 bpnzAC
jpeg.Y = cl.nsF5.simulate_single_channel(
y0=jpeg.Y,
alpha=0.4,
seed=12345)
# save result as stego image
jpeg.write_dct("stego.jpeg")
- EBS
# load cover
jpeg = jpeglib.read_dct("cover.jpeg")
# embed EBS 0.4 bpnzAC
jpeg.Y = cl.ebs.simulate_single_channel(
y0=jpeg.Y,
qt=jpeg.qt[0],
alpha=0.4,
seed=12345)
# save result as stego image
jpeg.write_dct("stego.jpeg")
- UERD
# load cover
jpeg = jpeglib.read_dct("cover.jpeg")
# embed UERD 0.4
jpeg.Y = cl.uerd.simulate_single_channel(
y0=jpeg.Y,
qt=jpeg.qt[0],
embedding_rate=0.4,
seed=12345)
# save result as stego image
jpeg.write_dct("stego.jpeg")
- J-UNIWARD
# load cover
im0 = jpeglib.read_spatial("cover.jpeg", jpeglib.JCS_GRAYSCALE)
jpeg = jpeglib.read_dct("cover.jpeg")
# embed J-UNIWARD 0.4
jpeg.Y = cl.juniward.simulate_single_channel(
x0=im0.spatial[..., 0],
y0=jpeg.Y,
qt=jpeg.qt[0],
alpha=0.4,
seed=12345)
# save result as stego image
jpeg.write_dct("stego.jpeg")
- LSB
# load cover
x0 = np.array(Image.open("cover.png"))
# embed HUGO 0.4 bpnzAC
x1 = cl.lsb.simulate(
x0=x0,
alpha=0.4,
seed=12345)
# save result as stego image
Image.fromarray(x1).save("stego.png")
- HUGO
# load cover
x0 = np.array(Image.open("cover.png"))
# embed HUGO 0.4 bpnzAC
x1 = cl.hugo.simulate_single_channel(
x0=x0,
alpha=0.4,
seed=12345)
# save result as stego image
Image.fromarray(x1).save("stego.png")
- WOW
# load cover
x0 = np.array(Image.open("cover.png"))
# embed WOW 0.4 bpnzAC
x1 = cl.wow.simulate_single_channel(
x0=x0,
alpha=0.4,
seed=12345)
# save result as stego image
Image.fromarray(x1).save("stego.png")
- S-UNIWARD
# load cover
x0 = np.array(Image.open("cover.png"))
# embed S-UNIWARD 0.4 bpnzAC
x1 = cl.suniward.simulate_single_channel(
x0=x0,
alpha=0.4,
seed=12345)
# save result as stego image
Image.fromarray(x1).save("stego.png")
- MiPOD
# load cover
x0 = np.array(Image.open("cover.png"))
# embed MiPOD 0.4 bpnzAC
x1 = cl.mipod.simulate_single_channel(
x0=x0,
alpha=0.4,
seed=12345)
# save result as stego image
Image.fromarray(x1).save("stego.png")
- HILL
# load cover
x0 = np.array(Image.open("cover.png"))
# embed HUGO 0.4 bpnzAC
x1 = cl.hill.simulate_single_channel(
x0=x0,
alpha=0.4,
seed=12345)
# save result as stego image
Image.fromarray(x1).save("stego.png")
Acknowledgements and Disclaimer
Developed by Martin Benes and Benedikt Lorch, University of Innsbruck, 2024.
The J-UNIWARD and nsF5 implementations in this package are based on the original Matlab code provided by the Digital Data Embedding Lab at Binghamton University. We also thank Patrick Bas and Rémi Cogranne for sharing their implementations of UERD and EBS with us.
We have made our best effort to ensure that our implementations produce identical results as the original Matlab implementations. However, it is the user's responsibility to verify this.
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 Distributions
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 conseal-2025.11.tar.gz.
File metadata
- Download URL: conseal-2025.11.tar.gz
- Upload date:
- Size: 745.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0cec6de64c99db7e0016244422f5e40a9bf993fb3c059951fe7f86e888b3d3b9
|
|
| MD5 |
f4b242bc50af987e074cc12b2802e10d
|
|
| BLAKE2b-256 |
219cc6a994b4c08805b70e3db6c4eb2233d2e0bb5ba578f5c2181c9339e3770e
|
File details
Details for the file conseal-2025.11-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: conseal-2025.11-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 983.0 kB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b7725fc79627edbfd42712886ced90251b3b1241aaf1073a77fb9c2821162ad
|
|
| MD5 |
263d1f37d7259e85ca563d580b81b787
|
|
| BLAKE2b-256 |
d3315d23ead429257161cbf193df882a51ac8724e044410c8e2ebd8104263daa
|
File details
Details for the file conseal-2025.11-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: conseal-2025.11-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7fe0738966f03ec0e945ff24e0a08cde802337cc735fee78e0345228c9d9090d
|
|
| MD5 |
63b1fb9af25df749bd478ab852f29844
|
|
| BLAKE2b-256 |
f69f39c7556677ecc29bc28d574e267e54e4903199b7d43b527717fb76b319a0
|
File details
Details for the file conseal-2025.11-cp38-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: conseal-2025.11-cp38-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.8+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3349804aea111fab9704b9c179a75c7b1238420d6436d700abd212acfaa887f6
|
|
| MD5 |
a7f1dfad6a1ae8880bfc3e3cf5ebc3ed
|
|
| BLAKE2b-256 |
38967fc98899801b5a03f64198be91c760bc1c1b0faef504c547d5fd5b5492c2
|