Beispiel #1
0
        /// <summary>
        /// Reads a parameter set from an input stream
        /// </summary>
        ///
        /// <param name="CipherParams">Stream containing a parameter set</param>
        public NTRUParameters(Stream CipherParams)
        {
            try
            {
                BinaryReader reader = new BinaryReader(CipherParams);

                _N               = reader.ReadInt32();
                _Q               = reader.ReadInt32();
                _DF              = reader.ReadInt32();
                _DF1             = reader.ReadInt32();
                _DF2             = reader.ReadInt32();
                _DF3             = reader.ReadInt32();
                _Db              = reader.ReadInt32();
                _Dm0             = reader.ReadInt32();
                _maxM1           = reader.ReadInt32();
                _cBits           = reader.ReadInt32();
                _minIGFHashCalls = reader.ReadInt32();
                _minMGFHashCalls = reader.ReadInt32();
                _hashSeed        = reader.ReadBoolean();
                _oId             = new byte[3];
                reader.Read(_oId, 0, _oId.Length);
                _sparseMode    = reader.ReadBoolean();
                _fastFp        = reader.ReadBoolean();
                _polyType      = (TernaryPolynomialType)reader.ReadInt32();
                _messageDigest = (Digests)reader.ReadInt32();
                _randomEngine  = (Prngs)reader.ReadInt32();

                Initialize();
            }
            catch (Exception ex)
            {
                throw new NTRUException("NTRUParameters:CTor", "The stream could not be read!", ex);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Builds a parameter set from an encoded input stream
        /// </summary>
        ///
        /// <param name="ParamStream">Stream containing a parameter set</param>
        ///
        /// <exception cref="CryptoAsymmetricException">Thrown if the Stream is unreadable</exception>
        public NTRUParameters(Stream ParamStream)
        {
            try
            {
                BinaryReader reader = new BinaryReader(ParamStream);

                _oId = new byte[OID_SIZE];
                reader.Read(_oId, 0, _oId.Length);
                _N               = reader.ReadInt32();
                _Q               = reader.ReadInt32();
                _DF              = reader.ReadInt32();
                _DF1             = reader.ReadInt32();
                _DF2             = reader.ReadInt32();
                _DF3             = reader.ReadInt32();
                _Db              = reader.ReadInt32();
                _Dm0             = reader.ReadInt32();
                _maxM1           = reader.ReadInt32();
                _cBits           = reader.ReadInt32();
                _minIGFHashCalls = reader.ReadInt32();
                _minMGFHashCalls = reader.ReadInt32();
                _hashSeed        = reader.ReadBoolean();
                _sparseMode      = reader.ReadBoolean();
                _fastFp          = reader.ReadBoolean();
                _polyType        = (TernaryPolynomialType)reader.ReadInt32();
                _dgtEngineType   = (Digests)reader.ReadInt32();
                _rndEngineType   = (Prngs)reader.ReadInt32();

                Initialize();
            }
            catch (Exception ex)
            {
                throw new CryptoAsymmetricException("NTRUParameters:CTor", "The stream could not be read!", ex);
            }
        }
Beispiel #3
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);
        }
        /**
         * Constructs a new private key from an input stream
         * @param is an input stream
         * @throws NtruException if an {@link IOException} occurs
         */
        public SignaturePrivateKey(MemoryStream ins)
        {
            bases = new List <Basis>();

            BinaryReader dataStream = new BinaryReader(ins);

            try
            {
                N = dataStream.ReadInt16();
                q = dataStream.ReadInt16();
                byte flags = dataStream.ReadByte();
                sparse         = (flags & 1) != 0;
                polyType       = (flags & 4) == 0 ? TernaryPolynomialType.SIMPLE : TernaryPolynomialType.PRODUCT;
                basisType      = ((flags & 8) == 0) ? BasisType.STANDARD : BasisType.TRANSPOSE;
                keyNormBoundSq = (float)dataStream.ReadInt32();

                int numBases = dataStream.ReadByte();
                for (int i = 0; i < numBases; i++)
                {
                    // include a public key h[i] in all bases except for the first one
                    add(new Basis(ins, N, q, sparse, polyType, basisType, keyNormBoundSq, i != 0));
                }
            }
            catch (IOException e)
            {
                throw new NtruException(e.Message);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Constructs a parameter set that uses product-form private keys (i.e. <c>PolyType=PRODUCT</c>).
        /// </summary>
        ///
        /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The NTRU family must be <c>2</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param>
        /// <param name="N">N number of polynomial coefficients</param>
        /// <param name="Q">The big Q Modulus</param>
        /// <param name="Df1">Number of ones in the private polynomial <c>f1</c></param>
        /// <param name="Df2">Number of ones in the private polynomial <c>f2</c></param>
        /// <param name="Df3">Number of ones in the private polynomial <c>f3</c></param>
        /// <param name="Dm0">Minimum acceptable number of -1's, 0's, and 1's in the polynomial <c>m'</c> in the last encryption step</param>
        /// <param name="MaxM1">Maximum absolute value of mTrin.sumCoeffs() or zero to disable this check. Values greater than zero cause the constant coefficient of the message to always be zero.</param>
        /// <param name="Db">Number of random bits to prepend to the message; should be a multiple of 8</param>
        /// <param name="CBits">The number of bits in candidate for deriving an index in IGF-2</param>
        /// <param name="MinIGFHashCalls">Minimum number of hash calls for the IGF to make</param>
        /// <param name="MinMGFHashCalls">Minimum number of calls to generate the masking polynomial</param>
        /// <param name="HashSeed">Whether to hash the seed in the MGF first (true) or use the seed directly (false)</param>
        /// <param name="Sparse">Whether to treat ternary polynomials as sparsely populated SparseTernaryPolynomial vs DenseTernaryPolynomial</param>
        /// <param name="FastFp">Whether <c>F=1+p*F</c> for a ternary <c>F</c> (true) or <c>F</c> is ternary (false)</param>
        /// <param name="Digest">The Message Digest engine to use; default is SHA512</param>
        /// <param name="Random">The pseudo random generator engine to use; default is CTRPrng</param>
        ///
        /// <exception cref="CryptoAsymmetricException">Thrown if the Oid format is invalid</exception>
        public NTRUParameters(byte[] OId, int N, int Q, int Df1, int Df2, int Df3, int Dm0, int MaxM1, int Db, int CBits, int MinIGFHashCalls, int MinMGFHashCalls,
                              bool HashSeed, bool Sparse, bool FastFp, Digests Digest = Digests.SHA512, Prngs Random = Prngs.CTRPrng)
        {
            if (OId.Length != OID_SIZE)
            {
                throw new CryptoAsymmetricException("NTRUParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException()));
            }
            if (OId[0] != (byte)AsymmetricEngines.NTRU)
            {
                throw new CryptoAsymmetricException("NTRUParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.NTRU, new ArgumentException()));
            }

            Array.Copy(OId, this.OId, Math.Min(OId.Length, OID_SIZE));
            _N               = N;
            _Q               = Q;
            _DF1             = Df1;
            _DF2             = Df2;
            _DF3             = Df3;
            _Db              = Db;
            _Dm0             = Dm0;
            _maxM1           = MaxM1;
            _cBits           = CBits;
            _minIGFHashCalls = MinIGFHashCalls;
            _minMGFHashCalls = MinMGFHashCalls;
            _hashSeed        = HashSeed;
            _sparseMode      = Sparse;
            _fastFp          = FastFp;
            _polyType        = TernaryPolynomialType.PRODUCT;
            _dgtEngineType   = Digest;
            _rndEngineType   = Random;

            Initialize();
        }
        /**
         * Constructs a new private key from an input stream
         * @param is an input stream
         * @throws NtruException if an {@link IOException} occurs
         */
        public SignaturePrivateKey(MemoryStream ins)
        {
            bases = new List<Basis>();

            BinaryReader dataStream = new BinaryReader(ins);
            try
            {
                N = dataStream.ReadInt16();
                q = dataStream.ReadInt16();
                byte flags = dataStream.ReadByte();
                sparse = (flags & 1) != 0;
                polyType = (flags & 4) == 0 ? TernaryPolynomialType.SIMPLE : TernaryPolynomialType.PRODUCT;
                basisType = ((flags & 8) == 0) ? BasisType.STANDARD : BasisType.TRANSPOSE;
                keyNormBoundSq = (float)dataStream.ReadInt32();

                int numBases = dataStream.ReadByte();
                for (int i = 0; i < numBases; i++)
                    // include a public key h[i] in all bases except for the first one
                    add(new Basis(ins, N, q, sparse, polyType, basisType, keyNormBoundSq, i != 0));
            }
            catch (IOException e)
            {
                throw new NtruException(e.Message);
            }
        }
Beispiel #7
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)
 {
     m_T        = T;
     m_FP       = FP;
     m_N        = N;
     m_Q        = Q;
     m_sparse   = Sparse;
     m_fastFp   = FastFp;
     m_polyType = PolyType;
 }
Beispiel #8
0
        /// <summary>
        /// Read a Private key from a stream
        /// </summary>
        ///
        /// <param name="KeyStream">The stream containing the key</param>
        ///
        /// <returns>An initialized NTRUPrivateKey class</returns>
        ///
        /// <exception cref="NTRUException">Thrown if the stream can not be read</exception>
        public static NTRUPrivateKey From(MemoryStream KeyStream)
        {
            BinaryReader dataStream = new BinaryReader(KeyStream);

            try
            {
                // ins.Position = 0; wrong here, ins pos is wrong
                int         n      = IntUtils.ReadShort(KeyStream);
                int         q      = IntUtils.ReadShort(KeyStream);
                byte        flags  = dataStream.ReadByte();
                bool        sparse = (flags & 1) != 0;
                bool        fastFp = (flags & 2) != 0;
                IPolynomial t;

                TernaryPolynomialType 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);
                    }
                }

                // Initializes fp from t
                IntegerPolynomial fp;
                if (fastFp)
                {
                    fp           = new IntegerPolynomial(n);
                    fp.Coeffs[0] = 1;
                }
                else
                {
                    fp = t.ToIntegerPolynomial().InvertF3();
                }

                return(new NTRUPrivateKey(t, fp, n, q, sparse, fastFp, polyType));
            }
            catch (IOException ex)
            {
                throw new NTRUException("NTRUPrivateKey:From", ex.Message, ex);
            }
        }
