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

package org.bouncycastle.pqc.crypto.snova;

import org.bouncycastle.util.GF16;

class GF16Utils
{
    private static final int GF16_MASK = 585;
    
    static void encodeMergeInHalf(final byte[] array, final int n, final byte[] array2) {
        int n2;
        int i;
        for (n2 = n + 1 >>> 1, i = 0; i < n / 2; ++i, ++n2) {
            array2[i] = (byte)(array[i] | array[n2] << 4);
        }
        if ((n & 0x1) == 0x1) {
            array2[i] = array[i];
        }
    }
    
    static void decodeMergeInHalf(final byte[] array, final byte[] array2, final int n) {
        for (int n2 = n + 1 >>> 1, i = 0; i < n2; ++i) {
            array2[i] = (byte)(array[i] & 0xF);
            array2[i + n2] = (byte)(array[i] >>> 4 & 0xF);
        }
    }
    
    static void gf16mTranMulMul(final byte[] array, final int n, final byte[] array2, final byte[] array3, final byte[] array4, final byte[] array5, final byte[] array6, final byte[] array7, final byte[] array8, final int n2) {
        int i = 0;
        int n3 = 0;
        int n4 = 0;
        while (i < n2) {
            for (int j = 0; j < n2; ++j) {
                byte b = 0;
                for (int k = 0, n5 = n + j, n6 = i; k < n2; ++k, n5 += n2, n6 += n2) {
                    b ^= GF16.mul(array[n5], array4[n6]);
                }
                array6[j] = b;
            }
            for (int l = 0, n7 = 0; l < n2; ++l, n7 += n2) {
                byte b2 = 0;
                for (int n8 = 0; n8 < n2; ++n8) {
                    b2 ^= GF16.mul(array2[n7 + n8], array6[n8]);
                }
                array7[i + n7] = b2;
            }
            for (int n9 = 0; n9 < n2; ++n9) {
                array6[n9] = GF16.innerProduct(array5, n3, array, n + n9, n2);
            }
            for (int n10 = 0; n10 < n2; ++n10) {
                array8[n4++] = GF16.innerProduct(array6, 0, array3, n10, n2);
            }
            ++i;
            n3 += n2;
        }
    }
    
    static void gf16mMulMul(final byte[] array, final byte[] array2, final byte[] array3, final byte[] array4, final byte[] array5, final int n) {
        int i = 0;
        int n2 = 0;
        int n3 = 0;
        while (i < n) {
            for (int j = 0; j < n; ++j) {
                array4[j] = GF16.innerProduct(array, n2, array2, j, n);
            }
            for (int k = 0; k < n; ++k) {
                array5[n3++] = GF16.innerProduct(array4, 0, array3, k, n);
            }
            ++i;
            n2 += n;
        }
    }
    
    static void gf16mMul(final byte[] array, final byte[] array2, final byte[] array3, final int n) {
        int i = 0;
        int n2 = 0;
        int n3 = 0;
        while (i < n) {
            for (int j = 0; j < n; ++j) {
                array3[n3++] = GF16.innerProduct(array, n2, array2, j, n);
            }
            ++i;
            n2 += n;
        }
    }
    
    static void gf16mMulMulTo(final byte[] array, final byte[] array2, final byte[] array3, final byte[] array4, final byte[] array5, final int n) {
        int i = 0;
        int n2 = 0;
        int n3 = 0;
        while (i < n) {
            for (int j = 0; j < n; ++j) {
                array4[j] = GF16.innerProduct(array, n2, array2, j, n);
            }
            for (int k = 0; k < n; ++k) {
                final int n4 = n3++;
                array5[n4] ^= GF16.innerProduct(array4, 0, array3, k, n);
            }
            ++i;
            n2 += n;
        }
    }
    
    static void gf16mMulTo(final byte[] array, final byte[] array2, final byte[] array3, final int n) {
        int i = 0;
        int n2 = 0;
        int n3 = 0;
        while (i < n) {
            for (int j = 0; j < n; ++j) {
                final int n4 = n3++;
                array3[n4] ^= GF16.innerProduct(array, n2, array2, j, n);
            }
            ++i;
            n2 += n;
        }
    }
    
    static void gf16mMulToTo(final byte[] array, final byte[] array2, final byte[] array3, final byte[] array4, final byte[] array5, final int n) {
        int i = 0;
        int n2 = 0;
        int n3 = 0;
        while (i < n) {
            for (int j = 0; j < n; ++j) {
                final int n4 = n3;
                array4[n4] ^= GF16.innerProduct(array, n2, array2, j, n);
                final int n5 = n3++;
                array5[n5] ^= GF16.innerProduct(array2, n2, array3, j, n);
            }
            ++i;
            n2 += n;
        }
    }
    
    static void gf16mMulTo(final byte[] array, final byte[] array2, final byte[] array3, int n, final int n2) {
        for (int i = 0, n3 = 0; i < n2; ++i, n3 += n2) {
            for (int j = 0; j < n2; ++j) {
                final int n4 = n++;
                array3[n4] ^= GF16.innerProduct(array, n3, array2, j, n2);
            }
        }
    }
    
    static void gf16mMulTo(final byte[] array, final byte[] array2, final byte[] array3, final byte[] array4, final byte[] array5, int n, final int n2) {
        for (int i = 0, n3 = 0; i < n2; ++i, n3 += n2) {
            for (int j = 0; j < n2; ++j) {
                final int n4 = n++;
                array5[n4] ^= (byte)(GF16.innerProduct(array, n3, array2, j, n2) ^ GF16.innerProduct(array3, n3, array4, j, n2));
            }
        }
    }
    
    static void gf16mMulTo(final byte[] array, final byte[] array2, final int n, final byte[] array3, int n2, final int n3) {
        for (int i = 0, n4 = 0; i < n3; ++i, n4 += n3) {
            for (int j = 0; j < n3; ++j) {
                final int n5 = n2++;
                array3[n5] ^= GF16.innerProduct(array, n4, array2, n + j, n3);
            }
        }
    }
    
    static int gf16FromNibble(final int n) {
        final int n2 = n | n << 4;
        return (n2 & 0x41) | (n2 << 2 & 0x208);
    }
    
    static int ctGF16IsNotZero(final byte b) {
        final int n = b & 0xFF;
        return (n | n >>> 1 | n >>> 2 | n >>> 3) & 0x1;
    }
    
    private static int gf16Reduce(final int n) {
        final int n2 = n & 0x49249249;
        final int n3 = n >>> 12;
        final int n4 = n2 ^ (n3 ^ n3 << 3);
        final int n5 = n4 >>> 12;
        final int n6 = n4 ^ (n5 ^ n5 << 3);
        final int n7 = n6 >>> 12;
        return (n6 ^ (n7 ^ n7 << 3)) & 0x249;
    }
    
    static byte gf16ToNibble(final int n) {
        final int gf16Reduce = gf16Reduce(n);
        final int n2 = gf16Reduce | gf16Reduce >>> 4;
        return (byte)((n2 & 0x5) | (n2 >>> 2 & 0xA));
    }
}
