Ejemplo n.º 1
0
        public void testResultant()
        {
            SecureRandom random = new SecureRandom();
            NTRUSigningKeyGenerationParameters parameters = NTRUSigningKeyGenerationParameters.APR2011_439;
            IntegerPolynomial a = DenseTernaryPolynomial.GenerateRandom(parameters.N, parameters.d, parameters.d, random);
            Resultant         r = a.Resultant();

            if (r.Rho.GetCoeffs().Length > parameters.N)
            {
                BigInteger[] trimmedArray = new BigInteger[parameters.N];
                Array.Copy(r.Rho.GetCoeffs(), trimmedArray, parameters.N);
                r.Rho.coeffs = trimmedArray;
            }
            verifyResultant(a, r);

            a = new IntegerPolynomial(new int[] { 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, -1, -1, 0, -1, 1, -1, 0, -1, 0, -1, -1, -1, 0, 0, 0, 1, 1, -1, -1, -1, 0, -1, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 1, 1, -1, 0, 1, -1, 0, 1, 0, 1, 0, -1, -1, 0, 1, 0, -1, 1, 1, 1, 1, 0, 0, -1, -1, 1, 0, 0, -1, -1, 0, -1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 1, 0, 1, -1, 0, 0, 1, 1, 1, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0, -1, -1, 0, -1, -1, -1, 0, -1, -1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, -1, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 1, 1, 0, 0, -1, 1, 0, 0, 0, -1, 1, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 1, 1, 0, 0, -1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0, 1, 0, -1, -1, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, -1, 1, -1, -1, 1, -1, 0, 1, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, -1, 0, 1, -1, 0, 0, 1, 1, 0, 0, 1, 1, 0, -1, 0, -1, 1, -1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 1, -1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, -1, -1, 0, 0, -1, 0, 1, 1, -1, 1, -1, 0, 0, 0, 1 });

            r = a.Resultant();
            if (r.Rho.GetCoeffs().Length > a.coeffs.Length)
            {
                BigInteger[] trimmedArray = new BigInteger[a.coeffs.Length];
                Array.Copy(r.Rho.GetCoeffs(), trimmedArray, a.coeffs.Length);
                r.Rho.coeffs = trimmedArray;
            }
            verifyResultant(a, r);
        }
        // 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!");
            }
        }
Ejemplo n.º 3
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());
        }
Ejemplo n.º 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));
        }