Home | History | Annotate | Download | only in digest
      1 /*
      2  * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
      3  * Please refer to the LICENSE.txt for licensing details.
      4  */
      5 package ch.ethz.ssh2.crypto.digest;
      6 
      7 /**
      8  * MD5. Based on the example code in RFC 1321. Optimized (...a little).
      9  *
     10  * @author Christian Plattner
     11  * @version 2.50, 03/15/10
     12  */
     13 
     14 /*
     15  * The following disclaimer has been copied from RFC 1321:
     16  *
     17  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights
     18  * reserved.
     19  *
     20  * License to copy and use this software is granted provided that it is
     21  * identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in
     22  * all material mentioning or referencing this software or this function.
     23  *
     24  * License is also granted to make and use derivative works provided that such
     25  * works are identified as "derived from the RSA Data Security, Inc. MD5
     26  * Message-Digest Algorithm" in all material mentioning or referencing the
     27  * derived work.
     28  *
     29  * RSA Data Security, Inc. makes no representations concerning either the
     30  * merchantability of this software or the suitability of this software for any
     31  * particular purpose. It is provided "as is" without express or implied
     32  * warranty of any kind.
     33  *
     34  * These notices must be retained in any copies of any part of this
     35  * documentation and/or software.
     36  *
     37  */
     38 
     39 public final class MD5 implements Digest
     40 {
     41 	private int state0, state1, state2, state3;
     42 	private long count;
     43 	private final byte[] block = new byte[64];
     44 	private final int x[] = new int[16];
     45 
     46 	private static final byte[] padding = new byte[] { (byte) 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     47 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     48 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
     49 
     50 	public MD5()
     51 	{
     52 		reset();
     53 	}
     54 
     55 	private static int FF(int a, int b, int c, int d, int x, int s, int ac)
     56 	{
     57 		a += ((b & c) | ((~b) & d)) + x + ac;
     58 		return ((a << s) | (a >>> (32 - s))) + b;
     59 	}
     60 
     61 	private static int GG(int a, int b, int c, int d, int x, int s, int ac)
     62 	{
     63 		a += ((b & d) | (c & (~d))) + x + ac;
     64 		return ((a << s) | (a >>> (32 - s))) + b;
     65 	}
     66 
     67 	private static int HH(int a, int b, int c, int d, int x, int s, int ac)
     68 	{
     69 		a += (b ^ c ^ d) + x + ac;
     70 		return ((a << s) | (a >>> (32 - s))) + b;
     71 	}
     72 
     73 	private static int II(int a, int b, int c, int d, int x, int s, int ac)
     74 	{
     75 		a += (c ^ (b | (~d))) + x + ac;
     76 		return ((a << s) | (a >>> (32 - s))) + b;
     77 	}
     78 
     79 	private static void encode(byte[] dst, int dstoff, int word)
     80 	{
     81 		dst[dstoff] = (byte) (word);
     82 		dst[dstoff + 1] = (byte) (word >> 8);
     83 		dst[dstoff + 2] = (byte) (word >> 16);
     84 		dst[dstoff + 3] = (byte) (word >> 24);
     85 	}
     86 
     87 	private void transform(byte[] src, int pos)
     88 	{
     89 		int a = state0;
     90 		int b = state1;
     91 		int c = state2;
     92 		int d = state3;
     93 
     94 		for (int i = 0; i < 16; i++, pos += 4)
     95 		{
     96 			x[i] = (src[pos] & 0xff) | ((src[pos + 1] & 0xff) << 8) | ((src[pos + 2] & 0xff) << 16)
     97 					| ((src[pos + 3] & 0xff) << 24);
     98 		}
     99 
    100 		/* Round 1 */
    101 
    102 		a = FF(a, b, c, d, x[0], 7, 0xd76aa478); /* 1 */
    103 		d = FF(d, a, b, c, x[1], 12, 0xe8c7b756); /* 2 */
    104 		c = FF(c, d, a, b, x[2], 17, 0x242070db); /* 3 */
    105 		b = FF(b, c, d, a, x[3], 22, 0xc1bdceee); /* 4 */
    106 		a = FF(a, b, c, d, x[4], 7, 0xf57c0faf); /* 5 */
    107 		d = FF(d, a, b, c, x[5], 12, 0x4787c62a); /* 6 */
    108 		c = FF(c, d, a, b, x[6], 17, 0xa8304613); /* 7 */
    109 		b = FF(b, c, d, a, x[7], 22, 0xfd469501); /* 8 */
    110 		a = FF(a, b, c, d, x[8], 7, 0x698098d8); /* 9 */
    111 		d = FF(d, a, b, c, x[9], 12, 0x8b44f7af); /* 10 */
    112 		c = FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
    113 		b = FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
    114 		a = FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
    115 		d = FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
    116 		c = FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
    117 		b = FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
    118 
    119 		/* Round 2 */
    120 		a = GG(a, b, c, d, x[1], 5, 0xf61e2562); /* 17 */
    121 		d = GG(d, a, b, c, x[6], 9, 0xc040b340); /* 18 */
    122 		c = GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
    123 		b = GG(b, c, d, a, x[0], 20, 0xe9b6c7aa); /* 20 */
    124 		a = GG(a, b, c, d, x[5], 5, 0xd62f105d); /* 21 */
    125 		d = GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */
    126 		c = GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
    127 		b = GG(b, c, d, a, x[4], 20, 0xe7d3fbc8); /* 24 */
    128 		a = GG(a, b, c, d, x[9], 5, 0x21e1cde6); /* 25 */
    129 		d = GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
    130 		c = GG(c, d, a, b, x[3], 14, 0xf4d50d87); /* 27 */
    131 		b = GG(b, c, d, a, x[8], 20, 0x455a14ed); /* 28 */
    132 		a = GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
    133 		d = GG(d, a, b, c, x[2], 9, 0xfcefa3f8); /* 30 */
    134 		c = GG(c, d, a, b, x[7], 14, 0x676f02d9); /* 31 */
    135 		b = GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
    136 
    137 		/* Round 3 */
    138 		a = HH(a, b, c, d, x[5], 4, 0xfffa3942); /* 33 */
    139 		d = HH(d, a, b, c, x[8], 11, 0x8771f681); /* 34 */
    140 		c = HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
    141 		b = HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
    142 		a = HH(a, b, c, d, x[1], 4, 0xa4beea44); /* 37 */
    143 		d = HH(d, a, b, c, x[4], 11, 0x4bdecfa9); /* 38 */
    144 		c = HH(c, d, a, b, x[7], 16, 0xf6bb4b60); /* 39 */
    145 		b = HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
    146 		a = HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
    147 		d = HH(d, a, b, c, x[0], 11, 0xeaa127fa); /* 42 */
    148 		c = HH(c, d, a, b, x[3], 16, 0xd4ef3085); /* 43 */
    149 		b = HH(b, c, d, a, x[6], 23, 0x4881d05); /* 44 */
    150 		a = HH(a, b, c, d, x[9], 4, 0xd9d4d039); /* 45 */
    151 		d = HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
    152 		c = HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
    153 		b = HH(b, c, d, a, x[2], 23, 0xc4ac5665); /* 48 */
    154 
    155 		/* Round 4 */
    156 		a = II(a, b, c, d, x[0], 6, 0xf4292244); /* 49 */
    157 		d = II(d, a, b, c, x[7], 10, 0x432aff97); /* 50 */
    158 		c = II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
    159 		b = II(b, c, d, a, x[5], 21, 0xfc93a039); /* 52 */
    160 		a = II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
    161 		d = II(d, a, b, c, x[3], 10, 0x8f0ccc92); /* 54 */
    162 		c = II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
    163 		b = II(b, c, d, a, x[1], 21, 0x85845dd1); /* 56 */
    164 		a = II(a, b, c, d, x[8], 6, 0x6fa87e4f); /* 57 */
    165 		d = II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
    166 		c = II(c, d, a, b, x[6], 15, 0xa3014314); /* 59 */
    167 		b = II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
    168 		a = II(a, b, c, d, x[4], 6, 0xf7537e82); /* 61 */
    169 		d = II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
    170 		c = II(c, d, a, b, x[2], 15, 0x2ad7d2bb); /* 63 */
    171 		b = II(b, c, d, a, x[9], 21, 0xeb86d391); /* 64 */
    172 
    173 		state0 += a;
    174 		state1 += b;
    175 		state2 += c;
    176 		state3 += d;
    177 	}
    178 
    179 	public final void reset()
    180 	{
    181 		count = 0;
    182 
    183 		state0 = 0x67452301;
    184 		state1 = 0xefcdab89;
    185 		state2 = 0x98badcfe;
    186 		state3 = 0x10325476;
    187 
    188 		/* Clear traces in memory... */
    189 
    190 		for (int i = 0; i < 16; i++)
    191 			x[i] = 0;
    192 	}
    193 
    194 	public final void update(byte b)
    195 	{
    196 		final int space = 64 - ((int) (count & 0x3f));
    197 
    198 		count++;
    199 
    200 		block[64 - space] = b;
    201 
    202 		if (space == 1)
    203 			transform(block, 0);
    204 	}
    205 
    206 	public final void update(byte[] buff, int pos, int len)
    207 	{
    208 		int space = 64 - ((int) (count & 0x3f));
    209 
    210 		count += len;
    211 
    212 		while (len > 0)
    213 		{
    214 			if (len < space)
    215 			{
    216 				System.arraycopy(buff, pos, block, 64 - space, len);
    217 				break;
    218 			}
    219 
    220 			if (space == 64)
    221 			{
    222 				transform(buff, pos);
    223 			}
    224 			else
    225 			{
    226 				System.arraycopy(buff, pos, block, 64 - space, space);
    227 				transform(block, 0);
    228 			}
    229 
    230 			pos += space;
    231 			len -= space;
    232 			space = 64;
    233 		}
    234 	}
    235 
    236 	public final void update(byte[] b)
    237 	{
    238 		update(b, 0, b.length);
    239 	}
    240 
    241 	public final void digest(byte[] dst, int pos)
    242 	{
    243 		byte[] bits = new byte[8];
    244 
    245 		encode(bits, 0, (int) (count << 3));
    246 		encode(bits, 4, (int) (count >> 29));
    247 
    248 		int idx = (int) count & 0x3f;
    249 		int padLen = (idx < 56) ? (56 - idx) : (120 - idx);
    250 
    251 		update(padding, 0, padLen);
    252 		update(bits, 0, 8);
    253 
    254 		encode(dst, pos, state0);
    255 		encode(dst, pos + 4, state1);
    256 		encode(dst, pos + 8, state2);
    257 		encode(dst, pos + 12, state3);
    258 
    259 		reset();
    260 	}
    261 
    262 	public final void digest(byte[] dst)
    263 	{
    264 		digest(dst, 0);
    265 	}
    266 
    267 	public final int getDigestLength()
    268 	{
    269 		return 16;
    270 	}
    271 }
    272