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