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

package org.bouncycastle.pqc.math.ntru;

import org.bouncycastle.pqc.math.ntru.parameters.NTRUParameterSet;
import org.bouncycastle.pqc.math.ntru.parameters.NTRUHRSSParameterSet;

public class HRSSPolynomial extends Polynomial
{
    public HRSSPolynomial(final NTRUHRSSParameterSet set) {
        super(set);
    }
    
    @Override
    public byte[] sqToBytes(final int n) {
        final byte[] array = new byte[n];
        final short[] array2 = new short[8];
        int i;
        for (i = 0; i < this.params.packDegree() / 8; ++i) {
            for (int j = 0; j < 8; ++j) {
                array2[j] = (short)Polynomial.modQ(this.coeffs[8 * i + j] & 0xFFFF, this.params.q());
            }
            array[13 * i + 0] = (byte)(array2[0] & 0xFF);
            array[13 * i + 1] = (byte)(array2[0] >>> 8 | (array2[1] & 0x7) << 5);
            array[13 * i + 2] = (byte)(array2[1] >>> 3 & 0xFF);
            array[13 * i + 3] = (byte)(array2[1] >>> 11 | (array2[2] & 0x3F) << 2);
            array[13 * i + 4] = (byte)(array2[2] >>> 6 | (array2[3] & 0x1) << 7);
            array[13 * i + 5] = (byte)(array2[3] >>> 1 & 0xFF);
            array[13 * i + 6] = (byte)(array2[3] >>> 9 | (array2[4] & 0xF) << 4);
            array[13 * i + 7] = (byte)(array2[4] >>> 4 & 0xFF);
            array[13 * i + 8] = (byte)(array2[4] >>> 12 | (array2[5] & 0x7F) << 1);
            array[13 * i + 9] = (byte)(array2[5] >>> 7 | (array2[6] & 0x3) << 6);
            array[13 * i + 10] = (byte)(array2[6] >>> 2 & 0xFF);
            array[13 * i + 11] = (byte)(array2[6] >>> 10 | (array2[7] & 0x1F) << 3);
            array[13 * i + 12] = (byte)(array2[7] >>> 5);
        }
        int k;
        for (k = 0; k < this.params.packDegree() - 8 * i; ++k) {
            array2[k] = (short)Polynomial.modQ(this.coeffs[8 * i + k] & 0xFFFF, this.params.q());
        }
        while (k < 8) {
            array2[k] = 0;
            ++k;
        }
        switch (this.params.packDegree() - 8 * (this.params.packDegree() / 8)) {
            case 4: {
                array[13 * i + 0] = (byte)(array2[0] & 0xFF);
                array[13 * i + 1] = (byte)(array2[0] >>> 8 | (array2[1] & 0x7) << 5);
                array[13 * i + 2] = (byte)(array2[1] >>> 3 & 0xFF);
                array[13 * i + 3] = (byte)(array2[1] >>> 11 | (array2[2] & 0x3F) << 2);
                array[13 * i + 4] = (byte)(array2[2] >>> 6 | (array2[3] & 0x1) << 7);
                array[13 * i + 5] = (byte)(array2[3] >>> 1 & 0xFF);
                array[13 * i + 6] = (byte)(array2[3] >>> 9 | (array2[4] & 0xF) << 4);
            }
            case 2: {
                array[13 * i + 0] = (byte)(array2[0] & 0xFF);
                array[13 * i + 1] = (byte)(array2[0] >>> 8 | (array2[1] & 0x7) << 5);
                array[13 * i + 2] = (byte)(array2[1] >>> 3 & 0xFF);
                array[13 * i + 3] = (byte)(array2[1] >>> 11 | (array2[2] & 0x3F) << 2);
                break;
            }
        }
        return array;
    }
    
