private void MultTest()
        {
            IntegerPolynomial i1 = new IntegerPolynomial(new int[] { 1368, 2047, 672, 871, 1662, 1352, 1099, 1608 });
            IntegerPolynomial i2 = new IntegerPolynomial(new int[] { 1729, 1924, 806, 179, 1530, 1381, 1695, 60 });
            LongPolynomial2 a = new LongPolynomial2(i1);
            LongPolynomial2 b = new LongPolynomial2(i2);
            IntegerPolynomial c1 = i1.Multiply(i2, 2048);
            IntegerPolynomial c2 = a.Multiply(b).ToIntegerPolynomial();

            if (!Compare.AreEqual(c1.Coeffs, c2.Coeffs))
                throw new Exception("LongPolynomial2 multiply test failed!");

            // test 10 random polynomials
            Random rng = new Random();
            for (int i = 0; i < 10; i++)
            {
                int N = 2 + rng.Next(2000);
                i1 = (IntegerPolynomial)PolynomialGeneratorForTesting.GenerateRandom(N, 2048);
                i2 = (IntegerPolynomial)PolynomialGeneratorForTesting.GenerateRandom(N, 2048);
                a = new LongPolynomial2(i1);
                b = new LongPolynomial2(i2);
                c1 = i1.Multiply(i2);
                c1.ModPositive(2048);
                c2 = a.Multiply(b).ToIntegerPolynomial();

                if (!Compare.AreEqual(c1.Coeffs, c2.Coeffs))
                    throw new Exception("LongPolynomial2 multiply test failed!");
            }
        }
 /// <summary>
 /// Computes the inverse mod <c>q</c> from the inverse mod 2.
 /// <para>The algorithm is described in <a href="http://www.securityinnovation.com/uploads/Crypto/NTRUTech014.pdf">
 /// Almost Inverses and Fast NTRU Key Generation</a>.</para>
 /// </summary>
 /// 
 /// <param name="Fq">Fq value</param>
 /// <param name="Q">Q value</param>
 /// 
 /// <returns>The inverse of this polynomial mod q</returns>
 private IntegerPolynomial Mod2ToModq(IntegerPolynomial Fq, int Q)
 {
     if (SystemUtils.Is64Bit() && Q == 2048)
     {
         LongPolynomial2 thisLong = new LongPolynomial2(this);
         LongPolynomial2 FqLong = new LongPolynomial2(Fq);
         int v = 2;
         while (v < Q)
         {
             v *= 2;
             LongPolynomial2 temp = FqLong.Clone();
             temp.Mult2And(v - 1);
             FqLong = thisLong.Multiply(FqLong).Multiply(FqLong);
             temp.SubAnd(FqLong, v - 1);
             FqLong = temp;
         }
         return FqLong.ToIntegerPolynomial();
     }
     else
     {
         int v = 2;
         while (v < Q)
         {
             v *= 2;
             IntegerPolynomial temp = Fq.Clone();
             temp.Mult2(v);
             Fq = Multiply(Fq, v).Multiply(Fq, v);
             temp.Subtract(Fq, v);
             Fq = temp;
         }
         return Fq;
     }
 }