Add professional project structure and documentation
New files: - LICENSE (MIT) - Required legal file - CHANGELOG.md - Version history following Keep a Changelog - CONTRIBUTING.md - Contributor guidelines - CODE_OF_CONDUCT.md - Community standards - .github/ISSUE_TEMPLATE/ - Bug report and feature request forms - .github/PULL_REQUEST_TEMPLATE.md - PR checklist - src/stegasoo/py.typed - PEP 561 type hint marker - examples/ - Usage examples (basic, file embedding, channel keys) Updated: - README.md - Added CI status badges 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
98
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
98
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
name: Bug Report
|
||||||
|
description: Report a bug or unexpected behavior
|
||||||
|
title: "[Bug]: "
|
||||||
|
labels: ["bug", "triage"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to report a bug! Please fill out the form below.
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Bug Description
|
||||||
|
description: A clear and concise description of what the bug is.
|
||||||
|
placeholder: Describe the bug...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: reproduction
|
||||||
|
attributes:
|
||||||
|
label: Steps to Reproduce
|
||||||
|
description: Steps to reproduce the behavior.
|
||||||
|
placeholder: |
|
||||||
|
1. Run command '...'
|
||||||
|
2. Upload image '...'
|
||||||
|
3. See error
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: expected
|
||||||
|
attributes:
|
||||||
|
label: Expected Behavior
|
||||||
|
description: What did you expect to happen?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: actual
|
||||||
|
attributes:
|
||||||
|
label: Actual Behavior
|
||||||
|
description: What actually happened?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: dropdown
|
||||||
|
id: interface
|
||||||
|
attributes:
|
||||||
|
label: Interface
|
||||||
|
description: Which interface are you using?
|
||||||
|
options:
|
||||||
|
- CLI
|
||||||
|
- Web UI
|
||||||
|
- REST API
|
||||||
|
- Python Library
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Stegasoo Version
|
||||||
|
description: Run `stegasoo --version` or check the web UI footer
|
||||||
|
placeholder: "4.0.1"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: python-version
|
||||||
|
attributes:
|
||||||
|
label: Python Version
|
||||||
|
description: Run `python --version`
|
||||||
|
placeholder: "3.11.0"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: Operating System
|
||||||
|
placeholder: "Ubuntu 22.04 / Windows 11 / macOS 14"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Error Logs
|
||||||
|
description: Paste any relevant error messages or tracebacks.
|
||||||
|
render: shell
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: additional
|
||||||
|
attributes:
|
||||||
|
label: Additional Context
|
||||||
|
description: Add any other context, screenshots, or files here.
|
||||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
blank_issues_enabled: true
|
||||||
|
contact_links:
|
||||||
|
- name: Security Vulnerability
|
||||||
|
url: https://github.com/adlee-was-taken/stegasoo/security/advisories/new
|
||||||
|
about: Report security vulnerabilities privately
|
||||||
|
- name: Documentation
|
||||||
|
url: https://github.com/adlee-was-taken/stegasoo#readme
|
||||||
|
about: Check the documentation before opening an issue
|
||||||
62
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
62
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
name: Feature Request
|
||||||
|
description: Suggest a new feature or enhancement
|
||||||
|
title: "[Feature]: "
|
||||||
|
labels: ["enhancement"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for suggesting a feature! Please fill out the form below.
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Problem Statement
|
||||||
|
description: Is your feature request related to a problem? Describe it.
|
||||||
|
placeholder: I'm always frustrated when...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: Proposed Solution
|
||||||
|
description: Describe the solution you'd like.
|
||||||
|
placeholder: I would like to be able to...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: Alternatives Considered
|
||||||
|
description: Describe any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
- type: dropdown
|
||||||
|
id: interface
|
||||||
|
attributes:
|
||||||
|
label: Affected Interface(s)
|
||||||
|
description: Which interface(s) would this feature affect?
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- CLI
|
||||||
|
- Web UI
|
||||||
|
- REST API
|
||||||
|
- Python Library
|
||||||
|
- Core Library
|
||||||
|
|
||||||
|
- type: dropdown
|
||||||
|
id: priority
|
||||||
|
attributes:
|
||||||
|
label: Priority
|
||||||
|
description: How important is this feature to you?
|
||||||
|
options:
|
||||||
|
- Nice to have
|
||||||
|
- Would improve my workflow
|
||||||
|
- Critical for my use case
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: context
|
||||||
|
attributes:
|
||||||
|
label: Additional Context
|
||||||
|
description: Add any other context, mockups, or examples here.
|
||||||
46
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
46
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- Describe your changes in detail -->
|
||||||
|
|
||||||
|
## Type of Change
|
||||||
|
|
||||||
|
<!-- Mark the relevant option with an 'x' -->
|
||||||
|
|
||||||
|
- [ ] Bug fix (non-breaking change that fixes an issue)
|
||||||
|
- [ ] New feature (non-breaking change that adds functionality)
|
||||||
|
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
||||||
|
- [ ] Documentation update
|
||||||
|
- [ ] Refactoring (no functional changes)
|
||||||
|
- [ ] CI/CD or build changes
|
||||||
|
|
||||||
|
## Related Issues
|
||||||
|
|
||||||
|
<!-- Link any related issues here -->
|
||||||
|
|
||||||
|
Fixes #
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
<!-- Describe how you tested your changes -->
|
||||||
|
|
||||||
|
- [ ] I have added tests that prove my fix/feature works
|
||||||
|
- [ ] Existing tests pass locally with my changes
|
||||||
|
- [ ] I have tested manually (describe below)
|
||||||
|
|
||||||
|
### Manual Testing Steps
|
||||||
|
|
||||||
|
<!-- If applicable, describe manual testing performed -->
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
- [ ] My code follows the project's style guidelines
|
||||||
|
- [ ] I have performed a self-review of my code
|
||||||
|
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||||
|
- [ ] I have updated the documentation accordingly
|
||||||
|
- [ ] I have updated CHANGELOG.md (if user-facing changes)
|
||||||
|
- [ ] My changes generate no new warnings
|
||||||
|
- [ ] Any dependent changes have been merged and published
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
<!-- If applicable, add screenshots to help explain your changes -->
|
||||||
96
CHANGELOG.md
Normal file
96
CHANGELOG.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to Stegasoo will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
|
|
||||||
|
## [4.0.1] - 2025-01-02
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed numpy binary incompatibility on Python 3.10 (jpegio/scipy)
|
||||||
|
- Fixed BatchCredentials test failures with missing `reference_photo` parameter
|
||||||
|
- Graceful handling when DCT dependencies have version mismatches
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Applied `ruff` linter fixes across entire codebase (~400 issues)
|
||||||
|
- Applied `black` formatter to all Python files
|
||||||
|
- Modernized type hints: `Optional[X]` → `X | None`
|
||||||
|
- Updated ruff config to use `[tool.ruff.lint]` section
|
||||||
|
- Moved documentation files to repository root
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- Removed obsolete debug/diagnostic scripts
|
||||||
|
- Cleaned up backup files and dev scripts
|
||||||
|
|
||||||
|
## [4.0.0] - 2024-12-29
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Refreshed Web UI with modern, snazzy interface
|
||||||
|
- Improved user experience across all pages
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Major version bump for breaking API changes
|
||||||
|
- Simplified passphrase handling (single passphrase instead of day-based)
|
||||||
|
- Removed date_str parameter from encoding
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Various bug fixes for Web UI
|
||||||
|
- CLI updates and improvements
|
||||||
|
|
||||||
|
## [3.2.0] - 2024-12-28
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Big revamp of the encoding system
|
||||||
|
- Home and about page improvements
|
||||||
|
- UNDER_THE_HOOD.md documentation
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Renamed `phrase` → `passphrase` in API
|
||||||
|
- Updated Web UI styling
|
||||||
|
|
||||||
|
## [3.0.2] - 2024-12-27
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Full experimental DCT steganography support
|
||||||
|
- jpegio integration for better JPEG manipulation
|
||||||
|
- DCT/LSB mode selector in Web UI
|
||||||
|
|
||||||
|
## [3.0.0] - 2024-12-25
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- DCT (Discrete Cosine Transform) steganography mode
|
||||||
|
- Support for JPEG carriers without quality loss
|
||||||
|
- Channel key feature for private messaging
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Complete rewrite of steganography engine
|
||||||
|
- New hybrid authentication system
|
||||||
|
|
||||||
|
## [2.0.0] - 2024-12-20
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Web UI frontend
|
||||||
|
- REST API (FastAPI)
|
||||||
|
- Batch processing support
|
||||||
|
- RSA key authentication option
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Migrated to hybrid photo + passphrase + PIN authentication
|
||||||
|
|
||||||
|
## [1.0.0] - 2024-12-15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial release
|
||||||
|
- LSB steganography
|
||||||
|
- AES-256-GCM encryption
|
||||||
|
- CLI interface
|
||||||
|
- Basic PIN authentication
|
||||||
|
|
||||||
|
[4.0.1]: https://github.com/adlee-was-taken/stegasoo/compare/v4.0.0...v4.0.1
|
||||||
|
[4.0.0]: https://github.com/adlee-was-taken/stegasoo/compare/v3.2.0...v4.0.0
|
||||||
|
[3.2.0]: https://github.com/adlee-was-taken/stegasoo/compare/v3.0.2...v3.2.0
|
||||||
|
[3.0.2]: https://github.com/adlee-was-taken/stegasoo/compare/v3.0.0...v3.0.2
|
||||||
|
[3.0.0]: https://github.com/adlee-was-taken/stegasoo/compare/v2.0.0...v3.0.0
|
||||||
|
[2.0.0]: https://github.com/adlee-was-taken/stegasoo/compare/v1.0.0...v2.0.0
|
||||||
|
[1.0.0]: https://github.com/adlee-was-taken/stegasoo/releases/tag/v1.0.0
|
||||||
54
CODE_OF_CONDUCT.md
Normal file
54
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or advances
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying and enforcing our standards
|
||||||
|
of acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the project maintainers. All complaints will be reviewed and
|
||||||
|
investigated promptly and fairly.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
|
||||||
|
version 2.0.
|
||||||
165
CONTRIBUTING.md
Normal file
165
CONTRIBUTING.md
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
# Contributing to Stegasoo
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to Stegasoo! This document provides guidelines and information for contributors.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Python 3.10 or higher
|
||||||
|
- Git
|
||||||
|
- Docker (optional, for container testing)
|
||||||
|
|
||||||
|
### Development Setup
|
||||||
|
|
||||||
|
1. **Clone the repository**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/adlee-was-taken/stegasoo.git
|
||||||
|
cd stegasoo
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Create a virtual environment**
|
||||||
|
```bash
|
||||||
|
python -m venv venv
|
||||||
|
source venv/bin/activate # On Windows: venv\Scripts\activate
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Install development dependencies**
|
||||||
|
```bash
|
||||||
|
pip install -e ".[dev]"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Install pre-commit hooks**
|
||||||
|
```bash
|
||||||
|
pre-commit install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Code Style
|
||||||
|
|
||||||
|
We use the following tools to maintain code quality:
|
||||||
|
|
||||||
|
- **Black** - Code formatting (line length: 100)
|
||||||
|
- **Ruff** - Linting
|
||||||
|
- **MyPy** - Type checking
|
||||||
|
|
||||||
|
Run all checks before committing:
|
||||||
|
```bash
|
||||||
|
black src/ tests/ frontends/
|
||||||
|
ruff check src/ tests/ frontends/
|
||||||
|
mypy src/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run all tests
|
||||||
|
pytest
|
||||||
|
|
||||||
|
# Run with coverage
|
||||||
|
pytest --cov=stegasoo --cov-report=term-missing
|
||||||
|
|
||||||
|
# Run specific test file
|
||||||
|
pytest tests/test_stegasoo.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Type Hints
|
||||||
|
|
||||||
|
All new code should include type hints:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def encode_message(
|
||||||
|
message: str,
|
||||||
|
carrier_image: bytes,
|
||||||
|
passphrase: str,
|
||||||
|
pin: str = "",
|
||||||
|
) -> EncodeResult:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Making Changes
|
||||||
|
|
||||||
|
### Branch Naming
|
||||||
|
|
||||||
|
- `feature/description` - New features
|
||||||
|
- `fix/description` - Bug fixes
|
||||||
|
- `docs/description` - Documentation updates
|
||||||
|
- `refactor/description` - Code refactoring
|
||||||
|
|
||||||
|
### Commit Messages
|
||||||
|
|
||||||
|
Write clear, concise commit messages:
|
||||||
|
|
||||||
|
```
|
||||||
|
Add channel key validation for private messaging
|
||||||
|
|
||||||
|
- Implement validate_channel_key() function
|
||||||
|
- Add tests for valid/invalid key formats
|
||||||
|
- Update CLI to support --channel-key flag
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pull Request Process
|
||||||
|
|
||||||
|
1. **Create a feature branch** from `main`
|
||||||
|
2. **Make your changes** with appropriate tests
|
||||||
|
3. **Ensure all checks pass** (tests, linting, formatting)
|
||||||
|
4. **Submit a PR** with a clear description
|
||||||
|
5. **Address review feedback** promptly
|
||||||
|
|
||||||
|
### PR Checklist
|
||||||
|
|
||||||
|
- [ ] Tests added/updated for changes
|
||||||
|
- [ ] Documentation updated if needed
|
||||||
|
- [ ] CHANGELOG.md updated for user-facing changes
|
||||||
|
- [ ] All CI checks passing
|
||||||
|
- [ ] No merge conflicts with `main`
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
stegasoo/
|
||||||
|
├── src/stegasoo/ # Core library
|
||||||
|
│ ├── crypto.py # Encryption/decryption
|
||||||
|
│ ├── steganography.py # LSB embedding
|
||||||
|
│ ├── dct_steganography.py # DCT embedding
|
||||||
|
│ └── ...
|
||||||
|
├── frontends/
|
||||||
|
│ ├── cli/ # Command-line interface
|
||||||
|
│ ├── web/ # Flask web UI
|
||||||
|
│ └── api/ # FastAPI REST API
|
||||||
|
├── tests/ # Test suite
|
||||||
|
└── examples/ # Usage examples
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reporting Issues
|
||||||
|
|
||||||
|
### Bug Reports
|
||||||
|
|
||||||
|
Please include:
|
||||||
|
- Python version and OS
|
||||||
|
- Stegasoo version (`stegasoo --version`)
|
||||||
|
- Minimal reproduction steps
|
||||||
|
- Expected vs actual behavior
|
||||||
|
- Error messages/tracebacks
|
||||||
|
|
||||||
|
### Feature Requests
|
||||||
|
|
||||||
|
Please include:
|
||||||
|
- Use case description
|
||||||
|
- Proposed solution (if any)
|
||||||
|
- Alternatives considered
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
If you discover a security vulnerability, please see [SECURITY.md](SECURITY.md) for responsible disclosure guidelines. **Do not open a public issue for security vulnerabilities.**
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing, you agree that your contributions will be licensed under the MIT License.
|
||||||
|
|
||||||
|
## Questions?
|
||||||
|
|
||||||
|
Feel free to open a discussion or issue if you have questions about contributing.
|
||||||
|
|
||||||
|
Thank you for helping make Stegasoo better!
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024-2025 Aaron D. Lee
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
A secure steganography system for hiding encrypted messages in images using hybrid authentication.
|
A secure steganography system for hiding encrypted messages in images using hybrid authentication.
|
||||||
|
|
||||||
|
[](https://github.com/adlee-was-taken/stegasoo/actions/workflows/test.yml)
|
||||||
|
[](https://github.com/adlee-was-taken/stegasoo/actions/workflows/lint.yml)
|
||||||

|

|
||||||

|
[](https://opensource.org/licenses/MIT)
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
|||||||
48
examples/README.md
Normal file
48
examples/README.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Stegasoo Examples
|
||||||
|
|
||||||
|
This directory contains example scripts demonstrating how to use Stegasoo.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Install Stegasoo first:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install stegasoo
|
||||||
|
# Or for development:
|
||||||
|
pip install -e ".[all]"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### basic_usage.py
|
||||||
|
|
||||||
|
Basic encode/decode workflow with a text message.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python basic_usage.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### embed_file.py
|
||||||
|
|
||||||
|
Embed and extract files (documents, images, etc.) inside carrier images.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python embed_file.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### channel_keys.py
|
||||||
|
|
||||||
|
Use channel keys to create private communication channels for groups.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python channel_keys.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Images
|
||||||
|
|
||||||
|
You'll need to provide your own images:
|
||||||
|
|
||||||
|
- `my_secret_photo.png` - Your reference photo (keep this secret!)
|
||||||
|
- `carrier.png` - The image that will carry your hidden message
|
||||||
|
|
||||||
|
For testing, you can use any PNG or BMP image. JPEG carriers are supported with DCT mode.
|
||||||
59
examples/basic_usage.py
Normal file
59
examples/basic_usage.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Basic Stegasoo Usage Example
|
||||||
|
|
||||||
|
This example demonstrates how to encode and decode a secret message
|
||||||
|
using the Stegasoo library.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import stegasoo
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Load your images
|
||||||
|
# The reference photo is your "key" - keep it secret!
|
||||||
|
reference_photo = Path("my_secret_photo.png").read_bytes()
|
||||||
|
carrier_image = Path("carrier.png").read_bytes()
|
||||||
|
|
||||||
|
# Your secret message
|
||||||
|
message = "This is my secret message!"
|
||||||
|
|
||||||
|
# Your credentials
|
||||||
|
passphrase = "correct horse battery staple" # Use 4+ words
|
||||||
|
pin = "123456" # 6-9 digits
|
||||||
|
|
||||||
|
# === ENCODE ===
|
||||||
|
print("Encoding message...")
|
||||||
|
result = stegasoo.encode(
|
||||||
|
message=message,
|
||||||
|
reference_photo=reference_photo,
|
||||||
|
carrier_image=carrier_image,
|
||||||
|
passphrase=passphrase,
|
||||||
|
pin=pin,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Save the stego image
|
||||||
|
output_path = Path(f"secret_{result.suggested_filename}")
|
||||||
|
output_path.write_bytes(result.stego_image)
|
||||||
|
print(f"Saved to: {output_path}")
|
||||||
|
print(f"Capacity used: {result.capacity_used_percent:.1f}%")
|
||||||
|
|
||||||
|
# === DECODE ===
|
||||||
|
print("\nDecoding message...")
|
||||||
|
stego_image = output_path.read_bytes()
|
||||||
|
|
||||||
|
decoded = stegasoo.decode(
|
||||||
|
stego_image=stego_image,
|
||||||
|
reference_photo=reference_photo,
|
||||||
|
passphrase=passphrase,
|
||||||
|
pin=pin,
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Decoded message: {decoded.message}")
|
||||||
|
print(f"Message type: {decoded.payload_type}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
72
examples/channel_keys.py
Normal file
72
examples/channel_keys.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Channel Keys Example
|
||||||
|
|
||||||
|
Channel keys allow you to create private communication channels.
|
||||||
|
Only people with the same channel key can decode messages.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import stegasoo
|
||||||
|
from stegasoo.channel import generate_channel_key, get_channel_fingerprint
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Generate a channel key for your group
|
||||||
|
channel_key = generate_channel_key()
|
||||||
|
fingerprint = get_channel_fingerprint(channel_key)
|
||||||
|
|
||||||
|
print("=== Channel Key Generated ===")
|
||||||
|
print(f"Key: {channel_key}")
|
||||||
|
print(f"Fingerprint: {fingerprint}")
|
||||||
|
print("\nShare this key securely with your group members!")
|
||||||
|
print("-" * 40)
|
||||||
|
|
||||||
|
# Load images
|
||||||
|
reference_photo = Path("my_secret_photo.png").read_bytes()
|
||||||
|
carrier_image = Path("carrier.png").read_bytes()
|
||||||
|
|
||||||
|
# Encode with channel key
|
||||||
|
print("\nEncoding message with channel key...")
|
||||||
|
result = stegasoo.encode(
|
||||||
|
message="Secret group message!",
|
||||||
|
reference_photo=reference_photo,
|
||||||
|
carrier_image=carrier_image,
|
||||||
|
passphrase="correct horse battery staple",
|
||||||
|
pin="123456",
|
||||||
|
channel_key=channel_key, # Add the channel key
|
||||||
|
)
|
||||||
|
|
||||||
|
stego_data = result.stego_image
|
||||||
|
print(f"Encoded successfully!")
|
||||||
|
|
||||||
|
# Decode with correct channel key
|
||||||
|
print("\nDecoding with correct channel key...")
|
||||||
|
decoded = stegasoo.decode(
|
||||||
|
stego_image=stego_data,
|
||||||
|
reference_photo=reference_photo,
|
||||||
|
passphrase="correct horse battery staple",
|
||||||
|
pin="123456",
|
||||||
|
channel_key=channel_key, # Same channel key
|
||||||
|
)
|
||||||
|
print(f"Message: {decoded.message}")
|
||||||
|
|
||||||
|
# Try to decode with wrong channel key
|
||||||
|
print("\nTrying to decode with wrong channel key...")
|
||||||
|
wrong_key = generate_channel_key()
|
||||||
|
try:
|
||||||
|
stegasoo.decode(
|
||||||
|
stego_image=stego_data,
|
||||||
|
reference_photo=reference_photo,
|
||||||
|
passphrase="correct horse battery staple",
|
||||||
|
pin="123456",
|
||||||
|
channel_key=wrong_key, # Different channel key
|
||||||
|
)
|
||||||
|
print("ERROR: Should have failed!")
|
||||||
|
except (stegasoo.DecryptionError, stegasoo.ExtractionError):
|
||||||
|
print("Correctly rejected - wrong channel key!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
78
examples/embed_file.py
Normal file
78
examples/embed_file.py
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
File Embedding Example
|
||||||
|
|
||||||
|
This example demonstrates how to embed a file (like a document or image)
|
||||||
|
inside a carrier image using Stegasoo.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import stegasoo
|
||||||
|
from stegasoo.models import FilePayload
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Load images
|
||||||
|
reference_photo = Path("my_secret_photo.png").read_bytes()
|
||||||
|
carrier_image = Path("carrier.png").read_bytes()
|
||||||
|
|
||||||
|
# Load the file to embed
|
||||||
|
secret_file = Path("secret_document.pdf")
|
||||||
|
file_data = secret_file.read_bytes()
|
||||||
|
|
||||||
|
# Create a FilePayload
|
||||||
|
payload = FilePayload(
|
||||||
|
filename=secret_file.name,
|
||||||
|
data=file_data,
|
||||||
|
mime_type="application/pdf",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Credentials
|
||||||
|
passphrase = "correct horse battery staple"
|
||||||
|
pin = "123456"
|
||||||
|
|
||||||
|
# Check capacity first
|
||||||
|
capacity = stegasoo.calculate_capacity(carrier_image)
|
||||||
|
print(f"Carrier capacity: {capacity['capacity_bytes']:,} bytes")
|
||||||
|
print(f"File size: {len(file_data):,} bytes")
|
||||||
|
|
||||||
|
if len(file_data) > capacity["capacity_bytes"]:
|
||||||
|
print("Error: File too large for this carrier!")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Encode the file
|
||||||
|
print("\nEmbedding file...")
|
||||||
|
result = stegasoo.encode(
|
||||||
|
file_payload=payload,
|
||||||
|
reference_photo=reference_photo,
|
||||||
|
carrier_image=carrier_image,
|
||||||
|
passphrase=passphrase,
|
||||||
|
pin=pin,
|
||||||
|
)
|
||||||
|
|
||||||
|
output_path = Path(f"contains_file_{result.suggested_filename}")
|
||||||
|
output_path.write_bytes(result.stego_image)
|
||||||
|
print(f"Saved to: {output_path}")
|
||||||
|
|
||||||
|
# Decode and extract the file
|
||||||
|
print("\nExtracting file...")
|
||||||
|
decoded = stegasoo.decode(
|
||||||
|
stego_image=output_path.read_bytes(),
|
||||||
|
reference_photo=reference_photo,
|
||||||
|
passphrase=passphrase,
|
||||||
|
pin=pin,
|
||||||
|
)
|
||||||
|
|
||||||
|
if decoded.payload_type == "file":
|
||||||
|
extracted_path = Path(f"extracted_{decoded.filename}")
|
||||||
|
extracted_path.write_bytes(decoded.file_data)
|
||||||
|
print(f"Extracted: {extracted_path}")
|
||||||
|
print(f"Original filename: {decoded.filename}")
|
||||||
|
print(f"MIME type: {decoded.mime_type}")
|
||||||
|
else:
|
||||||
|
print(f"Unexpected payload type: {decoded.payload_type}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
0
src/stegasoo/py.typed
Normal file
0
src/stegasoo/py.typed
Normal file
Reference in New Issue
Block a user