private void AddTest()
        {
            NTRUParameters     param = NTRUParamSets.EES1087EP2;
            IntegerPolynomial  a     = PolynomialGeneratorForTesting.GenerateRandom(param.N, param.Q);
            ITernaryPolynomial b     = PolynomialGeneratorForTesting.generateRandom(1087);

            IntegerPolynomial c1 = a.Clone();

            c1.Add(b.ToIntegerPolynomial());

            IntegerPolynomial c2 = a.Clone();

            c2.Add(b);

            if (!Compare.Equals(c1, c2))
            {
                throw new Exception("IntegerPolynomialTest addition test failed!");
            }
        }
Пример #2
0
        /// <summary>
        /// Multiplies the polynomial with a <c>TernaryPolynomial</c>, taking the indices mod N and the values mod 2048.
        /// </summary>
        /// 
        /// <param name="Factor">The polynomial factor</param>
        /// 
        /// <returns>The multiplication product</returns>
        public LongPolynomial5 Multiply(ITernaryPolynomial Factor)
        {
            long[][] prod = ArrayUtils.CreateJagged<long[][]>(5, _coeffs.Length + (Factor.Size() + 4) / 5 - 1);
            int[] pIdx = Factor.GetOnes();

            // multiply ones
            for (int i = 0; i < pIdx.Length; i++)
            {
                int cIdx = pIdx[i] / 5;
                int m = pIdx[i] - cIdx * 5;   // m = pIdx % 5

                for (int j = 0; j < _coeffs.Length; j++)
                {
                    prod[m][cIdx] = (prod[m][cIdx] + _coeffs[j]) & 0x7FF7FF7FF7FF7FFL;
                    cIdx++;
                }
            }

            pIdx = Factor.GetNegOnes();
            // multiply negative ones
            for (int i = 0; i < pIdx.Length; i++)
            {
                int cIdx = pIdx[i] / 5;
                int m = pIdx[i] - cIdx * 5;   // m = pIdx % 5

                for (int j = 0; j < _coeffs.Length; j++)
                {
                    prod[m][cIdx] = (0x800800800800800L + prod[m][cIdx] - _coeffs[j]) & 0x7FF7FF7FF7FF7FFL;
                    cIdx++;
                }
            }

            // combine shifted coefficients (5 arrays) into a single array of length prod[*].Length+1
            long[] cCoeffs = prod[0].CopyOf(prod[0].Length + 1);

            for (int m = 1; m <= 4; m++)
            {
                int shift = m * 12;
                int shift60 = 60 - shift;
                long mask = (1L << shift60) - 1;
                int pLen = prod[m].Length;

                for (int i = 0; i < pLen; i++)
                {
                    long upper, lower;
                    upper = prod[m][i] >> shift60;
                    lower = prod[m][i] & mask;

                    cCoeffs[i] = (cCoeffs[i] + (lower << shift)) & 0x7FF7FF7FF7FF7FFL;
                    int nextIdx = i + 1;
                    cCoeffs[nextIdx] = (cCoeffs[nextIdx] + upper) & 0x7FF7FF7FF7FF7FFL;
                }
            }

            // reduce indices of cCoeffs modulo numCoeffs
            int shift2 = 12 * (_numCoeffs % 5);
            for (int cIdx = _coeffs.Length - 1; cIdx < cCoeffs.Length; cIdx++)
            {
                long iCoeff;   // coefficient to shift into the [0..numCoeffs-1] range
                int newIdx;

                if (cIdx == _coeffs.Length - 1)
                {
                    iCoeff = _numCoeffs == 5 ? 0 : cCoeffs[cIdx] >> shift2;
                    newIdx = 0;
                }
                else
                {
                    iCoeff = cCoeffs[cIdx];
                    newIdx = cIdx * 5 - _numCoeffs;
                }

                int base1 = newIdx / 5;
                int m = newIdx - base1 * 5;   // m = newIdx % 5
                long lower = iCoeff << (12 * m);
                long upper = iCoeff >> (12 * (5 - m));
                cCoeffs[base1] = (cCoeffs[base1] + lower) & 0x7FF7FF7FF7FF7FFL;

                int base2 = base1 + 1;
                if (base2 < _coeffs.Length)
                    cCoeffs[base2] = (cCoeffs[base2] + upper) & 0x7FF7FF7FF7FF7FFL;
            }

            return new LongPolynomial5(cCoeffs, _numCoeffs);
        }