Beispiel #9
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;
 }
        /**
         * Constructs a private key that contains no bases
         */
        public SignaturePrivateKey(SignatureParameters param)
        {
            N              = param.N;
            q              = param.q;
            sparse         = param.sparse;
            polyType       = param.polyType;
            basisType      = param.basisType;
            keyNormBoundSq = param.keyNormBoundSq;

            bases = new List <Basis>();
        }
        /**
         * Constructs a private key that contains no bases
         */
        public SignaturePrivateKey(SignatureParameters param)
        {
            N = param.N;
            q = param.q;
            sparse = param.sparse;
            polyType = param.polyType;
            basisType = param.basisType;
            keyNormBoundSq = param.keyNormBoundSq;

            bases = new List<Basis>();
        }
Beispiel #12
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;
 }
Beispiel #13
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);
            }
        }
 /**
  * Constructs a parameter set that uses ternary private keys (i.e. </code>polyType=SIMPLE</code>).
  * @param N            number of polynomial coefficients
  * @param q            modulus
  * @param d            number of -1's in the private polynomials <code>f</code> and <code>g</code>
  * @param B            number of perturbations
  * @param basisType    whether to use the standard or transpose lattice
  * @param beta         balancing factor for the transpose lattice
  * @param normBound    maximum norm for valid signatures
  * @param keyNormBound maximum norm for the polynomials <code>F</code> and <code>G</code>
  * @param primeCheck   whether <code>2N+1</code> is prime
  * @param sparse       whether to treat ternary polynomials as sparsely populated ({@link SparseTernaryPolynomial} vs {@link DenseTernaryPolynomial})
  * @param keyGenAlg    <code>RESULTANT</code> produces better bases, <code>FLOAT</code> is slightly faster. <code>RESULTANT</code> follows the EESS standard while <code>FLOAT</code> is described in Hoffstein et al: An Introduction to Mathematical Cryptography.
  * @param hashAlg      a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method.
  */
 public SignatureParameters(int N, int q, int d, int B, BasisType basisType, float beta, float normBound, float keyNormBound, bool primeCheck, bool sparse, KeyGenAlg keyGenAlg, String hashAlg)
 {
     this.N            = N;
     this.q            = q;
     this.d            = d;
     this.B            = B;
     this.basisType    = basisType;
     this.beta         = beta;
     this.normBound    = normBound;
     this.keyNormBound = keyNormBound;
     this.primeCheck   = primeCheck;
     this.sparse       = sparse;
     this.keyGenAlg    = keyGenAlg;
     this.hashAlg      = hashAlg;
     polyType          = TernaryPolynomialType.SIMPLE;
     init();
 }
        /// <summary>
        /// Generates a new encryption key pair
        /// </summary>
        ///
        /// <param name="RngF">The random number generator to use for generating the secret polynomial f</param>
        /// <param name="RngG">The random number generator to use for generating the secret polynomial g</param>
        ///
        /// <returns>A key pair</returns>
        private IAsymmetricKeyPair GenerateKeyPair(IRandom RngF, IRandom RngG)
        {
            int  N      = _encParams.N;
            int  q      = _encParams.Q;
            bool fastFp = _encParams.FastFp;
            bool sparse = _encParams.Sparse;
            TernaryPolynomialType polyType = _encParams.PolyType;
            IPolynomial           t        = null;
            IntegerPolynomial     fq       = null;
            IntegerPolynomial     fp       = null;
            IntegerPolynomial     g        = null;

            if (ParallelUtils.IsParallel && _isParallel)
            {
                Action[] gA = new Action[] {
                    new Action(() => g = GenerateG(RngG)),
                    new Action(() => GenerateFQ(RngF, out t, out fq, out fp))
                };
                Parallel.Invoke(gA);
            }
            else
            {
                // Choose a random g that is invertible mod q.
                g = GenerateG(RngG);
                // choose a random f that is invertible mod 3 and q
                GenerateFQ(RngF, out t, out fq, out fp);
            }

            // if fastFp=true, fp=1
            if (fastFp)
            {
                fp           = new IntegerPolynomial(N);
                fp.Coeffs[0] = 1;
            }

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

            h.Mult3(q);
            h.EnsurePositive(q);

            NTRUPrivateKey priv = new NTRUPrivateKey(t, fp, N, q, sparse, fastFp, polyType);
            NTRUPublicKey  pub  = new NTRUPublicKey(h, N, q);

            return(new NTRUKeyPair(pub, priv));
        }
