~ubuntu-branches/ubuntu/precise/classpath/precise

« back to all changes in this revision

Viewing changes to gnu/javax/crypto/cipher/Anubis.java

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2006-05-27 16:11:15 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060527161115-h6e39eposdt5snb6
Tags: 2:0.91-3
* Install header files to /usr/include/classpath.
* debian/control: classpath: Conflict with jamvm < 1.4.3 and
  cacao < 0.96 (Closes: #368172).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Anubis.java -- 
 
2
   Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
 
3
 
 
4
This file is a part of GNU Classpath.
 
5
 
 
6
GNU Classpath is free software; you can redistribute it and/or modify
 
7
it under the terms of the GNU General Public License as published by
 
8
the Free Software Foundation; either version 2 of the License, or (at
 
9
your option) any later version.
 
10
 
 
11
GNU Classpath is distributed in the hope that it will be useful, but
 
12
WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
General Public License for more details.
 
15
 
 
16
You should have received a copy of the GNU General Public License
 
17
along with GNU Classpath; if not, write to the Free Software
 
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 
19
USA
 
20
 
 
21
Linking this library statically or dynamically with other modules is
 
22
making a combined work based on this library.  Thus, the terms and
 
23
conditions of the GNU General Public License cover the whole
 
24
combination.
 
25
 
 
26
As a special exception, the copyright holders of this library give you
 
27
permission to link this library with independent modules to produce an
 
28
executable, regardless of the license terms of these independent
 
29
modules, and to copy and distribute the resulting executable under
 
30
terms of your choice, provided that you also meet, for each linked
 
31
independent module, the terms and conditions of the license of that
 
32
module.  An independent module is a module which is not derived from
 
33
or based on this library.  If you modify this library, you may extend
 
34
this exception to your version of the library, but you are not
 
35
obligated to do so.  If you do not wish to do so, delete this
 
36
exception statement from your version.  */
 
37
 
 
38
 
 
39
package gnu.javax.crypto.cipher;
 
40
 
 
41
import gnu.java.security.Registry;
 
42
import gnu.java.security.util.Util;
 
43
 
 
44
//import java.io.PrintWriter;
 
45
import java.security.InvalidKeyException;
 
46
import java.util.ArrayList;
 
47
import java.util.Collections;
 
48
import java.util.Iterator;
 
49
 
 
50
/**
 
51
 * <p>Anubis is a 128-bit block cipher that accepts a variable-length key. The
 
52
 * cipher is a uniform substitution-permutation network whose inverse only
 
53
 * differs from the forward operation in the key schedule. The design of both
 
54
 * the round transformation and the key schedule is based upon the Wide Trail
 
55
 * strategy and permits a wide variety of implementation trade-offs.</p>
 
56
 *
 
57
 * <p>References:</p>
 
58
 *
 
59
 * <ol>
 
60
 *    <li><a href="http://planeta.terra.com.br/informatica/paulobarreto/AnubisPage.html">The
 
61
 *    ANUBIS Block Cipher</a>.<br>
 
62
 *    <a href="mailto:paulo.barreto@terra.com.br">Paulo S.L.M. Barreto</a> and
 
63
 *    <a href="mailto:vincent.rijmen@esat.kuleuven.ac.be">Vincent Rijmen</a>.</li>
 
64
 * </ol>
 
65
 */
 
66
public final class Anubis extends BaseCipher
 
67
{
 
68
 
 
69
  // Debugging methods and variables
 
70
  // -------------------------------------------------------------------------
 
71
 
 
72
  //   private static final String NAME = "anubis";
 
73
  private static final boolean DEBUG = false;
 
74
 
 
75
  private static final int debuglevel = 9;
 
76
 
 
77
  //   private static final PrintWriter err = new PrintWriter(System.out, true);
 
78
  //   private static void debug(String s) {
 
79
  //      err.println(">>> "+NAME+": "+s);
 
80
  //   }
 
81
 
 
82
  // Constants and variables
 
83
  // -------------------------------------------------------------------------
 
84
 
 
85
  private static final int DEFAULT_BLOCK_SIZE = 16; // in bytes
 
86
 
 
87
  private static final int DEFAULT_KEY_SIZE = 16; // in bytes
 
88
 
 
89
  private static final String Sd = // p. 25 [ANUBIS]
 
90
  "\uBA54\u2F74\u53D3\uD24D\u50AC\u8DBF\u7052\u9A4C"
 
91
      + "\uEAD5\u97D1\u3351\u5BA6\uDE48\uA899\uDB32\uB7FC"
 
92
      + "\uE39E\u919B\uE2BB\u416E\uA5CB\u6B95\uA1F3\uB102"
 
93
      + "\uCCC4\u1D14\uC363\uDA5D\u5FDC\u7DCD\u7F5A\u6C5C"
 
94
      + "\uF726\uFFED\uE89D\u6F8E\u19A0\uF089\u0F07\uAFFB"
 
95
      + "\u0815\u0D04\u0164\uDF76\u79DD\u3D16\u3F37\u6D38"
 
96
      + "\uB973\uE935\u5571\u7B8C\u7288\uF62A\u3E5E\u2746"
 
97
      + "\u0C65\u6861\u03C1\u57D6\uD958\uD866\uD73A\uC83C"
 
98
      + "\uFA96\uA798\uECB8\uC7AE\u694B\uABA9\u670A\u47F2"
 
99
      + "\uB522\uE5EE\uBE2B\u8112\u831B\u0E23\uF545\u21CE"
 
100
      + "\u492C\uF9E6\uB628\u1782\u1A8B\uFE8A\u09C9\u874E"
 
101
      + "\uE12E\uE4E0\uEB90\uA41E\u8560\u0025\uF4F1\u940B"
 
102
      + "\uE775\uEF34\u31D4\uD086\u7EAD\uFD29\u303B\u9FF8"
 
103
      + "\uC613\u0605\uC511\u777C\u7A78\u361C\u3959\u1856"
 
104
      + "\uB3B0\u2420\uB292\uA3C0\u4462\u10B4\u8443\u93C2"
 
105
      + "\u4ABD\u8F2D\uBC9C\u6A40\uCFA2\u804F\u1FCA\uAA42";
 
106
 
 
107
  private static final byte[] S = new byte[256];
 
108
 
 
109
  private static final int[] T0 = new int[256];
 
110
 
 
111
  private static final int[] T1 = new int[256];
 
112
 
 
113
  private static final int[] T2 = new int[256];
 
114
 
 
115
  private static final int[] T3 = new int[256];
 
116
 
 
117
  private static final int[] T4 = new int[256];
 
118
 
 
119
  private static final int[] T5 = new int[256];
 
120
 
 
121
  /**
 
122
   * Anubis round constants. This is the largest possible considering that we
 
123
   * always use R values, R = 8 + N, and 4 &lt;= N &lt;= 10.
 
124
   */
 
125
  private static final int[] rc = new int[18];
 
126
 
 
127
  /**
 
128
   * KAT vector (from ecb_vk):
 
129
   * I=83
 
130
   * KEY=000000000000000000002000000000000000000000000000
 
131
   * CT=2E66AB15773F3D32FB6C697509460DF4
 
132
   */
 
133
  private static final byte[] KAT_KEY = Util.toBytesFromString("000000000000000000002000000000000000000000000000");
 
134
 
 
135
  private static final byte[] KAT_CT = Util.toBytesFromString("2E66AB15773F3D32FB6C697509460DF4");
 
136
 
 
137
  /** caches the result of the correctness test, once executed. */
 
138
  private static Boolean valid;
 
139
 
 
140
  // Static code - to initialise lookup tables -------------------------------
 
141
 
 
142
  static
 
143
    {
 
144
      long time = System.currentTimeMillis();
 
145
 
 
146
      int ROOT = 0x11d; // para. 2.1 [ANUBIS]
 
147
      int i, s, s2, s4, s6, s8, t;
 
148
      char c;
 
149
      for (i = 0; i < 256; i++)
 
150
        {
 
151
          c = Sd.charAt(i >>> 1);
 
152
          s = ((i & 1) == 0 ? c >>> 8 : c) & 0xFF;
 
153
          S[i] = (byte) s;
 
154
 
 
155
          s2 = s << 1;
 
156
          if (s2 > 0xFF)
 
157
            {
 
158
              s2 ^= ROOT;
 
159
            }
 
160
 
 
161
          s4 = s2 << 1;
 
162
          if (s4 > 0xFF)
 
163
            {
 
164
              s4 ^= ROOT;
 
165
            }
 
166
 
 
167
          s6 = s4 ^ s2;
 
168
          s8 = s4 << 1;
 
169
          if (s8 > 0xFF)
 
170
            {
 
171
              s8 ^= ROOT;
 
172
            }
 
173
 
 
174
          T0[i] = s << 24 | s2 << 16 | s4 << 8 | s6;
 
175
          T1[i] = s2 << 24 | s << 16 | s6 << 8 | s4;
 
176
          T2[i] = s4 << 24 | s6 << 16 | s << 8 | s2;
 
177
          T3[i] = s6 << 24 | s4 << 16 | s2 << 8 | s;
 
178
 
 
179
          T4[i] = s << 24 | s << 16 | s << 8 | s;
 
180
          T5[s] = s << 24 | s2 << 16 | s6 << 8 | s8;
 
181
        }
 
182
 
 
183
      // compute round constant
 
184
      for (i = 0, s = 0; i < 18;)
 
185
        {
 
186
          rc[i++] = S[(s++) & 0xFF] << 24 | (S[(s++) & 0xFF] & 0xFF) << 16
 
187
                    | (S[(s++) & 0xFF] & 0xFF) << 8 | (S[(s++) & 0xFF] & 0xFF);
 
188
        }
 
189
 
 
190
      time = System.currentTimeMillis() - time;
 
191
 
 
192
      if (DEBUG && debuglevel > 8)
 
193
        {
 
194
          System.out.println("==========");
 
195
          System.out.println();
 
196
          System.out.println("Static data");
 
197
          System.out.println();
 
198
 
 
199
          System.out.println();
 
200
          System.out.println("T0[]:");
 
201
          for (i = 0; i < 64; i++)
 
202
            {
 
203
              for (t = 0; t < 4; t++)
 
204
                {
 
205
                  System.out.print("0x" + Util.toString(T0[i * 4 + t]) + ", ");
 
206
                }
 
207
              System.out.println();
 
208
            }
 
209
          System.out.println();
 
210
          System.out.println("T1[]:");
 
211
          for (i = 0; i < 64; i++)
 
212
            {
 
213
              for (t = 0; t < 4; t++)
 
214
                {
 
215
                  System.out.print("0x" + Util.toString(T1[i * 4 + t]) + ", ");
 
216
                }
 
217
              System.out.println();
 
218
            }
 
219
          System.out.println();
 
220
          System.out.println("T2[]:");
 
221
          for (i = 0; i < 64; i++)
 
222
            {
 
223
              for (t = 0; t < 4; t++)
 
224
                {
 
225
                  System.out.print("0x" + Util.toString(T2[i * 4 + t]) + ", ");
 
226
                }
 
227
              System.out.println();
 
228
            }
 
229
          System.out.println();
 
230
          System.out.println("T3[]:");
 
231
          for (i = 0; i < 64; i++)
 
232
            {
 
233
              for (t = 0; t < 4; t++)
 
234
                {
 
235
                  System.out.print("0x" + Util.toString(T3[i * 4 + t]) + ", ");
 
236
                }
 
237
              System.out.println();
 
238
            }
 
239
          System.out.println();
 
240
          System.out.println("T4[]:");
 
241
          for (i = 0; i < 64; i++)
 
242
            {
 
243
              for (t = 0; t < 4; t++)
 
244
                {
 
245
                  System.out.print("0x" + Util.toString(T4[i * 4 + t]) + ", ");
 
246
                }
 
247
              System.out.println();
 
248
            }
 
249
          System.out.println();
 
250
          System.out.println("T5[]:");
 
251
          for (i = 0; i < 64; i++)
 
252
            {
 
253
              for (t = 0; t < 4; t++)
 
254
                {
 
255
                  System.out.print("0x" + Util.toString(T5[i * 4 + t]) + ", ");
 
256
                }
 
257
              System.out.println();
 
258
            }
 
259
          System.out.println();
 
260
          System.out.println("rc[]:");
 
261
          for (i = 0; i < 18; i++)
 
262
            {
 
263
              System.out.println("0x" + Util.toString(rc[i]));
 
264
            }
 
265
          System.out.println();
 
266
 
 
267
          System.out.println();
 
268
          System.out.println("Total initialization time: " + time + " ms.");
 
269
          System.out.println();
 
270
        }
 
271
    }
 
272
 
 
273
  // Constructor(s)
 
274
  // -------------------------------------------------------------------------
 
275
 
 
276
  /** Trivial 0-arguments constructor. */
 
277
  public Anubis()
 
278
  {
 
279
    super(Registry.ANUBIS_CIPHER, DEFAULT_BLOCK_SIZE, DEFAULT_KEY_SIZE);
 
280
  }
 
281
 
 
282
  // Class methods
 
283
  // -------------------------------------------------------------------------
 
284
 
 
285
  private static void anubis(byte[] in, int i, byte[] out, int j, int[][] K)
 
286
  {
 
287
    // extract encryption round keys
 
288
    int R = K.length - 1;
 
289
    int[] Ker = K[0];
 
290
 
 
291
    // mu function + affine key addition
 
292
    int a0 = (in[i++] << 24 | (in[i++] & 0xFF) << 16 | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF))
 
293
             ^ Ker[0];
 
294
    int a1 = (in[i++] << 24 | (in[i++] & 0xFF) << 16 | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF))
 
295
             ^ Ker[1];
 
296
    int a2 = (in[i++] << 24 | (in[i++] & 0xFF) << 16 | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF))
 
