1use crate::{DispatchResult, OpFrame, OperationTable};
2
3#[derive(Debug, Clone)]
5pub struct SelectorPermutation {
6 logical_to_physical: [u8; 256],
7 physical_to_logical: [u8; 256],
8}
9
10impl SelectorPermutation {
11 pub fn from_seed(seed: u64) -> Self {
13 let mut arr = [0u8; 256];
14 let mut i = 0usize;
15 while i < 256 {
16 arr[i] = i as u8;
17 i += 1;
18 }
19 let mut x = seed;
20 let mut j = 255usize;
21 while j > 0 {
22 x ^= x << 13;
23 x ^= x >> 7;
24 x ^= x << 17;
25 let k = (x as usize) % (j + 1);
26 arr.swap(j, k);
27 j -= 1;
28 }
29 let mut inv = [0u8; 256];
30 for (logical, physical) in arr.iter().enumerate() {
31 inv[*physical as usize] = logical as u8;
32 }
33 Self { logical_to_physical: arr, physical_to_logical: inv }
34 }
35
36 pub fn encode(&self, logical: u8) -> u8 { self.logical_to_physical[logical as usize] }
38
39 pub fn decode(&self, physical: u8) -> u8 { self.physical_to_logical[physical as usize] }
41}
42
43#[derive(Debug, Clone)]
45pub struct ShuffledOperationTable {
46 table: OperationTable,
47 permutation: SelectorPermutation,
48}
49
50impl ShuffledOperationTable {
51 pub fn new(logical: OperationTable, seed: u64) -> Self {
53 Self { table: logical, permutation: SelectorPermutation::from_seed(seed) }
54 }
55
56 pub fn encode_selector(&self, logical: u8) -> u8 { self.permutation.encode(logical) }
58
59 pub fn execute_physical(&self, physical: u8, frame: OpFrame) -> DispatchResult<OpFrame> {
61 let logical = self.permutation.decode(physical);
62 self.table.execute(logical, frame)
63 }
64}