FileDocCategorySizeDatePackage
LongDigest.javaAPI DocAndroid 1.5 API9503Wed May 06 22:41:06 BST 2009org.bouncycastle.crypto.digests

LongDigest

public abstract class LongDigest extends Object implements org.bouncycastle.crypto.ExtendedDigest
Base class for SHA-384 and SHA-512.

Fields Summary
private static final int
BYTE_LENGTH
private byte[]
xBuf
private int
xBufOff
private long
byteCount1
private long
byteCount2
protected long
H1
protected long
H2
protected long
H3
protected long
H4
protected long
H5
protected long
H6
protected long
H7
protected long
H8
private long[]
W
private int
wOff
static final long[]
K
Constructors Summary
protected LongDigest()
Constructor for variable length word


              
     
    
        xBuf = new byte[8];
        xBufOff = 0;

        reset();
    
protected LongDigest(LongDigest t)
Copy constructor. We are using copy constructors in place of the Object.clone() interface as this interface is not supported by J2ME.

        xBuf = new byte[t.xBuf.length];
        System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);

        xBufOff = t.xBufOff;
        byteCount1 = t.byteCount1;
        byteCount2 = t.byteCount2;

        H1 = t.H1;
        H2 = t.H2;
        H3 = t.H3;
        H4 = t.H4;
        H5 = t.H5;
        H6 = t.H6;
        H7 = t.H7;
        H8 = t.H8;

        System.arraycopy(t.W, 0, W, 0, t.W.length);
        wOff = t.wOff;
    
Methods Summary
private longCh(long x, long y, long z)

        return ((x & y) ^ ((~x) & z));
    
private longMaj(long x, long y, long z)

        return ((x & y) ^ (x & z) ^ (y & z));
    
private longSigma0(long x)

        return ((x << 63)|(x >>> 1)) ^ ((x << 56)|(x >>> 8)) ^ (x >>> 7);
    
private longSigma1(long x)

        return ((x << 45)|(x >>> 19)) ^ ((x << 3)|(x >>> 61)) ^ (x >>> 6);
    
private longSum0(long x)

        return ((x << 36)|(x >>> 28)) ^ ((x << 30)|(x >>> 34)) ^ ((x << 25)|(x >>> 39));
    
private longSum1(long x)

        return ((x << 50)|(x >>> 14)) ^ ((x << 46)|(x >>> 18)) ^ ((x << 23)|(x >>> 41));
    
private voidadjustByteCounts()
adjust the byte counts so that byteCount2 represents the upper long (less 3 bits) word of the byte count.

        if (byteCount1 > 0x1fffffffffffffffL)
        {
            byteCount2 += (byteCount1 >>> 61);
            byteCount1 &= 0x1fffffffffffffffL;
        }
    
public voidfinish()

        adjustByteCounts();

        long    lowBitLength = byteCount1 << 3;
        long    hiBitLength = byteCount2;

        //
        // add the pad bytes.
        //
        update((byte)128);

        while (xBufOff != 0)
        {
            update((byte)0);
        }

        processLength(lowBitLength, hiBitLength);

        processBlock();
    
public intgetByteLength()

        return BYTE_LENGTH;
    