297
             ^ Ker[2];
 
298
    int a3 = (in[i++] << 24 | (in[i++] & 0xFF) << 16 | (in[i++] & 0xFF) << 8 | (in[i] & 0xFF))
 
299
             ^ Ker[3];
 
300
 
 
301
    int b0, b1, b2, b3;
 
302
    // round function
 
303
    for (int r = 1; r < R; r++)
 
304
      {
 
305
        Ker = K[r];
 
306
        b0 = T0[a0 >>> 24] ^ T1[a1 >>> 24] ^ T2[a2 >>> 24] ^ T3[a3 >>> 24]
 
307
             ^ Ker[0];
 
308
        b1 = T0[(a0 >>> 16) & 0xFF] ^ T1[(a1 >>> 16) & 0xFF]
 
309
             ^ T2[(a2 >>> 16) & 0xFF] ^ T3[(a3 >>> 16) & 0xFF] ^ Ker[1];
 
310
        b2 = T0[(a0 >>> 8) & 0xFF] ^ T1[(a1 >>> 8) & 0xFF]
 
311
             ^ T2[(a2 >>> 8) & 0xFF] ^ T3[(a3 >>> 8) & 0xFF] ^ Ker[2];
 
312
        b3 = T0[a0 & 0xFF] ^ T1[a1 & 0xFF] ^ T2[a2 & 0xFF] ^ T3[a3 & 0xFF]
 
313
             ^ Ker[3];
 
314
        a0 = b0;
 
315
        a1 = b1;
 
316
        a2 = b2;
 
317
        a3 = b3;
 
318
        if (DEBUG && debuglevel > 6)
 
319
          {
 
320
            System.out.println("T" + r + "=" + Util.toString(a0)
 
321
                               + Util.toString(a1) + Util.toString(a2)
 
322
                               + Util.toString(a3));
 
323
          }
 
324
      }
 
