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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [security/] [hash/] [MD2.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* MD2.java --
2
   Copyright (C) 2001, 2002, 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.java.security.hash;
40
 
41
import gnu.java.security.Registry;
42
import gnu.java.security.util.Util;
43
 
44
/**
45
 * An implementation of the MD2 message digest algorithm.
46
 * <p>
47
 * MD2 is not widely used. Unless it is needed for compatibility with
48
 * existing systems, it is not recommended for use in new applications.
49
 * <p>
50
 * References:
51
 * <ol>
52
 *    <li>The <a href="http://www.ietf.org/rfc/rfc1319.txt">MD2</a>
53
 *    Message-Digest Algorithm.<br>
54
 *    B. Kaliski.</li>
55
 *    <li>The <a href="http://www.rfc-editor.org/errata.html">RFC ERRATA PAGE</a>
56
 *    under section RFC 1319.</li>
57
 * </ol>
58
 */
59
public class MD2
60
    extends BaseHash
61
{
62
  /** An MD2 message digest is always 128-bits long, or 16 bytes. */
63
  private static final int DIGEST_LENGTH = 16;
64
 
65
  /** The MD2 algorithm operates on 128-bit blocks, or 16 bytes. */
66
  private static final int BLOCK_LENGTH = 16;
67
 
68
  /** 256 byte "random" permutation of the digits of pi. */
69
  private static final byte[] PI = {
70
        41,   46,   67,  -55,  -94,  -40,  124,   1,
71
        61,   54,   84,  -95,  -20,  -16,    6,  19,
72
        98,  -89,    5,  -13,  -64,  -57,  115, -116,
73
      -104, -109,   43,  -39,  -68,   76, -126,  -54,
74
        30, -101,   87,   60,   -3,  -44,  -32,   22,
75
       103,   66,  111,   24, -118,   23,  -27,   18,
76
       -66,   78,  -60,  -42,  -38,  -98,  -34,   73,
77
       -96,   -5,  -11, -114,  -69,   47,  -18,  122,
78
       -87,  104,  121, -111,   21,  -78,    7,   63,
79
      -108,  -62,   16, -119,   11,   34,   95,   33,
80
      -128,  127,   93, -102,   90, -112,   50,   39,
81
        53,   62,  -52,  -25,  -65,   -9, -105,    3,
82
        -1,   25,   48,  -77,   72,  -91,  -75,  -47,
83
       -41,   94, -110,   42,  -84,   86,  -86,  -58,
84
        79,  -72,   56,  -46, -106,  -92,  125,  -74,
85
       118,   -4,  107,  -30, -100,  116,    4,  -15,
86
        69,  -99,  112,   89,  100,  113, -121,   32,
87
      -122,   91,  -49,  101,  -26,   45,  -88,    2,
88
        27,   96,   37,  -83,  -82,  -80,  -71,  -10,
89
        28,   70,   97,  105,   52,   64,  126,   15,
90
        85,   71,  -93,   35,  -35,   81,  -81,   58,
91
       -61,   92,   -7,  -50,  -70,  -59,  -22,   38,
92
        44,   83,   13,  110, -123,   40, -124,    9,
93
       -45,  -33,  -51,  -12,   65, -127,   77,   82,
94
       106,  -36,   55,  -56,  108,  -63,  -85,   -6,
95
        36,  -31,  123,    8,   12,  -67,  -79,   74,
96
       120, -120, -107, -117,  -29,   99,  -24,  109,
97
       -23,  -53,  -43,   -2,   59,    0,   29,   57,
98
       -14,  -17,  -73,   14,  102,   88,  -48,  -28,
99
       -90,  119,  114,   -8,  -21,  117,   75,   10,
100
        49,   68,   80,  -76, -113,  -19,   31,   26,
101
       -37, -103, -115,   51, - 97,   17, -125,   20 };
102
 
103
  /** The output of this message digest when no data has been input. */
104
  private static final String DIGEST0 = "8350E5A3E24C153DF2275C9F80692773";
105
 
106
  /** caches the result of the correctness test, once executed. */
107
  private static Boolean valid;
108
 
109
  /** The checksum computed so far. */
110
  private byte[] checksum;
111
 
112
  /**
113
   * Work array needed by encrypt method. First <code>BLOCK_LENGTH</code> bytes
114
   * are also used to store the running digest.
115
   */
116
  private byte[] work;
117
 
118
  /** Creates a new MD2 digest ready for use. */
119
  public MD2()
120
  {
121
    super(Registry.MD2_HASH, DIGEST_LENGTH, BLOCK_LENGTH);
122
  }
123
 
124
  /**
125
   * Private constructor used for cloning.
126
   *
127
   * @param md2 the instance to clone.
128
   */
129
  private MD2(MD2 md2)
130
  {
131
    this();
132
 
133
    // superclass field
134
    this.count = md2.count;
135
    this.buffer = (byte[]) md2.buffer.clone();
136
    // private field
137
    this.checksum = (byte[]) md2.checksum.clone();
138
    this.work = (byte[]) md2.work.clone();
139
  }
140
 
141
  public Object clone()
142
  {
143
    return new MD2(this);
144
  }
145
 
146
  protected byte[] getResult()
147
  {
148
    byte[] result = new byte[DIGEST_LENGTH];
149
    // Encrypt checksum as last block.
150
    encryptBlock(checksum, 0);
151
    for (int i = 0; i < BLOCK_LENGTH; i++)
152
      result[i] = work[i];
153
 
154
    return result;
155
  }
156
 
157
  protected void resetContext()
158
  {
159
    checksum = new byte[BLOCK_LENGTH];
160
    work = new byte[BLOCK_LENGTH * 3];
161
  }
162
 
163
  public boolean selfTest()
164
  {
165
    if (valid == null)
166
      {
167
        String d = Util.toString(new MD2().digest());
168
        valid = Boolean.valueOf(DIGEST0.equals(d));
169
      }
170
    return valid.booleanValue();
171
  }
172
 
173
  /**
174
   * Generates an array of padding bytes. The padding is defined as
175
   * <code>i</code> bytes of value <code>i</code>, where <code>i</code> is the
176
   * number of bytes to fill the last block of the message to
177
   * <code>BLOCK_LENGTH</code> bytes (or <code>BLOCK_LENGTH</code> bytes when
178
   * the last block was completely full).
179
   *
180
   * @return the bytes to pad the remaining bytes in the buffer before
181
   * completing a hash operation.
182
   */
183
  protected byte[] padBuffer()
184
  {
185
    int length = BLOCK_LENGTH - (int) (count % BLOCK_LENGTH);
186
    if (length == 0)
187
      length = BLOCK_LENGTH;
188
 
189
    byte[] pad = new byte[length];
190
    for (int i = 0; i < length; i++)
191
      pad[i] = (byte) length;
192
 
193
    return pad;
194
  }
195
 
196
  /**
197
   * Adds <code>BLOCK_LENGTH</code> bytes to the running digest.
198
   *
199
   * @param in the byte array to take the <code>BLOCK_LENGTH</code> bytes from.
200
   * @param off the offset to start from in the given byte array.
201
   */
202
  protected void transform(byte[] in, int off)
203
  {
204
    updateCheckSumAndEncryptBlock(in, off);
205
  }
206
 
207
  /**
208
   * Adds a new block (<code>BLOCK_LENGTH</code> bytes) to the running digest
209
   * from the given byte array starting from the given offset.
210
   */
211
  private void encryptBlock(byte[] in, int off)
212
  {
213
    for (int i = 0; i < BLOCK_LENGTH; i++)
214
      {
215
        byte b = in[off + i];
216
        work[BLOCK_LENGTH + i] = b;
217
        work[BLOCK_LENGTH * 2 + i] = (byte)(work[i] ^ b);
218
      }
219
    byte t = 0;
220
    for (int i = 0; i < 18; i++)
221
      {
222
        for (int j = 0; j < 3 * BLOCK_LENGTH; j++)
223
          {
224
            t = (byte)(work[j] ^ PI[t & 0xFF]);
225
            work[j] = t;
226
          }
227
        t = (byte)(t + i);
228
      }
229
  }
230
 
231
  /**
232
   * Optimized method that combines a checksum update and encrypt of a block.
233
   */
234
  private void updateCheckSumAndEncryptBlock(byte[] in, int off)
235
  {
236
    byte l = checksum[BLOCK_LENGTH - 1];
237
    for (int i = 0; i < BLOCK_LENGTH; i++)
238
      {
239
        byte b = in[off + i];
240
        work[BLOCK_LENGTH + i] = b;
241
        work[BLOCK_LENGTH * 2 + i] = (byte)(work[i] ^ b);
242
        l = (byte)(checksum[i] ^ PI[(b ^ l) & 0xFF]);
243
        checksum[i] = l;
244
      }
245
    byte t = 0;
246
    for (int i = 0; i < 18; i++)
247
      {
248
        for (int j = 0; j < 3 * BLOCK_LENGTH; j++)
249
          {
250
            t = (byte)(work[j] ^ PI[t & 0xFF]);
251
            work[j] = t;
252
          }
253
        t = (byte)(t + i);
254
      }
255
  }
256
}

powered by: WebSVN 2.1.0

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