private void MultTest()
        {
            IntegerPolynomial i1 = new IntegerPolynomial(new int[] { 1368, 2047, 672, 871, 1662, 1352, 1099, 1608 });
            IntegerPolynomial i2 = new IntegerPolynomial(new int[] { 1729, 1924, 806, 179, 1530, 1381, 1695, 60 });
            LongPolynomial2 a = new LongPolynomial2(i1);
            LongPolynomial2 b = new LongPolynomial2(i2);
            IntegerPolynomial c1 = i1.Multiply(i2, 2048);
            IntegerPolynomial c2 = a.Multiply(b).ToIntegerPolynomial();

            if (!Compare.AreEqual(c1.Coeffs, c2.Coeffs))
                throw new Exception("LongPolynomial2 multiply test failed!");

            // test 10 random polynomials
            Random rng = new Random();
            for (int i = 0; i < 10; i++)
            {
                int N = 2 + rng.Next(2000);
                i1 = (IntegerPolynomial)PolynomialGeneratorForTesting.GenerateRandom(N, 2048);
                i2 = (IntegerPolynomial)PolynomialGeneratorForTesting.GenerateRandom(N, 2048);
                a = new LongPolynomial2(i1);
                b = new LongPolynomial2(i2);
                c1 = i1.Multiply(i2);
                c1.ModPositive(2048);
                c2 = a.Multiply(b).ToIntegerPolynomial();

                if (!Compare.AreEqual(c1.Coeffs, c2.Coeffs))
                    throw new Exception("LongPolynomial2 multiply test failed!");
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Read a Public Key from a Stream
 /// </summary>
 /// 
 /// <param name="KeyStream">An input stream containing an encoded key</param>
 /// 
 /// <exception cref="CryptoAsymmetricException">Thrown if the key could not be loaded</exception>
 public NTRUPublicKey(Stream KeyStream)
 {
     try
     {
         _N = IntUtils.ReadShort(KeyStream);
         _Q = IntUtils.ReadShort(KeyStream);
         _H = IntegerPolynomial.FromBinary(KeyStream, N, Q);
     }
     catch (Exception ex)
     {
         throw new CryptoAsymmetricException("NTRUPublicKey:CTor", "The Public key could not be loaded!", ex);
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Constructs a <c>LongPolynomial2</c> from a <c>IntegerPolynomial</c>. The two polynomials are independent of each other.
        /// </summary>
        /// <param name="P">The original polynomial. Coefficients must be between 0 and 2047.</param>
        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++;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Constructs a <c>LongPolynomial5</c> from a <c>IntegerPolynomial</c>. The two polynomials are independent of each other.
        /// </summary>
        /// 
        /// <param name="P">The original polynomial. Coefficients must be between 0 and 2047.</param>
        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++;
                }
            }
        }
        /// <summary>
        /// Test the validity of the BigDecimalPolynomial implementation
        /// </summary>
        /// 
        /// <returns>State</returns>
        public string Test()
        {
            try
            {
                BigDecimalPolynomial a = CreateBigDecimalPolynomial(new int[] { 4, -1, 9, 2, 1, -5, 12, -7, 0, -9, 5 });
                BigIntPolynomial b = new BigIntPolynomial(new IntegerPolynomial(new int[] { -6, 0, 0, 13, 3, -2, -4, 10, 11, 2, -1 }));
                BigDecimalPolynomial c = a.Multiply(b);
                if(!Compare.AreEqual(c.Coeffs, CreateBigDecimalPolynomial(new int[] { 2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34 }).Coeffs))
                    throw new Exception("The BigDecimalPolynomial test failed!");
                // multiply a polynomial by its inverse modulo 2048 and check that the result is 1
                IntegerPolynomial d, dInv;
                CSPRng rng = new CSPRng();

                do
                {
                    d = DenseTernaryPolynomial.GenerateRandom(1001, 333, 334, rng);
                    dInv = d.InvertFq(2048);
                } while (dInv == null);

                d.Mod(2048);
                BigDecimalPolynomial e = CreateBigDecimalPolynomial(d.Coeffs);
                BigIntPolynomial f = new BigIntPolynomial(dInv);
                IntegerPolynomial g = new IntegerPolynomial(e.Multiply(f).Round());
                g.ModPositive(2048);

                if (!g.EqualsOne())
                    throw new Exception("The BigDecimalPolynomial test failed!");
                OnProgress(new TestEventArgs("Passed BigDecimalPolynomial tests"));

                return SUCCESS;
            }
            catch (Exception Ex)
            {
                string message = Ex.Message == null ? "" : Ex.Message;
                throw new Exception(FAILURE + message);
            }
        }
        /// <summary>
        /// Resultant of this polynomial with <c>x^n-1 mod p</c>.
        /// </summary>
        /// 
        /// <param name="P">P value</param>
        /// 
        /// <returns>Returns <c>(rho, res)</c> satisfying <c>res = rho*this + t*(x^n-1) mod p</c> for some integer <c>t</c>.</returns>
        public ModularResultant Resultant(int P)
        {
            // Add a coefficient as the following operations involve polynomials of degree deg(f)+1
            int[] fcoeffs = Coeffs.CopyOf(Coeffs.Length + 1);
            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 = 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 *= 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 *= Pow(b.Coeffs[0], da, P);
            r %= P;
            c = 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
            v2.Coeffs = v2.Coeffs.CopyOf(v2.Coeffs.Length - 1);
            return new ModularResultant(new BigIntPolynomial(v2), BigInteger.ValueOf(r), BigInteger.ValueOf(P));
        }
 /// <summary>
 /// Subtracts another polynomial which must not have more coefficients than <c>this</c> polynomial.
 /// </summary>
 /// 
 /// <param name="B">The polynomial to subtract</param>
 public void Subtract(IntegerPolynomial B)
 {
     for (int i = 0; i < B.Coeffs.Length; i++)
         Coeffs[i] -= B.Coeffs[i];
 }
Esempio n. 8
0
        /// <summary>
        /// Multiplies the polynomial with another, taking the values mod modulus and the indices mod N
        /// </summary>
        /// 
        /// <param name="Factor">The polynomial factor</param>
        /// <param name="Modulus">The Modulus</param>
        /// 
        /// <returns>Multiplied polynomial</returns>
        public new IntegerPolynomial Multiply(IntegerPolynomial Factor, int Modulus)
        {
            // even on 32-bit systems, LongPolynomial5 multiplies faster than IntegerPolynomial
            if (Modulus == 2048)
            {
                IntegerPolynomial poly2Pos = Factor.Clone();
                poly2Pos.ModPositive(2048);
                LongPolynomial5 poly5 = new LongPolynomial5(poly2Pos);

                return poly5.Multiply(this).ToIntegerPolynomial();
            }
            else
            {
                return base.Multiply(Factor, Modulus);
            }
        }
Esempio n. 9
0
        private void GenerateFQ(IRandom Rng, out IPolynomial t, out IntegerPolynomial fq, out IntegerPolynomial fp)
        {
            int N = _ntruParams.N;
            int q = _ntruParams.Q;
            int df = _ntruParams.DF;
            int df1 = _ntruParams.DF1;
            int df2 = _ntruParams.DF2;
            int df3 = _ntruParams.DF3;
            bool fastFp = _ntruParams.FastFp;
            bool sparse = _ntruParams.Sparse;
            TernaryPolynomialType polyType = _ntruParams.PolyType;
            fp = null;

            // choose a random f that is invertible mod 3 and q
            while (true)
            {
                IntegerPolynomial f;

                // choose random t, calculate f and fp
                if (fastFp)
                {
                    // if fastFp=true, f is always invertible mod 3
                    if (polyType == TernaryPolynomialType.SIMPLE)
                        t = PolynomialGenerator.GenerateRandomTernary(N, df, df, sparse, Rng);
                    else
                        t = ProductFormPolynomial.GenerateRandom(N, df1, df2, df3, df3, Rng);

                    f = t.ToIntegerPolynomial();
                    f.Multiply(3);
                    f.Coeffs[0] += 1;
                }
                else
                {
                    if (polyType == TernaryPolynomialType.SIMPLE)
                        t = PolynomialGenerator.GenerateRandomTernary(N, df, df - 1, sparse, Rng);
                    else
                        t = ProductFormPolynomial.GenerateRandom(N, df1, df2, df3, df3 - 1, Rng);

                    f = t.ToIntegerPolynomial();
                    fp = f.InvertF3();

                    if (fp == null)
                        continue;
                }

                fq = f.InvertFq(q);

                if (fq != null)
                    break;
            }
        }
Esempio n. 10
0
 /// <summary>
 /// Constructs a new private key from a polynomial
 /// </summary>
 /// 
 /// <param name="T">The polynomial which determines the key: if <c>FastFp=true</c>, <c>f=1+3T</c>; otherwise, <c>f=T</c></param>
 /// <param name="FP">Fp the inverse of <c>f</c></param>
 /// <param name="N">The number of polynomial coefficients</param>
 /// <param name="Q">The big q modulus</param>
 /// <param name="Sparse">Sparse whether the polynomial <c>T</c> is sparsely or densely populated</param>
 /// <param name="FastFp">FastFp whether <c>FP=1</c></param>
 /// <param name="PolyType">PolyType type of the polynomial <c>T</c></param>
 internal NTRUPrivateKey(IPolynomial T, IntegerPolynomial FP, int N, int Q, bool Sparse, bool FastFp, TernaryPolynomialType PolyType)
 {
     _T = T;
     _FP = FP;
     _N = N;
     _Q = Q;
     _sparse = Sparse;
     _fastFp = FastFp;
     _polyType = PolyType;
 }
Esempio n. 11
0
 /// <summary>
 /// Constructs a <c>DenseTernaryPolynomial</c> from a <c>IntegerPolynomial</c>.
 /// <para>The two polynomials are independent of each other.</para>
 /// </summary>
 /// 
 /// <param name="IntPoly">The original polynomial></param>
 public SparseTernaryPolynomial(IntegerPolynomial IntPoly)
     : this(IntPoly.Coeffs)
 {
 }
Esempio n. 12
0
        /// <summary>
        /// Multiplies the polynomial by an <c>IntegerPolynomial</c>,
        /// taking the coefficient values mod <c>modulus</c> and the indices mod <c>N</c>.
        /// </summary>
        /// 
        /// <param name="Factor">A polynomial factor</param>
        /// <param name="Modulus">The modulus to apply</param>
        /// 
        /// <returns>The product of the two polynomials</returns>
        public IntegerPolynomial Multiply(IntegerPolynomial Factor, int Modulus)
        {
            IntegerPolynomial c = Multiply(Factor);
            c.Mod(Modulus);

            return c;
        }
Esempio n. 13
0
        /// <remarks>
        ///  Computes this-b*c*(x^k) mod p and stores the result in this polynomial.
        /// </remarks>
        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;
        }
