Imports System
Imports System.Diagnostics
Imports System.Reflection
Imports System.IO
Imports CryptoSysAPI

'   $Id: TestAPIvbnet.vb $
' *   Last updated:
' *   $Date: 2018-09-16 13:31:00 $
' *   $Version: 5.3.0 $
' 


' Some tests using the CryptoSysAPI .NET interface.
' * 
' * Requires `CryptoSys API` to be installed on your system: available from <http://cryptosys.net/api.html>.
' * Add a reference to `diCrSysAPINet.dll` installed in `C:\Program Files (x86)\CryptoSysAPI\DotNet`.
' * 
' * This is a Console Application written for target .NET Framework 2.0 and above.
' * Please report any bugs to <http://www.cryptosys.net/contact>.
' 

'****************************** LICENSE ***********************************
' * Copyright (C) 2005-18 David Ireland, DI Management Services Pty Limited.
' * All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net>
' * The code in this module is licensed under the terms of the MIT license.  
' * For a copy, see <http://opensource.org/licenses/MIT>
'****************************************************************************
'


' [2015-04] Re-organised into modular form 

' [2018-09] Changed license on this code to MIT 


' Ported from C# to VB.NET using icsharpcode.net's SharpDevelop.

Namespace TestAPIExamples
	''' <summary>
	''' Test examples for CryptoSysAPI interface
	''' </summary>
	Class TestAPIExamples
		Private Const MIN_API_VERSION As Integer = 50300

		' Global vars set by command-line args
		Private Shared doPrompt As Boolean = False

		''' <summary>
		''' The main entry point for the application.
		''' </summary>
		<STAThread> _
		Public Shared Sub Main(args As String())
			Dim origdir As String
			' To store CWD before changed to temp
			' Make sure minimum required version of CryptoSys API is installed...
			Console.WriteLine("API Version is " & General.Version())
			If General.Version() < MIN_API_VERSION Then
				Console.WriteLine("FATAL ERROR: Require API version " & MIN_API_VERSION & " or later.")
				Return
			End If

			' HANDLE COMMAND-LINE ARGUMENTS
