openadp-ocrypt 0.1.2

Rust SDK for OpenADP - Distributed secret sharing and advanced data protection
Documentation
# OpenADP Rust SDK

A complete Rust implementation of the OpenADP (Open Advanced Data Protection) distributed secret sharing system, designed to protect against nation-state attacks.

## Features

- **Ed25519 elliptic curve operations** with point compression/decompression
- **Shamir secret sharing** with threshold recovery
- **Noise-NK protocol** for secure server communication
- **JSON-RPC 2.0 API** with multi-server support
- **Cross-language compatibility** with Go and Python implementations
- **High-level key generation API** for file encryption
- **Simple ocrypt API** for password hashing replacement
- **Automatic server discovery** from registry
- **Load balancing** across multiple servers
- **Guess limiting** and rate limiting protection
- **Two-phase commit** backup refresh

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
openadp-ocrypt = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
```

## Quick Start

### High-Level Key Generation API

```rust
use openadp_ocrypt::{generate_encryption_key, recover_encryption_key, get_servers};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Get live servers from registry
    let servers = get_servers("").await?;
    
    // Generate encryption key with distributed backup
    let result = generate_encryption_key(
        "document.pdf",
        "secure_password",
        "user@example.com",
        10, // max_guesses
        0,  // expiration (0 = never)
        servers,
    ).await?;
    
    if let Some(key) = result.encryption_key {
        println!("Generated {}-byte encryption key", key.len());
        
        // Later: recover the key
        let recovered = recover_encryption_key(
            "document.pdf",
            "secure_password", 
            "user@example.com",
            result.server_infos.unwrap(),
            result.threshold.unwrap(),
            result.auth_codes.unwrap(),
        ).await?;
        
        if let Some(recovered_key) = recovered.encryption_key {
            assert_eq!(key, recovered_key);
            println!("Successfully recovered key!");
        }
    }
    
    Ok(())
}
```

### Simple Ocrypt API (Password Hashing Replacement)

Replace bcrypt, scrypt, Argon2, or PBKDF2 with distributed threshold cryptography:

```rust
use openadp_ocrypt::{register, recover};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Protect a Stripe API key (example - not a real key)
    let api_key = b"sk_live_EXAMPLE_NOT_REAL_KEY_FOR_DEMO_PURPOSES_ONLY_123456789";
    
    // Register with distributed protection
    let metadata = register(
        "payment_service",    // user_id
        "ecommerce_platform", // app_id
        api_key,              // long_term_secret
        "admin_pin_2024",     // pin
        5,                    // max_guesses
        "",                   // servers_url (empty = default registry)
    ).await?;
    
    // Store metadata with user record in database
    println!("Store metadata ({} bytes) with user record", metadata.len());
    
    // Later: recover the API key with automatic backup refresh
    let (recovered_key, remaining_guesses, updated_metadata) = recover(
        &metadata,
        "admin_pin_2024",
        "",
    ).await?;
    
    assert_eq!(api_key, recovered_key.as_slice());
    println!("Recovered API key! Remaining guesses: {}", remaining_guesses);
    
    // Update database if backup was refreshed
    if updated_metadata != metadata {
        println!("Update database with refreshed metadata");
    }
    
    Ok(())
}
```

## Core Components

### Cryptographic Operations

```rust
use openadp_ocrypt::{hash_to_point, point_compress, derive_enc_key};

// Hash-to-point function H(uid, did, bid, pin)
let point = hash_to_point(
    b"user@example.com",
    b"device123", 
    b"backup456",
    b"pin"
)?;

// Compress point to 32 bytes
let compressed = point_compress(&point)?;

// Derive encryption key from point
let key = derive_enc_key(&point)?;
```

### Client Communication

```rust
use openadp_ocrypt::{OpenADPClient, EncryptedOpenADPClient, ServerInfo};

// Basic client (no encryption)
let client = OpenADPClient::new("https://server.openadp.org:8443".to_string(), 30);
client.ping().await?;

// Encrypted client with Noise-NK
let public_key = Some(parse_server_public_key("ed25519:..."))?;
let mut encrypted_client = EncryptedOpenADPClient::new(
    "https://secure.openadp.org:8443".to_string(),
    public_key,
    30
);

// Get server information
let info = encrypted_client.get_server_info().await?;
println!("Server version: {}", info.server_version);
```

### Server Discovery

```rust
use openadp_ocrypt::{get_servers, discover_servers};

// Get servers from default registry
let servers = get_servers("").await?;

// Use custom registry
let servers = get_servers("https://custom.registry.com/servers.json").await?;

// Discover with fallback
let servers = discover_servers("").await?; // Falls back to hardcoded servers
```

## Use Cases

### 1. API Key Protection

Replace database storage of API keys with distributed protection:

```rust
// Instead of storing API keys in database:
// database.store("user123", "stripe_key", "sk_live_...");

// Use OpenADP distributed protection:
let metadata = register("user123", "stripe", api_key, user_pin, 5, "").await?;
database.store("user123", "stripe_metadata", &metadata);