Esempio n. 14
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;
     }
 }
Esempio n. 15
0
        /// <summary>
        /// Computes 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>
        /// 
        /// <returns>Returns <c>null</c> if the polynomial is not invertible.</returns>
        private IntegerPolynomial InvertF2()
        {
            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(Coeffs.CopyOf(N + 1));
            f.Mod2();

            // 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);
                f.Mod2();
                b.Add(c);
                b.Mod2();
            }

            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 Fq;
        }
Esempio n. 16
0
        private IntegerPolynomial MultRecursive(IntegerPolynomial Factor)
        {
            int[] a = Coeffs;
            int[] b = Factor.Coeffs;
            int n = Factor.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 = Math.Max(0, k - n + 1); i <= Math.Min(k, n - 1); i++)
                        c.Coeffs[k] += b[i] * a[k - i];
                }

                return c;
            }
            else
            {
                int n1 = n / 2;

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

                // make a copy of a1 that is the same length as a2
                IntegerPolynomial A = new IntegerPolynomial(a1.Coeffs.CopyOf(a2.Coeffs.Length));
                A.Add(a2);
                // make a copy of b1 that is the same length as b2
                IntegerPolynomial B = new IntegerPolynomial(b1.Coeffs.CopyOf(b2.Coeffs.Length));
                B.Add(b2);

                IntegerPolynomial c1 = a1.MultRecursive(b1);
                IntegerPolynomial c2 = a2.MultRecursive(b2);
                IntegerPolynomial c3 = A.MultRecursive(B);
                c3.Subtract(c1);
                c3.Subtract(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;
            }
        }
