1#[inline(always)]
5fn sip_round(mut v0: u64, mut v1: u64, mut v2: u64, mut v3: u64) -> (u64, u64, u64, u64) {
6 v0 = v0.wrapping_add(v1); v2 = v2.wrapping_add(v3);
7 v1 = v1.rotate_left(13); v3 = v3.rotate_left(16);
8 v1 ^= v0; v3 ^= v2;
9 v0 = v0.rotate_left(32);
10 v2 = v2.wrapping_add(v1); v0 = v0.wrapping_add(v3);
11 v1 = v1.rotate_left(17); v3 = v3.rotate_left(21);
12 v1 ^= v2; v3 ^= v0;
13 v2 = v2.rotate_left(32);
14 (v0, v1, v2, v3)
15}
16
17fn collatz_step(mut n: u128) -> u128 {
18 if n % 2 == 0 { n /= 2; }
19 else { n = n.wrapping_mul(3).wrapping_add(1); }
20 if n <= 1 { n = 0xdeadbeef1337cafe; }
21 if n > (u64::MAX as u128) { n = (n % u64::MAX as u128) + 7; }
22 n
23}
24
25pub fn lambda_process(data: &[u8], seed_hi: u64, seed_lo: u64) -> Vec<u8> {
26 let mut n = ((seed_hi as u128) << 64) | (seed_lo as u128);
27 let mut v0 = seed_hi ^ 0x736f6d6570736575;
28 let mut v1 = seed_lo ^ 0x646f72616e646f6d;
29 let mut v2 = seed_hi ^ 0x6c7967656e657261;
30 let mut v3 = seed_lo ^ 0x7465646279746573;
31
32 let mut result = Vec::with_capacity(data.len());
33 let mut counter: u64 = 0;
34
35 for &byte in data {
36 for _ in 0..8 { n = collatz_step(n); }
38
39 v3 ^= n as u64 ^ counter;
41 let (r0, r1, r2, r3) = sip_round(v0, v1, v2, v3);
42 v0 = r0; v1 = r1; v2 = r2; v3 = r3;
43
44 let keystream_byte = (v0 ^ v1 ^ v2 ^ v3) as u8;
45 result.push(byte ^ keystream_byte);
46 counter = counter.wrapping_add(1);
47 }
48 result
49}
50
51pub fn lambda_keystream(len: usize, seed_hi: u64, seed_lo: u64) -> Vec<u8> {
52 let dummy = vec![0u8; len];
53 lambda_process(&dummy, seed_hi, seed_lo)
54}