/// <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))); }
/// <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)); }
/// <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]); } }
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)); } }
/// <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); }
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."); } }
public static UInt64 GetUInt64(this IRandom random) { return(BitConverter.ToUInt64(random.GetBytes(8), 0)); }