Skip to content

Commit

Permalink
feat(image:encoder): variable step rate for color channels
Browse files Browse the repository at this point in the history
- variable step by the encoder would move through the color channels
- option for enable/disable the skip of the alpha channel for encoding
  • Loading branch information
sassman authored Dec 9, 2021
1 parent ee64c1b commit 45af81e
Show file tree
Hide file tree
Showing 28 changed files with 751 additions and 256 deletions.
1 change: 1 addition & 0 deletions .deb/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
deb:
docker pull 5422m4n/rust-deb-builder
docker run --rm -v ${ROOT_DIR}/..:/mnt -w /mnt \
5422m4n/rust-deb-builder \
cargo deb -p stegano-cli --target=x86_64-unknown-linux-musl
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ jobs:
name: binaray package .deb
needs: check
runs-on: ubuntu-latest
container:
image: 5422m4n/rust-deb-builder:latest
steps:
- uses: actions/checkout@v2
- name: cargo deb
run: cargo deb -p stegano-cli --target=x86_64-unknown-linux-musl
uses: sassman/[email protected]
with:
package: stegano-cli
- name: Archive deb artifact
uses: actions/upload-artifact@v2
with:
Expand Down
16 changes: 14 additions & 2 deletions .github/workflows/release-binary-assets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,28 @@ jobs:
omitBodyDuringUpdate: true
omitNameDuringUpdate: true
omitPrereleaseDuringUpdate: true
- run: cargo deb -p stegano-cli
- name: cargo deb
if: ${{ matrix.os == 'ubuntu-latest' }}
uses: sassman/[email protected]
with:
package: stegano-cli
- name: rename package
id: debpkg
shell: bash
env:
TAG: ${{ github.event.release.tag_name }}
run: |
filename="stegano-$TAG-amd64-static.deb"
mv target/x86_64-unknown-linux-musl/debian/stegano-cli*.deb "$filename"
echo "::set-output name=filename::$filename"
- name: Upload Deb File
if: ${{ matrix.os == 'ubuntu-latest' }}
uses: ncipollo/[email protected]
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
allowUpdates: true
artifactErrorsFailBuild: true
artifacts: ./target/debian/stegano-${{ steps.tag_name.outputs.current_version }}-amd64.deb
artifacts: ${{ steps.debpkg.outputs.filename }}
artifactContentType: application/vnd.debian.binary-package
omitBodyDuringUpdate: true
omitNameDuringUpdate: true
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ jobs:
default: true
profile: minimal
- uses: Swatinem/rust-cache@v1
- run: cargo install cargo-deb
- name: Get version from tag
id: tag_name
run: echo ::set-output name=current_version::${GITHUB_REF#refs/tags/v}
Expand Down
38 changes: 32 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ Let's unveil the raw data of the `README.md` that we've hidden just above in `RE
The file `README.bin` contains all raw binary data unfiltered decoded by the LSB decoding algorithm.
That is for the curious people, and not so much interesting for regular usage.

## stegano on the web

- [announcement on reddit](https://www.reddit.com/r/rust/comments/fbavos/command_line_steganography_for_png_images_written/)

## Contribute

To contribute to stegano-rs you can either checkout existing issues [labeled with `good first issue`][4] or [open a new issue][5]
Expand Down
10 changes: 5 additions & 5 deletions stegano-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "stegano-cli"
description = "Hiding secret data with steganography in PNG images and WAV audio files"
version = "0.4.10"
version = "0.5.0"
authors = ["Sven Assmann <[email protected]>"]
edition = "2018"
edition = "2021"
license = "GPL-3.0-only"
homepage = "https://www.stegano.org"
readme = "README.md"
Expand All @@ -17,9 +17,9 @@ travis-ci = { repository = "steganogram/stegano-rs", branch = "main" }
maintenance = { status = "passively-maintained" }

[dependencies]
stegano-core = { path = "../stegano-core", version = "0.4.10" }
#stegano-core = "0.4.5"
clap = "2.33"
stegano-core = { path = "../stegano-core", version = "0.5.0" }
#stegano-core = "0.5.0"
clap = "2.34"

[[bin]]
name = "stegano"
Expand Down
32 changes: 29 additions & 3 deletions stegano-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use clap::{crate_authors, crate_description, crate_version, App, AppSettings, Arg, SubCommand};
use clap::{
crate_authors, crate_description, crate_version, App, AppSettings, Arg, ArgMatches, SubCommand,
};

use std::path::Path;
use stegano_core::commands::{unveil, unveil_raw};
use stegano_core::media::image::lsb_codec::CodecOptions;
use stegano_core::*;

fn main() -> Result<()> {
Expand Down Expand Up @@ -99,11 +102,21 @@ fn main() -> Result<()> {
.required(true)
.help("Raw data will be stored as binary file"),
)
).get_matches();
)
.arg(
Arg::with_name("color_step_increment")
.long("x-color-step-increment")
.value_name("color channel step increment")
.takes_value(true)
.default_value("1")
.required(false)
.help("Experimental: image color channel step increment"),
)
.get_matches();

match matches.subcommand() {
("hide", Some(m)) => {
let mut s = SteganoCore::encoder();
let mut s = SteganoCore::encoder_with_options(get_options(m));

s.use_media(m.value_of("media").unwrap())?
.write_to(m.value_of("write_to_file").unwrap());
Expand Down Expand Up @@ -132,6 +145,7 @@ fn main() -> Result<()> {
unveil(
Path::new(m.value_of("input_image").unwrap()),
Path::new(m.value_of("output_folder").unwrap()),
&get_options(m),
)?;
}
("unveil-raw", Some(m)) => {
Expand All @@ -145,3 +159,15 @@ fn main() -> Result<()> {

Ok(())
}

fn get_options(args: &ArgMatches) -> CodecOptions {
let mut c = CodecOptions::default();
if args.is_present("color_step_increment") {
c.color_channel_step_increment = args
.value_of("color_step_increment")
.unwrap()
.parse()
.unwrap();
}
c
}
28 changes: 23 additions & 5 deletions stegano-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "stegano-core"
description = "Steganography core library for stegano-cli. Supports hiding data in PNG images via LSB Encoding."
version = "0.4.10"
version = "0.5.0"
authors = ["Sven Assmann <[email protected]>"]
edition = "2018"
edition = "2021"
license = "GPL-3.0-only"
homepage = "https://www.stegano.org"
readme = "README.md"
Expand All @@ -26,19 +26,37 @@ deflate = "1.0"
byteorder = "1.4"
hound = "3.4"
thiserror = "1.0"
enum_dispatch = "0.3"

[dev-dependencies]
speculate = "0.1"
criterion = "0.3"
criterion = { version = "0.3", features = ["html_reports"] }
tempfile = "3.2"

[dev-dependencies.cargo-husky]
version = "1"
default-features = false
features = ["prepush-hook", "run-cargo-test", "run-cargo-clippy", "run-cargo-fmt"]

[lib]
bench = false

[[bench]]
name = "decoder_benchmark"
name = "image_decoding"
path = "benches/image/decoding.rs"
harness = false

[[bench]]
name = "image_encoding"
path = "benches/image/encoding.rs"
harness = false

[[bench]]
name = "audio_decoding"
path = "benches/audio/decoding.rs"
harness = false

[[bench]]
name = "encoder_benchmark"
name = "audio_encoding"
path = "benches/audio/encoding.rs"
harness = false
21 changes: 21 additions & 0 deletions stegano-core/benches/audio/decoding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use criterion::{criterion_group, criterion_main, Criterion};
use hound::WavReader;
use stegano_core::media::audio::LsbCodec;

pub fn audio_decoding(c: &mut Criterion) {
c.bench_function("Audio Decoding", |b| {
let mut reader = WavReader::open("../resources/secrets/audio-with-secrets.wav")
.expect("Cannot create reader");
let mut buf = [0; 12];

b.iter(|| {
reader.seek(0).expect("Cannot seek to 0");
LsbCodec::decoder(&mut reader)
.read_exact(&mut buf)
.expect("Cannot read 12 bytes from decoder");
})
});
}

criterion_group!(benches, audio_decoding);
criterion_main!(benches);
21 changes: 21 additions & 0 deletions stegano-core/benches/audio/encoding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use criterion::{criterion_group, criterion_main, Criterion};
use hound::WavReader;
use stegano_core::media::audio::LsbCodec;

pub fn audio_encoding(c: &mut Criterion) {
c.bench_function("Audio Encoding to memory", |b| {
let mut reader =
WavReader::open("../resources/plain/carrier-audio.wav").expect("Cannot create reader");
let mut samples = reader.samples().map(|s| s.unwrap()).collect::<Vec<i16>>();
let secret_message = b"Hello World!";

b.iter(|| {
LsbCodec::encoder(&mut samples)
.write_all(&secret_message[..])
.expect("Cannot write to codec");
})
});
}

criterion_group!(benches, audio_encoding);
criterion_main!(benches);
43 changes: 0 additions & 43 deletions stegano-core/benches/decoder_benchmark.rs

This file was deleted.

Loading

0 comments on commit 45af81e

Please sign in to comment.