package org.bouncycastle.pqc.crypto.newhope;

import org.bouncycastle.crypto.digests.SHAKEDigest;
import org.bouncycastle.util.Pack;

class Poly
{
    static void add(short[] x, short[] y, short[] z)
    {
        for (int i = 0; i < Params.N; ++i)
        {
            z[i] = Reduce.barrett((short)(x[i] + y[i]));
        }
    }

    static void fromBytes(short[] r, byte[] a)
    {
        for (int i = 0; i < Params.N / 4; ++i)
        {
            int j = 7 * i;
            int a0 = a[j + 0] & 0xFF, a1 = a[j + 1] & 0xFF, a2 = a[j + 2] & 0xFF, a3 = a[j + 3] & 0xFF,
                a4 = a[j + 4] & 0xFF, a5 = a[j + 5] & 0xFF, a6 = a[j + 6] & 0xFF;

            int k = 4 * i;
            r[k + 0] = (short)( a0                    | ((a1 & 0x3F) <<  8));
            r[k + 1] = (short)((a1 >>> 6) | (a2 << 2) | ((a3 & 0x0F) << 10));
            r[k + 2] = (short)((a3 >>> 4) | (a4 << 4) | ((a5 & 0x03) << 12));
            r[k + 3] = (short)((a5 >>> 2) | (a6 << 6));
        }
    }

    static void fromNTT(short[] r)
    {
        NTT.bitReverse(r);
        NTT.core(r, Precomp.OMEGAS_INV_MONTGOMERY);
        NTT.mulCoefficients(r, Precomp.PSIS_INV_MONTGOMERY);
    }

    static void getNoise(short[] r, byte[] seed, byte nonce)
    {
        byte[] iv = new byte[8];
        iv[0] = nonce;

        byte[] buf = new byte[4 * Params.N];
        ChaCha20.process(seed, iv, buf, 0, buf.length);

        for (int i = 0; i < Params.N; ++i)
        {
            int t = Pack.bigEndianToInt(buf, i * 4);
            //r[i] = (short)(bitCount(t) + Params.Q - Params.K);

            int d = 0;
            for (int j = 0; j < 8; ++j)
            {
                d += (t >> j) & 0x01010101;
            }
            int a = ((d >>> 24) + (d >>> 0)) & 0xFF;
            int b = ((d >>> 16) + (d >>> 8)) & 0xFF;
            r[i] = (short)(a + Params.Q - b);
        }
    }

    static void pointWise(short[] x, short[] y, short[] z)
    {
        for (int i = 0; i < Params.N; ++i)
        {
            int xi = x[i] & 0xFFFF, yi = y[i] & 0xFFFF;
            short t = Reduce.montgomery(3186 * yi);         // t is now in Montgomery domain
            z[i] = Reduce.montgomery(xi * (t & 0xFFFF));    // z[i] is back in normal domain
        }
    }

    static void toBytes(byte[] r, short[] p)
    {
        for (int i = 0; i < Params.N / 4; ++i)
        {
            int j = 4 * i;

            // Make sure that coefficients are in [0,q]
            short t0 = normalize(p[j + 0]);
            short t1 = normalize(p[j + 1]);
            short t2 = normalize(p[j + 2]);
            short t3 = normalize(p[j + 3]);

            int k = 7 * i;
            r[k + 0] = (byte)t0;
            r[k + 1] = (byte)((t0 >> 8) | (t1 << 6));
            r[k + 2] = (byte)(t1 >> 2);
            r[k + 3] = (byte)((t1 >> 10) | (t2 << 4));
            r[k + 4] = (byte)(t2 >> 4);
            r[k + 5] = (byte)((t2 >> 12) | (t3 << 2));
            r[k + 6] = (byte)(t3 >> 6);
        }
    }

    static void toNTT(short[] r)
    {
        NTT.mulCoefficients(r, Precomp.PSIS_BITREV_MONTGOMERY); 
        NTT.core(r, Precomp.OMEGAS_MONTGOMERY);
    }

    static void uniform(short[] a, byte[] seed)
    {
        SHAKEDigest xof = new SHAKEDigest(128);
        xof.update(seed, 0, seed.length);

        int pos = 0;
        for (;;)
        {
            byte[] output = new byte[256];
            xof.doOutput(output, 0, output.length);

            for (int i = 0; i < output.length; i += 2)
            {
                int val = (output[i] & 0xFF) | ((output[i + 1] & 0xFF) << 8);
                val &= 0x3FFF;
                if (val < Params.Q)
                {
                    a[pos++] = (short)val;
                    if (pos == Params.N)
                    {
                        return;
                    }
                }
            }
        }
    }

//    private static int bitCount(int n)
//    {
////        return Integer.bitCount(n);
//        n = n - ((n >>> 1) & 0x55555555);
//        n = (n & 0x33333333) + ((n >>> 2) & 0x33333333);
//        return ((n + (n >>> 4) & 0x0F0F0F0F) * 0x01010101) >>> 24;
//    }

    private static short normalize(short x)
    {
        int t = Reduce.barrett(x);
        int m = t - Params.Q;
        int c = m >> 31;
        t = m ^ ((t ^ m) & c);
        return (short)t;
    }
}
