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

package org.bouncycastle.pqc.crypto.falcon;

class FalconFFT
{
    static void FFT(final double[] array, final int n, final int n2) {
        int n4;
        final int n3 = n4 = 1 << n2 >> 1;
        for (int i = 1, n5 = 2; i < n2; ++i, n5 <<= 1) {
            final int n6 = n4 >> 1;
            for (int n7 = n5 >> 1, j = 0, n8 = 0; j < n7; ++j, n8 += n4) {
                final int n9 = n8 + n6 + n;
                final int n10 = n5 + j << 1;
                final double n11 = FPREngine.fpr_gm_tab[n10];
                final double n12 = FPREngine.fpr_gm_tab[n10 + 1];
                for (int k = n + n8, n13 = k + n3, n14 = k + n6, n15 = n14 + n3; k < n9; ++k, ++n13, ++n14, ++n15) {
                    final double n16 = array[k];
                    final double n17 = array[n13];
                    final double n18 = array[n14];
                    final double n19 = array[n15];
                    final double n20 = n18 * n11 - n19 * n12;
                    final double n21 = n18 * n12 + n19 * n11;
                    array[k] = n16 + n20;
                    array[n13] = n17 + n21;
                    array[n14] = n16 - n20;
                    array[n15] = n17 - n21;
                }
            }
            n4 = n6;
        }
    }
    
    static void iFFT(final double[] array, final int n, final int n2) {
        final int n3 = 1 << n2;
        int n4 = 1;
        int n5 = n3;
        final int n6 = n3 >> 1;
        for (int i = n2; i > 1; --i) {
            final int n7 = n5 >> 1;
            final int n8 = n4 << 1;
            int n9 = 0;
            for (int j = 0; j < n6; j += n8) {
                final int n10 = j + n4 + n;
                final int n11 = n7 + n9 << 1;
                final double n12 = FPREngine.fpr_gm_tab[n11];
                final double n13 = -FPREngine.fpr_gm_tab[n11 + 1];
                for (int k = n + j, n14 = k + n6, n15 = k + n4, n16 = n15 + n6; k < n10; ++k, ++n14, ++n15, ++n16) {
                    final double n17 = array[k];
                    final double n18 = array[n14];
                    final double n19 = array[n15];
                    final double n20 = array[n16];
                    array[k] = n17 + n19;
                    array[n14] = n18 + n20;
                    final double n21 = n17 - n19;
                    final double n22 = n18 - n20;
                    array[n15] = n21 * n12 - n22 * n13;
                    array[n16] = n21 * n13 + n22 * n12;
                }
                ++n9;
            }
            n4 = n8;
            n5 = n7;
        }
        if (n2 > 0) {
            final double n23 = FPREngine.fpr_p2_tab[n2];
            for (int l = 0; l < n3; ++l) {
                array[n + l] *= n23;
            }
        }
    }
    
    static void poly_add(final double[] array, final int n, final double[] array2, final int n2, final int n3) {
        for (int n4 = 1 << n3, i = 0; i < n4; ++i) {
            final int n5 = n + i;
            array[n5] += array2[n2 + i];
        }
    }
    
    static void poly_sub(final double[] array, final int n, final double[] array2, final int n2, final int n3) {
        for (int n4 = 1 << n3, i = 0; i < n4; ++i) {
            final int n5 = n + i;
            array[n5] -= array2[n2 + i];
        }
    }
    
    static void poly_neg(final double[] array, final int n, final int n2) {
        for (int n3 = 1 << n2, i = 0; i < n3; ++i) {
            array[n + i] = -array[n + i];
        }
    }
    
    static void poly_adj_fft(final double[] array, final int n, final int n2) {
        for (int n3 = 1 << n2, i = n3 >> 1; i < n3; ++i) {
            array[n + i] = -array[n + i];
        }
    }
    
    static void poly_mul_fft(final double[] array, final int n, final double[] array2, final int n2, final int n3) {
        for (int n4 = 1 << n3 >> 1, i = 0, n5 = n, n6 = n + n4, n7 = n2; i < n4; ++i, ++n5, ++n7, ++n6) {
            final double n8 = array[n5];
            final double n9 = array[n6];
            final double n10 = array2[n7];
            final double n11 = array2[n7 + n4];
            array[n5] = n8 * n10 - n9 * n11;
            array[n6] = n8 * n11 + n9 * n10;
        }
    }
    
    static void poly_muladj_fft(final double[] array, final int n, final double[] array2, final int n2, final int n3) {
        for (int n4 = 1 << n3 >> 1, i = 0, n5 = n; i < n4; ++i, ++n5) {
            final double n6 = array[n5];
            final double n7 = array[n5 + n4];
            final double n8 = array2[n2 + i];
            final double n9 = array2[n2 + i + n4];
            array[n5] = n6 * n8 + n7 * n9;
            array[n5 + n4] = n7 * n8 - n6 * n9;
        }
    }
    
    static void poly_mulselfadj_fft(final double[] array, final int n, final int n2) {
        for (int n3 = 1 << n2 >> 1, i = 0; i < n3; ++i) {
            final double n4 = array[n + i];
            final double n5 = array[n + i + n3];
            array[n + i] = n4 * n4 + n5 * n5;
            array[n + i + n3] = 0.0;
        }
    }
    
    static void poly_mulconst(final double[] array, final int n, final double n2, final int n3) {
        for (int n4 = 1 << n3, i = 0; i < n4; ++i) {
            array[n + i] *= n2;
        }
    }
    
