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}