/// <remarks> /// Encrypts the key package buffer /// </remarks> private void TransformBuffer(byte[] KeyData, byte[] Salt) { byte[] kvm = new byte[48]; // use salt to derive key and counter vector using (Keccak512 digest = new Keccak512(384)) kvm = digest.ComputeHash(Salt); byte[] key = new byte[32]; byte[] iv = new byte[16]; Buffer.BlockCopy(kvm, 0, key, 0, key.Length); Buffer.BlockCopy(kvm, key.Length, iv, 0, iv.Length); byte[] outData = new byte[KeyData.Length]; using (KeyParams keyparam = new KeyParams(key, iv)) { // 32 rounds of serpent using (CTR cipher = new CTR(new SHX())) { cipher.Initialize(true, keyparam); cipher.Transform(KeyData, outData); } } Buffer.BlockCopy(outData, 0, KeyData, 0, KeyData.Length); }
/// <summary> /// Función encargada de descifrar el texto proporcionado por el usuario mediante 56 rondas del algoritmo Serpent /// </summary> /// <param name="txtCifrado">Cadena en Base64 con el texto cifrado</param> /// <returns>Cadena de texto plano con el texto descifrado</returns> public static string DescifraTxt(string txtCifrado) { using (var cifradoCEX = new CTR(new SPX(56))) { byte[] txtBytesCifrado = Convert.FromBase64String(txtCifrado); byte[] txtBytes = new byte[txtBytesCifrado.Length]; cifradoCEX.Initialize(true, new KeyParams(setClave(64), setClave(16))); cifradoCEX.Transform(txtBytesCifrado, txtBytes); return(Encoding.UTF32.GetString(txtBytes)); } }
/// <summary> /// Función encargada de cifrar el texto proporcionado por el usuario mediante 56 rondas del algoritmo Serpent /// </summary> /// <param name="txtPlano">Cadena con el texto en formato plano a cifrar</param> /// <returns>Cadena en Base64 con el texto cifrado</returns> public static string CifraTxt(string txtPlano) { using (var cifradoCEX = new CTR(new SPX(56))) { byte[] txtBytes = Encoding.UTF32.GetBytes(txtPlano); byte[] txtBytesCifrado = new byte[txtBytes.Length]; cifradoCEX.Initialize(true, new KeyParams(setClave(64), setClave(16))); cifradoCEX.Transform(txtBytes, txtBytesCifrado); return(Convert.ToBase64String(txtBytesCifrado)); } }
private void CTRTest(byte[] Key, byte[, ][] Input, byte[, ][] Output) { byte[] outBytes = new byte[16]; byte[] iv = _vectors[1]; int index = 24; if (Key.Length == 24) { index = 26; } else if (Key.Length == 32) { index = 28; } using (CTR mode = new CTR(new RHX())) { mode.Initialize(true, new KeyParams(Key, iv)); for (int i = 0; i < 4; i++) { mode.Transform(Input[index, i], outBytes); if (Evaluate.AreEqual(outBytes, Output[index, i]) == false) { throw new Exception("CTR Mode: Encrypted arrays are not equal!"); } } } index++; using (CTR mode = new CTR(new RHX())) { mode.Initialize(false, new KeyParams(Key, iv)); for (int i = 0; i < 4; i++) { mode.Transform(Input[index, i], outBytes); if (Evaluate.AreEqual(outBytes, _output[index, i]) == false) { throw new Exception("CTR Mode: Decrypted arrays are not equal!"); } } } }
/// <summary> /// Outputs expected values for 512 bit keys /// </summary> /// /// <returns>State</returns> public string Get512Vector(BlockCiphers EngineType, RoundCounts Rounds, int BlockSize = 16) { IBlockCipher engine = GetCipher(EngineType, Digests.None, Rounds, BlockSize); // rounds calc automatic int keyLen = 64; byte[] key = new byte[keyLen]; byte[] iv = new byte[engine.BlockSize]; ICipherMode cipher = new CTR(engine); for (int i = 0; i < keyLen; i++) { key[i] = (byte)i; } for (int i = 0; i < iv.Length; i++) { iv[i] = (byte)i; } cipher.Initialize(true, new KeyParams(key, iv)); return(MonteCarloTest(cipher)); }
/// <summary> /// Outputs expected values for the HX Ciphers /// </summary> /// /// <returns>State</returns> public string GetHXVector(BlockCiphers EngineType, Digests DigestType, RoundCounts Rounds) { IBlockCipher engine = GetCipher(EngineType, DigestType, Rounds); int keyLen = GetKeySize(engine); byte[] key = new byte[keyLen]; byte[] iv = new byte[engine.BlockSize]; ICipherMode cipher = new CTR(engine); for (int i = 0; i < keyLen; i++) { key[i] = (byte)i; } for (int i = 0; i < iv.Length; i++) { iv[i] = (byte)i; } cipher.Initialize(true, new KeyParams(key, iv)); return(MonteCarloTest(cipher)); }
private void ParallelTest() { byte[] data; byte[] dec1; byte[] dec2; byte[] enc1; byte[] enc2; int blockSize; KeyParams keyParam = new KeyParams(new byte[32], new byte[16]); // CTR mode using (CTR cipher = new CTR(new RHX())) { data = GetBytes(1036); // how to calculate an ideal block size int plen = (data.Length / cipher.ParallelMinimumSize) * cipher.ParallelMinimumSize; // you can factor it up or down or use a default if (plen > cipher.ParallelMaximumSize) { plen = 1024; } // set parallel block size cipher.ParallelBlockSize = plen; // parallel 1 cipher.Initialize(true, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; enc1 = Transform2(cipher, data, blockSize); // linear 1 cipher.Initialize(true, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; enc2 = Transform2(cipher, data, blockSize); if (Evaluate.AreEqual(enc1, enc2) == false) { throw new Exception("Parallel CTR: Encrypted output is not equal!"); } // encrypt // // parallel 2 cipher.Initialize(true, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; enc1 = Transform1(cipher, data, blockSize); if (Evaluate.AreEqual(enc1, enc2) == false) { throw new Exception("Parallel CTR: Encrypted output is not equal!"); } // linear 2 cipher.Initialize(true, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; enc2 = Transform2(cipher, data, blockSize); if (Evaluate.AreEqual(enc1, enc2) == false) { throw new Exception("Parallel CTR: Encrypted output is not equal!"); } // decrypt // // parallel 1 cipher.Initialize(false, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; dec1 = Transform1(cipher, enc1, blockSize); // parallel 2 cipher.Initialize(false, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; dec2 = Transform2(cipher, enc2, blockSize); if (Evaluate.AreEqual(dec1, dec2) == false) { throw new Exception("Parallel CTR: Decrypted output is not equal!"); } // linear 1 cipher.Initialize(false, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; dec2 = Transform1(cipher, enc1, blockSize); if (Evaluate.AreEqual(dec1, dec2) == false) { throw new Exception("Parallel CTR: Decrypted output is not equal!"); } // linear 2 cipher.Initialize(false, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; dec2 = Transform2(cipher, enc2, blockSize); if (Evaluate.AreEqual(dec1, dec2) == false) { throw new Exception("Parallel CTR: Decrypted output is not equal!"); } } if (Evaluate.AreEqual(data, dec1) == false) { throw new Exception("Parallel CTR: Decrypted output is not equal!"); } if (Evaluate.AreEqual(data, dec2) == false) { throw new Exception("Parallel CTR: Decrypted output is not equal!"); } OnProgress(new TestEventArgs("Passed Parallel CTR encryption and decryption tests..")); // CBC mode using (CBC cipher = new CBC(new RHX())) { // must be divisible by block size, add padding if required data = GetBytes(2048); // encrypt cipher.ParallelBlockSize = 1024; // t1: encrypt only in normal mode for cbc cipher.Initialize(true, keyParam); blockSize = cipher.BlockSize; enc1 = Transform1(cipher, data, blockSize); // t2 cipher.Initialize(true, keyParam); blockSize = cipher.BlockSize; enc2 = Transform2(cipher, data, blockSize); if (Evaluate.AreEqual(enc1, enc2) == false) { throw new Exception("Parallel CBC: Decrypted output is not equal!"); } // decrypt // // t1 parallel cipher.Initialize(false, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; dec1 = Transform1(cipher, enc1, blockSize); // t1 linear cipher.Initialize(false, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; dec2 = Transform1(cipher, enc2, blockSize); if (Evaluate.AreEqual(dec1, dec2) == false) { throw new Exception("Parallel CBC: Decrypted output is not equal!"); } // t2 parallel cipher.Initialize(false, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; dec1 = Transform2(cipher, enc2, blockSize); // t2 linear cipher.Initialize(false, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; dec2 = Transform2(cipher, enc1, blockSize); if (Evaluate.AreEqual(dec1, dec2) == false) { throw new Exception("Parallel CBC: Decrypted output is not equal!"); } } if (Evaluate.AreEqual(dec1, data) == false) { throw new Exception("Parallel CBC: Decrypted output is not equal!"); } if (Evaluate.AreEqual(dec2, data) == false) { throw new Exception("Parallel CBC: Decrypted output is not equal!"); } OnProgress(new TestEventArgs("Passed Parallel CBC decryption tests..")); // CFB mode using (CFB cipher = new CFB(new RHX())) { // must be divisible by block size, add padding if required data = GetBytes(2048); // encrypt cipher.ParallelBlockSize = 1024; // t1: encrypt only in normal mode for cfb cipher.Initialize(true, keyParam); blockSize = cipher.BlockSize; enc1 = Transform1(cipher, data, blockSize); // t2 cipher.Initialize(true, keyParam); blockSize = cipher.BlockSize; enc2 = Transform2(cipher, data, blockSize); if (Evaluate.AreEqual(enc1, enc2) == false) { throw new Exception("Parallel CFB: Decrypted output is not equal!"); } // decrypt // // t1 parallel cipher.Initialize(false, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; dec1 = Transform1(cipher, enc1, blockSize); // t1 linear cipher.Initialize(false, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; dec2 = Transform1(cipher, enc2, blockSize); if (Evaluate.AreEqual(dec1, dec2) == false) { throw new Exception("Parallel CFB: Decrypted output is not equal!"); } // t2 parallel cipher.Initialize(false, keyParam); cipher.IsParallel = true; blockSize = cipher.ParallelBlockSize; dec1 = Transform2(cipher, enc2, blockSize); // t2 linear cipher.Initialize(false, keyParam); cipher.IsParallel = false; blockSize = cipher.BlockSize; dec2 = Transform2(cipher, enc1, blockSize); if (Evaluate.AreEqual(dec1, dec2) == false) { throw new Exception("Parallel CFB: Decrypted output is not equal!"); } } if (Evaluate.AreEqual(data, dec1) == false) { throw new Exception("Parallel CFB: Decrypted output is not equal!"); } if (Evaluate.AreEqual(data, dec2) == false) { throw new Exception("Parallel CFB: Decrypted output is not equal!"); } OnProgress(new TestEventArgs("Passed Parallel CFB decryption tests..")); // dispose container keyParam.Dispose(); }
/// <summary> /// Test the PacketCipher class implementation /// <para>Throws an Exception on failure</</para> /// </summary> public static void PacketCipherTest() { const int BLSZ = 1024; KeyParams key; byte[] data; MemoryStream instrm; MemoryStream outstrm = new MemoryStream(); using (KeyGenerator kg = new KeyGenerator()) { // get the key key = kg.GetKeyParams(32, 16); // 2 * 1200 byte packets data = kg.GetBytes(BLSZ * 2); } // data to encrypt instrm = new MemoryStream(data); // Encrypt a stream // // create the outbound cipher using (ICipherMode cipher = new CTR(new RHX())) { // initialize the cipher for encryption cipher.Initialize(true, key); // set block size ((CTR)cipher).ParallelBlockSize = BLSZ; // encrypt the stream using (PacketCipher pc = new PacketCipher(cipher)) { byte[] inbuffer = new byte[BLSZ]; byte[] outbuffer = new byte[BLSZ]; int bytesread = 0; while ((bytesread = instrm.Read(inbuffer, 0, BLSZ)) > 0) { // encrypt the buffer pc.Write(inbuffer, 0, outbuffer, 0, BLSZ); // add it to the output stream outstrm.Write(outbuffer, 0, outbuffer.Length); } } } // reset stream position outstrm.Seek(0, SeekOrigin.Begin); MemoryStream tmpstrm = new MemoryStream(); // Decrypt a stream // // create the inbound cipher using (ICipherMode cipher = new CTR(new RHX())) { // initialize the cipher for decryption cipher.Initialize(false, key); // set block size ((CTR)cipher).ParallelBlockSize = BLSZ; // decrypt the stream using (PacketCipher pc = new PacketCipher(cipher)) { byte[] inbuffer = new byte[BLSZ]; byte[] outbuffer = new byte[BLSZ]; int bytesread = 0; while ((bytesread = outstrm.Read(inbuffer, 0, BLSZ)) > 0) { // process the encrypted bytes pc.Write(inbuffer, 0, outbuffer, 0, BLSZ); // write to stream tmpstrm.Write(outbuffer, 0, outbuffer.Length); } } } // compare decrypted output with data if (!Evaluate.AreEqual(tmpstrm.ToArray(), data)) { throw new Exception(); } }
private void CtrModeTest() { AllocateRandom(ref _iv, 16); AllocateRandom(ref _key, 32); KeyParams kp = new KeyParams(_key, _iv); RHX eng = new RHX(); CTR cipher = new CTR(eng); CTR cipher2 = new CTR(eng); CipherStream cs = new CipherStream(cipher2); cipher.IsParallel = false; // ctr test for (int i = 0; i < 10; i++) { int sze = AllocateRandom(ref _plnText); int prlBlock = sze - (sze % (cipher.BlockSize * _processorCount)); _encText = new byte[sze]; _cmpText = new byte[sze]; _decText = new byte[sze]; cipher.ParallelBlockSize = prlBlock; cipher2.ParallelBlockSize = prlBlock; MemoryStream mIn = new MemoryStream(_plnText); MemoryStream mOut = new MemoryStream(); MemoryStream mRes = new MemoryStream(); // *** Compare encryption output *** // // local processor cipher.Initialize(true, kp); BlockCTR(cipher, _plnText, 0, _encText, 0); // streamcipher linear mode cs.IsParallel = false; // memorystream interface cs.Initialize(true, kp); cs.Write(mIn, mOut); if (!Evaluate.AreEqual(mOut.ToArray(), _encText)) { throw new Exception("CipherStreamTest: Encrypted arrays are not equal!"); } // byte array interface cs.Initialize(true, kp); cs.Write(_plnText, 0, ref _cmpText, 0); if (!Evaluate.AreEqual(_cmpText, _encText)) { throw new Exception("CipherStreamTest: Encrypted arrays are not equal!"); } mIn.Seek(0, SeekOrigin.Begin); mOut.Seek(0, SeekOrigin.Begin); cs.IsParallel = true; cs.Initialize(true, kp); cs.Write(mIn, mOut); if (!Evaluate.AreEqual(mOut.ToArray(), _encText)) { throw new Exception("CipherStreamTest: Encrypted arrays are not equal!"); } // byte array interface cs.Initialize(true, kp); cs.Write(_plnText, 0, ref _cmpText, 0); if (!Evaluate.AreEqual(_cmpText, _encText)) { throw new Exception("CipherStreamTest: Encrypted arrays are not equal!"); } // ***compare decryption output *** // // local processor cipher.Initialize(false, kp); BlockCTR(cipher, _encText, 0, _decText, 0); if (!Evaluate.AreEqual(_plnText, _decText)) { throw new Exception("CipherStreamTest: Decrypted arrays are not equal!"); } // decrypt linear mode cs.IsParallel = false; mOut.Seek(0, SeekOrigin.Begin); cs.Initialize(false, kp); cs.Write(mOut, mRes); if (!Evaluate.AreEqual(mRes.ToArray(), _decText)) { throw new Exception("CipherStreamTest: Decrypted arrays are not equal!"); } // byte array interface cs.Initialize(false, kp); cs.Write(_encText, 0, ref _cmpText, 0); if (!Evaluate.AreEqual(_cmpText, _decText)) { throw new Exception("CipherStreamTest: Decrypted arrays are not equal!"); } // decrypt parallel mode cs.IsParallel = true; mOut.Seek(0, SeekOrigin.Begin); mRes.Seek(0, SeekOrigin.Begin); cs.Initialize(false, kp); cs.Write(mOut, mRes); if (!Evaluate.AreEqual(mRes.ToArray(), _decText)) { throw new Exception("CipherStreamTest: Decrypted arrays are not equal!"); } // byte array interface cs.Initialize(false, kp); cs.Write(_encText, 0, ref _cmpText, 0); if (!Evaluate.AreEqual(_cmpText, _decText)) { throw new Exception("CipherStreamTest: Decrypted arrays are not equal!"); } } eng.Dispose(); }