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

package org.bouncycastle.crypto.engines;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.digests.SparkleDigest;
import org.bouncycastle.util.Integers;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Pack;

public class SparkleEngine extends AEADBaseEngine
{
    private static final int[] RCON;
    private final int[] state;
    private final int[] k;
    private final int[] npub;
    private boolean encrypted;
    private final int SPARKLE_STEPS_SLIM;
    private final int SPARKLE_STEPS_BIG;
    private final int KEY_WORDS;
    private final int TAG_WORDS;
    private final int STATE_WORDS;
    private final int RATE_WORDS;
    private final int CAP_MASK;
    private final int _A0;
    private final int _A1;
    private final int _M2;
    private final int _M3;
    
    public SparkleEngine(final SparkleParameters sparkleParameters) {
        int n = 0;
        int n2 = 0;
        int n3 = 0;
        int n4 = 0;
        int n5 = 0;
        switch (sparkleParameters.ordinal()) {
            case 0: {
                n = 128;
                n2 = 128;
                n3 = 128;
                n4 = 256;
                n5 = 128;
                this.SPARKLE_STEPS_SLIM = 7;
                this.SPARKLE_STEPS_BIG = 10;
                this.algorithmName = "SCHWAEMM128-128";
                break;
            }
            case 1: {
                n = 128;
                n2 = 256;
                n3 = 128;
                n4 = 384;
                n5 = 128;
                this.SPARKLE_STEPS_SLIM = 7;
                this.SPARKLE_STEPS_BIG = 11;
                this.algorithmName = "SCHWAEMM256-128";
                break;
            }
            case 2: {
                n = 192;
                n2 = 192;
                n3 = 192;
                n4 = 384;
                n5 = 192;
                this.SPARKLE_STEPS_SLIM = 7;
                this.SPARKLE_STEPS_BIG = 11;
                this.algorithmName = "SCHWAEMM192-192";
                break;
            }
            case 3: {
                n = 256;
                n2 = 256;
                n3 = 256;
                n4 = 512;
                n5 = 256;
                this.SPARKLE_STEPS_SLIM = 8;
                this.SPARKLE_STEPS_BIG = 12;
                this.algorithmName = "SCHWAEMM256-256";
                break;
            }
            default: {
                throw new IllegalArgumentException("Invalid definition of SCHWAEMM instance");
            }
        }
        this.KEY_WORDS = n >>> 5;
        this.KEY_SIZE = n >>> 3;
        this.TAG_WORDS = n3 >>> 5;
        this.MAC_SIZE = n3 >>> 3;
        this.STATE_WORDS = n4 >>> 5;
        this.RATE_WORDS = n2 >>> 5;
        this.IV_SIZE = n2 >>> 3;
        final int n6 = n5 >>> 6;
        final int n7 = n5 >>> 5;
        this.CAP_MASK = ((this.RATE_WORDS > n7) ? (n7 - 1) : -1);
        this._A0 = 1 << n6 << 24;
        this._A1 = (0x1 ^ 1 << n6) << 24;
        this._M2 = (0x2 ^ 1 << n6) << 24;
        this._M3 = (0x3 ^ 1 << n6) << 24;
        this.state = new int[this.STATE_WORDS];
        this.k = new int[this.KEY_WORDS];
        this.npub = new int[this.RATE_WORDS];
        final int iv_SIZE = this.IV_SIZE;
        this.BlockSize = iv_SIZE;
        this.AADBufferSize = iv_SIZE;
        this.setInnerMembers(ProcessingBufferType.Buffered, AADOperatorType.Default, DataOperatorType.Default);
    }
    
    @Override
    protected void init(final byte[] array, final byte[] array2) throws IllegalArgumentException {
        Pack.littleEndianToInt(array, 0, this.k);
        Pack.littleEndianToInt(array2, 0, this.npub);
    }
    
    @Override
    protected void finishAAD(final State state, final boolean b) {
        this.finishAAD2(state);
    }
    
