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 ivParams)) {
174 newIV = ivParams.getIV();
175 myParams = ivParams.getParameters();
176 }
177 if (myParams instanceof KeyParameter keyParam) {
178 newKey = keyParam.getKey();
179 }
180
181
182 theIndex = 0;
183 theIterations = 0;
184 setKeyAndIV(newKey, newIV);
185
186
187 theResetState = copy();
188 }
189
190
191
192
193
194
195 protected int getMaxIterations() {
196 return 625;
197 }
198
199 @Override
200 public String getAlgorithmName() {
201 return "Snow3G";
202 }
203
204 @Override
205 public int processBytes(final byte[] in,
206 final int inOff,
207 final int len,
208 final byte[] out,
209 final int outOff) {
210
211 if (theResetState == null) {
212 throw new IllegalStateException(getAlgorithmName() + " not initialised");
213 }
214 if ((inOff + len) > in.length) {
215 throw new DataLengthException("input buffer too short");
216 }
217 if ((outOff + len) > out.length) {
218 throw new OutputLengthException("output buffer too short");
219 }
220
221
222 for (int i = 0; i < len; i++) {
223 out[i + outOff] = returnByte(in[i + inOff]);
224 }
225 return len;
226 }
227
228 @Override
229 public void reset() {
230 if (theResetState != null) {
231 reset(theResetState);
232 }
233 }
234
235 @Override
236 public byte returnByte(final byte in) {
237
238 if (theIndex == 0) {
239 makeKeyStream();
240 }
241
242
243 final byte out = (byte) (keyStream[theIndex] ^ in);
244 theIndex = (theIndex + 1) % Integer.BYTES;
245
246
247 return out;
248 }
249
250
251
252
253
254
255
256
257 private static int decode32be(final byte[] buf, final int off) {
258 return ((buf[off] & 0xFF) << 24)
259 | ((buf[off + 1] & 0xFF) << 16)
260 | ((buf[off + 2] & 0xFF) << 8)
261 | (buf[off + 3] & 0xFF);
262 }
263
264
265
266
267
268
269
270
271 private static void encode32be(final int val, final byte[] buf, final int off) {
272 buf[off] = (byte) (val >> 24);
273 buf[off + 1] = (byte) (val >> 16);
274 buf[off + 2] = (byte) (val >> 8);
275 buf[off + 3] = (byte) (val);
276 }
277
278
279
280
281
282
283
284 int mulX(final byte v, final int c) {
285 if ((v & 0x80) != 0) {
286 return ((v << 1) ^ c) & 0xFF;
287 } else {
288 return (v << 1) & 0xFF;
289 }
290 }
291
292
293
294
295
296
297
298
299 int mulXpow(final byte v, final int i, final int c) {
300 if (i == 0) {
301 return v & 0xFF;
302 } else {
303 return mulX((byte) mulXpow(v, i - 1, c), c);
304 }
305 }
306
307
308
309
310
311
312 int mulAlpha(final byte c) {
313 return ((mulXpow(c, 23, 0xa9) << 24)
314 | (mulXpow(c, 245, 0xa9) << 16)
315 | (mulXpow(c, 48, 0xa9) << 8)
316 | (mulXpow(c, 239, 0xa9)));
317 }
318
319
320
321
322
323
324 int divAlpha(final byte c) {
325 return ((mulXpow(c, 16, 0xa9) << 24)
326 | (mulXpow(c, 39, 0xa9) << 16)
327 | (mulXpow(c, 6, 0xa9) << 8)
328 | (mulXpow(c, 64, 0xa9)));
329 }
330
331
332
333
334
335
336 int s1(final int w) {
337 final byte srw0 = SR[((w >> 24) & 0xff)];
338 final byte srw1 = SR[((w >> 16) & 0xff)];
339 final byte srw2 = SR[((w >> 8) & 0xff)];
340 final byte srw3 = SR[((w) & 0xff)];
341 final int r0 = ((mulX(srw0, 0x1b))
342 ^ (srw1)
343 ^ (srw2)
344 ^ ((mulX(srw3, 0x1b)) ^ srw3)
345 ) & 0xFF;
346 final int r1 = (((mulX(srw0, 0x1b)) ^ srw0)
347 ^ (mulX(srw1, 0x1b))
348 ^ (srw2)
349 ^ (srw3)
350 ) & 0xFF;
351 final int r2 = ((srw0)
352 ^ ((mulX(srw1, 0x1b)) ^ srw1)
353 ^ (mulX(srw2, 0x1b))
354 ^ (srw3)
355 ) & 0xFF;
356 final int r3 = ((srw0)
357 ^ (srw1)
358 ^ ((mulX(srw2, 0x1b)) ^ srw2)
359 ^ (mulX(srw3, 0x1b))
360 ) & 0xFF;
361 return (((r0) << 24) | ((r1) << 16) | ((r2) << 8)
362 | (r3));
363 }
364
365
366
367
368
369
370 int s2(final int w) {
371 final byte sqw0 = SQ[((w >> 24) & 0xff)];
372 final byte sqw1 = SQ[((w >> 16) & 0xff)];
373 final byte sqw2 = SQ[((w >> 8) & 0xff)];
374 final byte sqw3 = SQ[((w) & 0xff)];
375 final int r0 = ((mulX(sqw0, 0x69))
376 ^ (sqw1)
377 ^ (sqw2)
378 ^ ((mulX(sqw3, 0x69)) ^ sqw3)
379 ) & 0xFF;
380 final int r1 = (((mulX(sqw0, 0x69)) ^ sqw0)
381 ^ (mulX(sqw1, 0x69))
382 ^ (sqw2)
383 ^ (sqw3)
384 ) & 0xFF;
385 final int r2 = ((sqw0)
386 ^ ((mulX(sqw1, 0x69)) ^ sqw1)
387 ^ (mulX(sqw2, 0x69))
388 ^ (sqw3)
389 ) & 0xFF;
390 final int r3 = ((sqw0)
391 ^ (sqw1)
392 ^ ((mulX(sqw2, 0x69)) ^ sqw2)
393 ^ (mulX(sqw3, 0x69))
394 ) & 0xFF;
395 return (((r0) << 24) | ((r1) << 16) | ((r2) << 8)
396 | (r3));
397 }
398
399
400
401
402
403
404 void clockLFSRInitializationMode(final int f) {
405 final int v = (((lfsrState[0] << 8) & 0xffffff00)
406 ^ (mulAlpha((byte) ((lfsrState[0] >>> 24) & 0xff)))
407 ^ (lfsrState[2])
408 ^ ((lfsrState[11] >>> 8) & 0x00ffffff)
409 ^ (divAlpha((byte) ((lfsrState[11]) & 0xff)))
410 ^ (f)
411 );
412 lfsrState[0] = lfsrState[1];
413 lfsrState[1] = lfsrState[2];
414 lfsrState[2] = lfsrState[3];
415 lfsrState[3] = lfsrState[4];
416 lfsrState[4] = lfsrState[5];
417 lfsrState[5] = lfsrState[6];
418 lfsrState[6] = lfsrState[7];
419 lfsrState[7] = lfsrState[8];
420 lfsrState[8] = lfsrState[9];
421 lfsrState[9] = lfsrState[10];
422 lfsrState[10] = lfsrState[11];
423 lfsrState[11] = lfsrState[12];
424 lfsrState[12] = lfsrState[13];
425 lfsrState[13] = lfsrState[14];
426 lfsrState[14] = lfsrState[15];
427 lfsrState[15] = v;
428 }
429
430
431
432
433
434 void clockLFSRKeyStreamMode() {
435 final int v = (((lfsrState[0] << 8) & 0xffffff00)
436 ^ (mulAlpha((byte) ((lfsrState[0] >>> 24) & 0xff)))
437 ^ (lfsrState[2])
438 ^ ((lfsrState[11] >>> 8) & 0x00ffffff)
439 ^ (divAlpha((byte) ((lfsrState[11]) & 0xff)))
440 );
441 lfsrState[0] = lfsrState[1];
442 lfsrState[1] = lfsrState[2];
443 lfsrState[2] = lfsrState[3];
444 lfsrState[3] = lfsrState[4];
445 lfsrState[4] = lfsrState[5];
446 lfsrState[5] = lfsrState[6];
447 lfsrState[6] = lfsrState[7];
448 lfsrState[7] = lfsrState[8];
449 lfsrState[8] = lfsrState[9];
450 lfsrState[9] = lfsrState[10];
451 lfsrState[10] = lfsrState[11];
452 lfsrState[11] = lfsrState[12];
453 lfsrState[12] = lfsrState[13];
454 lfsrState[13] = lfsrState[14];
455 lfsrState[14] = lfsrState[15];
456 lfsrState[15] = v;
457 }
458
459
460
461
462
463
464 int clockFSM() {
465 final int f = ((lfsrState[15] + fsmState[0]) & 0xffffffff) ^ fsmState[1];
466 final int r = (fsmState[1] + (fsmState[2] ^ lfsrState[5])) & 0xffffffff;
467 fsmState[2] = s2(fsmState[1]);
468 fsmState[1] = s1(fsmState[0]);
469 fsmState[0] = r;
470 return f;
471 }
472
473
474
475
476
477
478
479 void setKeyAndIV(final byte[] key, final byte[] iv) {
480
481 if (key == null || key.length != 16) {
482 throw new IllegalArgumentException("A key of 16 bytes is needed");
483 }
484 if (iv == null || iv.length != 16) {
485 throw new IllegalArgumentException("An IV of 16 bytes is needed");
486 }
487
488
489 final int k0 = decode32be(key, 12);
490 final int k1 = decode32be(key, 8);
491 final int k2 = decode32be(key, 4);
492 final int k3 = decode32be(key, 0);
493
494
495 final int i0 = decode32be(iv, 12);
496 final int i1 = decode32be(iv, 8);
497 final int i2 = decode32be(iv, 4);
498 final int i3 = decode32be(iv, 0);
499
500 lfsrState[15] = k3 ^ i0;
501 lfsrState[14] = k2;
502 lfsrState[13] = k1;
503 lfsrState[12] = k0 ^ i1;
504 lfsrState[11] = k3 ^ 0xffffffff;
505 lfsrState[10] = k2 ^ 0xffffffff ^ i2;
506 lfsrState[9] = k1 ^ 0xffffffff ^ i3;
507 lfsrState[8] = k0 ^ 0xffffffff;
508 lfsrState[7] = k3;
509 lfsrState[6] = k2;
510 lfsrState[5] = k1;
511 lfsrState[4] = k0;
512 lfsrState[3] = k3 ^ 0xffffffff;
513 lfsrState[2] = k2 ^ 0xffffffff;
514 lfsrState[1] = k1 ^ 0xffffffff;
515 lfsrState[0] = k0 ^ 0xffffffff;
516 fsmState[0] = 0x0;
517 fsmState[1] = 0x0;
518 fsmState[2] = 0x0;
519 for (int i = 0; i < 32; i++) {
520 final int f = clockFSM();
521 clockLFSRInitializationMode(f);
522 }
523
524 clockFSM();
525
526 clockLFSRKeyStreamMode();
527 }
528
529
530
531
532
533
534
535
536 void makeKeyStream() {
537 if (theIterations++ >= getMaxIterations()) {
538 throw new IllegalStateException("Too much data processed by singleKey/IV");
539 }
540
541 final int f = clockFSM();
542 encode32be(f ^ lfsrState[0], keyStream, 0);
543
544 clockLFSRKeyStreamMode();
545 }
546
547 @Override
548 public GordianSnow3GEngine copy() {
549 return new GordianSnow3GEngine(this);
550 }
551
552 @Override
553 public void reset(final Memoable pState) {
554 final GordianSnow3GEngine e = (GordianSnow3GEngine) pState;
555 System.arraycopy(e.lfsrState, 0, lfsrState, 0, lfsrState.length);
556 System.arraycopy(e.fsmState, 0, fsmState, 0, fsmState.length);
557 System.arraycopy(e.keyStream, 0, keyStream, 0, keyStream.length);
558 theIterations = e.theIterations;
559 theIndex = e.theIndex;
560 }
561 }