325
 
 
326
    // last round function
 
327
    Ker = K[R];
 
328
    int tt = Ker[0];
 
329
    out[j++] = (byte) (S[a0 >>> 24] ^ (tt >>> 24));
 
330
    out[j++] = (byte) (S[a1 >>> 24] ^ (tt >>> 16));
 
331
    out[j++] = (byte) (S[a2 >>> 24] ^ (tt >>> 8));
 
332
    out[j++] = (byte) (S[a3 >>> 24] ^ tt);
 
333
    tt = Ker[1];
 
334
    out[j++] = (byte) (S[(a0 >>> 16) & 0xFF] ^ (tt >>> 24));
 
335
    out[j++] = (byte) (S[(a1 >>> 16) & 0xFF] ^ (tt >>> 16));
 
336
    out[j++] = (byte) (S[(a2 >>> 16) & 0xFF] ^ (tt >>> 8));
 
337
    out[j++] = (byte) (S[(a3 >>> 16) & 0xFF] ^ tt);
 
338
    tt = Ker[2];
 
339
    out[j++] = (byte) (S[(a0 >>> 8) & 0xFF] ^ (tt >>> 24));
 
340
    out[j++] = (byte) (S[(a1 >>> 8) & 0xFF] ^ (tt >>> 16));
 
