示例#1
0
        /// <summary>
        /// Makes a copy of the polynomial that is independent of the original.
        /// </summary>
        /// <returns>The cloned polynomial</returns>
        public LongPolynomial2 Clone()
        {
            LongPolynomial2 p = new LongPolynomial2((long[])Coeffs.Clone());
            p._numCoeffs = _numCoeffs;

            return p;
        }
        /// <summary>
        /// Makes a copy of the polynomial that is independent of the original.
        /// </summary>
        /// <returns>The cloned polynomial</returns>
        public LongPolynomial2 Clone()
        {
            LongPolynomial2 p = new LongPolynomial2((long[])Coeffs.Clone());

            p._numCoeffs = _numCoeffs;

            return(p);
        }
        /// <summary>
        /// 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.
        /// </summary>
        ///
        /// <param name="B">Another polynomial</param>
        /// <param name="Mask">A bit mask less than 2048 to apply to each 11-bit coefficient</param>
        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;
            }
        }
 private void Subtract(LongPolynomial2 B)
 {
     // Subtracts another polynomial which can have a different number of coefficients
     if (B.Coeffs.Length > Coeffs.Length)
     {
         Coeffs = Coeffs.CopyOf(B.Coeffs.Length);
     }
     for (int i = 0; i < B.Coeffs.Length; i++)
     {
         Coeffs[i] = (0x0800000800000L + Coeffs[i] - B.Coeffs[i]) & 0x7FF0007FFL;
     }
 }
        private void Add(LongPolynomial2 B)
        {
            // Adds another polynomial which can have a different number of coefficients.
            if (B.Coeffs.Length > Coeffs.Length)
            {
                Coeffs = Coeffs.CopyOf(B.Coeffs.Length);
            }

            for (int i = 0; i < B.Coeffs.Length; i++)
            {
                Coeffs[i] = (Coeffs[i] + B.Coeffs[i]) & 0x7FF0007FFL;
            }
        }
        /// <summary>
        /// Multiplies the polynomial with another, taking the indices mod N and the values mod 2048.
        /// </summary>
        ///
        /// <param name="Factor">The polynomial factor</param>
        public LongPolynomial2 Multiply(LongPolynomial2 Factor)
        {
            int N = Coeffs.Length;

            if (Factor.Coeffs.Length != N || _numCoeffs != Factor._numCoeffs)
            {
                throw new NTRUException("LongPolynomial2:Multiply", "Number of coefficients must be the same!", new FormatException());
            }

            LongPolynomial2 c = MultRecursive(Factor);

            if (c.Coeffs.Length > N)
            {
                if (_numCoeffs % 2 == 0)
                {
                    for (int k = N; k < c.Coeffs.Length; k++)
                    {
                        c.Coeffs[k - N] = (c.Coeffs[k - N] + c.Coeffs[k]) & 0x7FF0007FFL;
                    }

                    c.Coeffs = c.Coeffs.CopyOf(N);
                }
                else
                {
                    for (int k = N; k < c.Coeffs.Length; k++)
                    {
                        c.Coeffs[k - N]  = c.Coeffs[k - N] + (c.Coeffs[k - 1] >> 24);
                        c.Coeffs[k - N]  = c.Coeffs[k - N] + ((c.Coeffs[k] & 2047) << 24);
                        c.Coeffs[k - N] &= 0x7FF0007FFL;
                    }

                    c.Coeffs = c.Coeffs.CopyOf(N);
                    c.Coeffs[c.Coeffs.Length - 1] &= 2047;
                }
            }

            c            = new LongPolynomial2(c.Coeffs);
            c._numCoeffs = _numCoeffs;
            return(c);
        }
示例#7
0
 private void Subtract(LongPolynomial2 B)
 {
     // Subtracts another polynomial which can have a different number of coefficients
     if (B.Coeffs.Length > Coeffs.Length)
         Coeffs = Coeffs.CopyOf(B.Coeffs.Length);
     for (int i = 0; i < B.Coeffs.Length; i++)
         Coeffs[i] = (0x0800000800000L + Coeffs[i] - B.Coeffs[i]) & 0x7FF0007FFL;
 }
示例#8
0
        private LongPolynomial2 MultRecursive(LongPolynomial2 Poly2)
        {
            // Karatsuba multiplication
            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 = Math.Max(0, k - n + 1); i <= Math.Min(k, n - 1); i++)
                    {
                        long c0 = a[k - i] * b[i];
                        long cu = c0 & 0x7FF000000L + (c0 & 2047);
                        long co = IntUtils.URShift(c0, 48) & 2047;

                        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;

                LongPolynomial2 a1 = new LongPolynomial2(a.CopyOf(n1));
                LongPolynomial2 a2 = new LongPolynomial2(a.CopyOfRange(n1, n));
                LongPolynomial2 b1 = new LongPolynomial2(b.CopyOf(n1));
                LongPolynomial2 b2 = new LongPolynomial2(b.CopyOfRange(n1, n));

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

                LongPolynomial2 c1 = a1.MultRecursive(b1);
                LongPolynomial2 c2 = a2.MultRecursive(b2);
                LongPolynomial2 c3 = A.MultRecursive(B);
                c3.Subtract(c1);
                c3.Subtract(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;
            }
        }
