Esempio n. 1
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());
        }
        // verifies that res=rho*a mod x^n-1 mod p
        private void VerifyResultant(IntegerPolynomial a, Resultant r, int p)
        {
            BigIntPolynomial b = new BigIntPolynomial(a).MultSmall(r.Rho);

            b.Mod(BigInteger.ValueOf(p));

            for (int j = 1; j < b.Coeffs.Length - 1; j++)
            {
                if (!Compare.Equals(BigInteger.Zero, b.Coeffs[j]))
                {
                    throw new Exception("IntegerPolynomialTest VerifyResultant test failed!");
                }
            }
            if (r.Res.Equals(BigInteger.Zero))
            {
                if (!Compare.Equals(BigInteger.Zero, b.Coeffs[0].Subtract(b.Coeffs[b.Coeffs.Length - 1])))
                {
                    throw new Exception("IntegerPolynomialTest VerifyResultant test failed!");
                }
            }
            else
            {
                if (!Compare.Equals(BigInteger.Zero, (b.Coeffs[0].Subtract(b.Coeffs[b.Coeffs.Length - 1]).Subtract(r.Res).Mod(BigInteger.ValueOf(p)))))
                {
                    throw new Exception("IntegerPolynomialTest VerifyResultant test failed!");
                }
            }

            if (!Compare.Equals(BigInteger.Zero, b.Coeffs[0].Subtract(r.Res).Subtract(b.Coeffs[b.Coeffs.Length - 1].Negate()).Mod(BigInteger.ValueOf(p))))
            {
                throw new Exception("IntegerPolynomialTest VerifyResultant test failed!");
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Test the validity of the BigIntPolynomial implementation
        /// </summary>
        ///
        /// <returns>State</returns>
        public string Test()
        {
            try
            {
                BigIntPolynomial a        = new BigIntPolynomial(new IntegerPolynomial(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 }));
                BigIntPolynomial expected = new BigIntPolynomial(new IntegerPolynomial(new int[] { 2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34 }));
                if (!Compare.AreEqual(expected.Coeffs, a.MultSmall(b).Coeffs))
                {
                    throw new Exception("BigIntPolynomial known value test failed!");
                }
                OnProgress(new TestEventArgs("Passed round 1 BigIntPolynomial known value"));

                if (!Compare.AreEqual(expected.Coeffs, a.MultBig(b).Coeffs))
                {
                    throw new Exception("BigIntPolynomial known value test failed!");
                }
                OnProgress(new TestEventArgs("Passed round 2 BigIntPolynomial known value"));

                Random       rng     = new Random();
                BigInteger[] aCoeffs = new BigInteger[10 + rng.Next(50)];
                BigInteger[] bCoeffs = new BigInteger[aCoeffs.Length];

                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < aCoeffs.Length; j++)
                    {
                        byte[] aArr = new byte[600 + rng.Next(100)];
                        rng.NextBytes(aArr);
                        aCoeffs[j] = new BigInteger(aArr);
                        byte[] bArr = new byte[600 + rng.Next(100)];
                        rng.NextBytes(bArr);
                        bCoeffs[j] = new BigInteger(bArr);
                    }
                    a = new BigIntPolynomial(aCoeffs);
                    b = new BigIntPolynomial(bCoeffs);
                    if (!Compare.AreEqual(a.MultSmall(b).Coeffs, a.MultBig(b).Coeffs))
                    {
                        throw new Exception("BigIntPolynomial coefficient comparison test failed!");
                    }
                }
                OnProgress(new TestEventArgs("Passed BigIntPolynomial coefficient comparison"));

                return(SUCCESS);
            }
            catch (Exception Ex)
            {
                string message = Ex.Message == null ? "" : Ex.Message;
                throw new Exception(FAILURE + message);
            }
        }