341
    out[j++] = (byte) (S[(a2 >>> 8) & 0xFF] ^ (tt >>> 8));
 
342
    out[j++] = (byte) (S[(a3 >>> 8) & 0xFF] ^ tt);
 
343
    tt = Ker[3];
 
344
    out[j++] = (byte) (S[a0 & 0xFF] ^ (tt >>> 24));
 
345
    out[j++] = (byte) (S[a1 & 0xFF] ^ (tt >>> 16));
 
346
    out[j++] = (byte) (S[a2 & 0xFF] ^ (tt >>> 8));
 
347
    out[j] = (byte) (S[a3 & 0xFF] ^ tt);
 
348
 
 
349
    if (DEBUG && debuglevel > 6)
 
350
      {
 
351
        System.out.println("T=" + Util.toString(out, j - 15, 16));
 
352
        System.out.println();
 
353
      }
 
354
  }
 
355
 
 
356
  // Instance methods
 
357
  // -------------------------------------------------------------------------
 
358
 
 
359
  // java.lang.Cloneable interface implementation ----------------------------
 
360
 
 
361
  public Object clone()
 
362
  {
 
363
    Anubis result = new Anubis();
 
364
    result.currentBlockSize = this.currentBlockSize;
 
365
 
 
366
    return result;
 
367
  }
 
