/// <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; } }
/// <summary> /// Multiplies the polynomial with another, taking the values mod modulus and the indices mod N /// </summary> /// /// <param name="Factor">The polynomial factor</param> /// <param name="Modulus">The Modulus</param> /// /// <returns>Multiplied polynomial</returns> public IntegerPolynomial Multiply(IntegerPolynomial Factor, int Modulus) { // even on 32-bit systems, LongPolynomial5 multiplies faster than IntegerPolynomial if (Modulus == 2048) { IntegerPolynomial poly2Pos = Factor.Clone(); poly2Pos.ModPositive(2048); LongPolynomial5 poly5 = new LongPolynomial5(poly2Pos); return poly5.Multiply(this).ToIntegerPolynomial(); } else { return base.Multiply(Factor, Modulus); } }