Beispiel #16
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
                m_N = IntUtils.ReadShort(KeyStream);
                m_Q = IntUtils.ReadShort(KeyStream);
                byte flags = dataStream.ReadByte();
                m_sparse = (flags & 1) != 0;
                m_fastFp = (flags & 2) != 0;

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

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

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

            Initialize();
        }
Beispiel #17
0
        /// <summary>
        /// Constructs a parameter set that uses ternary private keys (i.e. <c>PolyType=SIMPLE</c>)
        /// </summary>
        ///
        /// <param name="N">The ring dimension; the number of polynomial coefficients</param>
        /// <param name="Q">The big Q Modulus</param>
        /// <param name="Df">Number of ones in the private polynomial <c>f</c></param>
        /// <param name="Dm0">Minimum acceptable number of -1's, 0's, and 1's in the polynomial <c>m</c> in the last encryption step</param>
        /// <param name="MaxM1">Maximum absolute value of mTrin.sumCoeffs() or zero to disable this check. Values greater than zero cause the constant coefficient of the message to always be zero.</param>
        /// <param name="Db">Number of random bits to prepend to the message; should be a multiple of 8</param>
        /// <param name="CBits">The number of bits in candidate for deriving an index in IGF-2</param>
        /// <param name="MinIGFHashCalls">Minimum number of hash calls for the IGF to make</param>
        /// <param name="MinMGFHashCalls">Minimum number of calls to generate the masking polynomial</param>
        /// <param name="HashSeed">Whether to hash the seed in the MGF first (true), or use the seed directly (false)</param>
        /// <param name="OId">Three bytes that uniquely identify the parameter set</param>
        /// <param name="Sparse">Whether to treat ternary polynomials as sparsely populated; SparseTernaryPolynomial vs DenseTernaryPolynomial</param>
        /// <param name="FastFp">Whether <c>f=1+p*F</c> for a ternary <c>F</c> (true) or <c>f</c> is ternary (false)</param>
        /// <param name="Digest">The Message Digest engine to use; default is SHA512</param>
        /// <param name="Random">The pseudo random generator engine to use; default is CTRPrng</param>
        public NTRUParameters(int N, int Q, int Df, int Dm0, int MaxM1, int Db, int CBits, int MinIGFHashCalls, int MinMGFHashCalls,
                              bool HashSeed, byte[] OId, bool Sparse, bool FastFp, Digests Digest = Digests.SHA512, Prngs Random = Prngs.CTRPrng)
        {
            _N               = N;
            _Q               = Q;
            _DF              = Df;
            _Db              = Db;
            _Dm0             = Dm0;
            _maxM1           = MaxM1;
            _cBits           = CBits;
            _minIGFHashCalls = MinIGFHashCalls;
            _minMGFHashCalls = MinMGFHashCalls;
            _hashSeed        = HashSeed;
            _sparseMode      = Sparse;
            _fastFp          = FastFp;
            _polyType        = TernaryPolynomialType.SIMPLE;
            _messageDigest   = Digest;
            _randomEngine    = Random;
            this.OId         = OId;

            Initialize();
        }
        /**
         * Reads a parameter set from an input stream.
         * @param is an input stream
         * @throws IOException
         */
        public SignatureParameters(MemoryStream ins)
        {
            BinaryReader dis = new BinaryReader(ins);

            N                 = dis.ReadInt32();
            q                 = dis.ReadInt32();
            d                 = dis.ReadInt32();
            d1                = dis.ReadInt32();
            d2                = dis.ReadInt32();
            d3                = dis.ReadInt32();
            B                 = dis.ReadInt32();
            basisType         = (BasisType)dis.ReadInt32();
            beta              = dis.ReadSingle();
            normBound         = dis.ReadSingle();
            keyNormBound      = dis.ReadSingle();
            signFailTolerance = dis.ReadInt32();
            primeCheck        = dis.ReadBoolean();
            sparse            = dis.ReadBoolean();
            bitsF             = dis.ReadInt32();
            keyGenAlg         = (KeyGenAlg)dis.ReadInt32();
            hashAlg           = dis.ReadString();
            polyType          = (TernaryPolynomialType)dis.ReadInt32();
            init();
        }