368
 
 
369
  // IBlockCipherSpi interface implementation --------------------------------
 
370
 
 
371
  public Iterator blockSizes()
 
372
  {
 
373
    ArrayList al = new ArrayList();
 
374
    al.add(new Integer(DEFAULT_BLOCK_SIZE));
 
375
 
 
376
    return Collections.unmodifiableList(al).iterator();
 
377
  }
 
378
 
 
379
  public Iterator keySizes()
 
380
  {
 
381
    ArrayList al = new ArrayList();
 
382
    for (int n = 4; n < 10; n++)
 
383
      {
 
384
        al.add(new Integer(n * 32 / 8));
 
385
      }
 
386
 
 
387
    return Collections.unmodifiableList(al).iterator();
 
388
  }
 
389
 
 
390
  /**
 
391
   * <p>Expands a user-supplied key material into a session key for a
 
392
   * designated <i>block size</i>.</p>
 
393
   *
 
394
   * @param uk the 32N-bit user-supplied key material; 4 &lt;= N &lt;= 10.
 
395
   * @param bs the desired block size in bytes.
 
396
   * @return an Object encapsulating the session key.
 
397
   * @exception IllegalArgumentException if the block size is not 16 (128-bit).
 
398
   * @exception InvalidKeyException if the key data is invalid.
 
399
   */
 
400
  public Object makeKey(byte[] uk, int bs) throws InvalidKeyException
 
