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

package org.bouncycastle.pqc.crypto.picnic;

import org.bouncycastle.util.Pack;

class Tape
{
    byte[][] tapes;
    int pos;
    int nTapes;
    private PicnicEngine engine;
    
    public Tape(final PicnicEngine engine) {
        this.engine = engine;
        this.tapes = new byte[engine.numMPCParties][2 * engine.andSizeBytes];
        this.pos = 0;
        this.nTapes = engine.numMPCParties;
    }
    
    protected void setAuxBits(final byte[] array) {
        final int n = this.engine.numMPCParties - 1;
        int n2 = 0;
        final int stateSizeBits = this.engine.stateSizeBits;
        for (int i = 0; i < this.engine.numRounds; ++i) {
            for (int j = 0; j < stateSizeBits; ++j) {
                Utils.setBit(this.tapes[n], stateSizeBits + stateSizeBits * 2 * i + j, Utils.getBit(array, n2++));
            }
        }
    }
    
    protected void computeAuxTape(final byte[] array) {
        final int[] array2 = new int[16];
        final int[] array3 = new int[16];
        final int[] array4 = new int[16];
        final int[] array5 = new int[16];
        final int[] array6 = new int[16];
        array6[this.engine.stateSizeWords - 1] = 0;
        this.tapesToParityBits(array6, this.engine.stateSizeBits);
        final KMatricesWithPointer kMatrixInv = this.engine.lowmcConstants.KMatrixInv(this.engine);
        this.engine.matrix_mul(array5, array6, kMatrixInv.getData(), kMatrixInv.getMatrixPointer());
        if (array != null) {
            Pack.intToLittleEndian(array5, 0, this.engine.stateSizeWords, array, 0);
        }
        for (int i = this.engine.numRounds; i > 0; --i) {
            final KMatricesWithPointer kMatrix = this.engine.lowmcConstants.KMatrix(this.engine, i);
            this.engine.matrix_mul(array2, array5, kMatrix.getData(), kMatrix.getMatrixPointer());
            this.engine.xor_array(array3, array3, array2, 0);
            final KMatricesWithPointer lMatrixInv = this.engine.lowmcConstants.LMatrixInv(this.engine, i - 1);
            this.engine.matrix_mul(array4, array3, lMatrixInv.getData(), lMatrixInv.getMatrixPointer());
            if (i == 1) {
                System.arraycopy(array6, 0, array3, 0, array6.length);
            }
            else {
                this.pos = this.engine.stateSizeBits * 2 * (i - 1);
                this.tapesToParityBits(array3, this.engine.stateSizeBits);
            }
            this.pos = this.engine.stateSizeBits * 2 * (i - 1) + this.engine.stateSizeBits;
            this.engine.aux_mpc_sbox(array3, array4, this);
        }
        this.pos = 0;
    }
    
    private void tapesToParityBits(final int[] array, final int n) {
        for (int i = 0; i < n; ++i) {
            Utils.setBitInWordArray(array, i, Utils.parity16(this.tapesToWord()));
        }
    }
    
    protected int tapesToWord() {
        final int n = 0;
        final int n2 = this.pos >>> 3;
        final int n3 = (this.pos & 0x7) ^ 0x7;
        final int n4 = 1 << n3;
        final int n5 = n | (this.tapes[0][n2] & n4) << 7 | (this.tapes[1][n2] & n4) << 6 | (this.tapes[2][n2] & n4) << 5 | (this.tapes[3][n2] & n4) << 4 | (this.tapes[4][n2] & n4) << 3 | (this.tapes[5][n2] & n4) << 2 | (this.tapes[6][n2] & n4) << 1 | (this.tapes[7][n2] & n4) << 0 | (this.tapes[8][n2] & n4) << 15 | (this.tapes[9][n2] & n4) << 14 | (this.tapes[10][n2] & n4) << 13 | (this.tapes[11][n2] & n4) << 12 | (this.tapes[12][n2] & n4) << 11 | (this.tapes[13][n2] & n4) << 10 | (this.tapes[14][n2] & n4) << 9 | (this.tapes[15][n2] & n4) << 8;
        ++this.pos;
        return n5 >>> n3;
    }
}
