1 package org.bouncycastle.crypto.digests;
2
3 /*-
4 * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5 * SNMP Java Client
6 * ჻჻჻჻჻჻
7 * Copyright 2023 MetricsHub, Westhawk
8 * ჻჻჻჻჻჻
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation, either version 3 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Lesser Public License for more details.
18 *
19 * You should have received a copy of the GNU General Lesser Public
20 * License along with this program. If not, see
21 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22 * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
23 */
24
25 import org.bouncycastle.crypto.Digest;
26
27 /**
28 * base implementation of MD4 family style digest as outlined in
29 * "Handbook of Applied Cryptography", pages 344 - 347.
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 * Standard constructor
40 */
41 protected GeneralDigest() {
42 xBuf = new byte[4];
43 xBufOff = 0;
44 }
45
46 /**
47 * Copy constructor. We are using copy constructors in place
48 * of the Object.clone() interface as this interface is not
49 * supported by J2ME.
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 // fill the current word
77 //
78 while ((xBufOff != 0) && (len > 0)) {
79 update(in[inOff]);
80
81 inOff++;
82 len--;
83 }
84
85 //
86 // process whole words.
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 // load in the remainder.
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 // add the pad bytes.
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 }