Esempio n. 4
0
        public void testMult()
        {
            BigIntPolynomial a = new BigIntPolynomial(new IntegerPolynomial(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 }));
            BigIntPolynomial c = a.Multiply(b);

            BigInteger[] expectedCoeffs = new BigIntPolynomial(new IntegerPolynomial(new int[] { 2, -189, 77, 124, -29, 0, -75, 124, -49, 267, 34 })).GetCoeffs();
            BigInteger[] cCoeffs        = c.GetCoeffs();

            Assert.AreEqual(expectedCoeffs.Length, cCoeffs.Length);
            for (int i = 0; i != cCoeffs.Length; i++)
            {
                Assert.AreEqual(expectedCoeffs[i], cCoeffs[i]);
            }
        }
        /**
         * tests mult(IntegerPolynomial) and mult(BigIntPolynomial)
         */
        public void testMult()
        {
            SecureRandom            random = new SecureRandom();
            SparseTernaryPolynomial p1     = SparseTernaryPolynomial.GenerateRandom(1000, 500, 500, random);
            IntegerPolynomial       p2     = DenseTernaryPolynomial.GenerateRandom(1000, random);

            IntegerPolynomial prod1 = p1.Multiply(p2);
            IntegerPolynomial prod2 = p1.Multiply(p2);

            Assert.AreEqual(prod1.coeffs, prod2.coeffs);

            BigIntPolynomial p3    = new BigIntPolynomial(p2);
            BigIntPolynomial prod3 = p1.Multiply(p3);

            Assert.AreEqual((new BigIntPolynomial(prod1)).coeffs, prod3.coeffs);
        }
Esempio n. 6
0
        // verifies that res=rho*a mod x^n-1
        private void verifyResultant(IntegerPolynomial a, Resultant r)
        {
            BigIntPolynomial b = new BigIntPolynomial(a).Multiply(r.Rho);

            BigInteger[] bCoeffs = b.GetCoeffs();

            for (int j = 1; j < bCoeffs.Length - 1; j++)
            {
                Assert.AreEqual(BigInteger.Zero, bCoeffs[j]);
            }
            if (r.Res.Equals(BigInteger.Zero))
            {
                Assert.AreEqual(BigInteger.Zero, bCoeffs[0].Subtract(bCoeffs[bCoeffs.Length - 1]));
            }
            else
            {
                Assert.AreEqual(BigInteger.Zero, (bCoeffs[0].Subtract(bCoeffs[bCoeffs.Length - 1]).Mod(r.Res)));
            }
            Assert.AreEqual(bCoeffs[0].Subtract(r.Res), bCoeffs[bCoeffs.Length - 1].Negate());
        }
        /// <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);
            }
        }
        /** tests mult(IntegerPolynomial) and mult(BigIntPolynomial) */
        private void MultTest()
        {
            CSPRng rng = new CSPRng();
            SparseTernaryPolynomial p1 = SparseTernaryPolynomial.GenerateRandom(1000, 500, 500, rng);
            IntegerPolynomial       p2 = PolynomialGeneratorForTesting.generateRandom(1000);

            IntegerPolynomial prod1 = p1.Multiply(p2);

            prod1 = p1.Multiply(p2);
            IntegerPolynomial prod2 = p1.Multiply(p2);

            if (!Compare.Equals(prod1, prod2))
            {
                throw new Exception("SparseTernaryPolynomial multiplication test failed!");
            }

            BigIntPolynomial p3    = new BigIntPolynomial(p2);
            BigIntPolynomial prod3 = p1.Multiply(p3);

            if (!Compare.Equals(new BigIntPolynomial(prod1), prod3))
            {
                throw new Exception("SparseTernaryPolynomial multiplication test failed!");
            }
        }
