use crate::{error::CryptoError, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PqcMetadata {
pub kem_params: Option<KemParameters>,
pub sig_params: Option<SigParameters>,
pub enc_params: EncParameters,
pub compression_params: Option<CompressionParameters>,
pub custom: HashMap<String, Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct KemParameters {
pub public_key: Vec<u8>,
pub ciphertext: Vec<u8>,
pub params: HashMap<String, Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SigParameters {
pub public_key: Vec<u8>,
pub signature: Vec<u8>,
pub params: HashMap<String, Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EncParameters {
pub iv: Vec<u8>,
pub tag: Vec<u8>,
pub params: HashMap<String, Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CompressionParameters {
pub algorithm: String,
pub level: u8,
pub original_size: u64,
pub params: HashMap<String, Vec<u8>>,
}
impl PqcMetadata {
#[must_use]
pub fn new() -> Self {
Self {
kem_params: None,
sig_params: None,
enc_params: EncParameters {
iv: Vec::new(),
tag: Vec::new(),
params: HashMap::new(),
},
compression_params: None,
custom: HashMap::new(),
}
}
pub fn validate(&self) -> Result<()> {
if self.enc_params.iv.is_empty() {
return Err(CryptoError::MetadataError(
"Encryption IV cannot be empty".to_string(),
));
}
Ok(())
}
pub fn add_custom(&mut self, key: String, value: Vec<u8>) {
self.custom.insert(key, value);
}
#[must_use]
pub fn get_custom(&self, key: &str) -> Option<&[u8]> {
self.custom.get(key).map(Vec::as_slice)
}
}
impl Default for PqcMetadata {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_metadata_validation() {
let mut metadata = PqcMetadata::new();
assert!(metadata.validate().is_err());
metadata.enc_params.iv = vec![1; 12];
assert!(metadata.validate().is_ok());
}
#[test]
fn test_custom_parameters() {
let mut metadata = PqcMetadata::new();
metadata.add_custom("test".to_string(), vec![1, 2, 3]);
assert_eq!(metadata.get_custom("test"), Some(&[1, 2, 3][..]));
assert_eq!(metadata.get_custom("missing"), None);
}
}