Example #1
0
        /**
         * Multiplies the polynomial by another, taking the indices mod N. Does not
         * change this polynomial but returns the result as a new polynomial.<br>
         * Both polynomials must have the same number of coefficients.
         *
         * @param poly2 the polynomial to multiply by
         * @return a new polynomial
         */
        public BigIntPolynomial Multiply(BigIntPolynomial poly2)
        {
            int N = coeffs.Length;

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

            BigIntPolynomial c = MultiplyRecursive(poly2);

            if (c.coeffs.Length > N)
            {
                for (int k = N; k < c.coeffs.Length; k++)
                {
                    c.coeffs[k - N] = c.coeffs[k - N].Add(c.coeffs[k]);
                }

                // Shortening the Array
                BigInteger[] temp = new BigInteger[N];
                Array.Copy(c.coeffs, temp, N);
                c.coeffs = temp;
            }
            return(c);
        }
Example #2
0
        /**
         * Generates a random polynomial with <code>numOnes</code> coefficients equal to 1,
         * <code>numNegOnes</code> coefficients equal to -1, and the rest equal to 0.
         *
         * @param N          number of coefficients
         * @param numOnes    number of 1's
         * @param numNegOnes number of -1's
         * @return a random polynomial.
         */
        static BigIntPolynomial GenerateRandomSmall(int N, int numOnes, int numNegOnes)
        {
            List <BigInteger> coeffs = new List <BigInteger>();

            for (int i = 0; i < numOnes; i++)
            {
                coeffs.Add(BigInteger.ValueOf(1));
            }
            for (int i = 0; i < numNegOnes; i++)
            {
                coeffs.Add(BigInteger.ValueOf(-1));
            }
            while (coeffs.Count < N)
            {
                coeffs.Add(BigInteger.ValueOf(0));
            }

            Shuffle(coeffs, CryptoServicesRegistrar.GetSecureRandom());

            BigIntPolynomial poly = new BigIntPolynomial(N);

            for (int i = 0; i < coeffs.Count; i++)
            {
                poly.coeffs[i] = (BigInteger)coeffs[i];
            }
            return(poly);
        }
Example #3
0
 /**
  * Constructs a <code>IntegerPolynomial</code> from a <code>BigIntPolynomial</code>. The two polynomials are independent of each other.
  *
  * @param p the original polynomial
  */
 public IntegerPolynomial(BigIntPolynomial p)
 {
     coeffs = new int[p.coeffs.Length];
     for (int i = 0; i < p.coeffs.Length; i++)
     {
         coeffs[i] = p.coeffs[i].IntValue;
     }
 }
Example #4
0
        public BigIntPolynomial Multiply(BigIntPolynomial b)
        {
            BigIntPolynomial c = F1.Multiply(b);

            c = F2.Multiply(c);
            c.Add(F3.Multiply(b));
            return(c);
        }
        /**
         * Constructs a <code>BigDecimalPolynomial</code> from a <code>BigIntPolynomial</code>. The two polynomials are independent of each other.
         *
         * @param p the original polynomial
         */
        public BigDecimalPolynomial(BigIntPolynomial p)
        {
            int N = p.coeffs.Length;

            coeffs = new decimal[N];
            for (int i = 0; i < N; i++)
            {
                coeffs[i] = new decimal(p.coeffs[i].IntValue);
            }
        }
        /**
         * Rounds all coefficients to the nearest integer.
         *
         * @return a new polynomial with <code>BigInteger</code> coefficients
         */
        public BigIntPolynomial round()
        {
            int N = coeffs.Length;
            BigIntPolynomial p = new BigIntPolynomial(N);

            for (int i = 0; i < N; i++)
            {
                p.coeffs[i] = new BigInteger(decimal.Round(coeffs[i], 0, MidpointRounding.AwayFromZero).ToString());                 //BigDecimal.ROUND_HALF_EVEN).toBigInteger();
            }
            return(p);
        }
Example #7
0
 /**
  * Subtracts another polynomial which can have a different number of coefficients.
  *
  * @param b another polynomial
  */
 public void Sub(BigIntPolynomial b)
 {
     if (b.coeffs.Length > coeffs.Length)
     {
         int N = coeffs.Length;
         Array.Copy(coeffs, coeffs, b.coeffs.Length);
         for (int i = N; i < coeffs.Length; i++)
         {
             coeffs[i] = BigInteger.ValueOf(0);
         }
     }
     for (int i = 0; i < b.coeffs.Length; i++)
     {
         coeffs[i] = coeffs[i].Subtract(b.coeffs[i]);
     }
 }