Esempio n. 9
0
        /**
         * Creates a NtruSign basis consisting of polynomials <code>f, g, F, G, h</code>.<br/>
         * If <code>KeyGenAlg=FLOAT</code>, the basis may not be valid and this method must be rerun if that is the case.<br/>
         * @see #generateBoundedBasis()
         */
        private FGBasis generateBasis()
        {
            int       N         = param.N;
            int       q         = param.q;
            int       d         = param.d;
            int       d1        = param.d1;
            int       d2        = param.d2;
            int       d3        = param.d3;
            BasisType basisType = param.basisType;

            IPolynomial       f;
            IntegerPolynomial fInt;
            IPolynomial       g;
            IntegerPolynomial gInt;
            IntegerPolynomial fq;
            Resultant         rf;
            Resultant         rg;
            BigIntEuclidean   r;

            int  _2n1       = 2 * N + 1;
            bool primeCheck = param.primeCheck;

            Random rng = new Random();

            do
            {
                do
                {
                    if (param.polyType == TernaryPolynomialType.SIMPLE)
                    {
                        f = DenseTernaryPolynomial.GenerateRandom(N, d + 1, d);
                    }
                    else
                    {
                        f = ProductFormPolynomial.GenerateRandom(N, d1, d2, d3 + 1, d3);
                    }
                    fInt = f.ToIntegerPolynomial();
                } while (primeCheck && fInt.Resultant(_2n1).Res.Equals(BigInteger.Zero));
                fq = fInt.InvertFq(q);
            } while (fq == null);
            rf = fInt.Resultant();

            do
            {
                do
                {
                    do
                    {
                        if (param.polyType == TernaryPolynomialType.SIMPLE)
                        {
                            g = DenseTernaryPolynomial.GenerateRandom(N, d + 1, d);
                        }
                        else
                        {
                            g = ProductFormPolynomial.GenerateRandom(N, d1, d2, d3 + 1, d3);
                        }
                        gInt = g.ToIntegerPolynomial();
                    } while (primeCheck && gInt.Resultant(_2n1).Res.Equals(BigInteger.Zero));
                } while (!gInt.IsInvertiblePow2());
                rg = gInt.Resultant();
                r  = BigIntEuclidean.Calculate(rf.Res, rg.Res);
            } while (!r.GCD.Equals(BigInteger.One));

            BigIntPolynomial A = rf.Rho.Clone();

            A.Multiply(r.X.Multiply(BigInteger.ValueOf(q)));
            BigIntPolynomial B = rg.Rho.Clone();

            B.Multiply(r.Y.Multiply(BigInteger.ValueOf(-q)));

            BigIntPolynomial C;

            if (param.keyGenAlg == KeyGenAlg.RESULTANT)
            {
                int[] fRevCoeffs = new int[N];
                int[] gRevCoeffs = new int[N];
                fRevCoeffs[0] = fInt.Coeffs[0];
                gRevCoeffs[0] = gInt.Coeffs[0];
                for (int i = 1; i < N; i++)
                {
                    fRevCoeffs[i] = fInt.Coeffs[N - i];
                    gRevCoeffs[i] = gInt.Coeffs[N - i];
                }
                IntegerPolynomial fRev = new IntegerPolynomial(fRevCoeffs);
                IntegerPolynomial gRev = new IntegerPolynomial(gRevCoeffs);

                IntegerPolynomial t = f.Multiply(fRev);
                t.Add(g.Multiply(gRev));
                Resultant rt = t.Resultant();
                C = fRev.Multiply(B); // fRev.mult(B) is actually faster than new SparseTernaryPolynomial(fRev).mult(B), possibly due to cache locality?
                C.Add(gRev.Multiply(A));
                C = C.MultBig(rt.Rho);
                C.Divide(rt.Res);
            }
            else // KeyGenAlg.FLOAT
            // calculate ceil(log10(N))
            {
                int log10N = 0;
                for (int i = 1; i < N; i *= 10)
                {
                    log10N++;
                }

                // * Cdec needs to be accurate to 1 decimal place so it can be correctly rounded;
                // * fInv loses up to (#digits of longest coeff of B) places in fInv.mult(B);
                // * multiplying fInv by B also multiplies the rounding error by a factor of N;
                // so make #decimal places of fInv the sum of the above.
                BigDecimalPolynomial fInv = rf.Rho.Divide(new BigDecimal(rf.Res), B.GetMaxCoeffLength() + 1 + log10N);
                BigDecimalPolynomial gInv = rg.Rho.Divide(new BigDecimal(rg.Res), A.GetMaxCoeffLength() + 1 + log10N);

                BigDecimalPolynomial Cdec = fInv.Multiply(B);
                Cdec.Add(gInv.Multiply(A));
                Cdec.Halve();
                C = Cdec.Round();
            }

            BigIntPolynomial F = B.Clone();

            F.Subtract(f.Multiply(C));
            BigIntPolynomial G = A.Clone();

            G.Subtract(g.Multiply(C));

            IntegerPolynomial FInt = new IntegerPolynomial(F);
            IntegerPolynomial GInt = new IntegerPolynomial(G);

            minimizeFG(fInt, gInt, FInt, GInt, N);

            IPolynomial       fPrime;
            IntegerPolynomial h;

            if (basisType == BasisType.STANDARD)
            {
                fPrime = FInt;
                h      = g.Multiply(fq, q);
            }
            else
            {
                fPrime = g;
                h      = FInt.Multiply(fq, q);
            }
            h.ModPositive(q);

            return(new FGBasis(f, fPrime, h, FInt, GInt, param.q, param.polyType, param.basisType, param.keyNormBoundSq));
        }