    @Override
    protected void processFinalBlock(final byte[] array, int n) {
        if (this.encrypted || this.m_bufPos > 0) {
            final int[] state = this.state;
            final int n2 = this.STATE_WORDS - 1;
            state[n2] ^= ((this.m_bufPos < this.IV_SIZE) ? this._M2 : this._M3);
            final int[] array2 = new int[this.RATE_WORDS];
            for (int i = 0; i < this.m_bufPos; ++i) {
                final int[] array3 = array2;
                final int n3 = i >>> 2;
                array3[n3] |= (this.m_buf[i] & 0xFF) << ((i & 0x3) << 3);
            }
            if (this.m_bufPos < this.IV_SIZE) {
                if (!this.forEncryption) {
                    final int n4 = (this.m_bufPos & 0x3) << 3;
                    final int[] array4 = array2;
                    final int n5 = this.m_bufPos >>> 2;
                    array4[n5] |= this.state[this.m_bufPos >>> 2] >>> n4 << n4;
                    final int n6 = (this.m_bufPos >>> 2) + 1;
                    System.arraycopy(this.state, n6, array2, n6, this.RATE_WORDS - n6);
                }
                final int[] array5 = array2;
                final int n7 = this.m_bufPos >>> 2;
                array5[n7] ^= 128 << ((this.m_bufPos & 0x3) << 3);
            }
            for (int j = 0; j < this.RATE_WORDS / 2; ++j) {
                final int n8 = j + this.RATE_WORDS / 2;
                final int n9 = this.state[j];
                final int n10 = this.state[n8];
                if (this.forEncryption) {
                    this.state[j] = (n10 ^ array2[j] ^ this.state[this.RATE_WORDS + j]);
                    this.state[n8] = (n9 ^ n10 ^ array2[n8] ^ this.state[this.RATE_WORDS + (n8 & this.CAP_MASK)]);
                }
                else {
                    this.state[j] = (n9 ^ n10 ^ array2[j] ^ this.state[this.RATE_WORDS + j]);
                    this.state[n8] = (n9 ^ array2[n8] ^ this.state[this.RATE_WORDS + (n8 & this.CAP_MASK)]);
                }
                final int[] array6 = array2;
                final int n11 = j;
                array6[n11] ^= n9;
                final int[] array7 = array2;
                final int n12 = n8;
                array7[n12] ^= n10;
            }
            for (int k = 0; k < this.m_bufPos; ++k) {
                array[n++] = (byte)(array2[k >>> 2] >>> ((k & 0x3) << 3));
            }
            sparkle_opt(this.state, this.SPARKLE_STEPS_BIG);
        }
        for (int l = 0; l < this.KEY_WORDS; ++l) {
            final int[] state2 = this.state;
            final int n13 = this.RATE_WORDS + l;
            state2[n13] ^= this.k[l];
        }
        Pack.intToLittleEndian(this.state, this.RATE_WORDS, this.TAG_WORDS, this.mac, 0);
    }
    
    @Override
    protected void processBufferAAD(final byte[] array, final int n) {
        for (int i = 0; i < this.RATE_WORDS / 2; ++i) {
            final int n2 = i + this.RATE_WORDS / 2;
            final int n3 = this.state[i];
            final int n4 = this.state[n2];
            final int littleEndianToInt = Pack.littleEndianToInt(array, n + i * 4);
            final int littleEndianToInt2 = Pack.littleEndianToInt(array, n + n2 * 4);
            this.state[i] = (n4 ^ littleEndianToInt ^ this.state[this.RATE_WORDS + i]);
            this.state[n2] = (n3 ^ n4 ^ littleEndianToInt2 ^ this.state[this.RATE_WORDS + (n2 & this.CAP_MASK)]);
        }
        sparkle_opt(this.state, this.SPARKLE_STEPS_SLIM);
    }
    
    @Override
    protected void processBufferDecrypt(final byte[] array, final int n, final byte[] array2, final int n2) {
        for (int i = 0; i < this.RATE_WORDS / 2; ++i) {
            final int n3 = i + this.RATE_WORDS / 2;
            final int n4 = this.state[i];
            final int n5 = this.state[n3];
            final int littleEndianToInt = Pack.littleEndianToInt(array, n + i * 4);
            final int littleEndianToInt2 = Pack.littleEndianToInt(array, n + n3 * 4);
            this.state[i] = (n4 ^ n5 ^ littleEndianToInt ^ this.state[this.RATE_WORDS + i]);
            this.state[n3] = (n4 ^ littleEndianToInt2 ^ this.state[this.RATE_WORDS + (n3 & this.CAP_MASK)]);
            Pack.intToLittleEndian(littleEndianToInt ^ n4, array2, n2 + i * 4);
            Pack.intToLittleEndian(littleEndianToInt2 ^ n5, array2, n2 + n3 * 4);
        }
        sparkle_opt(this.state, this.SPARKLE_STEPS_SLIM);
        this.encrypted = true;
    }
    
