Example #1
0
        /**
         * Reads a basis from an input stream and constructs a new basis.
         * @param is an input stream
         * @param params NtruSign parameters
         * @param include_h whether to read the polynomial <code>h</code> (<code>true</code>) or only <code>f</code> and <code>f'</code> (<code>false</code>)
         * @throws IOException
         */
        public Basis(MemoryStream ins, int N, int q, bool sparse, TernaryPolynomialType polyType, BasisType basisType, double keyNormBoundSq, bool include_h)
        {
            this.N = N;
            this.q = q;
            this.polyType = polyType;
            this.basisType = basisType;
            this.keyNormBoundSq = keyNormBoundSq;

            if (polyType == TernaryPolynomialType.PRODUCT)
                f = ProductFormPolynomial.FromBinary(ins, N);
            else
            {
                IntegerPolynomial fInt = IntegerPolynomial.FromBinary3Tight(ins, N);
                if (sparse)
                    f = new SparseTernaryPolynomial(fInt);
                else
                    f = new DenseTernaryPolynomial(fInt);
            }

            if (basisType == BasisType.STANDARD)
            {
                IntegerPolynomial fPrimeInt = IntegerPolynomial.FromBinary(ins, N, q);
                for (int i = 0; i < fPrimeInt.Coeffs.Length; i++)
                    fPrimeInt.Coeffs[i] -= q / 2;
                fPrime = fPrimeInt;
            }
            else
                if (polyType == TernaryPolynomialType.PRODUCT)
                    fPrime = ProductFormPolynomial.FromBinary(ins, N);
                else
                    fPrime = IntegerPolynomial.FromBinary3Tight(ins, N);

            if (include_h)
                h = IntegerPolynomial.FromBinary(ins, N, q);
        }
Example #2
0
 /**
  * Constructs a new basis from polynomials <code>f, f', h</code>.
  * @param f
  * @param fPrime
  * @param h
  * @param params NtruSign parameters
  */
 public Basis(IPolynomial f, IPolynomial fPrime, IntegerPolynomial h, int q, TernaryPolynomialType polyType, BasisType basisType, double keyNormBoundSq)
 {
     this.f = f;
     this.fPrime = fPrime;
     this.h = h;
     this.N = h.Coeffs.Length;
     this.q = q;
     this.polyType = polyType;
     this.basisType = basisType;
     this.keyNormBoundSq = keyNormBoundSq;
 }
Example #3
0
 public bool EqualTo(IPolynomial t)
 {
     return(Equals(t));
 }
 /**
  * Constructs a new private key from a polynomial
  *
  * @param h the public polynomial for the key.
  * @param t      the polynomial which determines the key: if <code>fastFp=true</code>, <code>f=1+3t</code>; otherwise, <code>f=t</code>
  * @param fp     the inverse of <code>f</code>
  * @param params the NtruEncrypt parameters to use
  */
 public NTRUEncryptionPrivateKeyParameters(IntegerPolynomial h, IPolynomial t, IntegerPolynomial fp, NTRUEncryptionParameters parameters) : base(true, parameters)
 {
     this.h  = h;
     this.t  = t;
     this.fp = fp;
 }
Example #5
0
        /// <summary>
        /// Reads a Private 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 NTRUPrivateKey(MemoryStream KeyStream)
        {
            BinaryReader dataStream = new BinaryReader(KeyStream);

            try
            {
                // ins.Position = 0; wrong here, ins pos is wrong
                _N = IntUtils.ReadShort(KeyStream);
                _Q = IntUtils.ReadShort(KeyStream);
                byte flags = dataStream.ReadByte();
                _sparse = (flags & 1) != 0;
                _fastFp = (flags & 2) != 0;

                _polyType = (flags & 4) == 0 ?
                    TernaryPolynomialType.SIMPLE :
                    TernaryPolynomialType.PRODUCT;

                if (PolyType == TernaryPolynomialType.PRODUCT)
                {
                    _T = ProductFormPolynomial.FromBinary(KeyStream, N);
                }
                else
                {
                    IntegerPolynomial fInt = IntegerPolynomial.FromBinary3Tight(KeyStream, N);

                    if (_sparse)
                        _T = new SparseTernaryPolynomial(fInt);
                    else
                        _T = new DenseTernaryPolynomial(fInt);
                }
            }
            catch (Exception ex)
            {
                throw new CryptoAsymmetricException("NTRUPrivateKey:Ctor", "The Private key could not be loaded!", ex);
            }

            Initialize();
        }
