View Javadoc
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 }