saorsa-seal 0.1.3

Threshold sealing for group data in the Saorsa network
Documentation
//! # Threshold Sealing for Group Data in the Saorsa Network
//!
//! `saorsa-seal` provides threshold sealing capabilities for the Saorsa network,
//! combining threshold cryptography, forward error correction, and authenticated encryption
//! to create a robust distributed data protection system.
//!
//! ## Architecture Integration
//!
//! This crate leverages the Saorsa ecosystem:
//! - **[`saorsa-core`]**: Threshold cryptography and DHT abstraction
//! - **[`saorsa-fec`]**: Forward error correction and AEAD encryption  
//! - **[`saorsa-pqc`]**: Post-quantum cryptography
//!
//! ## Core Features
//!
//! - **Threshold Sealing**: Uses Shamir's Secret Sharing via [`saorsa-core`] for configurable threshold schemes
//! - **Forward Error Correction**: Reed-Solomon coding via [`saorsa-fec`] for fault tolerance
//! - **AEAD Encryption**: XChaCha20-Poly1305 content encryption via [`saorsa-fec::CryptoEngine`]
//! - **Post-Quantum Security**: ML-KEM-768 encryption via [`saorsa-pqc`]
//! - **Distributed Storage**: DHT abstraction from [`saorsa-core`] for decentralized storage
//! - **Verifiable Shares**: Feldman commitments for cryptographic share verification
//! - **Envelope Encryption**: Post-quantum recipient encryption using ML-KEM-768
//!
//! ## Quick Start
//!
//! ```rust
//! use saorsa_seal::{seal_bytes, open_bytes, SealPolicy, FecParams, EnvelopeKind, Recipient, RecipientId};
//! use std::collections::HashMap;
//! use std::sync::Mutex;
//!
//! // Simple DHT implementation for testing
//! #[derive(Debug)]
//! struct TestDht {
//!     storage: Mutex<HashMap<[u8; 32], Vec<u8>>>,
//! }
//!
//! impl TestDht {
//!     fn new() -> Self {
//!         Self { storage: Mutex::new(HashMap::new()) }
//!     }
//! }
//!
//! impl saorsa_seal::Dht for TestDht {
//!     fn put(&self, key: &[u8; 32], value: &[u8], _ttl: Option<u64>) -> anyhow::Result<()> {
//!         self.storage.lock().unwrap().insert(*key, value.to_vec());
//!         Ok(())
//!     }
//!
//!     fn get(&self, key: &[u8; 32]) -> anyhow::Result<Vec<u8>> {
//!         self.storage.lock().unwrap().get(key).cloned()
//!             .ok_or_else(|| anyhow::anyhow!("Key not found"))
//!     }
//! }
//!
//! #[tokio::main]
//! async fn main() -> anyhow::Result<()> {
//!     let dht = TestDht::new();
//!     let plaintext = b"Hello, Saorsa Network!";
//!
//!     // Create recipients (5 total, threshold of 3)
//!     let recipients: Vec<Recipient> = (0..5)
//!         .map(|i| Recipient {
//!             id: RecipientId::from_bytes(vec![i; 32]),
//!             public_key: None,
//!         })
//!         .collect();
//!
//!     // Configure sealing policy
//!     let policy = SealPolicy {
//!         n: 5, t: 3, recipients,
//!         fec: FecParams { data_shares: 3, parity_shares: 2, symbol_size: 1024 },
//!         envelope: EnvelopeKind::PostQuantum,
//!         aad: vec![],
//!     };
//!
//!     // Seal and recover data
//!     let summary = seal_bytes(plaintext, &policy, &dht).await?;
//!     // ... (recovery process)
//!     
//!     Ok(())
//! }
//! ```
//!
//! ## Features
//!
//! - **`std`** (default): Standard library support
//! - Post-quantum cryptography is always enabled via saorsa-pqc
//! - **`telemetry`**: Tracing and metrics support

// DHT trait for storage abstraction
pub trait Dht {
    fn put(&self, key: &[u8; 32], value: &[u8], ttl: Option<u64>) -> anyhow::Result<()>;
    fn get(&self, key: &[u8; 32]) -> anyhow::Result<Vec<u8>>;
}
pub use types::*;

// Main API functions
pub use api::{open_bytes, open_file, seal_bytes, seal_file};

pub mod aead;
pub mod api;
pub mod envelope;
pub mod types;

#[cfg(test)]
mod tests {
    use super::*;
    use std::collections::HashMap;
    use std::sync::Mutex;

    #[derive(Debug)]
    struct TestDht {
        storage: Mutex<HashMap<[u8; 32], Vec<u8>>>,
    }

    impl TestDht {
        fn new() -> Self {
            Self {
                storage: Mutex::new(HashMap::new()),
            }
        }
    }

    impl Dht for TestDht {
        fn put(&self, key: &[u8; 32], value: &[u8], _ttl: Option<u64>) -> anyhow::Result<()> {
            self.storage.lock().unwrap().insert(*key, value.to_vec());
            Ok(())
        }

        fn get(&self, key: &[u8; 32]) -> anyhow::Result<Vec<u8>> {
            self.storage
                .lock()
                .unwrap()
                .get(key)
                .cloned()
                .ok_or_else(|| anyhow::anyhow!("Key not found"))
        }
    }

    #[tokio::test]
    async fn test_basic_seal_and_open() {
        let dht = TestDht::new();
        let plaintext = b"Hello, Saorsa Network!";

        let recipients: Vec<Recipient> = (0..5)
            .map(|i| Recipient {
                id: RecipientId::from_bytes(vec![i; 32]),
                public_key: None,
            })
            .collect();

        let policy = SealPolicy {
            n: 5,
            t: 3,
            recipients,
            fec: FecParams {
                data_shares: 3,
                parity_shares: 2,
                symbol_size: 1024,
            },
            envelope: EnvelopeKind::PostQuantum,
            aad: vec![],
        };

        let summary = seal_bytes(plaintext, &policy, &dht).await.unwrap();

        // Get shares for recovery
        let sealed_meta_bytes = dht.get(&summary.handle.sealed_meta_key).unwrap();
        let sealed_meta: types::SealedMetaV1 = serde_cbor::from_slice(&sealed_meta_bytes).unwrap();

        let shares: Vec<ProvidedShare> = sealed_meta
            .shares
            .iter()
            .take(3)
            .map(|sr| ProvidedShare {
                index: sr.index,
                share_bytes: sr.share_plain.clone().unwrap(),
                recipient_id: sr.recipient.clone(),
            })
            .collect();

        let recovered = open_bytes(&summary.handle, &shares, &dht).unwrap();
        assert_eq!(plaintext, &recovered[..]);
    }
}