Example #8
0
        public BigIntPolynomial Multiply(BigIntPolynomial poly2)
        {
            BigInteger[] b = poly2.coeffs;
            if (b.Length != N)
            {
                throw new InvalidOperationException("Number of coefficients must be the same");
            }

            BigInteger[] c = new BigInteger[N];
            for (int i = 0; i < N; i++)
            {
                c[i] = BigInteger.Zero;
            }

            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] = c[k].Add(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] = c[k].Subtract(b[j]);
                    j--;
                    if (j < 0)
                    {
                        j = N - 1;
                    }
                }
            }

            return(new BigIntPolynomial(c));
        }
Example #9
0
 /**
  * Adds another polynomial which can have a different number of coefficients.
  *
  * @param b another polynomial
  */
 public void Add(BigIntPolynomial b)
 {
     if (b.coeffs.Length > coeffs.Length)
     {
         int          N    = coeffs.Length;
         BigInteger[] temp = new BigInteger[b.coeffs.Length];
         Array.Copy(coeffs, temp, coeffs.Length);
         coeffs = temp;
         for (int i = N; i < coeffs.Length; i++)
         {
             coeffs[i] = BigInteger.ValueOf(0);
         }
     }
     for (int i = 0; i < b.coeffs.Length; i++)
     {
         // b.coeffs[i] and coeffs[i] should never be null. If they are, somethings wrong.
         coeffs[i] = coeffs[i].Add(b.coeffs[i]);
     }
 }
        /**
         * Calculates a <code>rho</code> modulo <code>m1*m2</code> from
         * two resultants whose <code>rho</code>s are modulo <code>m1</code> and <code>m2</code>.<br/>
         * </code>res</code> is set to <code>null</code>.
         *
         * @param modRes1
         * @param modRes2
         * @return <code>rho</code> modulo <code>modRes1.modulus * modRes2.modulus</code>, and <code>null</code> for </code>res</code>.
         */
        public static ModularResultant CombineRho(ModularResultant modRes1, ModularResultant modRes2)
        {
            BigInteger      mod1 = modRes1.modulus;
            BigInteger      mod2 = modRes2.modulus;
            BigInteger      prod = mod1.Multiply(mod2);
            BigIntEuclidean er   = BigIntEuclidean.Calculate(mod2, mod1);

            BigIntPolynomial rho1 = (BigIntPolynomial)modRes1.Rho.Clone();

            rho1.Multiply(er.x.Multiply(mod2));

            BigIntPolynomial rho2 = (BigIntPolynomial)modRes2.Rho.Clone();

            rho2.Multiply(er.y.Multiply(mod1));

            rho1.Add(rho2);
            rho1.Mod(prod);

            return(new ModularResultant(rho1, null, prod));
        }
Example #11
0
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return(true);
            }
            if (obj == null)
            {
                return(false);
            }
            if (GetType() != obj.GetType())
            {
                return(false);
            }
            BigIntPolynomial other = (BigIntPolynomial)obj;

            if (!Array.Equals(coeffs, other.coeffs))
            {
                return(false);
            }
            return(true);
        }
Example #12
0
 public Resultant(BigIntPolynomial rho, BigInteger res)
 {
     Rho = rho;
     Res = res;
 }
Example #13
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
  */
 void Add(BigIntPolynomial b, BigInteger modulus)
 {
     Add(b);
     Mod(modulus);
 }
Example #14
0
        /**
         * Karazuba multiplication
         */
        private BigIntPolynomial MultiplyRecursive(BigIntPolynomial poly2)
        {
            BigInteger[] a = coeffs;
            BigInteger[] b = poly2.coeffs;

            int n = poly2.coeffs.Length;

            if (n <= 1)
            {
                BigInteger[] c = new BigInteger[coeffs.Length];
                Array.Copy(coeffs, c, coeffs.Length);
                for (int i = 0; i < coeffs.Length; i++)
                {
                    c[i] = c[i].Multiply(poly2.coeffs[0]);
                }
                return(new BigIntPolynomial(c));
            }
            else
            {
                int n1 = n / 2;

                // TODO: Double Check Conversion (Don't worry too much, it'll explode if wrong)... It Exploded
                BigInteger[] a1temp = new BigInteger[n1];
                BigInteger[] a2temp = new BigInteger[n - n1];
                BigInteger[] b1temp = new BigInteger[n1];
                BigInteger[] b2temp = new BigInteger[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);

                BigIntPolynomial a1 = new BigIntPolynomial(a1temp);
                BigIntPolynomial a2 = new BigIntPolynomial(a2temp);
                BigIntPolynomial b1 = new BigIntPolynomial(b1temp);
                BigIntPolynomial b2 = new BigIntPolynomial(b2temp);

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

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

                BigIntPolynomial c = new BigIntPolynomial(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] = c.coeffs[n1 + i].Add(c3.coeffs[i]);
                }
                for (int i = 0; i < c2.coeffs.Length; i++)
                {
                    c.coeffs[2 * n1 + i] = c.coeffs[2 * n1 + i].Add(c2.coeffs[i]);
                }
                return(c);
            }
        }