Esempio n. 17
0
 /// <summary>
 /// Constructs a new public key from a polynomial
 /// </summary>
 /// 
 /// <param name="H">The polynomial <c>H</c> which determines the key</param>
 /// <param name="N">The number of coefficients in the polynomial <c>H</c></param>
 /// <param name="Q">The "big" NtruEncrypt modulus</param>
 internal NTRUPublicKey(IntegerPolynomial H, int N, int Q)
 {
     _H = H;
     _N = N;
     _Q = Q;
 }
Esempio n. 18
0
 /// <summary>
 /// Constructs a <c>BigIntPolynomial</c> from a <c>IntegerPolynomial</c>. The two polynomials are
 /// independent of each other.
 /// </summary>
 /// 
 /// <param name="P">The original polynomial</param>
 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]);
 }
Esempio n. 19
0
        /// <summary>
        /// Multiplies the polynomial by an <c>IntegerPolynomial</c>,
        /// taking the indices mod <c>N</c>.
        /// </summary>
        /// 
        /// <param name="Factor">A polynomial factor</param>
        /// 
        /// <returns>The product of the two polynomials</returns>
        public IntegerPolynomial Multiply(IntegerPolynomial Factor)
        {
            IntegerPolynomial c = _f1.Multiply(Factor);
            c = _f2.Multiply(c);
            c.Add(_f3.Multiply(Factor));

            return c;
        }
