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