Example #6
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;
        }
Example #7
0
 public FGBasis(IPolynomial f, IPolynomial fPrime, IntegerPolynomial h, IntegerPolynomial F, IntegerPolynomial G, int q, TernaryPolynomialType polyType, BasisType basisType, double keyNormBoundSq) :
     base(f, fPrime, h, q, polyType, basisType, keyNormBoundSq)
 {
     ;
     this.F = F;
     this.G = G;
     this.q = q;
     this.keyNormBoundSq = keyNormBoundSq;
 }
Example #8
0
         private byte[] getEncoded(IPolynomial p)
 {
     if (p.GetType().IsAssignableFrom(typeof(ProductFormPolynomial)))
         return ((ProductFormPolynomial)p).toBinary();
     else
         return p.ToIntegerPolynomial().ToBinary3Tight();
 }
Example #9
0
        public static Tuple <BigInteger, BigInteger> AlgebraicSquareRoot(IPolynomial f, BigInteger m, int degree, IPolynomial dd, BigInteger p)
        {
            IPolynomial startPolynomial        = Polynomial.Modulus(dd, p);
            IPolynomial startInversePolynomial = Polynomial.ModularInverse(startPolynomial, p);

            IPolynomial resultPoly1 = FiniteFieldArithmetic.SquareRoot(startPolynomial, f, p, degree, m);
            IPolynomial resultPoly2 = Polynomial.ModularInverse(resultPoly1, p);

            BigInteger result1 = resultPoly1.Evaluate(m).Mod(p);
            BigInteger result2 = resultPoly2.Evaluate(m).Mod(p);

            IPolynomial resultSquared1 = Polynomial.ModMod(Polynomial.Square(resultPoly1), f, p);
            IPolynomial resultSquared2 = Polynomial.ModMod(Polynomial.Square(resultPoly2), f, p);

            bool bothResultsAgree = (resultSquared1.CompareTo(resultSquared2) == 0);

            if (bothResultsAgree)
            {
                bool resultSquaredEqualsInput1 = (startPolynomial.CompareTo(resultSquared1) == 0);
                bool resultSquaredEqualsInput2 = (startInversePolynomial.CompareTo(resultSquared1) == 0);

                if (resultSquaredEqualsInput1)
                {
                    return(new Tuple <BigInteger, BigInteger>(result1, result2));
                }
                else if (resultSquaredEqualsInput2)
                {
                    return(new Tuple <BigInteger, BigInteger>(result2, result1));
                }
            }

            return(new Tuple <BigInteger, BigInteger>(BigInteger.Zero, BigInteger.Zero));
        }