    @Override
    protected void processBufferEncrypt(final byte[] array, final int n, final byte[] array2, final int n2) {
        for (int i = 0; i < this.RATE_WORDS / 2; ++i) {
            final int n3 = i + this.RATE_WORDS / 2;
            final int n4 = this.state[i];
            final int n5 = this.state[n3];
            final int littleEndianToInt = Pack.littleEndianToInt(array, n + i * 4);
            final int littleEndianToInt2 = Pack.littleEndianToInt(array, n + n3 * 4);
            this.state[i] = (n5 ^ littleEndianToInt ^ this.state[this.RATE_WORDS + i]);
            this.state[n3] = (n4 ^ n5 ^ littleEndianToInt2 ^ this.state[this.RATE_WORDS + (n3 & this.CAP_MASK)]);
            Pack.intToLittleEndian(littleEndianToInt ^ n4, array2, n2 + i * 4);
            Pack.intToLittleEndian(littleEndianToInt2 ^ n5, array2, n2 + n3 * 4);
        }
        sparkle_opt(this.state, this.SPARKLE_STEPS_SLIM);
        this.encrypted = true;
    }
    
    @Override
    protected void processFinalAAD() {
        if (this.m_aadPos < this.BlockSize) {
            final int[] state = this.state;
            final int n = this.STATE_WORDS - 1;
            state[n] ^= this._A0;
            this.m_aad[this.m_aadPos++] = -128;
            Arrays.fill(this.m_aad, this.m_aadPos, this.BlockSize, (byte)0);
        }
        else {
            final int[] state2 = this.state;
            final int n2 = this.STATE_WORDS - 1;
            state2[n2] ^= this._A1;
        }
        for (int i = 0; i < this.RATE_WORDS / 2; ++i) {
            final int n3 = i + this.RATE_WORDS / 2;
            final int n4 = this.state[i];
            final int n5 = this.state[n3];
            final int littleEndianToInt = Pack.littleEndianToInt(this.m_aad, i * 4);
            final int littleEndianToInt2 = Pack.littleEndianToInt(this.m_aad, n3 * 4);
            this.state[i] = (n5 ^ littleEndianToInt ^ this.state[this.RATE_WORDS + i]);
            this.state[n3] = (n4 ^ n5 ^ littleEndianToInt2 ^ this.state[this.RATE_WORDS + (n3 & this.CAP_MASK)]);
        }
        sparkle_opt(this.state, this.SPARKLE_STEPS_BIG);
    }
    
    @Override
    protected void reset(final boolean b) {
        this.encrypted = false;
        System.arraycopy(this.npub, 0, this.state, 0, this.RATE_WORDS);
        System.arraycopy(this.k, 0, this.state, this.RATE_WORDS, this.KEY_WORDS);
        sparkle_opt(this.state, this.SPARKLE_STEPS_BIG);
        super.reset(b);
    }
    
    private static int ELL(final int n) {
        return Integers.rotateRight(n, 16) ^ (n & 0xFFFF);
    }
    
    private static void sparkle_opt(final int[] array, final int n) {
        switch (array.length) {
            case 8: {
                sparkle_opt8(array, n);
                break;
            }
            case 12: {
                sparkle_opt12(array, n);
                break;
            }
            case 16: {
                sparkle_opt16(array, n);
                break;
            }
            default: {
                throw new IllegalStateException();
            }
        }
    }
    
