- Use scipy.fft.dctn/idctn with axes=(1,2) to process 500 blocks at once
- Extract bits in batch using numpy array indexing
- Vectorized QIM embedding with array operations
- Tests pass, roundtrip verified
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add reedsolo>=1.7.0 to Dockerfile and Dockerfile.base for DCT
error correction (fixes DCT decode failures in container)
- Update all documentation to use docker/docker-compose.yml paths
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move Dockerfile, Dockerfile.base, docker-compose.yml to docker/
- Update docker-compose.yml with correct context paths
- Update scripts/build.sh to use new paths
- Update DOCKER_QUICKSTART.md with new commands
- Add scripts/build.sh to tracked files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Run on Pi after from-source build to create:
stegasoo-rpi-runtime-env-arm64.tar.zst (~50-60MB)
Contains pyenv + Python 3.12 + venv with all deps.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add grid icon to LSB button to match DCT soundwave icon
- Add divider between mode and output options (hidden on mobile)
- Wraps cleanly on small screens
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows ABCD-••••-3456 instead of ABCD...3456 to indicate
the key is longer and has been redacted.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Convert DCT/LSB (encode) and Auto/LSB/DCT (decode) to use
Bootstrap btn-group style matching Color/Gray and JPEG/PNG.
Better mobile layout - all options on one line.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Display ABCD...3456 instead of full masked fingerprint.
Full fingerprint still visible in tooltip on hover.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Step 3 now offers three choices:
- Skip (public mode)
- Generate new key
- Enter existing key (for joining team deployments)
Validates entered keys using Python channel module before accepting.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove pv (showed read progress, not write progress)
- Use dd status=progress for actual write progress
- Reduce block size to 1M (better for slow SD cards)
- Remove conv=fsync (sync at end instead, faster)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Run fsck.vfat on boot partition and e2fsck on root partition
after flashing to catch and fix any corruption.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
resize2fs only fills the partition. Need growpart first to
expand the partition to fill the disk, then resize2fs to
expand the filesystem.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of a hidden systemd service, expand the filesystem
visibly during the first-boot wizard so users can see it
happening.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
rpi-imager was doing something that prevented the auto-expand
service from working. Simplify to just dd with optional pv
for progress.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move the partition wipe to after user types 'yes' so they can
still abort without having already wiped the device.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create a systemd oneshot service that expands the rootfs on first boot
after flashing. The service self-destructs after running.
This ensures release images fill the SD card while keeping the
download size small (16GB shrunk image).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The shrinking is only for faster image downloads. After flashing,
the image should auto-expand to fill the SD card.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove --compress/--algorithm CLI options (not wired to encode flow)
- Add man page installation to rpi/setup.sh
- Document man page installation in README.md and CLI.md
- Update man page to remove compression options
Compression will be properly implemented in v4.1.8.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The color codes weren't displaying properly in all terminal
environments. Keep it simple with plain text.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use click.style() with bright_yellow and color=True to ensure
the channel fingerprint displays in color across different
terminal environments.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The function was trying to format encrypted keys directly,
causing ValueError when reading ENC: prefixed stored keys.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Channel keys saved to config files are now encrypted using the
machine's identity (/etc/machine-id), so:
- Not stored in plaintext
- Tied to specific machine (can't copy file to another device)
- Legacy plaintext keys still work (auto-detected)
Changes:
- Added _encrypt_for_storage() and _decrypt_from_storage()
- set_channel_key() now encrypts before writing
- get_channel_key() decrypts when reading (handles legacy plaintext)
- Pi setup saves encrypted key to ~/.stegasoo/channel.key
- CLI `stegasoo info` now shows channel status correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
No more browser warnings! mkcert creates locally-trusted certs.
Pi Setup:
- Auto-install mkcert during setup
- Generate trusted certs when HTTPS enabled
- Copy CA to /static/ca/rootCA.pem for easy device setup
- New devices can download CA via HTTP and install it
Docker:
- docker-entrypoint.sh checks for mkcert, falls back to openssl
- Shows instructions for CA distribution to other devices
Scripts:
- Added setup-trusted-certs.sh helper for local dev
- Installs mkcert, generates certs, shows device setup instructions
To trust on new devices:
1. Download: http://stegasoo.local/static/ca/rootCA.pem
2. Install as trusted CA in browser/OS
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Docker:
- HTTPS enabled by default (generates self-signed cert)
- Added docker-entrypoint.sh for SSL cert generation
- Gunicorn now starts with --certfile/--keyfile when HTTPS enabled
- Install curl/openssl in web container for healthcheck and certs
- Updated docs to reflect HTTPS default
Smoke Test:
- Moved from rpi/ to scripts/ (works for Pi, Docker, and dev)
- Updated header and examples
- Added to .gitignore exceptions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comprehensive test suite for Pi deployments:
- Connectivity check
- Auto-setup if first boot (admin/stegasoo)
- Login and session handling
- All page accessibility
- LSB encode/decode round trip
- DCT encode/decode round trip
- Tools API (capacity, EXIF)
Usage: ./rpi/smoke-test.sh [host] [port] [user] [pass]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove duplicate qr-crop-container styles from encode/decode templates
- Use only qr-scan-container from style.css (flex centering + object-fit)
- Fix rsaQrSection to use align-items: center for horizontal centering
- Darken channel key fingerprint in header (#f0c674 → #c9a860)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>