예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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));
            }
        }
예제 #3
0
        /// <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));
            }
        }
예제 #4
0
        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!");
                    }
                }
            }
        }
예제 #5
0
        /// <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));
        }
예제 #6
0
        /// <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));
        }
예제 #7
0
        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();
        }
예제 #8
0
        /// <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();
            }
        }
예제 #9
0
        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();
        }