Source for gnu.java.security.hash.MD4

   1: /* MD4.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 Ron Rivest's MD4 message digest algorithm.
  46:  * <p>
  47:  * MD4 was the precursor to the stronger {@link gnu.java.security.hash.MD5}
  48:  * algorithm, and while not considered cryptograpically secure itself, MD4 is
  49:  * in use in various applications. It is slightly faster than MD5.
  50:  * <p>
  51:  * References:
  52:  * <ol>
  53:  *    <li>The <a href="http://www.ietf.org/rfc/rfc1320.txt">MD4</a>
  54:  *    Message-Digest Algorithm.<br>
  55:  *    R. Rivest.</li>
  56:  * </ol>
  57:  *
  58:  * @author Casey Marshall (rsdio@metastatic.org)
  59:  */
  60: public class MD4
  61:     extends BaseHash
  62: {
  63:   /** An MD4 message digest is always 128-bits long, or 16 bytes. */
  64:   private static final int DIGEST_LENGTH = 16;
  65: 
  66:   /** The MD4 algorithm operates on 512-bit blocks, or 64 bytes. */
  67:   private static final int BLOCK_LENGTH = 64;
  68: 
  69:   private static final int A = 0x67452301;
  70: 
  71:   private static final int B = 0xefcdab89;
  72: 
  73:   private static final int C = 0x98badcfe;
  74: 
  75:   private static final int D = 0x10325476;
  76: 
  77:   /** The output of this message digest when no data has been input. */
  78:   private static final String DIGEST0 = "31D6CFE0D16AE931B73C59D7E0C089C0";
  79: 
  80:   /** caches the result of the correctness test, once executed. */
  81:   private static Boolean valid;
  82: 
  83:   private int a, b, c, d;
  84: 
  85:   /**
  86:    * Public constructor. Initializes the chaining variables, sets the byte
  87:    * count to <code>0</code>, and creates a new block of <code>512</code> bits.
  88:    */
  89:   public MD4()
  90:   {
  91:     super(Registry.MD4_HASH, DIGEST_LENGTH, BLOCK_LENGTH);
  92:   }
  93: 
  94:   /**
  95:    * Trivial private constructor for cloning purposes.
  96:    *
  97:    * @param that the instance to clone.
  98:    */
  99:   private MD4(MD4 that)
 100:   {
 101:     this();
 102: 
 103:     this.a = that.a;
 104:     this.b = that.b;
 105:     this.c = that.c;
 106:     this.d = that.d;
 107:     this.count = that.count;
 108:     this.buffer = (byte[]) that.buffer.clone();
 109:   }
 110: 
 111:   public Object clone()
 112:   {
 113:     return new MD4(this);
 114:   }
 115: 
 116:   protected byte[] getResult()
 117:   {
 118:     return new byte[] {
 119:         (byte) a, (byte)(a >>> 8), (byte)(a >>> 16), (byte)(a >>> 24),
 120:         (byte) b, (byte)(b >>> 8), (byte)(b >>> 16), (byte)(b >>> 24),
 121:         (byte) c, (byte)(c >>> 8), (byte)(c >>> 16), (byte)(c >>> 24),
 122:         (byte) d, (byte)(d >>> 8), (byte)(d >>> 16), (byte)(d >>> 24) };
 123:   }
 124: 
 125:   protected void resetContext()
 126:   {
 127:     a = A;
 128:     b = B;
 129:     c = C;
 130:     d = D;
 131:   }
 132: 
 133:   public boolean selfTest()
 134:   {
 135:     if (valid == null)
 136:       {
 137:         String d = Util.toString(new MD4().digest());
 138:         valid = Boolean.valueOf(DIGEST0.equals(d));
 139:       }
 140:     return valid.booleanValue();
 141:   }
 142: 
 143:   protected byte[] padBuffer()
 144:   {
 145:     int n = (int)(count % BLOCK_LENGTH);
 146:     int padding = (n < 56) ? (56 - n) : (120 - n);
 147:     byte[] pad = new byte[padding + 8];
 148:     pad[0] = (byte) 0x80;
 149:     long bits = count << 3;
 150:     pad[padding++] = (byte) bits;
 151:     pad[padding++] = (byte)(bits >>> 8);
 152:     pad[padding++] = (byte)(bits >>> 16);
 153:     pad[padding++] = (byte)(bits >>> 24);
 154:     pad[padding++] = (byte)(bits >>> 32);
 155:     pad[padding++] = (byte)(bits >>> 40);
 156:     pad[padding++] = (byte)(bits >>> 48);
 157:     pad[padding  ] = (byte)(bits >>> 56);
 158:     return pad;
 159:   }
 160: 
 161:   protected void transform(byte[] in, int i)
 162:   {
 163:     int X0 = (in[i++] & 0xFF)
 164:            | (in[i++] & 0xFF) << 8
 165:            | (in[i++] & 0xFF) << 16
 166:            | in[i++] << 24;
 167:     int X1 = (in[i++] & 0xFF)
 168:            | (in[i++] & 0xFF) << 8
 169:            | (in[i++] & 0xFF) << 16
 170:            | in[i++] << 24;
 171:     int X2 = (in[i++] & 0xFF)
 172:            | (in[i++] & 0xFF) << 8
 173:            | (in[i++] & 0xFF) << 16
 174:            | in[i++] << 24;
 175:     int X3 = (in[i++] & 0xFF)
 176:            | (in[i++] & 0xFF) << 8
 177:            | (in[i++] & 0xFF) << 16
 178:            | in[i++] << 24;
 179:     int X4 = (in[i++] & 0xFF)
 180:            | (in[i++] & 0xFF) << 8
 181:            | (in[i++] & 0xFF) << 16
 182:            | in[i++] << 24;
 183:     int X5 = (in[i++] & 0xFF)
 184:            | (in[i++] & 0xFF) << 8
 185:            | (in[i++] & 0xFF) << 16
 186:            | in[i++] << 24;
 187:     int X6 = (in[i++] & 0xFF)
 188:            | (in[i++] & 0xFF) << 8
 189:            | (in[i++] & 0xFF) << 16
 190:            | in[i++] << 24;
 191:     int X7 = (in[i++] & 0xFF)
 192:            | (in[i++] & 0xFF) << 8
 193:            | (in[i++] & 0xFF) << 16
 194:            | in[i++] << 24;
 195:     int X8 = (in[i++] & 0xFF)
 196:            | (in[i++] & 0xFF) << 8
 197:            | (in[i++] & 0xFF) << 16
 198:            | in[i++] << 24;
 199:     int X9 = (in[i++] & 0xFF)
 200:            | (in[i++] & 0xFF) << 8
 201:            | (in[i++] & 0xFF) << 16
 202:            | in[i++] << 24;
 203:     int X10 = (in[i++] & 0xFF)
 204:             | (in[i++] & 0xFF) << 8
 205:             | (in[i++] & 0xFF) << 16
 206:             | in[i++] << 24;
 207:     int X11 = (in[i++] & 0xFF)
 208:             | (in[i++] & 0xFF) << 8
 209:             | (in[i++] & 0xFF) << 16
 210:             | in[i++] << 24;
 211:     int X12 = (in[i++] & 0xFF)
 212:             | (in[i++] & 0xFF) << 8
 213:             | (in[i++] & 0xFF) << 16
 214:             | in[i++] << 24;
 215:     int X13 = (in[i++] & 0xFF)
 216:             | (in[i++] & 0xFF) << 8
 217:             | (in[i++] & 0xFF) << 16
 218:             | in[i++] << 24;
 219:     int X14 = (in[i++] & 0xFF)
 220:             | (in[i++] & 0xFF) << 8
 221:             | (in[i++] & 0xFF) << 16
 222:             | in[i++] << 24;
 223:     int X15 = (in[i++] & 0xFF)
 224:             | (in[i++] & 0xFF) << 8
 225:             | (in[i++] & 0xFF) << 16
 226:             | in[i] << 24;
 227:     int aa, bb, cc, dd;
 228:     aa = a;
 229:     bb = b;
 230:     cc = c;
 231:     dd = d;
 232: 
 233:     aa += ((bb & cc) | ((~bb) & dd)) + X0;
 234:     aa = aa << 3 | aa >>> -3;
 235:     dd += ((aa & bb) | ((~aa) & cc)) + X1;
 236:     dd = dd << 7 | dd >>> -7;
 237:     cc += ((dd & aa) | ((~dd) & bb)) + X2;
 238:     cc = cc << 11 | cc >>> -11;
 239:     bb += ((cc & dd) | ((~cc) & aa)) + X3;
 240:     bb = bb << 19 | bb >>> -19;
 241:     aa += ((bb & cc) | ((~bb) & dd)) + X4;
 242:     aa = aa << 3 | aa >>> -3;
 243:     dd += ((aa & bb) | ((~aa) & cc)) + X5;
 244:     dd = dd << 7 | dd >>> -7;
 245:     cc += ((dd & aa) | ((~dd) & bb)) + X6;
 246:     cc = cc << 11 | cc >>> -11;
 247:     bb += ((cc & dd) | ((~cc) & aa)) + X7;
 248:     bb = bb << 19 | bb >>> -19;
 249:     aa += ((bb & cc) | ((~bb) & dd)) + X8;
 250:     aa = aa << 3 | aa >>> -3;
 251:     dd += ((aa & bb) | ((~aa) & cc)) + X9;
 252:     dd = dd << 7 | dd >>> -7;
 253:     cc += ((dd & aa) | ((~dd) & bb)) + X10;
 254:     cc = cc << 11 | cc >>> -11;
 255:     bb += ((cc & dd) | ((~cc) & aa)) + X11;
 256:     bb = bb << 19 | bb >>> -19;
 257:     aa += ((bb & cc) | ((~bb) & dd)) + X12;
 258:     aa = aa << 3 | aa >>> -3;
 259:     dd += ((aa & bb) | ((~aa) & cc)) + X13;
 260:     dd = dd << 7 | dd >>> -7;
 261:     cc += ((dd & aa) | ((~dd) & bb)) + X14;
 262:     cc = cc << 11 | cc >>> -11;
 263:     bb += ((cc & dd) | ((~cc) & aa)) + X15;
 264:     bb = bb << 19 | bb >>> -19;
 265: 
 266:     aa += ((bb & (cc | dd)) | (cc & dd)) + X0 + 0x5a827999;
 267:     aa = aa << 3 | aa >>> -3;
 268:     dd += ((aa & (bb | cc)) | (bb & cc)) + X4 + 0x5a827999;
 269:     dd = dd << 5 | dd >>> -5;
 270:     cc += ((dd & (aa | bb)) | (aa & bb)) + X8 + 0x5a827999;
 271:     cc = cc << 9 | cc >>> -9;
 272:     bb += ((cc & (dd | aa)) | (dd & aa)) + X12 + 0x5a827999;
 273:     bb = bb << 13 | bb >>> -13;
 274:     aa += ((bb & (cc | dd)) | (cc & dd)) + X1 + 0x5a827999;
 275:     aa = aa << 3 | aa >>> -3;
 276:     dd += ((aa & (bb | cc)) | (bb & cc)) + X5 + 0x5a827999;
 277:     dd = dd << 5 | dd >>> -5;
 278:     cc += ((dd & (aa | bb)) | (aa & bb)) + X9 + 0x5a827999;
 279:     cc = cc << 9 | cc >>> -9;
 280:     bb += ((cc & (dd | aa)) | (dd & aa)) + X13 + 0x5a827999;
 281:     bb = bb << 13 | bb >>> -13;
 282:     aa += ((bb & (cc | dd)) | (cc & dd)) + X2 + 0x5a827999;
 283:     aa = aa << 3 | aa >>> -3;
 284:     dd += ((aa & (bb | cc)) | (bb & cc)) + X6 + 0x5a827999;
 285:     dd = dd << 5 | dd >>> -5;
 286:     cc += ((dd & (aa | bb)) | (aa & bb)) + X10 + 0x5a827999;
 287:     cc = cc << 9 | cc >>> -9;
 288:     bb += ((cc & (dd | aa)) | (dd & aa)) + X14 + 0x5a827999;
 289:     bb = bb << 13 | bb >>> -13;
 290:     aa += ((bb & (cc | dd)) | (cc & dd)) + X3 + 0x5a827999;
 291:     aa = aa << 3 | aa >>> -3;
 292:     dd += ((aa & (bb | cc)) | (bb & cc)) + X7 + 0x5a827999;
 293:     dd = dd << 5 | dd >>> -5;
 294:     cc += ((dd & (aa | bb)) | (aa & bb)) + X11 + 0x5a827999;
 295:     cc = cc << 9 | cc >>> -9;
 296:     bb += ((cc & (dd | aa)) | (dd & aa)) + X15 + 0x5a827999;
 297:     bb = bb << 13 | bb >>> -13;
 298: 
 299:     aa += (bb ^ cc ^ dd) + X0 + 0x6ed9eba1;
 300:     aa = aa << 3 | aa >>> -3;
 301:     dd += (aa ^ bb ^ cc) + X8 + 0x6ed9eba1;
 302:     dd = dd << 9 | dd >>> -9;
 303:     cc += (dd ^ aa ^ bb) + X4 + 0x6ed9eba1;
 304:     cc = cc << 11 | cc >>> -11;
 305:     bb += (cc ^ dd ^ aa) + X12 + 0x6ed9eba1;
 306:     bb = bb << 15 | bb >>> -15;
 307:     aa += (bb ^ cc ^ dd) + X2 + 0x6ed9eba1;
 308:     aa = aa << 3 | aa >>> -3;
 309:     dd += (aa ^ bb ^ cc) + X10 + 0x6ed9eba1;
 310:     dd = dd << 9 | dd >>> -9;
 311:     cc += (dd ^ aa ^ bb) + X6 + 0x6ed9eba1;
 312:     cc = cc << 11 | cc >>> -11;
 313:     bb += (cc ^ dd ^ aa) + X14 + 0x6ed9eba1;
 314:     bb = bb << 15 | bb >>> -15;
 315:     aa += (bb ^ cc ^ dd) + X1 + 0x6ed9eba1;
 316:     aa = aa << 3 | aa >>> -3;
 317:     dd += (aa ^ bb ^ cc) + X9 + 0x6ed9eba1;
 318:     dd = dd << 9 | dd >>> -9;
 319:     cc += (dd ^ aa ^ bb) + X5 + 0x6ed9eba1;
 320:     cc = cc << 11 | cc >>> -11;
 321:     bb += (cc ^ dd ^ aa) + X13 + 0x6ed9eba1;
 322:     bb = bb << 15 | bb >>> -15;
 323:     aa += (bb ^ cc ^ dd) + X3 + 0x6ed9eba1;
 324:     aa = aa << 3 | aa >>> -3;
 325:     dd += (aa ^ bb ^ cc) + X11 + 0x6ed9eba1;
 326:     dd = dd << 9 | dd >>> -9;
 327:     cc += (dd ^ aa ^ bb) + X7 + 0x6ed9eba1;
 328:     cc = cc << 11 | cc >>> -11;
 329:     bb += (cc ^ dd ^ aa) + X15 + 0x6ed9eba1;
 330:     bb = bb << 15 | bb >>> -15;
 331: 
 332:     a += aa;
 333:     b += bb;
 334:     c += cc;
 335:     d += dd;
 336:   }
 337: }