1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.crypto.digests; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.ExtendedDigest; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * base implementation of MD4 family style digest as outlined in 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * "Handbook of Applied Cryptography", pages 344 - 347. 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic abstract class GeneralDigest 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam implements ExtendedDigest 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final int BYTE_LENGTH = 64; 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private byte[] xBuf; 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private int xBufOff; 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private long byteCount; 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Standard constructor 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected GeneralDigest() 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xBuf = new byte[4]; 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xBufOff = 0; 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Copy constructor. We are using copy constructors in place 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * of the Object.clone() interface as this interface is not 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * supported by J2ME. 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected GeneralDigest(GeneralDigest t) 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xBuf = new byte[t.xBuf.length]; 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length); 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xBufOff = t.xBufOff; 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byteCount = t.byteCount; 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void update( 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte in) 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xBuf[xBufOff++] = in; 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (xBufOff == xBuf.length) 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam processWord(xBuf, 0); 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xBufOff = 0; 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byteCount++; 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void update( 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] in, 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int inOff, 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int len) 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // fill the current word 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while ((xBufOff != 0) && (len > 0)) 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam update(in[inOff]); 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam inOff++; 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam len--; 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // process whole words. 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (len > xBuf.length) 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam processWord(in, inOff); 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam inOff += xBuf.length; 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam len -= xBuf.length; 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byteCount += xBuf.length; 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // load in the remainder. 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (len > 0) 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam update(in[inOff]); 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam inOff++; 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam len--; 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void finish() 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam long bitLength = (byteCount << 3); 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // add the pad bytes. 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam update((byte)128); 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (xBufOff != 0) 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam update((byte)0); 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam processLength(bitLength); 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam processBlock(); 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void reset() 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byteCount = 0; 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xBufOff = 0; 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i < xBuf.length; i++) 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam xBuf[i] = 0; 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int getByteLength() 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return BYTE_LENGTH; 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected abstract void processWord(byte[] in, int inOff); 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected abstract void processLength(long bitLength); 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected abstract void processBlock(); 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 136