proofmode 0.8.0

Capture, share, and preserve verifiable photos and videos
# ProofMode

Rust implementation of [Guardian Project's](https://guardianproject.info) ProofMode system for capturing, sharing, and preserving verifiable photos and videos.

ProofMode generates cryptographic proof bundles for media files -- including PGP signatures, SHA-256 hashes, metadata records, and optional timestamps -- and can verify those bundles later to assess authenticity. It also provides a `sign` module for server-side C2PA signing with device attestation, used by [ProofSign](https://gitlab.com/guardianproject/proofmode/proofsign-rust).

## Features

- **Verify** media authenticity via C2PA manifests, PGP signatures, OpenTimestamps, and EXIF metadata
- **Generate** cryptographic proof bundles with device, location, and network metadata
- **Sign** data with ES256 keys, generate certificates, and build C2PA configurations
- **Attest** device identity via Apple App Attest and Google Play Integrity
- **Cross-platform**: native CLI, WebAssembly, Android (AAR), iOS (XCFramework), Python, Ruby, Docker

## Quick start

```sh
# Verify a media file and its proof bundle
proofmode check -f photo.jpg

# Verify from a URL
proofmode check -u https://example.com/photo.jpg

# Generate a proof bundle
proofmode generate -f photo.jpg -s ./proofs -e user@example.com

# Generate an ES256 signing key pair
proofmode sign generate-key -o ./keys

# Sign data with a private key
proofmode sign data -k ./keys/private.pem -f document.bin -p ios
```

## CLI commands

### check

Verifies media files through multiple verification methods.

```
proofmode check [OPTIONS]
  -f, --file <FILE>...     Files to check
  -d, --dir <DIR>...       Directories to check
  -u, --url <URL>...       URLs to check
  -c, --cid <CID>...       IPFS CIDs to check
  -o, --output-file <FILE> JSON output file
```

The verification pipeline runs four stages:

1. **Preprocessing** -- extract and prepare files (ZIP archives, local paths, URLs, IPFS CIDs)
2. **Integrity** -- verify C2PA manifests, PGP signatures, OpenTimestamps, EXIF data
3. **Consistency** -- check coherence across related files in a proof bundle
4. **Synchrony** -- validate temporal relationships between proofs

### generate

Creates cryptographic proof bundles for media files.

```
proofmode generate [OPTIONS]
  -f, --file <FILE>...     Files to generate proofs for
  -d, --dir <DIR>...       Directories to process
  -s, --storage <DIR>      Storage directory (default: ./proofmode)
  -e, --email <EMAIL>      Email for PGP key
  -p, --passphrase <PASS>  PGP key passphrase
```

Output files per media item: `.proof.csv`, `.proof.json`, `.asc` (PGP signature).

### sign

Certificate and data signing operations.

```
proofmode sign generate-key -o <DIR>                         # Generate ES256 key pair
proofmode sign data -k <KEY> -f <FILE> -p ios                # Sign data
proofmode sign verify -k <KEY> -f <FILE> -s <SIG> -p ios     # Verify signature
proofmode sign generate-csr -s <SAN>... -o <PATH>            # Generate CSR
proofmode sign sign-csr -c <CSR> -d <DOMAIN> -o <PATH>      # Sign CSR
```

## Library usage

Add to your `Cargo.toml`:

```toml
[dependencies]
proofmode = { version = "0.7", default-features = false }
```

### Verify files

```rust
use proofmode::check_files;

let results = check_files(
    &["photo.jpg".to_string()],
    Some("output.json"),
    |progress| println!("{}", progress),
).await?;
```

### Generate proofs

```rust
use proofmode::generate_proof_from_file;

generate_proof_from_file(
    "/path/to/photo.jpg",
    "/path/to/storage",
    "user@example.com",
    "passphrase",
    |progress| println!("{}", progress),
)?;
```

### Sign module

The `sign` feature provides traits and implementations for ES256 signing, device attestation, and C2PA configuration. This is the foundation that ProofSign builds on for server-side signing.

```rust
use proofmode::sign::{LocalES256Signer, Signer, Platform};

// Create a signer with random keys (for testing)
let signer = LocalES256Signer::random();

// Or load from PEM files
let signer = LocalES256Signer::new(
    Some(Path::new("ios_private.pem")),
    Some(Path::new("android_private.pem")),
)?;

let signature = signer.sign(&Platform::Ios, b"data to sign")?;
signer.verify(&Platform::Ios, b"data to sign", &signature)?;
```

Key exports from `proofmode::sign`:

| Item | Description |
|---|---|
| `Signer` | Synchronous signing trait (`sign`, `verify`, `public_key`) |
| `AsyncSigner` | Async signing trait for remote/KMS signers |
| `LocalES256Signer` | P-256 ECDSA signer with per-platform key pairs |
| `Platform` | `Ios` or `Android` |
| `PlayIntegrityVerifier` | Google Play Integrity token verification |
| `IntegrityStore` | Trait for Play Integrity storage (implement with your DB) |
| `DeviceStore` | Trait for App Attest device storage (implement with your DB) |
| `verify_device_assertion()` | Verify an iOS App Attest assertion |
| `verify_android_device_signature()` | Verify an Android cryptographic device signature |
| `build_c2pa_configuration()` | Build C2PA config with cert chain and signing URL |
| `cert::sign_csr()` / `cert::generate_csr()` | Certificate operations |

## Feature flags

| Feature | Default | Description |
|---|---|---|
| `clap` | yes | CLI argument parsing |
| `reqwest` | yes | HTTP client for URL checking and remote operations |
| `sequoia-openpgp` | yes | PGP signature verification and generation |
| `polars` | yes | Data analytics for verification results |
| `c2pa` | yes | C2PA manifest verification |
| `sign` | yes | ES256 signing, certificates, device attestation |
| `wasm` | no | WebAssembly support via wasm-bindgen |
| `uniffi` | no | Cross-language FFI bindings (base for mobile/python/ruby) |
| `mobile` | no | Mobile platform support |
| `python` | no | Python bindings via UniFFI |
| `ruby` | no | Ruby bindings via UniFFI |

## Platform builds

### Native CLI

```sh
cargo build --release
./target/release/proofmode check -f photo.jpg
```

### Python

```sh
cargo make python-build
# or: maturin build --features python
```

### Ruby

```sh
./scripts/build_ruby_uniffi.sh
```

### WebAssembly

```sh
cargo make wasm-pack
# or: wasm-pack build --scope guardianproject -- --features wasm
```

### Android (AAR)

```sh
cargo make install-android-targets
cargo make build-android
cargo make create-aar
```

### iOS (XCFramework)

Requires macOS.

```sh
cargo make install-ios-targets
cargo make build-ios
cargo make create-xcframework
cargo make create-swift-package
```

### Docker

```sh
docker build -t proofmode .
docker run -v $(pwd):/data proofmode check -f /data/photo.jpg
```

## Project structure

```
src/
  main.rs                CLI entry point (check, generate, sign commands)
  lib.rs                 Library exports
  uniffi_wrapper.rs      Mobile platform bindings (uniffi feature)
  check/                 Verification pipeline
    mod.rs                 Public API (check_files, check_urls, check_cids)
    preprocess.rs          File extraction (ZIP, URL, IPFS)
    integrity.rs           C2PA, PGP, OTS, EXIF verification
    consistency.rs         Multi-file coherence checks
    synchrony.rs           Temporal relationship verification
    analytics.rs           Data analysis with polars
  generate/              Proof generation
    mod.rs                 Public API wrappers
    core.rs                ProofGenerator implementation
    native.rs              Native/CLI implementation
    wasm.rs                WASM-specific implementation
  sign/                  Server-side signing module (sign feature)
    mod.rs                 Public API and re-exports
    signer.rs              Signer and AsyncSigner traits
    es256.rs               LocalES256Signer (P-256 ECDSA)
    cert.rs                Certificate generation and CSR signing
    c2pa_config.rs         C2PA configuration builder
    types.rs               Platform, request/response types
    error.rs               SignError type
    app_attest/            iOS App Attest attestation and assertion verification
    play_integrity/        Android Play Integrity token verification
  crypto/                Cryptographic primitives
    hash.rs                SHA-256 hashing
    pgp.rs                 PGP key management and signing
  generate_types.rs      Data structures (ProofData, LocationData, DeviceData, etc.)
  generate_error.rs      Error types for proof generation
scripts/                 Build scripts per platform (android/, ios/, python, ruby)
examples/                Example apps (iOS, Android, web, Python, Ruby, Node.js)
tests/                   Integration and CLI tests
```

## Development

```sh
cargo build            # Debug build
cargo test             # Run tests
cargo fmt              # Format code
cargo clippy           # Lint
cargo make test        # Full test suite including integration tests
```

### Prerequisites

- Rust 1.70+
- cargo-make (`cargo install cargo-make`) for cross-platform builds
- Platform SDKs as needed (Android NDK, Xcode, etc.)

### Build everything

```sh
make setup             # One-time setup
make build             # Rust CLI
make wasm-pack         # WebAssembly
make mobile            # All mobile targets
make test              # Run tests
make help              # Show all commands
```

## Platform support

| Platform | Library | Application | Status |
|----------|---------|-------------|--------|
| Rust | Crate | CLI binary | Production |
| Python | UniFFI (pip) | CLI tool | Production |
| Ruby | UniFFI (gem) | CLI tool | Production |
| Docker | N/A | Container | Production |
| Android | AAR (Kotlin) | Example app | Testing |
| iOS | XCFramework (Swift) | Example app | Testing |
| WebAssembly | npm package | Next.js app | In development |
| Node.js | WASM module | CLI tool | In development |

## Documentation

- [Platform Structure]docs/PLATFORM_STRUCTURE.md -- architecture overview
- [CLI Documentation]CLI_DOCUMENTATION.md -- cross-platform CLI reference
- [Changelog]CHANGELOG.md -- version history

## License

Apache-2.0. See [LICENSE](LICENSE) for details.