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