1 package org.bouncycastle.crypto.digests;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import org.bouncycastle.crypto.Digest;
26
27
28
29
30
31 public abstract class GeneralDigest
32 implements Digest {
33 private byte[] xBuf;
34 private int xBufOff;
35
36 private long byteCount;
37
38
39
40
41 protected GeneralDigest() {
42 xBuf = new byte[4];
43 xBufOff = 0;
44 }
45
46
47
48
49
50
51 protected GeneralDigest(GeneralDigest t) {
52 xBuf = new byte[t.xBuf.length];
53 System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
54
55 xBufOff = t.xBufOff;
56 byteCount = t.byteCount;
57 }
58
59 public void update(
60 byte in) {
61 xBuf[xBufOff++] = in;
62
63 if (xBufOff == xBuf.length) {
64 processWord(xBuf, 0);
65 xBufOff = 0;
66 }
67
68 byteCount++;
69 }
70
71 public void update(
72 byte[] in,
73 int inOff,
74 int len) {
75
76
77
78 while ((xBufOff != 0) && (len > 0)) {
79 update(in[inOff]);
80
81 inOff++;
82 len--;
83 }
84
85
86
87
88 while (len > xBuf.length) {
89 processWord(in, inOff);
90
91 inOff += xBuf.length;
92 len -= xBuf.length;
93 byteCount += xBuf.length;
94 }
95
96
97
98
99 while (len > 0) {
100 update(in[inOff]);
101
102 inOff++;
103 len--;
104 }
105 }
106
107 public void finish() {
108 long bitLength = (byteCount << 3);
109
110
111
112
113 update((byte) 128);
114
115 while (xBufOff != 0) {
116 update((byte) 0);
117 }
118
119 processLength(bitLength);
120
121 processBlock();
122 }
123
124 public void reset() {
125 byteCount = 0;
126
127 xBufOff = 0;
128 for (int i = 0; i < xBuf.length; i++) {
129 xBuf[i] = 0;
130 }
131 }
132
133 protected abstract void processWord(byte[] in, int inOff);
134
135 protected abstract void processLength(long bitLength);
136
137 protected abstract void processBlock();
138 }