Exemple #1
0
        /// <summary>
        /// Encrypt a plain text message
        /// </summary>
        ///
        /// <param name="Input">The plain text</param>
        ///
        /// <returns>The cipher text</returns>
        ///
        /// <exception cref="CryptoAsymmetricException">Thrown if cipher has not been initialized, or input text is too long</exception>
        public byte[] Encrypt(byte[] Input)
        {
            if (!_isInitialized)
            {
                throw new CryptoAsymmetricException("RLWEEncrypt:Encrypt", "The cipher has not been initialized!", new InvalidOperationException());
            }
            if (Input.Length > _maxPlainText - _mFp)
            {
                throw new CryptoAsymmetricException("RLWEEncrypt:Encrypt", "The input text is too long!", new ArgumentOutOfRangeException());
            }
            if (!_isEncryption)
            {
                throw new CryptoAsymmetricSignException("RLWEEncrypt:Encrypt", "The cipher is not initialized for encryption!", new ArgumentException());
            }

            int plen = _N >> 3;

            if (_N == 512)
            {
                NTT512 ntt = new NTT512(_rndEngine);
                byte[] ptx = new byte[plen];

                if (Input.Length < _maxPlainText)
                {
                    ptx = _rndEngine.GetBytes(plen);
                    Array.Copy(Input, 0, ptx, _mFp, Input.Length);
                }
                else
                {
                    Array.Copy(Input, 0, ptx, 0, Input.Length);
                }

                return(ntt.Encrypt((RLWEPublicKey)_asmKey, ptx));
            }
            else
            {
                NTT256 ntt = new NTT256(_rndEngine);
                byte[] ptx = new byte[plen];

                if (Input.Length < _maxPlainText)
                {
                    ptx = _rndEngine.GetBytes(plen);
                    Array.Copy(Input, 0, ptx, _mFp, Input.Length);
                }
                else
                {
                    Array.Copy(Input, 0, ptx, 0, Input.Length);
                }

                return(ntt.Encrypt((RLWEPublicKey)_asmKey, ptx));
            }
        }
        public byte[] Encrypt(byte[] Input)
        {
            if (!m_isEncryption)
            {
                throw new CryptoAsymmetricException("PointchevalCipher:Encrypt", "The cipher is not initialized for encryption!", new ArgumentException());
            }

            int kDiv8 = m_K >> 3;

            // generate random r of length k div 8 bytes
            byte[] r = new byte[kDiv8];
            m_rndEngine.GetBytes(r);
            // generate random vector r' of length k bits
            GF2Vector rPrime = new GF2Vector(m_K, m_rndEngine);

            // convert r' to byte array
            byte[] rPrimeBytes = rPrime.GetEncoded();
            // compute (input||r)
            byte[] mr = ByteUtils.Concatenate(Input, r);
            // compute H(input||r)
            m_dgtEngine.BlockUpdate(mr, 0, mr.Length);
            byte[] hmr = new byte[m_dgtEngine.DigestSize];
            m_dgtEngine.DoFinal(hmr, 0);

            // convert H(input||r) to error vector z
            GF2Vector z = CCA2Conversions.Encode(m_N, m_T, hmr);

            // compute c1 = E(rPrime, z)
            byte[] c1 = CCA2Primitives.Encrypt((MPKCPublicKey)m_asmKey, rPrime, z).GetEncoded();
            byte[] c2;
            // get PRNG object
            using (KDF2 sr0 = new KDF2(GetDigest(m_cprParams.Digest)))
            {
                // seed PRNG with r'
                sr0.Initialize(rPrimeBytes);
                // generate random c2
                c2 = new byte[Input.Length + kDiv8];
                sr0.Generate(c2);
            }

            // XOR with input
            for (int i = 0; i < Input.Length; i++)
            {
                c2[i] ^= Input[i];
            }

            // XOR with r
            for (int i = 0; i < kDiv8; i++)
            {
                c2[Input.Length + i] ^= r[i];
            }

            // return (c1||c2)
            return(ByteUtils.Concatenate(c1, c2));
        }
        public Uuid Create()
        {
            var bytes = random.GetBytes(16);

            bytes[7] |= 0x40;
            bytes[7] &= 0x4f;
            bytes[8] |= 0x80;
            bytes[8] &= 0xbf;

            return(new Uuid(new Guid(bytes)));
        }