Beispiel #19
0
        /// <summary>
        /// Builds a parameter set from an encoded input stream
        /// </summary>
        /// 
        /// <param name="ParamStream">Stream containing a parameter set</param>
        /// 
        /// <exception cref="CryptoAsymmetricException">Thrown if the Stream is unreadable</exception>
        public NTRUParameters(Stream ParamStream)
        {
            try
            {
                BinaryReader reader = new BinaryReader(ParamStream);

                _oId = new byte[OID_SIZE];
                reader.Read(_oId, 0, _oId.Length);
                _N = reader.ReadInt32();
                _Q = reader.ReadInt32();
                _DF = reader.ReadInt32();
                _DF1 = reader.ReadInt32();
                _DF2 = reader.ReadInt32();
                _DF3 = reader.ReadInt32();
                _Db = reader.ReadInt32();
                _Dm0 = reader.ReadInt32();
                _maxM1 = reader.ReadInt32();
                _cBits = reader.ReadInt32();
                _minIGFHashCalls = reader.ReadInt32();
                _minMGFHashCalls = reader.ReadInt32();
                _hashSeed = reader.ReadBoolean();
                _sparseMode = reader.ReadBoolean();
                _fastFp = reader.ReadBoolean();
                _polyType = (TernaryPolynomialType)reader.ReadInt32();
                _dgtEngineType = (Digests)reader.ReadInt32();
                _rndEngineType = (Prngs)reader.ReadInt32();

                Initialize();
            }
            catch (Exception ex)
            {
                throw new CryptoAsymmetricException("NTRUParameters:CTor", "The stream could not be read!", ex);
            }
        }
