skrillax_security/
count.rs1use std::cmp::max;
2
3fn generate_value(mut value: u32) -> u32 {
4 for _ in 0..32 {
5 let mut v = value;
6 v = (v >> 2) ^ value;
7 v = (v >> 2) ^ value;
8 v = (v >> 1) ^ value;
9 v = (v >> 1) ^ value;
10 v = (v >> 1) ^ value;
11 value = (((value >> 1) | (value << 31)) & (!1)) | (v & 1);
12 }
13 value
14}
15
16pub struct MessageCounter {
31 seeds: [u8; 3],
32}
33
34impl MessageCounter {
35 pub fn new(seed: u32) -> MessageCounter {
37 let mut1 = generate_value(seed);
38 let mut2 = generate_value(mut1);
39 let mut3 = generate_value(mut2);
40 let mut4 = generate_value(mut3);
41
42 let byte1 = (mut1 as u8) ^ (mut2 as u8);
43 let byte1 = max(byte1, 1);
44
45 let byte2 = (mut3 as u8) ^ (mut4 as u8);
46 let byte2 = max(byte2, 1);
47
48 MessageCounter {
49 seeds: [byte1 ^ byte2, byte1, byte2],
50 }
51 }
52
53 pub fn next_byte(&mut self) -> u8 {
58 let value = (self.seeds[2] as u32 * (!self.seeds[0] as u32 + self.seeds[1] as u32)) as u8;
59 self.seeds[0] = value ^ value >> 4;
60
61 self.seeds[0]
62 }
63}
64
65#[cfg(test)]
66mod test {
67 use super::*;
68
69 #[test]
70 fn test_sniffed() {
71 let mut counter = MessageCounter::new(0x7c);
72 assert_eq!(counter.next_byte(), 0xb7);
73 }
74}