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