Пример #1
0
        public IntegerPolynomial ToIntegerPolynomial()
        {
            IntegerPolynomial i = F1.Multiply(F2.ToIntegerPolynomial());

            i.Add(F3.ToIntegerPolynomial());
            return(i);
        }
Пример #2
0
        public IntegerPolynomial Multiply(IntegerPolynomial poly2, int modulus)
        {
            IntegerPolynomial c = Multiply(poly2);

            c.Mod(modulus);
            return(c);
        }
Пример #3
0
        public IntegerPolynomial Multiply(IntegerPolynomial b)
        {
            IntegerPolynomial c = F1.Multiply(b);

            c = F2.Multiply(c);
            c.Add(F3.Multiply(b));
            return(c);
        }
Пример #4
0
 /**
  * Constructs a <code>BigIntPolynomial</code> from a <code>IntegerPolynomial</code>. The two polynomials are
  * independent of each other.
  *
  * @param p the original polynomial
  */
 public BigIntPolynomial(IntegerPolynomial p)
 {
     coeffs = new BigInteger[p.coeffs.Length];
     for (int i = 0; i < coeffs.Length; i++)
     {
         coeffs[i] = BigInteger.ValueOf(p.coeffs[i]);
     }
 }
Пример #5
0
        /**
         * Computes <code>this-b*c*(x^k) mod p</code> and stores the result in this polynomial.<br/>
         * See steps 4a,4b in EESS algorithm 2.2.7.1.
         *
         * @param b
         * @param c
         * @param k
         * @param p
         */
        private void MultShiftSub(IntegerPolynomial b, int c, int k, int p)
        {
            int N = coeffs.Length;

            for (int i = k; i < N; i++)
            {
                coeffs[i] = (coeffs[i] - b.coeffs[i - k] * c) % p;
            }
        }
Пример #6
0
 /**
  * Subtracts another polynomial which can have a different number of coefficients.
  *
  * @param b another polynomial
  */
 public void Sub(IntegerPolynomial b)
 {
     if (b.coeffs.Length > coeffs.Length)
     {
         Array.Copy(coeffs, coeffs, b.coeffs.Length);
     }
     for (int i = 0; i < b.coeffs.Length; i++)
     {
         coeffs[i] -= b.coeffs[i];
     }
 }
Пример #7
0
 /**
  * Adds another polynomial which can have a different number of coefficients.
  *
  * @param b another polynomial
  */
 public void Add(IntegerPolynomial b)
 {
     if (b.coeffs.Length > coeffs.Length)
     {
         int[] temp = new int[b.coeffs.Length];
         Array.Copy(coeffs, temp, coeffs.Length);
         coeffs = temp;
     }
     for (int i = 0; i < b.coeffs.Length; i++)
     {
         coeffs[i] += b.coeffs[i];
     }
 }
 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));
     }
 }
Пример #9
0
        /**
         * Constructs a <code>LongPolynomial5</code> from a <code>IntegerPolynomial</code>. The two polynomials are independent of each other.
         *
         * @param p the original polynomial. Coefficients must be between 0 and 2047.
         */
        public LongPolynomial5(IntegerPolynomial p)
        {
            numCoeffs = p.coeffs.Length;

            coeffs = new long[(numCoeffs + 4) / 5];
            int cIdx  = 0;
            int shift = 0;

            for (int i = 0; i < numCoeffs; i++)
            {
                coeffs[cIdx] |= ((long)p.coeffs[i]) << shift;
                shift        += 12;
                if (shift >= 60)
                {
                    shift = 0;
                    cIdx++;
                }
            }
        }
Пример #10
0
        public IntegerPolynomial Multiply(IntegerPolynomial poly2)
        {
            int[] b = poly2.coeffs;
            if (b.Length != N)
            {
                throw new InvalidOperationException("Number of coefficients must be the same");
            }

            int[] c = new int[N];
            for (int idx = 0; idx != Ones.Length; idx++)
            {
                int i = Ones[idx];
                int j = N - 1 - i;
                for (int k = N - 1; k >= 0; k--)
                {
                    c[k] += b[j];
                    j--;
                    if (j < 0)
                    {
                        j = N - 1;
                    }
                }
            }

            for (int idx = 0; idx != NegOnes.Length; idx++)
            {
                int i = NegOnes[idx];
                int j = N - 1 - i;
                for (int k = N - 1; k >= 0; k--)
                {
                    c[k] -= b[j];
                    j--;
                    if (j < 0)
                    {
                        j = N - 1;
                    }
                }
            }

            return(new IntegerPolynomial(c));
        }