Example #10
0
        public Tuple <BigInteger, BigInteger> CalculateAlgebraicSide(CancellationToken cancelToken)
        {
            bool solutionFound = false;

            RootsOfS.AddRange(RelationsSet.Select(rel => new Tuple <BigInteger, BigInteger>(rel.A, rel.B)));

            PolynomialRing = new List <IPolynomial>();
            foreach (Relation rel in RelationsSet)
            {
                // poly(x) = A + (B * x)
                IPolynomial newPoly =
                    new Polynomial(
                        new Term[]
                {
                    new Term(rel.B, 1),
                    new Term(rel.A, 0)
                }
                        );

                PolynomialRing.Add(newPoly);
            }

            if (cancelToken.IsCancellationRequested)
            {
                return(new Tuple <BigInteger, BigInteger>(1, 1));
            }

            BigInteger  m      = polyBase;
            IPolynomial f      = (Polynomial)monicPoly.Clone();
            int         degree = f.Degree;

            IPolynomial fd = Polynomial.GetDerivativePolynomial(f);
            IPolynomial d3 = Polynomial.Product(PolynomialRing);
            IPolynomial derivativeSquared = Polynomial.Square(fd);
            IPolynomial d2 = Polynomial.Multiply(d3, derivativeSquared);
            IPolynomial dd = Polynomial.Mod(d2, f);

            // Set the result to S
            S           = dd;
            SRingSquare = dd;
            TotalS      = d2;

            algebraicNormCollection = RelationsSet.Select(rel => rel.AlgebraicNorm);
            AlgebraicProduct        = d2.Evaluate(m);
            AlgebraicSquare         = dd.Evaluate(m);
            AlgebraicProductModF    = dd.Evaluate(m).Mod(N);
            AlgebraicSquareResidue  = AlgebraicSquare.Mod(N);

            IsAlgebraicIrreducible = IsPrimitive(algebraicNormCollection);             // Irreducible check
            IsAlgebraicSquare      = AlgebraicSquareResidue.IsSquare();

            List <BigInteger> primes = new List <BigInteger>();
            List <Tuple <BigInteger, BigInteger> > resultTuples = new List <Tuple <BigInteger, BigInteger> >();

            BigInteger primeProduct = 1;

            BigInteger lastP = N / N.ToString().Length;             //((N * 3) + 1).NthRoot(3); //gnfs.QFB.Select(fp => fp.P).Max();

            while (!solutionFound)
            {
                if (primes.Count > 0 && resultTuples.Count > 0)
                {
                    primes.Remove(primes.First());
                    resultTuples.Remove(resultTuples.First());
                }

                do
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        return(new Tuple <BigInteger, BigInteger>(1, 1));
                    }

                    lastP = PrimeFactory.GetNextPrime(lastP + 1);

                    Tuple <BigInteger, BigInteger> lastResult = AlgebraicSquareRoot(f, m, degree, dd, lastP);

                    if (lastResult.Item1 != 0)
                    {
                        primes.Add(lastP);
                        resultTuples.Add(lastResult);
                    }
                }while (primes.Count < degree);


                if (primes.Count > degree)
                {
                    primes.Remove(primes.First());
                    resultTuples.Remove(resultTuples.First());
                }

                primeProduct = (resultTuples.Select(tup => BigInteger.Min(tup.Item1, tup.Item2)).Product());

                if (primeProduct < N)
                {
                    continue;
                }

                AlgebraicPrimes = primes;

                if (cancelToken.IsCancellationRequested)
                {
                    return(new Tuple <BigInteger, BigInteger>(1, 1));;
                }

                IEnumerable <IEnumerable <BigInteger> > permutations =
                    Combinatorics.CartesianProduct(resultTuples.Select(tup => new List <BigInteger>()
                {
                    tup.Item1, tup.Item2
                }));

                BigInteger rationalSquareRoot  = RationalSquareRootResidue;
                BigInteger algebraicSquareRoot = 1;

                foreach (List <BigInteger> X in permutations)
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        return(new Tuple <BigInteger, BigInteger>(1, 1));;
                    }

                    algebraicSquareRoot = FiniteFieldArithmetic.ChineseRemainder(N, X, primes);

                    BigInteger min = BigInteger.Min(rationalSquareRoot, algebraicSquareRoot);
                    BigInteger max = BigInteger.Max(rationalSquareRoot, algebraicSquareRoot);

                    BigInteger A = max + min;
                    BigInteger B = max - min;

                    BigInteger U = GCD.FindGCD(N, A);
                    BigInteger V = GCD.FindGCD(N, B);

                    if (U > 1 && U != N)
                    {
                        BigInteger rem   = 1;
                        BigInteger other = BigInteger.DivRem(N, U, out rem);

                        if (rem == 0)
                        {
                            solutionFound              = true;
                            V                          = other;
                            AlgebraicResults           = X;
                            AlgebraicSquareRootResidue = algebraicSquareRoot;

                            return(new Tuple <BigInteger, BigInteger>(U, V));
                        }
                    }

                    if (V > 1 && V != N)
                    {
                        BigInteger rem   = 1;
                        BigInteger other = BigInteger.DivRem(N, V, out rem);

                        if (rem == 0)
                        {
                            solutionFound = true;

                            U = other;
                            AlgebraicResults           = X;
                            AlgebraicSquareRootResidue = algebraicSquareRoot;

                            return(new Tuple <BigInteger, BigInteger>(U, V));
                        }
                    }
                }

                if (!solutionFound)
                {
                    gnfs.LogFunction($"No solution found amongst the algebraic square roots {{ {string.Join(", ", resultTuples.Select(tup => $"({ tup.Item1}, { tup.Item2})"))} }} mod primes {{ {string.Join(", ", primes.Select(p => p.ToString()))} }}");
                }
            }

            return(new Tuple <BigInteger, BigInteger>(1, 1));
        }
