Source code: com/ssttr/crypto/MD2.java
1 /*
2 * @(#)MD2.java 1.2 95/08/07
3 *
4 * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and distribute this software
7 * and its documentation for NON-COMMERCIAL purposes and without
8 * fee is hereby granted provided that this copyright notice
9 * appears in all copies. Please refer to the file "copyright.html"
10 * for further important copyright and licensing information.
11 *
12 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
13 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
14 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
16 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
17 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
18 *
19 * This file was obtained from: http://www.mcmanis.com/~cmcmanis/java/src/util/crypt/MD2.java
20 * More information can be found here: http://www.mcmanis.com/~cmcmanis/java/
21 */
22
23 package com.ssttr.crypto;
24
25
26 /**
27 * The MD2 class is used to compute an MD2 message digest over a given
28 * buffer of bytes. It is an implementation of the RSA Data Security Inc
29 * MD2 algorithim as described in internet RFC 1319.
30 *
31 * @version 07 Aug 1995, 1.2
32 * @author Chuck McManis
33 * @see MD5
34 */
35 public final class MD2 extends MessageDigest {
36 private byte state[] = new byte[16];
37 private byte checksum[] = new byte[16];
38 private int count;
39 private byte buffer[] = new byte[16];
40 private static byte transformBuffer[];
41
42 /**
43 * Permutation of 0..255 constructed from the digits of pi.
44 * It gives a "random" nonlinear byte substitution operation.
45 */
46 private static final byte PI_SUBST[] = {
47 (byte) 41, (byte)46, (byte)67, (byte)201, (byte)162,
48 (byte)216, (byte)124, (byte)1, (byte)61, (byte)54, (byte)84,
49 (byte)161, (byte)236, (byte)240, (byte)6, (byte) 19, (byte)98,
50 (byte)167, (byte)5, (byte)243, (byte)192, (byte)199, (byte)115,
51 (byte)140, (byte)152, (byte)147, (byte)43, (byte)217, (byte)188,
52 (byte) 76, (byte)130, (byte)202, (byte)30, (byte)155, (byte)87,
53 (byte)60, (byte)253, (byte)212, (byte)224, (byte)22, (byte)103,
54 (byte)66, (byte)111, (byte)24, (byte) 138, (byte)23, (byte)229,
55 (byte)18, (byte)190, (byte)78, (byte)196, (byte)214, (byte)218,
56 (byte)158, (byte)222, (byte)73, (byte)160, (byte)251, (byte) 245,
57 (byte)142, (byte)187, (byte)47, (byte)238, (byte)122, (byte)169,
58 (byte)104, (byte)121, (byte)145, (byte)21, (byte)178, (byte)7,
59 (byte)63, (byte) 148, (byte)194, (byte)16, (byte)137, (byte)11,
60 (byte)34, (byte)95, (byte)33, (byte)128, (byte)127, (byte)93,
61 (byte)154, (byte)90, (byte)144, (byte)50, (byte) 39, (byte)53,
62 (byte)62, (byte)204, (byte)231, (byte)191, (byte)247, (byte)151,
63 (byte)3, (byte)255, (byte)25, (byte)48, (byte)179, (byte)72,
64 (byte)165, (byte) 181, (byte)209, (byte)215, (byte)94, (byte)146,
65 (byte)42, (byte)172, (byte)86, (byte)170, (byte)198, (byte)79,
66 (byte)184, (byte)56, (byte)210, (byte) 150, (byte)164, (byte)125,
67 (byte)182, (byte)118, (byte)252, (byte)107, (byte)226, (byte)156,
68 (byte)116, (byte)4, (byte)241, (byte)69, (byte)157, (byte) 112,
69 (byte)89, (byte)100, (byte)113, (byte)135, (byte)32, (byte)134,
70 (byte)91, (byte)207, (byte)101, (byte)230, (byte)45, (byte)168,
71 (byte)2, (byte)27, (byte) 96, (byte)37, (byte)173, (byte)174,
72 (byte)176, (byte)185, (byte)246, (byte)28, (byte)70, (byte)97,
73 (byte)105, (byte)52, (byte)64, (byte)126, (byte)15, (byte) 85,
74 (byte)71, (byte)163, (byte)35, (byte)221, (byte)81, (byte)175,
75 (byte)58, (byte)195, (byte)92, (byte)249, (byte)206, (byte)186,
76 (byte)197, (byte) 234, (byte)38, (byte)44, (byte)83, (byte)13,
77 (byte)110, (byte)133, (byte)40, (byte)132, (byte)9, (byte)211,
78 (byte)223, (byte)205, (byte)244, (byte)65, (byte) 129, (byte)77,
79 (byte)82, (byte)106, (byte)220, (byte)55, (byte)200, (byte)108,
80 (byte)193, (byte)171, (byte)250, (byte)36, (byte)225, (byte)123,
81 (byte) 8, (byte)12, (byte)189, (byte)177, (byte)74, (byte)120,
82 (byte)136, (byte)149, (byte)139, (byte)227, (byte)99, (byte)232,
83 (byte)109, (byte)233, (byte) 203, (byte)213, (byte)254, (byte)59,
84 (byte)0, (byte)29, (byte)57, (byte)242, (byte)239, (byte)183,
85 (byte)14, (byte)102, (byte)88, (byte)208, (byte)228, (byte) 166,
86 (byte)119, (byte)114, (byte)248, (byte)235, (byte)117, (byte)75,
87 (byte)10, (byte)49, (byte)68, (byte)80, (byte)180, (byte)143,
88 (byte)237, (byte) 31, (byte)26, (byte)219, (byte)153, (byte)141,
89 (byte)51, (byte)159, (byte)17, (byte)131, (byte)20
90 };
91
92 /**
93 * Standard constructor, creates a new MD2 instance, allocates its
94 * buffers from the heap.
95 */
96 public MD2() {
97 count = 0;
98 if (transformBuffer == null)
99 transformBuffer = new byte[48];
100 digestBits = new byte[16];
101 digestValid = false;
102 }
103
104 /**
105 * Alternate constructor, allows you to pass in the buffer where you
106 * want the resulting digest stored.
107 */
108 public MD2(byte mydigest[]) {
109 count = 0;
110 if (transformBuffer == null)
111 transformBuffer = new byte[48];
112 digestBits = mydigest;
113 digestValid = false;
114 }
115
116 /**
117 * perform the basic MD2 transformation.
118 */
119 private void transform() {
120 for (int i = 0; i < 16; i++) {
121 transformBuffer[i] = state[i];
122 transformBuffer[i+16] = buffer[i];
123 transformBuffer[i+32] = (byte) (state[i] ^ buffer[i]);
124 }
125
126 /* do one round */
127 int t = 0;
128 for (int i = 0; i < 18; i++) {
129 for (int j = 0; j < 48; j++) {
130 transformBuffer[j] ^= PI_SUBST[t];
131 t = (transformBuffer[j]) & 0xff;
132 }
133 t = (t + i) & 0xff;
134 }
135
136 /* save new state */
137 for (int i = 0; i < 16; i++) {
138 state[i] = transformBuffer[i];
139 }
140
141 /* update checksum */
142 t = checksum[15];
143 for (int i = 0; i < 16; i++) {
144 checksum[i] ^= PI_SUBST[(buffer[i] ^ t) & 0xff];
145 t = (checksum[i]) & 0xff;
146 }
147
148 for (int i = 0; i < transformBuffer.length; i++) {
149 transformBuffer[i] = 0;
150 }
151 }
152
153 /**
154 * Initialize the MD2 state information and reset the counters.
155 */
156 public void init() {
157 count = 0;
158 // Load magic initialization constants.
159 for (int i = 0; i < state.length; i++)
160 state[i] = 0;
161
162 for (int i = 0; i < checksum.length; i++)
163 checksum[i] = 0;
164
165 digestValid = false;
166 for (int i = 0; i < digestBits.length; i++)
167 digestBits[i] = 0;
168 }
169
170 /**
171 * update adds the passed type to the input buffer
172 */
173 public synchronized void update(byte b) {
174 int index;
175
176 index = count;
177 count = (count + 1) % 16;
178 buffer[index] = b;
179 if (count == 0) {
180 transform();
181 }
182 }
183
184 /**
185 * Perform the final computations, any buffered bytes are added
186 * to the digest, the count is added to the digest, and the resulting
187 * digest is stored. After calling final you will need to call
188 * init() again to do another digest.
189 */
190 public void finish() {
191 byte b;
192 int index;
193 byte tmp[] = new byte[16];
194
195 /*
196 * Pad out to an exact multiple of 16, what to do if the
197 * input is a multiple of 16 ?
198 */
199 index = count;
200 b = (byte) (16 - index);
201 for (int i = 0; i < (16 - index); i ++) {
202 update(b);
203 }
204
205 System.arraycopy(checksum, 0, tmp, 0, checksum.length);
206 update(tmp);
207
208 System.arraycopy(state, 0, digestBits, 0, 16);
209 digestValid = true;
210 }
211
212 public String getAlg() {
213 return ("MD2");
214 }
215 }