Exemple #4
0
        /// <remarks>
        /// Create keying material using a two stage generator
        /// </remarks>
        private byte[] GetBlock()
        {
            // generate seed; 2x input block per NIST sp800-90b
            byte[] seed = _seedEngine.GetBytes((_hashEngine.BlockSize * 2));

            if (_hashEngine.GetType().Equals(typeof(SHA512)) || _hashEngine.GetType().Equals(typeof(SHA256)))
            {
                // hmac key size is digest hash size: rfc 2104
                byte[] key = _seedEngine.GetBytes(_hashEngine.DigestSize);

                // set hmac to *not* dispose of underlying digest
                using (HMAC mac = new HMAC(_hashEngine, key, false))
                    return(mac.ComputeMac(seed));
            }
            else
            {
                // other implemented digests do not require hmac
                return(_hashEngine.ComputeHash(seed));
            }
        }
        public byte[] Encrypt(byte[] Input)
        {
            int kDiv8 = _K >> 3;

            // generate random r of length k div 8 bytes
            byte[] r = new byte[kDiv8];
            _secRnd.GetBytes(r);
            // generate random vector r' of length k bits
            GF2Vector rPrime = new GF2Vector(_K, _secRnd);

            // convert r' to byte array
            byte[] rPrimeBytes = rPrime.GetEncoded();
            // compute (input||r)
            byte[] mr = ByteUtils.Concatenate(Input, r);
            // compute H(input||r)
            _dgtEngine.BlockUpdate(mr, 0, mr.Length);
            byte[] hmr = new byte[_dgtEngine.DigestSize];
            _dgtEngine.DoFinal(hmr, 0);

            // convert H(input||r) to error vector z
            GF2Vector z = CCA2Conversions.Encode(_N, _T, hmr);

            // compute c1 = E(rPrime, z)
            byte[] c1 = CCA2Primitives.Encrypt((MPKCPublicKey)_keyPair.PublicKey, rPrime, z).GetEncoded();
            byte[] c2;
            // get PRNG object
            using (KDF2Drbg sr0 = new KDF2Drbg(GetDigest(_cipherParams.Digest)))
            {
                // seed PRNG with r'
                sr0.Initialize(rPrimeBytes);
                // generate random c2
                c2 = new byte[Input.Length + kDiv8];
                sr0.Generate(c2);
            }

            // XOR with input
            for (int i = 0; i < Input.Length; i++)
            {
                c2[i] ^= Input[i];
            }

            // XOR with r
            for (int i = 0; i < kDiv8; i++)
            {
                c2[Input.Length + i] ^= r[i];
            }

            // return (c1||c2)
            return(ByteUtils.Concatenate(c1, c2));
        }
Exemple #6
0
        /// <summary>
        /// Initalizes the key pair generator using a parameter set as input
        /// </summary>
        private void Initialize()
        {
            _numLayer      = _gmssParams.NumLayers;
            _heightOfTrees = _gmssParams.HeightOfTrees;
            _otsIndex      = _gmssParams.WinternitzParameter;
            m_K            = _gmssParams.K;

            // seeds
            _currentSeeds  = ArrayUtils.CreateJagged <byte[][]>(_numLayer, _mdLength);
            _nextNextSeeds = ArrayUtils.CreateJagged <byte[][]>(_numLayer - 1, _mdLength);

            // generation of initial seeds
            for (int i = 0; i < _numLayer; i++)
            {
                m_rndEngine.GetBytes(_currentSeeds[i]);
                _gmssRand.NextSeed(_currentSeeds[i]);
            }
        }