    static void poly_invnorm2_fft(final double[] array, final int n, final double[] array2, final int n2, final double[] array3, final int n3, final int n4) {
        for (int n5 = 1 << n4 >> 1, i = 0; i < n5; ++i) {
            final double n6 = array2[n2 + i];
            final double n7 = array2[n2 + i + n5];
            final double n8 = array3[n3 + i];
            final double n9 = array3[n3 + i + n5];
            array[n + i] = 1.0 / (n6 * n6 + n7 * n7 + n8 * n8 + n9 * n9);
        }
    }
    
    static void poly_add_muladj_fft(final double[] array, final double[] array2, final double[] array3, final double[] array4, final double[] array5, final int n) {
        for (int n2 = 1 << n >> 1, i = 0; i < n2; ++i) {
            final int n3 = i + n2;
            final double n4 = array2[i];
            final double n5 = array2[n3];
            final double n6 = array3[i];
            final double n7 = array3[n3];
            final double n8 = array4[i];
            final double n9 = array4[n3];
            final double n10 = array5[i];
            final double n11 = array5[n3];
            final double n12 = n4 * n8 + n5 * n9;
            final double n13 = n5 * n8 - n4 * n9;
            final double n14 = n6 * n10 + n7 * n11;
            final double n15 = n7 * n10 - n6 * n11;
            array[i] = n12 + n14;
            array[n3] = n13 + n15;
        }
    }
    
    static void poly_mul_autoadj_fft(final double[] array, final int n, final double[] array2, final int n2, final int n3) {
        for (int n4 = 1 << n3 >> 1, i = 0; i < n4; ++i) {
            final int n5 = n + i;
            array[n5] *= array2[n2 + i];
            final int n6 = n + i + n4;
            array[n6] *= array2[n2 + i];
        }
    }
    
    static void poly_div_autoadj_fft(final double[] array, final int n, final double[] array2, final int n2, final int n3) {
        for (int n4 = 1 << n3 >> 1, i = 0; i < n4; ++i) {
            final double n5 = 1.0 / array2[n2 + i];
            final int n6 = n + i;
            array[n6] *= n5;
            final int n7 = n + i + n4;
            array[n7] *= n5;
        }
    }
    
    static void poly_LDL_fft(final double[] array, final int n, final double[] array2, final int n2, final double[] array3, final int n3, final int n4) {
        for (int n5 = 1 << n4 >> 1, i = 0, n6 = n5, n7 = n2, n8 = n2 + n5; i < n5; ++i, ++n6, ++n7, ++n8) {
            final double n9 = array[n + i];
            final double n10 = array[n + n6];
            final double n11 = array2[n7];
            final double n12 = array2[n8];
            final double n13 = 1.0 / (n9 * n9 + n10 * n10);
            final double n14 = n9 * n13;
            final double n15 = n13 * -n10;
            final double n16 = n11 * n14 - n12 * n15;
            final double n17 = n11 * n15 + n12 * n14;
            final double n18 = n11;
            final double n19 = n12;
            final double n20 = n16 * n18 + n17 * n19;
            final double n21 = n16 * -n19 + n17 * n18;
            final int n22 = n3 + i;
            array3[n22] -= n20;
            final int n23 = n3 + n6;
            array3[n23] -= n21;
            array2[n7] = n16;
            array2[n8] = -n17;
        }
    }
    
    static void poly_split_fft(final double[] array, final int n, final double[] array2, final int n2, final double[] array3, final int n3, final int n4) {
        final int n5 = 1 << n4 >> 1;
        final int n6 = n5 >> 1;
        array[n] = array3[n3];
        array2[n2] = array3[n3 + n5];
        for (int i = 0; i < n6; ++i) {
            int n7 = n3 + (i << 1);
            final double n8 = array3[n7];
            final double n9 = array3[n7++ + n5];
            final double n10 = array3[n7];
            final double n11 = array3[n7 + n5];
            array[n + i] = (n8 + n10) * 0.5;
            array[n + i + n6] = (n9 + n11) * 0.5;
            final double n12 = n8 - n10;
            final double n13 = n9 - n11;
            final int n14 = i + n5 << 1;
            final double n15 = FPREngine.fpr_gm_tab[n14];
            final double n16 = -FPREngine.fpr_gm_tab[n14 + 1];
            final int n17 = n2 + i;
            array2[n17] = (n12 * n15 - n13 * n16) * 0.5;
            array2[n17 + n6] = (n12 * n16 + n13 * n15) * 0.5;
        }
    }
    
    static void poly_merge_fft(final double[] array, final int n, final double[] array2, final int n2, final double[] array3, final int n3, final int n4) {
        final int n5 = 1 << n4 >> 1;
        final int n6 = n5 >> 1;
        array[n] = array2[n2];
        array[n + n5] = array3[n3];
        for (int i = 0; i < n6; ++i) {
            final int n7 = n3 + i;
            final double n8 = array3[n7];
            final double n9 = array3[n7 + n6];
            final int n10 = i + n5 << 1;
            final double n11 = FPREngine.fpr_gm_tab[n10];
            final double n12 = FPREngine.fpr_gm_tab[n10 + 1];
            final double n13 = n8 * n11 - n9 * n12;
            final double n14 = n8 * n12 + n9 * n11;
            final int n15 = n2 + i;
            final double n16 = array2[n15];
            final double n17 = array2[n15 + n6];
            int n18 = n + (i << 1);
            array[n18] = n16 + n13;
            array[n18++ + n5] = n17 + n14;
            array[n18] = n16 - n13;
            array[n18 + n5] = n17 - n14;
        }
    }
}
