1 21 22 package com.knowgate.jcifs.util; 23 24 import java.security.MessageDigest ; 25 26 40 public class MD4 extends MessageDigest implements Cloneable 41 { 42 45 48 private static final int BLOCK_LENGTH = 64; 50 53 private int[] context = new int[4]; 54 55 58 private long count; 59 60 63 private byte[] buffer = new byte[BLOCK_LENGTH]; 64 65 68 private int[] X = new int[16]; 69 70 71 74 public MD4 () { 75 super("MD4"); 76 engineReset(); 77 } 78 79 82 private MD4 (MD4 md) { 83 this(); 84 context = (int[])md.context.clone(); 85 buffer = (byte[])md.buffer.clone(); 86 count = md.count; 87 } 88 89 90 93 96 public Object clone() { return new MD4(this); } 97 98 99 102 106 public void engineReset () { 107 context[0] = 0x67452301; 110 context[1] = 0xEFCDAB89; 111 context[2] = 0x98BADCFE; 112 context[3] = 0x10325476; 113 count = 0L; 114 for (int i = 0; i < BLOCK_LENGTH; i++) 115 buffer[i] = 0; 116 } 117 118 121 public void engineUpdate (byte b) { 122 int i = (int)(count % BLOCK_LENGTH); 124 count++; buffer[i] = b; 126 if (i == BLOCK_LENGTH - 1) 127 transform(buffer, 0); 128 } 129 130 142 public void engineUpdate (byte[] input, int offset, int len) { 143 if (offset < 0 || len < 0 || (long)offset + len > input.length) 145 throw new ArrayIndexOutOfBoundsException (); 146 147 int bufferNdx = (int)(count % BLOCK_LENGTH); 149 count += len; int partLen = BLOCK_LENGTH - bufferNdx; 151 int i = 0; 152 if (len >= partLen) { 153 System.arraycopy(input, offset, buffer, bufferNdx, partLen); 154 155 156 transform(buffer, 0); 157 158 for (i = partLen; i + BLOCK_LENGTH - 1 < len; i+= BLOCK_LENGTH) 159 transform(input, offset + i); 160 bufferNdx = 0; 161 } 162 if (i < len) 164 System.arraycopy(input, offset + i, buffer, bufferNdx, len - i); 165 } 166 167 174 public byte[] engineDigest () { 175 int bufferNdx = (int)(count % BLOCK_LENGTH); 177 int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx); 178 179 byte[] tail = new byte[padLen + 8]; 181 tail[0] = (byte)0x80; 182 183 for (int i = 0; i < 8; i++) 187 tail[padLen + i] = (byte)((count * 8) >>> (8 * i)); 188 189 engineUpdate(tail, 0, tail.length); 190 191 byte[] result = new byte[16]; 192 for (int i = 0; i < 4; i++) 194 for (int j = 0; j < 4; j++) 195 result[i * 4 + j] = (byte)(context[i] >>> (8 * j)); 196 197 engineReset(); 199 return result; 200 } 201 202 203 206 215 private void transform (byte[] block, int offset) { 216 217 for (int i = 0; i < 16; i++) 220 X[i] = (block[offset++] & 0xFF) | 221 (block[offset++] & 0xFF) << 8 | 222 (block[offset++] & 0xFF) << 16 | 223 (block[offset++] & 0xFF) << 24; 224 225 226 int A = context[0]; 227 int B = context[1]; 228 int C = context[2]; 229 int D = context[3]; 230 231 A = FF(A, B, C, D, X[ 0], 3); 232 D = FF(D, A, B, C, X[ 1], 7); 233 C = FF(C, D, A, B, X[ 2], 11); 234 B = FF(B, C, D, A, X[ 3], 19); 235 A = FF(A, B, C, D, X[ 4], 3); 236 D = FF(D, A, B, C, X[ 5], 7); 237 C = FF(C, D, A, B, X[ 6], 11); 238 B = FF(B, C, D, A, X[ 7], 19); 239 A = FF(A, B, C, D, X[ 8], 3); 240 D = FF(D, A, B, C, X[ 9], 7); 241 C = FF(C, D, A, B, X[10], 11); 242 B = FF(B, C, D, A, X[11], 19); 243 A = FF(A, B, C, D, X[12], 3); 244 D = FF(D, A, B, C, X[13], 7); 245 C = FF(C, D, A, B, X[14], 11); 246 B = FF(B, C, D, A, X[15], 19); 247 248 A = GG(A, B, C, D, X[ 0], 3); 249 D = GG(D, A, B, C, X[ 4], 5); 250 C = GG(C, D, A, B, X[ 8], 9); 251 B = GG(B, C, D, A, X[12], 13); 252 A = GG(A, B, C, D, X[ 1], 3); 253 D = GG(D, A, B, C, X[ 5], 5); 254 C = GG(C, D, A, B, X[ 9], 9); 255 B = GG(B, C, D, A, X[13], 13); 256 A = GG(A, B, C, D, X[ 2], 3); 257 D = GG(D, A, B, C, X[ 6], 5); 258 C = GG(C, D, A, B, X[10], 9); 259 B = GG(B, C, D, A, X[14], 13); 260 A = GG(A, B, C, D, X[ 3], 3); 261 D = GG(D, A, B, C, X[ 7], 5); 262 C = GG(C, D, A, B, X[11], 9); 263 B = GG(B, C, D, A, X[15], 13); 264 265 A = HH(A, B, C, D, X[ 0], 3); 266 D = HH(D, A, B, C, X[ 8], 9); 267 C = HH(C, D, A, B, X[ 4], 11); 268 B = HH(B, C, D, A, X[12], 15); 269 A = HH(A, B, C, D, X[ 2], 3); 270 D = HH(D, A, B, C, X[10], 9); 271 C = HH(C, D, A, B, X[ 6], 11); 272 B = HH(B, C, D, A, X[14], 15); 273 A = HH(A, B, C, D, X[ 1], 3); 274 D = HH(D, A, B, C, X[ 9], 9); 275 C = HH(C, D, A, B, X[ 5], 11); 276 B = HH(B, C, D, A, X[13], 15); 277 A = HH(A, B, C, D, X[ 3], 3); 278 D = HH(D, A, B, C, X[11], 9); 279 C = HH(C, D, A, B, X[ 7], 11); 280 B = HH(B, C, D, A, X[15], 15); 281 282 context[0] += A; 283 context[1] += B; 284 context[2] += C; 285 context[3] += D; 286 } 287 288 290 private int FF (int a, int b, int c, int d, int x, int s) { 291 int t = a + ((b & c) | (~b & d)) + x; 292 return t << s | t >>> (32 - s); 293 } 294 private int GG (int a, int b, int c, int d, int x, int s) { 295 int t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999; 296 return t << s | t >>> (32 - s); 297 } 298 private int HH (int a, int b, int c, int d, int x, int s) { 299 int t = a + (b ^ c ^ d) + x + 0x6ED9EBA1; 300 return t << s | t >>> (32 - s); 301 } 302 } 303 | Popular Tags |