| Crates.io | saorsa-seal |
| lib.rs | saorsa-seal |
| version | 0.1.2 |
| created_at | 2025-08-29 13:43:53.645062+00 |
| updated_at | 2025-09-03 20:57:47.315025+00 |
| description | Threshold sealing for group data in the Saorsa network |
| homepage | |
| repository | https://github.com/dirvine/saorsa-seal |
| max_upload_size | |
| id | 1815853 |
| size | 194,971 |
Threshold sealing for group data in the Saorsa network - a comprehensive solution for secure, distributed data storage with threshold cryptography and forward error correction.
This crate leverages the Saorsa ecosystem:
saorsa-core]: Threshold cryptography and DHT abstractionsaorsa-fec]: Forward error correction and AEAD encryptionsaorsa-pqc]: Post-quantum cryptographyAdd this to your Cargo.toml:
[dependencies]
saorsa-seal = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
use saorsa_seal::{seal_bytes, open_bytes, SealPolicy, FecParams, EnvelopeKind, Recipient, RecipientId, Dht};
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 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, // Would include ML-KEM public key for real usage
})
.collect();
// Configure sealing policy
let policy = SealPolicy {
n: 5, // Total shares
t: 3, // Threshold needed to recover
recipients,
fec: FecParams {
data_shares: 3, // Data chunks
parity_shares: 2, // Recovery chunks
symbol_size: 1024, // Chunk size
},
envelope: EnvelopeKind::PostQuantum, // Post-quantum recipient encryption
aad: vec![], // Additional authenticated data
};
// Seal the data
let summary = seal_bytes(plaintext, &policy, &dht).await?;
println!("Data sealed with handle: {:?}", summary.handle);
// Simulate gathering shares from 3 recipients
let sealed_meta_bytes = dht.get(&summary.handle.sealed_meta_key)?;
let sealed_meta: saorsa_seal::types::SealedMetaV1 =
serde_cbor::from_slice(&sealed_meta_bytes)?;
let shares: Vec<saorsa_seal::ProvidedShare> = sealed_meta
.shares
.iter()
.take(3) // Use threshold number of shares
.map(|sr| saorsa_seal::ProvidedShare {
index: sr.index,
share_bytes: sr.share_plain.clone().unwrap(),
recipient_id: sr.recipient.clone(),
})
.collect();
// Open (unseal) the data
let recovered = open_bytes(&summary.handle, &shares, &dht)?;
println!("Original: {:?}", std::str::from_utf8(plaintext)?);
println!("Recovered: {:?}", std::str::from_utf8(&recovered)?);
assert_eq!(plaintext, &recovered[..]);
Ok(())
}
use saorsa_seal::{SealPolicy, FecParams, EnvelopeKind};
let policy = SealPolicy {
n: 5, // Total number of shares to generate
t: 3, // Minimum shares needed for recovery
recipients, // List of share recipients
fec: FecParams {
data_shares: 10, // Number of data chunks
parity_shares: 4, // Number of recovery chunks
symbol_size: 1024, // Size of each chunk in bytes
},
envelope: EnvelopeKind::PostQuantum, // Post-quantum recipient encryption
aad: b"context".to_vec(), // Additional authenticated data
};
EnvelopeKind::None: No recipient-level encryption (shares stored in plaintext)EnvelopeKind::PostQuantum: ML-KEM-768 post-quantum encryptionThe library is optimized for throughput with configurable chunking:
Benchmarks show:
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.