Beispiel #1
0
        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!");
                }
            }
        }
Beispiel #2
0
        public void testMult()
        {
            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();

            Assert.True(c1.coeffs.SequenceEqual(c2.coeffs));

            SecureRandom rng = new SecureRandom();

            for (int i = 0; i < 10; i++)
            {
                int N = 2 + rng.NextInt(2000);
                i1 = PolynomialGenerator.GenerateRandom(N, 2048);
                i2 = PolynomialGenerator.GenerateRandom(N, 2048);
                a  = new LongPolynomial2(i1);
                b  = new LongPolynomial2(i2);
                c1 = i1.Multiply(i2);
                c1.ModPositive(2048);
                c2 = a.Multiply(b).ToIntegerPolynomial();
                Assert.True(c1.coeffs.SequenceEqual(c2.coeffs));
            }
        }
Beispiel #3
0
        public void testMult()
        {
            BigDecimalPolynomial a = new BigDecimalPolynomial(new BigIntPolynomial(new IntegerPolynomial(new int[] { 4, -1, 9, 2, 1, -5, 12, -7, 0, -9, 5 })));
            BigDecimalPolynomial b = new BigDecimalPolynomial(new BigIntPolynomial(new IntegerPolynomial(new int[] { -6, 0, 0, 13, 3, -2, -4, 10, 11, 2, -1 })));
            BigDecimalPolynomial c = a.Multiply(b);

            decimal[] expectedCoeffs = new BigDecimalPolynomial(new BigIntPolynomial(new IntegerPolynomial(new int[] { 2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34 }))).getCoeffs();

            decimal[] cCoeffs = c.getCoeffs();

            Assert.AreEqual(expectedCoeffs.Length, cCoeffs.Length);
            for (int i = 0; i != cCoeffs.Length; i++)
            {
                Assert.AreEqual(expectedCoeffs[i], cCoeffs[i]);
            }

            // multiply a polynomial by its inverse modulo 2048 and check that the result is 1
            SecureRandom      random = new SecureRandom();
            IntegerPolynomial d, dInv;

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

            d.Mod(2048);
            BigDecimalPolynomial e = new BigDecimalPolynomial(new BigIntPolynomial(d));
            BigIntPolynomial     f = new BigIntPolynomial(dInv);
            IntegerPolynomial    g = new IntegerPolynomial(e.Multiply(f).round());

            g.ModPositive(2048);
            Assert.True(g.EqualsOne());
        }
