Home | History | Annotate | Download | only in digests
      1 package org.bouncycastle.crypto.digests;
      2 
      3 import org.bouncycastle.crypto.ExtendedDigest;
      4 
      5 /**
      6  * base implementation of MD4 family style digest as outlined in
      7  * "Handbook of Applied Cryptography", pages 344 - 347.
      8  */
      9 public abstract class GeneralDigest
     10     implements ExtendedDigest
     11 {
     12     private static final int BYTE_LENGTH = 64;
     13     private byte[]  xBuf;
     14     private int     xBufOff;
     15 
     16     private long    byteCount;
     17 
     18     /**
     19      * Standard constructor
     20      */
     21     protected GeneralDigest()
     22     {
     23         xBuf = new byte[4];
     24         xBufOff = 0;
     25     }
     26 
     27     /**
     28      * Copy constructor.  We are using copy constructors in place
     29      * of the Object.clone() interface as this interface is not
     30      * supported by J2ME.
     31      */
     32     protected GeneralDigest(GeneralDigest t)
     33     {
     34         xBuf = new byte[t.xBuf.length];
     35         System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
     36 
     37         xBufOff = t.xBufOff;
     38         byteCount = t.byteCount;
     39     }
     40 
     41     public void update(
     42         byte in)
     43     {
     44         xBuf[xBufOff++] = in;
     45 
     46         if (xBufOff == xBuf.length)
     47         {
     48             processWord(xBuf, 0);
     49             xBufOff = 0;
     50         }
     51 
     52         byteCount++;
     53     }
     54 
     55     public void update(
     56         byte[]  in,
     57         int     inOff,
     58         int     len)
     59     {
     60         //
     61         // fill the current word
     62         //
     63         while ((xBufOff != 0) && (len > 0))
     64         {
     65             update(in[inOff]);
     66 
     67             inOff++;
     68             len--;
     69         }
     70 
     71         //
     72         // process whole words.
     73         //
     74         while (len > xBuf.length)
     75         {
     76             processWord(in, inOff);
     77 
     78             inOff += xBuf.length;
     79             len -= xBuf.length;
     80             byteCount += xBuf.length;
     81         }
     82 
     83         //
     84         // load in the remainder.
     85         //
     86         while (len > 0)
     87         {
     88             update(in[inOff]);
     89 
     90             inOff++;
     91             len--;
     92         }
     93     }
     94 
     95     public void finish()
     96     {
     97         long    bitLength = (byteCount << 3);
     98 
     99         //
    100         // add the pad bytes.
    101         //
    102         update((byte)128);
    103 
    104         while (xBufOff != 0)
    105         {
    106             update((byte)0);
    107         }
    108 
    109         processLength(bitLength);
    110 
    111         processBlock();
    112     }
    113 
    114     public void reset()
    115     {
    116         byteCount = 0;
    117 
    118         xBufOff = 0;
    119         for (int i = 0; i < xBuf.length; i++)
    120         {
    121             xBuf[i] = 0;
    122         }
    123     }
    124 
    125     public int getByteLength()
    126     {
    127         return BYTE_LENGTH;
    128     }
    129 
    130     protected abstract void processWord(byte[] in, int inOff);
    131 
    132     protected abstract void processLength(long bitLength);
    133 
    134     protected abstract void processBlock();
    135 }
    136