Beispiel #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());
        }
        private BigDecimalPolynomial CreateBigDecimalPolynomial(int[] coeffs)
        {
            int N = coeffs.Length;
            BigDecimalPolynomial poly = new BigDecimalPolynomial(N);

            for (int i = 0; i < N; i++)
            {
                poly.Coeffs[i] = new BigDecimal(coeffs[i]);
            }

            return(poly);
        }
        /// <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);
            }
        }
Beispiel #4
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));
        }