401
  {
 
402
    if (bs != DEFAULT_BLOCK_SIZE)
 
403
      {
 
404
        throw new IllegalArgumentException();
 
405
      }
 
406
    if (uk == null)
 
407
      {
 
408
        throw new InvalidKeyException("Empty key");
 
409
      }
 
410
    if ((uk.length % 4) != 0)
 
411
      {
 
412
        throw new InvalidKeyException("Key is not multiple of 32-bit.");
 
413
      }
 
414
    int N = uk.length / 4;
 
415
    if (N < 4 || N > 10)
 
416
      {
 
417
        throw new InvalidKeyException("Key is not 32N; 4 <= N <= 10");
 
418
      }
 
419
    int R = 8 + N;
 
420
    int[][] Ke = new int[R + 1][4]; // encryption round keys
 
421
    int[][] Kd = new int[R + 1][4]; // decryption round keys
 
422
    int[] tk = new int[N];
 
423
    int[] kk = new int[N];
 
424
    int r, i, j, k, k0, k1, k2, k3, tt;
 
425
 
 
426
    // apply mu to k0
 
427
    for (r = 0, i = 0; r < N;)
 
428
      {
 
429
        tk[r++] = uk[i++] << 24 | (uk[i++] & 0xFF) << 16
 
430
                  | (uk[i++] & 0xFF) << 8 | (uk[i++] & 0xFF);
 
431
      }
 
432
    for (r = 0; r <= R; r++)
 
433
      {
 
434
        if (r > 0)
 
435
          {
 
436
            // psi = key evolution function
 
437
            kk[0] = T0[(tk[0] >>> 24)] ^ T1[(tk[N - 1] >>> 16) & 0xFF]
 
438
                    ^ T2[(tk[N - 2] >>> 8) & 0xFF] ^ T3[tk[N - 3] & 0xFF];
 
439
            kk[1] = T0[(tk[1] >>> 24)] ^ T1[(tk[0] >>> 16) & 0xFF]
 
440
                    ^ T2[(tk[N - 1] >>> 8) & 0xFF] ^ T3[tk[N - 2] & 0xFF];
 
441
            kk[2] = T0[(tk[2] >>> 24)] ^ T1[(tk[1] >>> 16) & 0xFF]
 
442
                    ^ T2[(tk[0] >>> 8) & 0xFF] ^ T3[tk[N - 1] & 0xFF];
 
443
            kk[3] = T0[(tk[3] >>> 24)] ^ T1[(tk[2] >>> 16) & 0xFF]
 
444
                    ^ T2[(tk[1] >>> 8) & 0xFF] ^ T3[tk[0] & 0xFF];
 
445
 
 
446
            for (i = 4; i < N; i++)
 
447
              {
 
448
                kk[i] = T0[tk[i] >>> 24] ^ T1[(tk[i - 1] >>> 16) & 0xFF]
 
449
                        ^ T2[(tk[i - 2] >>> 8) & 0xFF] ^ T3[tk[i - 3] & 0xFF];
 
450
              }
 
451
            // apply sigma (affine addition) to round constant
 
452
            tk[0] = rc[r - 1] ^ kk[0];
 
453
            for (i = 1; i < N; i++)
 
454
              {
 
455
                tk[i] = kk[i];
 
456
              }
 
457
          }
 
458
 
 
459
        // phi = key selection function
 
460
        tt = tk[N - 1];
 
461
        k0 = T4[tt >>> 24];
 
462
        k1 = T4[(tt >>> 16) & 0xFF];
 
463
        k2 = T4[(tt >>> 8) & 0xFF];
 
464
        k3 = T4[tt & 0xFF];
 
465
 
 
466
        for (k = N - 2; k >= 0; k--)
 
467
          {
 
468
            tt = tk[k];
 
469
            k0 = T4[tt >>> 24] ^ (T5[(k0 >>> 24) & 0xFF] & 0xFF000000)
 
470
                 ^ (T5[(k0 >>> 16) & 0xFF] & 0x00FF0000)
 
471
                 ^ (T5[(k0 >>> 8) & 0xFF] & 0x0000FF00)
 
472
                 ^ (T5[k0 & 0xFF] & 0x000000FF);
 
473
            k1 = T4[(tt >>> 16) & 0xFF] ^ (T5[(k1 >>> 24) & 0xFF] & 0xFF000000)
 
474
                 ^ (T5[(k1 >>> 16) & 0xFF] & 0x00FF0000)
 
475
                 ^ (T5[(k1 >>> 8) & 0xFF] & 0x0000FF00)
 
476
                 ^ (T5[k1 & 0xFF] & 0x000000FF);
 
477
            k2 = T4[(tt >>> 8) & 0xFF] ^ (T5[(k2 >>> 24) & 0xFF] & 0xFF000000)
 
478
                 ^ (T5[(k2 >>> 16) & 0xFF] & 0x00FF0000)
 
479
                 ^ (T5[(k2 >>> 8) & 0xFF] & 0x0000FF00)
 
480
                 ^ (T5[(k2) & 0xFF] & 0x000000FF);
 
481
            k3 = T4[tt & 0xFF] ^ (T5[(k3 >>> 24) & 0xFF] & 0xFF000000)
 
482
                 ^ (T5[(k3 >>> 16) & 0xFF] & 0x00FF0000)
 
483
                 ^ (T5[(k3 >>> 8) & 0xFF] & 0x0000FF00)
 
484
                 ^ (T5[k3 & 0xFF] & 0x000000FF);
 
485
          }
 
486
 
 
487
        Ke[r][0] = k0;
 
488
        Ke[r][1] = k1;
 
489
        Ke[r][2] = k2;
 
490
        Ke[r][3] = k3;
 
491
 
 
492
        if (r == 0 || r == R)
 
493
          {
 
494
            Kd[R - r][0] = k0;
 
495
            Kd[R - r][1] = k1;
 
496
            Kd[R - r][2] = k2;
 
497
            Kd[R - r][3] = k3;
 
498
          }
 
499
        else
 
500
          {
 
501
            Kd[R - r][0] = T0[S[k0 >>> 24] & 0xFF]
 
502
                           ^ T1[S[(k0 >>> 16) & 0xFF] & 0xFF]
 
503
                           ^ T2[S[(k0 >>> 8) & 0xFF] & 0xFF]
 
504
                           ^ T3[S[k0 & 0xFF] & 0xFF];
 
505
            Kd[R - r][1] = T0[S[k1 >>> 24] & 0xFF]
 
506
                           ^ T1[S[(k1 >>> 16) & 0xFF] & 0xFF]
 
507
                           ^ T2[S[(k1 >>> 8) & 0xFF] & 0xFF]
 
508
                           ^ T3[S[k1 & 0xFF] & 0xFF];
 
509
            Kd[R - r][2] = T0[S[k2 >>> 24] & 0xFF]
 
510
                           ^ T1[S[(k2 >>> 16) & 0xFF] & 0xFF]
 
511
                           ^ T2[S[(k2 >>> 8) & 0xFF] & 0xFF]
 
512
                           ^ T3[S[k2 & 0xFF] & 0xFF];
 
513
            Kd[R - r][3] = T0[S[k3 >>> 24] & 0xFF]
 
514
                           ^ T1[S[(k3 >>> 16) & 0xFF] & 0xFF]
 
515
                           ^ T2[S[(k3 >>> 8) & 0xFF] & 0xFF]
 
516
                           ^ T3[S[k3 & 0xFF] & 0xFF];
 
517
          }
 
518
      }
 
519
 
 
520
    if (DEBUG && debuglevel > 8)
 
521
      {
 
522
        System.out.println();
 
523
        System.out.println("Key schedule");
 
524
        System.out.println();
 
525
        System.out.println("Ke[]:");
 
526
        for (r = 0; r < R + 1; r++)
 
527
          {
 
528
            System.out.print("#" + r + ": ");
 
529
            for (j = 0; j < 4; j++)
 
530
              System.out.print("0x" + Util.toString(Ke[r][j]) + ", ");
 
531
            System.out.println();
 
532
          }
 
533
        System.out.println();
 
534
        System.out.println("Kd[]:");
 
535
        for (r = 0; r < R + 1; r++)
 
536
          {
 
537
            System.out.print("#" + r + ": ");
 
538
            for (j = 0; j < 4; j++)
 
539
              System.out.print("0x" + Util.toString(Kd[r][j]) + ", ");
 
540
            System.out.println();
 
541
          }
 
542
        System.out.println();
 
543
      }
 
544
 
 
545
    return new Object[] { Ke, Kd };
 
546
  }
 
547
 
 
548
  public void encrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
 
549
  {
 
550
    if (bs != DEFAULT_BLOCK_SIZE)
 
551
      {
 
552
        throw new IllegalArgumentException();
 
553
      }
 
554
 
 
555
    int[][] K = (int[][]) ((Object[]) k)[0];
 
556
    anubis(in, i, out, j, K);
 
557
  }
 
558
 
 
559
  public void decrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
 
560
  {
 
561
    if (bs != DEFAULT_BLOCK_SIZE)
 
562
      {
 
563
        throw new IllegalArgumentException();
 
564
      }
 
565
 
 
566
    int[][] K = (int[][]) ((Object[]) k)[1];
 
567
    anubis(in, i, out, j, K);
 
568
  }
 
569
 
 
570
  public boolean selfTest()
 
571
  {
 
572
    if (valid == null)
 
573
      {
 
574
        boolean result = super.selfTest(); // do symmetry tests
 
575
        if (result)
 
576
          {
 
577
            result = testKat(KAT_KEY, KAT_CT);
 
578
          }
 
579
        valid = Boolean.valueOf(result);
 
580
      }
 
581
    return valid.booleanValue();
 
582
  }
 
583
}
 
 
b'\\ No newline at end of file'