1 18 19 package jcifs.util; 20 21 import java.security.MessageDigest ; 22 23 37 public class MD4 extends MessageDigest implements Cloneable 38 { 39 42 45 private static final int BLOCK_LENGTH = 64; 47 50 private int[] context = new int[4]; 51 52 55 private long count; 56 57 60 private byte[] buffer = new byte[BLOCK_LENGTH]; 61 62 65 private int[] X = new int[16]; 66 67 68 71 public MD4 () { 72 super("MD4"); 73 engineReset(); 74 } 75 76 79 private MD4 (MD4 md) { 80 this(); 81 context = (int[])md.context.clone(); 82 buffer = (byte[])md.buffer.clone(); 83 count = md.count; 84 } 85 86 87 90 93 public Object clone() { return new MD4(this); } 94 95 96 99 103 public void engineReset () { 104 context[0] = 0x67452301; 107 context[1] = 0xEFCDAB89; 108 context[2] = 0x98BADCFE; 109 context[3] = 0x10325476; 110 count = 0L; 111 for (int i = 0; i < BLOCK_LENGTH; i++) 112 buffer[i] = 0; 113 } 114 115 118 public void engineUpdate (byte b) { 119 int i = (int)(count % BLOCK_LENGTH); 121 count++; buffer[i] = b; 123 if (i == BLOCK_LENGTH - 1) 124 transform(buffer, 0); 125 } 126 127 139 public void engineUpdate (byte[] input, int offset, int len) { 140 if (offset < 0 || len < 0 || (long)offset + len > input.length) 142 throw new ArrayIndexOutOfBoundsException (); 143 144 int bufferNdx = (int)(count % BLOCK_LENGTH); 146 count += len; int partLen = BLOCK_LENGTH - bufferNdx; 148 int i = 0; 149 if (len >= partLen) { 150 System.arraycopy(input, offset, buffer, bufferNdx, partLen); 151 152 153 transform(buffer, 0); 154 155 for (i = partLen; i + BLOCK_LENGTH - 1 < len; i+= BLOCK_LENGTH) 156 transform(input, offset + i); 157 bufferNdx = 0; 158 } 159 if (i < len) 161 System.arraycopy(input, offset + i, buffer, bufferNdx, len - i); 162 } 163 164 171 public byte[] engineDigest () { 172 int bufferNdx = (int)(count % BLOCK_LENGTH); 174 int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx); 175 176 byte[] tail = new byte[padLen + 8]; 178 tail[0] = (byte)0x80; 179 180 for (int i = 0; i < 8; i++) 184 tail[padLen + i] = (byte)((count * 8) >>> (8 * i)); 185 186 engineUpdate(tail, 0, tail.length); 187 188 byte[] result = new byte[16]; 189 for (int i = 0; i < 4; i++) 191 for (int j = 0; j < 4; j++) 192 result[i * 4 + j] = (byte)(context[i] >>> (8 * j)); 193 194 engineReset(); 196 return result; 197 } 198 199 200 203 212 private void transform (byte[] block, int offset) { 213 214 for (int i = 0; i < 16; i++) 217 X[i] = (block[offset++] & 0xFF) | 218 (block[offset++] & 0xFF) << 8 | 219 (block[offset++] & 0xFF) << 16 | 220 (block[offset++] & 0xFF) << 24; 221 222 223 int A = context[0]; 224 int B = context[1]; 225 int C = context[2]; 226 int D = context[3]; 227 228 A = FF(A, B, C, D, X[ 0], 3); 229 D = FF(D, A, B, C, X[ 1], 7); 230 C = FF(C, D, A, B, X[ 2], 11); 231 B = FF(B, C, D, A, X[ 3], 19); 232 A = FF(A, B, C, D, X[ 4], 3); 233 D = FF(D, A, B, C, X[ 5], 7); 234 C = FF(C, D, A, B, X[ 6], 11); 235 B = FF(B, C, D, A, X[ 7], 19); 236 A = FF(A, B, C, D, X[ 8], 3); 237 D = FF(D, A, B, C, X[ 9], 7); 238 C = FF(C, D, A, B, X[10], 11); 239 B = FF(B, C, D, A, X[11], 19); 240 A = FF(A, B, C, D, X[12], 3); 241 D = FF(D, A, B, C, X[13], 7); 242 C = FF(C, D, A, B, X[14], 11); 243 B = FF(B, C, D, A, X[15], 19); 244 245 A = GG(A, B, C, D, X[ 0], 3); 246 D = GG(D, A, B, C, X[ 4], 5); 247 C = GG(C, D, A, B, X[ 8], 9); 248 B = GG(B, C, D, A, X[12], 13); 249 A = GG(A, B, C, D, X[ 1], 3); 250 D = GG(D, A, B, C, X[ 5], 5); 251 C = GG(C, D, A, B, X[ 9], 9); 252 B = GG(B, C, D, A, X[13], 13); 253 A = GG(A, B, C, D, X[ 2], 3); 254 D = GG(D, A, B, C, X[ 6], 5); 255 C = GG(C, D, A, B, X[10], 9); 256 B = GG(B, C, D, A, X[14], 13); 257 A = GG(A, B, C, D, X[ 3], 3); 258 D = GG(D, A, B, C, X[ 7], 5); 259 C = GG(C, D, A, B, X[11], 9); 260 B = GG(B, C, D, A, X[15], 13); 261 262 A = HH(A, B, C, D, X[ 0], 3); 263 D = HH(D, A, B, C, X[ 8], 9); 264 C = HH(C, D, A, B, X[ 4], 11); 265 B = HH(B, C, D, A, X[12], 15); 266 A = HH(A, B, C, D, X[ 2], 3); 267 D = HH(D, A, B, C, X[10], 9); 268 C = HH(C, D, A, B, X[ 6], 11); 269 B = HH(B, C, D, A, X[14], 15); 270 A = HH(A, B, C, D, X[ 1], 3); 271 D = HH(D, A, B, C, X[ 9], 9); 272 C = HH(C, D, A, B, X[ 5], 11); 273 B = HH(B, C, D, A, X[13], 15); 274 A = HH(A, B, C, D, X[ 3], 3); 275 D = HH(D, A, B, C, X[11], 9); 276 C = HH(C, D, A, B, X[ 7], 11); 277 B = HH(B, C, D, A, X[15], 15); 278 279 context[0] += A; 280 context[1] += B; 281 context[2] += C; 282 context[3] += D; 283 } 284 285 287 private int FF (int a, int b, int c, int d, int x, int s) { 288 int t = a + ((b & c) | (~b & d)) + x; 289 return t << s | t >>> (32 - s); 290 } 291 private int GG (int a, int b, int c, int d, int x, int s) { 292 int t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999; 293 return t << s | t >>> (32 - s); 294 } 295 private int HH (int a, int b, int c, int d, int x, int s) { 296 int t = a + (b ^ c ^ d) + x + 0x6ED9EBA1; 297 return t << s | t >>> (32 - s); 298 } 299 } 300 | Popular Tags |