- Add FAKE_CAMERA=1 env var to use /dev/urandom instead of real camera for testing in environments without camera hardware (Docker, CI) - Add extract_entropy_fake() that simulates camera frames with random data - Add web UI (index.html) and MCP well-known endpoint - Add Dockerfile with multi-stage build for containerized deployment - Add OBS virtual camera scripts for testing with simulated noise input - Update Dockerfile to use rust:latest and add clang for bindgen |
||
|---|---|---|
| scripts | ||
| src | ||
| .gitignore | ||
| .woodpecker.yml | ||
| Cargo.lock | ||
| Cargo.toml | ||
| Dockerfile | ||
| README.md | ||
README.md
Camera TRNG
A minimal cross-platform true random number generator that extracts entropy from camera sensor noise.
How It Works
Camera sensors exhibit thermal noise and shot noise at the pixel level. This noise is most concentrated in the least significant bits (LSBs) of each pixel value. This service:
- Captures frames from the default camera at the lowest resolution
- Extracts the 2 LSBs from each pixel (where thermal/shot noise dominates)
- Hashes the LSBs with SHA-256 to whiten the data and remove any bias
- Mixes in timing entropy for additional randomness
Build
cargo build --release
Run
./target/release/camera-trng
# Or set a custom port
PORT=9000 ./target/release/camera-trng
Docker
Pull the pre-built image:
docker pull git.nixc.us/colin/camera-trng:latest
Run with camera access (Linux with V4L2):
docker run -d \
--name camera-trng \
--device /dev/video0:/dev/video0 \
-p 8787:8787 \
git.nixc.us/colin/camera-trng:latest
Available Tags
| Tag | Description |
|---|---|
latest |
Latest build from master branch |
<commit-sha> |
Specific commit (first 8 chars) |
<version> |
Semantic version tags (e.g., v1.0.0) |
API
GET /random
Returns random bytes from camera noise.
Query Parameters:
bytes- Number of bytes to return (default: 32, max: 1024)hex- Return as hex string instead of raw bytes (default: false)
Examples:
# Get 32 random bytes as hex
curl "http://localhost:8787/random?hex=true"
# Get 64 raw random bytes
curl "http://localhost:8787/random?bytes=64" -o random.bin
# Get 256 bytes as hex
curl "http://localhost:8787/random?bytes=256&hex=true"
GET /health
Returns ok if the server is running.
Rate Limiting
- Maximum 4 concurrent requests
- Maximum 1024 bytes per request
- Returns 429 Too Many Requests when overloaded
Cross-Platform Support
Uses nokhwa for camera access, supporting:
- macOS (AVFoundation)
- Windows (Media Foundation)
- Linux (V4L2)
CI/CD Pipeline
This project uses Woodpecker CI to automatically build, test, and deploy.
Pipeline Overview
┌─────────────────────────────────────────────────────────────────┐
│ Woodpecker CI │
├─────────────────────────────────────────────────────────────────┤
│ │
│ On Push/PR to master: │
│ ┌─────────┐ │
│ │ test │──┬──> build-linux-x86_64 ──> binary artifact │
│ └─────────┘ │ │
│ ├──> build-linux-aarch64 ──> binary artifact │
│ │ │
│ └──> build-image ──┬──> trivy-image (scan) │
│ └──> sbom-image (SBOM) │
│ │
│ Parallel checks: cargo-audit, trivy-fs, clippy, fmt-check │
│ │
└─────────────────────────────────────────────────────────────────┘
Build Artifacts
| Artifact | Architecture | Description |
|---|---|---|
camera-trng-linux-x86_64 |
x86_64 | Linux AMD64 binary |
camera-trng-linux-aarch64 |
aarch64 | Linux ARM64 binary (best-effort) |
| Docker Image | linux/amd64 | Container image |
Docker Image Registry
Images are pushed to: git.nixc.us/colin/camera-trng
- On push to master: Tags
latestand<commit-sha> - On version tag: Tags
<version>andlatest
Required Secrets
Configure these secrets in Woodpecker:
| Secret | Description |
|---|---|
REGISTRY_USER |
Username for git.nixc.us registry |
REGISTRY_PASSWORD |
Password/token for git.nixc.us registry |
DOCKER_REGISTRY_USER |
Docker Hub username (for base images) |
DOCKER_REGISTRY_PASSWORD |
Docker Hub password/token |
Security Scanning
The pipeline includes:
- cargo-audit: Scans Rust dependencies for known vulnerabilities
- trivy-fs: Scans filesystem and Cargo.lock for vulnerabilities
- trivy-image: Scans the built Docker image
- SBOM generation: Creates SPDX and CycloneDX SBOMs for dependencies
Cross-Compilation Notes
Linux x86_64: Fully supported, built natively on CI runners.
Linux aarch64: Best-effort cross-compilation. May fail due to native camera library dependencies (libv4l). For production ARM64 builds, consider using native ARM64 runners.
macOS/Windows: Not built in CI due to native camera library requirements. Build locally:
# macOS
cargo build --release
# Windows (requires MSVC toolchain)
cargo build --release
Local Docker Build
# Build locally
docker build -t camera-trng:local .
# Test locally (requires camera device)
docker run --rm --device /dev/video0 -p 8787:8787 camera-trng:local
Security Notes
This is intended for hobby/experimental use. For cryptographic applications:
- Consider mixing with system entropy (
/dev/urandom) - The quality of randomness depends on camera sensor characteristics
- Environmental factors (lighting, temperature) affect noise levels