1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.crypto.digests; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 4a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstromimport org.bouncycastle.util.Memoable; 5a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347. 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class MD5Digest 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam extends GeneralDigest 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int DIGEST_LENGTH = 16; 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int H1, H2, H3, H4; // IV's 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int[] X = new int[16]; 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int xOff; 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Standard constructor 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public MD5Digest() 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam reset(); 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Copy constructor. This will copy the state of the provided 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * message digest. 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public MD5Digest(MD5Digest t) 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam super(t); 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 35a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom copyIn(t); 36a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom } 37a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom 38a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom private void copyIn(MD5Digest t) 39a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom { 40a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom super.copyIn(t); 41a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H1 = t.H1; 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H2 = t.H2; 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H3 = t.H3; 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H4 = t.H4; 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.arraycopy(t.X, 0, X, 0, t.X.length); 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xOff = t.xOff; 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String getAlgorithmName() 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return "MD5"; 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int getDigestSize() 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return DIGEST_LENGTH; 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void processWord( 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] in, 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inOff) 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (xOff == 16) 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam processBlock(); 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void processLength( 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam long bitLength) 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (xOff > 14) 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam processBlock(); 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X[14] = (int)(bitLength & 0xffffffff); 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X[15] = (int)(bitLength >>> 32); 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private void unpackWord( 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int word, 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] out, 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int outOff) 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam out[outOff] = (byte)word; 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam out[outOff + 1] = (byte)(word >>> 8); 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam out[outOff + 2] = (byte)(word >>> 16); 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam out[outOff + 3] = (byte)(word >>> 24); 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int doFinal( 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] out, 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int outOff) 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam finish(); 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam unpackWord(H1, out, outOff); 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam unpackWord(H2, out, outOff + 4); 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam unpackWord(H3, out, outOff + 8); 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam unpackWord(H4, out, outOff + 12); 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam reset(); 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return DIGEST_LENGTH; 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * reset the chaining variables to the IV values. 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void reset() 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam super.reset(); 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H1 = 0x67452301; 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H2 = 0xefcdab89; 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H3 = 0x98badcfe; 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H4 = 0x10325476; 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xOff = 0; 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != X.length; i++) 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X[i] = 0; 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // round 1 left rotates 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S11 = 7; 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S12 = 12; 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S13 = 17; 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S14 = 22; 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // round 2 left rotates 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S21 = 5; 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S22 = 9; 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S23 = 14; 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S24 = 20; 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // round 3 left rotates 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S31 = 4; 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S32 = 11; 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S33 = 16; 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S34 = 23; 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // round 4 left rotates 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S41 = 6; 161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S42 = 10; 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S43 = 15; 163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int S44 = 21; 164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /* 166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * rotate int x left n bits. 167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int rotateLeft( 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int x, 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int n) 171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (x << n) | (x >>> (32 - n)); 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /* 176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * F, G, H and I are the basic MD5 functions. 177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int F( 179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int u, 180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int v, 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int w) 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (u & v) | (~u & w); 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int G( 187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int u, 188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int v, 189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int w) 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (u & w) | (v & ~w); 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int H( 195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int u, 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int v, 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int w) 198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return u ^ v ^ w; 200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int K( 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int u, 204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int v, 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int w) 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return v ^ (u | ~w); 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected void processBlock() 211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int a = H1; 213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int b = H2; 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int c = H3; 215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int d = H4; 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // Round 1 - F cycle, 16 times. 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + F(b, c, d) + X[ 0] + 0xd76aa478, S11) + b; 221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + F(a, b, c) + X[ 1] + 0xe8c7b756, S12) + a; 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + F(d, a, b) + X[ 2] + 0x242070db, S13) + d; 223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + F(c, d, a) + X[ 3] + 0xc1bdceee, S14) + c; 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + F(b, c, d) + X[ 4] + 0xf57c0faf, S11) + b; 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + F(a, b, c) + X[ 5] + 0x4787c62a, S12) + a; 226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + F(d, a, b) + X[ 6] + 0xa8304613, S13) + d; 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + F(c, d, a) + X[ 7] + 0xfd469501, S14) + c; 228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + F(b, c, d) + X[ 8] + 0x698098d8, S11) + b; 229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + F(a, b, c) + X[ 9] + 0x8b44f7af, S12) + a; 230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + F(d, a, b) + X[10] + 0xffff5bb1, S13) + d; 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + F(c, d, a) + X[11] + 0x895cd7be, S14) + c; 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + F(b, c, d) + X[12] + 0x6b901122, S11) + b; 233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + F(a, b, c) + X[13] + 0xfd987193, S12) + a; 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + F(d, a, b) + X[14] + 0xa679438e, S13) + d; 235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + F(c, d, a) + X[15] + 0x49b40821, S14) + c; 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // Round 2 - G cycle, 16 times. 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + G(b, c, d) + X[ 1] + 0xf61e2562, S21) + b; 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + G(a, b, c) + X[ 6] + 0xc040b340, S22) + a; 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + G(d, a, b) + X[11] + 0x265e5a51, S23) + d; 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + G(c, d, a) + X[ 0] + 0xe9b6c7aa, S24) + c; 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + G(b, c, d) + X[ 5] + 0xd62f105d, S21) + b; 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + G(a, b, c) + X[10] + 0x02441453, S22) + a; 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + G(d, a, b) + X[15] + 0xd8a1e681, S23) + d; 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + G(c, d, a) + X[ 4] + 0xe7d3fbc8, S24) + c; 248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + G(b, c, d) + X[ 9] + 0x21e1cde6, S21) + b; 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + G(a, b, c) + X[14] + 0xc33707d6, S22) + a; 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + G(d, a, b) + X[ 3] + 0xf4d50d87, S23) + d; 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + G(c, d, a) + X[ 8] + 0x455a14ed, S24) + c; 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + G(b, c, d) + X[13] + 0xa9e3e905, S21) + b; 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + G(a, b, c) + X[ 2] + 0xfcefa3f8, S22) + a; 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + G(d, a, b) + X[ 7] + 0x676f02d9, S23) + d; 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + G(c, d, a) + X[12] + 0x8d2a4c8a, S24) + c; 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // Round 3 - H cycle, 16 times. 259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + H(b, c, d) + X[ 5] + 0xfffa3942, S31) + b; 261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + H(a, b, c) + X[ 8] + 0x8771f681, S32) + a; 262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + H(d, a, b) + X[11] + 0x6d9d6122, S33) + d; 263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + H(c, d, a) + X[14] + 0xfde5380c, S34) + c; 264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + H(b, c, d) + X[ 1] + 0xa4beea44, S31) + b; 265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + H(a, b, c) + X[ 4] + 0x4bdecfa9, S32) + a; 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + H(d, a, b) + X[ 7] + 0xf6bb4b60, S33) + d; 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + H(c, d, a) + X[10] + 0xbebfbc70, S34) + c; 268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + H(b, c, d) + X[13] + 0x289b7ec6, S31) + b; 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + H(a, b, c) + X[ 0] + 0xeaa127fa, S32) + a; 270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + H(d, a, b) + X[ 3] + 0xd4ef3085, S33) + d; 271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + H(c, d, a) + X[ 6] + 0x04881d05, S34) + c; 272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + H(b, c, d) + X[ 9] + 0xd9d4d039, S31) + b; 273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + H(a, b, c) + X[12] + 0xe6db99e5, S32) + a; 274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + H(d, a, b) + X[15] + 0x1fa27cf8, S33) + d; 275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + H(c, d, a) + X[ 2] + 0xc4ac5665, S34) + c; 276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // Round 4 - K cycle, 16 times. 279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + K(b, c, d) + X[ 0] + 0xf4292244, S41) + b; 281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + K(a, b, c) + X[ 7] + 0x432aff97, S42) + a; 282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + K(d, a, b) + X[14] + 0xab9423a7, S43) + d; 283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + K(c, d, a) + X[ 5] + 0xfc93a039, S44) + c; 284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + K(b, c, d) + X[12] + 0x655b59c3, S41) + b; 285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + K(a, b, c) + X[ 3] + 0x8f0ccc92, S42) + a; 286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + K(d, a, b) + X[10] + 0xffeff47d, S43) + d; 287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + K(c, d, a) + X[ 1] + 0x85845dd1, S44) + c; 288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + K(b, c, d) + X[ 8] + 0x6fa87e4f, S41) + b; 289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + K(a, b, c) + X[15] + 0xfe2ce6e0, S42) + a; 290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + K(d, a, b) + X[ 6] + 0xa3014314, S43) + d; 291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + K(c, d, a) + X[13] + 0x4e0811a1, S44) + c; 292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam a = rotateLeft(a + K(b, c, d) + X[ 4] + 0xf7537e82, S41) + b; 293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam d = rotateLeft(d + K(a, b, c) + X[11] + 0xbd3af235, S42) + a; 294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = rotateLeft(c + K(d, a, b) + X[ 2] + 0x2ad7d2bb, S43) + d; 295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam b = rotateLeft(b + K(c, d, a) + X[ 9] + 0xeb86d391, S44) + c; 296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H1 += a; 298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H2 += b; 299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H3 += c; 300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam H4 += d; 301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // reset the offset and clean out the word buffer. 304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xOff = 0; 306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != X.length; i++) 307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X[i] = 0; 309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 311a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom 312a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom public Memoable copy() 313a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom { 314a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom return new MD5Digest(this); 315a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom } 316a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom 317a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom public void reset(Memoable other) 318a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom { 319a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom MD5Digest d = (MD5Digest)other; 320a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom 321a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom copyIn(d); 322a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom } 323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 324