Esempio n. 20
0
        /// <summary>
        /// Generates a seed for the Blinding Polynomial Generation Function
        /// </summary>
        /// 
        /// <param name="Message">The plain-text message</param>
        /// <param name="PubKey">The public key</param>
        /// <param name="Bits">Bits of random data</param>
        /// 
        /// <returns>A byte array containing a seed value</returns>
        private byte[] GetSeed(byte[] Message, IntegerPolynomial PubKey, byte[] Bits)
        {
            byte[] oid = _encParams.OId;
            byte[] hTrunc = PubKey.ToBinaryTrunc(_encParams.Q, _encParams.PkLen / 8);
            // sData = OID|m|b|hTrunc
            byte[] sData = new byte[oid.Length + Message.Length + Bits.Length + hTrunc.Length];

            Array.Copy(oid, 0, sData, 0, oid.Length);
            int start = oid.Length;
            Array.Copy(Message, 0, sData, start, Message.Length);
            start += Message.Length;
            Array.Copy(Bits, 0, sData, start, Bits.Length);
            start += Bits.Length;
            Array.Copy(hTrunc, 0, sData, start, hTrunc.Length);

            return sData;
        }
Esempio n. 21
0
 /// <summary>
 /// Subtracts another polynomial which can have a different number of coefficients,
 /// and takes the coefficient values mod <c>modulus</c>.
 /// </summary>
 /// 
 /// <param name="B">The polynomial to subtract</param>
 /// <param name="Modulus">The modulus</param>
 private void Subtract(IntegerPolynomial B, int Modulus)
 {
     Subtract(B);
     Mod(Modulus);
 }
Esempio n. 22
0
        /// <summary>
        /// Multiplies the polynomial by an <c>IntegerPolynomial</c>,
        /// taking the indices mod <c>N</c>.
        /// </summary>
        /// 
        /// <param name="Factor">A polynomial factor</param>
        /// 
        /// <returns>The product of the two polynomials</returns>
        public IntegerPolynomial Multiply(IntegerPolynomial Factor)
        {
            int[] b = Factor.Coeffs;
            if (b.Length != _N)
                throw new CryptoAsymmetricException("SparseTernaryPolynomial:Multiply", "Number of coefficients must be the same!", new FormatException());

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

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

            return new IntegerPolynomial(c);
        }