// Recovery:
let metadata = database.get("user123", "stripe_metadata");
let (api_key, _, updated_metadata) = recover(&metadata, user_pin, "").await?;
```

### 2. File Encryption

Generate encryption keys with distributed backup:

```rust
let servers = get_servers("").await?;
let result = generate_encryption_key(
    "financial_report.pdf",
    "user_password",
    "alice@company.com", 
    10, 0, servers
).await?;

// Use key for AES-256-GCM file encryption
let key = result.encryption_key.unwrap();
encrypt_file("financial_report.pdf", &key)?;
```

### 3. Private Key Protection

Protect Ed25519/RSA private keys:

```rust
let private_key = generate_ed25519_key();
let metadata = register(
    "alice@company.com",
    "document_signing",
    &private_key.to_bytes(),
    "secure_pin",
    10,
    ""
).await?;

// Later: recover for signing
let (recovered_key, _, _) = recover(&metadata, "secure_pin", "").await?;
let signing_key = SigningKey::from_bytes(&recovered_key)?;
```

### 4. Database Encryption

Protect database master keys:

```rust
let master_key = generate_random_key();
let metadata = register(
    "database_service",
    "production_db",
    &master_key,
    "db_admin_pin",
    3, // Strict limit for production
    ""
).await?;

// Store metadata in secure configuration
config.set("db_master_key_metadata", metadata);
```

## Architecture

### Distributed Secret Sharing

1. **Secret Generation**: Random 256-bit secret `s`
2. **Point Computation**: `U = H(uid, did, bid, pin)` 
3. **Shamir Sharing**: Split `s` into `n` shares with `t` threshold
4. **Server Registration**: Store shares `(i, s_i, U)` on distributed servers
5. **Key Derivation**: Final key = `derive_key(s * U)`

### Threshold Recovery

1. **Point Computation**: `U = H(uid, did, bid, pin)`
2. **Share Recovery**: Retrieve `t` shares from servers
3. **Secret Reconstruction**: Lagrange interpolation to recover `s`
4. **Key Derivation**: Compute final key from `s * U`

### Security Properties

- **Nation-state resistant**: Requires compromise of `t-of-n` servers
- **Guess limiting**: Wrong PIN attempts tracked across all servers
- **Forward security**: Backup refresh changes all server state
- **No single point of failure**: Distributed across multiple jurisdictions

## Error Handling

```rust
use openadp_ocrypt::{OpenADPError, Result};

match register("user", "app", secret, "pin", 10, "").await {
    Ok(metadata) => println!("Success!"),
    Err(OpenADPError::Network(e)) => println!("Network error: {}", e),
    Err(OpenADPError::NoServers) => println!("No servers available"),
    Err(OpenADPError::InvalidInput(msg)) => println!("Invalid input: {}", msg),
    Err(OpenADPError::Authentication(msg)) => println!("Auth failed: {}", msg),
    Err(e) => println!("Other error: {}", e),
}
```

## Testing

Run the test suite:

```bash
cargo test
```

Run examples:

```bash
# Basic usage
cargo run --example basic_usage

# API key protection
cargo run --example api_key_protection

# Full OpenADP demo
cargo run --example full_openadp_demo
```

## Cross-Language Compatibility

The Rust SDK is fully compatible with:

- **Go SDK**: `../ocrypt` (separate git repository)
- **Python SDK**: `../python/openadp/`
- **JavaScript SDK**: `../javascript/openadp/`

All implementations use the same:
- Cryptographic primitives (Ed25519, SHA-256, HKDF)
- JSON-RPC 2.0 protocol
- Server registry format
- Metadata structure

## Production Deployment

### Server Configuration

```rust
// Use custom server registry for production
let servers = get_servers("https://your-registry.com/servers.json").await?;

// Or specify servers directly
let servers = vec![
    ServerInfo {
        url: "https://server1.your-domain.com:8443".to_string(),
        public_key: "ed25519:...".to_string(),
        country: "US".to_string(),
    },
    // ... more servers
];
```

### Security Considerations

1. **Server Selection**: Use servers in different jurisdictions
2. **Threshold Setting**: Recommend `t = ⌊n/2⌋ + 1` for `n` servers
3. **Guess Limits**: Use low limits (3-10) for production secrets
4. **Backup Refresh**: Implement automatic refresh on recovery
5. **Key Rotation**: Periodically re-register secrets with new backup IDs

### Monitoring

```rust
// Monitor server health
for server in &servers {
    match client.ping().await {
        Ok(_) => println!("✅ {} is healthy", server.url),
        Err(e) => println!("❌ {} is down: {}", server.url, e),
    }
}

// Check remaining guesses
let (_, remaining, _) = recover(&metadata, pin, "").await?;
if remaining < 3 {
    alert!("Low remaining guesses: {}", remaining);
}
```

## Contributing

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass: `cargo test`
5. Submit a pull request

## License

Licensed under either of:

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE)
- MIT License ([LICENSE-MIT]LICENSE-MIT)

at your option.

## Security

For security issues, please email security@openadp.org instead of using the issue tracker.