| Crates.io | openadp-ocrypt |
| lib.rs | openadp-ocrypt |
| version | 0.1.3 |
| created_at | 2025-06-29 04:50:50.740742+00 |
| updated_at | 2025-07-01 09:52:38.141714+00 |
| description | Rust SDK for OpenADP - Distributed secret sharing and advanced data protection |
| homepage | https://openadp.org |
| repository | https://github.com/openadp/openadp |
| max_upload_size | |
| id | 1730347 |
| size | 293,582 |
A complete Rust implementation of the OpenADP (Open Advanced Data Protection) distributed secret sharing system, designed to protect against nation-state attacks.
Add this to your Cargo.toml:
[dependencies]
openadp-ocrypt = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
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(())
}
Replace bcrypt, scrypt, Argon2, or PBKDF2 with distributed threshold cryptography:
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(())
}
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)?;
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);
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
Replace database storage of API keys with distributed protection:
// 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?;
Generate encryption keys with distributed backup:
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)?;
Protect Ed25519/RSA private keys:
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)?;
Protect database master keys:
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);
sU = H(uid, did, bid, pin)s into n shares with t threshold(i, s_i, U) on distributed serversderive_key(s * U)U = H(uid, did, bid, pin)t shares from serversss * Ut-of-n serversuse 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),
}
Run the test suite:
cargo test
Run examples:
# 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
The Rust SDK is fully compatible with:
../ocrypt (separate git repository)../python/openadp/../javascript/openadp/All implementations use the same:
// 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
];
t = ⌊n/2⌋ + 1 for n servers// 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);
}
cargo testLicensed under either of:
at your option.
For security issues, please email security@openadp.org instead of using the issue tracker.