Exemple #7
0
        private void RandRangeTest(IRandom Rand, int Iterations = 1000)
        {
            byte[] data;
            int    x;
            long   y;
            int    min, max;

            min = Rand.Next(33);
            max = Rand.Next(34, 111);

            for (int i = 0; i < Iterations; i++)
            {
                data = Rand.GetBytes(i * 10);
            }

            for (int i = 1; i < Iterations; i++)
            {
                x = Rand.Next(i * min, i * max);
                if (x > i * max)
                {
                    throw new Exception(Rand.Name + ":Next returned a value above of the expected range.");
                }
                if (x < i * min)
                {
                    throw new Exception(Rand.Name + ":Next returned a value below of the expected range.");
                }
                y = Rand.NextLong(i * min, i * max);
                if (y > i * max)
                {
                    throw new Exception(Rand.Name + ":NextLong returned a value above of the expected range.");
                }
                if (y < i * min)
                {
                    throw new Exception(Rand.Name + ":NextLong returned a value below of the expected range.");
                }
            }
        }
        /// <summary>
        /// Encrypts a message
        /// </summary>
        ///
        /// <param name="Input">The message to encrypt</param>
        ///
        /// <returns>The encrypted message</returns>
        ///
        /// <exception cref="NTRUException">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 (!_isInitialized)
            {
                throw new NTRUException("NTRUEncrypt:Encrypt", "The cipher has not been initialized!", new InvalidOperationException());
            }

            IntegerPolynomial pub = ((NTRUPublicKey)_keyPair.PublicKey).H;
            int  N             = _encParams.N;
            int  q             = _encParams.Q;
            int  maxLenBytes   = _encParams.MaxMsgLenBytes;
            int  db            = _encParams.Db;
            int  bufferLenBits = _encParams.BufferLenBits;
            int  dm0           = _encParams.Dm0;
            int  maxM1         = _encParams.MaxM1;
            int  minCallsMask  = _encParams.MinMGFHashCalls;
            bool hashSeed      = _encParams.HashSeed;
            int  msgLen        = Input.Length;

            //if (maxLenBytes > 255)
            //    throw new NTRUException("len values bigger than 255 are not supported");
            if (msgLen > maxLenBytes)
            {
                throw new NTRUException("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
                _rndEngine.GetBytes(b);
                byte[] p0 = new byte[maxLenBytes + 1 - msgLen];
                byte[] msgTmp;

                using (BinaryWriter writer = new BinaryWriter(new MemoryStream((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));
            }
        }
Exemple #9
0
        /// <summary>
        /// Encrypt a plain text message
        /// </summary>
        ///
        /// <param name="Input">The plain text</param>
        ///
        /// <returns>The cipher text</returns>
        public byte[] Encrypt(byte[] Input)
        {
            if (!_isEncryption)
            {
                throw new CryptoAsymmetricSignException("KobaraImaiCipher:Encrypt", "The cipher is not initialized for encryption!", new ArgumentException());
            }

            int c2Len = _dgtEngine.DigestSize;
            int c4Len = _K >> 3;
            int c5Len = (BigMath.Binomial(_N, _T).BitLength - 1) >> 3;
            int mLen  = c4Len + c5Len - c2Len - MPKCINFO.Length;

            if (Input.Length > mLen)
            {
                mLen = Input.Length;
            }

            int c1Len = mLen + MPKCINFO.Length;
            int c6Len = c1Len + c2Len - c4Len - c5Len;

            // compute (m||const)
            byte[] mConst = new byte[c1Len];
            Array.Copy(Input, 0, mConst, 0, Input.Length);
            Array.Copy(MPKCINFO, 0, mConst, mLen, MPKCINFO.Length);

            // generate random r of length c2Len bytes
            byte[] r = new byte[c2Len];
            _rndEngine.GetBytes(r);

            byte[] c1;
            // get PRNG object ToDo:
            //DigestRandomGenerator sr0 = new DigestRandomGenerator(new SHA1Digest()); //why bc, why?
            using (KDF2Drbg sr0 = new KDF2Drbg(GetDigest(_cprParams.Digest)))
            {
                // seed PRNG with r'
                sr0.Initialize(r);
                // generate random sequence ...
                c1 = new byte[c1Len];
                sr0.Generate(c1);
            }

            // ... and XOR with (m||const) to obtain c1
            for (int i = c1Len - 1; i >= 0; i--)
            {
                c1[i] ^= mConst[i];
            }

            // compute H(c1) ...
            byte[] c2 = new byte[_dgtEngine.DigestSize];
            _dgtEngine.BlockUpdate(c1, 0, c1.Length);
            _dgtEngine.DoFinal(c2, 0);

            // ... and XOR with r
            for (int i = c2Len - 1; i >= 0; i--)
            {
                c2[i] ^= r[i];
            }

            // compute (c2||c1)
            byte[] c2c1 = ByteUtils.Concatenate(c2, c1);

            // split (c2||c1) into (c6||c5||c4), where c4Len is k/8 bytes, c5Len is
            // floor[log(n|t)]/8 bytes, and c6Len is c1Len+c2Len-c4Len-c5Len (may be 0).
            byte[] c6 = new byte[0];
            if (c6Len > 0)
            {
                c6 = new byte[c6Len];
                Array.Copy(c2c1, 0, c6, 0, c6Len);
            }

            byte[] c5 = new byte[c5Len];
            Array.Copy(c2c1, c6Len, c5, 0, c5Len);
            byte[] c4 = new byte[c4Len];
            Array.Copy(c2c1, c6Len + c5Len, c4, 0, c4Len);
            // convert c4 to vector over GF(2)
            GF2Vector c4Vec = GF2Vector.OS2VP(_K, c4);
            // convert c5 to error vector z
            GF2Vector z = CCA2Conversions.Encode(_N, _T, c5);

            // compute encC4 = E(c4, z)
            byte[] encC4 = CCA2Primitives.Encrypt((MPKCPublicKey)_asmKey, c4Vec, z).GetEncoded();

            // if c6Len > 0 return (c6||encC4)
            if (c6Len > 0)
            {
                return(ByteUtils.Concatenate(c6, encC4));
            }

            // else, return encC4
            return(encC4);
        }
Exemple #10
0
        private void RandRangeTest(IRandom Rand, int Iterations = 1000)
        {
            byte[] data;
            int x;
            long y;
            int min, max;
            min = Rand.Next(33);
            max = Rand.Next(34, 111);

            for (int i = 0; i < Iterations; i++)
                data = Rand.GetBytes(i * 10);

            for (int i = 1; i < Iterations; i++)
            {
                x = Rand.Next(i * min, i * max);
                if (x > i * max)
                    throw new Exception(Rand.Name + ":Next returned a value above of the expected range.");
                if (x < i * min)
                    throw new Exception(Rand.Name + ":Next returned a value below of the expected range.");
                y = Rand.NextLong(i * min, i * max);
                if (y > i * max)
                    throw new Exception(Rand.Name + ":NextLong returned a value above of the expected range.");
                if (y < i * min)
                    throw new Exception(Rand.Name + ":NextLong returned a value below of the expected range.");
            }
        }
Exemple #11
0
 public static UInt64 GetUInt64(this IRandom random)
 {
     return(BitConverter.ToUInt64(random.GetBytes(8), 0));
 }