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