Beispiel #20
0
        /// <summary>
        /// Constructs a parameter set that uses product-form private keys (i.e. <c>PolyType=PRODUCT</c>).
        /// </summary>
        /// 
        /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The NTRU family must be <c>2</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param>
        /// <param name="N">N number of polynomial coefficients</param>
        /// <param name="Q">The big Q Modulus</param>
        /// <param name="Df1">Number of ones in the private polynomial <c>f1</c></param>
        /// <param name="Df2">Number of ones in the private polynomial <c>f2</c></param>
        /// <param name="Df3">Number of ones in the private polynomial <c>f3</c></param>
        /// <param name="Dm0">Minimum acceptable number of -1's, 0's, and 1's in the polynomial <c>m'</c> in the last encryption step</param>
        /// <param name="MaxM1">Maximum absolute value of mTrin.sumCoeffs() or zero to disable this check. Values greater than zero cause the constant coefficient of the message to always be zero.</param>
        /// <param name="Db">Number of random bits to prepend to the message; should be a multiple of 8</param>
        /// <param name="CBits">The number of bits in candidate for deriving an index in IGF-2</param>
        /// <param name="MinIGFHashCalls">Minimum number of hash calls for the IGF to make</param>
        /// <param name="MinMGFHashCalls">Minimum number of calls to generate the masking polynomial</param>
        /// <param name="HashSeed">Whether to hash the seed in the MGF first (true) or use the seed directly (false)</param>
        /// <param name="Sparse">Whether to treat ternary polynomials as sparsely populated SparseTernaryPolynomial vs DenseTernaryPolynomial</param>
        /// <param name="FastFp">Whether <c>F=1+p*F</c> for a ternary <c>F</c> (true) or <c>F</c> is ternary (false)</param>
        /// <param name="Digest">The Message Digest engine to use; default is SHA512</param>
        /// <param name="Random">The pseudo random generator engine to use; default is CTRPrng</param>
        /// 
        /// <exception cref="CryptoAsymmetricException">Thrown if the Oid format is invalid</exception>
        public NTRUParameters(byte[] OId, int N, int Q, int Df1, int Df2, int Df3, int Dm0, int MaxM1, int Db, int CBits, int MinIGFHashCalls, int MinMGFHashCalls,
            bool HashSeed, bool Sparse, bool FastFp, Digests Digest = Digests.SHA512, Prngs Random = Prngs.CTRPrng)
        {
            if (OId.Length != OID_SIZE)
                throw new CryptoAsymmetricException("NTRUParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException()));
            if (OId[0] != (byte)AsymmetricEngines.NTRU)
                throw new CryptoAsymmetricException("NTRUParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.NTRU, new ArgumentException()));

            Array.Copy(OId, this.OId, Math.Min(OId.Length, OID_SIZE));
            _N = N;
            _Q = Q;
            _DF1 = Df1;
            _DF2 = Df2;
            _DF3 = Df3;
            _Db = Db;
            _Dm0 = Dm0;
            _maxM1 = MaxM1;
            _cBits = CBits;
            _minIGFHashCalls = MinIGFHashCalls;
            _minMGFHashCalls = MinMGFHashCalls;
            _hashSeed = HashSeed;
            _sparseMode = Sparse;
            _fastFp = FastFp;
            _polyType = TernaryPolynomialType.PRODUCT;
            _dgtEngineType = Digest;
            _rndEngineType = Random;

            Initialize();
        }
        /// <summary>
        /// Reads a parameter set from an input stream
        /// </summary>
        /// 
        /// <param name="CipherParams">Stream containing a parameter set</param>
        public NTRUParameters(Stream CipherParams)
        {
            try
            {
                BinaryReader reader = new BinaryReader(CipherParams);

                _N = reader.ReadInt32();
                _Q = reader.ReadInt32();
                _DF = reader.ReadInt32();
                _DF1 = reader.ReadInt32();
                _DF2 = reader.ReadInt32();
                _DF3 = reader.ReadInt32();
                _Db = reader.ReadInt32();
                _Dm0 = reader.ReadInt32();
                _maxM1 = reader.ReadInt32();
                _cBits = reader.ReadInt32();
                _minIGFHashCalls = reader.ReadInt32();
                _minMGFHashCalls = reader.ReadInt32();
                _hashSeed = reader.ReadBoolean();
                _oId = new byte[3];
                reader.Read(_oId, 0, _oId.Length);
                _sparseMode = reader.ReadBoolean();
                _fastFp = reader.ReadBoolean();
                _polyType = (TernaryPolynomialType)reader.ReadInt32();
                _messageDigest = (Digests)reader.ReadInt32();
                _randomEngine = (Prngs)reader.ReadInt32();

                Initialize();
            }
            catch (Exception ex)
            {
                throw new NTRUException("NTRUParameters:CTor", "The stream could not be read!", ex);
            }
        }
        /// <summary>
        /// Constructs a parameter set that uses product-form private keys (i.e. <c>PolyType=PRODUCT</c>).
        /// </summary>
        /// 
        /// <param name="N">N number of polynomial coefficients</param>
        /// <param name="Q">The big Q Modulus</param>
        /// <param name="Df1">Number of ones in the private polynomial <c>f1</c></param>
        /// <param name="Df2">Number of ones in the private polynomial <c>f2</c></param>
        /// <param name="Df3">Number of ones in the private polynomial <c>f3</c></param>
        /// <param name="Dm0">Minimum acceptable number of -1's, 0's, and 1's in the polynomial <c>m'</c> in the last encryption step</param>
        /// <param name="MaxM1">Maximum absolute value of mTrin.sumCoeffs() or zero to disable this check. Values greater than zero cause the constant coefficient of the message to always be zero.</param>
        /// <param name="Db">Number of random bits to prepend to the message; should be a multiple of 8</param>
        /// <param name="CBits">The number of bits in candidate for deriving an index in IGF-2</param>
        /// <param name="MinIGFHashCalls">Minimum number of hash calls for the IGF to make</param>
        /// <param name="MinMGFHashCalls">Minimum number of calls to generate the masking polynomial</param>
        /// <param name="HashSeed">Whether to hash the seed in the MGF first (true) or use the seed directly (false)</param>
        /// <param name="OId">Three bytes that uniquely identify the parameter set</param>
        /// <param name="Sparse">Whether to treat ternary polynomials as sparsely populated SparseTernaryPolynomial vs DenseTernaryPolynomial</param>
        /// <param name="FastFp">Whether <c>F=1+p*F</c> for a ternary <c>F</c> (true) or <c>F</c> is ternary (false)</param>
        /// <param name="Digest">The Message Digest engine to use; default is SHA512</param>
        /// <param name="Random">The pseudo random generator engine to use; default is CTRPrng</param>
        public NTRUParameters(int N, int Q, int Df1, int Df2, int Df3, int Dm0, int MaxM1, int Db, int CBits, int MinIGFHashCalls, int MinMGFHashCalls,
            bool HashSeed, byte[] OId, bool Sparse, bool FastFp, Digests Digest = Digests.SHA512, Prngs Random = Prngs.CTRPrng)
        {
            _N = N;
            _Q = Q;
            _DF1 = Df1;
            _DF2 = Df2;
            _DF3 = Df3;
            _Db = Db;
            _Dm0 = Dm0;
            _maxM1 = MaxM1;
            _cBits = CBits;
            _minIGFHashCalls = MinIGFHashCalls;
            _minMGFHashCalls = MinMGFHashCalls;
            _hashSeed = HashSeed;
            _sparseMode = Sparse;
            _fastFp = FastFp;
            _polyType = TernaryPolynomialType.PRODUCT;
            _messageDigest = Digest;
            _randomEngine = Random;
            this.OId = OId;

            Initialize();
        }
 /**
  * Reads a parameter set from an input stream.
  * @param is an input stream
  * @throws IOException
  */
 public SignatureParameters(MemoryStream ins)
 {
     BinaryReader dis = new BinaryReader(ins);
     N = dis.ReadInt32();
     q = dis.ReadInt32();
     d = dis.ReadInt32();
     d1 = dis.ReadInt32();
     d2 = dis.ReadInt32();
     d3 = dis.ReadInt32();
     B = dis.ReadInt32();
     basisType = (BasisType)dis.ReadInt32();
     beta = dis.ReadSingle();
     normBound = dis.ReadSingle();
     keyNormBound = dis.ReadSingle();
     signFailTolerance = dis.ReadInt32();
     primeCheck = dis.ReadBoolean();
     sparse = dis.ReadBoolean();
     bitsF = dis.ReadInt32();
     keyGenAlg = (KeyGenAlg)dis.ReadInt32();
     hashAlg = dis.ReadString();
     polyType = (TernaryPolynomialType)dis.ReadInt32();
     init();
 }
 /**
  * Constructs a parameter set that uses ternary private keys (i.e. </code>polyType=SIMPLE</code>).
  * @param N            number of polynomial coefficients
  * @param q            modulus
  * @param d            number of -1's in the private polynomials <code>f</code> and <code>g</code>
  * @param B            number of perturbations
  * @param basisType    whether to use the standard or transpose lattice
  * @param beta         balancing factor for the transpose lattice
  * @param normBound    maximum norm for valid signatures
  * @param keyNormBound maximum norm for the polynomials <code>F</code> and <code>G</code>
  * @param primeCheck   whether <code>2N+1</code> is prime
  * @param sparse       whether to treat ternary polynomials as sparsely populated ({@link SparseTernaryPolynomial} vs {@link DenseTernaryPolynomial})
  * @param keyGenAlg    <code>RESULTANT</code> produces better bases, <code>FLOAT</code> is slightly faster. <code>RESULTANT</code> follows the EESS standard while <code>FLOAT</code> is described in Hoffstein et al: An Introduction to Mathematical Cryptography.
  * @param hashAlg      a valid identifier for a <code>java.security.MessageDigest</code> instance such as <code>SHA-256</code>. The <code>MessageDigest</code> must support the <code>getDigestLength()</code> method.
  */
 public SignatureParameters(int N, int q, int d, int B, BasisType basisType, float beta, float normBound, float keyNormBound, bool primeCheck, bool sparse, KeyGenAlg keyGenAlg, String hashAlg)
 {
     this.N = N;
     this.q = q;
     this.d = d;
     this.B = B;
     this.basisType = basisType;
     this.beta = beta;
     this.normBound = normBound;
     this.keyNormBound = keyNormBound;
     this.primeCheck = primeCheck;
     this.sparse = sparse;
     this.keyGenAlg = keyGenAlg;
     this.hashAlg = hashAlg;
     polyType = TernaryPolynomialType.SIMPLE;
     init();
 }
        private void GenerateFQ(IRandom Rng, out IPolynomial t, out IntegerPolynomial fq, out IntegerPolynomial fp)
        {
            int  N      = _encParams.N;
            int  q      = _encParams.Q;
            int  df     = _encParams.DF;
            int  df1    = _encParams.DF1;
            int  df2    = _encParams.DF2;
            int  df3    = _encParams.DF3;
            bool fastFp = _encParams.FastFp;
            bool sparse = _encParams.Sparse;
            TernaryPolynomialType polyType = _encParams.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;
                }
            }
        }
Beispiel #26
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 #27
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;
 }
Beispiel #28
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;
 }
Beispiel #29
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();
        }
Beispiel #30
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;
 }