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

package org.bouncycastle.pqc.crypto.hqc;

import org.bouncycastle.util.Arrays;

class ReedMuller
{
    static void encodeSub(final Codeword codeword, final int n) {
        final int n2 = Bit0Mask(n >> 7) ^ (Bit0Mask(n) & 0xAAAAAAAA) ^ (Bit0Mask(n >> 1) & 0xCCCCCCCC) ^ (Bit0Mask(n >> 2) & 0xF0F0F0F0) ^ (Bit0Mask(n >> 3) & 0xFF00FF00) ^ (Bit0Mask(n >> 4) & 0xFFFF0000);
        codeword.type32[0] = n2;
        final int n3 = n2 ^ Bit0Mask(n >> 5);
        codeword.type32[1] = n3;
        final int n4 = n3 ^ Bit0Mask(n >> 6);
        codeword.type32[3] = n4;
        codeword.type32[2] = (n4 ^ Bit0Mask(n >> 5));
    }
    
    private static void hadamardTransform(final int[] array, final int[] array2) {
        int[] clone = Arrays.clone(array);
        int[] clone2 = Arrays.clone(array2);
        for (int i = 0; i < 7; ++i) {
            for (int j = 0; j < 64; ++j) {
                clone2[j] = clone[2 * j] + clone[2 * j + 1];
                clone2[j + 64] = clone[2 * j] - clone[2 * j + 1];
            }
            final int[] array3 = clone;
            clone = clone2;
            clone2 = array3;
        }
        System.arraycopy(clone2, 0, array, 0, array.length);
        System.arraycopy(clone, 0, array2, 0, array2.length);
    }
    
    private static void expandThenSum(final int[] array, final Codeword[] array2, final int n, final int n2) {
        for (int i = 0; i < 4; ++i) {
            for (int j = 0; j < 32; ++j) {
                array[i * 32 + j] = (array2[n].type32[i] >> j & 0x1);
            }
        }
        for (int k = 1; k < n2; ++k) {
            for (int l = 0; l < 4; ++l) {
                for (int n3 = 0; n3 < 32; ++n3) {
                    final int n4 = l * 32 + n3;
                    array[n4] += (array2[k + n].type32[l] >> n3 & 0x1);
                }
            }
        }
    }
    
    private static int findPeaks(final int[] array) {
        int max = 0;
        int n = 0;
        int n2 = 0;
        for (int i = 0; i < 128; ++i) {
            final int n3 = array[i];
            final int n4 = (n3 > 0) ? -1 : 0;
            final int a = (n4 & n3) | (~n4 & -n3);
            n = ((a > max) ? n3 : n);
            n2 = ((a > max) ? i : n2);
            max = Math.max(a, max);
        }
        return n2 | 128 * ((n > 0) ? 1 : 0);
    }
    
    private static int Bit0Mask(final int n) {
        return -(n & 0x1);
    }
    
    public static void encode(final long[] array, final byte[] array2, final int n, final int n2) {
        final byte[] clone = Arrays.clone(array2);
        final Codeword[] array3 = new Codeword[n * n2];
        for (int i = 0; i < array3.length; ++i) {
            array3[i] = new Codeword();
        }
        for (int j = 0; j < n; ++j) {
            final int n3 = j * n2;
            encodeSub(array3[n3], clone[j]);
            for (int k = 1; k < n2; ++k) {
                array3[n3 + k] = array3[n3];
            }
        }
        CopyCWD(array, array3);
    }
    
    private static void CopyCWD(final long[] array, final Codeword[] array2) {
        final int[] array3 = new int[array2.length * 4];
        int n = 0;
        for (int i = 0; i < array2.length; ++i) {
            System.arraycopy(array2[i].type32, 0, array3, n, array2[i].type32.length);
            n += 4;
        }
        Utils.fromByte32ArrayToLongArray(array, array3);
    }
    
    public static void decode(final byte[] array, final long[] array2, final int n, final int n2) {
        final byte[] clone = Arrays.clone(array);
        final Codeword[] array3 = new Codeword[array2.length / 2];
        final int[] array4 = new int[array2.length * 2];
        Utils.fromLongArrayToByte32Array(array4, array2);
        for (int i = 0; i < array3.length; ++i) {
            array3[i] = new Codeword();
            System.arraycopy(array4, i * 4, array3[i].type32, 0, 4);
        }
        final int[] array5 = new int[128];
        final int[] array6 = new int[128];
        for (int j = 0; j < n; ++j) {
            expandThenSum(array5, array3, j * n2, n2);
            hadamardTransform(array5, array6);
            final int[] array7 = array6;
            final int n3 = 0;
            array7[n3] -= 64 * n2;
            clone[j] = (byte)findPeaks(array6);
        }
        CopyCWD(array2, array3);
        System.arraycopy(clone, 0, array, 0, array.length);
    }
    
    static class Codeword
    {
        int[] type32;
        int[] type8;
        
        public Codeword() {
            this.type32 = new int[4];
            this.type8 = new int[16];
        }
    }
}