Beispiel #4
0
        public void testMult()
        {
            // multiplication modulo q
            IntegerPolynomial a = new IntegerPolynomial(new int[] { -1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1 });
            IntegerPolynomial b = new IntegerPolynomial(new int[] { 14, 11, 26, 24, 14, 16, 30, 7, 25, 6, 19 });
            IntegerPolynomial c = a.Multiply(b, 32);

            assertEqualsMod(new int[] { 3, -7, -10, -11, 10, 7, 6, 7, 5, -3, -7 }, c.coeffs, 32);

            a = new IntegerPolynomial(new int[] { 15, 27, 18, 16, 12, 13, 16, 2, 28, 22, 26 });
            b = new IntegerPolynomial(new int[] { -1, 0, 1, 1, 0, 1, 0, 0, -1, 0, -1 });
            c = a.Multiply(b, 32);
            assertEqualsMod(new int[] { 8, 25, 22, 20, 12, 24, 15, 19, 12, 19, 16 }, c.coeffs, 32);

            // multiplication without a modulus
            a = new IntegerPolynomial(new int[] { 1, 1, 0, 0, -1, -1, 0, 0, -1, 0, 1 });
            b = new IntegerPolynomial(new int[] { 704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
            c = a.Multiply(b);

            // mult(p, modulus) should give the same result as mult(p) followed by modulus
            a = new IntegerPolynomial(new int[] { 1, 0, -1, 1, 0, 1, 1, 1, -1, 1, -1 });
            b = new IntegerPolynomial(new int[] { 0, 1, 1, 0, 0, -1, -1, 1, 1, -1, 1 });
            c = a.Multiply(b);
            c.ModPositive(20);
            IntegerPolynomial d = a.Multiply(b, 20);

            d.ModPositive(20);
            Assert.True(c.coeffs.SequenceEqual(d.coeffs));
        }
Beispiel #5
0
        private IntegerPolynomial sign(IntegerPolynomial i, SignatureKeyPair kp)
        {
            int N = param.N;
            int q = param.q;
            int perturbationBases = param.B;

            IntegerPolynomial s = new IntegerPolynomial(N);
            int iLoop           = perturbationBases;

            while (iLoop >= 1)
            {
                IPolynomial f      = kp.priv.getBasis(iLoop).f;
                IPolynomial fPrime = kp.priv.getBasis(iLoop).fPrime;

                IntegerPolynomial y = f.Multiply(i);
                y.Divide(q);
                y = fPrime.Multiply(y);

                IntegerPolynomial x = fPrime.Multiply(i);
                x.Divide(q);
                x = f.Multiply(x);

                IntegerPolynomial si = y;
                si.Subtract(x);
                s.Add(si);

                IntegerPolynomial hi = kp.priv.getBasis(iLoop).h.Clone();
                if (iLoop > 1)
                {
                    hi.Subtract(kp.priv.getBasis(iLoop - 1).h);
                }
                else
                {
                    hi.Subtract(kp.pub.h);
                }
                i = si.Multiply(hi, q);

                iLoop--;
            }

            IPolynomial f2      = kp.priv.getBasis(0).f;
            IPolynomial fPrime2 = kp.priv.getBasis(0).fPrime;

            IntegerPolynomial y2 = f2.Multiply(i);

            y2.Divide(q);
            y2 = fPrime2.Multiply(y2);

            IntegerPolynomial x2 = fPrime2.Multiply(i);

            x2.Divide(q);
            x2 = f2.Multiply(x2);

            y2.Subtract(x2);
            s.Add(y2);
            s.ModPositive(q);
            return(s);
        }
Beispiel #6
0
        public void testMult2And()
        {
            IntegerPolynomial i1 = new IntegerPolynomial(new int[] { 1368, 2047, 672, 871, 1662, 1352, 1099, 1608 });
            LongPolynomial2   i2 = new LongPolynomial2(i1);

            i2.mult2And(2047);
            i1.Multiply(2);
            i1.ModPositive(2048);
            Assert.True(i1.coeffs.SequenceEqual(i2.ToIntegerPolynomial().coeffs));
        }
Beispiel #7
0
        public void testSubAnd()
        {
            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);

            a.SubAnd(b, 2047);
            i1.Sub(i2);
            i1.ModPositive(2048);
            Assert.True(a.ToIntegerPolynomial().coeffs.SequenceEqual(i1.coeffs));
        }
Beispiel #8
0
        private void Mult2AndTest()
        {
            IntegerPolynomial i1 = new IntegerPolynomial(new int[] { 1368, 2047, 672, 871, 1662, 1352, 1099, 1608 });
            LongPolynomial2   i2 = new LongPolynomial2(i1);

            i2.Mult2And(2047);
            i1.Multiply(2);
            i1.ModPositive(2048);

            if (!Compare.AreEqual(i1.Coeffs, i2.ToIntegerPolynomial().Coeffs))
            {
                throw new Exception("LongPolynomial2 Mult2And test failed!");
            }
        }
Beispiel #9
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 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));
            }
        }
Beispiel #10
0
        private void SubAndTest()
        {
            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);

            a.SubAnd(b, 2047);
            i1.Subtract(i2);
            i1.ModPositive(2048);

            if (!Compare.AreEqual(a.ToIntegerPolynomial().Coeffs, i1.Coeffs))
            {
                throw new Exception("LongPolynomial2 SubAnd test failed!");
            }
        }
        /// <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);
            }
        }
        private void MultTest()
        {
            // multiplication modulo q
            IntegerPolynomial a = new IntegerPolynomial(new int[] { -1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1 });
            IntegerPolynomial b = new IntegerPolynomial(new int[] { 14, 11, 26, 24, 14, 16, 30, 7, 25, 6, 19 });
            IntegerPolynomial c = a.Multiply(b, 32);

            AssertEqualsMod(new int[] { 3, -7, -10, -11, 10, 7, 6, 7, 5, -3, -7 }, c.Coeffs, 32);

            a = new IntegerPolynomial(new int[] { 15, 27, 18, 16, 12, 13, 16, 2, 28, 22, 26 });
            b = new IntegerPolynomial(new int[] { -1, 0, 1, 1, 0, 1, 0, 0, -1, 0, -1 });
            c = a.Multiply(b, 32);
            AssertEqualsMod(new int[] { 8, 25, 22, 20, 12, 24, 15, 19, 12, 19, 16 }, c.Coeffs, 32);

            // multiplication without a modulus
            a = new IntegerPolynomial(new int[] { 1, 1, 0, 0, -1, -1, 0, 0, -1, 0, 1 });
            b = new IntegerPolynomial(new int[] { 2, 14, -10, 10, -4, -10, 2, 12, 11, -2, 8 });
            c = a.Multiply(b);

            if (!Compare.AreEqual(new int[] { 0, -13, 15, -12, -26, -39, 2, 17, 13, 17, 26 }, c.Coeffs))
            {
                throw new Exception("IntegerPolynomial multiplication test failed!");
            }

            // mult(p, modulus) should give the same result as mult(p) followed by modulus
            a = new IntegerPolynomial(new int[] { 1, 0, -1, 1, 0, 1, 1, 1, -1, 1, -1 });
            b = new IntegerPolynomial(new int[] { 0, 1, 1, 0, 0, -1, -1, 1, 1, -1, 1 });
            c = a.Multiply(b);
            c.ModPositive(20);
            IntegerPolynomial d = a.Multiply(b, 20);

            d.ModPositive(20);

            if (!Compare.AreEqual(c.Coeffs, d.Coeffs))
            {
                throw new Exception("IntegerPolynomial multiplication test failed!");
            }
        }