    @Override
    public void sqFromBytes(final byte[] array) {
        int i;
        for (i = 0; i < this.params.packDegree() / 8; ++i) {
            this.coeffs[8 * i + 0] = (short)((array[13 * i + 0] & 0xFF) | ((short)(array[13 * i + 1] & 0xFF) & 0x1F) << 8);
            this.coeffs[8 * i + 1] = (short)((array[13 * i + 1] & 0xFF) >>> 5 | (short)(array[13 * i + 2] & 0xFF) << 3 | ((short)(array[13 * i + 3] & 0xFF) & 0x3) << 11);
            this.coeffs[8 * i + 2] = (short)((array[13 * i + 3] & 0xFF) >>> 2 | ((short)(array[13 * i + 4] & 0xFF) & 0x7F) << 6);
            this.coeffs[8 * i + 3] = (short)((array[13 * i + 4] & 0xFF) >>> 7 | (short)(array[13 * i + 5] & 0xFF) << 1 | ((short)(array[13 * i + 6] & 0xFF) & 0xF) << 9);
            this.coeffs[8 * i + 4] = (short)((array[13 * i + 6] & 0xFF) >>> 4 | (short)(array[13 * i + 7] & 0xFF) << 4 | ((short)(array[13 * i + 8] & 0xFF) & 0x1) << 12);
            this.coeffs[8 * i + 5] = (short)((array[13 * i + 8] & 0xFF) >>> 1 | ((short)(array[13 * i + 9] & 0xFF) & 0x3F) << 7);
            this.coeffs[8 * i + 6] = (short)((array[13 * i + 9] & 0xFF) >>> 6 | (short)(array[13 * i + 10] & 0xFF) << 2 | ((short)(array[13 * i + 11] & 0xFF) & 0x7) << 10);
            this.coeffs[8 * i + 7] = (short)((array[13 * i + 11] & 0xFF) >>> 3 | (short)(array[13 * i + 12] & 0xFF) << 5);
        }
        switch (this.params.packDegree() & 0x7) {
            case 4: {
                this.coeffs[8 * i + 0] = (short)((array[13 * i + 0] & 0xFF) | ((short)(array[13 * i + 1] & 0xFF) & 0x1F) << 8);
                this.coeffs[8 * i + 1] = (short)((array[13 * i + 1] & 0xFF) >>> 5 | (short)(array[13 * i + 2] & 0xFF) << 3 | ((short)(array[13 * i + 3] & 0xFF) & 0x3) << 11);
                this.coeffs[8 * i + 2] = (short)((array[13 * i + 3] & 0xFF) >>> 2 | ((short)(array[13 * i + 4] & 0xFF) & 0x7F) << 6);
                this.coeffs[8 * i + 3] = (short)((array[13 * i + 4] & 0xFF) >>> 7 | (short)(array[13 * i + 5] & 0xFF) << 1 | ((short)(array[13 * i + 6] & 0xFF) & 0xF) << 9);
                break;
            }
            case 2: {
                this.coeffs[8 * i + 0] = (short)((array[13 * i + 0] & 0xFF) | ((short)(array[13 * i + 1] & 0xFF) & 0x1F) << 8);
                this.coeffs[8 * i + 1] = (short)((array[13 * i + 1] & 0xFF) >>> 5 | (short)(array[13 * i + 2] & 0xFF) << 3 | ((short)(array[13 * i + 3] & 0xFF) & 0x3) << 11);
                break;
            }
        }
        this.coeffs[this.params.n() - 1] = 0;
    }
    
    @Override
    public void lift(final Polynomial polynomial) {
        final int length = this.coeffs.length;
        final Polynomial polynomial2 = this.params.createPolynomial();
        final short n = (short)(3 - length % 3);
        polynomial2.coeffs[0] = (short)(polynomial.coeffs[0] * (2 - n) + polynomial.coeffs[1] * 0 + polynomial.coeffs[2] * n);
        polynomial2.coeffs[1] = (short)(polynomial.coeffs[1] * (2 - n) + polynomial.coeffs[2] * 0);
        polynomial2.coeffs[2] = (short)(polynomial.coeffs[2] * (2 - n));
        short n2 = 0;
        for (int i = 3; i < length; ++i) {
            final short[] coeffs = polynomial2.coeffs;
            final int n3 = 0;
            coeffs[n3] += (short)(polynomial.coeffs[i] * (n2 + 2 * n));
            final short[] coeffs2 = polynomial2.coeffs;
            final int n4 = 1;
            coeffs2[n4] += (short)(polynomial.coeffs[i] * (n2 + n));
            final short[] coeffs3 = polynomial2.coeffs;
            final int n5 = 2;
            coeffs3[n5] += (short)(polynomial.coeffs[i] * n2);
            n2 = (short)((n2 + n) % 3);
        }
        final short[] coeffs4 = polynomial2.coeffs;
        final int n6 = 1;
        coeffs4[n6] += (short)(polynomial.coeffs[0] * (n2 + n));
        final short[] coeffs5 = polynomial2.coeffs;
        final int n7 = 2;
        coeffs5[n7] += (short)(polynomial.coeffs[0] * n2);
        final short[] coeffs6 = polynomial2.coeffs;
        final int n8 = 2;
        coeffs6[n8] += (short)(polynomial.coeffs[1] * (n2 + n));
        for (int j = 3; j < length; ++j) {
            polynomial2.coeffs[j] = (short)(polynomial2.coeffs[j - 3] + 2 * (polynomial.coeffs[j] + polynomial.coeffs[j - 1] + polynomial.coeffs[j - 2]));
        }
        polynomial2.mod3PhiN();
        polynomial2.z3ToZq();
        this.coeffs[0] = (short)(-polynomial2.coeffs[0]);
        for (int k = 0; k < length - 1; ++k) {
            this.coeffs[k + 1] = (short)(polynomial2.coeffs[k] - polynomial2.coeffs[k + 1]);
        }
    }
}
