1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.gordianknot.impl.ext.engines;
18
19 import org.bouncycastle.crypto.CipherParameters;
20 import org.bouncycastle.crypto.DataLengthException;
21 import org.bouncycastle.crypto.OutputLengthException;
22 import org.bouncycastle.crypto.StreamCipher;
23 import org.bouncycastle.crypto.params.KeyParameter;
24 import org.bouncycastle.crypto.params.ParametersWithIV;
25 import org.bouncycastle.util.Memoable;
26
27
28
29
30
31 @SuppressWarnings("checkstyle:MagicNumber")
32 public class GordianSnow3GEngine
33 implements StreamCipher, Memoable {
34
35
36
37 private static final byte[] SR = {
38 (byte) 0x63, (byte) 0x7C, (byte) 0x77, (byte) 0x7B, (byte) 0xF2, (byte) 0x6B, (byte) 0x6F, (byte) 0xC5,
39 (byte) 0x30, (byte) 0x01, (byte) 0x67, (byte) 0x2B, (byte) 0xFE, (byte) 0xD7, (byte) 0xAB, (byte) 0x76,
40 (byte) 0xCA, (byte) 0x82, (byte) 0xC9, (byte) 0x7D, (byte) 0xFA, (byte) 0x59, (byte) 0x47, (byte) 0xF0,
41 (byte) 0xAD, (byte) 0xD4, (byte) 0xA2, (byte) 0xAF, (byte) 0x9C, (byte) 0xA4, (byte) 0x72, (byte) 0xC0,
42 (byte) 0xB7, (byte) 0xFD, (byte) 0x93, (byte) 0x26, (byte) 0x36, (byte) 0x3F, (byte) 0xF7, (byte) 0xCC,
43 (byte) 0x34, (byte) 0xA5, (byte) 0xE5, (byte) 0xF1, (byte) 0x71, (byte) 0xD8, (byte) 0x31, (byte) 0x15,
44 (byte) 0x04, (byte) 0xC7, (byte) 0x23, (byte) 0xC3, (byte) 0x18, (byte) 0x96, (byte) 0x05, (byte) 0x9A,
45 (byte) 0x07, (byte) 0x12, (byte) 0x80, (byte) 0xE2, (byte) 0xEB, (byte) 0x27, (byte) 0xB2, (byte) 0x75,
46 (byte) 0x09, (byte) 0x83, (byte) 0x2C, (byte) 0x1A, (byte) 0x1B, (byte) 0x6E, (byte) 0x5A, (byte) 0xA0,
47 (byte) 0x52, (byte) 0x3B, (byte) 0xD6, (byte) 0xB3, (byte) 0x29, (byte) 0xE3, (byte) 0x2F, (byte) 0x84,
48 (byte) 0x53, (byte) 0xD1, (byte) 0x00, (byte) 0xED, (byte) 0x20, (byte) 0xFC, (byte) 0xB1, (byte) 0x5B,
49 (byte) 0x6A, (byte) 0xCB, (byte) 0xBE, (byte) 0x39, (byte) 0x4A, (byte) 0x4C, (byte) 0x58, (byte) 0xCF,
50 (byte) 0xD0, (byte) 0xEF, (byte) 0xAA, (byte) 0xFB, (byte) 0x43, (byte) 0x4D, (byte) 0x33, (byte) 0x85,
51 (byte) 0x45, (byte) 0xF9, (byte) 0x02, (byte) 0x7F, (byte) 0x50, (byte) 0x3C, (byte) 0x9F, (byte) 0xA8,
52 (byte) 0x51, (byte) 0xA3, (byte) 0x40, (byte) 0x8F, (byte) 0x92, (byte) 0x9D, (byte) 0x38, (byte) 0xF5,
53 (byte) 0xBC, (byte) 0xB6, (byte) 0xDA, (byte) 0x21, (byte) 0x10, (byte) 0xFF, (byte) 0xF3, (byte) 0xD2,
54 (byte) 0xCD, (byte) 0x0C, (byte) 0x13, (byte) 0xEC, (byte) 0x5F, (byte) 0x97, (byte) 0x44, (byte) 0x17,
55 (byte) 0xC4, (byte) 0xA7, (byte) 0x7E, (byte) 0x3D, (byte) 0x64, (byte) 0x5D, (byte) 0x19, (byte) 0x73,
56 (byte) 0x60, (byte) 0x81, (byte) 0x4F, (byte) 0xDC, (byte) 0x22, (byte) 0x2A, (byte) 0x90, (byte) 0x88,
57 (byte) 0x46, (byte) 0xEE, (byte) 0xB8, (byte) 0x14, (byte) 0xDE, (byte) 0x5E, (byte) 0x0B, (byte) 0xDB,
58 (byte) 0xE0, (byte) 0x32, (byte) 0x3A, (byte) 0x0A, (byte) 0x49, (byte) 0x06, (byte) 0x24, (byte) 0x5C,
59 (byte) 0xC2, (byte) 0xD3, (byte) 0xAC, (byte) 0x62, (byte) 0x91, (byte) 0x95, (byte) 0xE4, (byte) 0x79,
60 (byte) 0xE7, (byte) 0xC8, (byte) 0x37, (byte) 0x6D, (byte) 0x8D, (byte) 0xD5, (byte) 0x4E, (byte) 0xA9,
61 (byte) 0x6C, (byte) 0x56, (byte) 0xF4, (byte) 0xEA, (byte) 0x65, (byte) 0x7A, (byte) 0xAE, (byte) 0x08,
62 (byte) 0xBA, (byte) 0x78, (byte) 0x25, (byte) 0x2E, (byte) 0x1C, (byte) 0xA6, (byte) 0xB4, (byte) 0xC6,
63 (byte) 0xE8, (byte) 0xDD, (byte) 0x74, (byte) 0x1F, (byte) 0x4B, (byte) 0xBD, (byte) 0x8B, (byte) 0x8A,
64 (byte) 0x70, (byte) 0x3E, (byte) 0xB5, (byte) 0x66, (byte) 0x48, (byte) 0x03, (byte) 0xF6, (byte) 0x0E,
65 (byte) 0x61, (byte) 0x35, (byte) 0x57, (byte) 0xB9, (byte) 0x86, (byte) 0xC1, (byte) 0x1D, (byte) 0x9E,
66 (byte) 0xE1, (byte) 0xF8, (byte) 0x98, (byte) 0x11, (byte) 0x69, (byte) 0xD9, (byte) 0x8E, (byte) 0x94,
67 (byte) 0x9B, (byte) 0x1E, (byte) 0x87, (byte) 0xE9, (byte) 0xCE, (byte) 0x55, (byte) 0x28, (byte) 0xDF,
68 (byte) 0x8C, (byte) 0xA1, (byte) 0x89, (byte) 0x0D, (byte) 0xBF, (byte) 0xE6, (byte) 0x42, (byte) 0x68,
69 (byte) 0x41, (byte) 0x99, (byte) 0x2D, (byte) 0x0F, (byte) 0xB0, (byte) 0x54, (byte) 0xBB, (byte) 0x16
70 };
71
72
73
74
75 private static final byte[] SQ = {
76 (byte) 0x25, (byte) 0x24, (byte) 0x73, (byte) 0x67, (byte) 0xD7, (byte) 0xAE, (byte) 0x5C, (byte) 0x30,
77 (byte) 0xA4, (byte) 0xEE, (byte) 0x6E, (byte) 0xCB, (byte) 0x7D, (byte) 0xB5, (byte) 0x82, (byte) 0xDB,
78 (byte) 0xE4, (byte) 0x8E, (byte) 0x48, (byte) 0x49, (byte) 0x4F, (byte) 0x5D, (byte) 0x6A, (byte) 0x78,
79 (byte) 0x70, (byte) 0x88, (byte) 0xE8, (byte) 0x5F, (byte) 0x5E, (byte) 0x84, (byte) 0x65, (byte) 0xE2,
80 (byte) 0xD8, (byte) 0xE9, (byte) 0xCC, (byte) 0xED, (byte) 0x40, (byte) 0x2F, (byte) 0x11, (byte) 0x28,
81 (byte) 0x57, (byte) 0xD2, (byte) 0xAC, (byte) 0xE3, (byte) 0x4A, (byte) 0x15, (byte) 0x1B, (byte) 0xB9,
82 (byte) 0xB2, (byte) 0x80, (byte) 0x85, (byte) 0xA6, (byte) 0x2E, (byte) 0x02, (byte) 0x47, (byte) 0x29,
83 (byte) 0x07, (byte) 0x4B, (byte) 0x0E, (byte) 0xC1, (byte) 0x51, (byte) 0xAA, (byte) 0x89, (byte) 0xD4,
84 (byte) 0xCA, (byte) 0x01, (byte) 0x46, (byte) 0xB3, (byte) 0xEF, (byte) 0xDD, (byte) 0x44, (byte) 0x7B,
85 (byte) 0xC2, (byte) 0x7F, (byte) 0xBE, (byte) 0xC3, (byte) 0x9F, (byte) 0x20, (byte) 0x4C, (byte) 0x64,
86 (byte) 0x83, (byte) 0xA2, (byte) 0x68, (byte) 0x42, (byte) 0x13, (byte) 0xB4, (byte) 0x41, (byte) 0xCD,
87 (byte) 0xBA, (byte) 0xC6, (byte) 0xBB, (byte) 0x6D, (byte) 0x4D, (byte) 0x71, (byte) 0x21, (byte) 0xF4,
88 (byte) 0x8D, (byte) 0xB0, (byte) 0xE5, (byte) 0x93, (byte) 0xFE, (byte) 0x8F, (byte) 0xE6, (byte) 0xCF,
89 (byte) 0x43, (byte) 0x45, (byte) 0x31, (byte) 0x22, (byte) 0x37, (byte) 0x36, (byte) 0x96, (byte) 0xFA,
90 (byte) 0xBC, (byte) 0x0F, (byte) 0x08, (byte) 0x52, (byte) 0x1D, (byte) 0x55, (byte) 0x1A, (byte) 0xC5,
91 (byte) 0x4E, (byte) 0x23, (byte) 0x69, (byte) 0x7A, (byte) 0x92, (byte) 0xFF, (byte) 0x5B, (byte) 0x5A,
92 (byte) 0xEB, (byte) 0x9A, (byte) 0x1C, (byte) 0xA9, (byte) 0xD1, (byte) 0x7E, (byte) 0x0D, (byte) 0xFC,
93 (byte) 0x50, (byte) 0x8A, (byte) 0xB6, (byte) 0x62, (byte) 0xF5, (byte) 0x0A, (byte) 0xF8, (byte) 0xDC,
94 (byte) 0x03, (byte) 0x3C, (byte) 0x0C, (byte) 0x39, (byte) 0xF1, (byte) 0xB8, (byte) 0xF3, (byte) 0x3D,
95 (byte) 0xF2, (byte) 0xD5, (byte) 0x97, (byte) 0x66, (byte) 0x81, (byte) 0x32, (byte) 0xA0, (byte) 0x00,
96 (byte) 0x06, (byte) 0xCE, (byte) 0xF6, (byte) 0xEA, (byte) 0xB7, (byte) 0x17, (byte) 0xF7, (byte) 0x8C,
97 (byte) 0x79, (byte) 0xD6, (byte) 0xA7, (byte) 0xBF, (byte) 0x8B, (byte) 0x3F, (byte) 0x1F, (byte) 0x53,
98 (byte) 0x63, (byte) 0x75, (byte) 0x35, (byte) 0x2C, (byte) 0x60, (byte) 0xFD, (byte) 0x27, (byte) 0xD3,
99 (byte) 0x94, (byte) 0xA5, (byte) 0x7C, (byte) 0xA1, (byte) 0x05, (byte) 0x58, (byte) 0x2D, (byte) 0xBD,
100 (byte) 0xD9, (byte) 0xC7, (byte) 0xAF, (byte) 0x6B, (byte) 0x54, (byte) 0x0B, (byte) 0xE0, (byte) 0x38,
101 (byte) 0x04, (byte) 0xC8, (byte) 0x9D, (byte) 0xE7, (byte) 0x14, (byte) 0xB1, (byte) 0x87, (byte) 0x9C,
102 (byte) 0xDF, (byte) 0x6F, (byte) 0xF9, (byte) 0xDA, (byte) 0x2A, (byte) 0xC4, (byte) 0x59, (byte) 0x16,
103 (byte) 0x74, (byte) 0x91, (byte) 0xAB, (byte) 0x26, (byte) 0x61, (byte) 0x76, (byte) 0x34, (byte) 0x2B,
104 (byte) 0xAD, (byte) 0x99, (byte) 0xFB, (byte) 0x72, (byte) 0xEC, (byte) 0x33, (byte) 0x12, (byte) 0xDE,
105 (byte) 0x98, (byte) 0x3B, (byte) 0xC0, (byte) 0x9B, (byte) 0x3E, (byte) 0x18, (byte) 0x10, (byte) 0x3A,
106 (byte) 0x56, (byte) 0xE1, (byte) 0x77, (byte) 0xC9, (byte) 0x1E, (byte) 0x9E, (byte) 0x95, (byte) 0xA3,
107 (byte) 0x90, (byte) 0x19, (byte) 0xA8, (byte) 0x6C, (byte) 0x09, (byte) 0xD0, (byte) 0xF0, (byte) 0x86
108 };
109
110
111
112
113 private final int[] lfsrState = new int[16];
114
115
116
117
118 private final int[] fsmState = new int[3];
119
120
121
122
123 private int theIndex;
124
125
126
127
128 private final byte[] keyStream = new byte[Integer.BYTES];
129
130
131
132
133 private int theIterations;
134
135
136
137
138 private GordianSnow3GEngine theResetState;
139
140
141
142
143 public GordianSnow3GEngine() {
144 }
145
146
147
148
149
150
151 private GordianSnow3GEngine(final GordianSnow3GEngine pSource) {
152 reset(pSource);
153 }
154
155
156
157
158
159
160
161
162 public void init(final boolean forEncryption,
163 final CipherParameters params) {
164
165
166
167
168
169
170 CipherParameters myParams = params;
171 byte[] newKey = null;
172 byte[] newIV = null;
173 if ((myParams instanceof ParametersWithIV)) {
174 final ParametersWithIV ivParams = (ParametersWithIV) myParams;
175 newIV = ivParams.getIV();
176 myParams = ivParams.getParameters();
177 }
178 if (myParams instanceof KeyParameter) {
179 final KeyParameter keyParam = (KeyParameter) myParams;
180 newKey = keyParam.getKey();
181 }
182
183
184 theIndex = 0;
185 theIterations = 0;
186 setKeyAndIV(newKey, newIV);
187
188
189 theResetState = copy();
190 }
191
192
193
194
195
196
197 protected int getMaxIterations() {
198 return 625;
199 }
200
201 @Override
202 public String getAlgorithmName() {
203 return "Snow3G";
204 }
205
206 @Override
207 public int processBytes(final byte[] in,
208 final int inOff,
209 final int len,
210 final byte[] out,
211 final int outOff) {
212
213 if (theResetState == null) {
214 throw new IllegalStateException(getAlgorithmName() + " not initialised");
215 }
216 if ((inOff + len) > in.length) {
217 throw new DataLengthException("input buffer too short");
218 }
219 if ((outOff + len) > out.length) {
220 throw new OutputLengthException("output buffer too short");
221 }
222
223
224 for (int i = 0; i < len; i++) {
225 out[i + outOff] = returnByte(in[i + inOff]);
226 }
227 return len;
228 }
229
230 @Override
231 public void reset() {
232 if (theResetState != null) {
233 reset(theResetState);
234 }
235 }
236
237 @Override
238 public byte returnByte(final byte in) {
239
240 if (theIndex == 0) {
241 makeKeyStream();
242 }
243
244
245 final byte out = (byte) (keyStream[theIndex] ^ in);
246 theIndex = (theIndex + 1) % Integer.BYTES;
247
248
249 return out;
250 }
251
252
253
254
255
256
257
258
259 private static int decode32be(final byte[] buf, final int off) {
260 return ((buf[off] & 0xFF) << 24)
261 | ((buf[off + 1] & 0xFF) << 16)
262 | ((buf[off + 2] & 0xFF) << 8)
263 | (buf[off + 3] & 0xFF);
264 }
265
266
267
268
269
270
271
272
273 private static void encode32be(final int val, final byte[] buf, final int off) {
274 buf[off] = (byte) (val >> 24);
275 buf[off + 1] = (byte) (val >> 16);
276 buf[off + 2] = (byte) (val >> 8);
277 buf[off + 3] = (byte) (val);
278 }
279
280
281
282
283
284
285
286 int mulX(final byte v, final int c) {
287 if ((v & 0x80) != 0) {
288 return ((v << 1) ^ c) & 0xFF;
289 } else {
290 return (v << 1) & 0xFF;
291 }
292 }
293
294
295
296
297
298
299
300
301 int mulXpow(final byte v, final int i, final int c) {
302 if (i == 0) {
303 return v & 0xFF;
304 } else {
305 return mulX((byte) mulXpow(v, i - 1, c), c);
306 }
307 }
308
309
310
311
312
313
314 int mulAlpha(final byte c) {
315 return ((mulXpow(c, 23, 0xa9) << 24)
316 | (mulXpow(c, 245, 0xa9) << 16)
317 | (mulXpow(c, 48, 0xa9) << 8)
318 | (mulXpow(c, 239, 0xa9)));
319 }
320
321
322
323
324
325
326 int divAlpha(final byte c) {
327 return ((mulXpow(c, 16, 0xa9) << 24)
328 | (mulXpow(c, 39, 0xa9) << 16)
329 | (mulXpow(c, 6, 0xa9) << 8)
330 | (mulXpow(c, 64, 0xa9)));
331 }
332
333
334
335
336
337
338 int s1(final int w) {
339 final byte srw0 = SR[((w >> 24) & 0xff)];
340 final byte srw1 = SR[((w >> 16) & 0xff)];
341 final byte srw2 = SR[((w >> 8) & 0xff)];
342 final byte srw3 = SR[((w) & 0xff)];
343 final int r0 = ((mulX(srw0, 0x1b))
344 ^ (srw1)
345 ^ (srw2)
346 ^ ((mulX(srw3, 0x1b)) ^ srw3)
347 ) & 0xFF;
348 final int r1 = (((mulX(srw0, 0x1b)) ^ srw0)
349 ^ (mulX(srw1, 0x1b))
350 ^ (srw2)
351 ^ (srw3)
352 ) & 0xFF;
353 final int r2 = ((srw0)
354 ^ ((mulX(srw1, 0x1b)) ^ srw1)
355 ^ (mulX(srw2, 0x1b))
356 ^ (srw3)
357 ) & 0xFF;
358 final int r3 = ((srw0)
359 ^ (srw1)
360 ^ ((mulX(srw2, 0x1b)) ^ srw2)
361 ^ (mulX(srw3, 0x1b))
362 ) & 0xFF;
363 return (((r0) << 24) | ((r1) << 16) | ((r2) << 8)
364 | (r3));
365 }
366
367
368
369
370
371
372 int s2(final int w) {
373 final byte sqw0 = SQ[((w >> 24) & 0xff)];
374 final byte sqw1 = SQ[((w >> 16) & 0xff)];
375 final byte sqw2 = SQ[((w >> 8) & 0xff)];
376 final byte sqw3 = SQ[((w) & 0xff)];
377 final int r0 = ((mulX(sqw0, 0x69))
378 ^ (sqw1)
379 ^ (sqw2)
380 ^ ((mulX(sqw3, 0x69)) ^ sqw3)
381 ) & 0xFF;
382 final int r1 = (((mulX(sqw0, 0x69)) ^ sqw0)
383 ^ (mulX(sqw1, 0x69))
384 ^ (sqw2)
385 ^ (sqw3)
386 ) & 0xFF;
387 final int r2 = ((sqw0)
388 ^ ((mulX(sqw1, 0x69)) ^ sqw1)
389 ^ (mulX(sqw2, 0x69))
390 ^ (sqw3)
391 ) & 0xFF;
392 final int r3 = ((sqw0)
393 ^ (sqw1)
394 ^ ((mulX(sqw2, 0x69)) ^ sqw2)
395 ^ (mulX(sqw3, 0x69))
396 ) & 0xFF;
397 return (((r0) << 24) | ((r1) << 16) | ((r2) << 8)
398 | (r3));
399 }
400
401
402
403
404
405
406 void clockLFSRInitializationMode(final int f) {
407 final int v = (((lfsrState[0] << 8) & 0xffffff00)
408 ^ (mulAlpha((byte) ((lfsrState[0] >>> 24) & 0xff)))
409 ^ (lfsrState[2])
410 ^ ((lfsrState[11] >>> 8) & 0x00ffffff)
411 ^ (divAlpha((byte) ((lfsrState[11]) & 0xff)))
412 ^ (f)
413 );
414 lfsrState[0] = lfsrState[1];
415 lfsrState[1] = lfsrState[2];
416 lfsrState[2] = lfsrState[3];
417 lfsrState[3] = lfsrState[4];
418 lfsrState[4] = lfsrState[5];
419 lfsrState[5] = lfsrState[6];
420 lfsrState[6] = lfsrState[7];
421 lfsrState[7] = lfsrState[8];
422 lfsrState[8] = lfsrState[9];
423 lfsrState[9] = lfsrState[10];
424 lfsrState[10] = lfsrState[11];
425 lfsrState[11] = lfsrState[12];
426 lfsrState[12] = lfsrState[13];
427 lfsrState[13] = lfsrState[14];
428 lfsrState[14] = lfsrState[15];
429 lfsrState[15] = v;
430 }
431
432
433
434
435
436 void clockLFSRKeyStreamMode() {
437 final int v = (((lfsrState[0] << 8) & 0xffffff00)
438 ^ (mulAlpha((byte) ((lfsrState[0] >>> 24) & 0xff)))
439 ^ (lfsrState[2])
440 ^ ((lfsrState[11] >>> 8) & 0x00ffffff)
441 ^ (divAlpha((byte) ((lfsrState[11]) & 0xff)))
442 );
443 lfsrState[0] = lfsrState[1];
444 lfsrState[1] = lfsrState[2];
445 lfsrState[2] = lfsrState[3];
446 lfsrState[3] = lfsrState[4];
447 lfsrState[4] = lfsrState[5];
448 lfsrState[5] = lfsrState[6];
449 lfsrState[6] = lfsrState[7];
450 lfsrState[7] = lfsrState[8];
451 lfsrState[8] = lfsrState[9];
452 lfsrState[9] = lfsrState[10];
453 lfsrState[10] = lfsrState[11];
454 lfsrState[11] = lfsrState[12];
455 lfsrState[12] = lfsrState[13];
456 lfsrState[13] = lfsrState[14];
457 lfsrState[14] = lfsrState[15];
458 lfsrState[15] = v;
459 }
460
461
462
463
464
465
466 int clockFSM() {
467 final int f = ((lfsrState[15] + fsmState[0]) & 0xffffffff) ^ fsmState[1];
468 final int r = (fsmState[1] + (fsmState[2] ^ lfsrState[5])) & 0xffffffff;
469 fsmState[2] = s2(fsmState[1]);
470 fsmState[1] = s1(fsmState[0]);
471 fsmState[0] = r;
472 return f;
473 }
474
475
476
477
478
479
480
481 void setKeyAndIV(final byte[] key, final byte[] iv) {
482
483 if (key == null || key.length != 16) {
484 throw new IllegalArgumentException("A key of 16 bytes is needed");
485 }
486 if (iv == null || iv.length != 16) {
487 throw new IllegalArgumentException("An IV of 16 bytes is needed");
488 }
489
490
491 final int k0 = decode32be(key, 12);
492 final int k1 = decode32be(key, 8);
493 final int k2 = decode32be(key, 4);
494 final int k3 = decode32be(key, 0);
495
496
497 final int i0 = decode32be(iv, 12);
498 final int i1 = decode32be(iv, 8);
499 final int i2 = decode32be(iv, 4);
500 final int i3 = decode32be(iv, 0);
501
502 lfsrState[15] = k3 ^ i0;
503 lfsrState[14] = k2;
504 lfsrState[13] = k1;
505 lfsrState[12] = k0 ^ i1;
506 lfsrState[11] = k3 ^ 0xffffffff;
507 lfsrState[10] = k2 ^ 0xffffffff ^ i2;
508 lfsrState[9] = k1 ^ 0xffffffff ^ i3;
509 lfsrState[8] = k0 ^ 0xffffffff;
510 lfsrState[7] = k3;
511 lfsrState[6] = k2;
512 lfsrState[5] = k1;
513 lfsrState[4] = k0;
514 lfsrState[3] = k3 ^ 0xffffffff;
515 lfsrState[2] = k2 ^ 0xffffffff;
516 lfsrState[1] = k1 ^ 0xffffffff;
517 lfsrState[0] = k0 ^ 0xffffffff;
518 fsmState[0] = 0x0;
519 fsmState[1] = 0x0;
520 fsmState[2] = 0x0;
521 for (int i = 0; i < 32; i++) {
522 final int f = clockFSM();
523 clockLFSRInitializationMode(f);
524 }
525
526 clockFSM();
527
528 clockLFSRKeyStreamMode();
529 }
530
531
532
533
534
535
536
537
538 void makeKeyStream() {
539 if (theIterations++ >= getMaxIterations()) {
540 throw new IllegalStateException("Too much data processed by singleKey/IV");
541 }
542
543 final int f = clockFSM();
544 encode32be(f ^ lfsrState[0], keyStream, 0);
545
546 clockLFSRKeyStreamMode();
547 }
548
549 @Override
550 public GordianSnow3GEngine copy() {
551 return new GordianSnow3GEngine(this);
552 }
553
554 @Override
555 public void reset(final Memoable pState) {
556 final GordianSnow3GEngine e = (GordianSnow3GEngine) pState;
557 System.arraycopy(e.lfsrState, 0, lfsrState, 0, lfsrState.length);
558 System.arraycopy(e.fsmState, 0, fsmState, 0, fsmState.length);
559 System.arraycopy(e.keyStream, 0, keyStream, 0, keyStream.length);
560 theIterations = e.theIterations;
561 theIndex = e.theIndex;
562 }
563 }