use std::time::{Instant, Duration};
use zeroize::Zeroize;
use tracing::{info, warn};
use super::scatterer::ScatteredParts;
pub trait KeyAssembler: Send + Sync {
fn assemble(&self, parts: &ScatteredParts) -> [u8; 32];
fn execution_time_ns(&self) -> u64;
}
#[cfg(all(target_arch = "x86_64", target_feature = "avx2", target_feature = "aes"))]
pub struct Avx2AesAssembler;
#[cfg(all(target_arch = "x86_64", target_feature = "avx2", target_feature = "aes"))]
impl KeyAssembler for Avx2AesAssembler {
fn assemble(&self, parts: &ScatteredParts) -> [u8; 32] {
GenericAssembler.assemble(parts)
}
fn execution_time_ns(&self) -> u64 {
10
}
}
#[cfg(all(target_arch = "aarch64", target_feature = "neon"))]
pub struct NeonAssembler;
#[cfg(all(target_arch = "aarch64", target_feature = "neon"))]
impl KeyAssembler for NeonAssembler {
fn assemble(&self, parts: &ScatteredParts) -> [u8; 32] {
GenericAssembler.assemble(parts)
}
fn execution_time_ns(&self) -> u64 {
15
}
}
pub struct GenericAssembler;
impl KeyAssembler for GenericAssembler {
fn assemble(&self, parts: &ScatteredParts) -> [u8; 32] {
let start = Instant::now();
let mut ram_part = [0u8; 32];
for i in 0..32 {
ram_part[i] = parts.ram_part_encrypted[i] ^ parts.ram_part_iv[i % 12];
}
let mut key = [0u8; 32];
const FIXED_ITERATIONS: usize = 64;
for iteration in 0..FIXED_ITERATIONS {
for i in 0..32 {
let mut value = 0u8;
if i < 8 {
value ^= parts.l1_part[i];
}
if i < 16 {
value ^= parts.l2_part[i % 16];
}
value ^= ram_part[i];
value ^= parts.register_seed[i % 16];
value = value.rotate_left((iteration % 8) as u32);
key[i] = value;
}
}
let elapsed = start.elapsed();
if elapsed.as_nanos() > 200 {
warn!("⚠️ SLOW KEY ASSEMBLY: {:?} ({:?} ns) - ТРЕБОВАНИЕ: 20-200ns",
elapsed, elapsed.as_nanos());
} else if elapsed.as_nanos() < 20 {
warn!("⚠️ SUSPICIOUSLY FAST KEY ASSEMBLY: {:?} ({:?} ns)",
elapsed, elapsed.as_nanos());
} else {
info!("✅ Key assembly: {:?} ({:?} ns) - В НОРМЕ",
elapsed, elapsed.as_nanos());
}
assert!(elapsed < Duration::from_micros(100),
"Timing anomaly detected: {:?}", elapsed);
ram_part.zeroize();
key
}
fn execution_time_ns(&self) -> u64 {
66
}
}
#[derive(Default)]
pub struct KeyAssemblerFactory;
impl KeyAssemblerFactory {
pub fn create_assembler(&self) -> Box<dyn KeyAssembler> {
#[cfg(all(target_arch = "x86_64", target_feature = "avx2", target_feature = "aes"))]
{
if is_x86_feature_detected!("avx2") && is_x86_feature_detected!("aes") {
return Box::new(Avx2AesAssembler);
}
}
#[cfg(all(target_arch = "aarch64", target_feature = "neon"))]
{
use std::arch::is_aarch64_feature_detected;
if is_aarch64_feature_detected!("neon") {
return Box::new(NeonAssembler);
}
}
Box::new(GenericAssembler)
}
}