示例#9
0
        private void Add(LongPolynomial2 B)
        {
            // Adds another polynomial which can have a different number of coefficients.
            if (B.Coeffs.Length > Coeffs.Length)
                Coeffs = Coeffs.CopyOf(B.Coeffs.Length);

            for (int i = 0; i < B.Coeffs.Length; i++)
                Coeffs[i] = (Coeffs[i] + B.Coeffs[i]) & 0x7FF0007FFL;
        }
示例#10
0
        /// <summary>
        /// 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.
        /// </summary>
        /// 
        /// <param name="B">Another polynomial</param>
        /// <param name="Mask">A bit mask less than 2048 to apply to each 11-bit coefficient</param>
        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;
        }
示例#11
0
        /// <summary>
        /// Multiplies the polynomial with another, taking the indices mod N and the values mod 2048.
        /// </summary>
        /// 
        /// <param name="Factor">The polynomial factor</param>
        public LongPolynomial2 Multiply(LongPolynomial2 Factor)
        {
            int N = Coeffs.Length;
            if (Factor.Coeffs.Length != N || _numCoeffs != Factor._numCoeffs)
                throw new NTRUException("LongPolynomial2:Multiply", "Number of coefficients must be the same!", new FormatException());

            LongPolynomial2 c = MultRecursive(Factor);

            if (c.Coeffs.Length > N)
            {
                if (_numCoeffs % 2 == 0)
                {
                    for (int k = N; k < c.Coeffs.Length; k++)
                        c.Coeffs[k - N] = (c.Coeffs[k - N] + c.Coeffs[k]) & 0x7FF0007FFL;

                    c.Coeffs = c.Coeffs.CopyOf(N);
                }
                else
                {
                    for (int k = N; k < c.Coeffs.Length; k++)
                    {
                        c.Coeffs[k - N] = c.Coeffs[k - N] + (c.Coeffs[k - 1] >> 24);
                        c.Coeffs[k - N] = c.Coeffs[k - N] + ((c.Coeffs[k] & 2047) << 24);
                        c.Coeffs[k - N] &= 0x7FF0007FFL;
                    }

                    c.Coeffs = c.Coeffs.CopyOf(N);
                    c.Coeffs[c.Coeffs.Length - 1] &= 2047;
                }
            }

            c = new LongPolynomial2(c.Coeffs);
            c._numCoeffs = _numCoeffs;
            return c;
        }
示例#12
0
 /// <summary>
 /// Computes the inverse mod <c>q</c> from the inverse mod 2.
 /// <para>The algorithm is described in <a href="http://www.securityinnovation.com/uploads/Crypto/NTRUTech014.pdf">
 /// Almost Inverses and Fast NTRU Key Generation</a>.</para>
 /// </summary>
 /// 
 /// <param name="Fq">Fq value</param>
 /// <param name="Q">Q value</param>
 /// 
 /// <returns>The inverse of this polynomial mod q</returns>
 private IntegerPolynomial Mod2ToModq(IntegerPolynomial Fq, int Q)
 {
     if (SystemUtils.Is64Bit() && Q == 2048)
     {
         LongPolynomial2 thisLong = new LongPolynomial2(this);
         LongPolynomial2 FqLong = new LongPolynomial2(Fq);
         int v = 2;
         while (v < Q)
         {
             v *= 2;
             LongPolynomial2 temp = 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;
             IntegerPolynomial temp = Fq.Clone();
             temp.Mult2(v);
             Fq = Multiply(Fq, v).Multiply(Fq, v);
             temp.Subtract(Fq, v);
             Fq = temp;
         }
         return Fq;
     }
 }
示例#13
0
        private LongPolynomial2 MultRecursive(LongPolynomial2 Poly2)
        {
            // Karatsuba multiplication
            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 = Math.Max(0, k - n + 1); i <= Math.Min(k, n - 1); i++)
                    {
                        long c0 = a[k - i] * b[i];
                        long cu = c0 & 0x7FF000000L + (c0 & 2047);
                        long co = IntUtils.URShift(c0, 48) & 2047;

                        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;

                LongPolynomial2 a1 = new LongPolynomial2(a.CopyOf(n1));
                LongPolynomial2 a2 = new LongPolynomial2(a.CopyOfRange(n1, n));
                LongPolynomial2 b1 = new LongPolynomial2(b.CopyOf(n1));
                LongPolynomial2 b2 = new LongPolynomial2(b.CopyOfRange(n1, n));

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

                LongPolynomial2 c1 = a1.MultRecursive(b1);
                LongPolynomial2 c2 = a2.MultRecursive(b2);
                LongPolynomial2 c3 = A.MultRecursive(B);
                c3.Subtract(c1);
                c3.Subtract(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);
            }
        }