px_native/cipher/xor.rs
1//! `jw(t, n)` — single-byte XOR stream cipher used by the eT15wiaE
2//! tenant for both the payload stream (key `IS = 50`) and the secret
3//! feed (key `VJ = 10`). See `px-research/notes/eT15wiaE/r3-…`.
4
5/// Payload-cipher XOR key.
6pub const IS: u8 = 50;
7/// Secret-feed XOR key.
8pub const VJ: u8 = 10;
9
10/// XOR every byte of `buf` with `key`.
11///
12/// JS source: `function jw(t, n) { ... String.fromCharCode(n ^ t.charCodeAt(r)) ... }`
13/// All real call sites in the captured init.js pass ASCII-range inputs
14/// (`hP` produces base64 bytes; `JSON.stringify` produces UTF-8 bytes
15/// without surrogate pairs in our usage), so the JS UTF-16 semantics
16/// collapse to byte XOR.
17pub fn jw(buf: &[u8], key: u8) -> Vec<u8> {
18 buf.iter().map(|b| b ^ key).collect()
19}
20
21#[cfg(test)]
22mod tests {
23 use super::*;
24
25 #[test]
26 fn xor_is_involutive() {
27 let plain = b"hello world";
28 let cipher = jw(plain, IS);
29 assert_eq!(jw(&cipher, IS), plain);
30 }
31
32 #[test]
33 fn empty_input_returns_empty() {
34 assert!(jw(b"", IS).is_empty());
35 }
36}