Esempio n. 23
0
        /// <summary>
        /// Decrypts an integer polynomial
        /// </summary>
        /// 
        /// <param name="E">Encrypted polynomial</param>
        /// <param name="PrivT">A polynomial such that if <c>fastFp=true</c>, <c>f=1+3*priv_t</c>; otherwise, <c>f=priv_t</c></param>
        /// <param name="PrivFp">Fp</param>
        /// 
        /// <returns>Derypted polynomial</returns>
        private IntegerPolynomial Decrypt(IntegerPolynomial E, IPolynomial PrivT, IntegerPolynomial PrivFp)
        {
            int q = _encParams.Q;
            IntegerPolynomial a;

            if (_encParams.FastFp)
            {
                a = PrivT.Multiply(E, q);
                a.Multiply(3);
                a.Add(E);
            }
            else
            {
                a = PrivT.Multiply(E, q);
            }

            a.Center0(q);
            a.Mod3();
            IntegerPolynomial c = _encParams.FastFp ? a : new DenseTernaryPolynomial(a).Multiply(PrivFp, 3);
            c.Center0(3);

            return c;
        }
Esempio n. 24
0
 /// <summary>
 /// Adds another polynomial
 /// </summary>
 /// <param name="B">The polynomial to add</param> //p
 public void Add(IntegerPolynomial B)
 {
     for (int i = 0; i < B.Coeffs.Length; i++)
         Coeffs[i] += B.Coeffs[i];
 }
Esempio n. 25
0
        /// <summary>
        /// An implementation of MGF-TP-1 from P1363.1 section 8.4.1.1.
        /// </summary>
        /// 
        /// <param name="Seed">The seed value</param>
        /// <param name="N">N paramater</param>
        /// <param name="MinCallsMask">Minimum Calls Mask</param>
        /// <param name="HashSeed">Whether to hash the seed</param>
        /// 
        /// <returns></returns>
        private IntegerPolynomial MGF(byte[] Seed, int N, int MinCallsMask, bool HashSeed)
        {
            int hashLen = _dgtEngine.DigestSize;

            using (MemoryStream writer = new MemoryStream(MinCallsMask * hashLen))
            {
                byte[] Z = HashSeed ? _dgtEngine.ComputeHash(Seed) : Seed;
                int counter = 0;

                while (counter < MinCallsMask)
                {
                    byte[] data = new byte[Z.Length + 4];
                    Buffer.BlockCopy(Z, 0, data, 0, Z.Length);
                    Buffer.BlockCopy(IntUtils.IntToBytes(counter), 0, data, Z.Length, 4);
                    byte[] hash = _dgtEngine.ComputeHash(data);
                    writer.Write(hash, 0, hash.Length);
                    counter++;
                }

                IntegerPolynomial i = new IntegerPolynomial(N);
                while (true)
                {
                    int cur = 0;
                    byte[] buffer = writer.ToArray();

                    for (int j = 0; j < buffer.Length; j++)
                    {
                        int O = (int)buffer[j] & 0xFF;
                        if (O >= 243)   // 243 = 3^5
                            continue;

                        for (int terIdx = 0; terIdx < 4; terIdx++)
                        {
                            int rem3 = O % 3;
                            i.Coeffs[cur] = rem3 == 2 ? -1 : rem3;   // reduce to [-1..1]
                            cur++;
                            if (cur == N)
                                return i;
                            O = (O - rem3) / 3;
                        }

                        i.Coeffs[cur] = O == 2 ? -1 : O;            // reduce to [-1..1]
                        cur++;
                        if (cur == N)
                            return i;
                    }

                    if (cur >= N)
                        return i;
                    // reset the memory
                    writer.SetLength(0);
                    writer.SetLength(hashLen);
                    // get the hash
                    byte[] hash = _dgtEngine.ComputeHash(ArrayUtils.Concat(Z, IntUtils.IntToBytes(counter)));
                    writer.Write(hash, 0, hash.Length);
                    counter++;
                }
            }
        }