Example #11
0
        public static GNFS FindSquares(CancellationToken cancelToken, GNFS gnfs)
        {
            if (cancelToken.IsCancellationRequested)
            {
                return(gnfs);
            }

            Logging.LogMessage();
            Logging.LogMessage($"# of solution sets: {gnfs.CurrentRelationsProgress.FreeRelations.Count}");
            Logging.LogMessage();

            BigInteger polyBase = gnfs.PolynomialBase;

            List <List <Relation> > freeRelations = gnfs.CurrentRelationsProgress.FreeRelations;

            // Below randomly selects a solution set to try and find a square root of the polynomial in.

            // Each time this step is stopped and restarted, it will try a different solution set.
            // Previous used sets are tracked with the List<int> triedFreeRelationIndices

            if (triedFreeRelationIndices.Count == freeRelations.Count) // If we have exhausted our solution sets, alert the user. Number wont factor for some reason.
            {
                Logging.LogMessage("ERROR: ALL RELATION SETS HAVE BEEN TRIED...?");
                Logging.LogMessage($"If the number of solution sets ({freeRelations.Count}) is low, you may need to sieve some more and then re-run the matrix solving step.");
                Logging.LogMessage("If there are many solution sets, and you have tried them all without finding non-trivial factors, then something is wrong...");
                Logging.LogMessage();
                return(gnfs);
            }

            int freeRelationIndex = 0;

            do
            {
                freeRelationIndex = StaticRandom.Next(0, freeRelations.Count);
            }while (triedFreeRelationIndices.Contains(freeRelationIndex));

            triedFreeRelationIndices.Add(freeRelationIndex);                             // Add current selection to our list

            List <Relation> selectedRelationSet = freeRelations[freeRelationIndex];      // Get the solution set

            SquareFinder squareRootFinder = new SquareFinder(gnfs, selectedRelationSet); // If you want to solve for a new solution set, create a new instance

            Logging.LogMessage($"Selected solution set # {freeRelationIndex + 1}");
            Logging.LogMessage();
            Logging.LogMessage($"Selected set (a,b) pairs (count: {selectedRelationSet.Count}): {string.Join(" ", selectedRelationSet.Select(rel => $"({rel.A},{rel.B})"))}");
            Logging.LogMessage();
            Logging.LogMessage();
            Logging.LogMessage();
            Logging.LogMessage($"ƒ'(m)     = {squareRootFinder.PolynomialDerivative}");
            Logging.LogMessage($"ƒ'(m)^2   = {squareRootFinder.PolynomialDerivativeSquared}");
            Logging.LogMessage();
            Logging.LogMessage("Calculating Rational Square Root.");
            Logging.LogMessage("Please wait...");

            squareRootFinder.CalculateRationalSide();

            Logging.LogMessage("Completed.");
            Logging.LogMessage();
            Logging.LogMessage($"γ²        = {squareRootFinder.RationalProduct} IsSquare? {squareRootFinder.RationalProduct.IsSquare()}");
            Logging.LogMessage($"(γ  · ƒ'(m))^2 = {squareRootFinder.RationalSquare} IsSquare? {squareRootFinder.RationalSquare.IsSquare()}");
            Logging.LogMessage();
            Logging.LogMessage();
            Logging.LogMessage("Calculating Algebraic Square Root.");
            Logging.LogMessage("Please wait...");

            Tuple <BigInteger, BigInteger> foundFactors = squareRootFinder.CalculateAlgebraicSide(cancelToken);
            BigInteger P = foundFactors.Item1;
            BigInteger Q = foundFactors.Item2;

            if (cancelToken.IsCancellationRequested && P == 1 && Q == 1)
            {
                Logging.LogMessage("Square root search aborted!");
                return(gnfs);
            }

            Logging.LogMessage("Completed.");
            Logging.LogMessage();
            Logging.LogMessage();

            if (P != 1 || Q != 1)
            {
                Logging.LogMessage("NON-TRIVIAL FACTORS FOUND!");
                Logging.LogMessage();
            }

            IPolynomial S           = squareRootFinder.S;
            IPolynomial SRingSquare = squareRootFinder.SRingSquare;

            BigInteger prodS = SRingSquare.Evaluate(polyBase);

            IPolynomial reducedS = Polynomial.Field.Modulus(S, gnfs.N);

            BigInteger totalProdS    = squareRootFinder.TotalS.Evaluate(polyBase) * squareRootFinder.PolynomialDerivative;
            BigInteger totalProdModN = totalProdS % gnfs.N;
            BigInteger prodSmodN     = prodS % gnfs.N;

            List <BigInteger> algebraicNumberFieldSquareRoots = squareRootFinder.AlgebraicResults;

            BigInteger rationalSquareRoot  = squareRootFinder.RationalSquareRootResidue;
            BigInteger algebraicSquareRoot = squareRootFinder.AlgebraicSquareRootResidue;


            Logging.LogMessage($"∏ Sᵢ =");
            Logging.LogMessage($"{squareRootFinder.TotalS}");
            Logging.LogMessage();
            Logging.LogMessage($"∏ Sᵢ (mod ƒ) =");
            Logging.LogMessage($"{reducedS}");
            Logging.LogMessage();
            Logging.LogMessage("Polynomial ring:");
            Logging.LogMessage($"({string.Join(") * (", squareRootFinder.PolynomialRing.Select(ply => ply.ToString()))})");
            Logging.LogMessage();
            Logging.LogMessage("Primes:");
            Logging.LogMessage($"{string.Join(" * ", squareRootFinder.AlgebraicPrimes)}"); // .RelationsSet.Select(rel => rel.B).Distinct().OrderBy(relB => relB))
            Logging.LogMessage();
            Logging.LogMessage();
            Logging.LogMessage($"X² / ƒ(m) = {squareRootFinder.AlgebraicProductModF}  IsSquare? {squareRootFinder.AlgebraicProductModF.IsSquare()}");
            Logging.LogMessage();
            Logging.LogMessage($"");
            Logging.LogMessage($"AlgebraicPrimes: {squareRootFinder.AlgebraicPrimes.FormatString(false)}");
            Logging.LogMessage($"AlgebraicResults: {squareRootFinder.AlgebraicResults.FormatString(false)}");
            Logging.LogMessage($"");
            Logging.LogMessage($"*****************************");
            Logging.LogMessage($"");
            Logging.LogMessage($"AlgebraicSquareRootResidue: {squareRootFinder.AlgebraicSquareRootResidue}");
            Logging.LogMessage($"");
            Logging.LogMessage($"AlgebraicNumberFieldSquareRoots: {algebraicNumberFieldSquareRoots.FormatString(false)}");
            Logging.LogMessage($"");
            Logging.LogMessage($" RationalSquareRoot : {rationalSquareRoot}");
            Logging.LogMessage($" AlgebraicSquareRoot: {algebraicSquareRoot} ");
            Logging.LogMessage($"");
            Logging.LogMessage($"*****************************");
            Logging.LogMessage($"S (x)       = {prodSmodN}  IsSquare? {prodSmodN.IsSquare()}");
            Logging.LogMessage();
            Logging.LogMessage("Roots of S(x):");
            Logging.LogMessage($"{{{string.Join(", ", squareRootFinder.RootsOfS.Select(tup => (tup.Item2 > 1) ? $"{tup.Item1}/{tup.Item2}" : $"{tup.Item1}"))}}}");
Example #12
0
        /**
         * Tests if the basis is valid.
         * @param h the polynomial h (either from the public key or from this basis)
         * @return <code>true</code> if the basis is valid, <code>false</code> otherwise
         */
        public bool isValid(IntegerPolynomial h)
        {
            if (f.ToIntegerPolynomial().Coeffs.Length != N)
            {
                return(false);
            }
            if (fPrime.ToIntegerPolynomial().Coeffs.Length != N)
            {
                return(false);
            }

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

            // determine F, G, g from f, fPrime, h using the eqn. fG-Fg=q
            IPolynomial       FPoly = basisType == BasisType.STANDARD ? fPrime : f.Multiply(h, q);
            IntegerPolynomial F     = FPoly.ToIntegerPolynomial();
            IntegerPolynomial fq    = f.ToIntegerPolynomial().InvertFq(q);
            IPolynomial       g;

            if (basisType == BasisType.STANDARD)
            {
                g = f.Multiply(h, q);
            }
            else
            {
                g = fPrime;
            }
            IntegerPolynomial G = g.Multiply(F);

            G.Coeffs[0] -= q;
            G            = G.Multiply(fq, q);
            G.ModCenter(q);

            // check norms of F and G
            if (!new FGBasis(f, fPrime, h, F, G, q, polyType, basisType, keyNormBoundSq).isNormOk())
            {
                return(false);
            }
            // check norms of f and g
            int factor = N / 24;

            if (f.ToIntegerPolynomial().CenteredNormSq(q) * factor >= F.CenteredNormSq(q))
            {
                return(false);
            }
            if (g.ToIntegerPolynomial().CenteredNormSq(q) * factor >= G.CenteredNormSq(q))
            {
                return(false);
            }

            // check ternarity
            if (polyType == TernaryPolynomialType.SIMPLE)
            {
                if (!f.ToIntegerPolynomial().IsTernary())
                {
                    return(false);
                }
                if (!g.ToIntegerPolynomial().IsTernary())
                {
                    return(false);
                }
            }
            else
            {
                if (!(f.GetType().IsAssignableFrom(typeof(ProductFormPolynomial))))
                {
                    return(false);
                }
                if (!(g.GetType().IsAssignableFrom(typeof(ProductFormPolynomial))))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #13
0
        public static List <FactorPair> FindPolynomialRootsInRange(CancellationToken cancelToken, IPolynomial polynomial, IEnumerable <BigInteger> primes, BigInteger rangeFrom, BigInteger rangeTo, int totalFactorPairs)
        {
            List <FactorPair> result = new List <FactorPair>();

            BigInteger r = rangeFrom;

            while (r < rangeTo && result.Count < totalFactorPairs)
            {
                if (cancelToken.IsCancellationRequested)
                {
                    break;
                }

                IEnumerable <BigInteger> modList = primes.Where(p => p > r);
                List <BigInteger>        roots   = Polynomial.GetRootsMod(polynomial, r, modList);
                if (roots.Any())
                {
                    result.AddRange(roots.Select(p => new FactorPair(p, r)));
                }
                r++;
            }

            return(result.OrderBy(tup => tup.P).ToList());
        }
Example #14
0
 public Extrapolation(IPolynomial curve, double confidence)
 {
     Curve      = curve;
     Confidence = confidence;
 }
Example #15
0
        private void GenerateFQ(IRandom Rng, out IPolynomial T, out IntegerPolynomial Fq, out IntegerPolynomial Fp)
        {
            var N        = this.m_ntruParams.N;
            var q        = this.m_ntruParams.Q;
            var df       = this.m_ntruParams.DF;
            var df1      = this.m_ntruParams.DF1;
            var df2      = this.m_ntruParams.DF2;
            var df3      = this.m_ntruParams.DF3;
            var fastFp   = this.m_ntruParams.FastFp;
            var sparse   = this.m_ntruParams.Sparse;
            var polyType = this.m_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;
                }
            }
        }
 public GenericPolynomialExtensionField(IFiniteField subfield, IPolynomial polynomial)
 {
     this.subfield          = subfield;
     this.minimalPolynomial = polynomial;
 }
Example #17
0
 public CrcCalc8(IPolynomial polynomial)
 {
     poly  = polynomial;
     table = GenerateTable(poly);
 }
Example #18
0
 public IPolynomial Add(IPolynomial t)
 {
     return(AsPolynomial().Add(t));
 }
Example #19
0
 public bool EqualTo(IPolynomial t)
 {
     return(AsPolynomial().EqualTo(t));
 }
Example #20
0
 internal GenericPolynomialExtensionField(IFiniteField subfield, IPolynomial polynomial)
 {
     this.subfield     = subfield;
     minimalPolynomial = polynomial;
 }
Example #21
0
        /// <summary>
        /// Decrypts a message
        /// </summary>
        ///
        /// <param name="Input">The message to decrypt</param>
        ///
        /// <returns>The decrypted message</returns>
        ///
        /// <exception cref="CryptoAsymmetricException">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 (!m_isInitialized)
            {
                throw new CryptoAsymmetricException("NTRUEncrypt:Decrypt", "The cipher has not been initialized!", new InvalidOperationException());
            }

            IPolynomial       priv_t  = ((NTRUPrivateKey)m_keyPair.PrivateKey).T;
            IntegerPolynomial priv_fp = ((NTRUPrivateKey)m_keyPair.PrivateKey).FP;
            IntegerPolynomial pub     = ((NTRUPublicKey)m_keyPair.PublicKey).H;
            int  N               = m_encParams.N;
            int  q               = m_encParams.Q;
            int  db              = m_encParams.Db;
            int  maxMsgLenBytes  = m_encParams.MessageMax;
            int  dm0             = m_encParams.Dm0;
            int  maxM1           = m_encParams.MaxM1;
            int  minCallsMask    = m_encParams.MinMGFHashCalls;
            bool hashSeed        = m_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 CryptoAsymmetricException("NTRUEncrypt:Decrypt", "Less than dm0 coefficients equal -1", new InvalidDataException());
            }
            if (ci.Count(0) < dm0)
            {
                throw new CryptoAsymmetricException("NTRUEncrypt:Decrypt", "Less than dm0 coefficients equal 0", new InvalidDataException());
            }
            if (ci.Count(1) < dm0)
            {
                throw new CryptoAsymmetricException("NTRUEncrypt:Decrypt", "Less than dm0 coefficients equal 1", new InvalidDataException());
            }
            //if (maxMsgLenBytes > 255)
            //    throw new CryptoAsymmetricException("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 CryptoAsymmetricException("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.IsEqual(p0, new byte[p0.Length]))
            {
                throw new CryptoAsymmetricException("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 CryptoAsymmetricException("NTRUEncrypt:Decrypt", "Invalid message encoding!", new InvalidDataException());
            }

            return(cm);
        }
 internal GenericPolynomialExtensionField(IFiniteField subfield, IPolynomial polynomial)
 {
     this.subfield = subfield;
     this.minimalPolynomial = polynomial;
 }
