public new IntegerPolynomial Multiply(IntegerPolynomial poly2, int modulus) { // even on 32-bit systems, LongPolynomial5 multiplies faster than IntegerPolynomial if (modulus == 2048) { IntegerPolynomial poly2Pos = (IntegerPolynomial)poly2.Clone(); poly2Pos.ModPositive(2048); LongPolynomial5 poly5 = new LongPolynomial5(poly2Pos); return(poly5.Multiply(this).ToIntegerPolynomial()); } else { return(base.Multiply(poly2, modulus)); } }
/** * Computes the inverse mod 3. * Returns <code>null</code> if the polynomial is not invertible. * * @return a new polynomial */ public IntegerPolynomial InvertF3() { 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(N + 1); Array.Copy(coeffs, f.coeffs, N); f.ModPositive(3); // 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.EqualsAbsOne()) { 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; } if (f.coeffs[0] == g.coeffs[0]) { f.Sub(g, 3); b.Sub(c, 3); } else { f.Add(g, 3); b.Add(c, 3); } } if (b.coeffs[N] != 0) { return(null); } // Fp(x) = [+-] x^(N-k) * b(x) IntegerPolynomial Fp = new IntegerPolynomial(N); int j = 0; k %= N; for (int i = N - 1; i >= 0; i--) { j = i - k; if (j < 0) { j += N; } Fp.coeffs[j] = f.coeffs[0] * b.coeffs[i]; } Fp.EnsurePositive(3); return(Fp); }
/** * Computes the inverse mod <code>q; q</code> must be a power of 2.<br> * Returns <code>null</code> if the polynomial is not invertible. * * @param q the modulus * @return a new polynomial */ public IntegerPolynomial InvertFq(int q) { 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(N + 1); Array.Copy(coeffs, f.coeffs, N); f.ModPositive(2); // 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, 2); b.Add(c, 2); } 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(Mod2ToModq(Fq, q)); }