diff --git a/examples/01_simple_detect.rs b/examples/01_simple_detect.rs index a844245..55ad9e3 100644 --- a/examples/01_simple_detect.rs +++ b/examples/01_simple_detect.rs @@ -9,10 +9,16 @@ fn main() { println!("Input: {:?}", input); if let Some(hash) = cryptotrace::core::hashing::detect_hash(input) { - println!(" Hash: {} (confidence {:.2})", hash.algorithm, hash.confidence); + println!( + " Hash: {} (confidence {:.2})", + hash.algorithm, hash.confidence + ); } if let Some(enc) = cryptotrace::core::encoding::detect_encoding(input) { - println!(" Encoding: {} (confidence {:.2})", enc.encoding_type, enc.confidence); + println!( + " Encoding: {} (confidence {:.2})", + enc.encoding_type, enc.confidence + ); } let (entropy, _freq) = cryptotrace::core::entropy::shannon_entropy(input.as_bytes()); diff --git a/examples/02_scan_file.rs b/examples/02_scan_file.rs index 2c05a8c..2b03cad 100644 --- a/examples/02_scan_file.rs +++ b/examples/02_scan_file.rs @@ -3,14 +3,22 @@ use std::fs; fn main() { let args: Vec = env::args().collect(); - let path = if args.len() > 1 { &args[1] } else { "Cargo.toml" }; + let path = if args.len() > 1 { + &args[1] + } else { + "Cargo.toml" + }; let data = fs::read(path).expect("Failed to read file"); - match cryptotrace::analyzers::file::analyze_bytes(&data, cryptotrace::types::SourceType::Binary) { + match cryptotrace::analyzers::file::analyze_bytes(&data, cryptotrace::types::SourceType::Binary) + { Ok(result) => { println!("File: {}", path); - println!("Algorithm: {}", result.algorithm.unwrap_or_else(|| "".into())); + println!( + "Algorithm: {}", + result.algorithm.unwrap_or_else(|| "".into()) + ); println!("Encoding: {}", result.detected_type); let (entropy, _) = cryptotrace::core::entropy::shannon_entropy(&data); println!("Entropy: {:.2}", entropy); diff --git a/examples/03_batch_folder.rs b/examples/03_batch_folder.rs index 1ff6103..d62365d 100644 --- a/examples/03_batch_folder.rs +++ b/examples/03_batch_folder.rs @@ -4,11 +4,16 @@ use std::fs; fn main() { let args: Vec = env::args().collect(); let dir = if args.len() > 1 { &args[1] } else { "." }; - let max_size: u64 = std::env::var("MAX_FILE_SIZE").ok().and_then(|s| s.parse().ok()).unwrap_or(10_485_760); + let max_size: u64 = std::env::var("MAX_FILE_SIZE") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(10_485_760); for entry in fs::read_dir(dir).unwrap().flatten() { let path = entry.path(); - if !path.is_file() { continue; } + if !path.is_file() { + continue; + } let _meta = match fs::metadata(&path) { Ok(m) if m.len() <= max_size => m, @@ -20,12 +25,21 @@ fn main() { Err(_) => continue, }; - match cryptotrace::analyzers::file::analyze_bytes(&data, cryptotrace::types::SourceType::Binary) { + match cryptotrace::analyzers::file::analyze_bytes( + &data, + cryptotrace::types::SourceType::Binary, + ) { Ok(result) => { let algo = result.algorithm.unwrap_or_else(|| "-".into()); let (entropy, _) = cryptotrace::core::entropy::shannon_entropy(&data); - println!("{}\t{}\t{}\t{:.2}\t{:.2}", - path.display(), algo, result.detected_type, entropy, result.confidence); + println!( + "{}\t{}\t{}\t{:.2}\t{:.2}", + path.display(), + algo, + result.detected_type, + entropy, + result.confidence + ); } Err(e) => eprintln!("Error scanning {}: {}", path.display(), e), } diff --git a/examples/04_compare_inputs.rs b/examples/04_compare_inputs.rs index c4d8849..6f89121 100644 --- a/examples/04_compare_inputs.rs +++ b/examples/04_compare_inputs.rs @@ -6,20 +6,37 @@ fn main() { // Method 1: Raw bytes println!("=== Raw bytes ==="); - let r1 = cryptotrace::analyzers::file::analyze_bytes(test_data, cryptotrace::types::SourceType::Binary).unwrap(); - println!(" algo={:?} type={} ent={:.2} conf={:.2}", r1.algorithm, r1.detected_type, r1.entropy, r1.confidence); + let r1 = cryptotrace::analyzers::file::analyze_bytes( + test_data, + cryptotrace::types::SourceType::Binary, + ) + .unwrap(); + println!( + " algo={:?} type={} ent={:.2} conf={:.2}", + r1.algorithm, r1.detected_type, r1.entropy, r1.confidence + ); // Method 2: File println!("=== From file ==="); let r2 = cryptotrace::analyzers::file::analyze_file(Path::new("Cargo.toml")).unwrap(); - println!(" algo={:?} type={} ent={:.2} conf={:.2}", r2.algorithm, r2.detected_type, r2.entropy, r2.confidence); + println!( + " algo={:?} type={} ent={:.2} conf={:.2}", + r2.algorithm, r2.detected_type, r2.entropy, r2.confidence + ); // Method 3: Stdin (if piped) println!("=== Stdin (pipe data or skip) ==="); let mut buf = Vec::new(); if std::io::stdin().read_to_end(&mut buf).is_ok() && !buf.is_empty() { - let r3 = cryptotrace::analyzers::file::analyze_bytes(&buf, cryptotrace::types::SourceType::Binary).unwrap(); - println!(" algo={:?} type={} ent={:.2} conf={:.2}", r3.algorithm, r3.detected_type, r3.entropy, r3.confidence); + let r3 = cryptotrace::analyzers::file::analyze_bytes( + &buf, + cryptotrace::types::SourceType::Binary, + ) + .unwrap(); + println!( + " algo={:?} type={} ent={:.2} conf={:.2}", + r3.algorithm, r3.detected_type, r3.entropy, r3.confidence + ); } else { println!(" (no stdin data)"); } diff --git a/examples/05_csv_export.rs b/examples/05_csv_export.rs index e93741b..d4428b1 100644 --- a/examples/05_csv_export.rs +++ b/examples/05_csv_export.rs @@ -7,17 +7,29 @@ fn main() { let out = args.get(2).map(|s| s.as_str()).unwrap_or("scan_report.csv"); let mut wtr = csv::Writer::from_path(out).expect("Failed to create CSV"); - wtr.write_record(["path", "algorithm", "detected_type", "entropy", "confidence", "risk_level"]) - .unwrap(); + wtr.write_record([ + "path", + "algorithm", + "detected_type", + "entropy", + "confidence", + "risk_level", + ]) + .unwrap(); for entry in fs::read_dir(dir).unwrap().flatten() { let path = entry.path(); - if !path.is_file() { continue; } + if !path.is_file() { + continue; + } let data = match fs::read(&path) { Ok(d) if d.len() <= 10_485_760 => d, _ => continue, }; - if let Ok(r) = cryptotrace::analyzers::file::analyze_bytes(&data, cryptotrace::types::SourceType::Binary) { + if let Ok(r) = cryptotrace::analyzers::file::analyze_bytes( + &data, + cryptotrace::types::SourceType::Binary, + ) { let (entropy, _) = cryptotrace::core::entropy::shannon_entropy(&data); wtr.write_record([ path.to_string_lossy().as_ref(), @@ -26,7 +38,8 @@ fn main() { &format!("{:.4}", entropy), &format!("{:.4}", r.confidence), &format!("{:?}", r.risk_level), - ]).ok(); + ]) + .ok(); } } wtr.flush().ok(); diff --git a/examples/06_recursive_decode.rs b/examples/06_recursive_decode.rs index 07c2aa5..39a4163 100644 --- a/examples/06_recursive_decode.rs +++ b/examples/06_recursive_decode.rs @@ -6,7 +6,8 @@ fn main() { // Gzip then base64 encode let mut compressed = Vec::new(); { - let mut encoder = flate2::write::GzEncoder::new(&mut compressed, flate2::Compression::default()); + let mut encoder = + flate2::write::GzEncoder::new(&mut compressed, flate2::Compression::default()); encoder.write_all(plaintext).unwrap(); encoder.finish().unwrap(); } @@ -14,7 +15,10 @@ fn main() { use base64::Engine; let b64_payload = base64::engine::general_purpose::STANDARD.encode(&compressed); - println!("Encoded payload (first 80 chars): {:?}", &b64_payload[..80.min(b64_payload.len())]); + println!( + "Encoded payload (first 80 chars): {:?}", + &b64_payload[..80.min(b64_payload.len())] + ); // Decode layer by layer let mut current = b64_payload.as_bytes().to_vec(); @@ -22,16 +26,22 @@ fn main() { let s = String::from_utf8_lossy(¤t); if let Some(enc) = cryptotrace::core::encoding::detect_encoding(&s) { - println!("Layer {}: detected encoding = {} (conf={:.2})", layer, enc.encoding_type, enc.confidence); + println!( + "Layer {}: detected encoding = {} (conf={:.2})", + layer, enc.encoding_type, enc.confidence + ); match enc.encoding_type.as_str() { "Base64" => { - if let Ok(decoded) = base64::engine::general_purpose::STANDARD.decode(s.trim()) { + if let Ok(decoded) = base64::engine::general_purpose::STANDARD.decode(s.trim()) + { current = decoded; continue; } } - _ => { break; } + _ => { + break; + } } } @@ -39,7 +49,11 @@ fn main() { let mut decompressed = Vec::new(); let mut d = flate2::read::GzDecoder::new(std::io::Cursor::new(¤t)); if d.read_to_end(&mut decompressed).is_ok() && !decompressed.is_empty() { - println!("Layer {}: gzip decompressed ({} bytes)", layer, decompressed.len()); + println!( + "Layer {}: gzip decompressed ({} bytes)", + layer, + decompressed.len() + ); current = decompressed; continue; } @@ -47,5 +61,8 @@ fn main() { break; } - println!("Final decoded text: {:?}", String::from_utf8_lossy(¤t)); + println!( + "Final decoded text: {:?}", + String::from_utf8_lossy(¤t) + ); } diff --git a/examples/07_sandbox_crash_test.rs b/examples/07_sandbox_crash_test.rs index 84eba92..42f8bf8 100644 --- a/examples/07_sandbox_crash_test.rs +++ b/examples/07_sandbox_crash_test.rs @@ -19,10 +19,19 @@ fn main() { } } Err(e) => { - println!("Sandbox worker failed (expected if no worker binary): {}", e); + println!( + "Sandbox worker failed (expected if no worker binary): {}", + e + ); println!("Falling back to in-process analysis..."); - match cryptotrace::analyzers::file::analyze_bytes(test_data, cryptotrace::types::SourceType::Binary) { - Ok(r) => println!("In-process result: algo={:?} ent={}", r.algorithm, r.entropy), + match cryptotrace::analyzers::file::analyze_bytes( + test_data, + cryptotrace::types::SourceType::Binary, + ) { + Ok(r) => println!( + "In-process result: algo={:?} ent={}", + r.algorithm, r.entropy + ), Err(e2) => eprintln!("Fallback also failed: {}", e2), } } diff --git a/examples/08_confidence_calibration.rs b/examples/08_confidence_calibration.rs index 1ec30f6..cf3dc58 100644 --- a/examples/08_confidence_calibration.rs +++ b/examples/08_confidence_calibration.rs @@ -1,4 +1,6 @@ -use cryptotrace::core::calibration::{generate_synthetic_dataset, train, predict_proba, signal_contributions, save_model, load_model}; +use cryptotrace::core::calibration::{ + generate_synthetic_dataset, load_model, predict_proba, save_model, signal_contributions, train, +}; use cryptotrace::types::SignalBreakdown; fn main() { @@ -8,7 +10,10 @@ fn main() { println!(" {} samples generated", dataset.len()); let model = train(&dataset, 0.01, 1000, 0.001); - println!("Model trained: intercept={:.4}, weights={:?}", model.intercept, model.weights); + println!( + "Model trained: intercept={:.4}, weights={:?}", + model.intercept, model.weights + ); println!("Dataset size: {}", model.dataset_size); let test_signals = SignalBreakdown { @@ -26,12 +31,20 @@ fn main() { let contribs = signal_contributions(&model, &test_signals); println!("\nSignal contributions:"); for sc in &contribs { - println!(" {:20} {:>8} {:.4}", sc.signal_name, if sc.coefficient > 0.0 { "+" } else { "-" }, sc.contribution); + println!( + " {:20} {:>8} {:.4}", + sc.signal_name, + if sc.coefficient > 0.0 { "+" } else { "-" }, + sc.contribution + ); } save_model(&model, "calibration_example.json").ok(); if let Ok(loaded) = load_model("calibration_example.json") { - println!("\nModel save/load roundtrip: OK (weights={:?})", loaded.weights); + println!( + "\nModel save/load roundtrip: OK (weights={:?})", + loaded.weights + ); } std::fs::remove_file("calibration_example.json").ok(); } diff --git a/examples/09_sliding_entropy.rs b/examples/09_sliding_entropy.rs index 82e5d4d..ad4a045 100644 --- a/examples/09_sliding_entropy.rs +++ b/examples/09_sliding_entropy.rs @@ -2,14 +2,23 @@ use std::fs; fn main() { let args: Vec = std::env::args().collect(); - let path = if args.len() > 1 { &args[1] } else { "Cargo.toml" }; + let path = if args.len() > 1 { + &args[1] + } else { + "Cargo.toml" + }; let data = fs::read(path).expect("Failed to read file"); println!("File: {} ({} bytes)", path, data.len()); let (entropy, _) = cryptotrace::core::entropy::shannon_entropy(&data); println!("Global Shannon entropy: {:.2} bits/byte", entropy); - let sw = cryptotrace::core::sliding_entropy::sliding_window_entropy(&data, Some(4096), None, Some(7.5)); + let sw = cryptotrace::core::sliding_entropy::sliding_window_entropy( + &data, + Some(4096), + None, + Some(7.5), + ); if sw.window_scores.is_empty() { println!("File too small for any window"); @@ -17,8 +26,16 @@ fn main() { } let avg: f64 = sw.window_scores.iter().sum::() / sw.window_scores.len() as f64; - let max_score = sw.window_scores.iter().cloned().fold(f64::NEG_INFINITY, f64::max); - let min_score = sw.window_scores.iter().cloned().fold(f64::INFINITY, f64::min); + let max_score = sw + .window_scores + .iter() + .cloned() + .fold(f64::NEG_INFINITY, f64::max); + let min_score = sw + .window_scores + .iter() + .cloned() + .fold(f64::INFINITY, f64::min); println!("Windows analyzed: {}", sw.window_scores.len()); println!("Avg window entropy: {:.2}", avg); diff --git a/examples/10_threat_intel_pipeline.rs b/examples/10_threat_intel_pipeline.rs index 4d1fcde..8887c6b 100644 --- a/examples/10_threat_intel_pipeline.rs +++ b/examples/10_threat_intel_pipeline.rs @@ -4,14 +4,15 @@ async fn main() { println!("Step 1: Hash identification"); if let Some(h) = cryptotrace::core::hashing::detect_hash(sample_hash) { - println!(" Algorithm: {} (confidence {:.2})", h.algorithm, h.confidence); + println!( + " Algorithm: {} (confidence {:.2})", + h.algorithm, h.confidence + ); } println!("\nStep 2: CVE lookup"); - let cve_map = cryptotrace::intelligence::risk::build_cve_map( - "signatures/cve_map.yaml", - "cve-db.json", - ); + let cve_map = + cryptotrace::intelligence::risk::build_cve_map("signatures/cve_map.yaml", "cve-db.json"); if let Some(cves) = cve_map.get("MD5") { println!(" Known CVEs for MD5: {:?}", cves); } @@ -23,15 +24,16 @@ async fn main() { enable_scan: true, }; - let reports = cryptotrace::intelligence::threat_intel::composite_threat_scan( - sample_hash, - &[], - &config, - ).await.unwrap_or_default(); + let reports = + cryptotrace::intelligence::threat_intel::composite_threat_scan(sample_hash, &[], &config) + .await + .unwrap_or_default(); println!(" Threat reports: {}", reports.len()); for report in &reports { - println!(" Source: {} | Positives: {}/{} | Malicious: {}", - report.source, report.positives, report.total_scanners, report.malicious); + println!( + " Source: {} | Positives: {}/{} | Malicious: {}", + report.source, report.positives, report.total_scanners, report.malicious + ); } let malicious = reports.iter().any(|r| r.malicious); diff --git a/examples/12_siem_export.rs b/examples/12_siem_export.rs index c1383e7..3bafa05 100644 --- a/examples/12_siem_export.rs +++ b/examples/12_siem_export.rs @@ -1,7 +1,10 @@ fn main() { let test_data = b"d41d8cd98f00b204e9800998ecf8427e"; - let result = cryptotrace::analyzers::file::analyze_bytes(test_data, cryptotrace::types::SourceType::Binary) - .expect("Analysis failed"); + let result = cryptotrace::analyzers::file::analyze_bytes( + test_data, + cryptotrace::types::SourceType::Binary, + ) + .expect("Analysis failed"); let cef = cryptotrace::intelligence::siem::format_cef(&result); println!("=== CEF Format ==="); diff --git a/examples/14_compression_bomb_defense.rs b/examples/14_compression_bomb_defense.rs index 955bd0d..9a12795 100644 --- a/examples/14_compression_bomb_defense.rs +++ b/examples/14_compression_bomb_defense.rs @@ -7,7 +7,8 @@ fn main() { let mut compressed = Vec::new(); { - let mut encoder = flate2::write::GzEncoder::new(&mut compressed, flate2::Compression::best()); + let mut encoder = + flate2::write::GzEncoder::new(&mut compressed, flate2::Compression::best()); encoder.write_all(&bomb_data).unwrap(); encoder.finish().unwrap(); } @@ -26,7 +27,11 @@ fn main() { match result { Ok(decompressed) => { - println!("Decompressed: {} bytes (ratio: {:.1})", decompressed.data.len(), decompressed.expansion_ratio); + println!( + "Decompressed: {} bytes (ratio: {:.1})", + decompressed.data.len(), + decompressed.expansion_ratio + ); } Err(e) => { println!("Decompression denied: {}", e); @@ -37,16 +42,25 @@ fn main() { let normal_data = b"Hello World! This is a test of the compression bomb defense mechanism."; let mut normal_compressed = Vec::new(); { - let mut encoder = flate2::write::GzEncoder::new(&mut normal_compressed, flate2::Compression::default()); + let mut encoder = + flate2::write::GzEncoder::new(&mut normal_compressed, flate2::Compression::default()); encoder.write_all(normal_data).unwrap(); encoder.finish().unwrap(); } println!("\n--- Normal compression test ---"); - println!("Original: {} bytes, Compressed: {} bytes", normal_data.len(), normal_compressed.len()); + println!( + "Original: {} bytes, Compressed: {} bytes", + normal_data.len(), + normal_compressed.len() + ); match cryptotrace::core::compression::try_decompress(&normal_compressed, "GZIP") { - Ok(d) => println!("Normal decompression OK: {} bytes (ratio: {:.1})", d.data.len(), d.expansion_ratio), + Ok(d) => println!( + "Normal decompression OK: {} bytes (ratio: {:.1})", + d.data.len(), + d.expansion_ratio + ), Err(e) => println!("Unexpected rejection: {}", e), } } diff --git a/examples/15_signature_mutations.rs b/examples/15_signature_mutations.rs index a2ec684..dd1aecf 100644 --- a/examples/15_signature_mutations.rs +++ b/examples/15_signature_mutations.rs @@ -5,9 +5,18 @@ fn main() { println!("Loaded {} signatures", registry.signatures.len()); let test_cases: [(&str, &[u8]); 6] = [ - ("ELF binary", &[0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00]), - ("GZip file", &[0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00]), - ("PNG image", &[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]), + ( + "ELF binary", + &[0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00], + ), + ( + "GZip file", + &[0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00], + ), + ( + "PNG image", + &[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], + ), ("PDF file", &[0x25, 0x50, 0x44, 0x46]), ("JPEG image", &[0xff, 0xd8, 0xff, 0xe0]), ("ZIP archive", &[0x50, 0x4b, 0x03, 0x04]), @@ -15,14 +24,21 @@ fn main() { for (name, magic) in &test_cases { let matches = cryptotrace::signatures::match_signatures(magic, ®istry); - println!("{}: {:?}", name, matches.iter().map(|m| &m.name).collect::>()); + println!( + "{}: {:?}", + name, + matches.iter().map(|m| &m.name).collect::>() + ); } // Test mutation resistance println!("\n--- Mutation Testing ---"); let png_header: [u8; 8] = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; let base = cryptotrace::signatures::match_signatures(&png_header, ®istry); - println!("Original PNG: {:?}", base.iter().map(|m| &m.name).collect::>()); + println!( + "Original PNG: {:?}", + base.iter().map(|m| &m.name).collect::>() + ); for offset in 0..png_header.len().min(4) { for bit in 0..4 { diff --git a/examples/16_provider_round_robin.rs b/examples/16_provider_round_robin.rs index 3f4a2d9..40330d7 100644 --- a/examples/16_provider_round_robin.rs +++ b/examples/16_provider_round_robin.rs @@ -24,6 +24,9 @@ fn main() { println!("\n--- Encoding Providers ---"); for provider in registry.by_categories(&["encoding"]).into_iter().take(5) { - println!(" Provider: {} (trust: {})", provider.name, provider.trust_level); + println!( + " Provider: {} (trust: {})", + provider.name, provider.trust_level + ); } } diff --git a/examples/18_cache_stress_test.rs b/examples/18_cache_stress_test.rs index bdbc259..24d3123 100644 --- a/examples/18_cache_stress_test.rs +++ b/examples/18_cache_stress_test.rs @@ -13,16 +13,23 @@ fn main() { cache.insert(format!("key_{}", i), format!("value_{}", i)); } let fill_time = start.elapsed(); - println!("Fill {} entries: {:?} ({:.0} inserts/sec)", - capacity, fill_time, capacity as f64 / fill_time.as_secs_f64()); + println!( + "Fill {} entries: {:?} ({:.0} inserts/sec)", + capacity, + fill_time, + capacity as f64 / fill_time.as_secs_f64() + ); println!("Cache size after fill: {}", cache.len()); let start = Instant::now(); for _ in 0..100_000 { let _ = cache.get(&format!("key_{}", 0)); } - println!("100K hot reads: {:?} ({:.0} reads/sec)", - start.elapsed(), 100_000.0 / start.elapsed().as_secs_f64()); + println!( + "100K hot reads: {:?} ({:.0} reads/sec)", + start.elapsed(), + 100_000.0 / start.elapsed().as_secs_f64() + ); let start = Instant::now(); let evict_count = 5_000; @@ -31,7 +38,11 @@ fn main() { } let evict_time = start.elapsed(); println!("Evict {} entries: {:?}", evict_count, evict_time); - println!("Cache size after eviction: {} (capacity: {})", cache.len(), capacity); + println!( + "Cache size after eviction: {} (capacity: {})", + cache.len(), + capacity + ); let mut hits = 0; for i in 0..100 { @@ -39,9 +50,16 @@ fn main() { hits += 1; } } - println!("Hot keys (0-99) surviving eviction: {}/100 ({:.0}%)", hits, hits as f64); + println!( + "Hot keys (0-99) surviving eviction: {}/100 ({:.0}%)", + hits, hits as f64 + ); cache.clear(); assert!(cache.is_empty()); - println!("Cache cleared: size={}, is_empty={}", cache.len(), cache.is_empty()); + println!( + "Cache cleared: size={}, is_empty={}", + cache.len(), + cache.is_empty() + ); } diff --git a/examples/19_multi_layer_pipeline.rs b/examples/19_multi_layer_pipeline.rs index d96f4ea..0f075a1 100644 --- a/examples/19_multi_layer_pipeline.rs +++ b/examples/19_multi_layer_pipeline.rs @@ -10,8 +10,9 @@ byBkZXRlY3QgdGhpcyBzZWNyZXQga2V5IGFuZCBpdHMgZW5jb2Rpbmc= -----END PGP PRIVATE KEY BLOCK-----"#; println!("Step 1: Input ({} bytes)", input.len()); - let format_result = cryptotrace::analyzers::file::analyze_bytes(input, cryptotrace::types::SourceType::Binary) - .expect("Analysis failed"); + let format_result = + cryptotrace::analyzers::file::analyze_bytes(input, cryptotrace::types::SourceType::Binary) + .expect("Analysis failed"); println!("Step 2: Detection complete"); println!(" Algorithm: {:?}", format_result.algorithm); println!(" Type: {}", format_result.detected_type); @@ -23,9 +24,17 @@ byBkZXRlY3QgdGhpcyBzZWNyZXQga2V5IGFuZCBpdHMgZW5jb2Rpbmc= println!(" CVEs: {:?}", format_result.weakness_cve); } - let sw = cryptotrace::core::sliding_entropy::sliding_window_entropy(input, Some(4096), None, Some(0.75)); - println!("Step 3: Sliding window ({} windows, peak {:.2})", - sw.window_scores.len(), sw.max_window_entropy); + let sw = cryptotrace::core::sliding_entropy::sliding_window_entropy( + input, + Some(4096), + None, + Some(0.75), + ); + println!( + "Step 3: Sliding window ({} windows, peak {:.2})", + sw.window_scores.len(), + sw.max_window_entropy + ); if let Some(region) = sw.embedded_regions.first() { println!(" Peak region offset: {}-{}", region.start, region.end); } diff --git a/examples/20_false_positive_analysis.rs b/examples/20_false_positive_analysis.rs index 0a88903..0ccfed7 100644 --- a/examples/20_false_positive_analysis.rs +++ b/examples/20_false_positive_analysis.rs @@ -1,4 +1,4 @@ -use cryptotrace::core::calibration::{generate_synthetic_dataset, train, predict_proba}; +use cryptotrace::core::calibration::{generate_synthetic_dataset, predict_proba, train}; use cryptotrace::types::SignalBreakdown; fn main() { @@ -13,18 +13,31 @@ fn main() { "abcdefghijklmnopqrstuvwxyz", ]; - println!("Running detection on {} plaintext samples:\n", plaintexts.len()); + println!( + "Running detection on {} plaintext samples:\n", + plaintexts.len() + ); for text in &plaintexts { let hash_detection = cryptotrace::core::hashing::detect_hash(text); let enc_detection = cryptotrace::core::encoding::detect_encoding(text); - let algo = hash_detection.as_ref().map(|h| h.algorithm.as_str()).unwrap_or("none"); - let enc = enc_detection.as_ref().map(|e| e.encoding_type.as_str()).unwrap_or("none"); + let algo = hash_detection + .as_ref() + .map(|h| h.algorithm.as_str()) + .unwrap_or("none"); + let enc = enc_detection + .as_ref() + .map(|e| e.encoding_type.as_str()) + .unwrap_or("none"); let is_false_positive = algo != "none" || enc != "none"; - println!(" {:60} hash={:8} enc={:8}{}", - text, algo, enc, - if is_false_positive { " FP" } else { "" }); + println!( + " {:60} hash={:8} enc={:8}{}", + text, + algo, + enc, + if is_false_positive { " FP" } else { "" } + ); } println!("\n--- Calibration to Suppress False Positives ---"); @@ -43,8 +56,15 @@ fn main() { window_variance: Some(0.3), }; let prob = predict_proba(&model, &test_signals); - println!(" {:50} calibrated_prob={:.4} {}", - text, prob, - if prob < 0.3 { "suppressed" } else { "still flagged" }); + println!( + " {:50} calibrated_prob={:.4} {}", + text, + prob, + if prob < 0.3 { + "suppressed" + } else { + "still flagged" + } + ); } } diff --git a/examples/21_entropy_vs_encryption.rs b/examples/21_entropy_vs_encryption.rs index fe0e429..737ba1d 100644 --- a/examples/21_entropy_vs_encryption.rs +++ b/examples/21_entropy_vs_encryption.rs @@ -40,7 +40,10 @@ fn main() { }}, ]; - println!("{:30} {:>8} {:>12} {:>15} {:>10}", "Type", "Entropy", "Sliding Avg", "Encoding", "Algo"); + println!( + "{:30} {:>8} {:>12} {:>15} {:>10}", + "Type", "Entropy", "Sliding Avg", "Encoding", "Algo" + ); println!("{}", "-".repeat(80)); for s in &samples { @@ -50,16 +53,27 @@ fn main() { let enc = cryptotrace::core::encoding::detect_encoding(&text); let algo_s = hash.as_ref().map(|h| h.algorithm.as_str()).unwrap_or("-"); - let enc_s = enc.as_ref().map(|e| e.encoding_type.as_str()).unwrap_or("-"); + let enc_s = enc + .as_ref() + .map(|e| e.encoding_type.as_str()) + .unwrap_or("-"); - let sw = cryptotrace::core::sliding_entropy::sliding_window_entropy(&s.data, Some(4096), None, Some(0.75)); + let sw = cryptotrace::core::sliding_entropy::sliding_window_entropy( + &s.data, + Some(4096), + None, + Some(0.75), + ); let sliding_avg = if !sw.window_scores.is_empty() { sw.window_scores.iter().sum::() / sw.window_scores.len() as f64 } else { 0.0 }; - println!("{:30} {:>7.2} {:>10.2} {:>15} {:>10}", s.label, entropy, sliding_avg, enc_s, algo_s); + println!( + "{:30} {:>7.2} {:>10.2} {:>15} {:>10}", + s.label, entropy, sliding_avg, enc_s, algo_s + ); } println!("\n--- Entropy Confusion Zones ---"); diff --git a/examples/22_custom_detector_plugin.rs b/examples/22_custom_detector_plugin.rs index ba25c56..40de7a0 100644 --- a/examples/22_custom_detector_plugin.rs +++ b/examples/22_custom_detector_plugin.rs @@ -6,13 +6,19 @@ trait EncodingDetector { struct Rot13Detector; impl EncodingDetector for Rot13Detector { - fn name(&self) -> &'static str { "ROT13" } + fn name(&self) -> &'static str { + "ROT13" + } fn detect(&self, input: &str) -> Option { - if input.is_empty() || input.len() > 1024 { return None; } + if input.is_empty() || input.len() > 1024 { + return None; + } let alpha_count = input.chars().filter(|c| c.is_ascii_alphabetic()).count(); - if (alpha_count as f64) / (input.len() as f64) < 0.5 { return None; } + if (alpha_count as f64) / (input.len() as f64) < 0.5 { + return None; + } Some(alpha_count as f64 / input.len() as f64) } @@ -21,16 +27,25 @@ impl EncodingDetector for Rot13Detector { struct HexSpacedDetector; impl EncodingDetector for HexSpacedDetector { - fn name(&self) -> &'static str { "HexSpaced" } + fn name(&self) -> &'static str { + "HexSpaced" + } fn detect(&self, input: &str) -> Option { let trimmed = input.trim(); - if trimmed.len() < 5 { return None; } + if trimmed.len() < 5 { + return None; + } let parts: Vec<&str> = trimmed.split_whitespace().collect(); - if parts.len() < 3 { return None; } + if parts.len() < 3 { + return None; + } - let hex_count = parts.iter().filter(|p| p.len() == 2 && p.chars().all(|c| c.is_ascii_hexdigit())).count(); + let hex_count = parts + .iter() + .filter(|p| p.len() == 2 && p.chars().all(|c| c.is_ascii_hexdigit())) + .count(); if (hex_count as f64) / (parts.len() as f64) > 0.8 { Some(hex_count as f64 / parts.len() as f64) } else { @@ -42,10 +57,8 @@ impl EncodingDetector for HexSpacedDetector { fn main() { println!("=== Custom Detector Plugin System ===\n"); - let detectors: Vec> = vec![ - Box::new(Rot13Detector), - Box::new(HexSpacedDetector), - ]; + let detectors: Vec> = + vec![Box::new(Rot13Detector), Box::new(HexSpacedDetector)]; let test_cases = vec![ "Gur dhvpx oebja sbk whzcf bire gur ynml qbt", @@ -58,15 +71,25 @@ fn main() { println!("Input: {:?}", input); if let Some(h) = cryptotrace::core::hashing::detect_hash(input) { - println!(" Built-in hash: {} (conf={:.2})", h.algorithm, h.confidence); + println!( + " Built-in hash: {} (conf={:.2})", + h.algorithm, h.confidence + ); } if let Some(e) = cryptotrace::core::encoding::detect_encoding(input) { - println!(" Built-in encoding: {} (conf={:.2})", e.encoding_type, e.confidence); + println!( + " Built-in encoding: {} (conf={:.2})", + e.encoding_type, e.confidence + ); } for detector in &detectors { if let Some(confidence) = detector.detect(input) { - println!(" Custom [{}]: detected (conf={:.2})", detector.name(), confidence); + println!( + " Custom [{}]: detected (conf={:.2})", + detector.name(), + confidence + ); } } println!(); diff --git a/examples/23_fuzz_harness_simulation.rs b/examples/23_fuzz_harness_simulation.rs index d4ee7c8..b14b527 100644 --- a/examples/23_fuzz_harness_simulation.rs +++ b/examples/23_fuzz_harness_simulation.rs @@ -14,7 +14,9 @@ fn main() { println!("=== In-Process Fuzz Harness Simulation ===\n"); let iterations: u64 = std::env::var("FUZZ_ITERATIONS") - .ok().and_then(|s| s.parse().ok()).unwrap_or(10_000); + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(10_000); let mut stats = FuzzStats { total_inputs: 0, @@ -46,7 +48,12 @@ fn main() { let (entropy, _) = cryptotrace::core::entropy::shannon_entropy(&input); stats.avg_entropy += entropy; - let _sw = cryptotrace::core::sliding_entropy::sliding_window_entropy(&input, Some(4096), None, Some(0.75)); + let _sw = cryptotrace::core::sliding_entropy::sliding_window_entropy( + &input, + Some(4096), + None, + Some(0.75), + ); } let elapsed = start.elapsed(); @@ -55,11 +62,17 @@ fn main() { println!("=== Fuzz Results ==="); println!(" Total inputs: {}", stats.total_inputs); println!(" Time: {:.2}s", elapsed.as_secs_f64()); - println!(" Throughput: {:.0} inputs/sec", stats.total_inputs as f64 / elapsed.as_secs_f64()); + println!( + " Throughput: {:.0} inputs/sec", + stats.total_inputs as f64 / elapsed.as_secs_f64() + ); println!(" Hash detections: {}", stats.hash_detections); println!(" Encoding detects: {}", stats.enc_detections); println!(" Avg entropy: {:.2}", stats.avg_entropy); - println!(" Input range: {} - {} bytes", stats.min_len, stats.max_len); + println!( + " Input range: {} - {} bytes", + stats.min_len, stats.max_len + ); println!("\nAll detectors stable under fuzzing"); } diff --git a/examples/24_threat_hunting_dashboard.rs b/examples/24_threat_hunting_dashboard.rs index eba1419..693b17b 100644 --- a/examples/24_threat_hunting_dashboard.rs +++ b/examples/24_threat_hunting_dashboard.rs @@ -21,37 +21,75 @@ fn main() { let args: Vec = std::env::args().collect(); let scan_dir = args.get(1).map(|s| s.as_str()).unwrap_or("src"); - let max_size: u64 = std::env::var("MAX_FILE_SIZE").ok().and_then(|s| s.parse().ok()).unwrap_or(1_048_576); + let max_size: u64 = std::env::var("MAX_FILE_SIZE") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(1_048_576); let mut threats: Vec = Vec::new(); scan_directory(scan_dir, max_size, &mut threats); - threats.sort_by(|a, b| b.risk_score.partial_cmp(&a.risk_score).unwrap_or(std::cmp::Ordering::Equal)); + threats.sort_by(|a, b| { + b.risk_score + .partial_cmp(&a.risk_score) + .unwrap_or(std::cmp::Ordering::Equal) + }); let elapsed = start.elapsed(); - println!("Scanned {} files in {:.2}s\n", threats.len(), elapsed.as_secs_f64()); + println!( + "Scanned {} files in {:.2}s\n", + threats.len(), + elapsed.as_secs_f64() + ); let critical = threats.iter().filter(|t| t.risk_score > 7.0).count(); - let high = threats.iter().filter(|t| t.risk_score > 4.0 && t.risk_score <= 7.0).count(); - let medium = threats.iter().filter(|t| t.risk_score > 2.0 && t.risk_score <= 4.0).count(); + let high = threats + .iter() + .filter(|t| t.risk_score > 4.0 && t.risk_score <= 7.0) + .count(); + let medium = threats + .iter() + .filter(|t| t.risk_score > 2.0 && t.risk_score <= 4.0) + .count(); println!("=== Risk Summary ==="); - println!(" Critical: {} High: {} Medium: {}", critical, high, medium); + println!( + " Critical: {} High: {} Medium: {}", + critical, high, medium + ); println!("\n=== Top Threats ==="); - println!("{:6} {:50} {:12} {:8} {:20}", "Score", "Path", "Algorithm", "Entropy", "CVEs"); + println!( + "{:6} {:50} {:12} {:8} {:20}", + "Score", "Path", "Algorithm", "Entropy", "CVEs" + ); println!("{}", "-".repeat(100)); for t in threats.iter().filter(|t| t.risk_score > 2.0).take(20) { let algo = t.algorithm.as_deref().unwrap_or("-"); - let cve_str = if t.cves.is_empty() { "-".into() } else { t.cves.join(",") }; - let path_trunc = if t.path.len() > 50 { format!("...{}", &t.path[t.path.len()-47..]) } else { t.path.clone() }; - println!("{:>5.1} {:50} {:12} {:>7.2} {:20}", t.risk_score, path_trunc, algo, t.entropy, cve_str); + let cve_str = if t.cves.is_empty() { + "-".into() + } else { + t.cves.join(",") + }; + let path_trunc = if t.path.len() > 50 { + format!("...{}", &t.path[t.path.len() - 47..]) + } else { + t.path.clone() + }; + println!( + "{:>5.1} {:50} {:12} {:>7.2} {:20}", + t.risk_score, path_trunc, algo, t.entropy, cve_str + ); } - let avg_entropy: f64 = threats.iter().map(|t| t.entropy).sum::() / threats.len().max(1) as f64; + let avg_entropy: f64 = + threats.iter().map(|t| t.entropy).sum::() / threats.len().max(1) as f64; println!("\n=== Statistics ==="); println!(" Average entropy: {:.2}", avg_entropy); - println!(" Files with CVEs: {}", threats.iter().filter(|t| !t.cves.is_empty()).count()); + println!( + " Files with CVEs: {}", + threats.iter().filter(|t| !t.cves.is_empty()).count() + ); } fn should_skip(path: &Path) -> bool { @@ -75,29 +113,38 @@ fn scan_directory(dir: &str, max_size: u64, threats: &mut Vec) { continue; } - if !path.is_file() { continue; } + if !path.is_file() { + continue; + } let meta = match fs::metadata(&path) { Ok(m) => m, Err(_) => continue, }; - if meta.len() > max_size || meta.len() < 4 { continue; } + if meta.len() > max_size || meta.len() < 4 { + continue; + } let data = match fs::read(&path) { Ok(d) => d, Err(_) => continue, }; - let result = cryptotrace::analyzers::file::analyze_bytes(&data, cryptotrace::types::SourceType::Binary); + let result = cryptotrace::analyzers::file::analyze_bytes( + &data, + cryptotrace::types::SourceType::Binary, + ); let (entropy, _) = cryptotrace::core::entropy::shannon_entropy(&data); if let Ok(r) = result { - let risk_score = r.confidence * 10.0 * match r.risk_level { - cryptotrace::types::RiskLevel::Critical => 10.0, - cryptotrace::types::RiskLevel::High => 7.0, - cryptotrace::types::RiskLevel::Medium => 4.0, - cryptotrace::types::RiskLevel::Low => 2.0, - cryptotrace::types::RiskLevel::Unknown => 1.0, - }; + let risk_score = r.confidence + * 10.0 + * match r.risk_level { + cryptotrace::types::RiskLevel::Critical => 10.0, + cryptotrace::types::RiskLevel::High => 7.0, + cryptotrace::types::RiskLevel::Medium => 4.0, + cryptotrace::types::RiskLevel::Low => 2.0, + cryptotrace::types::RiskLevel::Unknown => 1.0, + }; threats.push(ThreatEntry { path: path.to_string_lossy().into_owned(), diff --git a/examples/25_distributed_scan_coordinator.rs b/examples/25_distributed_scan_coordinator.rs index 3ed3a2b..53bf75f 100644 --- a/examples/25_distributed_scan_coordinator.rs +++ b/examples/25_distributed_scan_coordinator.rs @@ -1,5 +1,5 @@ -use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex}; use std::thread; use std::time::Instant; @@ -71,7 +71,8 @@ impl Coordinator { let start = Instant::now(); let result = cryptotrace::analyzers::file::analyze_bytes( - &data, cryptotrace::types::SourceType::Binary, + &data, + cryptotrace::types::SourceType::Binary, ); let duration = start.elapsed(); @@ -109,8 +110,12 @@ impl Coordinator { println!(" Avg/job: {:.1}ms", avg); for job in jobs.iter() { - println!(" Job {:3}: {:8}ms | {:?}", job.id, job.duration_ms, - job.result.as_deref().unwrap_or("N/A")); + println!( + " Job {:3}: {:8}ms | {:?}", + job.id, + job.duration_ms, + job.result.as_deref().unwrap_or("N/A") + ); } } } @@ -137,7 +142,11 @@ fn main() { coordinator.submit(data.to_vec()); } - println!("Submitted {} jobs to {} workers\n", test_inputs.len(), coordinator.max_workers); + println!( + "Submitted {} jobs to {} workers\n", + test_inputs.len(), + coordinator.max_workers + ); let start = Instant::now(); coordinator.run();