use crate::parser::WasmaConfig;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PlatformWidth {
Bits64,
Bits32Semi,
}
impl PlatformWidth {
pub const fn detect() -> Self {
if cfg!(target_pointer_width = "64") {
Self::Bits64
} else {
Self::Bits32Semi
}
}
pub fn is_full_support(&self) -> bool {
matches!(self, Self::Bits64)
}
pub fn name(&self) -> &'static str {
match self {
Self::Bits64 => "64-bit (full support)",
Self::Bits32Semi => "32-bit (semi-restricted)",
}
}
}
pub const PLATFORM_WIDTH: PlatformWidth = PlatformWidth::detect();
#[derive(Debug, Clone, Copy)]
pub struct ShiftMaskKey {
raw: u64,
effective: u64,
}
impl ShiftMaskKey {
pub fn new(raw: u64) -> Self {
let effective = match PLATFORM_WIDTH {
PlatformWidth::Bits64 => raw,
PlatformWidth::Bits32Semi => raw & 0x0000_0000_FFFF_FFFF, };
Self { raw, effective }
}
pub fn from_seed(seed: &str) -> Self {
let mut h: u64 = 0xcbf2_9ce4_8422_2325; for byte in seed.bytes() {
h ^= byte as u64;
h = h.wrapping_mul(0x0000_0100_0000_01B3); }
Self::new(h)
}
pub fn from_config(config: &WasmaConfig) -> Self {
Self::from_seed(&config.uri_handling.window_app_spec)
}
pub fn raw(&self) -> u64 {
self.raw
}
pub fn effective(&self) -> u64 {
self.effective
}
pub fn derive(&self, context: u8) -> Self {
Self::new(
self.effective
.wrapping_mul(0x9e37_79b9_7f4a_7c15)
.wrapping_add(context as u64),
)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ShiftMaskAlgo {
Xor,
BitRotation,
PolynomialHash,
Lfsr,
}
impl ShiftMaskAlgo {
pub fn name(&self) -> &'static str {
match self {
Self::Xor => "XOR",
Self::BitRotation => "BitRotation",
Self::PolynomialHash => "PolynomialHash",
Self::Lfsr => "LFSR",
}
}
pub fn is_available(&self) -> bool {
match self {
Self::Lfsr => PLATFORM_WIDTH.is_full_support(), _ => true,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ShiftMaskError {
SemiRestricted(String),
InvalidKey,
SizeMismatch,
}
impl std::fmt::Display for ShiftMaskError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::SemiRestricted(msg) => write!(f, "ShiftMask semi-restricted: {}", msg),
Self::InvalidKey => write!(f, "ShiftMask invalid key (zero not allowed)"),
Self::SizeMismatch => write!(f, "ShiftMask buffer size mismatch"),
}
}
}
pub struct ShiftMaskEngine {
key: ShiftMaskKey,
algo: ShiftMaskAlgo,
}
impl ShiftMaskEngine {
pub fn new(key: ShiftMaskKey, algo: ShiftMaskAlgo) -> Result<Self, ShiftMaskError> {
if key.effective() == 0 {
return Err(ShiftMaskError::InvalidKey);
}
if !algo.is_available() {
return Err(ShiftMaskError::SemiRestricted(format!(
"{} requires 64-bit platform",
algo.name()
)));
}
Ok(Self { key, algo })
}
pub fn mask_id(&self, id: u64) -> u64 {
match self.algo {
ShiftMaskAlgo::Xor => self.xor_mask_u64(id),
ShiftMaskAlgo::BitRotation => self.rotate_mask_u64(id),
ShiftMaskAlgo::PolynomialHash => self.poly_mask_u64(id),
ShiftMaskAlgo::Lfsr => self.lfsr_mask_u64(id),
}
}
pub fn unmask_id(&self, masked: u64) -> u64 {
match self.algo {
ShiftMaskAlgo::Xor => self.xor_mask_u64(masked), ShiftMaskAlgo::BitRotation => self.rotate_unmask_u64(masked),
ShiftMaskAlgo::PolynomialHash => self.poly_unmask_u64(masked),
ShiftMaskAlgo::Lfsr => self.lfsr_unmask_u64(masked),
}
}
pub fn mask_stream(&self, data: &mut [u8]) {
match self.algo {
ShiftMaskAlgo::Xor => self.xor_stream(data),
ShiftMaskAlgo::BitRotation => self.rotate_stream(data),
ShiftMaskAlgo::PolynomialHash => self.poly_stream(data),
ShiftMaskAlgo::Lfsr => self.lfsr_stream(data),
}
}
pub fn unmask_stream(&self, data: &mut [u8]) {
self.mask_stream(data);
}
pub fn mask_stream_copy(&self, data: &[u8]) -> Vec<u8> {
let mut out = data.to_vec();
self.mask_stream(&mut out);
out
}
fn xor_mask_u64(&self, v: u64) -> u64 {
v ^ self.key.effective()
}
fn xor_stream(&self, data: &mut [u8]) {
let key_bytes = self.key.effective().to_le_bytes();
for (i, byte) in data.iter_mut().enumerate() {
*byte ^= key_bytes[i % 8];
}
}
fn rotation_amount(&self) -> u32 {
match PLATFORM_WIDTH {
PlatformWidth::Bits64 => (self.key.effective() & 0x3F) as u32, PlatformWidth::Bits32Semi => (self.key.effective() & 0x1F) as u32, }
}
fn rotate_mask_u64(&self, v: u64) -> u64 {
let r = self.rotation_amount();
match PLATFORM_WIDTH {
PlatformWidth::Bits64 => v.rotate_left(r),
PlatformWidth::Bits32Semi => {
let lo = (v as u32).rotate_left(r);
let hi = ((v >> 32) as u32).rotate_left(r);
lo as u64 | ((hi as u64) << 32)
}
}
}
fn rotate_unmask_u64(&self, v: u64) -> u64 {
let r = self.rotation_amount();
match PLATFORM_WIDTH {
PlatformWidth::Bits64 => v.rotate_right(r),
PlatformWidth::Bits32Semi => {
let lo = (v as u32).rotate_right(r);
let hi = ((v >> 32) as u32).rotate_right(r);
lo as u64 | ((hi as u64) << 32)
}
}
}
fn rotate_stream(&self, data: &mut [u8]) {
let r = (self.rotation_amount() % 8) as u32;
if r == 0 {
return;
}
for byte in data.iter_mut() {
*byte = byte.rotate_left(r);
}
}
const GF64_POLY: u64 = 0x0000_0000_0000_001B;
const GF32_POLY: u64 = 0x0000_0000_0000_00AF;
fn gf_mul(&self, a: u64, b: u64) -> u64 {
let (width, poly) = match PLATFORM_WIDTH {
PlatformWidth::Bits64 => (64u32, Self::GF64_POLY),
PlatformWidth::Bits32Semi => (32u32, Self::GF32_POLY),
};
let mask = if width == 64 {
u64::MAX
} else {
(1u64 << width) - 1
};
let mut result: u64 = 0;
let mut a = a & mask;
let mut b = b & mask;
while b > 0 {
if b & 1 == 1 {
result ^= a;
}
let carry = (a >> (width - 1)) & 1;
a = (a << 1) & mask;
if carry == 1 {
a ^= poly;
}
b >>= 1;
}
result
}
fn poly_mask_u64(&self, v: u64) -> u64 {
let k = self.key.effective();
self.gf_mul(v, k) ^ k.wrapping_mul(0x9e37_79b9_7f4a_7c15)
}
fn poly_unmask_u64(&self, v: u64) -> u64 {
let k = self.key.effective();
let v2 = v ^ k.wrapping_mul(0x9e37_79b9_7f4a_7c15);
self.gf_mul(v2, k.wrapping_add(1))
}
fn poly_stream(&self, data: &mut [u8]) {
let key_bytes = self.key.effective().to_le_bytes();
let poly_byte = (Self::GF32_POLY & 0xFF) as u8;
for (i, byte) in data.iter_mut().enumerate() {
let k = key_bytes[i % 8];
*byte ^= k;
*byte = byte.wrapping_add(poly_byte.wrapping_mul(i as u8));
}
}
const LFSR64_TAPS: u64 = 0xD800_0000_0000_0000;
fn lfsr_next(state: u64) -> u64 {
let lsb = state & 1;
let next = state >> 1;
if lsb == 1 {
next ^ Self::LFSR64_TAPS
} else {
next
}
}
fn lfsr_mask_u64(&self, v: u64) -> u64 {
let mut state = self.key.effective();
let steps = (state & 0xFF).max(1);
for _ in 0..steps {
state = Self::lfsr_next(state);
}
v ^ state
}
fn lfsr_unmask_u64(&self, v: u64) -> u64 {
self.lfsr_mask_u64(v)
}
fn lfsr_stream(&self, data: &mut [u8]) {
let mut state = self.key.effective();
for byte in data.iter_mut() {
state = Self::lfsr_next(state);
*byte ^= (state & 0xFF) as u8;
}
}
pub fn algo(&self) -> ShiftMaskAlgo {
self.algo
}
pub fn key(&self) -> &ShiftMaskKey {
&self.key
}
pub fn platform_width(&self) -> PlatformWidth {
PLATFORM_WIDTH
}
}
pub struct WindowIdEscaper {
engine: ShiftMaskEngine,
masked: std::collections::HashMap<u64, u64>,
reverse: std::collections::HashMap<u64, u64>,
}
impl WindowIdEscaper {
pub fn new(engine: ShiftMaskEngine) -> Self {
Self {
engine,
masked: std::collections::HashMap::new(),
reverse: std::collections::HashMap::new(),
}
}
pub fn register(&mut self, real_id: u64) -> u64 {
if let Some(&existing) = self.masked.get(&real_id) {
return existing;
}
let masked = self.engine.mask_id(real_id);
self.masked.insert(real_id, masked);
self.reverse.insert(masked, real_id);
masked
}
pub fn resolve(&self, masked_id: u64) -> Option<u64> {
if let Some(&real) = self.reverse.get(&masked_id) {
return Some(real);
}
Some(self.engine.unmask_id(masked_id))
}
pub fn unregister(&mut self, real_id: u64) {
if let Some(masked) = self.masked.remove(&real_id) {
self.reverse.remove(&masked);
}
}
pub fn masked_id_of(&self, real_id: u64) -> Option<u64> {
self.masked.get(&real_id).copied()
}
pub fn registered_count(&self) -> usize {
self.masked.len()
}
}
pub struct StreamEscaper {
engine: ShiftMaskEngine,
}
impl StreamEscaper {
pub fn new(engine: ShiftMaskEngine) -> Self {
Self { engine }
}
pub fn mask(&self, data: &mut [u8]) {
self.engine.mask_stream(data);
}
pub fn unmask(&self, data: &mut [u8]) {
self.engine.unmask_stream(data);
}
pub fn mask_copy(&self, data: &[u8]) -> Vec<u8> {
self.engine.mask_stream_copy(data)
}
pub fn algo(&self) -> ShiftMaskAlgo {
self.engine.algo()
}
}
pub struct PosixWindowEsc {
pub id_escaper: WindowIdEscaper,
pub stream_escaper: StreamEscaper,
pub platform: PlatformWidth,
}
impl PosixWindowEsc {
pub fn new(key: ShiftMaskKey, algo: ShiftMaskAlgo) -> Result<Self, ShiftMaskError> {
let id_engine = ShiftMaskEngine::new(key, algo)?;
let stream_key = key.derive(0xA5);
let stream_engine = ShiftMaskEngine::new(stream_key, algo)?;
Ok(Self {
id_escaper: WindowIdEscaper::new(id_engine),
stream_escaper: StreamEscaper::new(stream_engine),
platform: PLATFORM_WIDTH,
})
}
pub fn from_config(config: &WasmaConfig, algo: ShiftMaskAlgo) -> Result<Self, ShiftMaskError> {
let key = ShiftMaskKey::from_config(config);
Self::new(key, algo)
}
pub fn from_config_auto(config: &WasmaConfig) -> Result<Self, ShiftMaskError> {
let algo = if PLATFORM_WIDTH.is_full_support() {
ShiftMaskAlgo::Lfsr
} else {
ShiftMaskAlgo::Xor
};
Self::from_config(config, algo)
}
pub fn print_info(&self) {
println!("╔══════════════════════════════════════════╗");
println!("║ WASMA PosixWindowEsc Info ║");
println!("╚══════════════════════════════════════════╝");
println!(" Platform: {}", self.platform.name());
println!(" ID algo: {}", self.id_escaper.engine.algo().name());
println!(" Stream algo: {}", self.stream_escaper.algo().name());
println!(
" Registered: {} windows",
self.id_escaper.registered_count()
);
if !self.platform.is_full_support() {
println!(" ⚠️ Semi-restricted mode: LFSR disabled, 32-bit rotation");
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parser::ConfigParser;
fn make_config() -> WasmaConfig {
let parser = ConfigParser::new(None);
let content = parser.generate_default_config();
parser.parse(&content).unwrap()
}
fn make_key() -> ShiftMaskKey {
ShiftMaskKey::new(0xDEAD_BEEF_CAFE_1234)
}
fn make_engine(algo: ShiftMaskAlgo) -> Option<ShiftMaskEngine> {
ShiftMaskEngine::new(make_key(), algo).ok()
}
#[test]
fn test_platform_detection() {
let p = PLATFORM_WIDTH;
println!("✅ Platform: {}", p.name());
assert!(p.name().len() > 0);
}
#[test]
fn test_key_from_seed() {
let k1 = ShiftMaskKey::from_seed("wasma.app");
let k2 = ShiftMaskKey::from_seed("wasma.app");
let k3 = ShiftMaskKey::from_seed("other.app");
assert_eq!(k1.raw(), k2.raw());
assert_ne!(k1.raw(), k3.raw());
println!("✅ ShiftMaskKey from seed deterministic");
}
#[test]
fn test_key_derive() {
let k = make_key();
let d1 = k.derive(0xA5);
let d2 = k.derive(0xA5);
let d3 = k.derive(0x01);
assert_eq!(d1.raw(), d2.raw());
assert_ne!(d1.raw(), d3.raw());
println!("✅ ShiftMaskKey derive deterministic");
}
#[test]
fn test_xor_id_roundtrip() {
if let Some(engine) = make_engine(ShiftMaskAlgo::Xor) {
for id in [0u64, 1, 0xFFFF_FFFF, u64::MAX, 0xDEAD_BEEF] {
let masked = engine.mask_id(id);
let back = engine.unmask_id(masked);
assert_eq!(back, id, "XOR roundtrip failed for id={}", id);
}
println!("✅ XOR ID roundtrip working");
}
}
#[test]
fn test_bit_rotation_id_roundtrip() {
if let Some(engine) = make_engine(ShiftMaskAlgo::BitRotation) {
for id in [1u64, 42, 0x1234_5678_9ABC_DEF0, u64::MAX / 2] {
let masked = engine.mask_id(id);
let back = engine.unmask_id(masked);
assert_eq!(back, id, "BitRotation roundtrip failed for id={}", id);
}
println!("✅ BitRotation ID roundtrip working");
}
}
#[test]
fn test_poly_id_masking() {
if let Some(engine) = make_engine(ShiftMaskAlgo::PolynomialHash) {
let id = 0x1234u64;
let masked = engine.mask_id(id);
assert_ne!(masked, id);
println!("✅ PolynomialHash ID masking working: {} → {}", id, masked);
}
}
#[test]
fn test_lfsr_id_roundtrip() {
if PLATFORM_WIDTH.is_full_support() {
if let Some(engine) = make_engine(ShiftMaskAlgo::Lfsr) {
for id in [1u64, 0xABCD_1234, u64::MAX] {
let masked = engine.mask_id(id);
let back = engine.unmask_id(masked);
assert_eq!(back, id);
}
println!("✅ LFSR ID roundtrip working (64-bit)");
}
} else {
let result = ShiftMaskEngine::new(make_key(), ShiftMaskAlgo::Lfsr);
assert!(matches!(result, Err(ShiftMaskError::SemiRestricted(_))));
println!("✅ LFSR correctly blocked on 32-bit semi");
}
}
#[test]
fn test_xor_stream_roundtrip() {
if let Some(engine) = make_engine(ShiftMaskAlgo::Xor) {
let original = b"WASMA stream data test 1234567890";
let mut data = original.to_vec();
engine.mask_stream(&mut data);
assert_ne!(data, original);
engine.unmask_stream(&mut data);
assert_eq!(data, original);
println!("✅ XOR stream roundtrip working");
}
}
#[test]
fn test_rotation_stream_roundtrip() {
if let Some(engine) = make_engine(ShiftMaskAlgo::BitRotation) {
let original = vec![0xABu8; 64];
let mut data = original.clone();
engine.mask_stream(&mut data);
engine.unmask_stream(&mut data);
assert_eq!(data, original);
println!("✅ BitRotation stream roundtrip working");
}
}
#[test]
fn test_window_id_escaper() {
if let Some(engine) = make_engine(ShiftMaskAlgo::Xor) {
let mut escaper = WindowIdEscaper::new(engine);
let real_ids = [1u64, 2, 3, 100, 999];
let masked: Vec<u64> = real_ids.iter().map(|&id| escaper.register(id)).collect();
for i in 0..masked.len() {
for j in i + 1..masked.len() {
assert_ne!(masked[i], masked[j]);
}
}
for (i, &real) in real_ids.iter().enumerate() {
assert_eq!(escaper.resolve(masked[i]), Some(real));
}
assert_eq!(escaper.register(real_ids[0]), masked[0]);
println!(
"✅ WindowIdEscaper working ({} windows)",
escaper.registered_count()
);
}
}
#[test]
fn test_stream_escaper() {
if let Some(engine) = make_engine(ShiftMaskAlgo::Xor) {
let escaper = StreamEscaper::new(engine);
let original = b"test data stream";
let masked = escaper.mask_copy(original);
assert_ne!(masked, original);
let mut back = masked.clone();
escaper.unmask(&mut back);
assert_eq!(back, original);
println!("✅ StreamEscaper working");
}
}
#[test]
fn test_posix_window_esc_xor() {
let config = make_config();
let mut esc = PosixWindowEsc::from_config(&config, ShiftMaskAlgo::Xor).unwrap();
let real_id = 42u64;
let masked = esc.id_escaper.register(real_id);
assert_ne!(masked, real_id);
assert_eq!(esc.id_escaper.resolve(masked), Some(real_id));
let data = b"hello world";
let masked_data = esc.stream_escaper.mask_copy(data);
assert_ne!(masked_data, data);
esc.print_info();
println!("✅ PosixWindowEsc (XOR) working");
}
#[test]
fn test_posix_window_esc_auto() {
let config = make_config();
let esc = PosixWindowEsc::from_config_auto(&config);
assert!(esc.is_ok());
let esc = esc.unwrap();
println!(
"✅ PosixWindowEsc auto-algo: {}",
esc.id_escaper.engine.algo().name()
);
}
#[test]
fn test_invalid_zero_key() {
let key = ShiftMaskKey::new(0);
let result = ShiftMaskEngine::new(key, ShiftMaskAlgo::Xor);
assert!(matches!(result, Err(ShiftMaskError::InvalidKey)));
println!("✅ Zero key correctly rejected");
}
#[test]
fn test_mask_stream_copy_independent() {
if let Some(engine) = make_engine(ShiftMaskAlgo::Xor) {
let original = b"independent copy test";
let copy = engine.mask_stream_copy(original);
assert_eq!(original, b"independent copy test");
assert_ne!(copy.as_slice(), original.as_slice());
println!("✅ mask_stream_copy does not modify original");
}
}
}