Esempio n. 26
0
 /// <summary>
 /// Adds another polynomial which must not have more coefficients than <c>this</c>
 /// polynomial, and takes the coefficient values mod <c>modulus</c>.
 /// </summary>
 /// 
 /// <param name="B">The polynomial to add</param>
 /// <param name="Modulus">The modulus</param>
 public void Add(IntegerPolynomial B, int Modulus)
 {
     Add(B);
     Mod(Modulus);
 }
Esempio n. 27
0
 private void Initialize()
 {
     // Initializes fp from t
     if (_fastFp)
     {
         _FP = new IntegerPolynomial(N);
         _FP.Coeffs[0] = 1;
     }
     else
     {
         _FP = T.ToIntegerPolynomial().InvertF3();
     }
 }
Esempio n. 28
0
        /// <summary>
        /// Computes the inverse mod 3.
        /// <para>Returns <c>null</c> if the polynomial is not invertible.
        /// 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>
        /// 
        /// <returns>A new polynomial, or <c>null</c> if no inverse exists</returns>
        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);
            f.Coeffs = Coeffs.CopyOf(N + 1);
            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.Subtract(g, 3);
                    b.Subtract(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;
        }
Esempio n. 29
0
        /// <summary>
        /// Generates a new encryption key pair
        /// </summary>
        /// 
        /// <param name="RngF">The random number generator to use for generating the secret polynomial f</param>
        /// <param name="RngG">The random number generator to use for generating the secret polynomial g</param>
        /// 
        /// <returns>A key pair</returns>
        private IAsymmetricKeyPair GenerateKeyPair(IRandom RngF, IRandom RngG)
        {
            int N = _ntruParams.N;
            int q = _ntruParams.Q;
            bool fastFp = _ntruParams.FastFp;
            bool sparse = _ntruParams.Sparse;
            TernaryPolynomialType polyType = _ntruParams.PolyType;
            IPolynomial t = null;
            IntegerPolynomial fq = null;
            IntegerPolynomial fp = null;
            IntegerPolynomial g = null;

            if (ParallelUtils.IsParallel && _isParallel)
            {
                Action[] gA = new Action[] {
                    new Action(()=> g = GenerateG(RngG)),
                    new Action(()=> GenerateFQ(RngF, out t, out fq, out fp))
                };
                Parallel.Invoke(gA);
            }
            else
            {
                // Choose a random g that is invertible mod q.
                g = GenerateG(RngG);
                // choose a random f that is invertible mod 3 and q
                GenerateFQ(RngF, out t, out fq, out fp);
            }

            // if fastFp=true, fp=1
            if (fastFp)
            {
                fp = new IntegerPolynomial(N);
                fp.Coeffs[0] = 1;
            }

            IntegerPolynomial h = g.Multiply(fq, q);
            h.Mult3(q);
            h.EnsurePositive(q);

            NTRUPrivateKey priv = new NTRUPrivateKey(t, fp, N, q, sparse, fastFp, polyType);
            NTRUPublicKey pub = new NTRUPublicKey(h, N, q);

            return new NTRUKeyPair(pub, priv);
        }
Esempio n. 30
0
        /// <summary>
        /// Multiplies the polynomial with another, taking the indices mod N
        /// </summary>
        /// <param name="Factor">The polynomial factor</param>
        /// 
        /// <returns>Multiplied polynomial</returns>
        public IntegerPolynomial Multiply(IntegerPolynomial Factor)
        {
            int N = Coeffs.Length;

            if (Factor.Coeffs.Length != N)
                throw new CryptoAsymmetricException("IntegerPolynomial:Multiply", "Number of coefficients must be the same!", new FormatException());

            IntegerPolynomial c = MultRecursive(Factor);

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

                c.Coeffs = c.Coeffs.CopyOf(N);
            }

            return c;
        }