Пример #3
0
        /// <summary>
        /// Multiplies the polynomial with a <c>TernaryPolynomial</c>, taking the indices mod N and the values mod 2048.
        /// </summary>
        ///
        /// <param name="Factor">The polynomial factor</param>
        ///
        /// <returns>The multiplication product</returns>
        public LongPolynomial5 Multiply(ITernaryPolynomial Factor)
        {
            long[][] prod = ArrayUtils.CreateJagged <long[][]>(5, _coeffs.Length + (Factor.Size() + 4) / 5 - 1);
            int[]    pIdx = Factor.GetOnes();

            // multiply ones
            for (int i = 0; i < pIdx.Length; i++)
            {
                int cIdx = pIdx[i] / 5;
                int m    = pIdx[i] - cIdx * 5; // m = pIdx % 5

                for (int j = 0; j < _coeffs.Length; j++)
                {
                    prod[m][cIdx] = (prod[m][cIdx] + _coeffs[j]) & 0x7FF7FF7FF7FF7FFL;
                    cIdx++;
                }
            }

            pIdx = Factor.GetNegOnes();
            // multiply negative ones
            for (int i = 0; i < pIdx.Length; i++)
            {
                int cIdx = pIdx[i] / 5;
                int m    = pIdx[i] - cIdx * 5; // m = pIdx % 5

                for (int j = 0; j < _coeffs.Length; j++)
                {
                    prod[m][cIdx] = (0x800800800800800L + prod[m][cIdx] - _coeffs[j]) & 0x7FF7FF7FF7FF7FFL;
                    cIdx++;
                }
            }

            // combine shifted coefficients (5 arrays) into a single array of length prod[*].Length+1
            long[] cCoeffs = prod[0].CopyOf(prod[0].Length + 1);

            for (int m = 1; m <= 4; m++)
            {
                int  shift   = m * 12;
                int  shift60 = 60 - shift;
                long mask    = (1L << shift60) - 1;
                int  pLen    = prod[m].Length;

                for (int i = 0; i < pLen; i++)
                {
                    long upper, lower;
                    upper = prod[m][i] >> shift60;
                    lower = prod[m][i] & mask;

                    cCoeffs[i] = (cCoeffs[i] + (lower << shift)) & 0x7FF7FF7FF7FF7FFL;
                    int nextIdx = i + 1;
                    cCoeffs[nextIdx] = (cCoeffs[nextIdx] + upper) & 0x7FF7FF7FF7FF7FFL;
                }
            }

            // reduce indices of cCoeffs modulo numCoeffs
            int shift2 = 12 * (_numCoeffs % 5);

            for (int cIdx = _coeffs.Length - 1; cIdx < cCoeffs.Length; cIdx++)
            {
                long iCoeff;   // coefficient to shift into the [0..numCoeffs-1] range
                int  newIdx;

                if (cIdx == _coeffs.Length - 1)
                {
                    iCoeff = _numCoeffs == 5 ? 0 : cCoeffs[cIdx] >> shift2;
                    newIdx = 0;
                }
                else
                {
                    iCoeff = cCoeffs[cIdx];
                    newIdx = cIdx * 5 - _numCoeffs;
                }

                int  base1 = newIdx / 5;
                int  m     = newIdx - base1 * 5; // m = newIdx % 5
                long lower = iCoeff << (12 * m);
                long upper = iCoeff >> (12 * (5 - m));
                cCoeffs[base1] = (cCoeffs[base1] + lower) & 0x7FF7FF7FF7FF7FFL;

                int base2 = base1 + 1;
                if (base2 < _coeffs.Length)
                {
                    cCoeffs[base2] = (cCoeffs[base2] + upper) & 0x7FF7FF7FF7FF7FFL;
                }
            }

            return(new LongPolynomial5(cCoeffs, _numCoeffs));
        }
