1
2
3
4
5
6 package io.github.olyutorskii.aletojio.bijection;
7
8 import io.github.olyutorskii.aletojio.rng.RndInt32;
9 import java.util.Arrays;
10 import java.util.Objects;
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public class Pbox32 implements RndInt32 {
28
29 private static final String ERRMSG_LENGTH = "P-box table must be 32 entry";
30 private static final String ERRMSG_BIJECTION = "P-box table must be bijection";
31
32 private static final int START = 17;
33 private static final int STEP = 19;
34
35 private static final int[] DEF_PERM;
36
37 static {
38 DEF_PERM = new int[Integer.SIZE];
39 for (int ct = 0; ct < Integer.SIZE; ct++) {
40 DEF_PERM[ct] = (START + STEP * ct) % Integer.SIZE;
41 }
42 }
43
44
45 private final RndInt32 rnd;
46 private final int[] permute = new int[Integer.SIZE];
47
48
49
50
51
52
53
54
55
56 public Pbox32(RndInt32 rndArg)
57 throws NullPointerException, IllegalArgumentException {
58 this(rndArg, DEF_PERM);
59 return;
60 }
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public Pbox32(RndInt32 rndArg, int[] permuteArg)
77 throws NullPointerException, IllegalArgumentException {
78 super();
79 Objects.requireNonNull(rndArg);
80 Objects.requireNonNull(permuteArg);
81
82 this.rnd = rndArg;
83
84 checkPbox(permuteArg);
85 System.arraycopy(permuteArg, 0, this.permute, 0, Integer.SIZE);
86
87 return;
88 }
89
90
91
92
93
94
95
96
97
98
99 public static int mapPermutation(int iVal) {
100 int result = mapTable(iVal, DEF_PERM);
101 return result;
102 }
103
104
105
106
107
108
109
110
111
112
113
114 public static int mapTable(int iVal, int[] table) {
115 Objects.requireNonNull(table);
116
117 int result = 0;
118
119 for (int idx = 0; idx < Integer.SIZE; idx++) {
120 int bitVal = (iVal >>> idx) & 0b1;
121 int toPos = table[idx];
122 result |= bitVal << toPos;
123 }
124
125 return result;
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 public static void checkPbox(int[] permuteArg)
142 throws NullPointerException, IllegalArgumentException {
143 Objects.requireNonNull(permuteArg);
144 if (permuteArg.length != Integer.SIZE) {
145 throw new IllegalArgumentException(ERRMSG_LENGTH);
146 }
147
148
149 int[] sorted = Arrays.copyOf(permuteArg, Integer.SIZE);
150 Arrays.sort(sorted);
151 for (int src = 0; src < Integer.SIZE; src++) {
152 int dst = sorted[src];
153 if (dst != src) {
154 throw new IllegalArgumentException(ERRMSG_BIJECTION);
155 }
156 }
157
158 return;
159 }
160
161
162
163
164
165
166
167 @Override
168 public int nextInt32() {
169 int iVal = this.rnd.nextInt32();
170 int result = mapTable(iVal, this.permute);
171 return result;
172 }
173
174 }