using System;
using System.Diagnostics;
using System.IO;
using CryptoSysAPI;

// Some tests using the CryptoSysAPI .NET interface.

/* 
 **************************** COPYRIGHT NOTICE ****************************
 * Copyright (C) 2005-6 DI Management Services Pty Limited. 
 * All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net>
 *   $Id: TestAPIcsharp.cs $
 *   Last updated:
 *   $Date: 2006-07-21 09:50:00 $
 *   $Version: 3.2.0 $
 ************************* END OF COPYRIGHT NOTICE ************************
 */

namespace TestAPIcsharp
{
    /// <summary>
    /// Test examples for CryptoSysAPI interface
    /// </summary>
    class TestAPIcsharp
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            string s;
            string okhex;
            string filename;
            string keyStr, ivStr, saltHex;
            string plain, cipher;
            byte [] arrPlain;
            byte [] arrCipher;
            byte [] arrKey;
            byte [] arrIV;
            byte[] b;
            byte[] salt;
            byte[] arrPwd;
            byte[] arrOk;
            int n, i;
            char ch;
            bool tf;
            string excontent;
            string fnameData;
            string fnameEnc;
            string fnameCheck;
            byte[] a1000;

            //****************
            // GENERAL TESTS *
            //****************
            Console.WriteLine("GENERAL FUNCTIONS:");
            n = General.Version();
            Console.WriteLine("Version={0}", n);

            n = General.PowerUpTests();
            Console.WriteLine("PowerUpTests={0}", n);
            
            s = General.CompileTime();
            Console.WriteLine("CompileTime={0}", s);

            s = General.ModuleName();
            Console.WriteLine("ModuleName={0}", s);

            ch = General.LicenceType();
            Console.WriteLine("LicenceType={0}", ch);

            //*******************************
            // HEXADECIMAL CONVERSION TESTS *
            //*******************************
            Console.WriteLine("CONVERSION TESTS:");
            b = Cnv.FromHex("deadbeef");
            s = Cnv.ToHex(b);
            Console.WriteLine("ToHex={0}", s);
            b = Cnv.FromHex(s);
            Console.WriteLine("In base64='{0}'", Convert.ToBase64String(b));
            s = Cnv.StringFromHex("616263");
            Console.WriteLine("0x616263='{0}'", s);

            //**********************
            // ERROR LOOKUP TESTS *
            //**********************
            Console.WriteLine("ERROR CODES:");
            for (i = 0; i < 10000; i++)
            {
                s = General.ErrorLookup(i);
                if (!s.Equals(String.Empty))
                    Console.WriteLine("Error {0}={1}", i, s);
            }

