コード例 #1
0
 /**
  * Computes the inverse mod q from the inverse mod 2
  *
  * @param Fq
  * @param q
  * @return The inverse of this polynomial mod q
  */
 private IntegerPolynomial Mod2ToModq(IntegerPolynomial Fq, int q)
 {
     //if (Util.is64BitJVM() && q == 2048)
     if (true && q == 2048)
     {
         LongPolynomial2 thisLong = new LongPolynomial2(this);
         LongPolynomial2 FqLong   = new LongPolynomial2(Fq);
         int             v        = 2;
         while (v < q)
         {
             v *= 2;
             LongPolynomial2 temp = (LongPolynomial2)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;
             int[] copy = new int[Fq.coeffs.Length];
             Array.Copy(Fq.coeffs, copy, Fq.coeffs.Length);
             IntegerPolynomial temp = new IntegerPolynomial(copy);
             temp.Multiply2(v);
             Fq = Multiply(Fq, v).Multiply(Fq, v);
             temp.Sub(Fq, v);
             Fq = temp;
         }
         return(Fq);
     }
 }
コード例 #2
0
        /**
         * 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);
        }
コード例 #3
0
        /**
         * Karazuba multiplication
         */
        private IntegerPolynomial MultiplyRecursive(IntegerPolynomial poly2)
        {
            int[] a = coeffs;
            int[] b = poly2.coeffs;

            int n = poly2.coeffs.Length;

            if (n <= 32)
            {
                int cn = 2 * n - 1;
                IntegerPolynomial c = new IntegerPolynomial(new int[cn]);
                for (int k = 0; k < cn; k++)
                {
                    for (int i = System.Math.Max(0, k - n + 1); i <= System.Math.Min(k, n - 1); i++)
                    {
                        c.coeffs[k] += b[i] * a[k - i];
                    }
                }
                return(c);
            }
            else
            {
                int   n1     = n / 2;
                int[] a1temp = new int[n1];
                int[] a2temp = new int[n - n1];
                int[] b1temp = new int[n1];
                int[] b2temp = new int[n - n1];

                Array.Copy(a, a1temp, n1);
                Array.Copy(a, n1, a2temp, 0, n - n1);
                Array.Copy(b, b1temp, n1);
                Array.Copy(b, n1, b2temp, 0, n - n1);
                IntegerPolynomial a1 = new IntegerPolynomial(a1temp);
                IntegerPolynomial a2 = new IntegerPolynomial(a2temp);
                IntegerPolynomial b1 = new IntegerPolynomial(b1temp);
                IntegerPolynomial b2 = new IntegerPolynomial(b2temp);

                IntegerPolynomial A = (IntegerPolynomial)a1.Clone();
                A.Add(a2);
                IntegerPolynomial B = (IntegerPolynomial)b1.Clone();
                B.Add(b2);

                IntegerPolynomial c1 = a1.MultiplyRecursive(b1);
                IntegerPolynomial c2 = a2.MultiplyRecursive(b2);
                IntegerPolynomial c3 = A.MultiplyRecursive(B);
                c3.Sub(c1);
                c3.Sub(c2);

                IntegerPolynomial c = new IntegerPolynomial(2 * n - 1);
                for (int i = 0; i < c1.coeffs.Length; i++)
                {
                    c.coeffs[i] = c1.coeffs[i];
                }
                for (int i = 0; i < c3.coeffs.Length; i++)
                {
                    c.coeffs[n1 + i] += c3.coeffs[i];
                }
                for (int i = 0; i < c2.coeffs.Length; i++)
                {
                    c.coeffs[2 * n1 + i] += c2.coeffs[i];
                }
                return(c);
            }
        }