Beispiel #13
0
        /// <summary>
        /// Decrypts a message
        /// </summary>
        ///
        /// <param name="Input">The message to decrypt</param>
        ///
        /// <returns>The decrypted message</returns>
        ///
        /// <exception cref="NTRUException">If not initialized, the specified hash algorithm is invalid, the encrypted data is invalid, or <c>MaxLenBytes</c> is greater than 255</exception>
        public byte[] Decrypt(byte[] Input)
        {
            if (!_isInitialized)
            {
                throw new NTRUException("NTRUEncrypt:Decrypt", "The cipher has not been initialized!", new InvalidOperationException());
            }

            IPolynomial       priv_t  = ((NTRUPrivateKey)_keyPair.PrivateKey).T;
            IntegerPolynomial priv_fp = ((NTRUPrivateKey)_keyPair.PrivateKey).FP;
            IntegerPolynomial pub     = ((NTRUPublicKey)_keyPair.PublicKey).H;
            int  N               = _encParams.N;
            int  q               = _encParams.Q;
            int  db              = _encParams.Db;
            int  maxMsgLenBytes  = _encParams.MaxMsgLenBytes;
            int  dm0             = _encParams.Dm0;
            int  maxM1           = _encParams.MaxM1;
            int  minCallsMask    = _encParams.MinMGFHashCalls;
            bool hashSeed        = _encParams.HashSeed;
            int  bLen            = db / 8;
            IntegerPolynomial e  = IntegerPolynomial.FromBinary(Input, N, q);
            IntegerPolynomial ci = Decrypt(e, priv_t, priv_fp);

            if (ci.Count(-1) < dm0)
            {
                throw new NTRUException("NTRUEncrypt:Decrypt", "Less than dm0 coefficients equal -1", new InvalidDataException());
            }
            if (ci.Count(0) < dm0)
            {
                throw new NTRUException("NTRUEncrypt:Decrypt", "Less than dm0 coefficients equal 0", new InvalidDataException());
            }
            if (ci.Count(1) < dm0)
            {
                throw new NTRUException("NTRUEncrypt:Decrypt", "Less than dm0 coefficients equal 1", new InvalidDataException());
            }
            //if (maxMsgLenBytes > 255)
            //    throw new NTRUException("NTRUEncrypt:Decrypt", "maxMsgLenBytes values bigger than 255 are not supported", new ArgumentOutOfRangeException());

            IntegerPolynomial cR = e;

            cR.Subtract(ci);
            cR.ModPositive(q);

            byte[]            coR4   = cR.ToBinary4();
            IntegerPolynomial mask   = MGF(coR4, N, minCallsMask, hashSeed);
            IntegerPolynomial cMTrin = ci;

            cMTrin.Subtract(mask);
            cMTrin.Mod3();

            byte[] cb, p0, cm;
            using (BinaryReader reader = new BinaryReader(new MemoryStream(cMTrin.ToBinary3Sves(maxM1 > 0))))
            {
                cb = new byte[bLen];
                reader.Read(cb, 0, cb.Length);
                // llen=1, so read one byte
                int cl = reader.ReadByte() & 0xFF;

                if (cl > maxMsgLenBytes)
                {
                    throw new NTRUException("NTRUEncrypt:Decrypt", string.Format("Message too long: {0} > {1}!", cl, maxMsgLenBytes), new InvalidDataException());
                }

                cm = new byte[cl];
                reader.Read(cm, 0, cm.Length);
                p0 = new byte[reader.BaseStream.Length - reader.BaseStream.Position];
                reader.Read(p0, 0, p0.Length);
            }

            if (!Compare.AreEqual(p0, new byte[p0.Length]))
            {
                throw new NTRUException("NTRUEncrypt:Decrypt", "The message is not followed by zeroes!", new InvalidDataException());
            }

            byte[]            sData   = GetSeed(cm, pub, cb);
            IPolynomial       cr      = GenerateBlindingPoly(sData);
            IntegerPolynomial cRPrime = cr.Multiply(pub);

            cRPrime.ModPositive(q);

            if (!cRPrime.Equals(cR))
            {
                throw new NTRUException("NTRUEncrypt:Decrypt", "Invalid message encoding!", new InvalidDataException());
            }

            return(cm);
        }
