예제 #1
0
        public object Clone()
        {
            LongPolynomial2 p = new LongPolynomial2((long[])coeffs.Clone());

            p.numCoeffs = numCoeffs;
            return(p);
        }
예제 #2
0
        /**
         * Subtracts another polynomial which must have the same number of coefficients,
         * and applies an AND mask to the upper and lower halves of each coefficients.
         *
         * @param b    another polynomial
         * @param mask a bit mask less than 2048 to apply to each 11-bit coefficient
         */
        public void SubAnd(LongPolynomial2 b, int mask)
        {
            long longMask = (((long)mask) << 24) + mask;

            for (int i = 0; i < b.coeffs.Length; i++)
            {
                coeffs[i] = (0x0800000800000L + coeffs[i] - b.coeffs[i]) & longMask;
            }
        }
예제 #3
0
 /**
  * Subtracts another polynomial which can have a different number of coefficients.
  *
  * @param b another polynomial
  */
 private void Sub(LongPolynomial2 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] = (0x0800000800000L + coeffs[i] - b.coeffs[i]) & 0x7FF0007FFL;
     }
 }
예제 #4
0
 /**
  * Adds another polynomial which can have a different number of coefficients.
  *
  * @param b another polynomial
  */
 private void Add(LongPolynomial2 b)
 {
     if (b.coeffs.Length > coeffs.Length)
     {
         long[] temp = new long[b.coeffs.Length];
         Array.Copy(coeffs, temp, coeffs.Length);
         coeffs = temp;
     }
     for (int i = 0; i < b.coeffs.Length; i++)
     {
         coeffs[i] = (coeffs[i] + b.coeffs[i]) & 0x7FF0007FFL;
     }
 }
예제 #5
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);
     }
 }
예제 #6
0
        /**
         * Karazuba multiplication
         */
        private LongPolynomial2 MultiplyRecursive(LongPolynomial2 poly2)
        {
            long[] a = coeffs;
            long[] b = poly2.coeffs;

            int n = poly2.coeffs.Length;

            if (n <= 32)
            {
                int             cn = 2 * n;
                LongPolynomial2 c  = new LongPolynomial2(new long[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++)
                    {
                        long c0 = a[k - i] * b[i];
                        long cu = c0 & 0x7FF000000L + (c0 & 2047);
                        long co = (c0.UnsignedRightShift(48)) & 2047;                         //>>>  48

                        c.coeffs[k]     = (c.coeffs[k] + cu) & 0x7FF0007FFL;
                        c.coeffs[k + 1] = (c.coeffs[k + 1] + co) & 0x7FF0007FFL;
                    }
                }
                return(c);
            }
            else
            {
                int    n1     = n / 2;
                long[] a1Temp = new long[n1];
                long[] a2Temp = new long[n - n1];
                long[] b1Temp = new long[n1];
                long[] b2Temp = new long[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);
                LongPolynomial2 a1 = new LongPolynomial2(a1Temp);
                LongPolynomial2 a2 = new LongPolynomial2(a2Temp);
                LongPolynomial2 b1 = new LongPolynomial2(b1Temp);
                LongPolynomial2 b2 = new LongPolynomial2(b2Temp);

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

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

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