saorsa-seal 0.1.3

Threshold sealing for group data in the Saorsa network
Documentation
//! Core types for threshold sealing operations

use serde::{Deserialize, Serialize};
use thiserror::Error;
use zeroize::{Zeroize, ZeroizeOnDrop};

/// Result type for seal operations
pub type Result<T> = std::result::Result<T, SealError>;

/// Object identifier (32-byte hash)
pub type ObjectId = [u8; 32];

/// DHT key type
pub type Key = [u8; 32];

/// Content Encryption Key
#[derive(Clone, Debug, Zeroize, ZeroizeOnDrop)]
pub struct CEK([u8; 32]);

impl CEK {
    /// Generate a new random CEK
    pub fn generate() -> Self {
        let mut key = [0u8; 32];
        rand::RngCore::fill_bytes(&mut rand::thread_rng(), &mut key);
        Self(key)
    }

    /// Create CEK from bytes
    pub fn from_bytes(bytes: [u8; 32]) -> Self {
        Self(bytes)
    }

    /// Get key bytes
    pub fn as_bytes(&self) -> &[u8; 32] {
        &self.0
    }
}

/// Recipient identifier
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct RecipientId(pub [u8; 32]);

impl RecipientId {
    /// Create from bytes
    pub fn from_bytes(bytes: Vec<u8>) -> Self {
        let mut id = [0u8; 32];
        let len = bytes.len().min(32);
        id[..len].copy_from_slice(&bytes[..len]);
        Self(id)
    }
}

/// Recipient information for threshold sealing
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Recipient {
    /// Unique identifier for the recipient
    pub id: RecipientId,
    /// Optional public key for envelope encryption
    pub public_key: Option<Vec<u8>>,
}

/// Forward Error Correction parameters
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct FecParams {
    /// Number of data shares
    pub data_shares: usize,
    /// Number of parity shares for recovery
    pub parity_shares: usize,
    /// Size of each symbol/chunk
    pub symbol_size: usize,
}

/// Envelope encryption type
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum EnvelopeKind {
    /// No envelope encryption
    None,
    /// Post-quantum cryptography (ML-KEM-768)
    PostQuantum,
}

/// Sealing policy configuration
#[derive(Clone, Debug)]
pub struct SealPolicy {
    /// Total number of shares (n)
    pub n: usize,
    /// Threshold needed for recovery (t)
    pub t: usize,
    /// List of recipients
    pub recipients: Vec<Recipient>,
    /// Forward error correction parameters
    pub fec: FecParams,
    /// Envelope encryption type
    pub envelope: EnvelopeKind,
    /// Additional authenticated data
    pub aad: Vec<u8>,
}

/// Handle to sealed data
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SealHandle {
    /// Key for sealed metadata in DHT
    pub sealed_meta_key: Key,
    /// Original object identifier
    pub object_id: ObjectId,
}

/// Summary of sealing operation
#[derive(Debug)]
pub struct SealSummary {
    /// Handle to access sealed data
    pub handle: SealHandle,
    /// Number of shares created
    pub share_count: usize,
    /// Size of original data
    pub original_size: usize,
}

/// Share provided for recovery
#[derive(Clone, Debug)]
pub struct ProvidedShare {
    /// Share index
    pub index: u8,
    /// Share bytes
    pub share_bytes: Vec<u8>,
    /// Recipient identifier
    pub recipient_id: RecipientId,
}

/// Share record in sealed metadata
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ShareRecord {
    /// Share index
    pub index: u8,
    /// Recipient this share belongs to
    pub recipient: RecipientId,
    /// Encrypted share (if using envelopes)
    pub share_encrypted: Option<Vec<u8>>,
    /// Plain share (if no envelope encryption)
    pub share_plain: Option<Vec<u8>>,
    /// Commitment for verification
    pub commitment: Option<Vec<u8>>,
}

/// Sealed metadata stored in DHT
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SealedMetaV1 {
    /// Format version
    pub version: u8,
    /// Original object ID
    pub object_id: ObjectId,
    /// Content encryption key commitment
    pub cek_commitment: [u8; 32],
    /// FEC parameters used
    pub fec_params: FecParams,
    /// Envelope type used
    pub envelope: EnvelopeKind,
    /// Share records
    pub shares: Vec<ShareRecord>,
    /// Additional authenticated data
    pub aad: Vec<u8>,
}