'             * [some]      just do some tests (default = do all)
'             * [prompt]    prompt for keystrokes and passwords
'             * [noask]     do not ask to delete temp dir
'             

			Dim doSome As Boolean = False
			Dim askDelete As Boolean = True
			' Global vars...
			doPrompt = False
			For iarg As Integer = 0 To args.Length - 1
				If args(iarg) = "some" Then
					doSome = True
				End If
				If args(iarg) = "prompt" Then
					doPrompt = True
				End If
				If args(iarg) = "noask" Then
					askDelete = False
				End If
			Next

			' Setup temp directory
			origdir = SetupTestDirectory()
			If origdir Is Nothing Then
				Return
			End If

			'*************
			' DO THE TESTS
			'*************
			If doSome Then
				' Use "some" in the command line
				' Do some tests - comment these out as required
				Console.WriteLine("Just doing some tests...")

				'test_General();
				'test_Convert();
				'test_ErrorLookup();
				'test_Blowfish();
				'test_Des();
				'test_Tdea();
				'test_AES128();
				'test_AES192();
				'test_AES256();
				'test_KeyWrap();
				'test_SHA1();
				'test_SHA256();
				'test_MD5();
				'test_Hash();
				'test_HashBit();
				'test_HMAC();
				'test_CMAC();
				'test_PBKDF2();
				'test_scrypt();
				'test_ZLIB();
				'test_Random();
				'test_Wipe();
				'test_CRC();
				'test_GCM();
				'test_CipherFileExtended();
				'test_CipherPad();
				'test_StreamCipher();
				'test_Poly1305();
				'test_AEAD();
				'test_AEAD_incremental();
				'test_Padding();
				'test_SHA3_obj();
				'test_SHA3();
				'test_KMAC();
				test_XOF()
			Else
				' Do all the test modules (default)
				Console.WriteLine("Doing all tests...")
				DoAllTests()
			End If

			' FINALLY, DISPLAY QUICK INFO ABOUT THE CORE DLL
			Console.WriteLine(vbLf & "DETAILS OF CORE DLL...")
			Console.WriteLine("DLL Version={0} [{1}] Lic={2} Compiled=[{3}] ", General.Version(), General.Platform(), General.LicenceType(), General.CompileTime())
			Console.WriteLine("[{0}]", General.ModuleName())


			'********************************************
			Console.WriteLine(vbLf & "ALL TESTS COMPLETED.")

			' Put CWD back to original and offer to remove the test dir
			RestoreDirectory(origdir, askDelete)
		End Sub

		Private Shared Sub DoAllTests()
			'%-
			test_General()
			test_Convert()
			test_ErrorLookup()
			test_Blowfish()
			test_Des()
			test_Tdea()
			test_AES128()
			test_AES192()
			test_AES256()
			test_KeyWrap()
			test_SHA1()
			test_SHA256()
			test_MD5()
			test_Hash()
			test_HashBit()
			test_HMAC()
			test_CMAC()
			test_PBKDF2()
			test_scrypt()
			test_ZLIB()
			test_Random()
			test_Wipe()
			test_CRC()
			test_GCM()
			test_CipherFileExtended()
			test_CipherPad()
			test_StreamCipher()
			test_Poly1305()
			test_AEAD()
			test_AEAD_incremental()
			test_Padding()
			test_SHA3_obj()
			test_SHA3()
			test_KMAC()
			test_XOF()
		End Sub

		'********************
		' THE TEST MODULES...
		'********************

		Private Shared Sub test_General()
			Dim n As Integer
			Dim ch As Char
			Dim s As String
			'************
			' GENERAL TESTS *
			'****************
			Console.WriteLine(vbLf & "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)
			n = General.IsWin64()
			Console.WriteLine("IsWin64={0}", n)
			s = General.Platform()
			Console.WriteLine("Platform={0}", s)
			ch = General.LicenceType()
			Console.WriteLine("LicenceType={0}", ch)
		End Sub

		Private Shared Sub test_Convert()
			Dim s As String
			Dim b As Byte()
			Dim b64str As String
			'%+
			'***************************
			' HEXADECIMAL CONVERSION TESTS *
			'*******************************
			Console.WriteLine(vbLf & "HEX CONVERSION TESTS:")
			b = Cnv.FromHex("deadbeef")
			s = Cnv.ToHex(b)
			Console.WriteLine("ToHex={0}", s)
			s = Cnv.StringFromHex("616263")
			Console.WriteLine("0x616263='{0}'", s)

			'%+
			'**********************
			' BASE64 CONVERSION TESTS *
			'**************************
			Console.WriteLine("BASE64 CONVERSION TESTS:")
			' 0xFEDCBA9876543210 in base64
			b64str = "/ty6mHZUMhA="
			b = Cnv.FromBase64(b64str)
			Console.WriteLine("'{0}'=0x{1}", b64str, Cnv.ToHex(b))
			' Back to base64
			s = Cnv.ToBase64(b)
			Console.WriteLine("In base64='{0}'", s)
			' Directly to hex
			Console.WriteLine("In hex='{0}'", Cnv.HexFromBase64(b64str))
			' hex -> base64
			s = "FEDCBA9876543210"
			b64str = Cnv.Base64FromHex(s)
			Console.WriteLine("0x{0}='{1}'", s, b64str)

		End Sub

		Private Shared Sub test_ErrorLookup()
			Dim s As String
			'%+
			'*****************
			' ERROR LOOKUP TESTS *
			'*********************
			Console.WriteLine(vbLf & "ERROR CODES:")
			For i As Integer = 0 To 9999
				s = General.ErrorLookup(i)
				If Not s.Equals([String].Empty) Then
					Console.WriteLine("Error {0}={1}", i, s)
				End If
			Next
		End Sub

		Private Shared Sub test_Blowfish()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim keyStr As String, ivStr As String
			Dim ptStr As String, ctStr As String
			Dim arrPlain As Byte()
			Dim arrCipher As Byte()
			Dim arrKey As Byte()
			Dim arrIV As Byte()
			Dim arrOk As Byte()
			Dim excontent As String
			Dim fnameData As String
			Dim fnameEnc As String
			Dim fnameCheck As String

			'****************************
			' BLOWFISH ENCRYPTION TESTS *
			'****************************
			'%+
			Console.WriteLine(vbLf & "TESTING BLOWFISH:")
			keyStr = "FEDCBA9876543210"
			ptStr = "0123456789ABCDEF"
			ctStr = "0ACEAB0FC6A0A28D"
			' Encrypt in ECB mode using hex strings
			s = Blowfish.Encrypt(ptStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Blowfish.Encrypt failed")
			' Decrypt
			s = Blowfish.Decrypt(ctStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Blowfish.Decrypt failed")

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			arrKey = Cnv.FromHex(keyStr)
			b = Blowfish.Encrypt(arrPlain, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(Cnv.ToHex(b), ctStr, True) = 0, "Blowfish.Encrypt failed")
			b = Blowfish.Decrypt(arrCipher, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(Cnv.ToHex(b), ptStr, True) = 0, "Blowfish.Decrypt failed")

			'%+
			' Encrypt in CBC mode using hex strings
			keyStr = "0123456789ABCDEFF0E1D2C3B4A59687"
			ivStr = "FEDCBA9876543210"
			ptStr = "37363534333231204E6F77206973207468652074696D6520666F722000000000"
			ctStr = "6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC"
			s = Blowfish.Encrypt(ptStr, keyStr, Mode.CBC, ivStr)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("IV={0}", ivStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Blowfish.Encrypt (CBC) failed")
			' Decrypt
			s = Blowfish.Decrypt(ctStr, keyStr, Mode.CBC, ivStr)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Blowfish.Decrypt (CBC) failed")

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			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), ctStr, 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), ptStr, True) = 0, "Blowfish.Decrypt (CBC) failed")

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

			'%-
			' Pad some data ready for encryption - first in hex format
			okhex = "ffffff"
			s = okhex
			ptStr = Blowfish.Pad(s)
			Console.WriteLine("Blowfish.Pad('{0}')='{1}'", s, ptStr)
			Debug.Assert((ptStr.Length Mod (Blowfish.BlockSize * 2)) = 0, "Blowfish.Pad(hex) failed")
			' and remove it
			s = Blowfish.Unpad(ptStr)
			Console.WriteLine("Blowfish.Unpad('{0}')='{1}'", ptStr, s)
			Debug.Assert(s = okhex, "Blowfish.Unpad(hex) failed")
			' again padding an empty string
			okhex = ""
			s = okhex
			ptStr = Blowfish.Pad(s)
			Console.WriteLine("Blowfish.Pad('{0}')='{1}'", s, ptStr)
			Debug.Assert((ptStr.Length Mod (Blowfish.BlockSize * 2)) = 0, "Blowfish.Pad(hex) failed")
			' and remove it
			s = Blowfish.Unpad(ptStr)
			Console.WriteLine("Blowfish.Unpad('{0}')='{1}'", ptStr, 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 Mod 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
			Dim oBlf As Blowfish = 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")

			ptStr = "0101010101010101"
			ctStr = "46733BCD9C72C5E3"
			s = oBlf.Update(ptStr)
			Console.WriteLine("PT1={0}", ptStr)
			Console.WriteLine("CT1={0}", s)
			Console.WriteLine("OK1={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Blowfish.Update failed")
			' Line 2 using bytes
			ptStr = "0202020202020202"
			ctStr = "F434DA62B6869A06"
			b = Cnv.FromHex(ptStr)
			b = oBlf.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("PT2={0}", ptStr)
			Console.WriteLine("CT2={0}", s)
			Console.WriteLine("OK2={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Blowfish.Update failed")
			' Lines 3 and 4 together using hex and a longer input
			ptStr = "03030303030303030404040404040404"
			ctStr = "2AE6DFE458559138DEEBF97D6F83A5F3"
			s = oBlf.Update(ptStr)
			Console.WriteLine("PT3={0}", ptStr)
			Console.WriteLine("CT3={0}", s)
			Console.WriteLine("OK3={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, 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?
			Dim oBlf2 As Blowfish = Blowfish.Instance()
			n = oBlf2.InitDecrypt(keyStr, Mode.CBC, ivStr)
			Console.WriteLine("Initialize returns {0}", n)
			Debug.Assert(oBlf2.ErrCode = 0, "Blowfish.Init failed")

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

			' Experiment with object methods
			s = oBlf.ToString()
			Console.WriteLine("oBlf.ToString()={0}", s)
			Dim ty As Type = 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"
			File.WriteAllText(fnameData, excontent)

			' Encrypt a file
			keyStr = "fedcba9876543210"
			fnameEnc = "excontent.blf.enc.dat"
			okhex = "D45B1B15FA7960E34D67F6366B5ECDD91E941467F21F5BE34A1F5A5158A8569C"
			n = Blowfish.FileEncrypt(fnameEnc, fnameData, keyStr, Mode.ECB, Nothing)
			If 0 = n Then
				Console.WriteLine("Blowfish.File created encrypted file '{0}'", fnameEnc)
			Else
				Console.WriteLine("Blowfish.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Blowfish.File failed.")

			' Check we got what we should
			b = File.ReadAllBytes(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, Nothing)
			If 0 = n Then
				Console.WriteLine("Blowfish.File decrypted to file '{0}'", fnameCheck)
				' Show contents of file
				s = File.ReadAllText(fnameCheck)
				Debug.Assert([String].Compare(s, excontent) = 0, "Decrypted file data does not match")
			Else
				Console.WriteLine("Blowfish.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Blowfish.File failed.")


		End Sub

		Private Shared Sub test_Des()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim keyStr As String, ivStr As String
			Dim ptStr As String, ctStr As String
			Dim arrPlain As Byte()
			Dim arrCipher As Byte()
			Dim arrKey As Byte()
			Dim arrIV As Byte()
			Dim arrOk As Byte()
			Dim excontent As String
			Dim fnameData As String
			Dim fnameEnc As String
			Dim fnameCheck As String
			Dim keyHex As String
			'***************************
			' DES ENCRYPTION TESTS *
			'***************************
			Console.WriteLine(vbLf & "TESTING DES:")
			keyStr = "0123456789abcdef"
			ptStr = "4e6f772069732074"
			ctStr = "3fa40e8a984d4815"
			' Encrypt in ECB mode using hex strings
			s = Des.Encrypt(ptStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Des.HexECB failed")
			' Decrypt
			s = Des.Decrypt(ctStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Des.HexECB failed")

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			arrKey = Cnv.FromHex(keyStr)
			b = Des.Encrypt(arrPlain, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			b = Des.Decrypt(arrCipher, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", Cnv.ToHex(b))

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

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			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="
			ptStr = "Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwg"
			ctStr = "5cfN3ocr8nxD6TQAjDicD2g3iEmafAX2"
			s = Des.Encrypt(ptStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("IV={0}", ivStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Des.Encrypt{base64,CBC} failed")
			' Decrypt
			s = Des.Decrypt(ctStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Des.Decrypt{base64,CBC} failed")

			' Pad some data ready for encryption - first in hex format
			okhex = "ffffff"
			s = okhex
			ptStr = Des.Pad(s)
			Console.WriteLine("Des.Pad('{0}')='{1}'", s, ptStr)
			Debug.Assert((ptStr.Length Mod (Des.BlockSize * 2)) = 0, "Des.Pad(hex) failed")
			' and remove it
			s = Des.Unpad(ptStr)
			Console.WriteLine("Des.Unpad('{0}')='{1}'", ptStr, 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 Mod 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
			Dim oDes As Des = Des.Instance()
			n = oDes.InitEncrypt(keyStr, Mode.CBC, ivStr)
			Console.WriteLine("Initialize returns {0}", n)
			Debug.Assert(oDes.ErrCode = 0, "Des.Initialize failed")

			ptStr = "4e6f772069732074"
			ctStr = "E5C7CDDE872BF27C"
			s = oDes.Update(ptStr)
			Console.WriteLine("PT1={0}", ptStr)
			Console.WriteLine("CT1={0}", s)
			Console.WriteLine("OK1={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Des.Update failed")
			' Line 2 using bytes
			ptStr = "68652074696d6520"
			ctStr = "43E934008C389C0F"
			b = Cnv.FromHex(ptStr)
			b = oDes.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("PT2={0}", ptStr)
			Console.WriteLine("CT2={0}", s)
			Console.WriteLine("OK2={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Des.Update failed")
			' Line 3 using hex
			ptStr = "666f7220616c6c20"
			ctStr = "683788499A7C05F6"
			s = oDes.Update(ptStr)
			Console.WriteLine("PT3={0}", ptStr)
			Console.WriteLine("CT3={0}", s)
			Console.WriteLine("OK3={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, 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")

			ptStr = "4e6f772069732074"
			ctStr = "E5C7CDDE872BF27C"
			s = oDes.Update(ctStr)
			Console.WriteLine("CT1={0}", ctStr)
			Console.WriteLine("PT1={0}", s)
			Console.WriteLine("OK1={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Des.Update failed")
			' Line 2 using bytes
			ptStr = "68652074696d6520"
			ctStr = "43E934008C389C0F"
			b = Cnv.FromHex(ctStr)
			b = oDes.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("CT2={0}", ctStr)
			Console.WriteLine("PT2={0}", s)
			Console.WriteLine("OK2={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Des.Update failed")
			' Line 3 using hex
			ptStr = "666f7220616c6c20"
			ctStr = "683788499A7C05F6"
			s = oDes.Update(ctStr)
			Console.WriteLine("CT3={0}", ctStr)
			Console.WriteLine("PT3={0}", s)
			Console.WriteLine("OK3={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, 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"
			File.WriteAllText(fnameData, excontent)

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

			' Check we got what we should
			b = File.ReadAllBytes(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, Nothing)
			If 0 = n Then
				Console.WriteLine("Des.File decrypted to file '{0}'", fnameCheck)
				' Show contents of file
				s = File.ReadAllText(fnameCheck)
				Debug.Assert([String].Compare(s, excontent) = 0, "Decrypted file data does not match")
			Else
				Console.WriteLine("Des.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Des.File failed.")

			' Check for a DES weak key (chances of finding in a random-generated key = nil)
			Console.WriteLine("Test Des.CheckKey...")
			keyHex = "0101010101010101"
			' WEAK KEY
			n = Des.CheckKey(keyHex)
			Console.WriteLine("Des.CheckKey returned {0} for weak DES key {1} in hex format.", n, keyHex)
			Debug.Assert(0 <> n, "Des.CheckKey failed.")
			' again for key in byte array form
			arrKey = Cnv.FromHex(keyHex)
			n = Des.CheckKey(arrKey)
			Console.WriteLine("Des.CheckKey returned {0} for weak DES key {1} in byte format.", n, Cnv.ToHex(arrKey))
			Debug.Assert(0 <> n, "Des.CheckKey failed.")

			keyHex = "0101010101010102"
			' NOT QUITE WEAK KEY
			n = Des.CheckKey(keyHex)
			Console.WriteLine("Des.CheckKey returned {0} for OK DES key {1} in hex format.", n, keyHex)
			Debug.Assert(0 = n, "Des.CheckKey failed.")
			' again for key in byte array form
			arrKey = Cnv.FromHex(keyHex)
			n = Des.CheckKey(arrKey)
			Console.WriteLine("Des.CheckKey returned {0} for OK DES key {1} in byte format.", n, Cnv.ToHex(arrKey))
			Debug.Assert(0 = n, "Des.CheckKey failed.")

		End Sub

		Private Shared Sub test_Tdea()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim keyStr As String, ivStr As String
			Dim ptStr As String, ctStr As String
			Dim arrPlain As Byte()
			Dim arrCipher As Byte()
			Dim arrKey As Byte()
			Dim arrIV As Byte()
			Dim arrOk As Byte()
			Dim excontent As String
			Dim fnameData As String
			Dim fnameEnc As String
			Dim fnameCheck As String
			Dim keyHex As String
			'*****************************************************
			' TDEA (Triple DES, 3DES, DES-EDE3) ENCRYPTION TESTS *
			'*****************************************************
			Console.WriteLine(vbLf & "TESTING TRIPLE DES:")
			keyStr = "010101010101010101010101010101010101010101010101"
			ptStr = "8000000000000000"
			ctStr = "95F8A5E5DD31D900"
			' Encrypt in ECB mode using hex strings
			s = Tdea.Encrypt(ptStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Tdea.HexECB failed")
			' Decrypt
			s = Tdea.Decrypt(ctStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Tdea.HexECB failed")

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			arrKey = Cnv.FromHex(keyStr)
			b = Tdea.Encrypt(arrPlain, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			b = Tdea.Decrypt(arrCipher, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", Cnv.ToHex(b))

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

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			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="
			ptStr = "VGhpcyBzb21lIHNhbXBlIGNvbnRlbnQuCAgICAgICAg="
			ctStr = "12/RF4+9AvhCMfXB0qL3SkFZSClk9nUkglQiPa+a+OQ="
			s = Tdea.Encrypt(ptStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("IV={0}", ivStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Tdea.Encrypt{Base64,CBC} failed")
			' Decrypt
			s = Tdea.Decrypt(ctStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Tdea.Decrypt{Base64,CBC} failed")

			' Pad some data ready for encryption - first in hex format
			okhex = "ffffff"
			s = okhex
			ptStr = Tdea.Pad(s)
			Console.WriteLine("Tdea.Pad('{0}')='{1}'", s, ptStr)
			Debug.Assert((ptStr.Length Mod (Tdea.BlockSize * 2)) = 0, "Tdea.Pad(hex) failed")
			' and remove it
			s = Tdea.Unpad(ptStr)
			Console.WriteLine("Tdea.Unpad('{0}')='{1}'", ptStr, 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 Mod 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
			Dim oTdea As Tdea = Tdea.Instance()
			n = oTdea.InitEncrypt(keyStr, Mode.CBC, ivStr)
			Console.WriteLine("Initialize returns {0}", n)
			Debug.Assert(oTdea.ErrCode = 0, "Tdea.Initialize failed")

			ptStr = "4e6f772069732074"
			ctStr = "204011f986e35647"
			s = oTdea.Update(ptStr)
			Console.WriteLine("PT1={0}", ptStr)
			Console.WriteLine("CT1={0}", s)
			Console.WriteLine("OK1={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Tdea.Update failed")
			' Line 2 using bytes
			ptStr = "68652074696d6520"
			ctStr = "199e47af391620c5"
			b = Cnv.FromHex(ptStr)
			b = oTdea.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("PT2={0}", ptStr)
			Console.WriteLine("CT2={0}", s)
			Console.WriteLine("OK2={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Tdea.Update failed")
			' Line 3 using hex
			ptStr = "666f7220616c6c20"
			ctStr = "bb9a5bcfc86db0bb"
			s = oTdea.Update(ptStr)
			Console.WriteLine("PT3={0}", ptStr)
			Console.WriteLine("CT3={0}", s)
			Console.WriteLine("OK3={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, 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")

			ptStr = "4e6f772069732074"
			ctStr = "204011f986e35647"
			s = oTdea.Update(ctStr)
			Console.WriteLine("CT1={0}", ctStr)
			Console.WriteLine("PT1={0}", s)
			Console.WriteLine("OK1={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Tdea.Update failed")
			' Line 2 using bytes
			ptStr = "68652074696d6520"
			ctStr = "199e47af391620c5"
			b = Cnv.FromHex(ctStr)
			b = oTdea.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("CT2={0}", ctStr)
			Console.WriteLine("PT2={0}", s)
			Console.WriteLine("OK2={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Tdea.Update failed")
			' Line 3 using hex
			ptStr = "666f7220616c6c20"
			ctStr = "bb9a5bcfc86db0bb"
			s = oTdea.Update(ctStr)
			Console.WriteLine("CT3={0}", ctStr)
			Console.WriteLine("PT3={0}", s)
			Console.WriteLine("OK3={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, 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"
			File.WriteAllText(fnameData, excontent)

			' Encrypt a file
			keyStr = "fedcba98765432100123456789abcdeffedcba9876543210"
			fnameEnc = "excontent.tdea.enc.dat"
			okhex = "DD1E1FA430AE6BE1D3B83245F7A5B17C4BF03688238778E95F2CCD05AF1A8F44"
			n = Tdea.FileEncrypt(fnameEnc, fnameData, keyStr, Mode.ECB, Nothing)
			If 0 = n Then
				Console.WriteLine("Tdea.File created encrypted file '{0}'", fnameEnc)
			Else
				Console.WriteLine("Tdea.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Tdea.File failed.")

			' Check we got what we should
			b = File.ReadAllBytes(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, Nothing)
			If 0 = n Then
				Console.WriteLine("Tdea.File decrypted to file '{0}'", fnameCheck)
				' Show contents of file
				s = File.ReadAllText(fnameCheck)
				Debug.Assert([String].Compare(s, excontent) = 0, "Decrypted file data does not match")
			Else
				Console.WriteLine("Tdea.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Tdea.File failed.")

			' Attempt to encrypt a file with key and IV of invalid length
			Console.WriteLine("Expecting errors...")
			arrIV = Cnv.FromHex("BADBAD")
			' 3 bytes, expecting 8
			' Good key, bad IV
			n = Tdea.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.CBC, arrIV)
			Console.WriteLine("Tdea.File returned error code {0} {1}", n, General.ErrorLookup(n))
			arrKey = Cnv.FromHex("BADBADBADBAD")
			' 6 bytes, expecting 24
			' Bad key
			n = Tdea.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("Tdea.File returned error code {0} {1}", n, General.ErrorLookup(n))


			' Check for a TDEA weak key (chances of finding in a random-generated key = nil)
			Console.WriteLine("Test Tdea.CheckKey...")
			keyHex = "0101010101010101ffeeccddbbaa99887766554433221100"
			' WEAK KEY
			n = Tdea.CheckKey(keyHex)
			Console.WriteLine("Tdea.CheckKey returned {0} for weak TDEA key {1} in hex format.", n, keyHex)
			Debug.Assert(0 <> n, "Tdea.CheckKey failed.")
			' again for key in byte array form
			arrKey = Cnv.FromHex(keyHex)
			n = Tdea.CheckKey(arrKey)
			Console.WriteLine("Tdea.CheckKey returned {0} for weak TDEA key {1} in byte format.", n, Cnv.ToHex(arrKey))
			Debug.Assert(0 <> n, "Tdea.CheckKey failed.")

			keyHex = "0101010101010102ffeeccddbbaa99887766554433221100"
			' NOT QUITE WEAK KEY
			n = Tdea.CheckKey(keyHex)
			Console.WriteLine("Tdea.CheckKey returned {0} for OK TDEA key {1} in hex format.", n, keyHex)
			Debug.Assert(0 = n, "Tdea.CheckKey failed.")
			' again for key in byte array form
			arrKey = Cnv.FromHex(keyHex)
			n = Tdea.CheckKey(arrKey)
			Console.WriteLine("Tdea.CheckKey returned {0} for OK TDEA key {1} in byte format.", n, Cnv.ToHex(arrKey))
			Debug.Assert(0 = n, "Tdea.CheckKey failed.")

		End Sub

		Private Shared Sub test_AES128()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim keyStr As String, ivStr As String
			Dim ptStr As String, ctStr As String
			Dim arrPlain As Byte()
			Dim arrCipher As Byte()
			Dim arrKey As Byte()
			Dim arrIV As Byte()
			Dim arrOk As Byte()
			Dim excontent As String
			Dim fnameData As String
			Dim fnameEnc As String
			Dim fnameCheck As String
			'***************************
			' AES-128 ENCRYPTION TESTS *
			'***************************
			Console.WriteLine(vbLf & "TESTING AES-128:")
			keyStr = "000102030405060708090a0b0c0d0e0f"
			ptStr = "00112233445566778899aabbccddeeff"
			ctStr = "69c4e0d86a7b0430d8cdb78070b4c55a"
			' Encrypt in ECB mode using hex strings
			s = Aes128.Encrypt(ptStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes128.HexECB failed")
			' Decrypt
			s = Aes128.Decrypt(ctStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes128.HexECB failed")

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			arrKey = Cnv.FromHex(keyStr)
			b = Aes128.Encrypt(arrPlain, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			b = Aes128.Decrypt(arrCipher, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", Cnv.ToHex(b))

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

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			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=="
			ptStr = "oKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/" & "AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3w=="
			ctStr = "ww4y/+3Ad05q/2rwhp9xqg868HqaManGhNsgfrDvjk" & "41kHqmMsP/34aLt7KdPUatg86fmhAu6Z1JpT6H9MPaVQ=="
			s = Aes128.Encrypt(ptStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("IV={0}", ivStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			' Decrypt
			s = Aes128.Decrypt(ctStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)

			' Pad some data ready for encryption - first in hex format
			okhex = "ffffff"
			s = okhex
			ptStr = Aes128.Pad(s)
			Console.WriteLine("Aes128.Pad('{0}')='{1}'", s, ptStr)
			Debug.Assert((ptStr.Length Mod (Aes128.BlockSize * 2)) = 0, "Aes128.Pad(hex) failed")
			' and remove it
			s = Aes128.Unpad(ptStr)
			Console.WriteLine("Aes128.Unpad('{0}')='{1}'", ptStr, s)
			Debug.Assert(s = okhex, "Aes128.Unpad(hex) failed")
			' again padding an empty string
			okhex = ""
			s = okhex
			ptStr = Aes128.Pad(s)
			Console.WriteLine("Aes128.Pad('{0}')='{1}'", s, ptStr)
			Debug.Assert((ptStr.Length Mod (Aes128.BlockSize * 2)) = 0, "Aes128.Pad(hex) failed")
			' and remove it
			s = Aes128.Unpad(ptStr)
			Console.WriteLine("Aes128.Unpad('{0}')='{1}'", ptStr, 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 Mod 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
			Dim oAes128 As Aes128 = Aes128.Instance()
			n = oAes128.InitEncrypt(keyStr, Mode.CBC, ivStr)
			Console.WriteLine("Initialize returns {0}", n)
			Debug.Assert(oAes128.ErrCode = 0, "Aes128.Initialize failed")

			ptStr = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
			ctStr = "c30e32ffedc0774e6aff6af0869f71aa"
			s = oAes128.Update(ptStr)
			Console.WriteLine("PT1={0}", ptStr)
			Console.WriteLine("CT1={0}", s)
			Console.WriteLine("OK1={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes128.Update failed")
			' Line 2 using bytes
			ptStr = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
			ctStr = "0f3af07a9a31a9c684db207eb0ef8e4e"
			b = Cnv.FromHex(ptStr)
			b = oAes128.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("PT2={0}", ptStr)
			Console.WriteLine("CT2={0}", s)
			Console.WriteLine("OK2={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes128.Update failed")
			' Lines 3 and 4 using hex
			ptStr = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
			ctStr = "35907aa632c3ffdf868bb7b29d3d46ad83ce9f9a102ee99d49a53e87f4c3da55"
			s = oAes128.Update(ptStr)
			Console.WriteLine("PT3={0}", ptStr)
			Console.WriteLine("CT3={0}", s)
			Console.WriteLine("OK3={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, 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")

			ptStr = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
			ctStr = "c30e32ffedc0774e6aff6af0869f71aa"
			s = oAes128.Update(ctStr)
			Console.WriteLine("CT1={0}", ctStr)
			Console.WriteLine("PT1={0}", s)
			Console.WriteLine("OK1={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes128.Update failed")
			' Line 2 using bytes
			ptStr = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
			ctStr = "0f3af07a9a31a9c684db207eb0ef8e4e"
			b = Cnv.FromHex(ctStr)
			b = oAes128.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("CT2={0}", ctStr)
			Console.WriteLine("PT2={0}", s)
			Console.WriteLine("OK2={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes128.Update failed")
			' Lines 3 and 4 using hex
			ptStr = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
			ctStr = "35907aa632c3ffdf868bb7b29d3d46ad83ce9f9a102ee99d49a53e87f4c3da55"
			s = oAes128.Update(ctStr)
			Console.WriteLine("CT3={0}", ctStr)
			Console.WriteLine("PT3={0}", s)
			Console.WriteLine("OK3={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, 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"
			File.WriteAllText(fnameData, excontent)

			' Encrypt a file
			keyStr = "fedcba98765432100123456789abcdef"
			fnameEnc = "excontent.aes128.enc.dat"
			okhex = "DBBACBCC97FBFBE869079864B5077245FA9FD96992CFFF3F4387BD0ABC04EBCA"
			n = Aes128.FileEncrypt(fnameEnc, fnameData, keyStr, Mode.ECB, Nothing)
			If 0 = n Then
				Console.WriteLine("Aes128.File created encrypted file '{0}'", fnameEnc)
			Else
				Console.WriteLine("Aes128.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Aes128.File failed.")

			' Check we got what we should
			b = File.ReadAllBytes(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, Nothing)
			If 0 = n Then
				Console.WriteLine("Aes128.File decrypted to file '{0}'", fnameCheck)
				' Show contents of file
				s = File.ReadAllText(fnameCheck)
				Debug.Assert([String].Compare(s, excontent) = 0, "Decrypted file data does not match")
			Else
				Console.WriteLine("Aes128.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Aes128.File failed.")


		End Sub

		Private Shared Sub test_AES192()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim keyStr As String, ivStr As String
			Dim ptStr As String, ctStr As String
			Dim arrPlain As Byte()
			Dim arrCipher As Byte()
			Dim arrKey As Byte()
			Dim arrIV As Byte()
			Dim arrOk As Byte()
			Dim excontent As String
			Dim fnameData As String
			Dim fnameEnc As String
			Dim fnameCheck As String
			'***************************
			' AES-192 ENCRYPTION TESTS *
			'***************************
			Console.WriteLine(vbLf & "TESTING AES-192:")
			keyStr = "000102030405060708090a0b0c0d0e0f1011121314151617"
			ptStr = "00112233445566778899aabbccddeeff"
			ctStr = "dda97ca4864cdfe06eaf70a0ec0d7191"
			' Encrypt in ECB mode using hex strings
			s = Aes192.Encrypt(ptStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes192.HexECB failed")
			' Decrypt
			s = Aes192.Decrypt(ctStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes192.HexECB failed")

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			arrKey = Cnv.FromHex(keyStr)
			b = Aes192.Encrypt(arrPlain, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			b = Aes192.Decrypt(arrCipher, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", Cnv.ToHex(b))

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

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			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=="
			ptStr = "oKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/" & "AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3w=="
			ctStr = "c4I3A2393p3aM3T6GCYAxTjZGHoCmXJdCn/b6" & "ETXdXgVOeQBtVl8u/qDbv0i2ZjSFgXY3zQGIkF7kRRnteUaEg=="
			s = Aes192.Encrypt(ptStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("IV={0}", ivStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			' Decrypt
			s = Aes192.Decrypt(ctStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)

			' Pad some data ready for encryption - first in hex format
			okhex = "ffffff"
			s = okhex
			ptStr = Aes192.Pad(s)
			Console.WriteLine("Aes192.Pad('{0}')='{1}'", s, ptStr)
			Debug.Assert((ptStr.Length Mod (Aes192.BlockSize * 2)) = 0, "Aes192.Pad(hex) failed")
			' and remove it
			s = Aes192.Unpad(ptStr)
			Console.WriteLine("Aes192.Unpad('{0}')='{1}'", ptStr, 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 Mod 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
			Dim oAes192 As Aes192 = Aes192.Instance()
			n = oAes192.InitEncrypt(keyStr, Mode.CBC, ivStr)
			Console.WriteLine("Initialize returns {0}", n)
			Debug.Assert(oAes192.ErrCode = 0, "Aes192.Initialize failed")

			ptStr = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
			ctStr = "738237036dfdde9dda3374fa182600c5"
			s = oAes192.Update(ptStr)
			Console.WriteLine("PT1={0}", ptStr)
			Console.WriteLine("CT1={0}", s)
			Console.WriteLine("OK1={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes192.Update failed")
			' Line 2 using bytes
			ptStr = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
			ctStr = "38d9187a0299725d0a7fdbe844d77578"
			b = Cnv.FromHex(ptStr)
			b = oAes192.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("PT2={0}", ptStr)
			Console.WriteLine("CT2={0}", s)
			Console.WriteLine("OK2={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes192.Update failed")
			' Lines 3 and 4 using hex
			ptStr = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
			ctStr = "1539e401b5597cbbfa836efd22d998d21605d8df340622417b911467b5e51a12"
			s = oAes192.Update(ptStr)
			Console.WriteLine("PT3={0}", ptStr)
			Console.WriteLine("CT3={0}", s)
			Console.WriteLine("OK3={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, 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")

			ptStr = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
			ctStr = "738237036dfdde9dda3374fa182600c5"
			s = oAes192.Update(ctStr)
			Console.WriteLine("CT1={0}", ctStr)
			Console.WriteLine("PT1={0}", s)
			Console.WriteLine("OK1={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes192.Update failed")
			' Line 2 using bytes
			ptStr = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
			ctStr = "38d9187a0299725d0a7fdbe844d77578"
			b = Cnv.FromHex(ctStr)
			b = oAes192.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("CT2={0}", ctStr)
			Console.WriteLine("PT2={0}", s)
			Console.WriteLine("OK2={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes192.Update failed")
			' Lines 3 and 4 using hex
			ptStr = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
			ctStr = "1539e401b5597cbbfa836efd22d998d21605d8df340622417b911467b5e51a12"
			s = oAes192.Update(ctStr)
			Console.WriteLine("CT3={0}", ctStr)
			Console.WriteLine("PT3={0}", s)
			Console.WriteLine("OK3={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, 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"
			File.WriteAllText(fnameData, excontent)

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

			' Check we got what we should
			b = File.ReadAllBytes(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 = "excontent.aes192.chk.txt"
			b = Cnv.FromHex(keyStr)
			n = Aes192.FileDecrypt(fnameCheck, fnameEnc, b, Mode.ECB, Nothing)
			If 0 = n Then
				Console.WriteLine("Aes192.File decrypted to file '{0}'", fnameCheck)
				' Show contents of file
				s = File.ReadAllText(fnameCheck)
				Debug.Assert([String].Compare(s, excontent) = 0, "Decrypted file data does not match")
			Else
				Console.WriteLine("Aes192.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Aes192.File failed.")

		End Sub

		Private Shared Sub test_AES256()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim keyStr As String, ivStr As String
			Dim ptStr As String, ctStr As String
			Dim arrPlain As Byte()
			Dim arrCipher As Byte()
			Dim arrKey As Byte()
			Dim arrIV As Byte()
			Dim arrOk As Byte()
			Dim excontent As String
			Dim fnameData As String
			Dim fnameEnc As String
			Dim fnameCheck As String

			'***************************
			' AES-256 ENCRYPTION TESTS *
			'***************************
			Console.WriteLine(vbLf & "TESTING AES-256:")
			keyStr = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
			ptStr = "00112233445566778899aabbccddeeff"
			ctStr = "8EA2B7CA516745BFEAFC49904B496089"
			' Encrypt in ECB mode using hex strings
			s = Aes256.Encrypt(ptStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes256.HexECB failed")
			' Decrypt
			s = Aes256.Decrypt(ctStr, keyStr, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes256.HexECB failed")

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			arrKey = Cnv.FromHex(keyStr)
			b = Aes256.Encrypt(arrPlain, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			b = Aes256.Decrypt(arrCipher, arrKey, Mode.ECB, Nothing)
			Console.WriteLine("P'={0}", Cnv.ToHex(b))

			' Encrypt in CBC mode using hex strings
			keyStr = "56e47a38c5598974bc46903dba29034906a9214036b8a15b512e03d534120006"
			ivStr = "8ce82eefbea0da3c44699ed7db51b7d9"
			ptStr = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" & "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" & "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" & "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
			ctStr = "28409A2982BD2CF7CE343A7D43F6927F" & "DB9EC532BBA569EEC92E57A209C4FDBA" & "59ADBA05A5C854694DDC9F7991C01634" & "E72BEB4FE0236CB3B119A463891E346F"
			s = Aes256.Encrypt(ptStr, keyStr, Mode.CBC, ivStr)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("IV={0}", ivStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes256.Encrypt{Hex,CBC} failed")
			' Decrypt
			s = Aes256.Decrypt(ctStr, keyStr, Mode.CBC, ivStr)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes256.Decrypt{Hex,CBC} failed")

			' Ditto using byte arrays
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			arrKey = Cnv.FromHex(keyStr)
			arrIV = Cnv.FromHex(ivStr)
			b = Aes256.Encrypt(arrPlain, arrKey, Mode.CBC, arrIV)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			b = Aes256.Decrypt(arrCipher, arrKey, Mode.CBC, arrIV)
			Console.WriteLine("P'={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(Cnv.ToHex(arrPlain), Cnv.ToHex(b)) = 0, "Aes256.BytesCBC failed")

			' Ditto using base64 strings
			keyStr = "VuR6OMVZiXS8RpA9uikDSQapIUA2uKFbUS4D1TQSAAY="
			ivStr = "jOgu776g2jxEaZ7X21G32Q=="
			ptStr = "oKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/" & "AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3w=="
			ctStr = "KECaKYK9LPfONDp9Q/aSf9uexTK7pWnuyS5XognE/" & "bpZrboFpchUaU3cn3mRwBY05yvrT+AjbLOxGaRjiR40bw=="
			s = Aes256.Encrypt(ptStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("IV={0}", ivStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			' Decrypt
			s = Aes256.Decrypt(ctStr, keyStr, Mode.CBC, ivStr, EncodingBase.Base64)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)

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

			' Now use Init-Update-Final
			keyStr = "56e47a38c5598974bc46903dba29034906a9214036b8a15b512e03d534120006"
			ivStr = "8ce82eefbea0da3c44699ed7db51b7d9"
			' Instantiate a new encryption object
			Dim oAes256 As Aes256 = Aes256.Instance()
			n = oAes256.InitEncrypt(keyStr, Mode.CBC, ivStr)
			Console.WriteLine("Initialize returns {0}", n)
			Debug.Assert(oAes256.ErrCode = 0, "Aes256.Initialize failed")

			ptStr = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
			ctStr = "28409A2982BD2CF7CE343A7D43F6927F"
			s = oAes256.Update(ptStr)
			Console.WriteLine("PT1={0}", ptStr)
			Console.WriteLine("CT1={0}", s)
			Console.WriteLine("OK1={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes256.Update failed")
			' Line 2 using bytes
			ptStr = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
			ctStr = "DB9EC532BBA569EEC92E57A209C4FDBA"
			b = Cnv.FromHex(ptStr)
			b = oAes256.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("PT2={0}", ptStr)
			Console.WriteLine("CT2={0}", s)
			Console.WriteLine("OK2={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes256.Update failed")
			' Lines 3 and 4 using hex
			ptStr = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
			ctStr = "59ADBA05A5C854694DDC9F7991C01634E72BEB4FE0236CB3B119A463891E346F"
			s = oAes256.Update(ptStr)
			Console.WriteLine("PT3={0}", ptStr)
			Console.WriteLine("CT3={0}", s)
			Console.WriteLine("OK3={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Aes256.Update failed")

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

			ptStr = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
			ctStr = "28409A2982BD2CF7CE343A7D43F6927F"
			s = oAes256.Update(ctStr)
			Console.WriteLine("CT1={0}", ctStr)
			Console.WriteLine("PT1={0}", s)
			Console.WriteLine("OK1={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes256.Update failed")
			' Line 2 using bytes
			ptStr = "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
			ctStr = "DB9EC532BBA569EEC92E57A209C4FDBA"
			b = Cnv.FromHex(ctStr)
			b = oAes256.Update(b)
			s = Cnv.ToHex(b)
			Console.WriteLine("CT2={0}", ctStr)
			Console.WriteLine("PT2={0}", s)
			Console.WriteLine("OK2={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes256.Update failed")
			' Lines 3 and 4 using hex
			ptStr = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
			ctStr = "59ADBA05A5C854694DDC9F7991C01634E72BEB4FE0236CB3B119A463891E346F"
			s = oAes256.Update(ctStr)
			Console.WriteLine("CT3={0}", ctStr)
			Console.WriteLine("PT3={0}", s)
			Console.WriteLine("OK3={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Aes256.Update failed")

			' Make sure keys are disposed of
			oAes256.Dispose()
			Console.WriteLine("AES256 Objects disposed of.")

			' Create a test text file
			excontent = "This is some sample content."
			fnameData = "excontent.txt"
			File.WriteAllText(fnameData, excontent)

			' Encrypt a file
			keyStr = "fedcba98765432100123456789abcdeffedcba98765432100123456789abcdef"
			fnameEnc = "excontent.aes256.enc.dat"
			okhex = "7F94B5E5A76B747B9778FD20D033E804790E633D34F78C9194F799DD967996C4"
			n = Aes256.FileEncrypt(fnameEnc, fnameData, keyStr, Mode.ECB, Nothing)
			If 0 = n Then
				Console.WriteLine("Aes256.File created encrypted file '{0}'", fnameEnc)
			Else
				Console.WriteLine("Aes256.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Aes256.File failed.")

			' Check we got what we should
			b = File.ReadAllBytes(fnameEnc)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(Cnv.ToHex(b), okhex, True) = 0, "Aes256.FileEncrypt failed")

			' Decrypt it using byte format of key instead of hex
			fnameCheck = "excontent.aes256.chk.txt"
			b = Cnv.FromHex(keyStr)
			n = Aes256.FileDecrypt(fnameCheck, fnameEnc, b, Mode.ECB, Nothing)
			If 0 = n Then
				Console.WriteLine("Aes256.File decrypted to file '{0}'", fnameCheck)
				' Show contents of file
				s = File.ReadAllText(fnameCheck)
				Debug.Assert([String].Compare(s, excontent) = 0, "Decrypted file data does not match")
			Else
				Console.WriteLine("Aes256.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Aes256.File failed.")

		End Sub

		Private Shared Sub test_StreamCipher()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim keyStr As String
			Dim ptStr As String, ctStr As String
			Dim arrPlain As Byte()
			Dim arrCipher As Byte()
			Dim arrKey As Byte()
			Dim arrIV As Byte()
			Dim excontent As String
			Dim fnameData As String
			Dim fnameEnc As String
			Dim fnameCheck As String
			'***********************
			' STREAM CIPHER TESTS *
			'***********************
			Console.WriteLine(vbLf & "TESTING STREAM CIPHERS:")
			Console.WriteLine("ARCFOUR (RC4, PC1):")
			' Our original pseudonym for RC4 was PC1
			' [v4.8] Pc1 methods now superseded by CipherStream.

			keyStr = "0123456789abcdef"
			ptStr = "0123456789abcdef"
			ctStr = "75b7878099e0c596"
			' convert to byte arrays
			arrKey = Cnv.FromHex(keyStr)
			arrPlain = Cnv.FromHex(ptStr)
			arrCipher = Cnv.FromHex(ctStr)
			' encrypt
			b = Pc1.Encrypt(arrPlain, arrKey)
			Console.WriteLine("PC1:")
			Console.WriteLine("KY={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("PT={0}", Cnv.ToHex(arrPlain))
			s = Cnv.ToHex(b)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Pc1.Encrypt failed")
			' decrypt by encrypting again
			b = Pc1.Encrypt(b, arrKey)
			s = Cnv.ToHex(b)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Pc1.Encrypt(2) failed")

			' NEW in v4.8: Pc1 methods are superseded. Use CipherStream. methods instead
			b = CipherStream.Bytes(arrPlain, arrKey, Nothing, 0, CipherStream.Algorithm.Arcfour)
			Console.WriteLine("ARCFOUR:")
			Console.WriteLine("KY={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("PT={0}", Cnv.ToHex(arrPlain))
			s = Cnv.ToHex(b)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "CipherStream.Bytes failed")
			' decrypt by encrypting again
			b = CipherStream.Bytes(b, arrKey, Nothing, 0, CipherStream.Algorithm.Arcfour)
			s = Cnv.ToHex(b)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "CipherStream.Bytes(2) failed")


			' Again using data directly in hex format
			keyStr = "ef012345"
			ptStr = "00000000000000000000"
			ctStr = "d6a141a7ec3c38dfbd61"
			s = Pc1.Encrypt(ptStr, keyStr)
			Console.WriteLine("PC1:")
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "Pc1.Encrypt(Hex) failed")
			' decrypt by encrypting again
			s = Pc1.Encrypt(s, keyStr)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "Pc1.Encrypt(Hex, 2) failed")

			s = CipherStream.Hex(ptStr, keyStr, "", 0, CipherStream.Algorithm.Arcfour)
			Console.WriteLine("ARCFOUR:")
			Console.WriteLine("KY={0}", keyStr)
			Console.WriteLine("PT={0}", ptStr)
			Console.WriteLine("CT={0}", s)
			Console.WriteLine("OK={0}", ctStr)
			Debug.Assert([String].Compare(s, ctStr, True) = 0, "CipherStream.Hex failed")
			' decrypt by encrypting again
			s = CipherStream.Hex(s, keyStr, "", 0, CipherStream.Algorithm.Arcfour)
			Console.WriteLine("P'={0}", s)
			Console.WriteLine("OK={0}", ptStr)
			Debug.Assert([String].Compare(s, ptStr, True) = 0, "CipherStream.Hex(2) failed")

			' Create a test text file
			excontent = "This is some sample content."
			fnameData = "excontent.txt"
			File.WriteAllText(fnameData, excontent)

			' Encrypt a file
			keyStr = "fedcba98765432100123456789abcdeffedcba98765432100123456789abcdef"
			fnameEnc = "excontent.pc1.enc.dat"
			okhex = "E61C8126AC8B830C32E5ECF1862BCD70778C42B7C130310206151AB1"
			b = Cnv.FromHex(keyStr)


			n = Pc1.File(fnameEnc, fnameData, b)
			If 0 = n Then
				Console.WriteLine("Pc1.File created encrypted file '{0}'", fnameEnc)
			Else
				Console.WriteLine("Pc1.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Pc1.File failed.")

			' Check we got what we should
			b = File.ReadAllBytes(fnameEnc)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(Cnv.ToHex(b), okhex, True) = 0, "Pc1.FileEncrypt failed")

			' Decrypt it by encrypting again
			fnameCheck = "excontent.pc1.chk.txt"
			b = Cnv.FromHex(keyStr)
			n = Pc1.File(fnameCheck, fnameEnc, b)
			If 0 = n Then
				Console.WriteLine("Pc1.File decrypted to file '{0}'", fnameCheck)
				' Show contents of file
				s = File.ReadAllText(fnameCheck)
				Debug.Assert([String].Compare(s, excontent) = 0, "Decrypted file data does not match")
			Else
				Console.WriteLine("Pc1.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "Pc1.File failed.")

			' DO WITH CipherStream.
			fnameEnc = "excontent.rc4.enc.dat"
			n = CipherStream.File(fnameEnc, fnameData, b, Nothing, 0, CipherStream.Algorithm.Arcfour)
			If 0 = n Then
				Console.WriteLine("CipherStream.File created encrypted file '{0}'", fnameEnc)
			Else
				Console.WriteLine("CipherStream.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "CipherStream.File failed.")

			' Check we got what we should
			b = File.ReadAllBytes(fnameEnc)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(Cnv.ToHex(b), okhex, True) = 0, "CipherStream.File failed")

			' Decrypt it by encrypting again
			fnameCheck = "excontent.rc4.chk.txt"
			b = Cnv.FromHex(keyStr)
			n = CipherStream.File(fnameCheck, fnameEnc, b, Nothing, 0, CipherStream.Algorithm.Arcfour)
			If 0 = n Then
				Console.WriteLine("CipherStream.File decrypted to file '{0}'", fnameCheck)
				' Show contents of file
				s = File.ReadAllText(fnameCheck)
				Debug.Assert([String].Compare(s, excontent) = 0, "Decrypted file data does not match")
			Else
				Console.WriteLine("CipherStream.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "CipherStream.File failed.")

			' Create a test text file (Ref: "ChaCha20 and Poly1305 for IETF protocols")
			excontent = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."
			fnameData = "sunscreen.txt"
			File.WriteAllText(fnameData, excontent)
			fnameEnc = "sunscreen-chacha.dat"
			okhex = "6E2E359A2568F98041BA0728DD0D6981E97E7AEC1D4360C20A27AFCCFD9FAE0BF91B65C5524733AB8F593DABCD62B3571639D624E65152AB8F530C359F0861D807CA0DBF500D6A6156A38E088A22B65E52BC514D16CCF806818CE91AB77937365AF90BBF74A35BE6B40B8EEDF2785E42874D"

			' ENCRYPT WITH CHACHA20
			Console.WriteLine(vbLf & "CHACHA20:")
			arrKey = Cnv.FromHex("00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f")
			arrIV = Cnv.FromHex("00:00:00:00:00:00:00:4a:00:00:00:00")
			Console.WriteLine("Key   = " & Cnv.ToHex(arrKey))
			Console.WriteLine("Nonce = " & Cnv.ToHex(arrIV))
			' Counter = 1
			n = CipherStream.File(fnameEnc, fnameData, arrKey, arrIV, 1, CipherStream.Algorithm.Chacha20)
			If 0 = n Then
				Console.WriteLine("CipherStream.File created encrypted file '{0}'", fnameEnc)
			Else
				Console.WriteLine("CipherStream.File returned error code {0}", n)
			End If
			Debug.Assert(0 = n, "CipherStream.File failed.")

			' Check we got what we should
			b = File.ReadAllBytes(fnameEnc)
			Console.WriteLine("CT={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(Cnv.ToHex(b), okhex, True) = 0, "CipherStream.File failed")

			' Stream cipher of 65-byte block
			Console.WriteLine(vbLf & "STREAM CIPHER 65-BYTE KEYSTREAM:")
			' To generate a keystream of N bytes, encrypt input of N x zero bytes
			arrPlain = New Byte(64) {}
			' All zeros
			Console.WriteLine("ARCFOUR:")
			' Ref: RFC6229. Test Vector 7, Key length: 256 bits.
			arrKey = Cnv.FromHex("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20")
			okhex = "eaa6bd25880bf93d3f5d1e4ca2611d91cfa45c9f7e714b54bdfa80027cb14380"
			Console.WriteLine("Key: " & Cnv.ToHex(arrKey))
			Console.WriteLine("IV : " & "n/a")
			b = CipherStream.Bytes(arrPlain, arrKey, Nothing, 0, CipherStream.Algorithm.Arcfour)
			Debug.Assert(b.Length = arrPlain.Length)
			Console.WriteLine("Keystream:" & vbLf & Cnv.ToHex(b))
			' Check bytes we have test vector for
			Debug.Assert([String].Compare(Cnv.ToHex(b).Substring(0, okhex.Length), okhex, True) = 0, "CipherStream.File failed")

			Console.WriteLine("SALSA20:")
			' Ref: `verified.test-vectors.txt` Set 3, vector#  0:
			arrKey = Cnv.FromHex("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")
			arrIV = Cnv.FromHex("0000000000000000")
			okhex = "B580F7671C76E5F7441AF87C146D6B513910DC8B4146EF1B3211CF12AF4A4B49E5C874B3EF4F85E7D7ED539FFEBA73EB73E0CCA74FBD306D8AA716C7783E89AF"
			Console.WriteLine("Key: " & Cnv.ToHex(arrKey))
			Console.WriteLine("IV : " & Cnv.ToHex(arrIV))
			b = CipherStream.Bytes(arrPlain, arrKey, arrIV, 0, CipherStream.Algorithm.Salsa20)
			Debug.Assert(b.Length = arrPlain.Length)
			Console.WriteLine("Keystream:" & vbLf & Cnv.ToHex(b))
			' Check bytes we have test vector for
			Debug.Assert([String].Compare(Cnv.ToHex(b).Substring(0, okhex.Length), okhex, True) = 0, "CipherStream.File failed")

			Console.WriteLine("CHACHA20:")
			' Ref: `draft-strombergson-chacha-test-vectors-02.txt` TC7: Sequence patterns in key and IV. Rounds: 20
			arrKey = Cnv.FromHex("00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100")
			arrIV = Cnv.FromHex("0f1e2d3c4b5a6978")
			okhex = "9fadf409c00811d00431d67efbd88fba59218d5d6708b1d685863fabbb0e961eea480fd6fb532bfd494b2151015057423ab60a63fe4f55f7a212e2167ccab931fb"
			Console.WriteLine("Key: " & Cnv.ToHex(arrKey))
			Console.WriteLine("IV : " & Cnv.ToHex(arrIV))
			b = CipherStream.Bytes(arrPlain, arrKey, arrIV, 0, CipherStream.Algorithm.Chacha20)
			Debug.Assert(b.Length = arrPlain.Length)
			Console.WriteLine("Keystream:" & vbLf & Cnv.ToHex(b))
			' Check bytes we have test vector for
			Debug.Assert([String].Compare(Cnv.ToHex(b).Substring(0, okhex.Length), okhex, True) = 0, "CipherStream.File failed")

			' USE INCREMENTAL METHODS
			Console.WriteLine("CHACHA20 (incremental):")
			arrKey = Cnv.FromHex("00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100")
			arrIV = Cnv.FromHex("0f1e2d3c4b5a6978")
			okhex = "9fadf409c00811d00431d67efbd88fba59218d5d6708b1d685863fabbb0e961eea480fd6fb532bfd494b2151015057423ab60a63fe4f55f7a212e2167ccab931fb"

			Dim oCStream As CipherStream = CipherStream.Instance()
			n = oCStream.Init(arrKey, arrIV, 0, CipherStream.Algorithm.Chacha20)
			Console.WriteLine("oCStream.Init returns {0} (expecting 0)", n)
			Debug.Assert(oCStream.ErrCode = 0, "oCStream.Init failed")

			' Encrypt a 65-byte input of zeros in chunks of 1, 62 and 2 bytes
			arrCipher = New Byte(-1) {}
			' We'll build up the full ciphertext as we go, for a check
			arrPlain = New Byte(0) {}
			b = oCStream.Update(arrPlain)
			Console.WriteLine(Cnv.ToHex(b))
			arrCipher = ByteArraysConcat(arrCipher, b)

			arrPlain = New Byte(61) {}
			b = oCStream.Update(arrPlain)
			Console.WriteLine(Cnv.ToHex(b))
			arrCipher = ByteArraysConcat(arrCipher, b)

			arrPlain = New Byte(1) {}
			b = oCStream.Update(arrPlain)
			Console.WriteLine(Cnv.ToHex(b))
			arrCipher = ByteArraysConcat(arrCipher, b)

			Console.WriteLine(Cnv.ToHex(arrCipher))
			Debug.Assert([String].Compare(Cnv.ToHex(arrCipher).Substring(0, okhex.Length), okhex, True) = 0, "CipherStream.Update failed")


			' We are done with CipherStream object
			oCStream.Dispose()

		End Sub

		Private Shared Sub test_KeyWrap()
			Dim arrPlain As Byte()
			Dim arrCipher As Byte()
			Dim arrKey As Byte()
			Dim bcheck As Byte()
			Dim strCheck As String
			' **************
			' KEY WRAPPING
			' **************
			Console.WriteLine(vbLf & "KEY WRAPPING WITH BLOCK CIPHER:")
			' Some test AES-128 key material data
			Console.WriteLine("Using AES128-Wrap")
			arrPlain = Cnv.FromHex("00112233 44556677 8899aabb ccddeeff")
			Console.WriteLine("Key material={0}", Cnv.ToHex(arrPlain))
			' Key Encryption Key
			arrKey = Cnv.FromHex("c17a44e8 e28d7d64 81d1ddd5 0a3b8914")
			Console.WriteLine("KEK         ={0}", Cnv.ToHex(arrKey))
			' Wrap with AES128-Wrap algorithm
			arrCipher = Cipher.KeyWrap(arrPlain, arrKey, CipherAlgorithm.Aes128)
			Debug.Assert(arrCipher.Length > 0, "Cipher.KeyWrap failed.")
			Console.WriteLine("Wrapped Key ={0}", Cnv.ToHex(arrCipher))
			' Compare to known test vector (AES wrap always gives the same result for the same input)
			strCheck = "503D75C73630A7B02ECF51B9B29B907749310B77B0B2E054"
			Debug.Assert([String].Compare(strCheck, Cnv.ToHex(arrCipher), True) = 0, "AES128-Wrap key material does not match test vector")

			' Check we can unwrap it
			bcheck = Cipher.KeyUnwrap(arrCipher, arrKey, CipherAlgorithm.Aes128)
			Debug.Assert(arrCipher.Length > 0, "Cipher.KeyUnwrap failed.")
			Console.WriteLine("Unwrapped   ={0}", Cnv.ToHex(bcheck))
			Debug.Assert(ByteArraysEqual(bcheck, arrPlain), "Unwrapped key is different.")

			' Some test Triple DES key material data
			Console.WriteLine("Using 3DES-Wrap")
			arrPlain = Cnv.FromHex("84e7f2d8 78f89fcc cd2d5eba fc56daf7 3300f27e f771cd68")
			Console.WriteLine("Key material={0}", Cnv.ToHex(arrPlain))
			' Key Encryption Key
			arrKey = Cnv.FromHex("8ad8274e 56f46773 8edd83d4 394e5e29 af7c4089 e4f8d9f4")
			Console.WriteLine("KEK         ={0}", Cnv.ToHex(arrKey))
			' Wrap with 3DES-Wrap algorithm
			arrCipher = Cipher.KeyWrap(arrPlain, arrKey, CipherAlgorithm.Tdea)
			Debug.Assert(arrCipher.Length > 0, "Cipher.KeyWrap failed.")
			Console.WriteLine("Wrapped Key ={0}", Cnv.ToHex(arrCipher))
			' NOTE: We can't compare to known test vector because 3DES wrap gives a different result each time.
			' Check we can unwrap it
			bcheck = Cipher.KeyUnwrap(arrCipher, arrKey, CipherAlgorithm.Tdea)
			Debug.Assert(arrCipher.Length > 0, "Cipher.KeyUnwrap failed.")
			Console.WriteLine("Unwrapped   ={0}", Cnv.ToHex(bcheck))
			Debug.Assert(ByteArraysEqual(bcheck, arrPlain), "Unwrapped key is different.")

		End Sub

		Private Shared Sub test_Padding()
			Dim s As String
			Dim i As Integer
			Dim b As Byte()
			Dim arrPads As Padding() = New Padding() {Padding.[Default], Padding.Pkcs5, Padding.OneAndZeroes, Padding.AnsiX923}

			' *************************
			' PADDING FOR BLOCK CIPHERS
			' *************************
			Console.WriteLine(vbLf & "PADDING FOR BLOCK CIPHERS:")
			For Each padding__1 As Padding In arrPads
				Console.WriteLine("PADDING={0}", padding__1.ToString())
				' 1. Pad a byte array of 5 bytes for Triple DES ECB/CBC mode
				b = New Byte(4) {&Hff, &Hff, &Hff, &Hff, &Hff}
				Console.WriteLine("Input   =0x{0}", Cnv.ToHex(b))
				b = Cipher.Pad(b, CipherAlgorithm.Tdea, padding__1)
				Console.WriteLine("Padded  =0x{0}", Cnv.ToHex(b))
				' Now strip the padding
				b = Cipher.Unpad(b, CipherAlgorithm.Tdea, padding__1)
				Console.WriteLine("Unpadded=0x{0}", Cnv.ToHex(b))
				' 2. Pad a byte array of 18 bytes for AES ECB/CBC mode
				b = New Byte(17) {}
				For i = 0 To b.Length - 1
					b(i) = &Hff
				Next
				Console.WriteLine("Input   =0x{0}", Cnv.ToHex(b))
				b = Cipher.Pad(b, CipherAlgorithm.Aes128, padding__1)
				Console.WriteLine("Padded  =0x{0}", Cnv.ToHex(b))
				' Now strip the padding
				b = Cipher.Unpad(b, CipherAlgorithm.Aes128, padding__1)
				Console.WriteLine("Unpadded=0x{0}", Cnv.ToHex(b))
				' 3. Pad an empty byte array for TDEA
				b = New Byte(-1) {}
				Console.WriteLine("Input   =0x{0}", Cnv.ToHex(b))
				b = Cipher.Pad(b, CipherAlgorithm.Tdea, padding__1)
				Console.WriteLine("Padded  =0x{0}", Cnv.ToHex(b))
				' Now strip the padding
				b = Cipher.Unpad(b, CipherAlgorithm.Tdea, padding__1)
				Console.WriteLine("Unpadded=0x{0}", Cnv.ToHex(b))
				' 4. Pad a hex string for AES
				s = "ff"
				Console.WriteLine("Input   ='{0}'", s)
				s = Cipher.Pad(s, CipherAlgorithm.Aes128, padding__1)
				Console.WriteLine("Padded  ='{0}'", s)
				' Now strip the padding
				s = Cipher.Unpad(s, CipherAlgorithm.Aes128, padding__1)
				Console.WriteLine("Unpadded='{0}'", s)
				' 5. Pad an empty hex string for AES
				s = ""
				Console.WriteLine("Input   ='{0}'", s)
				s = Cipher.Pad(s, CipherAlgorithm.Aes128, padding__1)
				Console.WriteLine("Padded  ='{0}'", s)
				' Now strip the padding
				s = Cipher.Unpad(s, CipherAlgorithm.Aes128, padding__1)
				Console.WriteLine("Unpadded='{0}'", s)
			Next

		End Sub

		Private Shared Sub test_SHA1()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim isok As Boolean
			Dim i As Integer
			Dim fnameData As String
			Dim a1000 As Byte()
			'**************************
			' SHA-1 HASH DIGEST TESTS *
			'**************************
			Console.WriteLine(vbLf & "TESTING SHA-1:")
			' Ansi string input
			s = Sha1.HexHash("abc")
			Console.WriteLine("Sha1('abc')={0}", s)
			' Correct answers from FIPS-180-2
			okhex = "a9993e364706816aba3e25717850c26c9cd0d89d"
			Debug.Assert([String].Compare(okhex, s, True) = 0, "Sha1('abc') failed")

			' byte data input, hex output
			b = New Byte() {&H61, &H62, &H63}
			s = Sha1.HexHash(b)
			Console.WriteLine("Sha1('abc')={0}", s)
			Debug.Assert([String].Compare(okhex, s, True) = 0, "Sha1('abc') failed")

			' byte data input, byte output
			b = Sha1.BytesHash(b)
			Console.WriteLine("Sha1('abc')={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(okhex, Cnv.ToHex(b), True) = 0, "Sha1('abc') failed")

			' file input
			fnameData = "abc.txt"
			File.WriteAllText(fnameData, "abc")
			s = Sha1.FileHexHash(fnameData)
			Console.WriteLine("Sha1('abc')={0}", s)

			' Get digest of core DLL file
			' See http://www.cryptosys.net/integrity.html
			fnameData = General.ModuleName()
			s = Sha1.FileHexHash(fnameData)
			Console.WriteLine("Sha1(DLL module)={0}", s)

			' Instantiate a new object
			Dim oSha1 As Sha1 = Sha1.Instance()
			isok = oSha1.Init()
			Console.WriteLine("oSha1.Init returned {0}", isok)
			Debug.Assert(isok, "Sha1.Init failed")

			n = oSha1.AddData("a")
			n = oSha1.AddData("bc")
			s = oSha1.HexDigest()
			Console.WriteLine("Sha1('abc')={0}", s)

			' Compute SHA1(one million repetitions of 'a')
			oSha1.Init()
			a1000 = New Byte(999) {}
			For i = 0 To 999
				a1000(i) = &H61
			Next
			' 'a' in ascii form
			For i = 0 To 999
				n = oSha1.AddData(a1000)
				Debug.Assert(0 = n, "Sha1.Adddata failed")
			Next
			s = oSha1.HexDigest()
			Console.WriteLine("Sha1(1M x 'a')={0}", s)
			okhex = "34aa973cd4c4daa4f61eeb2bdbad27316534016f"
			Debug.Assert([String].Compare(okhex, s, True) = 0, "Sha1(1M x 'a') failed")

		End Sub

		Private Shared Sub test_SHA256()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim isok As Boolean
			Dim i As Integer
			Dim fnameData As String
			Dim a1000 As Byte()
			'****************************
			' SHA-256 HASH DIGEST TESTS *
			'****************************
			Console.WriteLine(vbLf & "TESTING SHA-256:")
			' Ansi string input
			s = Sha256.HexHash("abc")
			Console.WriteLine("Sha256('abc')={0}", s)
			' Correct answers from FIPS-180-2
			okhex = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
			Debug.Assert([String].Compare(okhex, s, True) = 0, "Sha256('abc') failed")

			' byte data input, hex output
			b = New Byte() {&H61, &H62, &H63}
			s = Sha256.HexHash(b)
			Console.WriteLine("Sha256('abc')={0}", s)
			Debug.Assert([String].Compare(okhex, s, True) = 0, "Sha256('abc') failed")

			' byte data input, byte output
			b = Sha256.BytesHash(b)
			Console.WriteLine("Sha256('abc')={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(Cnv.ToHex(b), s, True) = 0, "Sha256('abc') failed")

			' file input
			fnameData = "abc.txt"
			File.WriteAllText(fnameData, "abc")
			s = Sha256.FileHexHash(fnameData)
			Console.WriteLine("Sha256('abc')={0}", s)

			' Get digest of core DLL file
			' See http://www.cryptosys.net/integrity.html
			fnameData = General.ModuleName()
			s = Sha256.FileHexHash(fnameData)
			Console.WriteLine("Sha256(DLL module)={0}", s)

			' Instantiate a new object
			Dim oSha256 As Sha256 = Sha256.Instance()
			isok = oSha256.Init()
			Console.WriteLine("oSha256.Init returned {0}", isok)
			Debug.Assert(isok, "Sha256.Init failed")

			n = oSha256.AddData("a")
			n = oSha256.AddData("bc")
			s = oSha256.HexDigest()
			Console.WriteLine("Sha256('abc')={0}", s)

			' Compute SHA256(one million repetitions of 'a')
			oSha256.Init()
			a1000 = New Byte(999) {}
			For i = 0 To 999
				a1000(i) = &H61
			Next
			' 'a' in ascii form
			For i = 0 To 999
				n = oSha256.AddData(a1000)
				Debug.Assert(0 = n, "Sha256.Adddata failed")
			Next
			s = oSha256.HexDigest()
			Console.WriteLine("Sha256(1M x 'a')={0}", s)
			okhex = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
			Debug.Assert([String].Compare(okhex, s, True) = 0, "Sha256(1M x 'a') failed")

		End Sub

		Private Shared Sub test_MD5()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim okhex As String
			Dim isok As Boolean
			Dim i As Integer
			Dim fnameData As String
			Dim a1000 As Byte()
			'************************
			' MD5 HASH DIGEST TESTS *
			'************************
			Console.WriteLine(vbLf & "TESTING MD5:")
			' Ansi string input
			s = Md5.HexHash("abc")
			Console.WriteLine("Md5('abc')={0}", s)
			' Correct answers from RFC 1321
			okhex = "900150983cd24fb0d6963f7d28e17f72"
			Debug.Assert([String].Compare(okhex, s, True) = 0, "Md5('abc') failed")

			' byte data input, hex output
			b = New Byte() {&H61, &H62, &H63}
			s = Md5.HexHash(b)
			Console.WriteLine("Md5('abc')={0}", s)
			Debug.Assert([String].Compare(okhex, s, True) = 0, "Md5('abc') failed")

			' byte data input, byte output
			b = Md5.BytesHash(b)
			Console.WriteLine("Md5('abc')={0}", Cnv.ToHex(b))
			Debug.Assert([String].Compare(okhex, Cnv.ToHex(b), True) = 0, "Md5('abc') failed")

			' file input
			fnameData = "abc.txt"
			File.WriteAllText(fnameData, "abc")
			s = Md5.FileHexHash(fnameData)
			Console.WriteLine("Md5('abc')={0}", s)

			' Get digest of core DLL file
			' See http://www.cryptosys.net/integrity.html
			fnameData = General.ModuleName()
			s = Md5.FileHexHash(fnameData)
			Console.WriteLine("Md5(DLL module)={0}", s)

			' Instantiate a new object
			Dim oMd5 As Md5 = Md5.Instance()
			isok = oMd5.Init()
			Console.WriteLine("oMd5.Init returned {0}", isok)
			Debug.Assert(isok, "Md5.Init failed")

			n = oMd5.AddData("a")
			n = oMd5.AddData("bc")
			s = oMd5.HexDigest()
			Console.WriteLine("Md5('abc')={0}", s)

			' Compute MD5(one million repetitions of 'a')
			oMd5.Init()
			a1000 = New Byte(999) {}
			For i = 0 To 999
				a1000(i) = &H61
			Next
			' 'a' in ascii form
			For i = 0 To 999
				n = oMd5.AddData(a1000)
				Debug.Assert(0 = n, "Md5.Adddata failed")
			Next
			s = oMd5.HexDigest()
			Console.WriteLine("Md5(1M x 'a')={0}", s)
			okhex = "7707d6ae4e027c70eea2a935c2296f21"
			Debug.Assert([String].Compare(okhex, s, True) = 0, "Md5(1M x 'a') failed")
		End Sub

		Private Shared Sub test_Hash()
			Dim s As String
			Dim fnameInput As String

			'*************
			' HASH TESTS *
			'*************
			Console.WriteLine("HASH DIGEST TESTS:")
			' Known test vectors for Hash('abc')
			Const  OK_MD5_ABC As String = "900150983cd24fb0d6963f7d28e17f72"
			Const  OK_MD2_ABC As String = "da853b0d3f88d99b30283a69e6ded6bb"
			Const  OK_SHA1_ABC As String = "a9993e364706816aba3e25717850c26c9cd0d89d"
			Const  OK_SHA256_ABC As String = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
			Const  OK_SHA384_ABC As String = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"
			Const  OK_SHA512_ABC As String = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
			Const  OK_SHA224_ABC As String = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"
			Const  OK_RMD160_ABC As String = "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"
			'----

			s = Hash.HexFromString("abc", HashAlgorithm.Sha1)
			Console.WriteLine("SHA-1('abc')  ={0}", s)
			Debug.Assert([String].Compare(OK_SHA1_ABC, s, True) = 0, "SHA-1('abc')")

			s = Hash.HexFromString("abc", HashAlgorithm.Md5)
			Console.WriteLine("MD5('abc')    ={0}", s)
			Debug.Assert([String].Compare(OK_MD5_ABC, s, True) = 0, "MD5('abc')")

			s = Hash.HexFromString("abc", HashAlgorithm.Md2)
			Console.WriteLine("MD2('abc')    ={0}", s)
			Debug.Assert([String].Compare(OK_MD2_ABC, s, True) = 0, "MD2('abc')")

			s = Hash.HexFromString("abc", HashAlgorithm.Ripemd160)
			Console.WriteLine("RIPEMD-160('abc')    ={0}", s)
			Debug.Assert([String].Compare(OK_RMD160_ABC, s, True) = 0, "RIPEMD-160('abc')")

			s = Hash.HexFromString("abc", HashAlgorithm.Sha224)
			Console.WriteLine("SHA-224('abc')=" & vbLf & "{0}", s)
			Debug.Assert([String].Compare(OK_SHA224_ABC, s, True) = 0, "SHA-224('abc')")

			s = Hash.HexFromString("abc", HashAlgorithm.Sha256)
			Console.WriteLine("SHA-256('abc')=" & vbLf & "{0}", s)
			Debug.Assert([String].Compare(OK_SHA256_ABC, s, True) = 0, "SHA-256('abc')")

			s = Hash.HexFromString("abc", HashAlgorithm.Sha384)
			Console.WriteLine("SHA-384('abc')=" & vbLf & "{0}", s)
			Debug.Assert([String].Compare(OK_SHA384_ABC, s, True) = 0, "SHA-384('abc')")

			s = Hash.HexFromString("abc", HashAlgorithm.Sha512)
			Console.WriteLine("SHA-512('abc')=" & vbLf & "{0}", s)
			Debug.Assert([String].Compare(OK_SHA512_ABC, s, True) = 0, "SHA-512('abc')")

			' Hex input
			s = Hash.HexFromHex("616263", HashAlgorithm.Sha1)
			Console.WriteLine("SHA-1(0x616263)  ={0}", s)
			Debug.Assert([String].Compare(OK_SHA1_ABC, s, True) = 0, "SHA-1(0x616263)")

			s = Hash.HexFromHex("616263", HashAlgorithm.Sha512)
			Console.WriteLine("SHA-512(0x616263)=" & vbLf & "{0}", s)
			Debug.Assert([String].Compare(OK_SHA512_ABC, s, True) = 0, "SHA-512(0x616263)")

			' Create a test file
			fnameInput = "hello.txt"
			File.WriteAllText(fnameInput, "hello world" & vbCr & vbLf)
			' get digest from binary file
			s = Hash.HexFromFile(fnameInput, HashAlgorithm.Sha1)
			Console.WriteLine("SHA1('hello world+CR+LF')={0}", s)
			' and again treating CR-LF as a single LF
			' (we use this when moving between Unix and Windows systems)
			s = Hash.HexFromTextFile(fnameInput, HashAlgorithm.Sha1)
			Console.WriteLine("SHA1('hello world+LF')=   {0}", s)

		End Sub

		Private Shared Sub test_HashBit()
			Dim s As String
			Dim nbitlen As Integer
			Dim msg As Byte()
			Dim msgHex As String
			'**************************
			' BIT-ORIENTED HASH TESTS *
			'**************************
			' New in v4.6
			Console.WriteLine(vbLf & "BIT-ORIENTED HASH TESTS:")
			nbitlen = 9
			msgHex = "5180"
			msg = Cnv.FromHex(msgHex)
			Console.WriteLine("[SHA-1]")
			Console.WriteLine("[L = {0}]", Hash.LengthInBytes(HashAlgorithm.Sha1))
			Console.WriteLine("Len = {0}", nbitlen)
			Console.WriteLine("Msg = {0}", Cnv.ToHex(msg))
			s = Hash.HexFromBits(msg, nbitlen, HashAlgorithm.Sha1)
			Console.WriteLine("MD = {0}", s)
			Debug.Assert([String].Compare("0f582fa68b71ecdf1dcfc4946019cf5a18225bd2", s, True) = 0, "Hash.HexFromBits failed")
		End Sub

		Private Shared Sub test_HMAC()
			Dim s As String
			Dim b As Byte()
			Dim i As Integer
			Dim arrKey As Byte()
			Dim msg As Byte()
			Dim strCheck As String
			'*************
			' HMAC TESTS *
			'*************
			Console.WriteLine(vbLf & "HMAC TESTS:")
			'  Test case 2 from RFC 2202 and RFC 4231
			'	key =           "Jefe"
			'	key_len         4
			'	data =          "what do ya want for nothing?"
			'	data_len =      28

			Console.WriteLine("Test case 2 from RFC 2202 and RFC 4231...")
			' Convert strings to byte arrays
			arrKey = System.Text.Encoding.[Default].GetBytes("Jefe")
			msg = System.Text.Encoding.[Default].GetBytes("what do ya want for nothing?")
			' Compute HMAC-SHA-1 then check against known test vector
			s = Mac.HexFromBytes(msg, arrKey, MacAlgorithm.HmacSha1)
			Console.WriteLine("HMAC-SHA-1('WDYWFN?','Jefe')={0}", s)
			strCheck = "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"
			Console.WriteLine("CORRECT=                     {0}", strCheck)
			Debug.Assert([String].Compare(strCheck, s, True) = 0, "HMAC does not match test vector")
			' Compute HMAC-SHA-256 then check against known test vector
			s = Mac.HexFromBytes(msg, arrKey, MacAlgorithm.HmacSha256)
			Console.WriteLine("HMAC-SHA-256('WDYWFN?','Jefe')=" & vbLf & "{0}", s)
			strCheck = "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"
			Console.WriteLine("CORRECT=" & vbLf & "{0}", strCheck)
			Debug.Assert([String].Compare(strCheck, s, True) = 0, "HMAC does not match test vector")

			'  Test case 4 from RFC 2202 and RFC 4231
			'	key =           0x0102030405060708090a0b0c0d0e0f10111213141516171819
			'	key_len         25
			'	data =          0xcd repeated 50 times
			'	data_len =      50

			Console.WriteLine("Test case 4 from RFC 2202 and RFC 4231...")
			arrKey = New Byte(24) {}
			For i = 0 To 24
				arrKey(i) = CByte(i + 1)
			Next
			Console.WriteLine("Key={0}", Cnv.ToHex(arrKey))
			msg = New Byte(49) {}
			For i = 0 To 49
				msg(i) = &Hcd
			Next
			Console.WriteLine("Msg={0}", Cnv.ToHex(msg))
			' Output in byte format
			' Compute HMAC-SHA-1 then check against known test vector
			b = Mac.BytesFromBytes(msg, arrKey, MacAlgorithm.HmacSha1)
			Console.WriteLine("HMAC-SHA-1(50(0xcd), 0x0102..19)={0}", Cnv.ToHex(b))
			strCheck = "4c9007f4026250c6bc8414f9bf50c86c2d7235da"
			Console.WriteLine("CORRECT=                         {0}", strCheck)
			Debug.Assert([String].Compare(strCheck, Cnv.ToHex(b), True) = 0, "HMAC does not match test vector")
			' Compute HMAC-SHA-224 then check against known test vector
			b = Mac.BytesFromBytes(msg, arrKey, MacAlgorithm.HmacSha224)
			Console.WriteLine("HMAC-SHA-224(50(0xcd), 0x0102..19)=" & vbLf & "{0}", Cnv.ToHex(b))
			strCheck = "6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a"
			Console.WriteLine("CORRECT=" & vbLf & "{0}", strCheck)
			Debug.Assert([String].Compare(strCheck, Cnv.ToHex(b), True) = 0, "HMAC does not match test vector")
			' Compute HMAC-SHA-256 then check against known test vector
			b = Mac.BytesFromBytes(msg, arrKey, MacAlgorithm.HmacSha256)
			Console.WriteLine("HMAC-SHA-256(50(0xcd), 0x0102..19)=" & vbLf & "{0}", Cnv.ToHex(b))
			strCheck = "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"
			Console.WriteLine("CORRECT=" & vbLf & "{0}", strCheck)
			Debug.Assert([String].Compare(strCheck, Cnv.ToHex(b), True) = 0, "HMAC does not match test vector")
			' Compute HMAC-SHA-512 then check against known test vector
			b = Mac.BytesFromBytes(msg, arrKey, MacAlgorithm.HmacSha512)
			Console.WriteLine("HMAC-SHA-512(50(0xcd), 0x0102..19)=" & vbLf & "{0}", Cnv.ToHex(b))
			strCheck = "b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd"
			Console.WriteLine("CORRECT=" & vbLf & "{0}", strCheck)
			Debug.Assert([String].Compare(strCheck, Cnv.ToHex(b), True) = 0, "HMAC does not match test vector")
			' Compute HMAC-RIPEMD-160 then check against known test vector (RFC2286)
			b = Mac.BytesFromBytes(msg, arrKey, MacAlgorithm.HmacRipemd160)
			Console.WriteLine("HMAC-RIPEMD-160(50(0xcd), 0x0102..19)=" & vbLf & "{0}", Cnv.ToHex(b))
			strCheck = "d5ca862f4d21d5e610e18b4cf1beb97a4365ecf4"
			Console.WriteLine("CORRECT=" & vbLf & "{0}", strCheck)
			Debug.Assert([String].Compare(strCheck, Cnv.ToHex(b), True) = 0, "HMAC does not match test vector")


		End Sub

		Private Shared Sub test_CMAC()
			Dim s As String
			Dim strCheck As String
			Dim keyHex As String
			Dim msgHex As String
			'*************
			' CMAC TESTS *
			'*************
			Console.WriteLine(vbLf & "CMAC TESTS:")
			Console.WriteLine("Test cases from SP800-38B...")
			keyHex = "2b7e151628aed2a6abf7158809cf4f3c"
			' CMAC-AES-128 on the empty string
			msgHex = ""
			s = Mac.HexFromHex(msgHex, keyHex, MacAlgorithm.CmacAes128)
			Console.WriteLine("CMAC-AES-128(K128, '')=" & vbLf & "{0}", s)
			strCheck = "bb1d6929e95937287fa37d129b756746"
			Console.WriteLine("CORRECT=" & vbLf & "{0}", strCheck)
			Debug.Assert([String].Compare(strCheck, s, True) = 0, "CMAC does not match test vector")

			msgHex = "6bc1bee22e409f96e93d7e117393172a"
			s = Mac.HexFromHex(msgHex, keyHex, MacAlgorithm.CmacAes128)
			Console.WriteLine("CMAC-AES-128(K128, M128)=" & vbLf & "{0}", s)
			strCheck = "070a16b46b4d4144f79bdd9dd04a287c"
			Console.WriteLine("CORRECT=" & vbLf & "{0}", strCheck)
			Debug.Assert([String].Compare(strCheck, s, True) = 0, "CMAC does not match test vector")

			' CMAC_AES-256 on Example 12: Mlen = 512 

			keyHex = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"
			msgHex = "6bc1bee22e409f96e93d7e117393172a" & "ae2d8a571e03ac9c9eb76fac45af8e51" & "30c81c46a35ce411e5fbc1191a0a52ef" & "f69f2445df4f9b17ad2b417be66c3710"
			s = Mac.HexFromHex(msgHex, keyHex, MacAlgorithm.CmacAes256)
			Console.WriteLine("CMAC-AES-256(K256, M512)=" & vbLf & "{0}", s)
			strCheck = "e1992190549f6ed5696a2c056c315410"
			Console.WriteLine("CORRECT=" & vbLf & "{0}", strCheck)
			Debug.Assert([String].Compare(strCheck, s, True) = 0, "CMAC does not match test vector")

			' CMAC_TDEA on Example 16: Mlen = 256 

			keyHex = "8aa83bf8cbda10620bc1bf19fbb6cd58bc313d4a371ca8b5"
			msgHex = "6bc1bee22e409f96e93d7e117393172a" & "ae2d8a571e03ac9c9eb76fac45af8e51"
			s = Mac.HexFromHex(msgHex, keyHex, MacAlgorithm.CmacTdea)
			Console.WriteLine("CMAC-DES-EDE(K192, M256)=" & vbLf & "{0}", s)
			strCheck = "33e6b1092400eae5"
			Console.WriteLine("CORRECT=" & vbLf & "{0}", strCheck)
			Debug.Assert([String].Compare(strCheck, s, True) = 0, "CMAC does not match test vector")

		End Sub

		Private Shared Sub test_PBKDF2()
			Dim n As Integer
			Dim keyStr As String
			Dim saltHex As String
			Dim arrKey As Byte()
			Dim salt As Byte()
			Dim arrPwd As Byte()
			Dim strCheck As String
			'***************
			' PBKDF2 TESTS *
			'***************
			Console.WriteLine(vbLf & "TESTING PBKDF2...")
			' convert password string to bytes
			arrPwd = System.Text.Encoding.[Default].GetBytes("password")
			' make a salt
			salt = New Byte() {&H78, &H57, &H8e, &H5a, &H5d, &H63, _
				&Hcb, &H6}
			' create a 24-byte (192-bit) key
			n = 24
			arrKey = Pbe.Kdf2(n, arrPwd, salt, 2048)
			Debug.Assert(arrKey.Length > 0, "ERROR with Pbe.Kdf2")
			Console.WriteLine("Key({0})={1}", n * 8, Cnv.ToHex(arrKey))
			' and again for a 64-byte (512-bit) key
			n = 64
			arrKey = Pbe.Kdf2(n, arrPwd, salt, 2048)
			Debug.Assert(arrKey.Length > 0, "ERROR with Pbe.Kdf2")
			Console.WriteLine("Key({0})={1}", n * 8, Cnv.ToHex(arrKey))
			' Same example using hex format
			saltHex = "78578e5a5d63cb06"
			n = 24
			strCheck = "BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"
			keyStr = Pbe.Kdf2(n, "password", saltHex, 2048)
			Debug.Assert(keyStr.Length > 0, "ERROR with PbeKdf2/Hex")
			Console.WriteLine("Key({0})={1}", n * 8, keyStr)
			' Compare with known test vector
			Debug.Assert([String].Compare(strCheck, keyStr, True) = 0, "PBKDF Derived key {HMAC-SHA-1} does not match test vector")

			' Use different hash function (SHA-256) in KDF
			Console.WriteLine("Using SHA-256 in KDF...")
			n = 24
			arrKey = Pbe.Kdf2(n, arrPwd, salt, 2048, HashAlgorithm.Sha256)
			Debug.Assert(arrKey.Length > 0, "ERROR with Pbe.Kdf2")
			Console.WriteLine("Key({0})={1}", n * 8, Cnv.ToHex(arrKey))
			' using hex format
			saltHex = "78578e5a5d63cb06"
			n = 24
			strCheck = "97B5A91D35AF542324881315C4F849E327C4707D1BC9D322"
			keyStr = Pbe.Kdf2(n, "password", saltHex, 2048, HashAlgorithm.Sha256)
			Debug.Assert(keyStr.Length > 0, "ERROR with PbeKdf2/Hex")
			Console.WriteLine("Key({0})={1}", n * 8, keyStr)
			' Compare with known test vector
			Debug.Assert([String].Compare(strCheck, keyStr, True) = 0, "PBKDF Derived key {HMAC-SHA-256} does not match test vector")

			' And again using SHA-224 in KDF
			Console.WriteLine("Using SHA-224 in KDF...")
			n = 24
			arrKey = Pbe.Kdf2(n, arrPwd, salt, 2048, HashAlgorithm.Sha224)
			Debug.Assert(arrKey.Length > 0, "ERROR with Pbe.Kdf2")
			Console.WriteLine("Key({0})={1}", n * 8, Cnv.ToHex(arrKey))
			' using hex format
			saltHex = "78578e5a5d63cb06"
			n = 24
			strCheck = "10CFFEDFB13503519969151E466F587028E0720B387F9AEF"
			keyStr = Pbe.Kdf2(n, "password", saltHex, 2048, HashAlgorithm.Sha224)
			Debug.Assert(keyStr.Length > 0, "ERROR with PbeKdf2/Hex")
			Console.WriteLine("Key({0})={1}", n * 8, keyStr)
			' Compare with known test vector
			Debug.Assert([String].Compare(strCheck, keyStr, True) = 0, "PBKDF Derived key {HMAC-SHA-224} does not match test vector")

		End Sub

		Private Shared Sub test_scrypt()
			Dim dkLen As Integer
			Dim key As Byte()
			Dim salt As Byte()
			Dim pwd As Byte()
			Dim checkHex As String
			Dim N As Integer, r As Integer, p__1 As Integer
			Dim P__2 As String, S As String
			Dim keyHex As String, saltHex As String
			'***************
			' SCRYPT TESTS *
			'***************
			Console.WriteLine(vbLf & "TESTING SCRYPT...")
			' Test vectors from [RFC7914]
			' scrypt (P="password", S="NaCl", N=1024, r=8, p=16, dkLen=64)
			P__2 = "password"
			S = "NaCl"
			N = 1024
			r = 8
			p__1 = 16
			dkLen = 64
			' Convert password and salt strings to bytes
			pwd = System.Text.Encoding.[Default].GetBytes(P__2)
			salt = System.Text.Encoding.[Default].GetBytes(S)
			checkHex = "FDBABE1C9D3472007856E7190D01E9FE7C6AD7CBC8237830E77376634B3731622EAF30D92E22A3886FF109279D9830DAC727AFB94A83EE6D8360CBDFA2CC0640"
			key = Pbe.Scrypt(dkLen, pwd, salt, N, r, p__1)
			Debug.Assert(key.Length > 0, "ERROR with Pbe.Scrypt")
			Console.WriteLine("scrypt(P='{0}',S='{1}',N={2},r={3},p={4})=" & vbLf & "{5}", P__2, S, N, r, p__1, _
				Cnv.ToHex(key))
			' Compare with known test vector
			Debug.Assert([String].Compare(checkHex, Cnv.ToHex(key), True) = 0, "SCRYPT derived key does not match test vector")

			' scrypt (P="", S="", N=16, r=1, p=1, dkLen=64)
			P__2 = ""
			S = ""
			N = 16
			r = 1
			p__1 = 1
			dkLen = 64
			' Convert password and salt strings to bytes
			pwd = System.Text.Encoding.[Default].GetBytes(P__2)
			salt = System.Text.Encoding.[Default].GetBytes(S)
			checkHex = "77D6576238657B203B19CA42C18A0497F16B4844E3074AE8DFDFFA3FEDE21442FCD0069DED0948F8326A753A0FC81F17E8D3E0FB2E0D3628CF35E20C38D18906"
			key = Pbe.Scrypt(dkLen, pwd, salt, N, r, p__1)
			Debug.Assert(key.Length > 0, "ERROR with Pbe.Scrypt")
			Console.WriteLine("scrypt(P='{0}',S='{1}',N={2},r={3},p={4})=" & vbLf & "{5}", P__2, S, N, r, p__1, _
				Cnv.ToHex(key))
			' Compare with known test vector
			Debug.Assert([String].Compare(checkHex, Cnv.ToHex(key), True) = 0, "SCRYPT derived key does not match test vector")

			' Work with hex salt and key but plaintext password
			keyHex = Pbe.Scrypt(64, "password", "4E61436C", 1024, 8, 16)

			Console.WriteLine("scrypt='{0}'", keyHex)
			checkHex = "FDBABE1C9D3472007856E7190D01E9FE7C6AD7CBC8237830E77376634B3731622EAF30D92E22A3886FF109279D9830DAC727AFB94A83EE6D8360CBDFA2CC0640"
			Debug.Assert([String].Compare(checkHex, keyHex, True) = 0, "SCRYPT derived key does not match test vector")

			' scrypt (P="pleaseletmein", S="SodiumChloride", N=16384, r=8, p=1, dkLen=64)
			P__2 = "pleaseletmein"
			saltHex = Cnv.ToHex("SodiumChloride")
			N = 16384
			r = 8
			p__1 = 1
			dkLen = 64
			keyHex = Pbe.Scrypt(dkLen, P__2, saltHex, N, r, p__1)
			Console.WriteLine("scrypt(P='{0}',S='{1}',N={2},r={3},p={4})=" & vbLf & "{5}", P__2, Cnv.StringFromHex(saltHex), N, r, p__1, _
				keyHex)
			checkHex = "7023BDCB3AFD7348461C06CD81FD38EBFDA8FBBA904F8E3EA9B543F6545DA1F2D5432955613F0FCF62D49705242A9AF9E61E85DC0D651E40DFCF017B45575887"
			Debug.Assert([String].Compare(checkHex, keyHex, True) = 0, "SCRYPT derived key does not match test vector")
		End Sub


		Private Shared Sub test_ZLIB()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim excontent As String
			'*************************
			' ZLIB COMPRESSION TESTS *
			'*************************
			Console.WriteLine(vbLf & "TESTING ZLIB COMPRESSION...")
			' Some sample text to compress
			excontent = "hello, hello, hello. This is a 'hello world' message for the world, repeat, for the world."
			' Convert to bytes
			b = System.Text.Encoding.[Default].GetBytes(excontent)
			' Remember uncompressed len for later
			n = b.Length
			' Compress
			b = Zlib.Deflate(b)
			Debug.Assert(b.Length > 0, "ERROR with Zlib.Deflate")
			Console.WriteLine("Compressed {0} to {1} bytes", n, b.Length)
			Console.WriteLine("DEFL={0}", Cnv.ToHex(b))

			' Now inflate back (note we need the original uncompressed length here)
			b = Zlib.Inflate(b, n)
			Debug.Assert(b.Length > 0, "ERROR with Zlib.Deflate")
			s = System.Text.ASCIIEncoding.[Default].GetString(b)
			Console.WriteLine("INFL={0}", s)

		End Sub

		Private Shared Sub test_Random()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim filename As String, fname As String
			Dim keyStr As String
			Dim arrKey As Byte()
			Dim i As Integer
			Dim isok As Boolean

			'**********************
			' RANDOM NUMBER TESTS *
			'**********************
			Console.WriteLine(vbLf & "SOME RANDOM NUMBERS...")
			For i = 0 To 2
				s = Rng.NonceHex(8)
				Console.WriteLine("NonceHex={0}", s)
			Next
			For i = 0 To 2
				s = Rng.KeyHex(24, "")
				Console.WriteLine("KeyHex={0}", s)
			Next
			For i = 0 To 2
				b = Rng.KeyBytes(16, "")
				Console.WriteLine("KeyBytes={0}", Cnv.ToHex(b))
			Next
			For i = 0 To 2
				b = Rng.NonceBytes(8)
				Console.WriteLine("NonceBytes={0}", Cnv.ToHex(b))
			Next
			For i = 0 To 2
				n = Rng.Number(-100, +200)
				Console.WriteLine("Rng.Number(-100,+200)={0}", n)
			Next
			For i = 0 To 2
				n = Rng.Number(-2147483648, +2147483647)
				Console.WriteLine("Rng.Number(-2147483648,+2147483647)={0}", n)
			Next

			For i = 0 To 2
				n = Rng.Octet()
				Console.WriteLine("Rng.Octet={0:X2}", n)
			Next

			' Initialize with a seed file
			fname = "seed.dat"
			If Not FileExists(fname) AndAlso doPrompt Then
				' No seed file yet, so we'll make one and prompt the user for keyboard entropy
				Console.WriteLine("Creating a new seed file...")
				isok = Rng.MakeSeedFile(fname, "Please type some random keystrokes to create a new seedfile", Rng.Strength.Bits_128)
				Console.WriteLine("Rng.MakeSeedFile('{0}') returns {1} (expecting True)", fname, isok)
				Debug.Assert(True = isok, "Rng.MakeSeedFile failed")
			End If
			' If seed file has not been created, Initialize() will create one anyway
			isok = Rng.Initialize(fname)
			Console.WriteLine("Rng.Initialize('{0}') returns {1} (expecting True)", fname, isok)
			Debug.Assert(True = isok, "Rng.Initialize failed")

			' Update the seedfile
			isok = Rng.UpdateSeedFile(fname)
			Console.WriteLine("Rng.UpdateSeedFile('{0}') returns {1} (expecting True)", fname, isok)
			Debug.Assert(True = isok, "Rng.UpdateSeedFile failed")

			If doPrompt Then
				Console.WriteLine("Ask user to type some random keystrokes to add entropy...")
				b = Rng.BytesWithPrompt(16)
				Console.WriteLine("RNG=0x{0}", Cnv.ToHex(b))
				Console.WriteLine("And again with specified strength and custom prompt...")
				b = Rng.BytesWithPrompt(16, "Type until we reach 128 bits...", Rng.Strength.Bits_128)
				Console.WriteLine("RNG=0x{0}", Cnv.ToHex(b))
				Console.WriteLine("And again with output in hex format...")
				keyStr = Rng.HexWithPrompt(16)
				Console.WriteLine("RNG='{0}'", keyStr)
				Console.WriteLine("And again in hex with specified strength and custom prompt...")
				keyStr = Rng.HexWithPrompt(16, "Type until we reach 128 bits...", Rng.Strength.Bits_128)
				Console.WriteLine("RNG='{0}'", keyStr)
			End If

			' Test the ability to add "user-entropy"...
			' ... as a string ...
			s = "this is some user entropy in a string, well it should be!"
			arrKey = Rng.KeyBytes(16, s)
			Console.WriteLine("RNG(seeded)=0x{0}", Cnv.ToHex(arrKey))
			keyStr = Rng.KeyHex(16, s)
			Console.WriteLine("RNG(seeded)='{0}'", keyStr)

			' and with some bytes as a "seed"...
			b = New Byte() {&Hde, &Had, &Hbe, &Hef}
			Console.WriteLine("seed=0x{0}", Cnv.ToHex(b))
			arrKey = Rng.KeyBytes(16, b)
			Console.WriteLine("RNG(seeded)=0x{0}", Cnv.ToHex(arrKey))
			keyStr = Rng.KeyHex(16, b)
			Console.WriteLine("RNG(seeded)='{0}'", keyStr)

			' Do a health check and FIPS-140 stat test on the RNG function
			' NB As of [v4.0.0] Rng.Test now returns true/false, not an int.
			filename = "Fips140.txt"
			isok = Rng.Test(filename)
			Console.WriteLine("Rng.Test('{0}') returns {1} (expecting True)", filename, isok)
			Debug.Assert(isok, "Rng.Test Failed")
			' Test without creating a file
			isok = Rng.Test(Nothing)
			Console.WriteLine("Rng.Test('{0}') returns {1} (expecting True)", Nothing, isok)
			Debug.Assert(isok, "Rng.Test Failed")

			' New in [v4.6]...
			Console.WriteLine("CARRY OUT TESTS AS PER DRBGVS...")
			' Carry out tests as per DRBGVS...
			' DRBG mechanism = HMAC_DRBG SHA1
			' [SHA-1]
			' [PredictionResistance = False]
			' [ReturnedBitsLen = 160]

			' COUNT = 0
			' EntropyInput = d949a64fcf4cd79958e1eb025e750f0b
			' Nonce = ad67cdcbadd17e5e
			' PersonalizationString = 
			' AdditionalInput = 
			' EntropyInputReseed = f86c2fcc9e74102f591f9f276311a0af
			' AdditionalInputReseed = 
			' AdditionalInput = 
			' ReturnedBits = c8d171e7fdd084fc739275fa1e79bd3038857f37
			s = Rng.TestDrbgvs(160, "d949a64fcf4cd79958e1eb025e750f0b", "ad67cdcbadd17e5e", "", "", "f86c2fcc9e74102f591f9f276311a0af", _
				"", "")
			Console.WriteLine("ReturnedBits = {0}", s)
			Debug.Assert(([String].Compare(s, "c8d171e7fdd084fc739275fa1e79bd3038857f37", True) = 0), "Rng.TestDrbgvs failed")

			' COUNT = 0
			' EntropyInput = 329a2a877b897cf6cb95d54017fe4770
			' Nonce = 16d8e0c752cf4a25
			' PersonalizationString = 3535a9a540be9bd156dd440072f7d35e
			' AdditionalInput = 1b2c842d4a898f6919f1f3dbbbe3aaea
			' EntropyInputReseed = 9075150495f1ba810c37946f86526d9c
			' AdditionalInputReseed = 5b40ba5f1770f04bdfc9979279c58228
			' AdditionalInput = 97c88090b3aa6e60ea837ae38acaa47f
			' ReturnedBits = 90bd05566db522d5b95a292de90be1acde270bb0
			s = Rng.TestDrbgvs(160, "329a2a877b897cf6cb95d54017fe4770", "16d8e0c752cf4a25", "3535a9a540be9bd156dd440072f7d35e", "1b2c842d4a898f6919f1f3dbbbe3aaea", "9075150495f1ba810c37946f86526d9c", _
				"5b40ba5f1770f04bdfc9979279c58228", "97c88090b3aa6e60ea837ae38acaa47f")
			Console.WriteLine("ReturnedBits = {0}", s)
			Debug.Assert(([String].Compare(s, "90bd05566db522d5b95a292de90be1acde270bb0", True) = 0), "Rng.TestDrbgvs failed")

		End Sub

		Private Shared Sub test_Wipe()
			Dim b As Byte()
			Dim isok As Boolean
			Dim excontent As String
			Dim fnameData As String
			'******************
			' WIPE DATA TESTS *
			'******************
			Console.WriteLine(vbLf & "TESTING WIPE DATA...")

			' Create a test text file
			excontent = "This is some very secret data."
			fnameData = "todelete.txt"
			File.WriteAllText(fnameData, excontent)
			isok = Wipe.File(fnameData)
			Console.WriteLine("Wipe.File returns {0}", isok)
			Debug.Assert(isok, "ERROR with Wipe.File")
			Debug.Assert(Not FileExists(fnameData), "ERROR: Wipe.File did not delete file")
			' Again, but with simple wipe (one pass, all zeros)
			excontent = "This is some very secret data."
			fnameData = "todelete.txt"
			File.WriteAllText(fnameData, excontent)
			isok = Wipe.File(fnameData, Wipe.Options.Simple)
			Console.WriteLine("Wipe.File(Simple) returns {0}", isok)
			Debug.Assert(isok, "ERROR with Wipe.File")
			Debug.Assert(Not FileExists(fnameData), "ERROR: Wipe.File did not delete file")

			' Copy the string into a byte array
			b = System.Text.Encoding.[Default].GetBytes(excontent)
			' Wipe the byte data
			Console.WriteLine("Before={0}", Cnv.ToHex(b))
			isok = Wipe.Data(b)
			Console.WriteLine("Wipe.Data returns {0}", isok)
			Console.WriteLine("After ={0}", Cnv.ToHex(b))
			Debug.Assert(isok, "ERROR with Wipe.Data")

			' Copy to a StringBuilder (we can't wipe a ptStr string)
			Dim sb As New System.Text.StringBuilder()
			sb.Append(excontent)
			Console.WriteLine("Before=[{0}]", sb.ToString())
			isok = Wipe.[String](sb)
			Console.WriteLine("Wipe.String returns {0}", isok)
			Console.WriteLine("After =[{0}]", sb.ToString())
			Debug.Assert(isok, "ERROR with Wipe.String")
		End Sub

		Private Shared Sub test_CRC()
			Dim s As String
			Dim n As Integer
			Dim b As Byte()
			Dim excontent As String
			Dim fnameData As String
			'************
			' CRC TESTS *
			'************
			Console.WriteLine(vbLf & "TESTING CRC CHECKSUMS...")
			' Create a test text file
			excontent = "hello world" & vbCr & vbLf
			fnameData = "hello.txt"
			File.WriteAllText(fnameData, excontent)
			n = Crc.File(fnameData)
			Console.WriteLine("CRC32('{0}')={1:x}", fnameData, n)

			s = "123456789"
			n = Crc.Data(s)
			Console.WriteLine("CRC32('{0}')={1:x}", s, n)

			' Convert to bytes
			b = System.Text.Encoding.[Default].GetBytes(s)
			n = Crc.Data(b)
			Console.WriteLine("CRC32(0x{0})={1:x}", Cnv.ToHex(b), n)

		End Sub

		Private Shared Sub test_GCM()
			Dim n As Integer
			Dim ctStr As String
			Dim arrPlain As Byte()
			Dim arrCipher As Byte()
			Dim arrKey As Byte()
			Dim arrIV As Byte()
			Dim arrTag As Byte()
			Dim arrAAD As Byte()
			Dim bcheck As Byte()
			' ******************************
			' GCM AUTHENTICATED ENCRYPTION *
			' ******************************
			Console.WriteLine(vbLf & "GCM AUTHENTICATED ENCRYPTION (AES-GCM) AND GMAC:")
			' Ref: McGrew & Viega, The Galois/Counter Mode of Operation (GCM), May, 31 2005

			Console.WriteLine("AES-GCM Test case 2:")
			arrKey = Cnv.FromHex("00000000000000000000000000000000")
			arrPlain = Cnv.FromHex("00000000000000000000000000000000")
			arrIV = Cnv.FromHex("000000000000000000000000")
			Console.WriteLine("K ={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("P ={0}", Cnv.ToHex(arrPlain))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			arrTag = New Byte(15) {}
			' Add this to avoid "before it has been assigned a value" error
			arrCipher = Gcm.Encrypt(arrTag, arrPlain, arrKey, arrIV, Nothing)
			Console.WriteLine("C ={0}", Cnv.ToHex(arrCipher))
			Console.WriteLine("T ={0}", Cnv.ToHex(arrTag))
			Debug.Assert([String].Compare(Cnv.ToHex(arrCipher), "0388dace60b6a392f328c2b971b2fe78", True) = 0, "Gcm.Encrypt failed")
			Debug.Assert([String].Compare(Cnv.ToHex(arrTag), "ab6e47d42cec13bdf53a67b21257bddf", True) = 0, "Gcm.Encrypt failed")
			' Decrypt and check against original plain text
			bcheck = Gcm.Decrypt(arrCipher, arrKey, arrIV, Nothing, arrTag)
			Console.WriteLine("P'={0}", Cnv.ToHex(bcheck))
			Debug.Assert(ByteArraysEqual(bcheck, arrPlain), "Gcm.Decrypt failed")
			' Try shorter tag value
			Dim tag2 As Byte() = New Byte(3) {}
			Array.Copy(arrTag, tag2, tag2.Length)
			bcheck = Gcm.Decrypt(arrCipher, arrKey, arrIV, Nothing, tag2)
			Console.WriteLine("T2={0}", Cnv.ToHex(tag2))
			Console.WriteLine("P2={0}", Cnv.ToHex(bcheck))
			Debug.Assert(ByteArraysEqual(bcheck, arrPlain), "Gcm.Decrypt (short tag) failed")

			Console.WriteLine("AES-GCM Test case 17:")
			arrKey = Cnv.FromHex("feffe9928665731c6d6a8f9467308308" & "feffe9928665731c6d6a8f9467308308")
			arrPlain = Cnv.FromHex("d9313225f88406e5a55909c5aff5269a" & "86a7a9531534f7da2e4c303d8a318a72" & "1c3c0c95956809532fcf0e2449a6b525" & "b16aedf5aa0de657ba637b39")
			arrAAD = Cnv.FromHex("feedfacedeadbeeffeedfacedeadbeef" & "abaddad2")
			arrIV = Cnv.FromHex("cafebabefacedbad")
			ctStr = "c3762df1ca787d32ae47c13bf19844cb" & "af1ae14d0b976afac52ff7d79bba9de0" & "feb582d33934a4f0954cc2363bc73f78" & "62ac430e64abe499f47c9b1f"
			Console.WriteLine("K ={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("P ={0}", Cnv.ToHex(arrPlain))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			arrCipher = Gcm.Encrypt(arrTag, arrPlain, arrKey, arrIV, arrAAD)
			Console.WriteLine("C ={0}", Cnv.ToHex(arrCipher))
			Console.WriteLine("T ={0}", Cnv.ToHex(arrTag))
			Debug.Assert([String].Compare(Cnv.ToHex(arrCipher), ctStr, True) = 0, "Gcm.Encrypt failed")
			Debug.Assert([String].Compare(Cnv.ToHex(arrTag), "3a337dbf46a792c45e454913fe2ea8f2", True) = 0, "Gcm.Encrypt failed")
			' Decrypt and check against original plain text
			bcheck = Gcm.Decrypt(arrCipher, arrKey, arrIV, arrAAD, arrTag)
			Console.WriteLine("P'={0}", Cnv.ToHex(bcheck))
			Debug.Assert(ByteArraysEqual(bcheck, arrPlain), "Gcm.Decrypt failed")

			Console.WriteLine("GMAC test vectors:")
			arrKey = Cnv.FromHex("feffe9928665731c6d6a8f9467308308")
			arrIV = Cnv.FromHex("cafebabefacedbaddecaf888")
			arrAAD = Cnv.FromHex("feedfacedeadbeeffeedfacedeadbeef")
			Console.WriteLine("K ={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			Console.WriteLine("A ={0}", Cnv.ToHex(arrAAD))
			arrTag = Gcm.Gmac(arrKey, arrIV, arrAAD)
			Console.WriteLine("T ={0}", Cnv.ToHex(arrTag))
			Debug.Assert([String].Compare(Cnv.ToHex(arrTag), "54df474f4e71a9ef8a09bf30da7b1a92", True) = 0, "Gcm.Gmac failed")

			Console.WriteLine("Use stateful InitKey-NextEncrypt-Dispose methods:")
			Dim oGcm As Gcm = Gcm.Instance()
			Console.WriteLine("First, try InitKey with bad key (too short)...")
			arrKey = Cnv.FromHex("badace")
			Console.WriteLine("K ={0}", Cnv.ToHex(arrKey))
			n = oGcm.InitKey(arrKey)
			Console.WriteLine("Gcm.InitKey returns {0}", n)
			Console.WriteLine("Error={0}", General.ErrorLookup(oGcm.ErrCode))
			Console.WriteLine("...line above should be an error.")

			' Do Test Case 3 then 4. Same key.
			Console.WriteLine("Setup AES-GCM key for continued use...")
			arrKey = Cnv.FromHex("feffe9928665731c6d6a8f9467308308")
			Console.WriteLine("K ={0}", Cnv.ToHex(arrKey))
			n = oGcm.InitKey(arrKey)
			Debug.Assert(0 = n, "oGcm.InitKey failed")

			Console.WriteLine("AES-GCM Test case 3:")
			arrPlain = Cnv.FromHex("d9313225f88406e5a55909c5aff5269a" & "86a7a9531534f7da2e4c303d8a318a72" & "1c3c0c95956809532fcf0e2449a6b525" & "b16aedf5aa0de657ba637b391aafd255")
			arrAAD = Nothing
			arrIV = Cnv.FromHex("cafebabefacedbaddecaf888")
			ctStr = "42831ec2217774244b7221b784d0d49c" & "e3aa212f2c02a4e035c17e2329aca12e" & "21d514b25466931c7d8f6a5aac84aa05" & "1ba30b396a0aac973d58e091473f5985"
			Console.WriteLine("P ={0}", Cnv.ToHex(arrPlain))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			arrCipher = oGcm.NextEncrypt(arrTag, arrPlain, arrIV, arrAAD)
			Console.WriteLine("C ={0}", Cnv.ToHex(arrCipher))
			Console.WriteLine("T ={0}", Cnv.ToHex(arrTag))
			Debug.Assert([String].Compare(Cnv.ToHex(arrCipher), ctStr, True) = 0, "Gcm.Encrypt failed")
			Debug.Assert([String].Compare(Cnv.ToHex(arrTag), "4d5c2af327cd64a62cf35abd2ba6fab4", True) = 0, "Gcm.NextEncrypt failed")
			' Decrypt and check against original plain text
			bcheck = oGcm.NextDecrypt(arrCipher, arrIV, arrAAD, arrTag)
			Console.WriteLine("P'={0}", Cnv.ToHex(bcheck))
			Debug.Assert(ByteArraysEqual(bcheck, arrPlain), "Gcm.NextDecrypt failed")

			Console.WriteLine("AES-GCM Test case 4:")
			arrPlain = Cnv.FromHex("d9313225f88406e5a55909c5aff5269a" & "86a7a9531534f7da2e4c303d8a318a72" & "1c3c0c95956809532fcf0e2449a6b525" & "b16aedf5aa0de657ba637b39")
			arrAAD = Cnv.FromHex("feedfacedeadbeeffeedfacedeadbeefabaddad2")
			arrIV = Cnv.FromHex("cafebabefacedbaddecaf888")
			ctStr = "42831ec2217774244b7221b784d0d49c" & "e3aa212f2c02a4e035c17e2329aca12e" & "21d514b25466931c7d8f6a5aac84aa05" & "1ba30b396a0aac973d58e091"
			Console.WriteLine("P ={0}", Cnv.ToHex(arrPlain))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			arrCipher = oGcm.NextEncrypt(arrTag, arrPlain, arrIV, arrAAD)
			Console.WriteLine("C ={0}", Cnv.ToHex(arrCipher))
			Console.WriteLine("T ={0}", Cnv.ToHex(arrTag))
			Debug.Assert([String].Compare(Cnv.ToHex(arrCipher), ctStr, True) = 0, "Gcm.Encrypt failed")
			Debug.Assert([String].Compare(Cnv.ToHex(arrTag), "5bc94fbc3221a5db94fae95ae7121a47", True) = 0, "Gcm.NextEncrypt failed")
			' Decrypt and check against original plain text
			bcheck = oGcm.NextDecrypt(arrCipher, arrIV, arrAAD, arrTag)
			Console.WriteLine("P'={0}", Cnv.ToHex(bcheck))
			Debug.Assert(ByteArraysEqual(bcheck, arrPlain), "Gcm.NextDecrypt failed")

			' Destroy the key we set up
			oGcm.Dispose()
			Console.WriteLine("...Key has been destroyed.")

		End Sub

		Private Shared Sub test_AEAD()
			Dim pt As Byte()
			Dim ct As Byte()
			Dim key As Byte()
			Dim nonce As Byte()
			Dim tag As Byte()
			Dim aad As Byte()
			Dim check As Byte()
			Dim ctok As Byte()
			Dim tagok As Byte()
			Dim isok As Boolean
			' ***********************************************
			' AUTHENTICATED ENCRYPTION WITH ASSOCIATED DATA *
			' ***********************************************
			Console.WriteLine(vbLf & "AUTHENTICATED ENCRYPTION WITH ASSOCIATED DATA:")

			Console.WriteLine("NIST 800-38D AES-GCM Test case 2:")
			key = Cnv.FromHex("00000000000000000000000000000000")
			pt = Cnv.FromHex("00000000000000000000000000000000")
			nonce = Cnv.FromHex("000000000000000000000000")
			ctok = Cnv.FromHex("0388dace60b6a392f328c2b971b2fe78")
			tagok = Cnv.FromHex("ab6e47d42cec13bdf53a67b21257bddf")
			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))
			Console.WriteLine("P: " & Cnv.ToHex(pt))

			tag = New Byte(-1) {}
			' Do this to avoid "before it has been assigned a value" error
			ct = Aead.Encrypt(tag, pt, key, nonce, Nothing, Aead.Algorithm.Aes_128_Gcm)
			Console.WriteLine("C: " & Cnv.ToHex(ct))
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(ct, ctok), "Aead.Encrypt failed")
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.Encrypt failed")
			' Decrypt and check against original plain text
			check = Aead.Decrypt(ct, key, nonce, Nothing, tag, Aead.Algorithm.Aes_128_Gcm)
			Console.WriteLine("P':" & Cnv.ToHex(check))
			Debug.Assert(ByteArraysEqual(check, pt), "Aead.Decrypt failed")
			' Try shorter tag value
			Dim tag2 As Byte() = New Byte(3) {}
			Array.Copy(tag, tag2, tag2.Length)
			check = Gcm.Decrypt(ct, key, nonce, Nothing, tag2)
			Console.WriteLine("T2:" & Cnv.ToHex(tag2))
			Console.WriteLine("P2:" & Cnv.ToHex(check))
			Debug.Assert(ByteArraysEqual(check, pt), "Aead.Decrypt (short tag) failed")

			Console.WriteLine(vbLf & "IEEE P802.1 MACsec 2.4.1 54-byte Packet Encryption Using GCM-AES-128:")
			key = Cnv.FromHex("071b113b 0ca743fe cccf3d05 1f737382")
			nonce = Cnv.FromHex("f0761e8d cd3d0001 76d457ed")
			aad = Cnv.FromHex("e20106d7 cd0df076 1e8dcd3d 88e54c2a 76d457ed")
			pt = Cnv.FromHex("08000f10 11121314 15161718 191a1b1c 1d1e1f20 21222324 25262728 292a2b2c 2d2e2f30 31323334 0004")
			ctok = Cnv.FromHex("13b4c72b 389dc501 8e72a171 dd85a5d3 752274d3 a019fbca ed09a425 cd9b2e1c 9b72eee7 c9de7d52 b3f3")
			tagok = Cnv.FromHex("d6a5284f 4a6d3fe2 2a5d6c2b 960494c3")
			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))
			Console.WriteLine("P: " & Cnv.ToHex(pt))
			tag = New Byte(-1) {}
			' Do this to avoid "before it has been assigned a value" error
			ct = Aead.Encrypt(tag, pt, key, nonce, aad, Aead.Algorithm.Aes_128_Gcm)
			Console.WriteLine("C: " & Cnv.ToHex(ct))
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(ct, ctok), "Aead.Encrypt failed")
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.Encrypt failed")
			' Decrypt and check against original plain text
			check = Aead.Decrypt(ct, key, nonce, aad, tag, Aead.Algorithm.Aes_128_Gcm)
			Console.WriteLine("P':" & Cnv.ToHex(check))
			Debug.Assert(ByteArraysEqual(check, pt), "Aead.Decrypt failed")

			Console.WriteLine(vbLf & "IEEE P802.1 MACsec 2.6.2 61-byte Packet Encryption Using GCM-AES-256:")
			key = Cnv.FromHex("83c093b5 8de7ffe1 c0da926a c43fb360 9ac1c80f ee1b6244 97ef942e 2f79a823")
			nonce = Cnv.FromHex("7cfde9f9 e33724c6 8932d612")
			aad = Cnv.FromHex("84c5d513 d2aaf6e5 bbd27277 88e52f00 8932d612 7cfde9f9 e33724c6")
			pt = Cnv.FromHex("08000f10 11121314 15161718 191a1b1c 1d1e1f20 21222324 25262728 292a2b2c 2d2e2f30 31323334 35363738 393a3b00 06")
			ctok = Cnv.FromHex("110222ff 8050cbec e66a813a d09a73ed 7a9a089c 106b9593 89168ed6 e8698ea9 02eb1277 dbec2e68 e473155a 15a7daee d4")
			tagok = Cnv.FromHex("a10f4e05 139c23df 00b3aadc 71f0596a")
			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))
			Console.WriteLine("P: " & Cnv.ToHex(pt))
			tag = New Byte(-1) {}
			' Do this to avoid "before it has been assigned a value" error
			ct = Aead.Encrypt(tag, pt, key, nonce, aad, Aead.Algorithm.Aes_256_Gcm)
			Console.WriteLine("C: " & Cnv.ToHex(ct))
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(ct, ctok), "Aead.Encrypt failed")
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.Encrypt failed")
			' Decrypt and check against original plain text
			check = Aead.Decrypt(ct, key, nonce, aad, tag, Aead.Algorithm.Aes_256_Gcm)
			Console.WriteLine("P':" & Cnv.ToHex(check))
			Debug.Assert(ByteArraysEqual(check, pt), "Aead.Decrypt failed")

			Console.WriteLine(vbLf & "IEEE P802.1 MACsec 2.1.1 54-byte Packet Authentication Using GCM-AES-128:")
			key = Cnv.FromHex("ad7a2bd0 3eac835a 6f620fdc b506b345")
			nonce = Cnv.FromHex("12153524 c0895e81 b2c28465")
			aad = Cnv.FromHex("d609b1f0 56637a0d 46df998d 88e5222a b2c28465 12153524 c0895e81 08000f10 11121314 15161718 191a1b1c 1d1e1f20 21222324 25262728 292a2b2c 2d2e2f30 31323334 0001")
			tagok = Cnv.FromHex("f09478a9 b09007d0 6f46e9b6 a1da25dd")
			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))
			' Compute MAC over AAD
			tag = Aead.Mac(key, nonce, aad, Aead.Algorithm.Aes_128_Gcm)
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.Mac failed")
			' Authenticate over AAD
			isok = Aead.Authenticate(key, nonce, aad, tag, Aead.Algorithm.Aes_128_Gcm)
			Console.WriteLine("Aead.Authenticate returns " & isok)
			Debug.Assert(isok, "Aead.Authenticate failed")

			Console.WriteLine(vbLf & "RFC7739 ChaCha20_Poly1305 Sunscreen test:")
			key = Cnv.FromHex("808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f")
			nonce = Cnv.FromHex("070000004041424344454647")
			aad = Cnv.FromHex("50515253c0c1c2c3c4c5c6c7")
			pt = Cnv.FromHex("4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e")
			ctok = Cnv.FromHex("d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116")
			tagok = Cnv.FromHex("1ae10b594f09e26a7e902ecbd0600691")
			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))
			Console.WriteLine("A: " & Cnv.ToHex(aad))
			Console.WriteLine("P: " & Cnv.ToHex(pt))

			tag = New Byte(-1) {}
			' Do this to avoid "before it has been assigned a value" error
			ct = Aead.Encrypt(tag, pt, key, nonce, aad, Aead.Algorithm.Chacha20_Poly1305)

			Console.WriteLine("C: " & Cnv.ToHex(ct))
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(ct, ctok), "Aead.Encrypt failed")
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.Encrypt failed")

			' Decrypt and check against original plain text
			check = Aead.Decrypt(ct, key, nonce, aad, tag, Aead.Algorithm.Chacha20_Poly1305)
			Console.WriteLine("P':" & Cnv.ToHex(check))
			Debug.Assert(ByteArraysEqual(check, pt), "Aead.Decrypt failed")

			Console.WriteLine(vbLf & "ChaCha20_Poly1305 empty PT and AAD strings:")
			key = Cnv.FromHex("808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f")
			nonce = Cnv.FromHex("070000004041424344454647")
			aad = Cnv.FromHex("")
			pt = Cnv.FromHex("")
			ctok = Cnv.FromHex("")
			tagok = Cnv.FromHex("A0784D7A4716F3FEB4F64E7F4B39BF04")
			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))
			Console.WriteLine("A: " & Cnv.ToHex(aad))
			Console.WriteLine("P: " & Cnv.ToHex(pt))

			tag = New Byte(-1) {}
			' Do this to avoid "before it has been assigned a value" error
			ct = Aead.Encrypt(tag, pt, key, nonce, aad, Aead.Algorithm.Chacha20_Poly1305)

			Console.WriteLine("C: " & Cnv.ToHex(ct))
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(ct, ctok), "Aead.Encrypt failed")
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.Encrypt failed")

			' Decrypt and check against original plain text
			check = Aead.Decrypt(ct, key, nonce, aad, tag, Aead.Algorithm.Chacha20_Poly1305)
			Console.WriteLine("P':" & Cnv.ToHex(check))
			Debug.Assert(ByteArraysEqual(check, pt), "Aead.Decrypt failed")

			Console.WriteLine("Check we get same tag using .Mac() method")
			tag = Aead.Mac(key, nonce, aad, Aead.Algorithm.Chacha20_Poly1305)
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.Encrypt failed")


			Console.WriteLine(vbLf & "ipsecme-chacha20-poly1305 Appendix B IKEv2 Example:")
			key = Cnv.FromHex("808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f")
			nonce = Cnv.FromHex("a0 a1 a2 a3 10 11 12 13 14 15 16 17")
			aad = Cnv.FromHex("c0c1c2c3c4c5c6c7d0d1d2d3d4d5d6d72e202500000000090000004529000029")
			pt = Cnv.FromHex("00 00 00 0c 00 00 40 01 00 00 00 0a 00")
			ctok = Cnv.FromHex("61 03 94 70 1f 8d 01 7f 7c 12 92 48 89")
			tagok = Cnv.FromHex("6b 71 bf e2 52 36 ef d7 cd c6 70 66 90 63 15 b2")
			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))
			Console.WriteLine("A: " & Cnv.ToHex(aad))
			Console.WriteLine("P: " & Cnv.ToHex(pt))

			tag = New Byte(-1) {}
			' Do this to avoid "before it has been assigned a value" error
			ct = Aead.Encrypt(tag, pt, key, nonce, aad, Aead.Algorithm.Chacha20_Poly1305)

			Console.WriteLine("C: " & Cnv.ToHex(ct))
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(ct, ctok), "Aead.Encrypt failed")
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.Encrypt failed")


			' Compute tags for all empty strings for all algorithms
			Console.WriteLine(vbLf & "Use Aead.Mac() to compute tags for empty PT and AAD strings:")
			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))
			tag = Aead.Mac(key, nonce, aad, Aead.Algorithm.Chacha20_Poly1305)
			Console.WriteLine("T (e, Chacha20_Poly1305): " & Cnv.ToHex(tag))
			'Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.Encrypt failed");

			tag = Aead.Mac(key, nonce, aad, Aead.Algorithm.Aes_256_Gcm)
			Console.WriteLine("T (e, Aes_256_Gcm): " & Cnv.ToHex(tag))
			' Shorten the 256-bit key to 128 bits
			Array.Resize(key, 16)
			Console.WriteLine("K: " & Cnv.ToHex(key))
			tag = Aead.Mac(key, nonce, aad, Aead.Algorithm.Aes_128_Gcm)
			Console.WriteLine("T (e, Aes_128_Gcm): " & Cnv.ToHex(tag))
		End Sub

		Private Shared Sub test_AEAD_incremental()
			Dim pt As Byte()
			Dim ct As Byte()
			Dim key As Byte()
			Dim nonce As Byte()
			Dim tag As Byte()
			Dim aad As Byte()
			Dim check As Byte()
			Dim ctok As Byte()
			Dim tagok As Byte()
			Dim r As Integer
			Dim chunk As Byte()
			Dim isok As Boolean
			Dim offset As Integer, len As Integer, nleft As Integer, chunklen As Integer
			Dim o As Aead

			' *************************************************************
			' AUTHENTICATED ENCRYPTION WITH ASSOCIATED DATA - INCREMENTAL *
			' *************************************************************
			Console.WriteLine(vbLf & "AUTHENTICATED ENCRYPTION WITH ASSOCIATED DATA - INCREMENTAL:")

			Console.WriteLine(vbLf & "IEEE P802.1 MACsec 2.6.2 61-byte Packet Encryption Using GCM-AES-256:")
			key = Cnv.FromHex("83c093b5 8de7ffe1 c0da926a c43fb360 9ac1c80f ee1b6244 97ef942e 2f79a823")
			nonce = Cnv.FromHex("7cfde9f9 e33724c6 8932d612")
			pt = Cnv.FromHex("08000f10 11121314 15161718 191a1b1c 1d1e1f20 21222324 25262728 292a2b2c 2d2e2f30 31323334 35363738 393a3b00 06")
			ctok = Cnv.FromHex("110222ff 8050cbec e66a813a d09a73ed 7a9a089c 106b9593 89168ed6 e8698ea9 02eb1277 dbec2e68 e473155a 15a7daee d4")
			tagok = Cnv.FromHex("a10f4e05 139c23df 00b3aadc 71f0596a")
			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))

			' Setup a new Aead object, initialize the key and nonce
			o = Aead.Instance()
			r = o.InitKey(key, Aead.Algorithm.Aes_256_Gcm)
			Debug.Assert(0 = r, "Aead.InitKey failed")
			r = o.SetNonce(nonce)
			Debug.Assert(0 = r, "Aead.SetNonce failed")

			' Add the AAD in chunks
			aad = Cnv.FromHex("84c5d513 d2aaf6e5 bbd27277 88e52f00 8932d612 7cfde9f9 e33724c6")
			Console.WriteLine("A: " & Cnv.ToHex(aad))
			chunk = Cnv.FromHex("84c5d513 d2aaf6e5 bb")
			r = o.AddAAD(chunk)
			Debug.Assert(0 = r, "Aead.AddAAD failed")
			chunk = Cnv.FromHex("d27277 88e52f00 8932d612 7cfde9f9 e337")
			r = o.AddAAD(chunk)
			Debug.Assert(0 = r, "Aead.AddAAD failed")
			chunk = Cnv.FromHex("24c6")
			r = o.AddAAD(chunk)
			Debug.Assert(0 = r, "Aead.AddAAD failed")

			Console.WriteLine("ENCRYPTING IN CHUNKS...")
			r = o.StartEncrypt()
			Debug.Assert(0 = r, "Aead.StartEncrypt failed")

			Console.WriteLine("P-all: " & Cnv.ToHex(pt))

			' Encrypt PT in chunks
			chunklen = 17
			nleft = pt.Length
			ct = New Byte(pt.Length - 1) {}

			offset = 0
			len = chunklen
			While nleft > 0
				If nleft < len Then
					len = nleft
				End If
				chunk = New Byte(len - 1) {}
				Array.Copy(pt, offset, chunk, 0, len)
				Console.WriteLine("P-chunk: " & Cnv.ToHex(chunk))
				chunk = o.Update(chunk)
				Console.WriteLine("C-chunk: " & Cnv.ToHex(chunk))
				Array.Copy(chunk, 0, ct, offset, len)
				offset += len
				nleft -= len
			End While
			Console.WriteLine("C-all: " & Cnv.ToHex(ct))
			Debug.Assert(ByteArraysEqual(ct, ctok), "Aead.Update failed")

			tag = o.FinishEncrypt()
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.FinishEncrypt failed")

			' DECRYPT:
			Console.WriteLine("DECRYPTING IN CHUNKS...")
			' Key is set above, reset the nonce to decrypt
			r = o.SetNonce(nonce)
			Debug.Assert(0 = r, "Aead.SetNonce failed")

			' Add the AAD in toto
			aad = Cnv.FromHex("84c5d513 d2aaf6e5 bbd27277 88e52f00 8932d612 7cfde9f9 e33724c6")
			Console.WriteLine("A: " & Cnv.ToHex(aad))
			r = o.AddAAD(aad)

			r = o.StartDecrypt(tag)
			Debug.Assert(0 = r, "Aead.StartDecrypt failed")

			' Decrypt CT in chunks
			chunklen = 13
			nleft = ct.Length
			check = New Byte(ct.Length - 1) {}

			offset = 0
			len = chunklen
			While nleft > 0
				If nleft < len Then
					len = nleft
				End If
				chunk = New Byte(len - 1) {}
				Array.Copy(ct, offset, chunk, 0, len)
				Console.WriteLine("C-chunk: " & Cnv.ToHex(chunk))
				chunk = o.Update(chunk)
				Console.WriteLine("P-chunk: " & Cnv.ToHex(chunk))
				Array.Copy(chunk, 0, check, offset, len)
				offset += len
				nleft -= len
			End While
			Console.WriteLine("P-all: " & Cnv.ToHex(check))
			Debug.Assert(ByteArraysEqual(pt, check), "Aead.Update failed")

			isok = o.FinishDecrypt()
			Console.WriteLine("FinishDecrypt: " & isok)
			Debug.Assert(isok, "Aead.FinishDecrypt failed")

			o.Dispose()

			'************************************
			' DO THE SAME USING CHACHA20_POLY1305
			'************************************

			Console.WriteLine(vbLf & "RFC7739 ChaCha20_Poly1305 Sunscreen test:")
			key = Cnv.FromHex("808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f")
			nonce = Cnv.FromHex("070000004041424344454647")
			aad = Cnv.FromHex("50515253c0c1c2c3c4c5c6c7")
			pt = Cnv.FromHex("4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e")
			ctok = Cnv.FromHex("d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116")
			tagok = Cnv.FromHex("1ae10b594f09e26a7e902ecbd0600691")

			Console.WriteLine("K: " & Cnv.ToHex(key))
			Console.WriteLine("N: " & Cnv.ToHex(nonce))

			' Setup a new Aead object, initialize the key and nonce
			o = Aead.Instance()
			r = o.InitKey(key, Aead.Algorithm.Chacha20_Poly1305)
			Debug.Assert(0 = r, "Aead.InitKey failed")
			r = o.SetNonce(nonce)
			Debug.Assert(0 = r, "Aead.SetNonce failed")

			' Add the AAD in one go
			Console.WriteLine("A: " & Cnv.ToHex(aad))
			r = o.AddAAD(aad)
			Debug.Assert(0 = r, "Aead.AddAAD failed")

			Console.WriteLine("ENCRYPTING IN CHUNKS...")
			r = o.StartEncrypt()
			Debug.Assert(0 = r, "Aead.StartEncrypt failed")

			Console.WriteLine("P-all: " & Cnv.ToHex(pt))

			' Encrypt PT in chunks
			chunklen = 19
			nleft = pt.Length
			ct = New Byte(pt.Length - 1) {}

			offset = 0
			len = chunklen
			While nleft > 0
				If nleft < len Then
					len = nleft
				End If
				chunk = New Byte(len - 1) {}
				Array.Copy(pt, offset, chunk, 0, len)
				Console.WriteLine("P-chunk: " & Cnv.ToHex(chunk))
				chunk = o.Update(chunk)
				Console.WriteLine("C-chunk: " & Cnv.ToHex(chunk))
				Array.Copy(chunk, 0, ct, offset, len)
				offset += len
				nleft -= len
			End While
			Console.WriteLine("C-all: " & Cnv.ToHex(ct))
			Debug.Assert(ByteArraysEqual(ct, ctok), "Aead.Update failed")

			tag = o.FinishEncrypt()
			Console.WriteLine("T: " & Cnv.ToHex(tag))
			Debug.Assert(ByteArraysEqual(tag, tagok), "Aead.FinishEncrypt failed")

			' DECRYPT:
			Console.WriteLine("DECRYPTING IN CHUNKS...")
			' Key is set above, reset the nonce and AAD to decrypt
			r = o.SetNonce(nonce)
			Debug.Assert(0 = r, "Aead.SetNonce failed")
			r = o.AddAAD(aad)
			Debug.Assert(0 = r, "Aead.AddAAD failed")

			r = o.StartDecrypt(tag)
			Debug.Assert(0 = r, "Aead.StartDecrypt failed")

			' Decrypt CT in chunks
			chunklen = 7
			nleft = ct.Length
			check = New Byte(ct.Length - 1) {}

			offset = 0
			len = chunklen
			While nleft > 0
				If nleft < len Then
					len = nleft
				End If
				chunk = New Byte(len - 1) {}
				Array.Copy(ct, offset, chunk, 0, len)
				Console.WriteLine("C-chunk: " & Cnv.ToHex(chunk))
				chunk = o.Update(chunk)
				Console.WriteLine("P-chunk: " & Cnv.ToHex(chunk))
				Array.Copy(chunk, 0, check, offset, len)
				offset += len
				nleft -= len
			End While
			Console.WriteLine("P-all: " & Cnv.ToHex(check))
			Debug.Assert(ByteArraysEqual(pt, check), "Aead.Update failed")

			isok = o.FinishDecrypt()
			Console.WriteLine("FinishDecrypt: " & isok)
			Debug.Assert(isok, "Aead.FinishDecrypt failed")

			o.Dispose()

		End Sub

		Private Shared Sub test_CipherFileExtended()
			Dim n As Integer
			Dim arrKey As Byte()
			Dim arrIV As Byte()
			Dim excontent As String
			Dim fnameData As String
			Dim fnameEnc As String
			Dim fnameCheck As String
			Dim fnameChk1 As String
			' *********************************
			' EXTENDED FILE CIPHER OPERATIONS *
			' *********************************
			Console.WriteLine(vbLf & "TESTING EXTENDED FILE CIPHER OPERATIONS:")
			' Create a test text file
			excontent = "Now is the time for"
			fnameData = "nowis19.txt"
			File.WriteAllText(fnameData, excontent)

			Console.WriteLine("Des.FileEncrypt/Decrypt with CipherFileOption...")
			' Encrypt file using DES in CBC mode using byte arrays for key and IV
			fnameEnc = "nowis.des-cbc.enc.dat"
			fnameCheck = "nowis.des-cbc.chk.txt"
			fnameChk1 = "nowis.des-cbc.chk1.txt"
			arrKey = Cnv.FromHex("0123456789ABCDEF")
			arrIV = Cnv.FromHex("1234567890ABCDEF")
			Console.WriteLine("KY={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			Console.WriteLine("Input file contents ({0} bytes):" & vbLf & "{1}", FileLength(fnameData), GetFileAsHex(fnameData))
			' Use default option
			n = Des.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.CBC, arrIV, CipherFileOption.[Default])
			Console.WriteLine("Des.FileEncrypt(CBC, Default) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Des.FileEncrypt(CBC, Default) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameEnc, FileLength(fnameEnc), GetFileAsHex(fnameEnc))
			' Use PrefixIV option
			n = Des.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.CBC, arrIV, CipherFileOption.PrefixIV)
			Console.WriteLine("Des.FileEncrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Des.FileEncrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameEnc, FileLength(fnameEnc), GetFileAsHex(fnameEnc))
			' Now decrypt using same PrefixIV option
			n = Des.FileDecrypt(fnameCheck, fnameEnc, arrKey, Mode.CBC, Nothing, CipherFileOption.PrefixIV)
			Console.WriteLine("Des.FileDecrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Des.FileDecrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameCheck, FileLength(fnameCheck), GetFileAsHex(fnameCheck))
			' Check we got what we started with
			Debug.Assert(FilesAreIdentical(fnameData, fnameCheck), "Decrypted file does not match original")
			' Now decrypt using LeavePadding option
			n = Des.FileDecrypt(fnameChk1, fnameEnc, arrKey, Mode.CBC, Nothing, CipherFileOption.PrefixIV Or CipherFileOption.LeavePadding)
			Console.WriteLine("Des.FileDecrypt(CBC, PrefixIV+LeavePadding) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Des.FileDecrypt(CBC, PrefixIV+LeavePadding) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameChk1, FileLength(fnameChk1), GetFileAsHex(fnameChk1))

			Console.WriteLine("")
			Console.WriteLine("Aes128.FileEncrypt/Decrypt with CipherFileOption...")
			fnameEnc = "nowis.aes128-cbc.enc.dat"
			fnameCheck = "nowis.aes128-cbc.chk.txt"
			fnameChk1 = "nowis.aes128-cbc.chk1.txt"
			arrKey = Cnv.FromHex("0123456789ABCDEFFEDCBA9876543210")
			arrIV = Cnv.FromHex("1234567890ABCDEFFEDCBA0987654321")
			Console.WriteLine("KY={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			Console.WriteLine("Input file contents ({0} bytes):" & vbLf & "{1}", FileLength(fnameData), GetFileAsHex(fnameData))
			' Use default option
			n = Aes128.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.CBC, arrIV, CipherFileOption.[Default])
			Console.WriteLine("Aes128.FileEncrypt(CBC, Default) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Aes128.FileEncrypt(CBC, Default) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameEnc, FileLength(fnameEnc), GetFileAsHex(fnameEnc))
			' Use PrefixIV option
			n = Aes128.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.CBC, arrIV, CipherFileOption.PrefixIV)
			Console.WriteLine("Aes128.FileEncrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Aes128.FileEncrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameEnc, FileLength(fnameEnc), GetFileAsHex(fnameEnc))
			' Now decrypt using same PrefixIV option
			n = Aes128.FileDecrypt(fnameCheck, fnameEnc, arrKey, Mode.CBC, Nothing, CipherFileOption.PrefixIV)
			Console.WriteLine("Aes128.FileDecrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Aes128.FileDecrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameCheck, FileLength(fnameCheck), GetFileAsHex(fnameCheck))
			' Check we got what we started with
			Debug.Assert(FilesAreIdentical(fnameData, fnameCheck), "Decrypted file does not match original")
			' Now decrypt using LeavePadding option
			n = Aes128.FileDecrypt(fnameChk1, fnameEnc, arrKey, Mode.CBC, Nothing, CipherFileOption.PrefixIV Or CipherFileOption.LeavePadding)
			Console.WriteLine("Aes128.FileDecrypt(CBC, PrefixIV+LeavePadding) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Aes128.FileDecrypt(CBC, PrefixIV+LeavePadding) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameChk1, FileLength(fnameChk1), GetFileAsHex(fnameChk1))

			' Call all other versions at least once
			' AES-192
			Console.WriteLine("Aes192.FileEncrypt/Decrypt with CipherFileOption...")
			fnameEnc = "nowis.aes192-cbc.enc.dat"
			fnameCheck = "nowis.aes192-cbc.chk.txt"
			arrKey = Cnv.FromHex("0123456789ABCDEFFEDCBA987654321089ABCDEF01234567")
			arrIV = Cnv.FromHex("1234567890ABCDEFFEDCBA0987654321")
			Console.WriteLine("KY={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			' Use PrefixIV option
			n = Aes192.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.CBC, arrIV, CipherFileOption.PrefixIV)
			Console.WriteLine("Aes192.FileEncrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Aes192.FileEncrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameEnc, FileLength(fnameEnc), GetFileAsHex(fnameEnc))
			' Now decrypt using same PrefixIV option
			n = Aes192.FileDecrypt(fnameCheck, fnameEnc, arrKey, Mode.CBC, Nothing, CipherFileOption.PrefixIV)
			Console.WriteLine("Aes192.FileDecrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Aes192.FileDecrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameCheck, FileLength(fnameCheck), GetFileAsHex(fnameCheck))
			' Check we got what we started with
			Debug.Assert(FilesAreIdentical(fnameData, fnameCheck), "Decrypted file does not match original")

			' AES-256
			Console.WriteLine("Aes256.FileEncrypt/Decrypt with CipherFileOption...")
			fnameEnc = "nowis.aes256-cbc.enc.dat"
			fnameCheck = "nowis.aes256-cbc.chk.txt"
			arrKey = Cnv.FromHex("0123456789ABCDEFFEDCBA987654321089ABCDEF0123456776543210FEDCBA98")
			arrIV = Cnv.FromHex("1234567890ABCDEFFEDCBA0987654321")
			Console.WriteLine("KY={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			' Use PrefixIV option
			n = Aes256.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.CBC, arrIV, CipherFileOption.PrefixIV)
			Console.WriteLine("Aes256.FileEncrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Aes256.FileEncrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameEnc, FileLength(fnameEnc), GetFileAsHex(fnameEnc))
			' Now decrypt using same PrefixIV option
			n = Aes256.FileDecrypt(fnameCheck, fnameEnc, arrKey, Mode.CBC, Nothing, CipherFileOption.PrefixIV)
			Console.WriteLine("Aes256.FileDecrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Aes256.FileDecrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameCheck, FileLength(fnameCheck), GetFileAsHex(fnameCheck))
			' Check we got what we started with
			Debug.Assert(FilesAreIdentical(fnameData, fnameCheck), "Decrypted file does not match original")

			' TDEA
			Console.WriteLine("Tdea.FileEncrypt/Decrypt with CipherFileOption...")
			fnameEnc = "nowis.tdea-cbc.enc.dat"
			fnameCheck = "nowis.tdea-cbc.chk.txt"
			arrKey = Cnv.FromHex("0123456789ABCDEFFEDCBA987654321089ABCDEF01234567")
			arrIV = Cnv.FromHex("1234567890ABCDEF")
			Console.WriteLine("KY={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			' Use PrefixIV option
			n = Tdea.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.CBC, arrIV, CipherFileOption.PrefixIV)
			Console.WriteLine("Tdea.FileEncrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Tdea.FileEncrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameEnc, FileLength(fnameEnc), GetFileAsHex(fnameEnc))
			' Now decrypt using same PrefixIV option
			n = Tdea.FileDecrypt(fnameCheck, fnameEnc, arrKey, Mode.CBC, Nothing, CipherFileOption.PrefixIV)
			Console.WriteLine("Tdea.FileDecrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Tdea.FileDecrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameCheck, FileLength(fnameCheck), GetFileAsHex(fnameCheck))
			' Check we got what we started with
			Debug.Assert(FilesAreIdentical(fnameData, fnameCheck), "Decrypted file does not match original")

			' Blowfish
			Console.WriteLine("Blowfish.FileEncrypt/Decrypt with CipherFileOption...")
			fnameEnc = "nowis.blf-cbc.enc.dat"
			fnameCheck = "nowis.blf-cbc.chk.txt"
			arrKey = Cnv.FromHex("0123456789abcdeff0e1d2c3b4a59687")
			arrIV = Cnv.FromHex("1234567890ABCDEF")
			Console.WriteLine("KY={0}", Cnv.ToHex(arrKey))
			Console.WriteLine("IV={0}", Cnv.ToHex(arrIV))
			' Use PrefixIV option
			n = Blowfish.FileEncrypt(fnameEnc, fnameData, arrKey, Mode.CBC, arrIV, CipherFileOption.PrefixIV)
			Console.WriteLine("Blowfish.FileEncrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Blowfish.FileEncrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameEnc, FileLength(fnameEnc), GetFileAsHex(fnameEnc))
			' Now decrypt using same PrefixIV option
			n = Blowfish.FileDecrypt(fnameCheck, fnameEnc, arrKey, Mode.CBC, Nothing, CipherFileOption.PrefixIV)
			Console.WriteLine("Blowfish.FileDecrypt(CBC, PrefixIV) returns {0} (expecting 0)", n)
			Debug.Assert(0 = n, "Blowfish.FileDecrypt(CBC, PrefixIV) failed")
			Console.WriteLine("...created file {0} ({1} bytes). File contents:" & vbLf & "{2}", fnameCheck, FileLength(fnameCheck), GetFileAsHex(fnameCheck))
			' Check we got what we started with
			Debug.Assert(FilesAreIdentical(fnameData, fnameCheck), "Decrypted file does not match original")

		End Sub

		Private Shared Sub test_CipherPad()
			Dim s As String
			Dim key As Byte(), iv As Byte(), pt As Byte(), ct As Byte(), p1 As Byte(), correct As Byte()

			Console.WriteLine(vbLf & "TEST THE CIPHER CLASS WITH PADDING...")
			Console.WriteLine("Tdea/CBC/Pkcs5")
			key = Cnv.FromHex("737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32")
			iv = Cnv.FromHex("B36B6BFB6231084E")
			Console.WriteLine("KY=" & Cnv.ToHex(key))
			Console.WriteLine("IV=" & Cnv.ToHex(iv))
			pt = Cnv.FromHex("5468697320736F6D652073616D706520636F6E74656E742E")
			Console.WriteLine("PT=" & Cnv.ToHex(pt))
			Console.WriteLine("PT='" & System.Text.Encoding.[Default].GetString(pt) & "'")
			correct = Cnv.FromHex("d76fd1178fbd02f84231f5c1d2a2f74a4159482964f675248254223daf9af8e4")
			ct = Cipher.Encrypt(pt, key, iv, CipherAlgorithm.Tdea, Mode.CBC, Padding.Pkcs5)
			Console.WriteLine("CT=" & Cnv.ToHex(ct))
			Console.WriteLine("OK=" & Cnv.ToHex(correct))
			Debug.Assert(ByteArraysEqual(ct, correct), "Cipher.Encrypt with padding failed")
			' Now decrypt
			p1 = Cipher.Decrypt(ct, key, iv, CipherAlgorithm.Tdea, Mode.CBC, Padding.Pkcs5)
			Console.WriteLine("P'=" & Cnv.ToHex(p1))
			Console.WriteLine("P'='" & System.Text.Encoding.[Default].GetString(p1) & "'")
			Debug.Assert(ByteArraysEqual(p1, pt), "Cipher.Decrypt with padding failed")

			Console.WriteLine("Aes128/CBC/pkcs5")
			key = Cnv.FromHex("0123456789ABCDEFF0E1D2C3B4A59687")
			iv = Cnv.FromHex("FEDCBA9876543210FEDCBA9876543210")
			Console.WriteLine("KY=" & Cnv.ToHex(key))
			Console.WriteLine("IV=" & Cnv.ToHex(iv))
			s = "Now is the time for all good men to"
			pt = System.Text.Encoding.[Default].GetBytes(s)
			Console.WriteLine("PT=" & Cnv.ToHex(pt))
			Console.WriteLine("PT='" & System.Text.Encoding.[Default].GetString(pt) & "'")
			correct = Cnv.FromHex("C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E17753C7E8DF5975A36677355F5C6584228B")
			ct = Cipher.Encrypt(pt, key, iv, CipherAlgorithm.Aes128, Mode.CBC, Padding.Pkcs5)
			Console.WriteLine("CT=" & Cnv.ToHex(ct))
			Console.WriteLine("OK=" & Cnv.ToHex(correct))
			Debug.Assert(ByteArraysEqual(ct, correct), "Cipher.Encrypt with padding failed")
			' Now decrypt
			p1 = Cipher.Decrypt(ct, key, iv, CipherAlgorithm.Aes128, Mode.CBC, Padding.Pkcs5)
			Console.WriteLine("P'=" & Cnv.ToHex(p1))
			Console.WriteLine("P'='" & System.Text.Encoding.[Default].GetString(p1) & "'")
			Debug.Assert(ByteArraysEqual(p1, pt), "Cipher.Decrypt with padding failed")
			p1 = Cipher.Decrypt(ct, key, iv, CipherAlgorithm.Aes128, Mode.CBC, Padding.NoPad)
			Console.WriteLine("Pn=" & Cnv.ToHex(p1))

			Console.WriteLine("Aes128/ECB/OneAndZeroes...")
			ct = Cipher.Encrypt(pt, key, iv, CipherAlgorithm.Aes128, Mode.ECB, Padding.OneAndZeroes)
			Console.WriteLine("CT=" & Cnv.ToHex(ct))
			p1 = Cipher.Decrypt(ct, key, iv, CipherAlgorithm.Aes128, Mode.ECB, Padding.NoPad)
			Console.WriteLine("Pn=" & Cnv.ToHex(p1))
			p1 = Cipher.Decrypt(ct, key, iv, CipherAlgorithm.Aes128, Mode.ECB, Padding.OneAndZeroes)
			Console.WriteLine("P'=" & Cnv.ToHex(p1))
			Console.WriteLine("P'='" & System.Text.Encoding.[Default].GetString(p1) & "'")
			Debug.Assert(ByteArraysEqual(p1, pt))


		End Sub

		Private Shared Sub test_Poly1305()
			Dim msg As String
			Dim msgHex As String
			Dim keyHex As String
			Dim tagHex As String
			Dim okhex As String

			' ***********************************
			' POLY1305 AUTHENTICATION ALGORITHM *
			' ***********************************
			Console.WriteLine(vbLf & "POLY1305 AUTHENTICATION ALGORITHM:")
			' Ref: Test vector from `draft-irtf-cfrg-chacha20-poly1305-06.txt`
			msg = "Cryptographic Forum Research Group"
			keyHex = "85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b"
			okhex = "a8061dc1305136c6c22b8baf0c0127a9"

			msgHex = Cnv.ToHex(msg)
			Console.WriteLine("Message to be authenticated:")
			Console.WriteLine("'" & msg & "'")
			Console.WriteLine(msgHex)

			Console.WriteLine("Key: " & keyHex)
			tagHex = Mac.HexFromHex(msgHex, keyHex, MacAlgorithm.Poly1305)
			Console.WriteLine("Tag: " & tagHex)
			Debug.Assert([String].Compare(tagHex, okhex, True) = 0, "Mac.HexFromHex(Poly1305) failed")


		End Sub

		Private Shared Sub test_SHA3_obj()
			Dim n As Integer
			Dim s As String
			Dim isok As Boolean
			Dim okhex As String

			'**************************
			' SHA-3 HASH DIGEST TESTS *
			'**************************
			Console.WriteLine("TESTING SHA-3 object:")
			Dim bitlengths As Integer() = {224, 256, 384, 512}
			For Each nbits As Integer In bitlengths
				' Instantiate a new object for SHA-3
				Dim oSha3 As Sha3 = Sha3.Instance()
				isok = oSha3.Init(nbits)
				Console.WriteLine("oSha3.Init({1}) returned {0}. LengthInBytes={2}", isok, nbits, oSha3.LengthInBytes)
				Debug.Assert(isok, "Sha3.Init failed")

				n = oSha3.AddData("a")
				n = oSha3.AddData("bc")
				s = oSha3.HexDigest()
				Console.WriteLine("SHA3-{1}('abc')={0}", s, nbits)
				' Correct result
				Select Case nbits
					Case 224
						okhex = "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf"
						Exit Select
					Case 256
						okhex = "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"
						Exit Select
					Case 384
						okhex = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25"
						Exit Select
					Case 512
						okhex = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"
						Exit Select
					Case Else
						okhex = ""
						Exit Select
				End Select
				Debug.Assert([String].Compare(okhex, s, True) = 0, "SHA-3('abc') failed")

				' Compute SHA-3(one million repetitions of 'a')
				oSha3.Init(nbits)
				Dim a1000 As Byte() = New Byte(999) {}
				For i As Integer = 0 To 999
					a1000(i) = &H61
				Next
				' 'a' in ascii form
				For i As Integer = 0 To 999
					n = oSha3.AddData(a1000)
					Debug.Assert(0 = n, "Sha3.Adddata failed")
				Next
				s = oSha3.HexDigest()
				Console.WriteLine("SHA3-{1}(1M x 'a')={0}", s, nbits)
				' Correct result
				Select Case nbits
					Case 224
						okhex = "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c"
						Exit Select
					Case 256
						okhex = "5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1"
						Exit Select
					Case 384
						okhex = "eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340"
						Exit Select
					Case 512
						okhex = "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87"
						Exit Select
					Case Else
						okhex = ""
						Exit Select
				End Select
				Debug.Assert([String].Compare(okhex, s, True) = 0, "SHA-3(1M x 'a') failed")

				' Compute the SHA-3 digest of the empty string
				oSha3.Init(nbits)
				s = oSha3.HexDigest()
				Console.WriteLine("SHA3-{1}('')={0}", s, nbits)
				' Correct result
				Select Case nbits
					Case 224
						okhex = "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"
						Exit Select
					Case 256
						okhex = "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"
						Exit Select
					Case 384
						okhex = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"
						Exit Select
					Case 512
						okhex = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"
						Exit Select
					Case Else
						okhex = ""
						Exit Select
				End Select
				Debug.Assert([String].Compare(okhex, s, True) = 0, "SHA-3(empty) failed")

				oSha3.Dispose()
			Next
		End Sub

		Private Shared Sub test_SHA3()
			Dim s As String
			Dim b As Byte()
			Dim okhex As String
			Dim msghex As String
			Dim keyhex As String
			Dim bitlen As Integer

			Console.WriteLine("TESTING SHA-3:")
			' SHA-3-256("abc")
			okhex = "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"

			' Compute digest from string
			s = Hash.HexFromString("abc", HashAlgorithm.Sha3_256)
			Console.WriteLine("SHA3-256('abc')={0}", s)
			Debug.Assert([String].Compare(okhex, s, True) = 0, "SHA-3('abc') failed")

			' SHA-3-256 of "abc" as byte array
			b = New Byte() {&H61, &H62, &H63}
			' "abc" in a byte array
			s = Hash.HexFromBytes(b, HashAlgorithm.Sha3_256)
			Console.WriteLine("SHA3-256('abc')={0}", s)
			Debug.Assert([String].Compare(okhex, s, True) = 0, "SHA-3('abc') failed")

			' Same again bitwise
			s = Hash.HexFromBits(b, 24, HashAlgorithm.Sha3_256)
			Console.WriteLine("SHA3-256('abc')={0}", s)
			Debug.Assert([String].Compare(okhex, s, True) = 0, "SHA-3('abc') failed")

			' Ref: SHAVS-SHA3 CAVS 19.0 "SHA3-256 ShortMsg" information for "SHA3AllBits1-28-16"
			b = Cnv.FromHex("2590A0")
			' NIST "259028"
			bitlen = 22
			okhex = "d5863d4b1ff41551c92a9e08c52177e32376c9bd100c611c607db840096eb22f"
			s = Hash.HexFromBits(b, bitlen, HashAlgorithm.Sha3_256)
			Console.WriteLine("SHA3-256(22bits)={0}", s)
			Debug.Assert([String].Compare(okhex, s, True) = 0, "SHA-3(22bits) failed")

			' HMAC-SHA3-256
			' Text is "Sample message for keylen<blocklen"
			msghex = "53616D706C65206D65737361676520666F72206B65796C656E3C626C6F636B6C656E"
			keyhex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
			okhex = "4fe8e202c4f058e8dddc23d8c34e467343e23555e24fc2f025d598f558f67205"
			s = Mac.HexFromHex(msghex, keyhex, MacAlgorithm.HmacSha3_256)
			Console.WriteLine("HMAC-SHA3-256()={0}", s)
			Debug.Assert([String].Compare(okhex, s, True) = 0, "HMAC-SHA3-256() failed")

		End Sub

		Private Shared Sub test_KMAC()
			Dim b As Byte()
			Dim s As String
			Dim okhex As String
			Dim msghex As String
			Dim keyhex As String
			Dim noutbits As Integer

			Console.WriteLine("TESTING KMAC:")
			' Ref: `KMAC_samples.pdf` "Secure Hashing - KMAC-Samples" 2017-02-27
			' Sample #1
			keyhex = "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"
			msghex = "00010203"
			noutbits = 256
			okhex = "E5780B0D3EA6F7D3A429C5706AA43A00FADBD7D49628839E3187243F456EE14E"

			' Compute MAC from hex-encoded strings, fixed "standard" size
			s = Mac.HexFromHex(msghex, keyhex, MacAlgorithm.Kmac128)
			Console.WriteLine("KMAC128={0}", s)
			Console.WriteLine("OK     ={0}", okhex)
			Debug.Assert([String].Compare(okhex, s, True) = 0, "KMAC failed")

			' Compute MAC using Prf class, explicitly specifying size
			b = Prf.Bytes(noutbits \ 8, Cnv.FromHex(msghex), Cnv.FromHex(keyhex), "", PrfAlgorithm.Kmac128)
			Console.WriteLine("KMAC128={0}", Cnv.ToHex(b))
			Console.WriteLine("OK     ={0}", okhex)
			Debug.Assert([String].Compare(okhex, Cnv.ToHex(b), True) = 0, "KMAC failed")

			' Request a lot of output (> single KECCAK block)
			okhex = "38158A1CAE4E1A25D85F2031246ADE697B3292FEF88B0923A59A02D1D53B704653EE7242662A10796BA20779D300D52D7432018741233D587252D31DC48BDB8233285D4A4ACD65848509B051A448D873649228B6626E5EF817C7AF2DEDC91F120F8CA535A1EE301FAE8186FDEDE5A76181A472A32CFAD1DDD1391E162F124D4A7572AD8A20076601BCF81E4B0391F3E95AEFFA708C33C1217C96BE6A4F02FBBC2D3B3B6FFAEB5BFD3BE4A2E02B75993FCC04DA6FAC4BFCB2A9F05792A1A5CC80CA34186243EFDB31"
			noutbits = 1600
			b = Prf.Bytes(noutbits \ 8, Cnv.FromHex(msghex), Cnv.FromHex(keyhex), "", PrfAlgorithm.Kmac128)
			Console.WriteLine("KMAC128={0}", Cnv.ToHex(b))
			Console.WriteLine("OK     ={0}", okhex)
			Debug.Assert([String].Compare(okhex, Cnv.ToHex(b), True) = 0, "KMAC failed")
		End Sub

		Private Shared Sub test_XOF()
			Dim b As Byte()
			Dim okhex As String
			Dim msghex As String
			Dim noutbits As Integer

			Console.WriteLine("TESTING XOF:")
			' Ref: "SHA-3 XOF Test Vectors for Byte-Oriented Output"
			' File `SHAKE256VariableOut.rsp` COUNT = 1244
			msghex = "6ae23f058f0f2264a18cd609acc26dd4dbc00f5c3ee9e13ecaea2bb5a2f0bb6b"
			noutbits = 2000
			okhex = "b9b92544fb25cfe4ec6fe437d8da2bbe00f7bdaface3de97b8775a44d753c3adca3f7c6f183cc8647e229070439aa9539ae1f8f13470c9d3527fffdeef6c94f9f0520ff0c1ba8b16e16014e1af43ac6d94cb7929188cce9d7b02f81a2746f52ba16988e5f6d93298d778dfe05ea0ef256ae3728643ce3e29c794a0370e9ca6a8bf3e7a41e86770676ac106f7ae79e67027ce7b7b38efe27d253a52b5cb54d6eb4367a87736ed48cb45ef27f42683da140ed3295dfc575d3ea38cfc2a3697cc92864305407369b4abac054e497378dd9fd0c4b352ea3185ce1178b3dc1599df69db29259d4735320c8e7d33e8226620c9a1d22761f1d35bdff79a"

			b = Xof.Bytes(noutbits \ 8, Cnv.FromHex(msghex), XofAlgorithm.Shake256)
			Console.WriteLine("SHAKE256={0}", Cnv.ToHex(b))
			Console.WriteLine("OK      ={0}", okhex)
			Debug.Assert([String].Compare(okhex, Cnv.ToHex(b), True) = 0, "XOF failed")
		End Sub

		'*****************
		' FILE UTILITIES *
		'*****************

		Private Shared Function GetFileAsHex(fileName As String) As String
			Dim b As Byte() = File.ReadAllBytes(fileName)
			Dim s As String = Cnv.ToHex(b)
			Return s
		End Function

		Private Shared Function FileExists(filePath As String) As Boolean
			Dim fi As New FileInfo(filePath)
			Return fi.Exists
		End Function

		Private Shared Function FileLength(filePath As String) As Integer
			' Assuming size less than 2 GB
			Dim fi As New FileInfo(filePath)
			Return CInt(fi.Length)
		End Function

		Private Shared Function FilesAreIdentical(file1 As String, file2 As String) As Boolean
		' Returns true if two binary files are identical, false if they are not
		' Ref: http://support.microsoft.com/kb/320348
			Dim file1byte As Integer
			Dim file2byte As Integer
			Dim fs1 As FileStream
			Dim fs2 As FileStream

			' Open the two files.
			fs1 = New FileStream(file1, FileMode.Open)
			fs2 = New FileStream(file2, FileMode.Open)

			' Check the file sizes. If they are not the same, the files 
			' are not the same.
			If fs1.Length <> fs2.Length Then
				' Close the files
				fs1.Close()
				fs2.Close()

				' Return false to indicate files are different
				Return False
			End If
			Do
				' Read one byte from each file.
				file1byte = fs1.ReadByte()
				file2byte = fs2.ReadByte()
			Loop While (file1byte = file2byte) AndAlso (file1byte <> -1)

			' Close the files.
			fs1.Close()
			fs2.Close()
			' Return the success of the comparison. "file1byte" is 
			' equal to "file2byte" at this point only if the files are 
			' the same.
			Return ((file1byte - file2byte) = 0)
		End Function


		' Incredibly, there isn't a byte compare function in .NET
		Private Shared Function ByteArraysEqual(data1 As Byte(), data2 As Byte()) As Boolean
			' Thanks to Jon Skeet http://www.pobox.com/~skeet
			' If both are null, they're equal
			If data1 Is Nothing AndAlso data2 Is Nothing Then
				Return True
			End If
			' If either but not both are null, they're not equal
			If data1 Is Nothing OrElse data2 Is Nothing Then
				Return False
			End If
			If data1.Length <> data2.Length Then
				Return False
			End If
			For i As Integer = 0 To data1.Length - 1
				If data1(i) <> data2(i) Then
					Return False
				End If
			Next
			Return True
		End Function

		''' <summary>
		''' Concatenate byte arrays a and b
		''' </summary>
		''' <param name="a">Array a</param>
		''' <param name="b">Array b</param>
		''' <returns>a concat b</returns>
		Private Shared Function ByteArraysConcat(a As Byte(), b As Byte()) As Byte()
			Dim len As Integer = a.Length + b.Length
			Dim c As Byte() = New Byte(len - 1) {}
			a.CopyTo(c, 0)
			b.CopyTo(c, a.Length)
			Return c
		End Function

		'**********************
		' HOUSEKEEPING STUFF...
		'**********************

		Private Shared Function SetupTestDirectory() As String
			Dim subdir As String
			'**************************************************
			' Check we have required files in local directory *
			'**************************************************
			Dim assemblyFile As String = Assembly.GetExecutingAssembly().Location
			Dim assemblyDir As String = Path.GetDirectoryName(assemblyFile)
			Console.WriteLine("Local directory is '{0}'.", assemblyDir)

			'*************************************************
			' Create a test sub-directory with a random name, 
			' copy these test files to it, and work in that sub-directory
			'*************************************************
			subdir = "apitest." & Cnv.ToHex(Rng.NonceBytes(4))
			Console.WriteLine("Creating test sub-directory '{0}'", subdir)
			System.IO.Directory.CreateDirectory(subdir)
			' Change current working directory to sub-dir
			System.IO.Directory.SetCurrentDirectory(subdir)
			Console.WriteLine("CWD is " & System.IO.Directory.GetCurrentDirectory())

			Return subdir
		End Function

		'*********************************************************
		' Put CWD back to parent and offer to remove the test dir
		'*********************************************************
		Private Shared Sub RestoreDirectory(subdir As String, askDelete As Boolean)
			Dim s As String

			System.IO.Directory.SetCurrentDirectory("..")
			Console.WriteLine(vbLf & "CWD reset to " & System.IO.Directory.GetCurrentDirectory())
			If askDelete Then
				Console.Write("The temp test directory '{0}' was created by this program." & vbLf & "Do you want to remove it? ([Y]/N) ", subdir)
				s = Console.ReadLine()
				If "N" <> s AndAlso "n" <> s Then
					' Remove directory
					Console.WriteLine("Removing test directory...")
					System.IO.Directory.Delete(subdir, True)
				Else
					Console.WriteLine("Temp directory '{0}' left in place.", subdir)
				End If
			Else
				' Remove directory regardless
				Console.WriteLine("Removing test directory '{0}'", subdir)
				System.IO.Directory.Delete(subdir, True)
			End If
		End Sub

	End Class
End Namespace