Пример #11
0
        /**
         * Computes the centered euclidean norm of the polynomial.
         *
         * @param q a modulus
         * @return the centered norm
         */
        public long CenteredNormSq(int q)
        {
            int N = coeffs.Length;
            IntegerPolynomial p = (IntegerPolynomial)Clone();

            p.ShiftGap(q);

            long sum   = 0;
            long sqSum = 0;

            for (int i = 0; i != p.coeffs.Length; i++)
            {
                int c = p.coeffs[i];
                sum   += c;
                sqSum += c * c;
            }

            long centeredNormSq = sqSum - sum * sum / N;

            return(centeredNormSq);
        }
Пример #12
0
        /**
         * Constructs a <code>LongPolynomial2</code> from a <code>IntegerPolynomial</code>. The two polynomials are independent of each other.
         *
         * @param p the original polynomial. Coefficients must be between 0 and 2047.
         */
        public LongPolynomial2(IntegerPolynomial p)
        {
            numCoeffs = p.coeffs.Length;
            coeffs    = new long[(numCoeffs + 1) / 2];
            int idx = 0;

            for (int pIdx = 0; pIdx < numCoeffs;)
            {
                int c0 = p.coeffs[pIdx++];
                while (c0 < 0)
                {
                    c0 += 2048;
                }
                long c1 = pIdx < numCoeffs ? p.coeffs[pIdx++] : 0;
                while (c1 < 0)
                {
                    c1 += 2048;
                }
                coeffs[idx] = c0 + (c1 << 24);
                idx++;
            }
        }
Пример #13
0
        /**
         * Multiplies the polynomial with another, taking the indices mod N
         */
        public IntegerPolynomial Multiply(IntegerPolynomial poly2)
        {
            int N = coeffs.Length;

            if (poly2.coeffs.Length != N)
            {
                throw new InvalidDataException("Number of coefficients must be the same");
            }

            IntegerPolynomial c = MultiplyRecursive(poly2);

            if (c.coeffs.Length > N)
            {
                for (int k = N; k < c.coeffs.Length; k++)
                {
                    c.coeffs[k - N] += c.coeffs[k];
                }
                int[] myCoeffs = new int[N];
                Array.Copy(c.coeffs, myCoeffs, N);
                c.coeffs = myCoeffs;
            }
            return(c);
        }
Пример #14
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);
     }
 }
Пример #15
0
 /**
  * Constructs a <code>DenseTernaryPolynomial</code> from a <code>IntegerPolynomial</code>. The two polynomials are
  * independent of each other.
  *
  * @param intPoly the original polynomial
  */
 public SparseTernaryPolynomial(IntegerPolynomial intPoly) : this(intPoly.coeffs)
 {
 }
Пример #16
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);
            }
        }
Пример #17
0
        /**
         * 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));
        }
Пример #18
0
 /**
  * Subtracts another polynomial which can have a different number of coefficients,
  * and takes the coefficient values mod <code>modulus</code>.
  *
  * @param b another polynomial
  */
 public void Sub(IntegerPolynomial b, int modulus)
 {
     Sub(b);
     Mod(modulus);
 }
Пример #19
0
 /**
  * Adds another polynomial which can have a different number of coefficients,
  * and takes the coefficient values mod <code>modulus</code>.
  *
  * @param b another polynomial
  */
 public void Add(IntegerPolynomial b, int modulus)
 {
     Add(b);
     Mod(modulus);
 }
Пример #20
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);
        }
