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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* Square.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.security.InvalidKeyException;
45
import java.util.ArrayList;
46
import java.util.Collections;
47
import java.util.Iterator;
48
 
49
/**
50
 * Square is a 128-bit key, 128-bit block cipher algorithm developed by Joan
51
 * Daemen, Lars Knudsen and Vincent Rijmen.
52
 * <p>
53
 * References:
54
 * <ol>
55
 * <li><a href="http://www.esat.kuleuven.ac.be/~rijmen/square/">The block
56
 * cipher Square</a>.<br>
57
 * <a href="mailto:daemen.j@protonworld.com">Joan Daemen</a>, <a
58
 * href="mailto:lars.knudsen@esat.kuleuven.ac.be">Lars Knudsen</a> and <a
59
 * href="mailto:vincent.rijmen@esat.kuleuven.ac.be">Vincent Rijmen</a>.</li>
60
 * </ol>
61
 */
62
public final class Square
63
    extends BaseCipher
64
{
65
  private static final int DEFAULT_BLOCK_SIZE = 16; // in bytes
66
  private static final int DEFAULT_KEY_SIZE = 16; // in bytes
67
  private static final int ROUNDS = 8;
68
  private static final int ROOT = 0x1F5; // for generating GF(2**8)
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
  /** Substitution boxes for encryption and decryption. */
88
  private static final byte[] Se = new byte[256];
89
  private static final byte[] Sd = new byte[256];
90
  /** Transposition boxes for encryption and decryption. */
91
  private static final int[] Te = new int[256];
92
  private static final int[] Td = new int[256];
93
  /**
94
   * KAT vector (from ecb_vk): I=87 KEY=00000000000000000000020000000000
95
   * CT=A9DF031B4E25E89F527EFFF89CB0BEBA
96
   */
97
  private static final byte[] KAT_KEY =
98
      Util.toBytesFromString("00000000000000000000020000000000");
99
  private static final byte[] KAT_CT =
100
      Util.toBytesFromString("A9DF031B4E25E89F527EFFF89CB0BEBA");
101
  /** caches the result of the correctness test, once executed. */
102
  private static Boolean valid;
103
  static
104
    {
105
      int i, j;
106
      // re-construct Se box values
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
      // compute Sd box values
116
      for (i = 0; i < 256; i++)
117
        Sd[Se[i] & 0xFF] = (byte) i;
118
      // generate OFFSET values
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
      // generate Te and Td boxes if we're not reading their values
127
      // Notes:
128
      // (1) The function mul() computes the product of two elements of GF(2**8)
129
      // with ROOT as reduction polynomial.
130
      // (2) the values used in computing the Te and Td are the GF(2**8)
131
      // coefficients of the diffusion polynomial c(x) and its inverse
132
      // (modulo x**4 + 1) d(x), defined in sections 2.1 and 4 of the Square
133
      // paper.
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
  /** Trivial 0-arguments constructor. */
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
      { // R - 1 full rounds
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
    // last round (diffusion becomes only transposition)
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
  /**
236
   * Applies the Theta function to an input <i>in</i> in order to produce in
237
   * <i>out</i> an internal session sub-key.
238
   * <p>
239
   * Both <i>in</i> and <i>out</i> are arrays of four ints.
240
   * <p>
241
   * Pseudo-code is:
242
   * <pre>
243
   * for (i = 0; i &lt; 4; i++)
244
   *   {
245
   *     out[i] = 0;
246
   *     for (j = 0, n = 24; j &lt; 4; j++, n -= 8)
247
   *       {
248
   *         k = mul(in[i] &gt;&gt;&gt; 24, G[0][j]) &circ; mul(in[i] &gt;&gt;&gt; 16, G[1][j])
249
   *             &circ; mul(in[i] &gt;&gt;&gt; 8, G[2][j]) &circ; mul(in[i], G[3][j]);
250
   *         out[i] &circ;= k &lt;&lt; n;
251
   *       }
252
   *   }
253
   * </pre>
254
   */
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
  /**
273
   * Left rotate a 32-bit chunk.
274
   *
275
   * @param x the 32-bit data to rotate
276
   * @param s number of places to left-rotate by
277
   * @return the newly permutated value.
278
   */
279
  private static int rot32L(int x, int s)
280
  {
281
    return x << s | x >>> (32 - s);
282
  }
283
 
284
  /**
285
   * Right rotate a 32-bit chunk.
286
   *
287
   * @param x the 32-bit data to rotate
288
   * @param s number of places to right-rotate by
289
   * @return the newly permutated value.
290
   */
291
  private static int rot32R(int x, int s)
292
  {
293
    return x >>> s | x << (32 - s);
294
  }
295
 
296
  /**
297
   * Returns the product of two binary numbers a and b, using the generator ROOT
298
   * as the modulus: p = (a * b) mod ROOT. ROOT Generates a suitable Galois
299
   * Field in GF(2**8).
300
   * <p>
301
   * For best performance call it with abs(b) &lt; abs(a).
302
   *
303
   * @param a operand for multiply.
304
   * @param b operand for multiply.
305
   * @return the result of (a * b) % ROOT.
306
   */
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(); // do symmetry tests
419
        if (result)
420
          result = testKat(KAT_KEY, KAT_CT);
421
        valid = Boolean.valueOf(result);
422
      }
423
    return valid.booleanValue();
424
  }
425
}

powered by: WebSVN 2.1.0

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