001: package org.bouncycastle.crypto.digests;
002:
003: import org.bouncycastle.crypto.ExtendedDigest;
004:
005: /**
006: * base implementation of MD4 family style digest as outlined in
007: * "Handbook of Applied Cryptography", pages 344 - 347.
008: */
009: public abstract class GeneralDigest implements ExtendedDigest {
010: private static final int BYTE_LENGTH = 64;
011: private byte[] xBuf;
012: private int xBufOff;
013:
014: private long byteCount;
015:
016: /**
017: * Standard constructor
018: */
019: protected GeneralDigest() {
020: xBuf = new byte[4];
021: xBufOff = 0;
022: }
023:
024: /**
025: * Copy constructor. We are using copy constructors in place
026: * of the Object.clone() interface as this interface is not
027: * supported by J2ME.
028: */
029: protected GeneralDigest(GeneralDigest t) {
030: xBuf = new byte[t.xBuf.length];
031: System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
032:
033: xBufOff = t.xBufOff;
034: byteCount = t.byteCount;
035: }
036:
037: public void update(byte in) {
038: xBuf[xBufOff++] = in;
039:
040: if (xBufOff == xBuf.length) {
041: processWord(xBuf, 0);
042: xBufOff = 0;
043: }
044:
045: byteCount++;
046: }
047:
048: public void update(byte[] in, int inOff, int len) {
049: //
050: // fill the current word
051: //
052: while ((xBufOff != 0) && (len > 0)) {
053: update(in[inOff]);
054:
055: inOff++;
056: len--;
057: }
058:
059: //
060: // process whole words.
061: //
062: while (len > xBuf.length) {
063: processWord(in, inOff);
064:
065: inOff += xBuf.length;
066: len -= xBuf.length;
067: byteCount += xBuf.length;
068: }
069:
070: //
071: // load in the remainder.
072: //
073: while (len > 0) {
074: update(in[inOff]);
075:
076: inOff++;
077: len--;
078: }
079: }
080:
081: public void finish() {
082: long bitLength = (byteCount << 3);
083:
084: //
085: // add the pad bytes.
086: //
087: update((byte) 128);
088:
089: while (xBufOff != 0) {
090: update((byte) 0);
091: }
092:
093: processLength(bitLength);
094:
095: processBlock();
096: }
097:
098: public void reset() {
099: byteCount = 0;
100:
101: xBufOff = 0;
102: for (int i = 0; i < xBuf.length; i++) {
103: xBuf[i] = 0;
104: }
105: }
106:
107: public int getByteLength() {
108: return BYTE_LENGTH;
109: }
110:
111: protected abstract void processWord(byte[] in, int inOff);
112:
113: protected abstract void processLength(long bitLength);
114:
115: protected abstract void processBlock();
116: }
|