Пример #21
0
        /**
         * Multithreaded version of {@link #resultant()}.
         *
         * @return <code>(rho, res)</code> satisfying <code>res = rho*this + t*(x^n-1)</code> for some integer <code>t</code>.
         */
        /* Taking out Async for now, harder problem than just translating.
         * public async Task<Resultant> ResultantMultiThread()
         * {
         *      int N = coeffs.Length;
         *
         *      // upper bound for resultant(f, g) = ||f, 2||^deg(g) * ||g, 2||^deg(f) = squaresum(f)^(N/2) * 2^(deg(f)/2) because g(x)=x^N-1
         *      // see http://jondalon.mathematik.uni-osnabrueck.de/staff/phpages/brunsw/CompAlg.pdf chapter 3
         *      BigInteger max = squareSum().pow((N + 1) / 2);
         *      max = max.multiply(BigInteger.ValueOf(2).pow((degree() + 1) / 2));
         *      BigInteger max2 = max.multiply(BigInteger.ValueOf(2));
         *
         *      // compute resultants modulo prime numbers
         *      BigInteger prime = BigInteger.ValueOf(10000);
         *      BigInteger pProd = Constants.BIGINT_ONE;
         *      LinkedBlockingQueue<Task<ModularResultant>> resultantTasks = new LinkedBlockingQueue<Task<ModularResultant>>();
         *      Iterator<BigInteger> primes = BIGINT_PRIMES.Iterator();
         *      ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
         *      while (pProd.CompareTo(max2) < 0)
         *      {
         *              if (primes.hasNext())
         *              {
         *                      prime = primes.next();
         *              }
         *              else
         *              {
         *                      prime = prime.NextProbablePrime();
         *              }
         *              Task<ModularResultant> task = executor.submit(new ModResultantTask(prime.IntValue));
         *              resultantTasks.add(task);
         *              pProd = pProd.Multiply(prime);
         *      }
         *
         *      // Combine modular resultants to obtain the resultant.
         *      // For efficiency, first combine all pairs of small resultants to bigger resultants,
         *      // then combine pairs of those, etc. until only one is left.
         *      ModularResultant overallResultant = null;
         *      while (!resultantTasks.isEmpty())
         *      {
         *              try
         *              {
         *                      Task<ModularResultant> modRes1 = resultantTasks.take();
         *                      Task<ModularResultant> modRes2 = resultantTasks.poll();
         *                      if (modRes2 == null)
         *                      {
         *                              // modRes1 is the only one left
         *                              overallResultant = await modRes1; //modRes1..get();
         *                              break;
         *                      }
         *                      Task<ModularResultant> newTask = executor.submit(new CombineTask(modRes1.get(), modRes2.get()));
         *                      resultantTasks.add(newTask);
         *              }
         *              catch (Exception e)
         *              {
         *                      throw new InvalidOperationException(e.ToString());
         *              }
         *      }
         *      executor.shutdown();
         *      BigInteger res = overallResultant.res;
         *      BigIntPolynomial rhoP = overallResultant.rho;
         *
         *      BigInteger pProd2 = pProd.divide(BigInteger.ValueOf(2));
         *      BigInteger pProd2n = pProd2.negate();
         *
         *      if (res.compareTo(pProd2) > 0)
         *      {
         *              res = res.subtract(pProd);
         *      }
         *      if (res.compareTo(pProd2n) < 0)
         *      {
         *              res = res.add(pProd);
         *      }
         *
         *      for (int i = 0; i < N; i++)
         *      {
         *              BigInteger c = rhoP.coeffs[i];
         *              if (c.compareTo(pProd2) > 0)
         *              {
         *                      rhoP.coeffs[i] = c.subtract(pProd);
         *              }
         *              if (c.compareTo(pProd2n) < 0)
         *              {
         *                      rhoP.coeffs[i] = c.add(pProd);
         *              }
         *      }
         *
         *      return new Resultant(rhoP, res);
         * }
         */
        /**
         * Resultant of this polynomial with <code>x^n-1 mod p</code>.
         *
         * @return <code>(rho, res)</code> satisfying <code>res = rho*this + t*(x^n-1) mod p</code> for some integer <code>t</code>.
         */
        public ModularResultant Resultant(int p)
        {
            // Add a coefficient as the following operations involve polynomials of degree deg(f)+1
            int[] fcoeffs = new int[coeffs.Length + 1];
            Array.Copy(coeffs, fcoeffs, coeffs.Length);
            IntegerPolynomial f = new IntegerPolynomial(fcoeffs);
            int N = fcoeffs.Length;

            IntegerPolynomial a = new IntegerPolynomial(N);

            a.coeffs[0]     = -1;
            a.coeffs[N - 1] = 1;
            IntegerPolynomial b  = new IntegerPolynomial(f.coeffs);
            IntegerPolynomial v1 = new IntegerPolynomial(N);
            IntegerPolynomial v2 = new IntegerPolynomial(N);

            v2.coeffs[0] = 1;
            int da = N - 1;
            int db = b.Degree();
            int ta = da;
            int c  = 0;
            int r  = 1;

            while (db > 0)
            {
                c = Util.Util.Invert(b.coeffs[db], p);
                c = (c * a.coeffs[da]) % p;
                a.MultShiftSub(b, c, da - db, p);
                v1.MultShiftSub(v2, c, da - db, p);

                da = a.Degree();
                if (da < db)
                {
                    r *= Util.Util.Pow(b.coeffs[db], ta - da, p);
                    r %= p;
                    if (ta % 2 == 1 && db % 2 == 1)
                    {
                        r = (-r) % p;
                    }
                    IntegerPolynomial temp = a;
                    a = b;
                    b = temp;
                    int tempdeg = da;
                    da   = db;
                    temp = v1;
                    v1   = v2;
                    v2   = temp;
                    ta   = db;
                    db   = tempdeg;
                }
            }
            r *= Util.Util.Pow(b.coeffs[0], da, p);
            r %= p;
            c  = Util.Util.Invert(b.coeffs[0], p);
            v2.Multiply(c);
            v2.Mod(p);
            v2.Multiply(r);
            v2.Mod(p);

            // drop the highest coefficient so #coeffs matches the original input
            int[] newCoeffs = new int[v2.coeffs.Length - 1];
            Array.Copy(v2.coeffs, newCoeffs, v2.coeffs.Length - 1);
            v2.coeffs = newCoeffs;
            return(new ModularResultant(new BigIntPolynomial(v2), BigInteger.ValueOf(r), BigInteger.ValueOf(p)));
        }