use crate::types::{
PerformancePreference, SecurityLevel, UseCase,
error::{Result, TypeError},
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CoreConfig {
pub security_level: SecurityLevel,
pub performance_preference: PerformancePreference,
pub hardware_acceleration: bool,
pub fallback_enabled: bool,
pub strict_validation: bool,
}
impl Default for CoreConfig {
fn default() -> Self {
Self {
security_level: SecurityLevel::High,
performance_preference: PerformancePreference::Balanced,
hardware_acceleration: true,
fallback_enabled: true,
strict_validation: true,
}
}
}
impl CoreConfig {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn for_development() -> Self {
Self::default().with_security_level(SecurityLevel::Standard).with_strict_validation(false)
}
#[must_use]
pub fn for_production() -> Self {
Self::default().with_security_level(SecurityLevel::Maximum).with_strict_validation(true)
}
#[must_use]
pub fn with_security_level(mut self, level: SecurityLevel) -> Self {
self.security_level = level;
self
}
#[must_use]
pub fn with_performance_preference(mut self, preference: PerformancePreference) -> Self {
self.performance_preference = preference;
self
}
#[must_use]
pub fn with_hardware_acceleration(mut self, enabled: bool) -> Self {
self.hardware_acceleration = enabled;
self
}
#[must_use]
pub fn with_fallback(mut self, enabled: bool) -> Self {
self.fallback_enabled = enabled;
self
}
#[must_use]
pub fn with_strict_validation(mut self, enabled: bool) -> Self {
self.strict_validation = enabled;
self
}
pub fn build(self) -> Result<Self> {
self.validate()?;
Ok(self)
}
pub fn validate(&self) -> Result<()> {
if self.strict_validation && matches!(self.security_level, SecurityLevel::Standard) {
return Err(TypeError::ConfigurationError(
"Strict validation mode requires SecurityLevel::High or above. \
SecurityLevel::Standard (NIST Level 1) is not permitted in strict mode."
.to_string(),
));
}
if matches!(self.performance_preference, PerformancePreference::Speed)
&& !self.fallback_enabled
{
return Err(TypeError::ConfigurationError(
"Speed preference should have fallback enabled for reliability".to_string(),
));
}
Ok(())
}
}
pub type EncryptionConfig = CoreConfig;
pub type SignatureConfig = CoreConfig;
#[derive(Debug, Clone)]
pub struct ZeroTrustConfig {
pub base: CoreConfig,
pub challenge_timeout_ms: u64,
pub proof_complexity: ProofComplexity,
pub continuous_verification: bool,
pub verification_interval_ms: u64,
}
impl Default for ZeroTrustConfig {
fn default() -> Self {
Self {
base: CoreConfig::default(),
challenge_timeout_ms: 5000,
proof_complexity: ProofComplexity::Medium,
continuous_verification: true,
verification_interval_ms: 30000,
}
}
}
impl ZeroTrustConfig {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn with_timeout(mut self, timeout_ms: u64) -> Self {
self.challenge_timeout_ms = timeout_ms;
self
}
#[must_use]
pub fn with_complexity(mut self, complexity: ProofComplexity) -> Self {
self.proof_complexity = complexity;
self
}
#[must_use]
pub fn with_continuous_verification(mut self, enabled: bool) -> Self {
self.continuous_verification = enabled;
self
}
#[must_use]
pub fn with_verification_interval(mut self, interval_ms: u64) -> Self {
self.verification_interval_ms = interval_ms;
self
}
pub fn validate(&self) -> Result<()> {
self.base.validate()?;
if self.challenge_timeout_ms == 0 {
return Err(TypeError::ConfigurationError(
"Challenge timeout cannot be zero".to_string(),
));
}
if self.continuous_verification && self.verification_interval_ms == 0 {
return Err(TypeError::ConfigurationError(
"Continuous verification requires non-zero interval".to_string(),
));
}
Ok(())
}
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(kani, derive(kani::Arbitrary))]
pub enum ProofComplexity {
Low,
Medium,
High,
}
#[derive(Debug, Clone)]
pub struct UseCaseConfig {
pub use_case: UseCase,
pub encryption: CoreConfig,
pub signature: CoreConfig,
pub zero_trust: ZeroTrustConfig,
}
impl UseCaseConfig {
#[must_use]
pub fn new(use_case: UseCase) -> Self {
let base_config = match use_case {
UseCase::SecureMessaging | UseCase::ApiSecurity => {
CoreConfig::new().with_performance_preference(PerformancePreference::Speed)
}
UseCase::EmailEncryption => CoreConfig::new().with_security_level(SecurityLevel::High),
UseCase::VpnTunnel => CoreConfig::new()
.with_performance_preference(PerformancePreference::Speed)
.with_hardware_acceleration(true),
UseCase::FileStorage | UseCase::CloudStorage | UseCase::BackupArchive => {
CoreConfig::new().with_security_level(SecurityLevel::Maximum)
}
UseCase::DatabaseEncryption | UseCase::ConfigSecrets => {
CoreConfig::new().with_performance_preference(PerformancePreference::Memory)
}
UseCase::Authentication | UseCase::DigitalCertificate => {
CoreConfig::new().with_security_level(SecurityLevel::Maximum)
}
UseCase::SessionToken => {
CoreConfig::new().with_performance_preference(PerformancePreference::Speed)
}
UseCase::KeyExchange => CoreConfig::new().with_security_level(SecurityLevel::Maximum),
UseCase::FinancialTransactions | UseCase::LegalDocuments => {
CoreConfig::new().with_security_level(SecurityLevel::Maximum)
}
UseCase::BlockchainTransaction => {
CoreConfig::new().with_performance_preference(PerformancePreference::Balanced)
}
UseCase::HealthcareRecords | UseCase::GovernmentClassified | UseCase::PaymentCard => {
CoreConfig::new().with_security_level(SecurityLevel::Maximum)
}
UseCase::IoTDevice => CoreConfig::new()
.with_security_level(SecurityLevel::Standard)
.with_performance_preference(PerformancePreference::Memory)
.with_strict_validation(false),
UseCase::FirmwareSigning => CoreConfig::new().with_security_level(SecurityLevel::High),
UseCase::AuditLog => CoreConfig::new().with_security_level(SecurityLevel::High),
};
Self {
use_case,
encryption: base_config.clone(),
signature: base_config.clone(),
zero_trust: ZeroTrustConfig { base: base_config, ..Default::default() },
}
}
pub fn validate(&self) -> Result<()> {
self.encryption.validate()?;
self.signature.validate()?;
self.zero_trust.validate()?;
Ok(())
}
}
#[cfg(kani)]
impl kani::Arbitrary for CoreConfig {
fn any() -> Self {
Self {
security_level: kani::any(),
performance_preference: kani::any(),
hardware_acceleration: kani::any(),
fallback_enabled: kani::any(),
strict_validation: kani::any(),
}
}
}
#[cfg(kani)]
mod kani_proofs {
use super::*;
#[kani::proof]
fn core_config_default_validates() {
let config = CoreConfig::default();
kani::assert(config.validate().is_ok(), "Default CoreConfig must validate");
}
#[kani::proof]
fn core_config_for_production_validates() {
let config = CoreConfig::for_production();
kani::assert(config.validate().is_ok(), "Production config must validate");
}
#[kani::proof]
fn core_config_for_development_validates() {
let config = CoreConfig::for_development();
kani::assert(config.validate().is_ok(), "Development config must validate");
}
#[kani::proof]
fn core_config_validation_biconditional() {
let config: CoreConfig = kani::any();
let result = config.validate();
let should_pass = !((config.strict_validation
&& matches!(config.security_level, SecurityLevel::Standard))
|| (matches!(config.performance_preference, PerformancePreference::Speed)
&& !config.fallback_enabled));
kani::assert(result.is_ok() == should_pass, "validate() passes iff both invariants hold");
}
}
#[cfg(test)]
#[allow(
clippy::panic,
clippy::unwrap_used,
clippy::expect_used,
clippy::indexing_slicing,
clippy::arithmetic_side_effects,
clippy::panic_in_result_fn,
clippy::unnecessary_wraps,
clippy::redundant_clone,
clippy::useless_vec,
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::clone_on_copy,
clippy::len_zero,
clippy::single_match,
clippy::unnested_or_patterns,
clippy::default_constructed_unit_structs,
clippy::redundant_closure_for_method_calls,
clippy::semicolon_if_nothing_returned,
clippy::unnecessary_unwrap,
clippy::redundant_pattern_matching,
clippy::missing_const_for_thread_local,
clippy::get_first,
clippy::float_cmp,
clippy::needless_borrows_for_generic_args,
unused_qualifications
)]
mod tests {
use super::*;
#[test]
fn test_core_config_default_fields_are_correct() {
let config = CoreConfig::new();
assert_eq!(config.security_level, SecurityLevel::High);
assert_eq!(config.performance_preference, PerformancePreference::Balanced);
assert!(config.hardware_acceleration);
assert!(config.fallback_enabled);
assert!(config.strict_validation);
}
#[test]
fn test_core_config_for_development_succeeds() {
let config = CoreConfig::for_development();
assert_eq!(config.security_level, SecurityLevel::Standard);
assert!(!config.strict_validation);
}
#[test]
fn test_core_config_for_production_succeeds() {
let config = CoreConfig::for_production();
assert_eq!(config.security_level, SecurityLevel::Maximum);
assert!(config.strict_validation);
}
#[test]
fn test_core_config_builder_pattern_succeeds() {
let config = CoreConfig::new()
.with_security_level(SecurityLevel::Maximum)
.with_performance_preference(PerformancePreference::Speed)
.with_hardware_acceleration(true)
.with_fallback(true)
.with_strict_validation(true);
assert_eq!(config.security_level, SecurityLevel::Maximum);
assert_eq!(config.performance_preference, PerformancePreference::Speed);
}
#[test]
fn test_core_config_validation_success_succeeds() -> Result<()> {
let config = CoreConfig::new().with_security_level(SecurityLevel::Maximum);
config.validate()?;
Ok(())
}
#[test]
fn test_core_config_strict_validation_rejects_standard_fails() {
let config = CoreConfig::new()
.with_security_level(SecurityLevel::Standard)
.with_strict_validation(true);
let result = config.validate();
assert!(result.is_err());
}
#[test]
fn test_core_config_strict_validation_allows_high_succeeds() -> Result<()> {
let config =
CoreConfig::new().with_security_level(SecurityLevel::High).with_strict_validation(true);
config.validate()?;
Ok(())
}
#[test]
fn test_core_config_build_success_succeeds() -> Result<()> {
let config = CoreConfig::new()
.with_security_level(SecurityLevel::High)
.with_hardware_acceleration(true)
.build()?;
assert_eq!(config.security_level, SecurityLevel::High);
Ok(())
}
#[test]
fn test_encryption_config_is_core_config_succeeds() {
let config = EncryptionConfig::default();
assert_eq!(config.security_level, SecurityLevel::High);
assert!(config.validate().is_ok());
}
#[test]
fn test_signature_config_is_core_config_succeeds() {
let config = SignatureConfig::default();
assert_eq!(config.security_level, SecurityLevel::High);
assert!(config.validate().is_ok());
}
#[test]
fn test_zero_trust_config_default_fields_are_correct() {
let config = ZeroTrustConfig::default();
assert_eq!(config.challenge_timeout_ms, 5000);
assert_eq!(config.proof_complexity, ProofComplexity::Medium);
assert!(config.continuous_verification);
}
#[test]
fn test_use_case_config_financial_transactions_selects_maximum_security_succeeds() {
let config = UseCaseConfig::new(UseCase::FinancialTransactions);
assert_eq!(config.use_case, UseCase::FinancialTransactions);
assert_eq!(config.encryption.security_level, SecurityLevel::Maximum);
}
#[test]
fn test_use_case_config_iot_device_succeeds() {
let config = UseCaseConfig::new(UseCase::IoTDevice);
assert_eq!(config.encryption.security_level, SecurityLevel::Standard);
assert_eq!(config.encryption.performance_preference, PerformancePreference::Memory);
}
#[test]
fn test_strict_validation_rejects_standard_security_level_fails() {
let config = CoreConfig::new()
.with_strict_validation(true)
.with_security_level(SecurityLevel::Standard);
assert!(config.validate().is_err());
}
#[test]
fn test_strict_validation_accepts_high_security_level_succeeds() {
let config =
CoreConfig::new().with_strict_validation(true).with_security_level(SecurityLevel::High);
assert!(config.validate().is_ok());
}
#[test]
fn test_strict_validation_false_accepts_standard_security_level_succeeds() {
let config = CoreConfig::new()
.with_strict_validation(false)
.with_security_level(SecurityLevel::Standard);
assert!(config.validate().is_ok());
}
}