Пример #4
0
 /// <summary>
 /// Adds a <c>TernaryPolynomial</c> which must not have more coefficients than <c>this</c> polynomial.
 /// </summary>
 /// 
 /// <param name="B">Another polynomial</param>
 public void Add(ITernaryPolynomial B)
 {
     foreach (int n in B.GetOnes())
         Coeffs[n]++;
     foreach (int n in B.GetNegOnes())
         Coeffs[n]--;
 }
Пример #5
0
        /**
         * Multiplies the polynomial with a <code>TernaryPolynomial</code>, taking the indices mod N and the values mod 2048.
         */
        public LongPolynomial5 Multiply(ITernaryPolynomial poly2)
        {
            long[,] prod = new long[5, (coeffs.Length + ((poly2.Size() + 4) / 5 - 1))];              // intermediate results, the subarrays are shifted by 0,...,4 coefficients

            // multiply ones
            int[] ones = poly2.GetOnes();
            for (int idx = 0; idx != ones.Length; idx++)
            {
                int pIdx = ones[idx];
                int cIdx = pIdx / 5;
                int m    = pIdx - cIdx * 5;                // m = pIdx % 5
                for (int i = 0; i < coeffs.Length; i++)
                {
                    prod[m, cIdx] = (prod[m, cIdx] + coeffs[i]) & 0x7FF7FF7FF7FF7FFL;
                    cIdx++;
                }
            }

            // multiply negative ones  (God Java Sucks)
            int[] negOnes = poly2.GetNegOnes();
            for (int idx = 0; idx != negOnes.Length; idx++)
            {
                int pIdx = negOnes[idx];
                int cIdx = pIdx / 5;
                int m    = pIdx - cIdx * 5;                // m = pIdx % 5
                for (int i = 0; i < coeffs.Length; i++)
                {
                    prod[m, cIdx] = (0x800800800800800L + prod[m, cIdx] - coeffs[i]) & 0x7FF7FF7FF7FF7FFL;
                    cIdx++;
                }
            }

            // combine shifted coefficients (5 arrays) into a single array of length prod[*].Length+1
            // long[] cCoeffs = Arrays.copyOf(prod[0], prod[0].length + 1);
            long[] cCoeffs = new long[prod.Length + 1];
            prod.FlatCopyTo(cCoeffs);
            int pLen = prod.GetLength(1);             // All polynomials must be the same size, or boom!

            for (int m = 1; m <= 4; m++)
            {
                int  shifter = m * 12;
                int  shift60 = 60 - shifter;
                long mask    = (1L << shift60) - 1;

                for (int i = 0; i < pLen; i++)
                {
                    long upper, lower;
                    upper = prod[m, i] >> shift60;
                    lower = prod[m, i] & mask;

                    cCoeffs[i] = (cCoeffs[i] + (lower << shifter)) & 0x7FF7FF7FF7FF7FFL;
                    int nextIdx = i + 1;
                    cCoeffs[nextIdx] = (cCoeffs[nextIdx] + upper) & 0x7FF7FF7FF7FF7FFL;
                }
            }

            // reduce indices of cCoeffs modulo numCoeffs
            int shift = 12 * (numCoeffs % 5);

            for (int cIdx = coeffs.Length - 1; cIdx < cCoeffs.Length; cIdx++)
            {
                long iCoeff;                   // coefficient to shift into the [0..numCoeffs-1] range
                int  newIdx;
                if (cIdx == coeffs.Length - 1)
                {
                    iCoeff = numCoeffs == 5 ? 0 : cCoeffs[cIdx] >> shift;
                    newIdx = 0;
                }
                else
                {
                    iCoeff = cCoeffs[cIdx];
                    newIdx = cIdx * 5 - numCoeffs;
                }

                int  baseCoef = newIdx / 5;
                int  m        = newIdx - baseCoef * 5;           // m = newIdx % 5
                long lower    = iCoeff << (12 * m);
                long upper    = iCoeff >> (12 * (5 - m));
                cCoeffs[baseCoef] = (cCoeffs[baseCoef] + lower) & 0x7FF7FF7FF7FF7FFL;
                int base1 = baseCoef + 1;
                if (base1 < coeffs.Length)
                {
                    cCoeffs[base1] = (cCoeffs[base1] + upper) & 0x7FF7FF7FF7FF7FFL;
                }
            }

            return(new LongPolynomial5(cCoeffs, numCoeffs));
        }