Files
multiverse/xcom-ultra/xcu-crypto/src/shield.rs
T

51 lines
1.8 KiB
Rust

// [TSM.ID].[11031972] -- All Rights Reserved. Proprietary & Confidential.
use aes_gcm::{
aead::{Aead, AeadCore, KeyInit, OsRng},
Aes256Gcm, Nonce, Key
};
pub type ShieldResult<T> = std::result::Result<T, String>;
/// Mengamankan frame video dengan AES-256-GCM.
/// Frame ini tidak akan bisa dibuka oleh VPS XCU (Zero-Knowledge).
pub fn lock_video_frame(secret_key: &[u8], frame_data: &[u8]) -> ShieldResult<Vec<u8>> {
if secret_key.len() != 32 {
return Err("Kunci AES-256 wajib 32 bytes (256 bits).".to_string());
}
let key = Key::<Aes256Gcm>::from_slice(secret_key);
let cipher = Aes256Gcm::new(key);
// Generate Nonce Kuantum (12-bytes)
let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
// Eksekusi Enkripsi Militer
let mut ciphertext = cipher.encrypt(&nonce, frame_data)
.map_err(|e| format!("Gagal mengenkripsi frame: {:?}", e))?;
// Menggabungkan Nonce dengan Ciphertext agar bisa di dekripsi di ujung penerima
let mut final_payload = nonce.to_vec();
final_payload.append(&mut ciphertext);
Ok(final_payload)
}
/// Membuka frame video yang datang dari Server Buta (XCU)
pub fn unlock_video_frame(secret_key: &[u8], encrypted_payload: &[u8]) -> ShieldResult<Vec<u8>> {
if encrypted_payload.len() < 12 {
return Err("Payload cacat atau telah diubah peretas (Missing Nonce).".to_string());
}
let key = Key::<Aes256Gcm>::from_slice(secret_key);
let cipher = Aes256Gcm::new(key);
let (nonce_bytes, ciphertext) = encrypted_payload.split_at(12);
let nonce = Nonce::from_slice(nonce_bytes);
// Eksekusi Dekripsi Militer
let plaintext = cipher.decrypt(nonce, ciphertext)
.map_err(|_| "Kunci salah atau Data disadap (Integrity Check Failed).".to_string())?;
Ok(plaintext)
}