/// Errors that can occur during sealing operations
#[derive(Debug, Error)]
pub enum SealError {
    /// Encryption operation failed
    #[error("Encryption failed: {0}")]
    EncryptionError(String),
    /// Decryption operation failed
    #[error("Decryption failed: {0}")]
    DecryptionError(String),
    /// Threshold scheme operation failed
    #[error("Threshold scheme error: {0}")]
    ThresholdError(String),
    /// Forward error correction failed
    #[error("FEC error: {0}")]
    FecError(String),
    /// DHT operation failed
    #[error("DHT error: {0}")]
    DhtError(String),
    /// Invalid configuration
    #[error("Invalid configuration: {0}")]
    ConfigError(String),
    /// Serialization failed
    #[error("Serialization error: {0}")]
    SerializationError(String),
    /// Not enough shares for recovery
    #[error("Insufficient shares: need {needed}, got {provided}")]
    InsufficientShares { needed: usize, provided: usize },
    /// Other error
    #[error("Other error: {0}")]
    Other(String),
}

impl From<anyhow::Error> for SealError {
    fn from(err: anyhow::Error) -> Self {
        SealError::Other(err.to_string())
    }
}

impl From<serde_cbor::Error> for SealError {
    fn from(err: serde_cbor::Error) -> Self {
        SealError::SerializationError(err.to_string())
    }
}

/// Threshold verifier for validating threshold signatures and shares
#[derive(Clone, Debug)]
pub struct ThresholdVerifier {
    /// Threshold value (t of n)
    pub threshold: usize,
    /// Total number of shares (n)
    pub total_shares: usize,
    /// Group public key for verification
    pub group_public_key: Vec<u8>,
}

impl ThresholdVerifier {
    /// Create a new threshold verifier
    pub fn new(threshold: usize, total_shares: usize, group_public_key: Vec<u8>) -> Self {
        Self {
            threshold,
            total_shares,
            group_public_key,
        }
    }

    /// Verify a threshold signature
    pub fn verify(&self, _message: &[u8], _signature: &ShareSignature) -> Result<bool> {
        // Placeholder for actual verification logic
        // Would integrate with saorsa-core threshold implementation
        Ok(true)
    }
}

/// Signature from a threshold share
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ShareSignature {
    /// Share index
    pub index: u8,
    /// Signature data
    pub signature: Vec<u8>,
    /// Optional proof of correctness
    pub proof: Option<Vec<u8>>,
}

impl ShareSignature {
    /// Create a new share signature
    pub fn new(index: u8, signature: Vec<u8>) -> Self {
        Self {
            index,
            signature,
            proof: None,
        }
    }

    /// Create with proof
    pub fn with_proof(index: u8, signature: Vec<u8>, proof: Vec<u8>) -> Self {
        Self {
            index,
            signature,
            proof: Some(proof),
        }
    }
}

/// Public key share for threshold cryptography
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PublicKeyShare {
    /// Share index
    pub index: u8,
    /// Public key data
    pub public_key: Vec<u8>,
    /// Commitment for verification
    pub commitment: Option<Vec<u8>>,
}

impl PublicKeyShare {
    /// Create a new public key share
    pub fn new(index: u8, public_key: Vec<u8>) -> Self {
        Self {
            index,
            public_key,
            commitment: None,
        }
    }

    /// Create with commitment
    pub fn with_commitment(index: u8, public_key: Vec<u8>, commitment: Vec<u8>) -> Self {
        Self {
            index,
            public_key,
            commitment: Some(commitment),
        }
    }

    /// Verify this share against a commitment
    pub fn verify(&self, _commitment: &[u8]) -> bool {
        // Placeholder for actual verification
        // Would use Feldman VSS or similar
        true
    }
}

/// Trait for post-quantum envelope encryption
pub trait PqcEnvelope: Send + Sync {
    /// Encapsulate data for a recipient
    fn encap_to(&self, recipient: &Recipient, data: &[u8]) -> anyhow::Result<Vec<u8>>;
    /// Decapsulate data from a sender
    fn decap_from(&self, sender: &Recipient, data: &[u8]) -> anyhow::Result<Vec<u8>>;
    /// Clone as boxed trait object
    fn clone_box(&self) -> Box<dyn PqcEnvelope>;
}