# Camera TRNG > **[Read the Research & Science Behind This](RESEARCH.md)** — A deep dive into the physics, academic literature, and the LavaRnd approach. A true random number generator that extracts entropy from camera sensor thermal noise, following the LavaRnd methodology. ## Setup Requirements **Important**: Cover the camera lens for optimal operation. 1. **Cover the lens**: Use the lens cap, opaque tape, or place the camera in a light-proof enclosure 2. **Verify darkness**: The camera should capture pure black frames 3. **Run the service**: Gain and brightness are automatically maximized This approach (pioneered by the LavaRnd project) isolates pure thermal noise from the sensor, eliminating any scene-correlated data and providing a simpler security model. ## How It Works With the lens covered, camera sensors produce noise from thermal electron activity and dark current. This service: 1. Opens the camera and maximizes gain/brightness settings 2. Captures frames of pure sensor noise (no light = no scene data) 3. Extracts the 2 LSBs from each pixel (highest entropy density) 4. Hashes the LSBs with SHA-256 to condition the output 5. Mixes in timing entropy for additional randomness ## Build ```bash cargo build --release ``` ## Run ```bash ./target/release/camera-trng # Or set a custom port PORT=9000 ./target/release/camera-trng Use the camera at **max resolution** (and highest frame rate): ```bash CAMERA_MAX_RESOLUTION=1 cargo run ``` **macOS — camera in use ("Lock Rejected")?** Run once to release the webcam, then start the server: ```bash ./scripts/release-camera.sh # may prompt for sudo password cargo run ``` ### Streaming random (multiple terminals) To see a stream of random in the terminal and verify each stream is unique: - **One stream:** `./scripts/stream-random.sh 0` (infinite; Ctrl+C to stop) - **Several streams in different terminals** (each gets different random; never the same): - Terminal 1: `./scripts/stream-random.sh "Stream-1" 0` - Terminal 2: `./scripts/stream-random.sh "Stream-2" 0` - Terminal 3: `./scripts/stream-random.sh "Stream-3" 0` - **Quick demo (3 streams, 5 lines each, verify no duplicates):** `./scripts/stream-demo.sh 5` ## Docker Pull the pre-built image: ```bash docker pull git.nixc.us/colin/camera-trng:latest ``` Run with camera access (Linux with V4L2): ```bash docker run -d \ --name camera-trng \ --device /dev/video0:/dev/video0 \ -p 8787:8787 \ git.nixc.us/colin/camera-trng:latest ``` **Note**: Ensure the camera lens is covered before starting the container. ### Available Tags | Tag | Description | |-----|-------------| | `latest` | Latest build from master branch | | `` | Specific commit (first 8 chars) | | `` | Semantic version tags (e.g., `v1.0.0`) | ## API ### GET /random Returns random bytes from camera thermal 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:** ```bash # 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) ## Randomness Validation A built-in test suite validates the statistical quality of generated random data. ### Quick Test ```bash # Test against running server (fetches 1MB) ./scripts/test-randomness.py --server http://127.0.0.1:8787 # Test a file ./scripts/test-randomness.py /path/to/random.bin # Test from stdin curl -s http://127.0.0.1:8787/random?bytes=1048576 | ./scripts/test-randomness.py - ``` ### Test Suite The validation suite includes 8 statistical tests: | Test | Description | Pass Criteria | |------|-------------|---------------| | Shannon Entropy | Information density | >7.9 bits/byte | | Chi-Square | Distribution uniformity | 200-330 (df=255) | | Arithmetic Mean | Average byte value | 126-129 | | Monte Carlo Pi | Geometric randomness | <1% error | | Serial Correlation | Sequential independence | \|r\| < 0.01 | | Byte Coverage | Value distribution | 256/256 present | | Bit Balance | Binary distribution | 49-51% ones | | Longest Run | Pattern detection | <25 bits | ### Example Output ``` ======================================================= CAMERA QRNG RANDOMNESS VALIDATION ======================================================= Sample size: 1,048,576 bytes (1.00 MB) 1. Shannon Entropy: 7.999796 bits/byte [PASS] 2. Chi-Square Test: 297.12 [PASS] 3. Arithmetic Mean: 127.5829 [PASS] 4. Monte Carlo Pi: 3.155151 [PASS] 5. Serial Correlation: 0.000235 [PASS] 6. Byte Coverage: 256/256 [PASS] 7. Bit Balance: 50.00% ones [PASS] 8. Longest Run (10KB): 19 bits [PASS] RESULTS: 8/8 tests passed VERDICT: EXCELLENT - All tests passed! ``` ### External Test Suites For more rigorous validation, the output also passes industry-standard test suites: - **NIST SP 800-22**: 15 statistical tests (official NIST standard) - **Dieharder**: 100+ statistical tests - **TestU01**: Academic test library (BigCrush) - **ENT**: Entropy analysis tool ```bash # Using dieharder (if installed) curl -s http://127.0.0.1:8787/random?bytes=10485760 | dieharder -a -g 200 # Using rngtest curl -s http://127.0.0.1:8787/random?bytes=2500000 | rngtest ``` ## 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 `latest` and `` - **On version tag**: Tags `` and `latest` ### 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: ```bash # macOS cargo build --release # Windows (requires MSVC toolchain) cargo build --release ``` ### Local Docker Build ```bash # Build locally docker build -t camera-trng:local . # Test locally (requires camera device with lens covered) docker run --rm --device /dev/video0 -p 8787:8787 camera-trng:local ``` ## Security Notes This implementation follows the LavaRnd approach for thermal noise extraction: - **Cover the lens**: Required for the intended security model - **Gain maximized**: Software automatically configures camera for maximum noise amplification - **No scene data**: With lens covered, there is no side-channel information leakage - **SHA-256 conditioning**: Removes any bias and ensures uniform distribution For high-security cryptographic applications, consider: - Using dedicated hardware RNGs (HSMs) - Mixing with system entropy (`/dev/urandom`) - Verifying the camera is properly covered before deployment