1 package org.bouncycastle.crypto.digests;
2
3 import org.bouncycastle.crypto.Digest;
4
5
9 public abstract class GeneralDigest
10 implements Digest
11 {
12 private byte[] xBuf;
13 private int xBufOff;
14
15 private long byteCount;
16
17
20 protected GeneralDigest()
21 {
22 xBuf = new byte[4];
23 xBufOff = 0;
24 }
25
26
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
61
62 while ((xBufOff != 0) && (len > 0))
63 {
64 update(in[inOff]);
65
66 inOff++;
67 len--;
68 }
69
70
71
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
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
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 }
129