1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44: import ;
45: import ;
46: import ;
47: import ;
48:
49:
62: public final class Square
63: extends BaseCipher
64: {
65: private static final int DEFAULT_BLOCK_SIZE = 16;
66: private static final int DEFAULT_KEY_SIZE = 16;
67: private static final int ROUNDS = 8;
68: private static final int ROOT = 0x1F5;
69: private static final int[] OFFSET = new int[ROUNDS];
70: private static final String Sdata =
71: "\uB1CE\uC395\u5AAD\uE702\u4D44\uFB91\u0C87\uA150"
72: + "\uCB67\u54DD\u468F\uE14E\uF0FD\uFCEB\uF9C4\u1A6E"
73: + "\u5EF5\uCC8D\u1C56\u43FE\u0761\uF875\u59FF\u0322"
74: + "\u8AD1\u13EE\u8800\u0E34\u1580\u94E3\uEDB5\u5323"
75: + "\u4B47\u17A7\u9035\uABD8\uB8DF\u4F57\u9A92\uDB1B"
76: + "\u3CC8\u9904\u8EE0\uD77D\u85BB\u402C\u3A45\uF142"
77: + "\u6520\u4118\u7225\u9370\u3605\uF20B\uA379\uEC08"
78: + "\u2731\u32B6\u7CB0\u0A73\u5B7B\uB781\uD20D\u6A26"
79: + "\u9E58\u9C83\u74B3\uAC30\u7A69\u770F\uAE21\uDED0"
80: + "\u2E97\u10A4\u98A8\uD468\u2D62\u296D\u1649\u76C7"
81: + "\uE8C1\u9637\uE5CA\uF4E9\u6312\uC2A6\u14BC\uD328"
82: + "\uAF2F\uE624\u52C6\uA009\uBD8C\uCF5D\u115F\u01C5"
83: + "\u9F3D\uA29B\uC93B\uBE51\u191F\u3F5C\uB2EF\u4ACD"
84: + "\uBFBA\u6F64\uD9F3\u3EB4\uAADC\uD506\uC07E\uF666"
85: + "\u6C84\u7138\uB91D\u7F9D\u488B\u2ADA\uA533\u8239"
86: + "\uD678\u86FA\uE42B\uA91E\u8960\u6BEA\u554C\uF7E2";
87:
88: private static final byte[] Se = new byte[256];
89: private static final byte[] Sd = new byte[256];
90:
91: private static final int[] Te = new int[256];
92: private static final int[] Td = new int[256];
93:
97: private static final byte[] KAT_KEY =
98: Util.toBytesFromString("00000000000000000000020000000000");
99: private static final byte[] KAT_CT =
100: Util.toBytesFromString("A9DF031B4E25E89F527EFFF89CB0BEBA");
101:
102: private static Boolean valid;
103: static
104: {
105: int i, j;
106:
107: int limit = Sdata.length();
108: char c1;
109: for (i = 0, j = 0; i < limit; i++)
110: {
111: c1 = Sdata.charAt(i);
112: Se[j++] = (byte)(c1 >>> 8);
113: Se[j++] = (byte) c1;
114: }
115:
116: for (i = 0; i < 256; i++)
117: Sd[Se[i] & 0xFF] = (byte) i;
118:
119: OFFSET[0] = 1;
120: for (i = 1; i < ROUNDS; i++)
121: {
122: OFFSET[i] = mul(OFFSET[i - 1], 2);
123: OFFSET[i - 1] <<= 24;
124: }
125: OFFSET[ROUNDS - 1] <<= 24;
126:
127:
128:
129:
130:
131:
132:
133:
134: for (i = 0; i < 256; i++)
135: {
136: j = Se[i] & 0xFF;
137: Te[i] = (Se[i & 3] == 0) ? 0
138: : mul(j, 2) << 24
139: | j << 16
140: | j << 8
141: | mul(j, 3);
142: j = Sd[i] & 0xFF;
143: Td[i] = (Sd[i & 3] == 0) ? 0
144: : mul(j, 14) << 24
145: | mul(j, 9) << 16
146: | mul(j, 13) << 8
147: | mul(j, 11);
148: }
149: }
150:
151:
152: public Square()
153: {
154: super(Registry.SQUARE_CIPHER, DEFAULT_BLOCK_SIZE, DEFAULT_KEY_SIZE);
155: }
156:
157: private static void square(byte[] in, int i, byte[] out, int j, int[][] K,
158: int[] T, byte[] S)
159: {
160: int a = ((in[i++]) << 24
161: | (in[i++] & 0xFF) << 16
162: | (in[i++] & 0xFF) << 8
163: | (in[i++] & 0xFF) ) ^ K[0][0];
164: int b = ((in[i++]) << 24
165: | (in[i++] & 0xFF) << 16
166: | (in[i++] & 0xFF) << 8
167: | (in[i++] & 0xFF) ) ^ K[0][1];
168: int c = ((in[i++]) << 24
169: | (in[i++] & 0xFF) << 16
170: | (in[i++] & 0xFF) << 8
171: | (in[i++] & 0xFF) ) ^ K[0][2];
172: int d = ((in[i++]) << 24
173: | (in[i++] & 0xFF) << 16
174: | (in[i++] & 0xFF) << 8
175: | (in[i ] & 0xFF) ) ^ K[0][3];
176: int r, aa, bb, cc, dd;
177: for (r = 1; r < ROUNDS; r++)
178: {
179: aa = T[(a >>> 24) ]
180: ^ rot32R(T[(b >>> 24) ], 8)
181: ^ rot32R(T[(c >>> 24) ], 16)
182: ^ rot32R(T[(d >>> 24) ], 24) ^ K[r][0];
183: bb = T[(a >>> 16) & 0xFF]
184: ^ rot32R(T[(b >>> 16) & 0xFF], 8)
185: ^ rot32R(T[(c >>> 16) & 0xFF], 16)
186: ^ rot32R(T[(d >>> 16) & 0xFF], 24) ^ K[r][1];
187: cc = T[(a >>> 8) & 0xFF]
188: ^ rot32R(T[(b >>> 8) & 0xFF], 8)
189: ^ rot32R(T[(c >>> 8) & 0xFF], 16)
190: ^ rot32R(T[(d >>> 8) & 0xFF], 24) ^ K[r][2];
191: dd = T[ a & 0xFF]
192: ^ rot32R(T[ b & 0xFF], 8)
193: ^ rot32R(T[ c & 0xFF], 16)
194: ^ rot32R(T[ d & 0xFF], 24) ^ K[r][3];
195: a = aa;
196: b = bb;
197: c = cc;
198: d = dd;
199: }
200:
201: aa = ((S[(a >>> 24) ] ) << 24
202: | (S[(b >>> 24) ] & 0xFF) << 16
203: | (S[(c >>> 24) ] & 0xFF) << 8
204: | (S[(d >>> 24) ] & 0xFF) ) ^ K[r][0];
205: bb = ((S[(a >>> 16) & 0xFF] ) << 24
206: | (S[(b >>> 16) & 0xFF] & 0xFF) << 16
207: | (S[(c >>> 16) & 0xFF] & 0xFF) << 8
208: | (S[(d >>> 16) & 0xFF] & 0xFF) ) ^ K[r][1];
209: cc = ((S[(a >>> 8) & 0xFF] ) << 24
210: | (S[(b >>> 8) & 0xFF] & 0xFF) << 16
211: | (S[(c >>> 8) & 0xFF] & 0xFF) << 8
212: | (S[(d >>> 8) & 0xFF] & 0xFF) ) ^ K[r][2];
213: dd = ((S[ a & 0xFF] ) << 24
214: | (S[ b & 0xFF] & 0xFF) << 16
215: | (S[ c & 0xFF] & 0xFF) << 8
216: | (S[ d & 0xFF] & 0xFF) ) ^ K[r][3];
217: out[j++] = (byte)(aa >>> 24);
218: out[j++] = (byte)(aa >>> 16);
219: out[j++] = (byte)(aa >>> 8);
220: out[j++] = (byte) aa;
221: out[j++] = (byte)(bb >>> 24);
222: out[j++] = (byte)(bb >>> 16);
223: out[j++] = (byte)(bb >>> 8);
224: out[j++] = (byte) bb;
225: out[j++] = (byte)(cc >>> 24);
226: out[j++] = (byte)(cc >>> 16);
227: out[j++] = (byte)(cc >>> 8);
228: out[j++] = (byte) cc;
229: out[j++] = (byte)(dd >>> 24);
230: out[j++] = (byte)(dd >>> 16);
231: out[j++] = (byte)(dd >>> 8);
232: out[j ] = (byte) dd;
233: }
234:
235:
255: private static void transform(int[] in, int[] out)
256: {
257: int l3, l2, l1, l0, m;
258: for (int i = 0; i < 4; i++)
259: {
260: l3 = in[i];
261: l2 = l3 >>> 8;
262: l1 = l3 >>> 16;
263: l0 = l3 >>> 24;
264: m = ((mul(l0, 2) ^ mul(l1, 3) ^ l2 ^ l3) & 0xFF) << 24;
265: m ^= ((l0 ^ mul(l1, 2) ^ mul(l2, 3) ^ l3) & 0xFF) << 16;
266: m ^= ((l0 ^ l1 ^ mul(l2, 2) ^ mul(l3, 3)) & 0xFF) << 8;
267: m ^= ((mul(l0, 3) ^ l1 ^ l2 ^ mul(l3, 2)) & 0xFF);
268: out[i] = m;
269: }
270: }
271:
272:
279: private static int rot32L(int x, int s)
280: {
281: return x << s | x >>> (32 - s);
282: }
283:
284:
291: private static int rot32R(int x, int s)
292: {
293: return x >>> s | x << (32 - s);
294: }
295:
296:
307: private static final int mul(int a, int b)
308: {
309: if (a == 0)
310: return 0;
311: a &= 0xFF;
312: b &= 0xFF;
313: int result = 0;
314: while (b != 0)
315: {
316: if ((b & 0x01) != 0)
317: result ^= a;
318: b >>>= 1;
319: a <<= 1;
320: if (a > 0xFF)
321: a ^= ROOT;
322: }
323: return result & 0xFF;
324: }
325:
326: public Object clone()
327: {
328: Square result = new Square();
329: result.currentBlockSize = this.currentBlockSize;
330:
331: return result;
332: }
333:
334: public Iterator blockSizes()
335: {
336: ArrayList al = new ArrayList();
337: al.add(Integer.valueOf(DEFAULT_BLOCK_SIZE));
338:
339: return Collections.unmodifiableList(al).iterator();
340: }
341:
342: public Iterator keySizes()
343: {
344: ArrayList al = new ArrayList();
345: al.add(Integer.valueOf(DEFAULT_KEY_SIZE));
346:
347: return Collections.unmodifiableList(al).iterator();
348: }
349:
350: public Object makeKey(byte[] uk, int bs) throws InvalidKeyException
351: {
352: if (bs != DEFAULT_BLOCK_SIZE)
353: throw new IllegalArgumentException();
354: if (uk == null)
355: throw new InvalidKeyException("Empty key");
356: if (uk.length != DEFAULT_KEY_SIZE)
357: throw new InvalidKeyException("Key is not 128-bit.");
358: int[][] Ke = new int[ROUNDS + 1][4];
359: int[][] Kd = new int[ROUNDS + 1][4];
360: int[][] tK = new int[ROUNDS + 1][4];
361: int i = 0;
362: Ke[0][0] = (uk[i++] & 0xFF) << 24
363: | (uk[i++] & 0xFF) << 16
364: | (uk[i++] & 0xFF) << 8
365: | (uk[i++] & 0xFF);
366: tK[0][0] = Ke[0][0];
367: Ke[0][1] = (uk[i++] & 0xFF) << 24
368: | (uk[i++] & 0xFF) << 16
369: | (uk[i++] & 0xFF) << 8
370: | (uk[i++] & 0xFF);
371: tK[0][1] = Ke[0][1];
372: Ke[0][2] = (uk[i++] & 0xFF) << 24
373: | (uk[i++] & 0xFF) << 16
374: | (uk[i++] & 0xFF) << 8
375: | (uk[i++] & 0xFF);
376: tK[0][2] = Ke[0][2];
377: Ke[0][3] = (uk[i++] & 0xFF) << 24
378: | (uk[i++] & 0xFF) << 16
379: | (uk[i++] & 0xFF) << 8
380: | (uk[i ] & 0xFF);
381: tK[0][3] = Ke[0][3];
382: int j;
383: for (i = 1, j = 0; i < ROUNDS + 1; i++, j++)
384: {
385: tK[i][0] = tK[j][0] ^ rot32L(tK[j][3], 8) ^ OFFSET[j];
386: tK[i][1] = tK[j][1] ^ tK[i][0];
387: tK[i][2] = tK[j][2] ^ tK[i][1];
388: tK[i][3] = tK[j][3] ^ tK[i][2];
389: System.arraycopy(tK[i], 0, Ke[i], 0, 4);
390: transform(Ke[j], Ke[j]);
391: }
392: for (i = 0; i < ROUNDS; i++)
393: System.arraycopy(tK[ROUNDS - i], 0, Kd[i], 0, 4);
394: transform(tK[0], Kd[ROUNDS]);
395: return new Object[] { Ke, Kd };
396: }
397:
398: public void encrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
399: {
400: if (bs != DEFAULT_BLOCK_SIZE)
401: throw new IllegalArgumentException();
402: int[][] K = (int[][])((Object[]) k)[0];
403: square(in, i, out, j, K, Te, Se);
404: }
405:
406: public void decrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
407: {
408: if (bs != DEFAULT_BLOCK_SIZE)
409: throw new IllegalArgumentException();
410: int[][] K = (int[][])((Object[]) k)[1];
411: square(in, i, out, j, K, Td, Sd);
412: }
413:
414: public boolean selfTest()
415: {
416: if (valid == null)
417: {
418: boolean result = super.selfTest();
419: if (result)
420: result = testKat(KAT_KEY, KAT_CT);
421: valid = Boolean.valueOf(result);
422: }
423: return valid.booleanValue();
424: }
425: }