            //****************************
            // BLOWFISH ENCRYPTION TESTS *
            //****************************
            Console.WriteLine("TESTING BLOWFISH:");
            keyStr = "FEDCBA9876543210";
            plain = "0123456789ABCDEF";
            cipher = "0ACEAB0FC6A0A28D";
            // Encrypt in ECB mode using hex strings
            s = Blowfish.Encrypt(plain, keyStr, Mode.ECB, null);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Blowfish.Encrypt failed");
            // Decrypt
            s = Blowfish.Decrypt(cipher, keyStr, Mode.ECB, null);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Blowfish.Decrypt failed");

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            b = Blowfish.Encrypt(arrPlain, arrKey, Mode.ECB, null);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), cipher, true)==0, "Blowfish.Encrypt failed");
            b = Blowfish.Decrypt(arrCipher, arrKey, Mode.ECB, null);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), plain, true)==0, "Blowfish.Decrypt failed");

            // Encrypt in CBC mode using hex strings
            keyStr = "0123456789ABCDEFF0E1D2C3B4A59687";
            ivStr = "FEDCBA9876543210";
            plain = "37363534333231204E6F77206973207468652074696D6520666F722000000000";
            cipher = "6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC";
            s = Blowfish.Encrypt(plain, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Blowfish.Encrypt (CBC) failed");
            // Decrypt
            s = Blowfish.Decrypt(cipher, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Blowfish.Decrypt (CBC) failed");

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            arrIV = Cnv.FromHex(ivStr);
            b = Blowfish.Encrypt(arrPlain, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), cipher, true)==0, "Blowfish.Encrypt (CBC) failed");
            b = Blowfish.Decrypt(arrCipher, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), plain, true)==0, "Blowfish.Decrypt (CBC) failed");

            // And again using base64 strings
            keyStr = "ASNFZ4mrze/w4dLDtKWWhw==";
            ivStr = "/ty6mHZUMhA=";
            plain = "NzY1NDMyMSBOb3cgaXMgdGhlIHRpbWUgZm9yIAAAAAA=";
            cipher = "a3e01jAG3uYFsVbidAOXk1jeuecVRhbZWfFlK9X/ksw=";
            s = Blowfish.Encrypt(plain, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Blowfish.Encrypt (CBC-base64) failed");
            // Decrypt
            s = Blowfish.Decrypt(cipher, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Blowfish.Decrypt (CBC-base64) failed");

            // Pad some data ready for encryption - first in hex format
            okhex = "ffffff";
            s = okhex;
            plain = Blowfish.Pad(s);
            Console.WriteLine("Blowfish.Pad('{0}')='{1}'", s, plain);
            Debug.Assert((plain.Length % (Blowfish.BlockSize * 2)) == 0, "Blowfish.Pad(hex) failed");
            // and remove it
            s = Blowfish.Unpad(plain);
            Console.WriteLine("Blowfish.Unpad('{0}')='{1}'", plain, s);
            Debug.Assert(s == okhex, "Blowfish.Unpad(hex) failed");
            // again padding an empty string
            okhex = "";
            s = okhex;
            plain = Blowfish.Pad(s);
            Console.WriteLine("Blowfish.Pad('{0}')='{1}'", s, plain);
            Debug.Assert((plain.Length % (Blowfish.BlockSize * 2)) == 0, "Blowfish.Pad(hex) failed");
            // and remove it
            s = Blowfish.Unpad(plain);
            Console.WriteLine("Blowfish.Unpad('{0}')='{1}'", plain, s);
            Debug.Assert(s == okhex, "Blowfish.Unpad(hex) failed");
            // Pad using bytes
            arrOk = Cnv.FromHex("ffffffffffffffff");
            b = arrOk;
            arrPlain = Blowfish.Pad(b);
            Console.WriteLine("Blowfish.Pad(0x{0})=0x{1}", Cnv.ToHex(b), Cnv.ToHex(arrPlain));
            Debug.Assert((arrPlain.Length % Blowfish.BlockSize) == 0, "Blowfish.Pad(bytes) failed");
            b = Blowfish.Unpad(arrPlain);
            Console.WriteLine("Blowfish.Unpad(0x{0})=0x{1}", Cnv.ToHex(arrPlain), Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), Cnv.ToHex(arrOk)) == 0, "Blowfish.Unpad(bytes) failed");

            // Now use Init-Update-Final
            keyStr = "FEDCBA9876543210";
            ivStr = "0123456789abcdef";
            // Instantiate a new encryption object
            Blowfish oBlf = Blowfish.Instance();
            // Setup to encrypt in CBC mode
            n = oBlf.InitEncrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oBlf.ErrCode == 0, "Blowfish.Initialize failed");

            plain = "0101010101010101";
            cipher = "46733BCD9C72C5E3";
            s = oBlf.Update(plain);
            Console.WriteLine("PT1={0}", plain);
            Console.WriteLine("CT1={0}", s);
            Console.WriteLine("OK1={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Blowfish.Update failed");
            // Line 2 using bytes
            plain = "0202020202020202";
            cipher = "F434DA62B6869A06";
            b = Cnv.FromHex(plain);
            b = oBlf.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("PT2={0}", plain);
            Console.WriteLine("CT2={0}", s);
            Console.WriteLine("OK2={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Blowfish.Update failed");
            // Lines 3 and 4 together using hex and a longer input
            plain = "03030303030303030404040404040404";
            cipher = "2AE6DFE458559138DEEBF97D6F83A5F3";
            s = oBlf.Update(plain);
            Console.WriteLine("PT3={0}", plain);
            Console.WriteLine("CT3={0}", s);
            Console.WriteLine("OK3={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Blowfish.Update failed");

            // Create a second object this time to decrypt
            // NB You can only have one Instance at a time in the same thread
            // So this just overwrites the previous one as a test
            // TODO: perhaps return an error here to emphasise the point?
            Blowfish oBlf2 = Blowfish.Instance();
            n = oBlf2.InitDecrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oBlf2.ErrCode == 0, "Blowfish.Init failed");

            plain = "0101010101010101";
            cipher = "46733BCD9C72C5E3";
            s = oBlf2.Update(cipher);
            Console.WriteLine("CT1={0}", cipher);
            Console.WriteLine("PT1={0}", s);
            Console.WriteLine("OK1={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Blowfish.Update failed");
            // Line 2 using bytes
            plain = "0202020202020202";
            cipher = "F434DA62B6869A06";
            b = Cnv.FromHex(cipher);
            b = oBlf2.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("CT2={0}", cipher);
            Console.WriteLine("PT2={0}", s);
            Console.WriteLine("OK2={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Blowfish.Update failed");
            // Lines 3 and 4 using hex
            plain = "03030303030303030404040404040404";
            cipher = "2AE6DFE458559138DEEBF97D6F83A5F3";
            s = oBlf2.Update(cipher);
            Console.WriteLine("CT3={0}", cipher);
            Console.WriteLine("PT3={0}", s);
            Console.WriteLine("OK3={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Blowfish.Update failed");

            // Experiment with object methods
            s = oBlf.ToString();
            Console.WriteLine("oBlf.ToString()={0}", s);
            Type ty = oBlf.GetType();
            Console.WriteLine("oBlf.GetType()={0}", ty);
            n = oBlf.GetHashCode();
            Console.WriteLine("oBlf.GetHashCode()={0}", n);
            n = oBlf2.GetHashCode();
            Console.WriteLine("oBlf2.GetHashCode()={0}", n);
            
            // Make sure keys are disposed of
            oBlf.Dispose();
            oBlf2.Dispose();
            Console.WriteLine("Blf Objects disposed of.");

            // Create a test text file
            excontent = "This is some sample content.";
            fnameData = "excontent.txt";
            MakeATextFile(fnameData, excontent);

            // Encrypt a file
            keyStr = "fedcba9876543210";
            fnameEnc = "excontent.blf.enc.dat";
            okhex = "D45B1B15FA7960E34D67F6366B5ECDD91E941467F21F5BE34A1F5A5158A8569C";
            n = Blowfish.FileEncrypt(fnameEnc, fnameData, keyStr, Mode.ECB, null);
            if (0 == n)
                Console.WriteLine("Blowfish.File created encrypted file '{0}'", fnameEnc);
            else
                Console.WriteLine("Blowfish.File returned error code {0}", n);
            Debug.Assert(0 == n, "Blowfish.File failed.");

            // Check we got what we should
            b = ReadABinaryFile(fnameEnc);
            Console.WriteLine("CT={0}", Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), okhex, true)==0, "Blowfish.FileEncrypt failed");

            // Decrypt it using byte format of key instead of hex
            fnameCheck = "excontent.blf.chk.txt";
            b = Cnv.FromHex(keyStr);
            n = Blowfish.FileDecrypt(fnameCheck, fnameEnc, b, Mode.ECB, null);
            if (0 == n)
            {
                Console.WriteLine("Blowfish.File decrypted to file '{0}'", fnameCheck);
                // Show contents of file
                s = ReadATextFile(fnameCheck);
                Debug.Assert(String.Compare(s, excontent)==0, "Decrypted file data does not match");
            }
            else
                Console.WriteLine("Blowfish.File returned error code {0}", n);
            Debug.Assert(0 == n, "Blowfish.File failed.");


            //***************************
            // DES ENCRYPTION TESTS *
            //***************************
            Console.WriteLine("TESTING DES:");
            keyStr = "0123456789abcdef";
            plain = "4e6f772069732074";
            cipher = "3fa40e8a984d4815";
            // Encrypt in ECB mode using hex strings
            s = Des.Encrypt(plain, keyStr, Mode.ECB, null);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Des.HexECB failed");
            // Decrypt
            s = Des.Decrypt(cipher, keyStr, Mode.ECB, null);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Des.HexECB failed");

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            b = Des.Encrypt(arrPlain, arrKey, Mode.ECB, null);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            b = Des.Decrypt(arrCipher, arrKey, Mode.ECB, null);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));

            // Encrypt in CBC mode using hex strings
            keyStr = "0123456789abcdef";
            ivStr = "1234567890abcdef";
            plain = "4e6f77206973207468652074696d6520666f7220616c6c20";
            cipher = "e5c7cdde872bf27c43e934008c389c0f683788499a7c05f6";
            s = Des.Encrypt(plain, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Des.Encrypt{Hex,CBC} failed");
            // Decrypt
            s = Des.Decrypt(cipher, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Des.Decrypt{Hex,CBC} failed");

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            arrIV = Cnv.FromHex(ivStr);
            b = Des.Encrypt(arrPlain, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            b = Des.Decrypt(arrCipher, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(arrPlain), Cnv.ToHex(b))==0, "Des.BytesCBC failed");

            // And again using base64 strings
            keyStr = "ASNFZ4mrze8=";
            ivStr = "EjRWeJCrze8=";
            plain = "Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwg";
            cipher = "5cfN3ocr8nxD6TQAjDicD2g3iEmafAX2";
            s = Des.Encrypt(plain, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Des.Encrypt{base64,CBC} failed");
            // Decrypt
            s = Des.Decrypt(cipher, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Des.Decrypt{base64,CBC} failed");

            // Pad some data ready for encryption - first in hex format
            okhex = "ffffff";
            s = okhex;
            plain = Des.Pad(s);
            Console.WriteLine("Des.Pad('{0}')='{1}'", s, plain);
            Debug.Assert((plain.Length % (Des.BlockSize * 2)) == 0, "Des.Pad(hex) failed");
            // and remove it
            s = Des.Unpad(plain);
            Console.WriteLine("Des.Unpad('{0}')='{1}'", plain, s);
            Debug.Assert(s == okhex, "Des.Unpad(hex) failed");
            // Pad using bytes
            arrOk = Cnv.FromHex("ffffffffffffffff");
            b = arrOk;
            arrPlain = Des.Pad(b);
            Console.WriteLine("Des.Pad(0x{0})=0x{1}", Cnv.ToHex(b), Cnv.ToHex(arrPlain));
            Debug.Assert((arrPlain.Length % Des.BlockSize) == 0, "Des.Pad(bytes) failed");
            b = Des.Unpad(arrPlain);
            Console.WriteLine("Des.Unpad(0x{0})=0x{1}", Cnv.ToHex(arrPlain), Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), Cnv.ToHex(arrOk)) == 0, "Des.Unpad(bytes) failed");

            // Now use Init-Update-Final
            keyStr = "0123456789abcdef";
            ivStr = "1234567890abcdef";
            // Instantiate a new encryption object
            Des oDes = Des.Instance();
            n = oDes.InitEncrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oDes.ErrCode == 0, "Des.Initialize failed");

            plain = "4e6f772069732074";
            cipher = "E5C7CDDE872BF27C";
            s = oDes.Update(plain);
            Console.WriteLine("PT1={0}", plain);
            Console.WriteLine("CT1={0}", s);
            Console.WriteLine("OK1={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Des.Update failed");
            // Line 2 using bytes
            plain = "68652074696d6520";
            cipher = "43E934008C389C0F";
            b = Cnv.FromHex(plain);
            b = oDes.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("PT2={0}", plain);
            Console.WriteLine("CT2={0}", s);
            Console.WriteLine("OK2={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Des.Update failed");
            // Line 3 using hex
            plain = "666f7220616c6c20";
            cipher = "683788499A7C05F6";
            s = oDes.Update(plain);
            Console.WriteLine("PT3={0}", plain);
            Console.WriteLine("CT3={0}", s);
            Console.WriteLine("OK3={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Des.Update failed");

            n = oDes.InitDecrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oDes.ErrCode == 0, "Des.Initialize failed");

            plain = "4e6f772069732074";
            cipher = "E5C7CDDE872BF27C";
            s = oDes.Update(cipher);
            Console.WriteLine("CT1={0}", cipher);
            Console.WriteLine("PT1={0}", s);
            Console.WriteLine("OK1={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Des.Update failed");
            // Line 2 using bytes
            plain = "68652074696d6520";
            cipher = "43E934008C389C0F";
            b = Cnv.FromHex(cipher);
            b = oDes.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("CT2={0}", cipher);
            Console.WriteLine("PT2={0}", s);
            Console.WriteLine("OK2={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Des.Update failed");
            // Line 3 using hex
            plain = "666f7220616c6c20";
            cipher = "683788499A7C05F6";
            s = oDes.Update(cipher);
            Console.WriteLine("CT3={0}", cipher);
            Console.WriteLine("PT3={0}", s);
            Console.WriteLine("OK3={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Des.Update failed");

            // Make sure keys are disposed of
            oDes.Dispose();
            Console.WriteLine("Des Object disposed of.");

            // Create a test text file
            excontent = "This is some sample content.";
            fnameData = "excontent.txt";
            MakeATextFile(fnameData, excontent);

            // Encrypt a file
            keyStr = "fedcba9876543210";
            fnameEnc = "excontent.des.enc.dat";
            okhex = "84D1604C0A33D9335F7EDB5C7ABE73F86B9C87F0639D45F2C8172C8AA976B247";
            n = Des.FileEncrypt(fnameEnc, fnameData, keyStr, Mode.ECB, null);
            if (0 == n)
                Console.WriteLine("Des.File created encrypted file '{0}'", fnameEnc);
            else
                Console.WriteLine("Des.File returned error code {0}", n);
            Debug.Assert(0 == n, "Des.File failed.");

            // Check we got what we should
            b = ReadABinaryFile(fnameEnc);
            Console.WriteLine("CT={0}", Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), okhex, true)==0, "Des.FileEncrypt failed");

            // Decrypt it using byte format of key instead of hex
            fnameCheck = "excontent.des.chk.txt";
            b = Cnv.FromHex(keyStr);
            n = Des.FileDecrypt(fnameCheck, fnameEnc, b, Mode.ECB, null);
            if (0 == n)
            {
                Console.WriteLine("Des.File decrypted to file '{0}'", fnameCheck);
                // Show contents of file
                s = ReadATextFile(fnameCheck);
                Debug.Assert(String.Compare(s, excontent)==0, "Decrypted file data does not match");
            }
            else
                Console.WriteLine("Des.File returned error code {0}", n);
            Debug.Assert(0 == n, "Des.File failed.");


            //*****************************************************
            // TDEA (Triple DES, 3DES, DES-EDE3) ENCRYPTION TESTS *
            //*****************************************************
            Console.WriteLine("TESTING TRIPLE DES:");
            keyStr = "010101010101010101010101010101010101010101010101";
            plain = "8000000000000000";
            cipher = "95F8A5E5DD31D900";
            // Encrypt in ECB mode using hex strings
            s = Tdea.Encrypt(plain, keyStr, Mode.ECB, null);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Tdea.HexECB failed");
            // Decrypt
            s = Tdea.Decrypt(cipher, keyStr, Mode.ECB, null);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Tdea.HexECB failed");

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            b = Tdea.Encrypt(arrPlain, arrKey, Mode.ECB, null);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            b = Tdea.Decrypt(arrCipher, arrKey, Mode.ECB, null);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));

            // Encrypt in CBC mode using hex strings
            keyStr = "737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32";
            ivStr = "B36B6BFB6231084E";
            plain = "5468697320736F6D652073616D706520636F6E74656E742E0808080808080808";
            cipher = "d76fd1178fbd02f84231f5c1d2a2f74a4159482964f675248254223daf9af8e4";
            s = Tdea.Encrypt(plain, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Tdea.Encrypt{Hex,CBC} failed");
            // Decrypt
            s = Tdea.Decrypt(cipher, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Tdea.Decrypt{Hex,CBC} failed");

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            arrIV = Cnv.FromHex(ivStr);
            b = Tdea.Encrypt(arrPlain, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            b = Tdea.Decrypt(arrCipher, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(arrPlain), Cnv.ToHex(b))==0, "Tdea.BytesCBC failed");

            // ditto using base64 data
            keyStr = "c3x5HyXq0OBGKSVDUvfcYpHlyyaRetoy";
            ivStr = "s2tr+2IxCE4=";
            plain = "VGhpcyBzb21lIHNhbXBlIGNvbnRlbnQuCAgICAgICAg=";
            cipher = "12/RF4+9AvhCMfXB0qL3SkFZSClk9nUkglQiPa+a+OQ=";
            s = Tdea.Encrypt(plain, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Tdea.Encrypt{Base64,CBC} failed");
            // Decrypt
            s = Tdea.Decrypt(cipher, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Tdea.Decrypt{Base64,CBC} failed");

            // Pad some data ready for encryption - first in hex format
            okhex = "ffffff";
            s = okhex;
            plain = Tdea.Pad(s);
            Console.WriteLine("Tdea.Pad('{0}')='{1}'", s, plain);
            Debug.Assert((plain.Length % (Tdea.BlockSize * 2)) == 0, "Tdea.Pad(hex) failed");
            // and remove it
            s = Tdea.Unpad(plain);
            Console.WriteLine("Tdea.Unpad('{0}')='{1}'", plain, s);
            Debug.Assert(s == okhex, "Tdea.Unpad(hex) failed");
            // Pad using bytes
            arrOk = Cnv.FromHex("ffffffffffffffff");
            b = arrOk;
            arrPlain = Tdea.Pad(b);
            Console.WriteLine("Tdea.Pad(0x{0})=0x{1}", Cnv.ToHex(b), Cnv.ToHex(arrPlain));
            Debug.Assert((arrPlain.Length % Tdea.BlockSize) == 0, "Tdea.Pad(bytes) failed");
            b = Tdea.Unpad(arrPlain);
            Console.WriteLine("Tdea.Unpad(0x{0})=0x{1}", Cnv.ToHex(arrPlain), Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), Cnv.ToHex(arrOk)) == 0, "Tdea.Unpad(bytes) failed");

            // Now use Init-Update-Final
            keyStr = "0123456789abcdeffedcba987654321089abcdef01234567";
            ivStr = "1234567890abcdef";
            // Instantiate a new encryption object
            Tdea oTdea = Tdea.Instance();
            n = oTdea.InitEncrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oTdea.ErrCode == 0, "Tdea.Initialize failed");

            plain = "4e6f772069732074";
            cipher = "204011f986e35647";
            s = oTdea.Update(plain);
            Console.WriteLine("PT1={0}", plain);
            Console.WriteLine("CT1={0}", s);
            Console.WriteLine("OK1={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Tdea.Update failed");
            // Line 2 using bytes
            plain = "68652074696d6520";
            cipher = "199e47af391620c5";
            b = Cnv.FromHex(plain);
            b = oTdea.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("PT2={0}", plain);
            Console.WriteLine("CT2={0}", s);
            Console.WriteLine("OK2={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Tdea.Update failed");
            // Line 3 using hex
            plain = "666f7220616c6c20";
            cipher = "bb9a5bcfc86db0bb";
            s = oTdea.Update(plain);
            Console.WriteLine("PT3={0}", plain);
            Console.WriteLine("CT3={0}", s);
            Console.WriteLine("OK3={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Tdea.Update failed");

            // Now decrypt
            n = oTdea.InitDecrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oTdea.ErrCode == 0, "Tdea.Initialize failed");

            plain = "4e6f772069732074";
            cipher = "204011f986e35647";
            s = oTdea.Update(cipher);
            Console.WriteLine("CT1={0}", cipher);
            Console.WriteLine("PT1={0}", s);
            Console.WriteLine("OK1={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Tdea.Update failed");
            // Line 2 using bytes
            plain = "68652074696d6520";
            cipher = "199e47af391620c5";
            b = Cnv.FromHex(cipher);
            b = oTdea.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("CT2={0}", cipher);
            Console.WriteLine("PT2={0}", s);
            Console.WriteLine("OK2={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Tdea.Update failed");
            // Line 3 using hex
            plain = "666f7220616c6c20";
            cipher = "bb9a5bcfc86db0bb";
            s = oTdea.Update(cipher);
            Console.WriteLine("CT3={0}", cipher);
            Console.WriteLine("PT3={0}", s);
            Console.WriteLine("OK3={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Tdea.Update failed");

            // Make sure keys are disposed of
            oTdea.Dispose();
            Console.WriteLine("Tdea Object disposed of.");

            // Create a test text file
            excontent = "This is some sample content.";
            fnameData = "excontent.txt";
            MakeATextFile(fnameData, excontent);

            // Encrypt a file
            keyStr = "fedcba98765432100123456789abcdeffedcba9876543210";
            fnameEnc = "excontent.tdea.enc.dat";
            okhex = "DD1E1FA430AE6BE1D3B83245F7A5B17C4BF03688238778E95F2CCD05AF1A8F44";
            n = Tdea.FileEncrypt(fnameEnc, fnameData, keyStr, Mode.ECB, null);
            if (0 == n)
                Console.WriteLine("Tdea.File created encrypted file '{0}'", fnameEnc);
            else
                Console.WriteLine("Tdea.File returned error code {0}", n);
            Debug.Assert(0 == n, "Tdea.File failed.");

            // Check we got what we should
            b = ReadABinaryFile(fnameEnc);
            Console.WriteLine("CT={0}", Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), okhex, true)==0, "Tdea.FileEncrypt failed");

            // Decrypt it using byte format of key instead of hex
            fnameCheck = "excontent.tdea.chk.txt";
            b = Cnv.FromHex(keyStr);
            n = Tdea.FileDecrypt(fnameCheck, fnameEnc, b, Mode.ECB, null);
            if (0 == n)
            {
                Console.WriteLine("Tdea.File decrypted to file '{0}'", fnameCheck);
                // Show contents of file
                s = ReadATextFile(fnameCheck);
                Debug.Assert(String.Compare(s, excontent)==0, "Decrypted file data does not match");
            }
            else
                Console.WriteLine("Tdea.File returned error code {0}", n);
            Debug.Assert(0 == n, "Tdea.File failed.");


            //***************************
            // AES-128 ENCRYPTION TESTS *
            //***************************
            Console.WriteLine("TESTING AES-128:");
            keyStr = "000102030405060708090a0b0c0d0e0f";
            plain = "00112233445566778899aabbccddeeff";
            cipher = "69c4e0d86a7b0430d8cdb78070b4c55a";
            // Encrypt in ECB mode using hex strings
            s = Aes128.Encrypt(plain, keyStr, Mode.ECB, null);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Aes128.HexECB failed");
            // Decrypt
            s = Aes128.Decrypt(cipher, keyStr, Mode.ECB, null);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Aes128.HexECB failed");

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            b = Aes128.Encrypt(arrPlain, arrKey, Mode.ECB, null);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            b = Aes128.Decrypt(arrCipher, arrKey, Mode.ECB, null);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));

            // Encrypt in CBC mode using hex strings
            keyStr = "56e47a38c5598974bc46903dba290349";
            ivStr = "8ce82eefbea0da3c44699ed7db51b7d9";
            plain = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
                + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
                + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
                + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
            cipher = "c30e32ffedc0774e6aff6af0869f71aa"
                + "0f3af07a9a31a9c684db207eb0ef8e4e"
                + "35907aa632c3ffdf868bb7b29d3d46ad"
                + "83ce9f9a102ee99d49a53e87f4c3da55";
            s = Aes128.Encrypt(plain, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            // Decrypt
            s = Aes128.Decrypt(cipher, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            arrIV = Cnv.FromHex(ivStr);
            b = Aes128.Encrypt(arrPlain, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            b = Aes128.Decrypt(arrCipher, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(arrPlain), Cnv.ToHex(b))==0, "Aes128.BytesCBC failed");

            // Ditto using base64 strings
            keyStr = "VuR6OMVZiXS8RpA9uikDSQ==";
            ivStr = "jOgu776g2jxEaZ7X21G32Q==";
            plain = "oKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/"
                + "AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3w==";
            cipher = "ww4y/+3Ad05q/2rwhp9xqg868HqaManGhNsgfrDvjk"
                + "41kHqmMsP/34aLt7KdPUatg86fmhAu6Z1JpT6H9MPaVQ==";
            s = Aes128.Encrypt(plain, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            // Decrypt
            s = Aes128.Decrypt(cipher, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);

            // Pad some data ready for encryption - first in hex format
            okhex = "ffffff";
            s = okhex;
            plain = Aes128.Pad(s);
            Console.WriteLine("Aes128.Pad('{0}')='{1}'", s, plain);
            Debug.Assert((plain.Length % (Aes128.BlockSize * 2)) == 0, "Aes128.Pad(hex) failed");
            // and remove it
            s = Aes128.Unpad(plain);
            Console.WriteLine("Aes128.Unpad('{0}')='{1}'", plain, s);
            Debug.Assert(s == okhex, "Aes128.Unpad(hex) failed");
            // again padding an empty string
            okhex = "";
            s = okhex;
            plain = Aes128.Pad(s);
            Console.WriteLine("Aes128.Pad('{0}')='{1}'", s, plain);
            Debug.Assert((plain.Length % (Aes128.BlockSize * 2)) == 0, "Aes128.Pad(hex) failed");
            // and remove it
            s = Aes128.Unpad(plain);
            Console.WriteLine("Aes128.Unpad('{0}')='{1}'", plain, s);
            Debug.Assert(s == okhex, "Aes128.Unpad(hex) failed");
            // Pad using bytes
            arrOk = Cnv.FromHex("ffffffffffffffff");
            b = arrOk;
            arrPlain = Aes128.Pad(b);
            Console.WriteLine("Aes128.Pad(0x{0})=0x{1}", Cnv.ToHex(b), Cnv.ToHex(arrPlain));
            Debug.Assert((arrPlain.Length % Aes128.BlockSize) == 0, "Aes128.Pad(bytes) failed");
            b = Aes128.Unpad(arrPlain);
            Console.WriteLine("Aes128.Unpad(0x{0})=0x{1}", Cnv.ToHex(arrPlain), Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), Cnv.ToHex(arrOk)) == 0, "Aes128.Unpad(bytes) failed");

            // Now use Init-Update-Final
            keyStr = "56e47a38c5598974bc46903dba290349";
            ivStr = "8ce82eefbea0da3c44699ed7db51b7d9";
            // Instantiate a new encryption object
            Aes128 oAes128 = Aes128.Instance();
            n = oAes128.InitEncrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oAes128.ErrCode == 0, "Aes128.Initialize failed");

            plain = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf";
            cipher = "c30e32ffedc0774e6aff6af0869f71aa";
            s = oAes128.Update(plain);
            Console.WriteLine("PT1={0}", plain);
            Console.WriteLine("CT1={0}", s);
            Console.WriteLine("OK1={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Aes128.Update failed");
            // Line 2 using bytes
            plain = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf";
            cipher = "0f3af07a9a31a9c684db207eb0ef8e4e";
            b = Cnv.FromHex(plain);
            b = oAes128.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("PT2={0}", plain);
            Console.WriteLine("CT2={0}", s);
            Console.WriteLine("OK2={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Aes128.Update failed");
            // Lines 3 and 4 using hex
            plain = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
            cipher = "35907aa632c3ffdf868bb7b29d3d46ad83ce9f9a102ee99d49a53e87f4c3da55";
            s = oAes128.Update(plain);
            Console.WriteLine("PT3={0}", plain);
            Console.WriteLine("CT3={0}", s);
            Console.WriteLine("OK3={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Aes128.Update failed");

            // Now decrypt using the same object
            n = oAes128.InitDecrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oAes128.ErrCode == 0, "Aes128.Initialize failed");

            plain = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf";
            cipher = "c30e32ffedc0774e6aff6af0869f71aa";
            s = oAes128.Update(cipher);
            Console.WriteLine("CT1={0}", cipher);
            Console.WriteLine("PT1={0}", s);
            Console.WriteLine("OK1={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Aes128.Update failed");
            // Line 2 using bytes
            plain = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf";
            cipher = "0f3af07a9a31a9c684db207eb0ef8e4e";
            b = Cnv.FromHex(cipher);
            b = oAes128.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("CT2={0}", cipher);
            Console.WriteLine("PT2={0}", s);
            Console.WriteLine("OK2={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Aes128.Update failed");
            // Lines 3 and 4 using hex
            plain = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
            cipher = "35907aa632c3ffdf868bb7b29d3d46ad83ce9f9a102ee99d49a53e87f4c3da55";
            s = oAes128.Update(cipher);
            Console.WriteLine("CT3={0}", cipher);
            Console.WriteLine("PT3={0}", s);
            Console.WriteLine("OK3={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Aes128.Update failed");

            // Make sure keys are disposed of
            oAes128.Dispose();
            Console.WriteLine("AES128 Objects disposed of.");

            // Create a test text file
            excontent = "This is some sample content.";
            fnameData = "excontent.txt";
            MakeATextFile(fnameData, excontent);

            // Encrypt a file
            keyStr = "fedcba98765432100123456789abcdef";
            fnameEnc = "excontent.aes128.enc.dat";
            okhex = "DBBACBCC97FBFBE869079864B5077245FA9FD96992CFFF3F4387BD0ABC04EBCA";
            n = Aes128.FileEncrypt(fnameEnc, fnameData, keyStr, Mode.ECB, null);
            if (0 == n)
                Console.WriteLine("Aes128.File created encrypted file '{0}'", fnameEnc);
            else
                Console.WriteLine("Aes128.File returned error code {0}", n);
            Debug.Assert(0 == n, "Aes128.File failed.");

            // Check we got what we should
            b = ReadABinaryFile(fnameEnc);
            Console.WriteLine("CT={0}", Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), okhex, true)==0, "Aes128.FileEncrypt failed");

            // Decrypt it using byte format of key instead of hex
            fnameCheck = "excontent.aes128.chk.txt";
            b = Cnv.FromHex(keyStr);
            n = Aes128.FileDecrypt(fnameCheck, fnameEnc, b, Mode.ECB, null);
            if (0 == n)
            {
                Console.WriteLine("Aes128.File decrypted to file '{0}'", fnameCheck);
                // Show contents of file
                s = ReadATextFile(fnameCheck);
                Debug.Assert(String.Compare(s, excontent)==0, "Decrypted file data does not match");
            }
            else
                Console.WriteLine("Aes128.File returned error code {0}", n);
            Debug.Assert(0 == n, "Aes128.File failed.");
            

            //***************************
            // AES-192 ENCRYPTION TESTS *
            //***************************
            Console.WriteLine("TESTING AES-192:");
            keyStr = "000102030405060708090a0b0c0d0e0f1011121314151617";
            plain = "00112233445566778899aabbccddeeff";
            cipher = "dda97ca4864cdfe06eaf70a0ec0d7191";
            // Encrypt in ECB mode using hex strings
            s = Aes192.Encrypt(plain, keyStr, Mode.ECB, null);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Aes192.HexECB failed");
            // Decrypt
            s = Aes192.Decrypt(cipher, keyStr, Mode.ECB, null);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Aes192.HexECB failed");

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            b = Aes192.Encrypt(arrPlain, arrKey, Mode.ECB, null);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            b = Aes192.Decrypt(arrCipher, arrKey, Mode.ECB, null);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));

            // Encrypt in CBC mode using hex strings
            keyStr = "56e47a38c5598974bc46903dba29034906a9214036b8a15b";
            ivStr = "8ce82eefbea0da3c44699ed7db51b7d9";
            plain = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
                + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
                + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
                + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
            cipher = "738237036dfdde9dda3374fa182600c5"
                + "38d9187a0299725d0a7fdbe844d77578"
                + "1539e401b5597cbbfa836efd22d998d2"
                + "1605d8df340622417b911467b5e51a12";
            s = Aes192.Encrypt(plain, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            // Decrypt
            s = Aes192.Decrypt(cipher, keyStr, Mode.CBC, ivStr);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);

            // Ditto using byte arrays
            arrPlain = Cnv.FromHex(plain);
            arrCipher = Cnv.FromHex(cipher);
            arrKey = Cnv.FromHex(keyStr);
            arrIV = Cnv.FromHex(ivStr);
            b = Aes192.Encrypt(arrPlain, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("CT={0}",Cnv.ToHex(b));
            b = Aes192.Decrypt(arrCipher, arrKey, Mode.CBC, arrIV);
            Console.WriteLine("P'={0}",Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(arrPlain), Cnv.ToHex(b))==0, "Aes192.BytesCBC failed");

            // Ditto using base64 strings
            keyStr = "VuR6OMVZiXS8RpA9uikDSQapIUA2uKFb";
            ivStr = "jOgu776g2jxEaZ7X21G32Q==";
            plain = "oKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/"
                + "AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3w==";
            cipher = "c4I3A2393p3aM3T6GCYAxTjZGHoCmXJdCn/b6"
                + "ETXdXgVOeQBtVl8u/qDbv0i2ZjSFgXY3zQGIkF7kRRnteUaEg==";
            s = Aes192.Encrypt(plain, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("KY={0}",keyStr);
            Console.WriteLine("IV={0}",ivStr);
            Console.WriteLine("PT={0}",plain);
            Console.WriteLine("CT={0}",s);
            Console.WriteLine("OK={0}",cipher);
            // Decrypt
            s = Aes192.Decrypt(cipher, keyStr, Mode.CBC, ivStr, EncodingBase.Base64);
            Console.WriteLine("P'={0}",s);
            Console.WriteLine("OK={0}",plain);

            // Pad some data ready for encryption - first in hex format
            okhex = "ffffff";
            s = okhex;
            plain = Aes192.Pad(s);
            Console.WriteLine("Aes192.Pad('{0}')='{1}'", s, plain);
            Debug.Assert((plain.Length % (Aes192.BlockSize * 2)) == 0, "Aes192.Pad(hex) failed");
            // and remove it
            s = Aes192.Unpad(plain);
            Console.WriteLine("Aes192.Unpad('{0}')='{1}'", plain, s);
            Debug.Assert(s == okhex, "Aes192.Unpad(hex) failed");
            // Pad using bytes
            arrOk = Cnv.FromHex("ffffffffffffffff");
            b = arrOk;
            arrPlain = Aes192.Pad(b);
            Console.WriteLine("Aes192.Pad(0x{0})=0x{1}", Cnv.ToHex(b), Cnv.ToHex(arrPlain));
            Debug.Assert((arrPlain.Length % Aes192.BlockSize) == 0, "Aes192.Pad(bytes) failed");
            b = Aes192.Unpad(arrPlain);
            Console.WriteLine("Aes192.Unpad(0x{0})=0x{1}", Cnv.ToHex(arrPlain), Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), Cnv.ToHex(arrOk)) == 0, "Aes192.Unpad(bytes) failed");

            // Now use Init-Update-Final
            keyStr = "56e47a38c5598974bc46903dba29034906a9214036b8a15b";
            ivStr = "8ce82eefbea0da3c44699ed7db51b7d9";
            // Instantiate a new encryption object
            Aes192 oAes192 = Aes192.Instance();
            n = oAes192.InitEncrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oAes192.ErrCode == 0, "Aes192.Initialize failed");

            plain = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf";
            cipher = "738237036dfdde9dda3374fa182600c5";
            s = oAes192.Update(plain);
            Console.WriteLine("PT1={0}", plain);
            Console.WriteLine("CT1={0}", s);
            Console.WriteLine("OK1={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Aes192.Update failed");
            // Line 2 using bytes
            plain = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf";
            cipher = "38d9187a0299725d0a7fdbe844d77578";
            b = Cnv.FromHex(plain);
            b = oAes192.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("PT2={0}", plain);
            Console.WriteLine("CT2={0}", s);
            Console.WriteLine("OK2={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Aes192.Update failed");
            // Lines 3 and 4 using hex
            plain  = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
            cipher = "1539e401b5597cbbfa836efd22d998d21605d8df340622417b911467b5e51a12";
            s = oAes192.Update(plain);
            Console.WriteLine("PT3={0}", plain);
            Console.WriteLine("CT3={0}", s);
            Console.WriteLine("OK3={0}", cipher);
            Debug.Assert(String.Compare(s, cipher, true)==0, "Aes192.Update failed");

            n = oAes192.InitDecrypt(keyStr, Mode.CBC, ivStr);
            Console.WriteLine("Initialize returns {0}", n);
            Debug.Assert(oAes192.ErrCode == 0, "Aes192.Initialize failed");

            plain = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf";
            cipher = "738237036dfdde9dda3374fa182600c5";
            s = oAes192.Update(cipher);
            Console.WriteLine("CT1={0}", cipher);
            Console.WriteLine("PT1={0}", s);
            Console.WriteLine("OK1={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Aes192.Update failed");
            // Line 2 using bytes
            plain = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf";
            cipher = "38d9187a0299725d0a7fdbe844d77578";
            b = Cnv.FromHex(cipher);
            b = oAes192.Update(b);
            s = Cnv.ToHex(b);
            Console.WriteLine("CT2={0}", cipher);
            Console.WriteLine("PT2={0}", s);
            Console.WriteLine("OK2={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Aes192.Update failed");
            // Lines 3 and 4 using hex
            plain = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
            cipher = "1539e401b5597cbbfa836efd22d998d21605d8df340622417b911467b5e51a12";
            s = oAes192.Update(cipher);
            Console.WriteLine("CT3={0}", cipher);
            Console.WriteLine("PT3={0}", s);
            Console.WriteLine("OK3={0}", plain);
            Debug.Assert(String.Compare(s, plain, true)==0, "Aes192.Update failed");

            // Make sure keys are disposed of
            oAes192.Dispose();
            Console.WriteLine("AES192 Objects disposed of.");

            // Create a test text file
            excontent = "This is some sample content.";
            fnameData = "excontent.txt";
            MakeATextFile(fnameData, excontent);

            // Encrypt a file
            keyStr = "fedcba98765432100123456789abcdeffedcba9876543210";
            fnameEnc = "excontent.aes192.enc.dat";
            okhex = "37C94F74ADDC362FA16B2A16DE40B583296A25DB83136E2CD669351EFE61A6C0";
            n = Aes192.FileEncrypt(fnameEnc, fnameData, keyStr, Mode.ECB, null);
            if (0 == n)
                Console.WriteLine("Aes192.File created encrypted file '{0}'", fnameEnc);
            else
                Console.WriteLine("Aes192.File returned error code {0}", n);
            Debug.Assert(0 == n, "Aes192.File failed.");

            // Check we got what we should
            b = ReadABinaryFile(fnameEnc);
            Console.WriteLine("CT={0}", Cnv.ToHex(b));
            Debug.Assert(String.Compare(Cnv.ToHex(b), okhex, true)==0, "Aes192.FileEncrypt failed");

            // Decrypt it using byte format of key instead of hex
            fnameCheck = "