    static void sparkle_opt8(final int[] array, final int n) {
        int n2 = array[0];
        int n3 = array[1];
        int n4 = array[2];
        int n5 = array[3];
        int n6 = array[4];
        int n7 = array[5];
        int n8 = array[6];
        int n9 = array[7];
        for (int i = 0; i < n; ++i) {
            final int n10 = n3 ^ SparkleEngine.RCON[i & 0x7];
            final int n11 = n5 ^ i;
            final int n12 = SparkleEngine.RCON[0];
            final int n13 = n2 + Integers.rotateRight(n10, 31);
            final int n14 = n10 ^ Integers.rotateRight(n13, 24);
            final int n15 = (n13 ^ n12) + Integers.rotateRight(n14, 17);
            final int n16 = n14 ^ Integers.rotateRight(n15, 17);
            final int n17 = (n15 ^ n12) + n16;
            final int n18 = n16 ^ Integers.rotateRight(n17, 31);
            final int n19 = (n17 ^ n12) + Integers.rotateRight(n18, 24);
            final int n20 = n18 ^ Integers.rotateRight(n19, 16);
            final int n21 = n19 ^ n12;
            final int n22 = SparkleEngine.RCON[1];
            final int n23 = n4 + Integers.rotateRight(n11, 31);
            final int n24 = n11 ^ Integers.rotateRight(n23, 24);
            final int n25 = (n23 ^ n22) + Integers.rotateRight(n24, 17);
            final int n26 = n24 ^ Integers.rotateRight(n25, 17);
            final int n27 = (n25 ^ n22) + n26;
            final int n28 = n26 ^ Integers.rotateRight(n27, 31);
            final int n29 = (n27 ^ n22) + Integers.rotateRight(n28, 24);
            final int n30 = n28 ^ Integers.rotateRight(n29, 16);
            final int n31 = n29 ^ n22;
            final int n32 = SparkleEngine.RCON[2];
            final int n33 = n6 + Integers.rotateRight(n7, 31);
            final int n34 = n7 ^ Integers.rotateRight(n33, 24);
            final int n35 = (n33 ^ n32) + Integers.rotateRight(n34, 17);
            final int n36 = n34 ^ Integers.rotateRight(n35, 17);
            final int n37 = (n35 ^ n32) + n36;
            final int n38 = n36 ^ Integers.rotateRight(n37, 31);
            final int n39 = (n37 ^ n32) + Integers.rotateRight(n38, 24);
            final int n40 = n38 ^ Integers.rotateRight(n39, 16);
            final int n41 = n39 ^ n32;
            final int n42 = SparkleEngine.RCON[3];
            final int n43 = n8 + Integers.rotateRight(n9, 31);
            final int n44 = n9 ^ Integers.rotateRight(n43, 24);
            final int n45 = (n43 ^ n42) + Integers.rotateRight(n44, 17);
            final int n46 = n44 ^ Integers.rotateRight(n45, 17);
            final int n47 = (n45 ^ n42) + n46;
            final int n48 = n46 ^ Integers.rotateRight(n47, 31);
            final int n49 = (n47 ^ n42) + Integers.rotateRight(n48, 24);
            final int n50 = n48 ^ Integers.rotateRight(n49, 16);
            final int n51 = n49 ^ n42;
            final int ell = ELL(n21 ^ n31);
            final int ell2 = ELL(n20 ^ n30);
            final int n52 = n21 ^ n41;
            final int n53 = n20 ^ n40;
            final int n54 = n31 ^ n51;
            final int n55 = n30 ^ n50;
            n6 = n21;
            n7 = n20;
            n8 = n31;
            n9 = n30;
            n2 = (n54 ^ ell2);
            n3 = (n55 ^ ell);
            n4 = (n52 ^ ell2);
            n5 = (n53 ^ ell);
        }
        array[0] = n2;
        array[1] = n3;
        array[2] = n4;
        array[3] = n5;
        array[4] = n6;
        array[5] = n7;
        array[6] = n8;
        array[7] = n9;
    }
    