Example #23
0
        /// <summary>
        /// Encrypts a message
        /// </summary>
        ///
        /// <param name="Input">The message to encrypt</param>
        ///
        /// <returns>The encrypted message</returns>
        ///
        /// <exception cref="CryptoAsymmetricException">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[] Encrypt(byte[] Input)
        {
            if (!m_isInitialized)
            {
                throw new CryptoAsymmetricException("NTRUEncrypt:Encrypt", "The cipher has not been initialized!", new InvalidOperationException());
            }

            IntegerPolynomial pub = ((NTRUPublicKey)m_keyPair.PublicKey).H;
            int  N               = m_encParams.N;
            int  q               = m_encParams.Q;
            int  maxLenBytes     = m_encParams.MessageMax;
            int  db              = m_encParams.Db;
            int  m_bufferLenBits = m_encParams.m_bufferLenBits;
            int  dm0             = m_encParams.Dm0;
            int  maxM1           = m_encParams.MaxM1;
            int  minCallsMask    = m_encParams.MinMGFHashCalls;
            bool hashSeed        = m_encParams.HashSeed;
            int  msgLen          = Input.Length;

            //if (maxLenBytes > 255)
            //    throw new CryptoAsymmetricException("len values bigger than 255 are not supported");
            if (msgLen > maxLenBytes)
            {
                throw new CryptoAsymmetricException("NTRUEncrypt:Encrypt", string.Format("Message too long: {0} > {1}!", msgLen, maxLenBytes), new InvalidDataException());
            }

            while (true)
            {
                // M = b|octL|m|p0
                byte[] b = new byte[db / 8];
                // forward padding
                m_rndEngine.GetBytes(b);
                byte[] p0 = new byte[maxLenBytes + 1 - msgLen];
                byte[] msgTmp;

                using (BinaryWriter writer = new BinaryWriter(new MemoryStream((m_bufferLenBits + 7) / 8)))
                {
                    writer.Write(b);
                    writer.Write((byte)msgLen);
                    writer.Write(Input);
                    writer.Write(p0);
                    msgTmp = ((MemoryStream)writer.BaseStream).ToArray();
                }

                // don't use the constant coeff if maxM1 is set; see below
                IntegerPolynomial mTrin = IntegerPolynomial.FromBinary3Sves(msgTmp, N, maxM1 > 0);
                byte[]            sData = GetSeed(Input, pub, b);
                IPolynomial       r     = GenerateBlindingPoly(sData);
                IntegerPolynomial R     = r.Multiply(pub, q);
                byte[]            oR4   = R.ToBinary4();
                IntegerPolynomial mask  = MGF(oR4, N, minCallsMask, hashSeed);
                mTrin.Add(mask);

                // If df and dr are close to N/3, and the absolute value of mTrin.sumCoeffs() is
                // large enough, the message becomes vulnerable to a meet-in-the-middle attack.
                // To prevent this, we set the constant coefficient to zero but first check to ensure
                // sumCoeffs() is small enough to keep the likelihood of a decryption failure low.
                if (maxM1 > 0)
                {
                    if (mTrin.SumCoeffs() > maxM1)
                    {
                        continue;
                    }
                    mTrin.Coeffs[0] = 0;
                }

                mTrin.Mod3();

                if (mTrin.Count(-1) < dm0)
                {
                    continue;
                }
                if (mTrin.Count(0) < dm0)
                {
                    continue;
                }
                if (mTrin.Count(1) < dm0)
                {
                    continue;
                }

                R.Add(mTrin, q);
                R.EnsurePositive(q);

                return(R.ToBinary(q));
            }
        }
Example #24
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;
 }
Example #25
0
 public IPolynomial Add(IPolynomial t)
 {
     return(AsPolynomial() + t.AsPolynomial());
 }
Example #26
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;
            }
        }
Example #27
0
 public static LEMatrix DifferentiationMatrix(this IPolynomial p) => Polynomial.DifferentiationMatrix(p.Degree);