/// <summary> /// Test the validity of the BigDecimalPolynomial implementation /// </summary> /// /// <returns>State</returns> public string Test() { try { BigDecimalPolynomial a = CreateBigDecimalPolynomial(new int[] { 4, -1, 9, 2, 1, -5, 12, -7, 0, -9, 5 }); BigIntPolynomial b = new BigIntPolynomial(new IntegerPolynomial(new int[] { -6, 0, 0, 13, 3, -2, -4, 10, 11, 2, -1 })); BigDecimalPolynomial c = a.Multiply(b); if(!Compare.AreEqual(c.Coeffs, CreateBigDecimalPolynomial(new int[] { 2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34 }).Coeffs)) throw new Exception("The BigDecimalPolynomial test failed!"); // multiply a polynomial by its inverse modulo 2048 and check that the result is 1 IntegerPolynomial d, dInv; CSPRng rng = new CSPRng(); do { d = DenseTernaryPolynomial.GenerateRandom(1001, 333, 334, rng); dInv = d.InvertFq(2048); } while (dInv == null); d.Mod(2048); BigDecimalPolynomial e = CreateBigDecimalPolynomial(d.Coeffs); BigIntPolynomial f = new BigIntPolynomial(dInv); IntegerPolynomial g = new IntegerPolynomial(e.Multiply(f).Round()); g.ModPositive(2048); if (!g.EqualsOne()) throw new Exception("The BigDecimalPolynomial test failed!"); OnProgress(new TestEventArgs("Passed BigDecimalPolynomial tests")); return SUCCESS; } catch (Exception Ex) { string message = Ex.Message == null ? "" : Ex.Message; throw new Exception(FAILURE + message); } }
/// <summary> /// Computes 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> /// /// <returns>Returns <c>null</c> if the polynomial is not invertible.</returns> private IntegerPolynomial InvertF2() { int N = Coeffs.Length; int k = 0; IntegerPolynomial b = new IntegerPolynomial(N + 1); b.Coeffs[0] = 1; IntegerPolynomial c = new IntegerPolynomial(N + 1); IntegerPolynomial f = new IntegerPolynomial(Coeffs.CopyOf(N + 1)); f.Mod2(); // set g(x) = x^N − 1 IntegerPolynomial g = new IntegerPolynomial(N + 1); g.Coeffs[0] = 1; g.Coeffs[N] = 1; while (true) { while (f.Coeffs[0] == 0) { for (int i = 1; i <= N; i++) { f.Coeffs[i - 1] = f.Coeffs[i]; // f(x) = f(x) / x c.Coeffs[N + 1 - i] = c.Coeffs[N - i]; // c(x) = c(x) * x } f.Coeffs[N] = 0; c.Coeffs[0] = 0; k++; if (f.EqualsZero()) return null; // not invertible } if (f.EqualsOne()) break; if (f.Degree() < g.Degree()) { // exchange f and g IntegerPolynomial temp = f; f = g; g = temp; // exchange b and c temp = b; b = c; c = temp; } f.Add(g); f.Mod2(); b.Add(c); b.Mod2(); } if (b.Coeffs[N] != 0) return null; // Fq(x) = x^(N-k) * b(x) IntegerPolynomial Fq = new IntegerPolynomial(N); int j = 0; k %= N; for (int i = N - 1; i >= 0; i--) { j = i - k; if (j < 0) j += N; Fq.Coeffs[j] = b.Coeffs[i]; } return Fq; }