    static void sparkle_opt12(final int[] array, final int n) {
        int n2 = array[0];
        int n3 = array[1];
        int n4 = array[2];
        int n5 = array[3];
        int n6 = array[4];
        int n7 = array[5];
        int n8 = array[6];
        int n9 = array[7];
        int n10 = array[8];
        int n11 = array[9];
        int n12 = array[10];
        int n13 = array[11];
        for (int i = 0; i < n; ++i) {
            final int n14 = n3 ^ SparkleEngine.RCON[i & 0x7];
            final int n15 = n5 ^ i;
            final int n16 = SparkleEngine.RCON[0];
            final int n17 = n2 + Integers.rotateRight(n14, 31);
            final int n18 = n14 ^ Integers.rotateRight(n17, 24);
            final int n19 = (n17 ^ n16) + Integers.rotateRight(n18, 17);
            final int n20 = n18 ^ Integers.rotateRight(n19, 17);
            final int n21 = (n19 ^ n16) + n20;
            final int n22 = n20 ^ Integers.rotateRight(n21, 31);
            final int n23 = (n21 ^ n16) + Integers.rotateRight(n22, 24);
            final int n24 = n22 ^ Integers.rotateRight(n23, 16);
            final int n25 = n23 ^ n16;
            final int n26 = SparkleEngine.RCON[1];
            final int n27 = n4 + Integers.rotateRight(n15, 31);
            final int n28 = n15 ^ Integers.rotateRight(n27, 24);
            final int n29 = (n27 ^ n26) + Integers.rotateRight(n28, 17);
            final int n30 = n28 ^ Integers.rotateRight(n29, 17);
            final int n31 = (n29 ^ n26) + n30;
            final int n32 = n30 ^ Integers.rotateRight(n31, 31);
            final int n33 = (n31 ^ n26) + Integers.rotateRight(n32, 24);
            final int n34 = n32 ^ Integers.rotateRight(n33, 16);
            final int n35 = n33 ^ n26;
            final int n36 = SparkleEngine.RCON[2];
            final int n37 = n6 + Integers.rotateRight(n7, 31);
            final int n38 = n7 ^ Integers.rotateRight(n37, 24);
            final int n39 = (n37 ^ n36) + Integers.rotateRight(n38, 17);
            final int n40 = n38 ^ Integers.rotateRight(n39, 17);
            final int n41 = (n39 ^ n36) + n40;
            final int n42 = n40 ^ Integers.rotateRight(n41, 31);
            final int n43 = (n41 ^ n36) + Integers.rotateRight(n42, 24);
            final int n44 = n42 ^ Integers.rotateRight(n43, 16);
            final int n45 = n43 ^ n36;
            final int n46 = SparkleEngine.RCON[3];
            final int n47 = n8 + Integers.rotateRight(n9, 31);
            final int n48 = n9 ^ Integers.rotateRight(n47, 24);
            final int n49 = (n47 ^ n46) + Integers.rotateRight(n48, 17);
            final int n50 = n48 ^ Integers.rotateRight(n49, 17);
            final int n51 = (n49 ^ n46) + n50;
            final int n52 = n50 ^ Integers.rotateRight(n51, 31);
            final int n53 = (n51 ^ n46) + Integers.rotateRight(n52, 24);
            final int n54 = n52 ^ Integers.rotateRight(n53, 16);
            final int n55 = n53 ^ n46;
            final int n56 = SparkleEngine.RCON[4];
            final int n57 = n10 + Integers.rotateRight(n11, 31);
            final int n58 = n11 ^ Integers.rotateRight(n57, 24);
            final int n59 = (n57 ^ n56) + Integers.rotateRight(n58, 17);
            final int n60 = n58 ^ Integers.rotateRight(n59, 17);
            final int n61 = (n59 ^ n56) + n60;
            final int n62 = n60 ^ Integers.rotateRight(n61, 31);
            final int n63 = (n61 ^ n56) + Integers.rotateRight(n62, 24);
            final int n64 = n62 ^ Integers.rotateRight(n63, 16);
            final int n65 = n63 ^ n56;
            final int n66 = SparkleEngine.RCON[5];
            final int n67 = n12 + Integers.rotateRight(n13, 31);
            final int n68 = n13 ^ Integers.rotateRight(n67, 24);
            final int n69 = (n67 ^ n66) + Integers.rotateRight(n68, 17);
            final int n70 = n68 ^ Integers.rotateRight(n69, 17);
            final int n71 = (n69 ^ n66) + n70;
            final int n72 = n70 ^ Integers.rotateRight(n71, 31);
            final int n73 = (n71 ^ n66) + Integers.rotateRight(n72, 24);
            final int n74 = n72 ^ Integers.rotateRight(n73, 16);
            final int n75 = n73 ^ n66;
            final int ell = ELL(n25 ^ n35 ^ n45);
            final int ell2 = ELL(n24 ^ n34 ^ n44);
            final int n76 = n25 ^ n55;
            final int n77 = n24 ^ n54;
            final int n78 = n35 ^ n65;
            final int n79 = n34 ^ n64;
            final int n80 = n45 ^ n75;
            final int n81 = n44 ^ n74;
            n8 = n25;
            n9 = n24;
            n10 = n35;
            n11 = n34;
            n12 = n45;
            n13 = n44;
            n2 = (n78 ^ ell2);
            n3 = (n79 ^ ell);
            n4 = (n80 ^ ell2);
            n5 = (n81 ^ ell);
            n6 = (n76 ^ ell2);
            n7 = (n77 ^ ell);
        }
        array[0] = n2;
        array[1] = n3;
        array[2] = n4;
        array[3] = n5;
        array[4] = n6;
        array[5] = n7;
        array[6] = n8;
        array[7] = n9;
        array[8] = n10;
        array[9] = n11;
        array[10] = n12;
        array[11] = n13;
    }
    
