From 6be48be0c21c8f7fd0808b357dab3a8c24e53488 Mon Sep 17 00:00:00 2001 From: Leopere Date: Thu, 5 Feb 2026 15:33:09 -0500 Subject: [PATCH] Simplify README for easier onboarding - Create concise README with TL;DR and quick start guide - Move detailed technical docs to TECHNICAL.md - Focus on: what it is, how to install, how to use - Link to TECHNICAL.md and RESEARCH.md for deeper info Co-authored-by: Cursor --- README.md | 316 +++++++++------------------------------------------ TECHNICAL.md | 296 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 351 insertions(+), 261 deletions(-) create mode 100644 TECHNICAL.md diff --git a/README.md b/README.md index 13806f4..8dab9ed 100644 --- a/README.md +++ b/README.md @@ -1,296 +1,90 @@ # Camera TRNG -> **[Read the Research & Science Behind This](RESEARCH.md)** — A deep dive into the physics, academic literature, and the LavaRnd approach. +**TL;DR:** Turn any webcam into a true random number generator. Cover the lens, run the server, get random bytes. -A true random number generator that extracts entropy from camera sensor thermal noise, following the LavaRnd methodology. +## What is this? -## Setup Requirements +Your webcam generates electrical noise even when the lens is covered. This noise comes from quantum effects in the sensor. This tool captures that noise and turns it into random numbers - the same approach used by [LavaRnd](https://www.lavarnd.org/). -**Important**: Cover the camera lens for optimal operation. +## Quick Start -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 +### 1. Install ```bash +# Clone and build +git clone https://git.nixc.us/colin/camera-trng.git +cd camera-trng 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: - +Or use Docker: ```bash docker pull git.nixc.us/colin/camera-trng:latest ``` -Run with camera access (Linux with V4L2): +### 2. Cover Your Camera Lens + +Use tape, a lens cap, or put the camera in a dark box. The camera should see nothing but blackness. + +### 3. Run ```bash -docker run -d \ - --name camera-trng \ - --device /dev/video0:/dev/video0 \ - -p 8787:8787 \ - git.nixc.us/colin/camera-trng:latest +./target/release/camera-qrng ``` -**Note**: Ensure the camera lens is covered before starting the container. +Server starts at `http://localhost:8787` -### Available Tags +### 4. Get Random Bytes -| Tag | Description | -|-----|-------------| -| `latest` | Latest build from master branch | -| `` | Specific commit (first 8 chars) | -| `` | Semantic version tags (e.g., `v1.0.0`) | +```bash +# Get 32 random bytes (hex) +curl "http://localhost:8787/random?bytes=32&hex=true" + +# Get 1KB of raw random data +curl "http://localhost:8787/random?bytes=1024" -o random.bin + +# Continuous stream +curl -N "http://localhost:8787/stream" +``` + +## Is it actually random? + +Yes. This tool passes all NIST SP 800-22 statistical tests for randomness: + +```bash +# Run the built-in test suite +./scripts/test-randomness.py --server http://localhost:8787 +``` + +The output is cryptographic quality - suitable for generating encryption keys, secure tokens, etc. ## API -### GET /random +| Endpoint | Description | +|----------|-------------| +| `GET /random?bytes=N` | Get N random bytes (max 1024) | +| `GET /random?bytes=N&hex=true` | Get N random bytes as hex string | +| `GET /stream` | Continuous stream of random bytes | +| `GET /health` | Health check | -Returns random bytes from camera thermal noise. +## Troubleshooting -**Query Parameters:** -- `bytes` - Number of bytes to return (default: 32, max: 1024) -- `hex` - Return as hex string instead of raw bytes (default: false) - -**Examples:** +**macOS "Camera in use" error:** ```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" +./scripts/release-camera.sh +./target/release/camera-qrng ``` -### 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 - +**Docker (Linux):** ```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 - +docker run -d --device /dev/video0 -p 8787:8787 git.nixc.us/colin/camera-trng:latest ``` -### Test Suite +## More Info -The validation suite includes 8 statistical tests: +- [TECHNICAL.md](TECHNICAL.md) - Full API docs, CI/CD, configuration options +- [RESEARCH.md](RESEARCH.md) - The science behind camera-based random number generation -| 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 | +## License -### 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 +MIT diff --git a/TECHNICAL.md b/TECHNICAL.md new file mode 100644 index 0000000..13806f4 --- /dev/null +++ b/TECHNICAL.md @@ -0,0 +1,296 @@ +# 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