// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.crypto.digests;

import org.bouncycastle.util.Bytes;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.CryptoServicePurpose;

public class Haraka512Digest extends HarakaBase
{
    private final byte[] buffer;
    private int off;
    private final CryptoServicePurpose purpose;
    
    public Haraka512Digest() {
        this(CryptoServicePurpose.ANY);
    }
    
    public Haraka512Digest(final CryptoServicePurpose purpose) {
        this.purpose = purpose;
        this.buffer = new byte[64];
    }
    
    public Haraka512Digest(final Haraka512Digest haraka512Digest) {
        this.purpose = haraka512Digest.purpose;
        this.buffer = Arrays.clone(haraka512Digest.buffer);
        this.off = haraka512Digest.off;
    }
    
    private void mix512(final byte[][] array, final byte[][] array2) {
        System.arraycopy(array[0], 12, array2[0], 0, 4);
        System.arraycopy(array[2], 12, array2[0], 4, 4);
        System.arraycopy(array[1], 12, array2[0], 8, 4);
        System.arraycopy(array[3], 12, array2[0], 12, 4);
        System.arraycopy(array[2], 0, array2[1], 0, 4);
        System.arraycopy(array[0], 0, array2[1], 4, 4);
        System.arraycopy(array[3], 0, array2[1], 8, 4);
        System.arraycopy(array[1], 0, array2[1], 12, 4);
        System.arraycopy(array[2], 4, array2[2], 0, 4);
        System.arraycopy(array[0], 4, array2[2], 4, 4);
        System.arraycopy(array[3], 4, array2[2], 8, 4);
        System.arraycopy(array[1], 4, array2[2], 12, 4);
        System.arraycopy(array[0], 8, array2[3], 0, 4);
        System.arraycopy(array[2], 8, array2[3], 4, 4);
        System.arraycopy(array[1], 8, array2[3], 8, 4);
        System.arraycopy(array[3], 8, array2[3], 12, 4);
    }
    
    private int haraka512256(final byte[] array, final byte[] array2, final int n) {
        final byte[][] array3 = new byte[4][16];
        final byte[][] array4 = new byte[4][16];
        System.arraycopy(array, 0, array3[0], 0, 16);
        System.arraycopy(array, 16, array3[1], 0, 16);
        System.arraycopy(array, 32, array3[2], 0, 16);
        System.arraycopy(array, 48, array3[3], 0, 16);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka512Digest.RC[0]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka512Digest.RC[1]);
        array3[2] = HarakaBase.aesEnc(array3[2], Haraka512Digest.RC[2]);
        array3[3] = HarakaBase.aesEnc(array3[3], Haraka512Digest.RC[3]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka512Digest.RC[4]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka512Digest.RC[5]);
        array3[2] = HarakaBase.aesEnc(array3[2], Haraka512Digest.RC[6]);
        array3[3] = HarakaBase.aesEnc(array3[3], Haraka512Digest.RC[7]);
        this.mix512(array3, array4);
        array3[0] = HarakaBase.aesEnc(array4[0], Haraka512Digest.RC[8]);
        array3[1] = HarakaBase.aesEnc(array4[1], Haraka512Digest.RC[9]);
        array3[2] = HarakaBase.aesEnc(array4[2], Haraka512Digest.RC[10]);
        array3[3] = HarakaBase.aesEnc(array4[3], Haraka512Digest.RC[11]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka512Digest.RC[12]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka512Digest.RC[13]);
        array3[2] = HarakaBase.aesEnc(array3[2], Haraka512Digest.RC[14]);
        array3[3] = HarakaBase.aesEnc(array3[3], Haraka512Digest.RC[15]);
        this.mix512(array3, array4);
        array3[0] = HarakaBase.aesEnc(array4[0], Haraka512Digest.RC[16]);
        array3[1] = HarakaBase.aesEnc(array4[1], Haraka512Digest.RC[17]);
        array3[2] = HarakaBase.aesEnc(array4[2], Haraka512Digest.RC[18]);
        array3[3] = HarakaBase.aesEnc(array4[3], Haraka512Digest.RC[19]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka512Digest.RC[20]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka512Digest.RC[21]);
        array3[2] = HarakaBase.aesEnc(array3[2], Haraka512Digest.RC[22]);
        array3[3] = HarakaBase.aesEnc(array3[3], Haraka512Digest.RC[23]);
        this.mix512(array3, array4);
        array3[0] = HarakaBase.aesEnc(array4[0], Haraka512Digest.RC[24]);
        array3[1] = HarakaBase.aesEnc(array4[1], Haraka512Digest.RC[25]);
        array3[2] = HarakaBase.aesEnc(array4[2], Haraka512Digest.RC[26]);
        array3[3] = HarakaBase.aesEnc(array4[3], Haraka512Digest.RC[27]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka512Digest.RC[28]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka512Digest.RC[29]);
        array3[2] = HarakaBase.aesEnc(array3[2], Haraka512Digest.RC[30]);
        array3[3] = HarakaBase.aesEnc(array3[3], Haraka512Digest.RC[31]);
        this.mix512(array3, array4);
        array3[0] = HarakaBase.aesEnc(array4[0], Haraka512Digest.RC[32]);
        array3[1] = HarakaBase.aesEnc(array4[1], Haraka512Digest.RC[33]);
        array3[2] = HarakaBase.aesEnc(array4[2], Haraka512Digest.RC[34]);
        array3[3] = HarakaBase.aesEnc(array4[3], Haraka512Digest.RC[35]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka512Digest.RC[36]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka512Digest.RC[37]);
        array3[2] = HarakaBase.aesEnc(array3[2], Haraka512Digest.RC[38]);
        array3[3] = HarakaBase.aesEnc(array3[3], Haraka512Digest.RC[39]);
        this.mix512(array3, array4);
        Bytes.xor(16, array4[0], 0, array, 0, array3[0], 0);
        Bytes.xor(16, array4[1], 0, array, 16, array3[1], 0);
        Bytes.xor(16, array4[2], 0, array, 32, array3[2], 0);
        Bytes.xor(16, array4[3], 0, array, 48, array3[3], 0);
        System.arraycopy(array3[0], 8, array2, n, 8);
        System.arraycopy(array3[1], 8, array2, n + 8, 8);
        System.arraycopy(array3[2], 0, array2, n + 16, 8);
        System.arraycopy(array3[3], 0, array2, n + 24, 8);
        return 32;
    }
    
    @Override
    public String getAlgorithmName() {
        return "Haraka-512";
    }
    
    @Override
    public void update(final byte b) {
        if (this.off > 63) {
            throw new IllegalArgumentException("total input cannot be more than 64 bytes");
        }
        this.buffer[this.off++] = b;
    }
    
    @Override
    public void update(final byte[] array, final int n, final int n2) {
        if (this.off > 64 - n2) {
            throw new IllegalArgumentException("total input cannot be more than 64 bytes");
        }
        System.arraycopy(array, n, this.buffer, this.off, n2);
        this.off += n2;
    }
    
    @Override
    public int doFinal(final byte[] array, final int n) {
        if (this.off != 64) {
            throw new IllegalStateException("input must be exactly 64 bytes");
        }
        if (array.length - n < 32) {
            throw new IllegalArgumentException("output too short to receive digest");
        }
        final int haraka512256 = this.haraka512256(this.buffer, array, n);
        this.reset();
        return haraka512256;
    }
    
    @Override
    public void reset() {
        this.off = 0;
        Arrays.clear(this.buffer);
    }
}
