private void DivTest() { Random rng = new Random(); for (int i = 0; i < 10; i++) { IntegerPolynomial poly = (IntegerPolynomial)PolynomialGeneratorForTesting.GenerateRandom(439, 10000); // test special case: division by 2048 IntegerPolynomial a = poly.Clone(); a.Divide(2048); for (int j = 0; j < poly.Coeffs.Length; j++) { if (!Compare.Equals((int)Math.Floor((((double)poly.Coeffs[j]) / 2048) + 0.5), a.Coeffs[j])) { throw new Exception("IntegerPolynomialTest division test failed!"); } } // test the general case a = poly.Clone(); int k = rng.Next(2047) + 1; a.Divide(k); for (int j = 0; j < poly.Coeffs.Length; j++) { if (!Compare.Equals((int)Math.Floor(((double)poly.Coeffs[j] / k) + 0.5), a.Coeffs[j])) { throw new Exception("IntegerPolynomialTest division test failed!"); } } } }
private void AddTest() { NTRUParameters param = NTRUParamSets.EES1087EP2; IntegerPolynomial a = PolynomialGeneratorForTesting.GenerateRandom(param.N, param.Q); ITernaryPolynomial b = PolynomialGeneratorForTesting.generateRandom(1087); IntegerPolynomial c1 = a.Clone(); c1.Add(b.ToIntegerPolynomial()); IntegerPolynomial c2 = a.Clone(); c2.Add(b); if (!Compare.Equals(c1, c2)) { throw new Exception("IntegerPolynomialTest addition test failed!"); } }
/** * Implementation of the optional steps 20 through 26 in EESS1v2.pdf, section 3.5.1.1. * This doesn't seem to have much of an effect and sometimes actually increases the * norm of F, but on average it slightly reduces the norm.<br/> * This method changes <code>F</code> and <code>G</code> but leaves <code>f</code> and * <code>g</code> unchanged. * @param f * @param g * @param F * @param G * @param N */ private void minimizeFG(IntegerPolynomial f, IntegerPolynomial g, IntegerPolynomial F, IntegerPolynomial G, int N) { int E = 0; for (int j = 0; j < N; j++) { E += 2 * N * (f.Coeffs[j] * f.Coeffs[j] + g.Coeffs[j] * g.Coeffs[j]); } // [f(1)+g(1)]^2 = 4 E -= 4; IntegerPolynomial u = f.Clone(); IntegerPolynomial v = g.Clone(); int j2 = 0; int k = 0; int maxAdjustment = N; while (k < maxAdjustment && j2 < N) { int D = 0; int i = 0; while (i < N) { int D1 = F.Coeffs[i] * f.Coeffs[i]; int D2 = G.Coeffs[i] * g.Coeffs[i]; int D3 = 4 * N * (D1 + D2); D += D3; i++; } // f(1)+g(1) = 2 int D4 = 4 * (F.SumCoeffs() + G.SumCoeffs()); D -= D4; if (D > E) { F.Subtract(u); G.Subtract(v); k++; j2 = 0; } else if (D < -E) { F.Add(u); G.Add(v); k++; j2 = 0; } j2++; u.Rotate1(); v.Rotate1(); } }
/// <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)); } }
/** * Implementation of the optional steps 20 through 26 in EESS1v2.pdf, section 3.5.1.1. * This doesn't seem to have much of an effect and sometimes actually increases the * norm of F, but on average it slightly reduces the norm.<br/> * This method changes <code>F</code> and <code>G</code> but leaves <code>f</code> and * <code>g</code> unchanged. * @param f * @param g * @param F * @param G * @param N */ private void minimizeFG(IntegerPolynomial f, IntegerPolynomial g, IntegerPolynomial F, IntegerPolynomial G, int N) { int E = 0; for (int j = 0; j < N; j++) E += 2 * N * (f.Coeffs[j] * f.Coeffs[j] + g.Coeffs[j] * g.Coeffs[j]); // [f(1)+g(1)]^2 = 4 E -= 4; IntegerPolynomial u = f.Clone(); IntegerPolynomial v = g.Clone(); int j2 = 0; int k = 0; int maxAdjustment = N; while (k < maxAdjustment && j2 < N) { int D = 0; int i = 0; while (i < N) { int D1 = F.Coeffs[i] * f.Coeffs[i]; int D2 = G.Coeffs[i] * g.Coeffs[i]; int D3 = 4 * N * (D1 + D2); D += D3; i++; } // f(1)+g(1) = 2 int D4 = 4 * (F.SumCoeffs() + G.SumCoeffs()); D -= D4; if (D > E) { F.Subtract(u); G.Subtract(v); k++; j2 = 0; } else if (D < -E) { F.Add(u); G.Add(v); k++; j2 = 0; } j2++; u.Rotate1(); v.Rotate1(); } }