View Javadoc
1   package org.bouncycastle.crypto.digests;
2   
3   /*-
4    * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5    * SNMP Java Client
6    * ჻჻჻჻჻჻
7    * Copyright 2023 Sentry Software, 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  {
34      private byte[]  xBuf;
35      private int     xBufOff;
36  
37      private long    byteCount;
38  
39      /**
40       * Standard constructor
41       */
42      protected GeneralDigest()
43      {
44          xBuf = new byte[4];
45          xBufOff = 0;
46      }
47  
48      /**
49       * Copy constructor.  We are using copy constructors in place
50       * of the Object.clone() interface as this interface is not
51       * supported by J2ME.
52       */
53      protected GeneralDigest(GeneralDigest t)
54      {
55          xBuf = new byte[t.xBuf.length];
56          System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
57  
58          xBufOff = t.xBufOff;
59          byteCount = t.byteCount;
60      }
61  
62      public void update(
63          byte in)
64      {
65          xBuf[xBufOff++] = in;
66  
67          if (xBufOff == xBuf.length)
68          {
69              processWord(xBuf, 0);
70              xBufOff = 0;
71          }
72  
73          byteCount++;
74      }
75  
76      public void update(
77          byte[]  in,
78          int     inOff,
79          int     len)
80      {
81          //
82          // fill the current word
83          //
84          while ((xBufOff != 0) && (len > 0))
85          {
86              update(in[inOff]);
87  
88              inOff++;
89              len--;
90          }
91  
92          //
93          // process whole words.
94          //
95          while (len > xBuf.length)
96          {
97              processWord(in, inOff);
98  
99              inOff += xBuf.length;
100             len -= xBuf.length;
101             byteCount += xBuf.length;
102         }
103 
104         //
105         // load in the remainder.
106         //
107         while (len > 0)
108         {
109             update(in[inOff]);
110 
111             inOff++;
112             len--;
113         }
114     }
115 
116     public void finish()
117     {
118         long    bitLength = (byteCount << 3);
119 
120         //
121         // add the pad bytes.
122         //
123         update((byte)128);
124 
125         while (xBufOff != 0)
126         {
127             update((byte)0);
128         }
129 
130         processLength(bitLength);
131 
132         processBlock();
133     }
134 
135     public void reset()
136     {
137         byteCount = 0;
138 
139         xBufOff = 0;
140         for ( int i = 0; i < xBuf.length; i++ ) {
141             xBuf[i] = 0;
142         }
143     }
144 
145     protected abstract void processWord(byte[] in, int inOff);
146 
147     protected abstract void processLength(long bitLength);
148 
149     protected abstract void processBlock();
150 }