예제 #1
0
        public static void poly_uniform(Poly a, byte [] seed)
        {
            uint   pos = 0, ctr = 0;
            ushort val;

            ulong [] state   = new ulong[25];
            int      nblocks = 16;

            byte [] buf = new byte[Fips202.SHAKE128_RATE * nblocks];

            Fips202.shake128_absorb(state, seed, NewHope.NEWHOPE_SEEDBYTES);

            Fips202.shake128_squeezeblocks(buf, nblocks, state);

            while (ctr < NewHope.PARAM_N)
            {
                val = (buf[pos] | ((ushort)buf[pos + 1] << 8)) & 0x3fff; // Specialized for q = 12889
                if (val < NewHope.PARAM_Q)
                {
                    a.coeffs[ctr++] = val;
                }
                pos += 2;
                if (pos > Fips202.SHAKE128_RATE * nblocks - 2)
                {
                    nblocks = 1;
                    Fips202.shake128_squeezeblocks(buf, nblocks, state);
                    pos = 0;
                }
            }
        }
예제 #2
0
        public static void poly_ntt(Poly r)
        {
            double [] temp = new double[NewHope.PARAM_N];

            pwmul_double(r.coeffs, psis_bitrev);
            ntt_double(r.coeffs, omegas_double, temp);
        }
예제 #3
0
 public static void poly_add(Poly r, Poly a, Poly b)
 {
     for (int i = 0; i < NewHope.PARAM_N; i++)
     {
         r.coeffs[i] = a.coeffs[i] + b.coeffs[i] % NewHope.PARAM_Q; /* XXX: Get rid of the % here! */
     }
 }
예제 #4
0
        public static void poly_invntt(Poly r)
        {
            double [] temp = new double[NewHope.PARAM_N];

            bitrev_vector(r.coeffs);
            ntt_double(r.coeffs, omegas_inv_double, temp);
            pwmul_double(r.coeffs, psis_inv);
        }
예제 #5
0
 static void encode_b(byte[] r, Poly b, Poly c)
 {
     Poly.poly_tobytes(r, b);
     for (int i = 0; i < PARAM_N / 4; i++)
     {
         r[POLY_BYTES + i] = c.coeffs[4 * i] | (c.coeffs[4 * i + 1] << 2) | (c.coeffs[4 * i + 2] << 4) | (c.coeffs[4 * i + 3] << 6);
     }
 }
예제 #6
0
 static void decode_a(Poly pk, byte[] seed, byte[] r)
 {
     Poly.poly_frombytes(pk, r);
     for (int i = 0; i < NEWHOPE_SEEDBYTES; i++)
     {
         seed[i] = r[POLY_BYTES + i];
     }
 }
예제 #7
0
 static void encode_a(byte[] r, Poly pk, byte[] seed)
 {
     Poly.poly_tobytes(r, pk);
     for (int i = 0; i < NEWHOPE_SEEDBYTES; i++)
     {
         r[POLY_BYTES + i] = seed[i];
     }
 }
예제 #8
0
 static void decode_b(Poly b, Poly c, byte[] r)
 {
     Poly.poly_frombytes(b, r);
     for (int i = 0; i < PARAM_N / 4; i++)
     {
         c.coeffs[4 * i + 0] = r[POLY_BYTES + i] & 0x03;
         c.coeffs[4 * i + 1] = (r[POLY_BYTES + i] >> 2) & 0x03;
         c.coeffs[4 * i + 2] = (r[POLY_BYTES + i] >> 4) & 0x03;
         c.coeffs[4 * i + 3] = (r[POLY_BYTES + i] >> 6);
     }
 }
예제 #9
0
        public static void poly_frombytes(Poly r, byte[] a)
        {
            int i;

            for (i = 0; i < NewHope.PARAM_N / 4; i++)
            {
                r.coeffs[4 * i + 0] = a[7 * i + 0] | (((ushort)a[7 * i + 1] & 0x3f) << 8);
                r.coeffs[4 * i + 1] = (a[7 * i + 1] >> 6) | (((ushort)a[7 * i + 2]) << 2) | (((ushort)a[7 * i + 3] & 0x0f) << 10);
                r.coeffs[4 * i + 2] = (a[7 * i + 3] >> 4) | (((ushort)a[7 * i + 4]) << 4) | (((ushort)a[7 * i + 5] & 0x03) << 12);
                r.coeffs[4 * i + 3] = (a[7 * i + 5] >> 2) | (((ushort)a[7 * i + 6]) << 6);
            }
        }
예제 #10
0
        public static void poly_getnoise(Poly r, byte [] seed, byte nonce)
        {
            if (NewHope.PARAM_K != 16)
            {
                throw new Exception("poly_getnoise in poly.c only supports k=16");
            }

            byte [] buf = new byte[4 * NewHope.PARAM_N];
            byte[]  n   = new byte[NewHope.CRYPTO_STREAM_NONCEBYTES];

            for (int i = 1; i < NewHope.CRYPTO_STREAM_NONCEBYTES; i++)
            {
                n[i] = 0;
            }
            n[0] = nonce;

            crypto_stream(buf, 4 * NewHope.PARAM_N, n, seed);
            cbd(r, buf);
        }
예제 #11
0
        public static void poly_tobytes(byte [] r, Poly p)
        {
            int    i;
            ushort t0, t1, t2, t3, m;
            ushort c;

            for (i = 0; i < NewHope.PARAM_N / 4; i++)
            {
                t0 = barrett_reduce(p.coeffs[4 * i + 0]); //Make sure that coefficients have only 14 bits
                t1 = barrett_reduce(p.coeffs[4 * i + 1]);
                t2 = barrett_reduce(p.coeffs[4 * i + 2]);
                t3 = barrett_reduce(p.coeffs[4 * i + 3]);

                m   = t0 - NewHope.PARAM_Q;
                c   = m;
                c >>= 15;
                t0  = m ^ ((t0 ^ m) & c); // <Make sure that coefficients are in [0,q]

                m   = t1 - NewHope.PARAM_Q;
                c   = m;
                c >>= 15;
                t1  = m ^ ((t1 ^ m) & c); // <Make sure that coefficients are in [0,q]

                m   = t2 - NewHope.PARAM_Q;
                c   = m;
                c >>= 15;
                t2  = m ^ ((t2 ^ m) & c); // <Make sure that coefficients are in [0,q]

                m   = t3 - NewHope.PARAM_Q;
                c   = m;
                c >>= 15;
                t3  = m ^ ((t3 ^ m) & c); // <Make sure that coefficients are in [0,q]

                r[7 * i + 0] = t0 & 0xff;
                r[7 * i + 1] = (t0 >> (ushort)8) | (t1 << (ushort)6);
                r[7 * i + 2] = (t1 >> 2);
                r[7 * i + 3] = (t1 >> 10) | (t2 << 4);
                r[7 * i + 4] = (t2 >> 4);
                r[7 * i + 5] = (t2 >> 12) | (t3 << 2);
                r[7 * i + 6] = (t3 >> 6);
            }
        }
예제 #12
0
 extern static void cbd(Poly r, byte [] b)
 {
     throw new NotImplementedException();
 }
예제 #13
0
        // API FUNCTIONS

        void newhope_keygen(byte[] send, Poly sk)
        {
            Poly          a, e, r, pk;
            unsigned char seed[NEWHOPE_SEEDBYTES];
예제 #14
0
 static void gen_a(Poly a, byte[] seed)
 {
     Poly.poly_uniform(a, seed);
 }