protected voidprocessBlock()

        adjustByteCounts();

        //
        // expand 16 word block into 80 word blocks.
        //
        for (int t = 16; t <= 79; t++)
        {
            W[t] = Sigma1(W[t - 2]) + W[t - 7] + Sigma0(W[t - 15]) + W[t - 16];
        }

        //
        // set up working variables.
        //
        long     a = H1;
        long     b = H2;
        long     c = H3;
        long     d = H4;
        long     e = H5;
        long     f = H6;
        long     g = H7;
        long     h = H8;

        int t = 0;     
        for(int i = 0; i < 10; i ++)
        {
          // t = 8 * i
          h += Sum1(e) + Ch(e, f, g) + K[t] + W[t++];
          d += h;
          h += Sum0(a) + Maj(a, b, c);

          // t = 8 * i + 1
          g += Sum1(d) + Ch(d, e, f) + K[t] + W[t++];
          c += g;
          g += Sum0(h) + Maj(h, a, b);

          // t = 8 * i + 2
          f += Sum1(c) + Ch(c, d, e) + K[t] + W[t++];
          b += f;
          f += Sum0(g) + Maj(g, h, a);

          // t = 8 * i + 3
          e += Sum1(b) + Ch(b, c, d) + K[t] + W[t++];
          a += e;
          e += Sum0(f) + Maj(f, g, h);

          // t = 8 * i + 4
          d += Sum1(a) + Ch(a, b, c) + K[t] + W[t++];
          h += d;
          d += Sum0(e) + Maj(e, f, g);

          // t = 8 * i + 5
          c += Sum1(h) + Ch(h, a, b) + K[t] + W[t++];
          g += c;
          c += Sum0(d) + Maj(d, e, f);

          // t = 8 * i + 6
          b += Sum1(g) + Ch(g, h, a) + K[t] + W[t++];
          f += b;
          b += Sum0(c) + Maj(c, d, e);

          // t = 8 * i + 7
          a += Sum1(f) + Ch(f, g, h) + K[t] + W[t++];
          e += a;
          a += Sum0(b) + Maj(b, c, d);
        }
 
        H1 += a;
        H2 += b;
        H3 += c;
        H4 += d;
        H5 += e;
        H6 += f;
        H7 += g;
        H8 += h;

        //
        // reset the offset and clean out the word buffer.
        //
        wOff = 0;
        for (int i = 0; i < 16; i++)
        {
            W[i] = 0;
        }
    
protected voidprocessLength(long lowW, long hiW)

        if (wOff > 14)
        {
            processBlock();
        }

        W[14] = hiW;
        W[15] = lowW;
    
protected voidprocessWord(byte[] in, int inOff)

        W[wOff++] = ((long)(in[inOff] & 0xff) << 56)
                    | ((long)(in[inOff + 1] & 0xff) << 48)
                    | ((long)(in[inOff + 2] & 0xff) << 40)
                    | ((long)(in[inOff + 3] & 0xff) << 32)
                    | ((long)(in[inOff + 4] & 0xff) << 24)
                    | ((long)(in[inOff + 5] & 0xff) << 16)
                    | ((long)(in[inOff + 6] & 0xff) << 8)
                    | ((in[inOff + 7] & 0xff)); 

        if (wOff == 16)
        {
            processBlock();
        }
    
public voidreset()

        byteCount1 = 0;
        byteCount2 = 0;

        xBufOff = 0;
        for (int i = 0; i < xBuf.length; i++)
        {
            xBuf[i] = 0;
        }

        wOff = 0;
        for (int i = 0; i != W.length; i++)
        {
            W[i] = 0;
        }
    
protected voidunpackWord(long word, byte[] out, int outOff)

        out[outOff]     = (byte)(word >>> 56);
        out[outOff + 1] = (byte)(word >>> 48);
        out[outOff + 2] = (byte)(word >>> 40);
        out[outOff + 3] = (byte)(word >>> 32);
        out[outOff + 4] = (byte)(word >>> 24);
        out[outOff + 5] = (byte)(word >>> 16);
        out[outOff + 6] = (byte)(word >>> 8);
        out[outOff + 7] = (byte)word;
    
public voidupdate(byte in)

        xBuf[xBufOff++] = in;

        if (xBufOff == xBuf.length)
        {
            processWord(xBuf, 0);
            xBufOff = 0;
        }

        byteCount1++;
    
public voidupdate(byte[] in, int inOff, int len)

        //
        // fill the current word
        //
        while ((xBufOff != 0) && (len > 0))
        {
            update(in[inOff]);

            inOff++;
            len--;
        }

        //
        // process whole words.
        //
        while (len > xBuf.length)
        {
            processWord(in, inOff);

            inOff += xBuf.length;
            len -= xBuf.length;
            byteCount1 += xBuf.length;
        }

        //
        // load in the remainder.
        //
        while (len > 0)
        {
            update(in[inOff]);

            inOff++;
            len--;
        }