visual_cryptography/
lib.rs1pub mod algorithms;
10pub mod error;
11pub mod matrix;
12pub mod share;
13pub mod utils;
14
15pub use algorithms::{Algorithm, VCScheme};
16pub use error::{Result, VCError};
17pub use share::{Share, ShareType};
18
19pub use image::{DynamicImage, ImageBuffer, Luma, Rgb, Rgba};
21
22#[derive(Debug, Clone)]
24pub struct VCConfig {
25    pub num_shares: usize,
27    pub threshold: usize,
29    pub block_size: usize,
31    pub algorithm: Algorithm,
33    pub use_meaningful_shares: bool,
35}
36
37impl Default for VCConfig {
38    fn default() -> Self {
39        Self {
40            num_shares: 2,
41            threshold: 2,
42            block_size: 2,
43            algorithm: Algorithm::BasicThreshold,
44            use_meaningful_shares: false,
45        }
46    }
47}
48
49pub struct VisualCryptography {
51    config: VCConfig,
52}
53
54impl VisualCryptography {
55    pub fn new(config: VCConfig) -> Result<Self> {
57        if config.threshold > config.num_shares {
58            return Err(VCError::InvalidConfiguration(
59                "Threshold cannot be greater than number of shares".to_string(),
60            ));
61        }
62        if config.threshold == 0 || config.num_shares == 0 {
63            return Err(VCError::InvalidConfiguration(
64                "Threshold and number of shares must be greater than 0".to_string(),
65            ));
66        }
67        if config.block_size == 0 {
68            return Err(VCError::InvalidConfiguration(
69                "Block size must be greater than 0".to_string(),
70            ));
71        }
72
73        Ok(Self { config })
74    }
75
76    pub fn encrypt(
78        &self,
79        image: &DynamicImage,
80        cover_images: Option<Vec<DynamicImage>>,
81    ) -> Result<Vec<Share>> {
82        algorithms::encrypt(image, &self.config, cover_images)
83    }
84
85    pub fn decrypt(&self, shares: &[Share]) -> Result<DynamicImage> {
87        if shares.len() < self.config.threshold {
88            return Err(VCError::InsufficientShares {
89                required: self.config.threshold,
90                provided: shares.len(),
91            });
92        }
93        algorithms::decrypt(shares, &self.config)
94    }
95
96    pub fn progressive(num_shares: usize) -> Result<Self> {
98        Self::new(VCConfig {
99            num_shares,
100            threshold: 2, algorithm: Algorithm::Progressive,
102            ..Default::default()
103        })
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn test_config_validation() {
113        let config = VCConfig {
115            num_shares: 3,
116            threshold: 2,
117            block_size: 2,
118            algorithm: Algorithm::BasicThreshold,
119            use_meaningful_shares: false,
120        };
121        assert!(VisualCryptography::new(config).is_ok());
122
123        let config = VCConfig {
125            num_shares: 2,
126            threshold: 3,
127            ..Default::default()
128        };
129        assert!(VisualCryptography::new(config).is_err());
130
131        let config = VCConfig {
133            threshold: 0,
134            ..Default::default()
135        };
136        assert!(VisualCryptography::new(config).is_err());
137    }
138
139    #[test]
140    fn test_progressive_creation() {
141        let vc = VisualCryptography::progressive(5).unwrap();
142        assert_eq!(vc.config.num_shares, 5);
143        assert_eq!(vc.config.algorithm, Algorithm::Progressive);
144    }
145}