Example #15
0
 public BigIntPolynomial Multiply(BigIntPolynomial poly2)
 {
     return(new BigIntPolynomial(this).Multiply(poly2));
 }
 /**
  * Multiplies the polynomial by another. Does not change this polynomial
  * but returns the result as a new polynomial.
  *
  * @param poly2 the polynomial to multiply by
  * @return a new polynomial
  */
 public BigDecimalPolynomial Multiply(BigIntPolynomial poly2)
 {
     return(Multiply(new BigDecimalPolynomial(poly2)));
 }
Example #17
0
        /**
         * Resultant of this polynomial with <code>x^n-1</code> using a probabilistic algorithm.
         * <p>
         * Unlike EESS, this implementation does not compute all resultants modulo primes
         * such that their product exceeds the maximum possible resultant, but rather stops
         * when <code>NUM_EQUAL_RESULTANTS</code> consecutive modular resultants are equal.<br>
         * This means the return value may be incorrect. Experiments show this happens in
         * about 1 out of 100 cases when <code>N=439</code> and <code>NUM_EQUAL_RESULTANTS=2</code>,
         * so the likelyhood of leaving the loop too early is <code>(1/100)^(NUM_EQUAL_RESULTANTS-1)</code>.
         * <p>
         * Because of the above, callers must verify the output and try a different polynomial if necessary.
         *
         * @return <code>(rho, res)</code> satisfying <code>res = rho*this + t*(x^n-1)</code> for some integer <code>t</code>.
         */
        public Resultant Resultant()
        {
            int N = coeffs.Length;

            // Compute resultants modulo prime numbers. Continue until NUM_EQUAL_RESULTANTS consecutive modular resultants are equal.
            LinkedList <ModularResultant> modResultants = new LinkedList <ModularResultant>();
            BigInteger pProd    = Constants.BIGINT_ONE;
            BigInteger res      = Constants.BIGINT_ONE;
            int        numEqual = 1;        // number of consecutive modular resultants equal to each other

            PrimeGenerator primes = new PrimeGenerator();
            BigInteger     pProd2;
            BigInteger     pProd2n;

            while (true)
            {
                BigInteger       prime = primes.nextPrime();
                ModularResultant crr   = Resultant(prime.IntValue);
                modResultants.AddLast(crr);                 //Was just add in Java

                BigInteger      temp    = pProd.Multiply(prime);
                BigIntEuclidean er      = BigIntEuclidean.Calculate(prime, pProd);
                BigInteger      resPrev = res;
                res = res.Multiply(er.x.Multiply(prime));
                BigInteger res2 = crr.Res.Multiply(er.y.Multiply(pProd));
                res   = res.Add(res2).Mod(temp);
                pProd = temp;

                pProd2  = pProd.Divide(BigInteger.ValueOf(2));
                pProd2n = pProd2.Negate();
                if (res.CompareTo(pProd2) > 0)
                {
                    res = res.Subtract(pProd);
                }
                else if (res.CompareTo(pProd2n) < 0)
                {
                    res = res.Add(pProd);
                }

                if (res.Equals(resPrev))
                {
                    numEqual++;
                    if (numEqual >= NUM_EQUAL_RESULTANTS)
                    {
                        break;
                    }
                }
                else
                {
                    numEqual = 1;
                }
            }

            // Combine modular rho's to obtain the final rho.
            // For efficiency, first combine all pairs of small resultants to bigger resultants,
            // then combine pairs of those, etc. until only one is left.
            while (modResultants.Count > 1)
            {
                ModularResultant modRes1 = modResultants.First.Value;
                modResultants.RemoveFirst();
                ModularResultant modRes2 = modResultants.First.Value;
                modResultants.RemoveFirst();
                ModularResultant modRes3 = ModularResultant.CombineRho(modRes1, modRes2);
                modResultants.AddLast(modRes3);
            }
            BigIntPolynomial rhoP = modResultants.First.Value.Rho;

            pProd2  = pProd.Divide(BigInteger.ValueOf(2));
            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));
        }
 public ModularResultant(BigIntPolynomial rho, BigInteger res, BigInteger modulus) : base(rho, res)
 {
     this.modulus = modulus;
 }