OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [crypto/] [cipher/] [Khazad.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* Khazad.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.Configuration;
42
import gnu.java.security.Registry;
43
import gnu.java.security.util.Util;
44
 
45
import java.security.InvalidKeyException;
46
import java.util.ArrayList;
47
import java.util.Collections;
48
import java.util.Iterator;
49
import java.util.logging.Logger;
50
 
51
/**
52
 * Khazad is a 64-bit (legacy-level) block cipher that accepts a 128-bit key.
53
 * The cipher is a uniform substitution-permutation network whose inverse only
54
 * differs from the forward operation in the key schedule. The overall cipher
55
 * design follows the Wide Trail strategy, favours component reuse, and permits
56
 * a wide variety of implementation trade-offs.
57
 * <p>
58
 * References:
59
 * <ol>
60
 * <li><a
61
 * href="http://planeta.terra.com.br/informatica/paulobarreto/KhazadPage.html">The
62
 * Khazad Block Cipher</a>.<br>
63
 * <a href="mailto:paulo.barreto@terra.com.br">Paulo S.L.M. Barreto</a> and <a
64
 * href="mailto:vincent.rijmen@esat.kuleuven.ac.be">Vincent Rijmen</a>.</li>
65
 * </ol>
66
 */
67
public final class Khazad
68
    extends BaseCipher
69
{
70
  private static final Logger log = Logger.getLogger(Khazad.class.getName());
71
  private static final int DEFAULT_BLOCK_SIZE = 8; // in bytes
72
  private static final int DEFAULT_KEY_SIZE = 16; // in bytes
73
  private static final int R = 8; // standard number of rounds; para. 3.7
74
  private static final String Sd = // p. 20 [KHAZAD]
75
      "\uBA54\u2F74\u53D3\uD24D\u50AC\u8DBF\u7052\u9A4C"
76
    + "\uEAD5\u97D1\u3351\u5BA6\uDE48\uA899\uDB32\uB7FC"
77
    + "\uE39E\u919B\uE2BB\u416E\uA5CB\u6B95\uA1F3\uB102"
78
    + "\uCCC4\u1D14\uC363\uDA5D\u5FDC\u7DCD\u7F5A\u6C5C"
79
    + "\uF726\uFFED\uE89D\u6F8E\u19A0\uF089\u0F07\uAFFB"
80
    + "\u0815\u0D04\u0164\uDF76\u79DD\u3D16\u3F37\u6D38"
81
    + "\uB973\uE935\u5571\u7B8C\u7288\uF62A\u3E5E\u2746"
82
    + "\u0C65\u6861\u03C1\u57D6\uD958\uD866\uD73A\uC83C"
83
    + "\uFA96\uA798\uECB8\uC7AE\u694B\uABA9\u670A\u47F2"
84
    + "\uB522\uE5EE\uBE2B\u8112\u831B\u0E23\uF545\u21CE"
85
    + "\u492C\uF9E6\uB628\u1782\u1A8B\uFE8A\u09C9\u874E"
86
    + "\uE12E\uE4E0\uEB90\uA41E\u8560\u0025\uF4F1\u940B"
87
    + "\uE775\uEF34\u31D4\uD086\u7EAD\uFD29\u303B\u9FF8"
88
    + "\uC613\u0605\uC511\u777C\u7A78\u361C\u3959\u1856"
89
    + "\uB3B0\u2420\uB292\uA3C0\u4462\u10B4\u8443\u93C2"
90
    + "\u4ABD\u8F2D\uBC9C\u6A40\uCFA2\u804F\u1FCA\uAA42";
91
  private static final byte[] S = new byte[256];
92
  private static final int[] T0 = new int[256];
93
  private static final int[] T1 = new int[256];
94
  private static final int[] T2 = new int[256];
95
  private static final int[] T3 = new int[256];
96
  private static final int[] T4 = new int[256];
97
  private static final int[] T5 = new int[256];
98
  private static final int[] T6 = new int[256];
99
  private static final int[] T7 = new int[256];
100
  private static final int[][] rc = new int[R + 1][2]; // round constants
101
  /**
102
   * KAT vector (from ecb_vk): I=120 KEY=00000000000000000000000000000100
103
   * CT=A0C86A1BBE2CBF4C
104
   */
105
  private static final byte[] KAT_KEY =
106
      Util.toBytesFromString("00000000000000000000000000000100");
107
  private static final byte[] KAT_CT = Util.toBytesFromString("A0C86A1BBE2CBF4C");
108
  /** caches the result of the correctness test, once executed. */
109
  private static Boolean valid;
110
 
111
  static
112
    {
113
      long time = System.currentTimeMillis();
114
      long ROOT = 0x11d; // para. 2.1 [KHAZAD]
115
      int i, j;
116
      int s, s2, s3, s4, s5, s6, s7, s8, sb;
117
      char c;
118
      for (i = 0; i < 256; i++)
119
        {
120
          c = Sd.charAt(i >>> 1);
121
          s = ((i & 1) == 0 ? c >>> 8 : c) & 0xFF;
122
          S[i] = (byte) s;
123
          s2 = s << 1;
124
          if (s2 > 0xFF)
125
            s2 ^= ROOT;
126
          s3 = s2 ^ s;
127
          s4 = s2 << 1;
128
          if (s4 > 0xFF)
129
            s4 ^= ROOT;
130
          s5 = s4 ^ s;
131
          s6 = s4 ^ s2;
132
          s7 = s6 ^ s;
133
          s8 = s4 << 1;
134
          if (s8 > 0xFF)
135
            s8 ^= ROOT;
136
          sb = s8 ^ s2 ^ s;
137
          T0[i] = s  << 24 | s3 << 16 | s4 << 8 | s5;
138
          T1[i] = s3 << 24 | s  << 16 | s5 << 8 | s4;
139
          T2[i] = s4 << 24 | s5 << 16 | s  << 8 | s3;
140
          T3[i] = s5 << 24 | s4 << 16 | s3 << 8 | s;
141
          T4[i] = s6 << 24 | s8 << 16 | sb << 8 | s7;
142
          T5[i] = s8 << 24 | s6 << 16 | s7 << 8 | sb;
143
          T6[i] = sb << 24 | s7 << 16 | s6 << 8 | s8;
144
          T7[i] = s7 << 24 | sb << 16 | s8 << 8 | s6;
145
        }
146
      for (i = 0, j = 0; i < R + 1; i++) // compute round constant
147
        {
148
          rc[i][0] =  S[j++]         << 24
149
                   | (S[j++] & 0xFF) << 16
150
                   | (S[j++] & 0xFF) << 8
151
                   | (S[j++] & 0xFF);
152
          rc[i][1] =  S[j++]         << 24
153
                   | (S[j++] & 0xFF) << 16
154
                   | (S[j++] & 0xFF) << 8
155
                   | (S[j++] & 0xFF);
156
        }
157
      time = System.currentTimeMillis() - time;
158
      if (Configuration.DEBUG)
159
        {
160
          log.fine("Static data");
161
          log.fine("T0[]:");
162
          StringBuilder b;
163
          for (i = 0; i < 64; i++)
164
            {
165
              b = new StringBuilder();
166
              for (j = 0; j < 4; j++)
167
                b.append("0x").append(Util.toString(T0[i * 4 + j])).append(", ");
168
              log.fine(b.toString());
169
            }
170
          log.fine("T1[]:");
171
          for (i = 0; i < 64; i++)
172
            {
173
              b = new StringBuilder();
174
              for (j = 0; j < 4; j++)
175
                b.append("0x").append(Util.toString(T1[i * 4 + j])).append(", ");
176
              log.fine(b.toString());
177
            }
178
          log.fine("T2[]:");
179
          for (i = 0; i < 64; i++)
180
            {
181
              b = new StringBuilder();
182
              for (j = 0; j < 4; j++)
183
                b.append("0x").append(Util.toString(T2[i * 4 + j])).append(", ");
184
              log.fine(b.toString());
185
            }
186
          log.fine("T3[]:");
187
          for (i = 0; i < 64; i++)
188
            {
189
              b = new StringBuilder();
190
              for (j = 0; j < 4; j++)
191
                b.append("0x").append(Util.toString(T3[i * 4 + j])).append(", ");
192
              log.fine(b.toString());
193
            }
194
          log.fine("T4[]:");
195
          for (i = 0; i < 64; i++)
196
            {
197
              b = new StringBuilder();
198
              for (j = 0; j < 4; j++)
199
                b.append("0x").append(Util.toString(T4[i * 4 + j])).append(", ");
200
              log.fine(b.toString());
201
            }
202
          log.fine("T5[]:");
203
          for (i = 0; i < 64; i++)
204
            {
205
              b = new StringBuilder();
206
              for (j = 0; j < 4; j++)
207
                b.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
208
              log.fine(b.toString());
209
            }
210
          log.fine("T6[]:");
211
          for (i = 0; i < 64; i++)
212
            {
213
              b = new StringBuilder();
214
              for (j = 0; j < 4; j++)
215
                b.append("0x").append(Util.toString(T6[i * 4 + j])).append(", ");
216
              log.fine(b.toString());
217
            }
218
          log.fine("T7[]:");
219
          for (i = 0; i < 64; i++)
220
            {
221
              b = new StringBuilder();
222
              for (j = 0; j < 4; j++)
223
                b.append("0x").append(Util.toString(T7[i * 4 + j])).append(", ");
224
              log.fine(b.toString());
225
            }
226
          log.fine("rc[]:");
227
          for (i = 0; i < R + 1; i++)
228
            log.fine("0x" + Util.toString(rc[i][0]) + Util.toString(rc[i][1]));
229
          log.fine("Total initialization time: " + time + " ms.");
230
        }
231
    }
232
 
233
  /** Trivial 0-arguments constructor. */
234
  public Khazad()
235
  {
236
    super(Registry.KHAZAD_CIPHER, DEFAULT_BLOCK_SIZE, DEFAULT_KEY_SIZE);
237
  }
238
 
239
  private static void khazad(byte[] in, int i, byte[] out, int j, int[][] K)
240
  {
241
    // sigma(K[0])
242
    int k0 = K[0][0];
243
    int k1 = K[0][1];
244
    int a0 = (in[i++]         << 24
245
           | (in[i++] & 0xFF) << 16
246
           | (in[i++] & 0xFF) <<  8
247
           | (in[i++] & 0xFF)      ) ^ k0;
248
    int a1 = (in[i++]         << 24
249
           | (in[i++] & 0xFF) << 16
250
           | (in[i++] & 0xFF) <<  8
251
           | (in[i  ] & 0xFF)      ) ^ k1;
252
    int b0, b1;
253
    // round function
254
    for (int r = 1; r < R; r++)
255
      {
256
        k0 = K[r][0];
257
        k1 = K[r][1];
258
        b0 = T0[ a0 >>> 24        ]
259
           ^ T1[(a0 >>> 16) & 0xFF]
260
           ^ T2[(a0 >>>  8) & 0xFF]
261
           ^ T3[ a0         & 0xFF]
262
           ^ T4[ a1 >>> 24        ]
263
           ^ T5[(a1 >>> 16) & 0xFF]
264
           ^ T6[(a1 >>>  8) & 0xFF]
265
           ^ T7[ a1         & 0xFF] ^ k0;
266
        b1 = T0[ a1 >>> 24        ]
267
           ^ T1[(a1 >>> 16) & 0xFF]
268
           ^ T2[(a1 >>>  8) & 0xFF]
269
           ^ T3[ a1         & 0xFF]
270
           ^ T4[ a0 >>> 24        ]
271
           ^ T5[(a0 >>> 16) & 0xFF]
272
           ^ T6[(a0 >>>  8) & 0xFF]
273
           ^ T7[ a0         & 0xFF] ^ k1;
274
        a0 = b0;
275
        a1 = b1;
276
        if (Configuration.DEBUG)
277
          log.fine("T" + r + "=" + Util.toString(a0) + Util.toString(a1));
278
      }
279
    // sigma(K[R]) o gamma applied to previous output
280
    k0 = K[R][0];
281
    k1 = K[R][1];
282
    out[j++] = (byte)(S[ a0 >>> 24        ] ^ (k0 >>> 24));
283
    out[j++] = (byte)(S[(a0 >>> 16) & 0xFF] ^ (k0 >>> 16));
284
    out[j++] = (byte)(S[(a0 >>>  8) & 0xFF] ^ (k0 >>>  8));
285
    out[j++] = (byte)(S[ a0         & 0xFF] ^  k0        );
286
    out[j++] = (byte)(S[ a1 >>> 24        ] ^ (k1 >>> 24));
287
    out[j++] = (byte)(S[(a1 >>> 16) & 0xFF] ^ (k1 >>> 16));
288
    out[j++] = (byte)(S[(a1 >>>  8) & 0xFF] ^ (k1 >>>  8));
289
    out[j  ] = (byte)(S[ a1         & 0xFF] ^  k1        );
290
    if (Configuration.DEBUG)
291
      log.fine("T=" + Util.toString(out, j - 7, 8) + "\n");
292
  }
293
 
294
  public Object clone()
295
  {
296
    Khazad result = new Khazad();
297
    result.currentBlockSize = this.currentBlockSize;
298
 
299
    return result;
300
  }
301
 
302
  public Iterator blockSizes()
303
  {
304
    ArrayList al = new ArrayList();
305
    al.add(Integer.valueOf(DEFAULT_BLOCK_SIZE));
306
 
307
    return Collections.unmodifiableList(al).iterator();
308
  }
309
 
310
  public Iterator keySizes()
311
  {
312
    ArrayList al = new ArrayList();
313
    al.add(Integer.valueOf(DEFAULT_KEY_SIZE));
314
    return Collections.unmodifiableList(al).iterator();
315
  }
316
 
317
  /**
318
   * Expands a user-supplied key material into a session key for a designated
319
   * <i>block size</i>.
320
   *
321
   * @param uk the 128-bit user-supplied key material.
322
   * @param bs the desired block size in bytes.
323
   * @return an Object encapsulating the session key.
324
   * @exception IllegalArgumentException if the block size is not 16 (128-bit).
325
   * @exception InvalidKeyException if the key data is invalid.
326
   */
327
  public Object makeKey(byte[] uk, int bs) throws InvalidKeyException
328
  {
329
    if (bs != DEFAULT_BLOCK_SIZE)
330
      throw new IllegalArgumentException();
331
    if (uk == null)
332
      throw new InvalidKeyException("Empty key");
333
    if (uk.length != 16)
334
      throw new InvalidKeyException("Key is not 128-bit.");
335
    int[][] Ke = new int[R + 1][2]; // encryption round keys
336
    int[][] Kd = new int[R + 1][2]; // decryption round keys
337
    int r, i;
338
    int k20, k21, k10, k11, rc0, rc1, kr0, kr1;
339
    i = 0;
340
    k20 =  uk[i++]         << 24
341
        | (uk[i++] & 0xFF) << 16
342
        | (uk[i++] & 0xFF) << 8
343
        | (uk[i++] & 0xFF);
344
    k21 =  uk[i++]         << 24
345
        | (uk[i++] & 0xFF) << 16
346
        | (uk[i++] & 0xFF) << 8
347
        | (uk[i++] & 0xFF);
348
    k10 =  uk[i++]         << 24
349
        | (uk[i++] & 0xFF) << 16
350
        | (uk[i++] & 0xFF) << 8
351
        | (uk[i++] & 0xFF);
352
    k11 =  uk[i++]         << 24
353
        | (uk[i++] & 0xFF) << 16
354
        | (uk[i++] & 0xFF) << 8
355
        | (uk[i++] & 0xFF);
356
    for (r = 0, i = 0; r <= R; r++)
357
      {
358
        rc0 = rc[r][0];
359
        rc1 = rc[r][1];
360
        kr0 = T0[ k10 >>> 24        ]
361
            ^ T1[(k10 >>> 16) & 0xFF]
362
            ^ T2[(k10 >>>  8) & 0xFF]
363
            ^ T3[ k10         & 0xFF]
364
            ^ T4[(k11 >>> 24) & 0xFF]
365
            ^ T5[(k11 >>> 16) & 0xFF]
366
            ^ T6[(k11 >>>  8) & 0xFF]
367
            ^ T7[ k11         & 0xFF] ^ rc0 ^ k20;
368
        kr1 = T0[ k11 >>> 24        ]
369
            ^ T1[(k11 >>> 16) & 0xFF]
370
            ^ T2[(k11 >>>  8) & 0xFF]
371
            ^ T3[ k11         & 0xFF]
372
            ^ T4[(k10 >>> 24) & 0xFF]
373
            ^ T5[(k10 >>> 16) & 0xFF]
374
            ^ T6[(k10 >>>  8) & 0xFF]
375
            ^ T7[ k10         & 0xFF] ^ rc1 ^ k21;
376
        Ke[r][0] = kr0;
377
        Ke[r][1] = kr1;
378
        k20 = k10;
379
        k21 = k11;
380
        k10 = kr0;
381
        k11 = kr1;
382
        if (r == 0 || r == R)
383
          {
384
            Kd[R - r][0] = kr0;
385
            Kd[R - r][1] = kr1;
386
          }
387
        else
388
          {
389
            Kd[R - r][0] = T0[S[ kr0 >>> 24        ] & 0xFF]
390
                         ^ T1[S[(kr0 >>> 16) & 0xFF] & 0xFF]
391
                         ^ T2[S[(kr0 >>>  8) & 0xFF] & 0xFF]
392
                         ^ T3[S[ kr0         & 0xFF] & 0xFF]
393
                         ^ T4[S[ kr1 >>> 24        ] & 0xFF]
394
                         ^ T5[S[(kr1 >>> 16) & 0xFF] & 0xFF]
395
                         ^ T6[S[(kr1 >>>  8) & 0xFF] & 0xFF]
396
                         ^ T7[S[ kr1         & 0xFF] & 0xFF];
397
            Kd[R - r][1] = T0[S[ kr1 >>> 24        ] & 0xFF]
398
                         ^ T1[S[(kr1 >>> 16) & 0xFF] & 0xFF]
399
                         ^ T2[S[(kr1 >>>  8) & 0xFF] & 0xFF]
400
                         ^ T3[S[ kr1         & 0xFF] & 0xFF]
401
                         ^ T4[S[ kr0 >>> 24        ] & 0xFF]
402
                         ^ T5[S[(kr0 >>> 16) & 0xFF] & 0xFF]
403
                         ^ T6[S[(kr0 >>>  8) & 0xFF] & 0xFF]
404
                         ^ T7[S[ kr0         & 0xFF] & 0xFF];
405
          }
406
      }
407
    if (Configuration.DEBUG)
408
      {
409
        log.fine("Key schedule");
410
        log.fine("Ke[]:");
411
        for (r = 0; r < R + 1; r++)
412
          log.fine("#" + r + ": 0x" + Util.toString(Ke[r][0])
413
                   + Util.toString(Ke[r][1]));
414
        log.fine("Kd[]:");
415
        for (r = 0; r < R + 1; r++)
416
          log.fine("#" + r + ": 0x" + Util.toString(Kd[r][0])
417
                   + Util.toString(Kd[r][1]));
418
      }
419
    return new Object[] { Ke, Kd };
420
  }
421
 
422
  public void encrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
423
  {
424
    if (bs != DEFAULT_BLOCK_SIZE)
425
      throw new IllegalArgumentException();
426
    int[][] K = (int[][])((Object[]) k)[0];
427
    khazad(in, i, out, j, K);
428
  }
429
 
430
  public void decrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
431
  {
432
    if (bs != DEFAULT_BLOCK_SIZE)
433
      throw new IllegalArgumentException();
434
    int[][] K = (int[][])((Object[]) k)[1];
435
    khazad(in, i, out, j, K);
436
  }
437
 
438
  public boolean selfTest()
439
  {
440
    if (valid == null)
441
      {
442
        boolean result = super.selfTest(); // do symmetry tests
443
        if (result)
444
          result = testKat(KAT_KEY, KAT_CT);
445
        valid = Boolean.valueOf(result);
446
      }
447
    return valid.booleanValue();
448
  }
449
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.