    public static void sparkle_opt12(final SparkleDigest.Friend friend, final int[] array, final int n) {
        if (null == friend) {
            throw new NullPointerException("This method is only for use by SparkleDigest");
        }
        sparkle_opt12(array, n);
    }
    
    static void sparkle_opt16(final int[] array, final int n) {
        int n2 = array[0];
        int n3 = array[1];
        int n4 = array[2];
        int n5 = array[3];
        int n6 = array[4];
        int n7 = array[5];
        int n8 = array[6];
        int n9 = array[7];
        int n10 = array[8];
        int n11 = array[9];
        int n12 = array[10];
        int n13 = array[11];
        int n14 = array[12];
        int n15 = array[13];
        int n16 = array[14];
        int n17 = array[15];
        for (int i = 0; i < n; ++i) {
            final int n18 = n3 ^ SparkleEngine.RCON[i & 0x7];
            final int n19 = n5 ^ i;
            final int n20 = SparkleEngine.RCON[0];
            final int n21 = n2 + Integers.rotateRight(n18, 31);
            final int n22 = n18 ^ Integers.rotateRight(n21, 24);
            final int n23 = (n21 ^ n20) + Integers.rotateRight(n22, 17);
            final int n24 = n22 ^ Integers.rotateRight(n23, 17);
            final int n25 = (n23 ^ n20) + n24;
            final int n26 = n24 ^ Integers.rotateRight(n25, 31);
            final int n27 = (n25 ^ n20) + Integers.rotateRight(n26, 24);
            final int n28 = n26 ^ Integers.rotateRight(n27, 16);
            final int n29 = n27 ^ n20;
            final int n30 = SparkleEngine.RCON[1];
            final int n31 = n4 + Integers.rotateRight(n19, 31);
            final int n32 = n19 ^ Integers.rotateRight(n31, 24);
            final int n33 = (n31 ^ n30) + Integers.rotateRight(n32, 17);
            final int n34 = n32 ^ Integers.rotateRight(n33, 17);
            final int n35 = (n33 ^ n30) + n34;
            final int n36 = n34 ^ Integers.rotateRight(n35, 31);
            final int n37 = (n35 ^ n30) + Integers.rotateRight(n36, 24);
            final int n38 = n36 ^ Integers.rotateRight(n37, 16);
            final int n39 = n37 ^ n30;
            final int n40 = SparkleEngine.RCON[2];
            final int n41 = n6 + Integers.rotateRight(n7, 31);
            final int n42 = n7 ^ Integers.rotateRight(n41, 24);
            final int n43 = (n41 ^ n40) + Integers.rotateRight(n42, 17);
            final int n44 = n42 ^ Integers.rotateRight(n43, 17);
            final int n45 = (n43 ^ n40) + n44;
            final int n46 = n44 ^ Integers.rotateRight(n45, 31);
            final int n47 = (n45 ^ n40) + Integers.rotateRight(n46, 24);
            final int n48 = n46 ^ Integers.rotateRight(n47, 16);
            final int n49 = n47 ^ n40;
            final int n50 = SparkleEngine.RCON[3];
            final int n51 = n8 + Integers.rotateRight(n9, 31);
            final int n52 = n9 ^ Integers.rotateRight(n51, 24);
            final int n53 = (n51 ^ n50) + Integers.rotateRight(n52, 17);
            final int n54 = n52 ^ Integers.rotateRight(n53, 17);
            final int n55 = (n53 ^ n50) + n54;
            final int n56 = n54 ^ Integers.rotateRight(n55, 31);
            final int n57 = (n55 ^ n50) + Integers.rotateRight(n56, 24);
            final int n58 = n56 ^ Integers.rotateRight(n57, 16);
            final int n59 = n57 ^ n50;
            final int n60 = SparkleEngine.RCON[4];
            final int n61 = n10 + Integers.rotateRight(n11, 31);
            final int n62 = n11 ^ Integers.rotateRight(n61, 24);
            final int n63 = (n61 ^ n60) + Integers.rotateRight(n62, 17);
            final int n64 = n62 ^ Integers.rotateRight(n63, 17);
            final int n65 = (n63 ^ n60) + n64;
            final int n66 = n64 ^ Integers.rotateRight(n65, 31);
            final int n67 = (n65 ^ n60) + Integers.rotateRight(n66, 24);
            final int n68 = n66 ^ Integers.rotateRight(n67, 16);
            final int n69 = n67 ^ n60;
            final int n70 = SparkleEngine.RCON[5];
            final int n71 = n12 + Integers.rotateRight(n13, 31);
            final int n72 = n13 ^ Integers.rotateRight(n71, 24);
            final int n73 = (n71 ^ n70) + Integers.rotateRight(n72, 17);
            final int n74 = n72 ^ Integers.rotateRight(n73, 17);
            final int n75 = (n73 ^ n70) + n74;
            final int n76 = n74 ^ Integers.rotateRight(n75, 31);
            final int n77 = (n75 ^ n70) + Integers.rotateRight(n76, 24);
            final int n78 = n76 ^ Integers.rotateRight(n77, 16);
            final int n79 = n77 ^ n70;
            final int n80 = SparkleEngine.RCON[6];
            final int n81 = n14 + Integers.rotateRight(n15, 31);
            final int n82 = n15 ^ Integers.rotateRight(n81, 24);
            final int n83 = (n81 ^ n80) + Integers.rotateRight(n82, 17);
            final int n84 = n82 ^ Integers.rotateRight(n83, 17);
            final int n85 = (n83 ^ n80) + n84;
            final int n86 = n84 ^ Integers.rotateRight(n85, 31);
            final int n87 = (n85 ^ n80) + Integers.rotateRight(n86, 24);
            final int n88 = n86 ^ Integers.rotateRight(n87, 16);
            final int n89 = n87 ^ n80;
            final int n90 = SparkleEngine.RCON[7];
            final int n91 = n16 + Integers.rotateRight(n17, 31);
            final int n92 = n17 ^ Integers.rotateRight(n91, 24);
            final int n93 = (n91 ^ n90) + Integers.rotateRight(n92, 17);
            final int n94 = n92 ^ Integers.rotateRight(n93, 17);
            final int n95 = (n93 ^ n90) + n94;
            final int n96 = n94 ^ Integers.rotateRight(n95, 31);
            final int n97 = (n95 ^ n90) + Integers.rotateRight(n96, 24);
            final int n98 = n96 ^ Integers.rotateRight(n97, 16);
            final int n99 = n97 ^ n90;
            final int ell = ELL(n29 ^ n39 ^ n49 ^ n59);
            final int ell2 = ELL(n28 ^ n38 ^ n48 ^ n58);
            final int n100 = n29 ^ n69;
            final int n101 = n28 ^ n68;
            final int n102 = n39 ^ n79;
            final int n103 = n38 ^ n78;
            final int n104 = n49 ^ n89;
            final int n105 = n48 ^ n88;
            final int n106 = n59 ^ n99;
            final int n107 = n58 ^ n98;
            n10 = n29;
            n11 = n28;
            n12 = n39;
            n13 = n38;
            n14 = n49;
            n15 = n48;
            n16 = n59;
            n17 = n58;
            n2 = (n102 ^ ell2);
            n3 = (n103 ^ ell);
            n4 = (n104 ^ ell2);
            n5 = (n105 ^ ell);
            n6 = (n106 ^ ell2);
            n7 = (n107 ^ ell);
            n8 = (n100 ^ ell2);
            n9 = (n101 ^ ell);
        }
        array[0] = n2;
        array[1] = n3;
        array[2] = n4;
        array[3] = n5;
        array[4] = n6;
        array[5] = n7;
        array[6] = n8;
        array[7] = n9;
        array[8] = n10;
        array[9] = n11;
        array[10] = n12;
        array[11] = n13;
        array[12] = n14;
        array[13] = n15;
        array[14] = n16;
        array[15] = n17;
    }
    
    public static void sparkle_opt16(final SparkleDigest.Friend friend, final int[] array, final int n) {
        if (null == friend) {
            throw new NullPointerException("This method is only for use by SparkleDigest");
        }
        sparkle_opt16(array, n);
    }
    
    static {
        RCON = new int[] { -1209970334, -1083090816, 951376470, 844003128, -1156479509, 1333558103, -809524792, -1028445891 };
    }
    
    public enum SparkleParameters
    {
        SCHWAEMM128_128, 
        SCHWAEMM256_128, 
        SCHWAEMM192_192, 
        SCHWAEMM256_256;
    }
}
