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

package org.bouncycastle.crypto.digests;

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

public class Haraka256Digest extends HarakaBase
{
    private final byte[] buffer;
    private int off;
    private final CryptoServicePurpose purpose;
    
    private void mix256(final byte[][] array, final byte[][] array2) {
        System.arraycopy(array[0], 0, array2[0], 0, 4);
        System.arraycopy(array[1], 0, array2[0], 4, 4);
        System.arraycopy(array[0], 4, array2[0], 8, 4);
        System.arraycopy(array[1], 4, array2[0], 12, 4);
        System.arraycopy(array[0], 8, array2[1], 0, 4);
        System.arraycopy(array[1], 8, array2[1], 4, 4);
        System.arraycopy(array[0], 12, array2[1], 8, 4);
        System.arraycopy(array[1], 12, array2[1], 12, 4);
    }
    
    private int haraka256256(final byte[] array, final byte[] array2, final int n) {
        final byte[][] array3 = new byte[2][16];
        final byte[][] array4 = new byte[2][16];
        System.arraycopy(array, 0, array3[0], 0, 16);
        System.arraycopy(array, 16, array3[1], 0, 16);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka256Digest.RC[0]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka256Digest.RC[1]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka256Digest.RC[2]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka256Digest.RC[3]);
        this.mix256(array3, array4);
        array3[0] = HarakaBase.aesEnc(array4[0], Haraka256Digest.RC[4]);
        array3[1] = HarakaBase.aesEnc(array4[1], Haraka256Digest.RC[5]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka256Digest.RC[6]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka256Digest.RC[7]);
        this.mix256(array3, array4);
        array3[0] = HarakaBase.aesEnc(array4[0], Haraka256Digest.RC[8]);
        array3[1] = HarakaBase.aesEnc(array4[1], Haraka256Digest.RC[9]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka256Digest.RC[10]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka256Digest.RC[11]);
        this.mix256(array3, array4);
        array3[0] = HarakaBase.aesEnc(array4[0], Haraka256Digest.RC[12]);
        array3[1] = HarakaBase.aesEnc(array4[1], Haraka256Digest.RC[13]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka256Digest.RC[14]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka256Digest.RC[15]);
        this.mix256(array3, array4);
        array3[0] = HarakaBase.aesEnc(array4[0], Haraka256Digest.RC[16]);
        array3[1] = HarakaBase.aesEnc(array4[1], Haraka256Digest.RC[17]);
        array3[0] = HarakaBase.aesEnc(array3[0], Haraka256Digest.RC[18]);
        array3[1] = HarakaBase.aesEnc(array3[1], Haraka256Digest.RC[19]);
        this.mix256(array3, array4);
        Bytes.xor(16, array4[0], 0, array, 0, array2, n);
        Bytes.xor(16, array4[1], 0, array, 16, array2, n + 16);
        return 32;
    }
    
    public Haraka256Digest() {
        this(CryptoServicePurpose.ANY);
    }
    
    public Haraka256Digest(final CryptoServicePurpose purpose) {
        this.purpose = purpose;
        this.buffer = new byte[32];
        CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, this.getDigestSize() * 4, purpose));
    }
    
    public Haraka256Digest(final Haraka256Digest haraka256Digest) {
        this.purpose = haraka256Digest.purpose;
        this.buffer = Arrays.clone(haraka256Digest.buffer);
        this.off = haraka256Digest.off;
        CryptoServicesRegistrar.checkConstraints(Utils.getDefaultProperties(this, this.getDigestSize() * 4, this.purpose));
    }
    
    @Override
    public String getAlgorithmName() {
        return "Haraka-256";
    }
    
    @Override
    public void update(final byte b) {
        if (this.off > 31) {
            throw new IllegalArgumentException("total input cannot be more than 32 bytes");
        }
        this.buffer[this.off++] = b;
    }
    
    @Override
    public void update(final byte[] array, final int n, final int n2) {
        if (this.off > 32 - n2) {
            throw new IllegalArgumentException("total input cannot be more than 32 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 != 32) {
            throw new IllegalStateException("input must be exactly 32 bytes");
        }
        if (array.length - n < 32) {
            throw new IllegalArgumentException("output too short to receive digest");
        }
        final int haraka256256 = this.haraka256256(this.buffer, array, n);
        this.reset();
        return haraka256256;
    }
    
    @Override
    public void reset() {
        this.off = 0;
        Arrays.clear(this.buffer);
    }
}
