View Javadoc
1   /*
2    * GordianKnot: Security Suite
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
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   * Snow3GEngine implementation.
29   * Based on https://www.gsma.com/aboutus/wp-content/uploads/2014/12/snow3gspec.pdf
30   */
31  @SuppressWarnings("checkstyle:MagicNumber")
32  public class GordianSnow3GEngine
33          implements StreamCipher, Memoable {
34      /**
35       * Rijndael S-box SR.
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       * S-box SQ.
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      * LFSR State.
112      */
113     private final int[] lfsrState = new int[16];
114 
115     /**
116      * FSM State.
117      */
118     private final int[] fsmState = new int[3];
119 
120     /**
121      * index of next byte in keyStream.
122      */
123     private int theIndex;
124 
125     /**
126      * Advanced stream.
127      */
128     private final byte[] keyStream = new byte[Integer.BYTES];
129 
130     /**
131      * The iterations.
132      */
133     private int theIterations;
134 
135     /**
136      * Reset state.
137      */
138     private GordianSnow3GEngine theResetState;
139 
140     /**
141      * Constructor.
142      */
143     public GordianSnow3GEngine() {
144     }
145 
146     /**
147      * Constructor.
148      *
149      * @param pSource the source engine
150      */
151     private GordianSnow3GEngine(final GordianSnow3GEngine pSource) {
152         reset(pSource);
153     }
154 
155     /**
156      * initialise a Snow3G cipher.
157      *
158      * @param forEncryption whether or not we are for encryption.
159      * @param params        the parameters required to set up the cipher.
160      * @throws IllegalArgumentException if the params argument is inappropriate.
161      */
162     public void init(final boolean forEncryption,
163                      final CipherParameters params) {
164         /*
165          * encryption and decryption is completely symmetrical, so the 'forEncryption' is
166          * irrelevant. (Like 90% of stream ciphers)
167          */
168 
169         /* Determine parameters */
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         /* Initialise engine and mark as initialised */
182         theIndex = 0;
183         theIterations = 0;
184         setKeyAndIV(newKey, newIV);
185 
186         /* Save reset state */
187         theResetState = copy();
188     }
189 
190     /**
191      * Obtain Max iterations.
192      *
193      * @return the maximum iterations
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         /* Check for errors */
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         /* Loop through the input bytes */
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         /* Make the keyStream if required */
238         if (theIndex == 0) {
239             makeKeyStream();
240         }
241 
242         /* Map the next byte and adjust index */
243         final byte out = (byte) (keyStream[theIndex] ^ in);
244         theIndex = (theIndex + 1) % Integer.BYTES;
245 
246         /* Return the mapped character */
247         return out;
248     }
249 
250     /**
251      * Decode a 32-bit value from a buffer (little-endian).
252      *
253      * @param buf the input buffer
254      * @param off the input offset
255      * @return the decoded value
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      * Encode a 32-bit value into a buffer (little-endian).
266      *
267      * @param val the value to encode
268      * @param buf the output buffer
269      * @param off the output offset
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     /* MULx.
279      * Input v: an 8-bit input.
280      * Input c: an 8-bit input.
281      * Output : an 8-bit output.
282      * See section 3.1.1 for details.
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     /* MULxPOW.
293      * Input v: an 8-bit input.
294      * Input i: a positive integer.
295      * Input c: an 8-bit input.
296      * Output : an 8-bit output.
297      * See section 3.1.2 for details.
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     /* The function MUL alpha.
308      * Input c: 8-bit input.
309      * Output : 32-bit output.
310      * See section 3.4.2 for details.
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     /* The function DIV alpha.
320      * Input c: 8-bit input.
321      * Output : 32-bit output.
322      * See section 3.4.3 for details.
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     /* The 32x32-bit S-Box S1
332      * Input: a 32-bit input.
333      * Output: a 32-bit output of S1 box.
334      * See section 3.3.1.
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     /* The 32x32-bit S-Box S2
366      * Input: a 32-bit input.
367      * Output: a 32-bit output of S2 box.
368      * See section 3.3.2.
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     /* Clocking LFSR in initialization mode.
400      * LFSR Registers S0 to S15 are updated as the LFSR receives a single clock.
401      * Input f: a 32-bit word comes from output of FSM.
402      * See section 3.4.4.
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     /* Clocking LFSR in keystream mode.
431      * LFSR Registers S0 to S15 are updated as the LFSR receives a single clock.
432      * See section 3.4.5.
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     /* Clocking FSM.
460      * Produces a 32-bit word F.
461      * Updates FSM registers R1, R2, R3.
462      * See Section 3.4.6.
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     /* Initialization.
474      * Input k[4]: Four 32-bit words making up 128-bit key.
475      * Input IV[4]: Four 32-bit words making 128-bit initialization variable.
476      * Output: All the LFSRs and FSM are initialized for key generation.
477      * See Section 4.1.
478      */
479     void setKeyAndIV(final byte[] key, final byte[] iv) {
480         /* Check lengths */
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         /* Generate four subkeys */
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         /* Generate four subvectors */
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         /* Clock FSM once. Discard the output. */
524         clockFSM();
525         /* Clock LFSR in keystream mode once. */
526         clockLFSRKeyStreamMode();
527     }
528 
529     /* Generation of Keystream.
530      * input n: number of 32-bit words of keystream.
531      * input z: space for the generated keystream, assumes
532      * memory is allocated already.
533      * output: generated keystream which is filled in z
534      * See section 4.2.
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(); // STEP 1 */
542         encode32be(f ^ lfsrState[0], keyStream, 0); // STEP 2 */
543         /* Note that ks[t] corresponds to z_{t+1} in section 4.2 */
544         clockLFSRKeyStreamMode(); // STEP 3 */
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 }