FileDocCategorySizeDatePackage
TigerDigest.javaAPI DocAzureus 3.0.3.447623Tue Jun 08 05:12:58 BST 2004org.bouncycastle.crypto.digests

TigerDigest

public class TigerDigest extends Object implements org.bouncycastle.crypto.Digest
implementation of Tiger based on: http://www.cs.technion.ac.il/~biham/Reports/Tiger

Fields Summary
private static final long[]
t1
private static final long[]
t2
private static final long[]
t3
private static final long[]
t4
private static final int
DIGEST_LENGTH
private long
a
private long
b
private long
c
private long
byteCount
private byte[]
buf
private int
bOff
private long[]
x
private int
xOff
Constructors Summary
public TigerDigest()
Standard constructor


	  	 
     
    
        reset();
    
public TigerDigest(TigerDigest t)
Copy constructor. This will copy the state of the provided message digest.

		a = t.a;
		b = t.b;
		c = t.c;

		System.arraycopy(t.x, 0, x, 0, t.x.length);
		xOff = t.xOff;

		System.arraycopy(t.buf, 0, buf, 0, t.buf.length);
		bOff = t.bOff;

        byteCount = t.byteCount;
	
Methods Summary
public intdoFinal(byte[] out, int outOff)

        finish();

        unpackWord(a, out, outOff);
        unpackWord(b, out, outOff + 8);
        unpackWord(c, out, outOff + 16);

        reset();

        return DIGEST_LENGTH;
    
private voidfinish()

        long    bitLength = (byteCount << 3);

        update((byte)0x01);

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

        processLength(bitLength);

        processBlock();
    
public java.lang.StringgetAlgorithmName()

        return "Tiger";
    
public intgetDigestSize()

        return DIGEST_LENGTH;
    
private voidkeySchedule()

        x[0] -= x[7] ^ 0xA5A5A5A5A5A5A5A5L; 
        x[1] ^= x[0]; 
        x[2] += x[1]; 
        x[3] -= x[2] ^ ((~x[1]) << 19); 
        x[4] ^= x[3]; 
        x[5] += x[4]; 
        x[6] -= x[5] ^ ((~x[4]) >>> 23); 
        x[7] ^= x[6]; 
        x[0] += x[7]; 
        x[1] -= x[0] ^ ((~x[7]) << 19); 
        x[2] ^= x[1]; 
        x[3] += x[2]; 
        x[4] -= x[3] ^ ((~x[2]) >>> 23); 
        x[5] ^= x[4]; 
        x[6] += x[5]; 
        x[7] -= x[6] ^ 0x0123456789ABCDEFL;
    
private voidprocessBlock()

        //
        // save abc
        //
        long aa = a;
        long bb = b;
        long cc = c;

        //
        // rounds and schedule
        //
        roundABC(x[0], 5);
        roundBCA(x[1], 5);
        roundCAB(x[2], 5);
        roundABC(x[3], 5);
        roundBCA(x[4], 5);
        roundCAB(x[5], 5);
        roundABC(x[6], 5);
        roundBCA(x[7], 5);

        keySchedule();

        roundCAB(x[0], 7);
        roundABC(x[1], 7);
        roundBCA(x[2], 7);
        roundCAB(x[3], 7);
        roundABC(x[4], 7);
        roundBCA(x[5], 7);
        roundCAB(x[6], 7);
        roundABC(x[7], 7);

        keySchedule();

        roundBCA(x[0], 9);
        roundCAB(x[1], 9);
        roundABC(x[2], 9);
        roundBCA(x[3], 9);
        roundCAB(x[4], 9);
        roundABC(x[5], 9);
        roundBCA(x[6], 9);
        roundCAB(x[7], 9);

        //
        // feed forward
        //
        a ^= aa;
        b -= bb;
        c += cc;

        //
        // clear the x buffer
        //
        xOff = 0;
        for (int i = 0; i != x.length; i++)
        {
            x[i] = 0;
        }
    
private voidprocessLength(long bitLength)

        x[7] = bitLength;
    
private voidprocessWord(byte[] b, int off)

        x[xOff++] = ((long)(b[off + 7] & 0xff) << 56)
             | ((long)(b[off + 6] & 0xff) << 48)
             | ((long)(b[off + 5] & 0xff) << 40)
             | ((long)(b[off + 4] & 0xff) << 32)
             | ((long)(b[off + 3] & 0xff) << 24)
             | ((long)(b[off + 2] & 0xff) << 16)
             | ((long)(b[off + 1] & 0xff) << 8)
             | ((b[off + 0] & 0xff));

        if (xOff == x.length)
        {
            processBlock();
        }

        bOff = 0;
    
public voidreset()
reset the chaining variables

        a = 0x0123456789ABCDEFL;
        b = 0xFEDCBA9876543210L;
        c = 0xF096A5B4C3B2E187L;

        xOff = 0;
        for (int i = 0; i != x.length; i++)
        {
            x[i] = 0;
        }

        bOff = 0;
        for (int i = 0; i != buf.length; i++)
        {
            buf[i] = 0;
        }

        byteCount = 0;
    
private voidroundABC(long x, long mul)

         c ^= x ;
         a -= t1[(int)c & 0xff] ^ t2[(int)(c >> 16) & 0xff]
                ^ t3[(int)(c >> 32) & 0xff] ^ t4[(int)(c >> 48) & 0xff];
         b += t4[(int)(c >> 8) & 0xff] ^ t3[(int)(c >> 24) & 0xff]
                ^ t2[(int)(c >> 40) & 0xff] ^ t1[(int)(c >> 56) & 0xff];
         b *= mul;
    
private voidroundBCA(long x, long mul)

         a ^= x ;
         b -= t1[(int)a & 0xff] ^ t2[(int)(a >> 16) & 0xff]
                ^ t3[(int)(a >> 32) & 0xff] ^ t4[(int)(a >> 48) & 0xff];
         c += t4[(int)(a >> 8) & 0xff] ^ t3[(int)(a >> 24) & 0xff]
                ^ t2[(int)(a >> 40) & 0xff] ^ t1[(int)(a >> 56) & 0xff];
         c *= mul;
    
private voidroundCAB(long x, long mul)

         b ^= x ;
         c -= t1[(int)b & 0xff] ^ t2[(int)(b >> 16) & 0xff]
                ^ t3[(int)(b >> 32) & 0xff] ^ t4[(int)(b >> 48) & 0xff];
         a += t4[(int)(b >> 8) & 0xff] ^ t3[(int)(b >> 24) & 0xff]
                ^ t2[(int)(b >> 40) & 0xff] ^ t1[(int)(b >> 56) & 0xff];
         a *= mul;
    
public voidunpackWord(long r, byte[] out, int outOff)

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

        buf[bOff++] = in;

        if (bOff == buf.length)
        {
            processWord(buf, 0);
        }

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

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

            inOff++;
            len--;
        }

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

            inOff += 8;
            len -= 8;
            byteCount += 8;
        }

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

            inOff++;
            len--;
        }