Beispiel #14
0
        /// <summary>
        /// Tests if the key pair is valid.
        /// <para>See IEEE 1363.1 section 9.2.4.1.</para>
        /// </summary>
        ///
        /// <returns>if the key pair is valid, <c>true</c> otherwise false</returns>
        public bool IsValid()
        {
            int N = ((NTRUPrivateKey)PrivateKey).N;
            int q = ((NTRUPrivateKey)PrivateKey).Q;
            TernaryPolynomialType polyType = ((NTRUPrivateKey)PrivateKey).PolyType;

            if (((NTRUPublicKey)PublicKey).N != N)
            {
                return(false);
            }
            if (((NTRUPublicKey)PublicKey).Q != q)
            {
                return(false);
            }
            if (((NTRUPrivateKey)PrivateKey).T.ToIntegerPolynomial().Coeffs.Length != N)
            {
                return(false);
            }

            IntegerPolynomial h = ((NTRUPublicKey)PublicKey).H.ToIntegerPolynomial();

            if (h.Coeffs.Length != N)
            {
                return(false);
            }
            if (!h.IsReduced(q))
            {
                return(false);
            }

            IntegerPolynomial f = ((NTRUPrivateKey)PrivateKey).T.ToIntegerPolynomial();

            if (polyType == TernaryPolynomialType.SIMPLE && !f.IsTernary())
            {
                return(false);
            }
            // if t is a ProductFormPolynomial, ternarity of f1,f2,f3 doesn't need to be verified
            if (polyType == TernaryPolynomialType.PRODUCT && !(((NTRUPrivateKey)PrivateKey).T.GetType().Equals(typeof(ProductFormPolynomial))))
            {
                return(false);
            }

            if (polyType == TernaryPolynomialType.PRODUCT)
            {
                f.Multiply(3);
                f.Coeffs[0] += 1;
                f.ModPositive(q);
            }

            // the key generator pre-multiplies h by 3, so divide by 9 instead of 3
            int inv9 = IntEuclidean.Calculate(9, q).X;   // 9^-1 mod q

            IntegerPolynomial g = f.Multiply(h, q);

            g.Multiply(inv9);
            g.ModCenter(q);

            if (!g.IsTernary())
            {
                return(false);
            }

            int dg = N / 3;   // see EncryptionParameters.Initialize()

            if (g.Count(1) != dg)
            {
                return(false);
            }
            if (g.Count(-1) != dg - 1)
            {
                return(false);
            }

            return(true);
        }
Beispiel #15
0
        private IntegerPolynomial sign(IntegerPolynomial i, SignatureKeyPair kp)
        {
            int N = param.N;
            int q = param.q;
            int perturbationBases = param.B;

            IntegerPolynomial s = new IntegerPolynomial(N);
            int iLoop = perturbationBases;
            while (iLoop >= 1)
            {
                IPolynomial f = kp.priv.getBasis(iLoop).f;
                IPolynomial fPrime = kp.priv.getBasis(iLoop).fPrime;

                IntegerPolynomial y = f.Multiply(i);
                y.Divide(q);
                y = fPrime.Multiply(y);

                IntegerPolynomial x = fPrime.Multiply(i);
                x.Divide(q);
                x = f.Multiply(x);

                IntegerPolynomial si = y;
                si.Subtract(x);
                s.Add(si);

                IntegerPolynomial hi = kp.priv.getBasis(iLoop).h.Clone();
                if (iLoop > 1)
                    hi.Subtract(kp.priv.getBasis(iLoop - 1).h);
                else
                    hi.Subtract(kp.pub.h);
                i = si.Multiply(hi, q);

                iLoop--;
            }

            IPolynomial f2 = kp.priv.getBasis(0).f;
            IPolynomial fPrime2 = kp.priv.getBasis(0).fPrime;

            IntegerPolynomial y2 = f2.Multiply(i);
            y2.Divide(q);
            y2 = fPrime2.Multiply(y2);

            IntegerPolynomial x2 = fPrime2.Multiply(i);
            x2.Divide(q);
            x2 = f2.Multiply(x2);

            y2.Subtract(x2);
            s.Add(y2);
            s.ModPositive(q);
            return s;
        }