summary refs log tree commit diff
path: root/crypto/test/src/openpgp
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2013-06-28 15:26:06 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2013-06-28 15:26:06 +0700
commit44288db4414158ac9b98a507b15e81d0d3c66ca6 (patch)
treeaa5ef88948ebb68ed6c8df81eb5da889641a9b50 /crypto/test/src/openpgp
parentSet up text/binary handling for existing file types (diff)
downloadBouncyCastle.NET-ed25519-44288db4414158ac9b98a507b15e81d0d3c66ca6.tar.xz
Initial import of old CVS repository
Diffstat (limited to 'crypto/test/src/openpgp')
-rw-r--r--crypto/test/src/openpgp/examples/ByteArrayHandler.cs195
-rw-r--r--crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs375
-rw-r--r--crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs167
-rw-r--r--crypto/test/src/openpgp/examples/DirectKeySignature.cs140
-rw-r--r--crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs134
-rw-r--r--crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs259
-rw-r--r--crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs267
-rw-r--r--crypto/test/src/openpgp/examples/PbeFileProcessor.cs183
-rw-r--r--crypto/test/src/openpgp/examples/PgpExampleUtilities.cs123
-rw-r--r--crypto/test/src/openpgp/examples/PublicKeyRingDump.cs98
-rw-r--r--crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs115
-rw-r--r--crypto/test/src/openpgp/examples/SignedFileProcessor.cs188
-rw-r--r--crypto/test/src/openpgp/examples/test/AllTests.cs403
-rw-r--r--crypto/test/src/openpgp/test/DSA2Test.cs237
-rw-r--r--crypto/test/src/openpgp/test/PGPArmoredTest.cs265
-rw-r--r--crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs445
-rw-r--r--crypto/test/src/openpgp/test/PGPCompressionTest.cs117
-rw-r--r--crypto/test/src/openpgp/test/PGPDSAElGamalTest.cs492
-rw-r--r--crypto/test/src/openpgp/test/PGPDSATest.cs597
-rw-r--r--crypto/test/src/openpgp/test/PGPPBETest.cs384
-rw-r--r--crypto/test/src/openpgp/test/PGPPacketTest.cs80
-rw-r--r--crypto/test/src/openpgp/test/PGPRSATest.cs1235
-rw-r--r--crypto/test/src/openpgp/test/PGPSignatureTest.cs761
-rw-r--r--crypto/test/src/openpgp/test/PgpKeyRingTest.cs2163
-rw-r--r--crypto/test/src/openpgp/test/PgpMarkerTest.cs102
-rw-r--r--crypto/test/src/openpgp/test/RegressionTest.cs34
26 files changed, 9559 insertions, 0 deletions
diff --git a/crypto/test/src/openpgp/examples/ByteArrayHandler.cs b/crypto/test/src/openpgp/examples/ByteArrayHandler.cs
new file mode 100644
index 000000000..676db8766
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/ByteArrayHandler.cs
@@ -0,0 +1,195 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * Simple routine to encrypt and decrypt using a passphrase.
+    * This service routine provides the basic PGP services between
+    * byte arrays.
+    *
+    * Note: this code plays no attention to -Console in the file name
+    * the specification of "_CONSOLE" in the filename.
+    * It also expects that a single pass phrase will have been used.
+    *
+    */
+    public sealed class ByteArrayHandler
+    {
+        private ByteArrayHandler()
+        {
+        }
+
+        /**
+        * decrypt the passed in message stream
+        *
+        * @param encrypted  The message to be decrypted.
+        * @param passPhrase Pass phrase (key)
+        *
+        * @return Clear text as a byte array.  I18N considerations are
+        *         not handled by this routine
+        * @exception IOException
+        * @exception PgpException
+        */
+        public static byte[] Decrypt(
+            byte[] encrypted,
+            char[] passPhrase)
+        {
+            Stream inputStream = new MemoryStream(encrypted);
+
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            PgpObjectFactory pgpF = new PgpObjectFactory(inputStream);
+            PgpEncryptedDataList enc = null;
+            PgpObject o = pgpF.NextPgpObject();
+
+			//
+            // the first object might be a PGP marker packet.
+            //
+            if (o is PgpEncryptedDataList)
+            {
+                enc = (PgpEncryptedDataList) o;
+            }
+            else
+            {
+                enc = (PgpEncryptedDataList) pgpF.NextPgpObject();
+            }
+
+            PgpPbeEncryptedData pbe = (PgpPbeEncryptedData)enc[0];
+
+            Stream clear = pbe.GetDataStream(passPhrase);
+
+            PgpObjectFactory pgpFact = new PgpObjectFactory(clear);
+
+            PgpCompressedData cData = (PgpCompressedData) pgpFact.NextPgpObject();
+
+            pgpFact = new PgpObjectFactory(cData.GetDataStream());
+
+            PgpLiteralData ld = (PgpLiteralData) pgpFact.NextPgpObject();
+
+            Stream unc = ld.GetInputStream();
+
+			return Streams.ReadAll(unc);
+        }
+
+        /**
+        * Simple PGP encryptor between byte[].
+        *
+        * @param clearData  The test to be encrypted
+        * @param passPhrase The pass phrase (key).  This method assumes that the
+        *                   key is a simple pass phrase, and does not yet support
+        *                   RSA or more sophisiticated keying.
+        * @param fileName   File name. This is used in the Literal Data Packet (tag 11)
+        *                   which is really inly important if the data is to be
+        *                   related to a file to be recovered later.  Because this
+        *                   routine does not know the source of the information, the
+        *                   caller can set something here for file name use that
+        *                   will be carried.  If this routine is being used to
+        *                   encrypt SOAP MIME bodies, for example, use the file name from the
+        *                   MIME type, if applicable. Or anything else appropriate.
+        *
+        * @param armor
+        *
+        * @return encrypted data.
+        * @exception IOException
+        * @exception PgpException
+        */
+        public static byte[] Encrypt(
+            byte[]						clearData,
+            char[]						passPhrase,
+            string						fileName,
+            SymmetricKeyAlgorithmTag	algorithm,
+            bool						armor)
+        {
+            if (fileName == null)
+            {
+                fileName = PgpLiteralData.Console;
+            }
+
+			byte[] compressedData = Compress(clearData, fileName, CompressionAlgorithmTag.Zip);
+
+			MemoryStream bOut = new MemoryStream();
+
+			Stream output = bOut;
+			if (armor)
+			{
+				output = new ArmoredOutputStream(output);
+			}
+
+			PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(algorithm, new SecureRandom());
+            encGen.AddMethod(passPhrase);
+
+			Stream encOut = encGen.Open(output, compressedData.Length);
+
+			encOut.Write(compressedData, 0, compressedData.Length);
+			encOut.Close();
+			
+			if (armor)
+			{
+				output.Close();
+			}
+
+			return bOut.ToArray();
+        }
+
+		private static byte[] Compress(byte[] clearData, string fileName, CompressionAlgorithmTag algorithm)
+		{
+            MemoryStream bOut = new MemoryStream();
+
+            PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(algorithm);
+            Stream cos = comData.Open(bOut); // open it with the final destination
+            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
+
+            // we want to Generate compressed data. This might be a user option later,
+            // in which case we would pass in bOut.
+            Stream pOut = lData.Open(
+				cos,					// the compressed output stream
+                PgpLiteralData.Binary,
+                fileName,				// "filename" to store
+                clearData.Length,		// length of clear data
+                DateTime.UtcNow			// current time
+            );
+
+			pOut.Write(clearData, 0, clearData.Length);
+			pOut.Close();
+
+			comData.Close();
+
+			return bOut.ToArray();
+		}
+
+		private static string GetAsciiString(byte[] bs)
+		{
+			return Encoding.ASCII.GetString(bs, 0, bs.Length);
+		}
+
+        public static void Main(
+			string[] args)
+        {
+            string passPhrase = "Dick Beck";
+            char[] passArray = passPhrase.ToCharArray();
+
+            byte[] original = Encoding.ASCII.GetBytes("Hello world");
+            Console.WriteLine("Starting PGP test");
+            byte[] encrypted = Encrypt(original, passArray, "iway", SymmetricKeyAlgorithmTag.Cast5, true);
+
+            Console.WriteLine("\nencrypted data = '"+Hex.ToHexString(encrypted)+"'");
+            byte[] decrypted= Decrypt(encrypted,passArray);
+
+            Console.WriteLine("\ndecrypted data = '"+GetAsciiString(decrypted)+"'");
+
+            encrypted = Encrypt(original, passArray, "iway", SymmetricKeyAlgorithmTag.Aes256, false);
+
+            Console.WriteLine("\nencrypted data = '"+Hex.ToHexString(encrypted)+"'");
+            decrypted= Decrypt(encrypted, passArray);
+
+            Console.WriteLine("\ndecrypted data = '"+GetAsciiString(decrypted)+"'");
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs b/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs
new file mode 100644
index 000000000..14fa37269
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs
@@ -0,0 +1,375 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that creates clear signed files and verifies them.
+    * <p>
+    * To sign a file: ClearSignedFileProcessor -s fileName secretKey passPhrase.
+	* </p>
+    * <p>
+    * To decrypt: ClearSignedFileProcessor -v fileName signatureFile publicKeyFile.
+	* </p>
+    */
+    public sealed class ClearSignedFileProcessor
+    {
+        private ClearSignedFileProcessor()
+        {
+        }
+
+		private static int ReadInputLine(
+			MemoryStream	bOut,
+			Stream			fIn)
+		{
+			bOut.SetLength(0);
+
+			int lookAhead = -1;
+			int ch;
+
+			while ((ch = fIn.ReadByte()) >= 0)
+			{
+				bOut.WriteByte((byte) ch);
+				if (ch == '\r' || ch == '\n')
+				{
+					lookAhead = ReadPassedEol(bOut, ch, fIn);
+					break;
+				}
+			}
+
+			return lookAhead;
+		}
+
+		private static int ReadInputLine(
+			MemoryStream	bOut,
+			int				lookAhead,
+			Stream			fIn)
+		{
+			bOut.SetLength(0);
+
+			int ch = lookAhead;
+
+			do
+			{
+				bOut.WriteByte((byte) ch);
+				if (ch == '\r' || ch == '\n')
+				{
+					lookAhead = ReadPassedEol(bOut, ch, fIn);
+					break;
+				}
+			}
+			while ((ch = fIn.ReadByte()) >= 0);
+
+			if (ch < 0)
+			{
+				lookAhead = -1;
+			}
+
+			return lookAhead;
+		}
+
+		private static int ReadPassedEol(
+			MemoryStream	bOut,
+			int				lastCh,
+			Stream			fIn)
+		{
+			int lookAhead = fIn.ReadByte();
+
+			if (lastCh == '\r' && lookAhead == '\n')
+			{
+				bOut.WriteByte((byte) lookAhead);
+				lookAhead = fIn.ReadByte();
+			}
+
+			return lookAhead;
+		}
+
+		/*
+		* verify a clear text signed file
+		*/
+        private static void VerifyFile(
+            Stream	inputStream,
+            Stream	keyIn,
+			string	resultName)
+        {
+			ArmoredInputStream aIn = new ArmoredInputStream(inputStream);
+			Stream outStr = File.Create(resultName);
+
+			//
+			// write out signed section using the local line separator.
+			// note: trailing white space needs to be removed from the end of
+			// each line RFC 4880 Section 7.1
+			//
+			MemoryStream lineOut = new MemoryStream();
+			int lookAhead = ReadInputLine(lineOut, aIn);
+			byte[] lineSep = LineSeparator;
+
+			if (lookAhead != -1 && aIn.IsClearText())
+			{
+				byte[] line = lineOut.ToArray();
+				outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
+				outStr.Write(lineSep, 0, lineSep.Length);
+
+				while (lookAhead != -1 && aIn.IsClearText())
+				{
+					lookAhead = ReadInputLine(lineOut, lookAhead, aIn);
+                
+					line = lineOut.ToArray();
+					outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
+					outStr.Write(lineSep, 0, lineSep.Length);
+				}
+			}
+
+			outStr.Close();
+
+			PgpPublicKeyRingBundle pgpRings = new PgpPublicKeyRingBundle(keyIn);
+
+			PgpObjectFactory pgpFact = new PgpObjectFactory(aIn);
+			PgpSignatureList p3 = (PgpSignatureList) pgpFact.NextPgpObject();
+			PgpSignature sig = p3[0];
+
+			sig.InitVerify(pgpRings.GetPublicKey(sig.KeyId));
+
+			//
+			// read the input, making sure we ignore the last newline.
+			//
+			Stream sigIn = File.OpenRead(resultName);
+
+			lookAhead = ReadInputLine(lineOut, sigIn);
+
+			ProcessLine(sig, lineOut.ToArray());
+
+			if (lookAhead != -1)
+			{
+				do
+				{
+					lookAhead = ReadInputLine(lineOut, lookAhead, sigIn);
+
+					sig.Update((byte) '\r');
+					sig.Update((byte) '\n');
+
+					ProcessLine(sig, lineOut.ToArray());
+				}
+				while (lookAhead != -1);
+			}
+
+			sigIn.Close();
+
+			if (sig.Verify())
+            {
+                Console.WriteLine("signature verified.");
+            }
+            else
+            {
+                Console.WriteLine("signature verification failed.");
+            }
+        }
+
+		private static byte[] LineSeparator
+		{
+			get { return Encoding.ASCII.GetBytes(SimpleTest.NewLine); }
+		}
+
+        /*
+        * create a clear text signed file.
+        */
+        private static void SignFile(
+            string	fileName,
+            Stream	keyIn,
+            Stream	outputStream,
+            char[]	pass,
+			string	digestName)
+        {
+			HashAlgorithmTag digest;
+
+			if (digestName.Equals("SHA256"))
+			{
+				digest = HashAlgorithmTag.Sha256;
+			}
+			else if (digestName.Equals("SHA384"))
+			{
+				digest = HashAlgorithmTag.Sha384;
+			}
+			else if (digestName.Equals("SHA512"))
+			{
+				digest = HashAlgorithmTag.Sha512;
+			}
+			else if (digestName.Equals("MD5"))
+			{
+				digest = HashAlgorithmTag.MD5;
+			}
+			else if (digestName.Equals("RIPEMD160"))
+			{
+				digest = HashAlgorithmTag.RipeMD160;
+			}
+			else
+			{
+				digest = HashAlgorithmTag.Sha1;
+			}
+
+			PgpSecretKey                    pgpSecKey = PgpExampleUtilities.ReadSecretKey(keyIn);
+            PgpPrivateKey                   pgpPrivKey = pgpSecKey.ExtractPrivateKey(pass);
+            PgpSignatureGenerator           sGen = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, digest);
+            PgpSignatureSubpacketGenerator  spGen = new PgpSignatureSubpacketGenerator();
+
+			sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey);
+
+			IEnumerator enumerator = pgpSecKey.PublicKey.GetUserIds().GetEnumerator();
+            if (enumerator.MoveNext())
+            {
+                spGen.SetSignerUserId(false, (string) enumerator.Current);
+                sGen.SetHashedSubpackets(spGen.Generate());
+            }
+
+            Stream fIn = File.OpenRead(fileName);
+			ArmoredOutputStream aOut = new ArmoredOutputStream(outputStream);
+
+			aOut.BeginClearText(digest);
+
+			//
+			// note the last \n/\r/\r\n in the file is ignored
+			//
+			MemoryStream lineOut = new MemoryStream();
+			int lookAhead = ReadInputLine(lineOut, fIn);
+
+			ProcessLine(aOut, sGen, lineOut.ToArray());
+
+			if (lookAhead != -1)
+			{
+				do
+				{
+					lookAhead = ReadInputLine(lineOut, lookAhead, fIn);
+
+					sGen.Update((byte) '\r');
+					sGen.Update((byte) '\n');
+
+					ProcessLine(aOut, sGen, lineOut.ToArray());
+				}
+				while (lookAhead != -1);
+			}
+
+			fIn.Close();
+
+			aOut.EndClearText();
+
+			BcpgOutputStream bOut = new BcpgOutputStream(aOut);
+
+            sGen.Generate().Encode(bOut);
+
+            aOut.Close();
+        }
+
+		private static void ProcessLine(
+			PgpSignature	sig,
+			byte[]			line)
+		{
+			// note: trailing white space needs to be removed from the end of
+			// each line for signature calculation RFC 4880 Section 7.1
+			int length = GetLengthWithoutWhiteSpace(line);
+			if (length > 0)
+			{
+				sig.Update(line, 0, length);
+			}
+		}
+
+		private static void ProcessLine(
+			Stream					aOut,
+			PgpSignatureGenerator	sGen,
+			byte[]					line)
+		{
+			int length = GetLengthWithoutWhiteSpace(line);
+			if (length > 0)
+			{
+				sGen.Update(line, 0, length);
+			}
+
+			aOut.Write(line, 0, line.Length);
+		}
+
+		private static int GetLengthWithoutSeparatorOrTrailingWhitespace(byte[] line)
+		{
+			int end = line.Length - 1;
+
+			while (end >= 0 && IsWhiteSpace(line[end]))
+			{
+				end--;
+			}
+
+			return end + 1;
+		}
+
+		private static bool IsLineEnding(
+			byte b)
+		{
+			return b == '\r' || b == '\n';
+		}
+
+		private static int GetLengthWithoutWhiteSpace(
+			byte[] line)
+		{
+			int end = line.Length - 1;
+
+			while (end >= 0 && IsWhiteSpace(line[end]))
+			{
+				end--;
+			}
+
+			return end + 1;
+		}
+
+		private static bool IsWhiteSpace(
+			byte b)
+		{
+			return IsLineEnding(b) || b == '\t' || b == ' ';
+		}
+
+		public static int Main(
+            string[] args)
+        {
+            if (args[0].Equals("-s"))
+            {
+				Stream fis = File.OpenRead(args[2]);
+				Stream fos = File.Create(args[1] + ".asc");
+
+				Stream keyIn = PgpUtilities.GetDecoderStream(fis);
+
+				string digestName = (args.Length == 4)
+					?	"SHA1"
+					:	args[4];
+
+				SignFile(args[1], keyIn, fos, args[3].ToCharArray(), digestName);
+
+				fis.Close();
+				fos.Close();
+            }
+            else if (args[0].Equals("-v"))
+            {
+				if (args[1].IndexOf(".asc") < 0)
+				{
+					Console.Error.WriteLine("file needs to end in \".asc\"");
+					return 1;
+				}
+
+				Stream fin = File.OpenRead(args[1]);
+				Stream fis = File.OpenRead(args[2]);
+
+				Stream keyIn = PgpUtilities.GetDecoderStream(fis);
+
+				VerifyFile(fin, keyIn, args[1].Substring(0, args[1].Length - 4));
+
+				fin.Close();
+				fis.Close();
+            }
+            else
+            {
+                Console.Error.WriteLine("usage: ClearSignedFileProcessor [-s file keyfile passPhrase]|[-v sigFile keyFile]");
+            }
+			return 0;
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs b/crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs
new file mode 100644
index 000000000..c4959844d
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs
@@ -0,0 +1,167 @@
+using System;
+using System.Collections;
+using System.IO;
+
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that creates seperate signatures for files and verifies them.
+    * <p>
+    * To sign a file: DetachedSignatureProcessor -s [-a] fileName secretKey passPhrase.<br/>
+    * If -a is specified the output file will be "ascii-armored".</p>
+    * <p>
+    * To decrypt: DetachedSignatureProcessor -v  fileName signatureFile publicKeyFile.</p>
+    * <p>
+    * Note: this example will silently overwrite files.
+    * It also expects that a single pass phrase
+    * will have been used.</p>
+    */
+    public sealed class DetachedSignatureProcessor
+    {
+        private DetachedSignatureProcessor()
+        {
+        }
+
+		private static void VerifySignature(
+			string	fileName,
+			string	inputFileName,
+			string	keyFileName)
+		{
+			using (Stream input = File.OpenRead(inputFileName),
+				keyIn = File.OpenRead(keyFileName))
+			{
+				VerifySignature(fileName, input, keyIn);
+			}
+		}
+
+		/**
+        * verify the signature in in against the file fileName.
+        */
+        private static void VerifySignature(
+            string	fileName,
+            Stream	inputStream,
+            Stream	keyIn)
+        {
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            PgpObjectFactory pgpFact = new PgpObjectFactory(inputStream);
+            PgpSignatureList p3 = null;
+            PgpObject o = pgpFact.NextPgpObject();
+            if (o is PgpCompressedData)
+            {
+                PgpCompressedData c1 = (PgpCompressedData)o;
+                pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+                p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+            }
+            else
+            {
+                p3 = (PgpSignatureList)o;
+            }
+
+            PgpPublicKeyRingBundle pgpPubRingCollection = new PgpPublicKeyRingBundle(
+				PgpUtilities.GetDecoderStream(keyIn));
+            Stream dIn = File.OpenRead(fileName);
+            PgpSignature sig = p3[0];
+            PgpPublicKey key = pgpPubRingCollection.GetPublicKey(sig.KeyId);
+            sig.InitVerify(key);
+
+			int ch;
+            while ((ch = dIn.ReadByte()) >= 0)
+            {
+                sig.Update((byte)ch);
+            }
+
+			dIn.Close();
+
+			if (sig.Verify())
+            {
+                Console.WriteLine("signature verified.");
+            }
+            else
+            {
+                Console.WriteLine("signature verification failed.");
+            }
+        }
+
+		private static void CreateSignature(
+			string	inputFileName,
+			string	keyFileName,
+			string	outputFileName,
+			char[]	pass,
+			bool	armor)
+		{
+			using (Stream keyIn = File.OpenRead(keyFileName),
+				output = File.OpenRead(outputFileName))
+			{
+				CreateSignature(inputFileName, keyIn, output, pass, armor);
+			}
+		}
+
+		private static void CreateSignature(
+			string	fileName,
+			Stream	keyIn,
+			Stream	outputStream,
+			char[]	pass,
+			bool	armor)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+            PgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn);
+            PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass);
+            PgpSignatureGenerator sGen = new PgpSignatureGenerator(
+				pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
+
+			BcpgOutputStream bOut = new BcpgOutputStream(outputStream);
+
+			Stream fIn = File.OpenRead(fileName);
+
+            int ch;
+            while ((ch = fIn.ReadByte()) >= 0)
+            {
+                sGen.Update((byte)ch);
+            }
+
+			fIn.Close();
+
+			sGen.Generate().Encode(bOut);
+
+			if (armor)
+			{
+				outputStream.Close();
+			}
+        }
+
+		public static void Main(
+            string[] args)
+        {
+            if (args[0].Equals("-s"))
+            {
+                if (args[1].Equals("-a"))
+                {
+					CreateSignature(args[2], args[3], args[2] + ".asc", args[4].ToCharArray(), true);
+                }
+                else
+                {
+					CreateSignature(args[1], args[2], args[1] + ".bpg", args[3].ToCharArray(), false);
+                }
+            }
+            else if (args[0].Equals("-v"))
+            {
+				VerifySignature(args[1], args[2], args[3]);
+			}
+            else
+            {
+                Console.Error.WriteLine("usage: DetachedSignatureProcessor [-s [-a] file keyfile passPhrase]|[-v file sigFile keyFile]");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/DirectKeySignature.cs b/crypto/test/src/openpgp/examples/DirectKeySignature.cs
new file mode 100644
index 000000000..a6bf8e755
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/DirectKeySignature.cs
@@ -0,0 +1,140 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Bcpg;
+using Org.BouncyCastle.Bcpg.Sig;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+	/**
+	* A simple utility class that directly signs a public key and writes the signed key to "SignedKey.asc" in 
+	* the current working directory.
+	* <p>
+	* To sign a key: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue.<br/>
+	* </p><p>
+	* To display a NotationData packet from a publicKey previously signed: DirectKeySignature signedPublicKeyFile.<br/>
+	* </p><p>
+	* <b>Note</b>: this example will silently overwrite files, nor does it pay any attention to
+	* the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+	* will have been used.
+	* </p>
+	*/
+	public class DirectKeySignature
+	{
+		public static void Main(
+			string[] args)
+		{
+			if (args.Length == 1)
+			{
+				Stream fis = File.OpenRead(args[0]);
+
+				PgpPublicKeyRing ring = new PgpPublicKeyRing(
+					PgpUtilities.GetDecoderStream(fis));
+				PgpPublicKey key = ring.GetPublicKey();
+
+				// iterate through all direct key signautures and look for NotationData subpackets
+				foreach (PgpSignature sig in key.GetSignaturesOfType(PgpSignature.DirectKey))
+				{
+					Console.WriteLine("Signature date is: "
+						+ sig.GetHashedSubPackets().GetSignatureCreationTime());
+
+					NotationData[] data = sig.GetHashedSubPackets().GetNotationDataOccurences();
+
+					for (int i = 0; i < data.Length; i++)
+					{
+						Console.WriteLine("Found Notaion named '" + data[i].GetNotationName()
+							+"' with content '" + data[i].GetNotationValue() + "'.");
+					}
+				}
+
+				fis.Close();
+			}
+			else if (args.Length == 5)
+			{
+				Stream secFis = File.OpenRead(args[0]);
+				Stream pubFis = File.OpenRead(args[2]);
+
+				// gather command line arguments
+				PgpSecretKeyRing secRing = new PgpSecretKeyRing(
+					PgpUtilities.GetDecoderStream(secFis));
+				String secretKeyPass = args[1];
+				PgpPublicKeyRing ring = new PgpPublicKeyRing(
+					PgpUtilities.GetDecoderStream(pubFis));
+				String notationName = args[3];
+				String notationValue = args[4];
+
+				// create the signed keyRing
+				PgpPublicKeyRing sRing = null;
+				sRing = new PgpPublicKeyRing(
+					new MemoryStream(
+						SignPublicKey(secRing.GetSecretKey(), secretKeyPass,
+							ring.GetPublicKey(), notationName, notationValue, true),
+						false));
+				ring = sRing;
+
+				secFis.Close();
+				pubFis.Close();
+
+				Stream fos = File.Create("SignedKey.asc");
+
+				// write the created keyRing to file
+				ArmoredOutputStream aOut = new ArmoredOutputStream(fos);
+				sRing.Encode(aOut);
+				aOut.Close();
+
+				// Note: ArmoredOutputStream.Close() leaves underlying stream open
+				fos.Close();
+			}
+			else
+			{
+				Console.Error.WriteLine("usage: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue");
+				Console.Error.WriteLine("or: DirectKeySignature signedPublicKeyFile");
+			}
+		}
+
+		private static byte[] SignPublicKey(
+			PgpSecretKey	secretKey,
+			string			secretKeyPass,
+			PgpPublicKey	keyToBeSigned,
+			string			notationName,
+			string			notationValue,
+			bool			armor)
+		{
+			Stream os = new MemoryStream();
+			if (armor)
+			{
+				os = new ArmoredOutputStream(os);
+			}
+
+			PgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey(
+				secretKeyPass.ToCharArray());
+
+			PgpSignatureGenerator sGen = new PgpSignatureGenerator(
+				secretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.DirectKey, pgpPrivKey);
+
+			BcpgOutputStream bOut = new BcpgOutputStream(os);
+
+			sGen.GenerateOnePassVersion(false).Encode(bOut);
+
+			PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
+
+			bool isHumanReadable = true;
+
+			spGen.SetNotationData(true, isHumanReadable, notationName, notationValue);
+
+			PgpSignatureSubpacketVector packetVector = spGen.Generate();
+			sGen.SetHashedSubpackets(packetVector);
+
+			bOut.Flush();
+
+			if (armor)
+			{
+				os.Close();
+			}
+
+			return PgpPublicKey.AddCertification(keyToBeSigned, sGen.Generate()).GetEncoded();
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs b/crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs
new file mode 100644
index 000000000..6040351a3
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs
@@ -0,0 +1,134 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that Generates a public/secret keyring containing a DSA signing
+    * key and an El Gamal key for encryption.
+    * <p>
+    * usage: DSAElGamalKeyRingGenerator [-a] identity passPhrase</p>
+    * <p>
+    * Where identity is the name to be associated with the public key. The keys are placed
+    * in the files pub.[asc|bpg] and secret.[asc|bpg].</p>
+    * <p>
+    * <b>Note</b>: this example encrypts the secret key using AES_256, many PGP products still
+    * do not support this, if you are having problems importing keys try changing the algorithm
+    * id to PgpEncryptedData.Cast5. CAST5 is more widelysupported.</p>
+    */
+    public sealed class DsaElGamalKeyRingGenerator
+    {
+        private DsaElGamalKeyRingGenerator()
+        {
+        }
+
+		private static void ExportKeyPair(
+            Stream					secretOut,
+            Stream					publicOut,
+            AsymmetricCipherKeyPair	dsaKp,
+            AsymmetricCipherKeyPair	elgKp,
+            string					identity,
+            char[]					passPhrase,
+            bool					armor)
+        {
+            if (armor)
+            {
+                secretOut = new ArmoredOutputStream(secretOut);
+            }
+
+			PgpKeyPair dsaKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.Dsa, dsaKp, DateTime.UtcNow);
+            PgpKeyPair elgKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalEncrypt, elgKp, DateTime.UtcNow);
+
+			PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, dsaKeyPair,
+				identity, SymmetricKeyAlgorithmTag.Aes256, passPhrase, true, null, null, new SecureRandom());
+
+			keyRingGen.AddSubKey(elgKeyPair);
+
+			keyRingGen.GenerateSecretKeyRing().Encode(secretOut);
+
+			if (armor)
+            {
+				secretOut.Close();
+				publicOut = new ArmoredOutputStream(publicOut);
+            }
+
+			keyRingGen.GeneratePublicKeyRing().Encode(publicOut);
+
+			if (armor)
+			{
+				publicOut.Close();
+			}
+        }
+
+		public static int Main(
+            string[] args)
+        {
+            if (args.Length < 2)
+            {
+                Console.WriteLine("DsaElGamalKeyRingGenerator [-a] identity passPhrase");
+                return 0;
+            }
+
+			IAsymmetricCipherKeyPairGenerator dsaKpg = GeneratorUtilities.GetKeyPairGenerator("DSA");
+            DsaParametersGenerator pGen = new DsaParametersGenerator();
+            pGen.Init(1024, 80, new SecureRandom());
+            DsaParameters dsaParams = pGen.GenerateParameters();
+            DsaKeyGenerationParameters kgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams);
+            dsaKpg.Init(kgp);
+
+
+			//
+            // this takes a while as the key generator has to Generate some DSA parameters
+            // before it Generates the key.
+            //
+            AsymmetricCipherKeyPair dsaKp = dsaKpg.GenerateKeyPair();
+
+
+			IAsymmetricCipherKeyPairGenerator elgKpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL");
+
+			BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
+            BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
+
+			ElGamalParameters elParams = new ElGamalParameters(p, g);
+            ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(new SecureRandom(), elParams);
+            elgKpg.Init(elKgp);
+
+			//
+            // this is quicker because we are using preGenerated parameters.
+            //
+            AsymmetricCipherKeyPair elgKp = elgKpg.GenerateKeyPair();
+
+			Stream out1, out2;
+			if (args[0].Equals("-a"))
+            {
+                if (args.Length < 3)
+                {
+                    Console.WriteLine("DSAElGamalKeyRingGenerator [-a] identity passPhrase");
+                    return 0;
+                }
+
+				out1 = File.Create("secret.asc");
+                out2 = File.Create("pub.asc");
+
+				ExportKeyPair(out1, out2, dsaKp, elgKp, args[1], args[2].ToCharArray(), true);
+            }
+            else
+            {
+                out1 = File.Create("secret.bpg");
+                out2 = File.Create("pub.bpg");
+
+				ExportKeyPair(out1, out2, dsaKp, elgKp, args[0], args[1].ToCharArray(), false);
+            }
+			out1.Close();
+			out2.Close();
+			return 0;
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs b/crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs
new file mode 100644
index 000000000..c77408b1f
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs
@@ -0,0 +1,259 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that encrypts/decrypts public key based
+    * encryption files.
+    * <p>
+    * To encrypt a file: KeyBasedFileProcessor -e [-a|-ai] fileName publicKeyFile.<br/>
+    * If -a is specified the output file will be "ascii-armored".
+    * If -i is specified the output file will be have integrity checking added.</p>
+    * <p>
+    * To decrypt: KeyBasedFileProcessor -d fileName secretKeyFile passPhrase.</p>
+    * <p>
+	* Note 1: this example will silently overwrite files, nor does it pay any attention to
+	* the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+	* will have been used.</p>
+	* <p>
+	* Note 2: if an empty file name has been specified in the literal data object contained in the
+	* encrypted packet a file with the name filename.out will be generated in the current working directory.</p>
+    */
+    public sealed class KeyBasedFileProcessor
+    {
+        private KeyBasedFileProcessor()
+        {
+        }
+
+		private static void DecryptFile(
+			string	inputFileName,
+			string	keyFileName,
+			char[]	passwd,
+			string	defaultFileName)
+		{
+			using (Stream input = File.OpenRead(inputFileName),
+			       keyIn = File.OpenRead(keyFileName))
+			{
+				DecryptFile(input, keyIn, passwd, defaultFileName);
+			}
+		}
+
+		/**
+		 * decrypt the passed in message stream
+		 */
+		private static void DecryptFile(
+			Stream	inputStream,
+			Stream	keyIn,
+			char[]	passwd,
+			string	defaultFileName)
+		{
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            try
+            {
+                PgpObjectFactory pgpF = new PgpObjectFactory(inputStream);
+                PgpEncryptedDataList enc;
+
+                PgpObject o = pgpF.NextPgpObject();
+                //
+                // the first object might be a PGP marker packet.
+                //
+                if (o is PgpEncryptedDataList)
+                {
+                    enc = (PgpEncryptedDataList)o;
+                }
+                else
+                {
+                    enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
+                }
+
+                //
+                // find the secret key
+                //
+                PgpPrivateKey sKey = null;
+                PgpPublicKeyEncryptedData pbe = null;
+				PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
+					PgpUtilities.GetDecoderStream(keyIn));
+
+				foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
+                {
+                    sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd);
+
+                    if (sKey != null)
+                    {
+                        pbe = pked;
+                        break;
+                    }
+                }
+
+				if (sKey == null)
+                {
+                    throw new ArgumentException("secret key for message not found.");
+                }
+
+                Stream clear = pbe.GetDataStream(sKey);
+
+                PgpObjectFactory plainFact = new PgpObjectFactory(clear);
+
+                PgpObject message = plainFact.NextPgpObject();
+
+                if (message is PgpCompressedData)
+                {
+                    PgpCompressedData cData = (PgpCompressedData)message;
+                    PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream());
+
+                    message = pgpFact.NextPgpObject();
+                }
+
+                if (message is PgpLiteralData)
+                {
+                    PgpLiteralData ld = (PgpLiteralData)message;
+
+					string outFileName = ld.FileName;
+					if (outFileName.Length == 0)
+					{
+						outFileName = defaultFileName;
+					}
+
+					Stream fOut = File.Create(outFileName);
+					Stream unc = ld.GetInputStream();
+					Streams.PipeAll(unc, fOut);
+					fOut.Close();
+                }
+                else if (message is PgpOnePassSignatureList)
+                {
+                    throw new PgpException("encrypted message contains a signed message - not literal data.");
+                }
+                else
+                {
+                    throw new PgpException("message is not a simple encrypted file - type unknown.");
+                }
+
+                if (pbe.IsIntegrityProtected())
+                {
+                    if (!pbe.Verify())
+                    {
+                        Console.Error.WriteLine("message failed integrity check");
+                    }
+                    else
+                    {
+                        Console.Error.WriteLine("message integrity check passed");
+                    }
+                }
+                else
+                {
+                    Console.Error.WriteLine("no message integrity check");
+                }
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+		
+		private static void EncryptFile(
+			string	outputFileName,
+			string	inputFileName,
+			string	encKeyFileName,
+			bool	armor,
+			bool	withIntegrityCheck)
+		{
+			PgpPublicKey encKey = PgpExampleUtilities.ReadPublicKey(encKeyFileName);
+
+			using (Stream output = File.Create(outputFileName))
+			{
+				EncryptFile(output, inputFileName, encKey, armor, withIntegrityCheck);
+			}
+		}
+
+        private static void EncryptFile(
+            Stream			outputStream,
+            string			fileName,
+            PgpPublicKey	encKey,
+            bool			armor,
+            bool			withIntegrityCheck)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+            try
+            {
+            	byte[] bytes = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip);
+
+				PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(
+					SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
+				encGen.AddMethod(encKey);
+
+				Stream cOut = encGen.Open(outputStream, bytes.Length);
+
+				cOut.Write(bytes, 0, bytes.Length);
+				cOut.Close();
+
+				if (armor)
+				{
+					outputStream.Close();
+				}
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            if (args.Length == 0)
+            {
+                Console.Error.WriteLine("usage: KeyBasedFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
+                return;
+            }
+
+            if (args[0].Equals("-e"))
+            {
+                if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia"))
+                {
+					EncryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].IndexOf('i') > 0));
+                }
+                else if (args[1].Equals("-i"))
+                {
+					EncryptFile(args[2] + ".bpg", args[2], args[3], false, true);
+                }
+                else
+                {
+					EncryptFile(args[1] + ".bpg", args[1], args[2], false, false);
+                }
+            }
+            else if (args[0].Equals("-d"))
+            {
+				DecryptFile(args[1], args[2], args[3].ToCharArray(), new FileInfo(args[1]).Name + ".out");
+            }
+            else
+            {
+                Console.Error.WriteLine("usage: KeyBasedFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs b/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs
new file mode 100644
index 000000000..7fb00a3b7
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs
@@ -0,0 +1,267 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that encrypts/decrypts public key based
+    * encryption large files.
+    * <p>
+    * To encrypt a file: KeyBasedLargeFileProcessor -e [-a|-ai] fileName publicKeyFile.<br/>
+    * If -a is specified the output file will be "ascii-armored".
+    * If -i is specified the output file will be have integrity checking added.</p>
+    * <p>
+    * To decrypt: KeyBasedLargeFileProcessor -d fileName secretKeyFile passPhrase.</p>
+    * <p>
+    * Note 1: this example will silently overwrite files, nor does it pay any attention to
+    * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+    * will have been used.</p>
+    * <p>
+    * Note 2: this example Generates partial packets to encode the file, the output it Generates
+    * will not be readable by older PGP products or products that don't support partial packet
+    * encoding.</p>
+	* <p>
+	* Note 3: if an empty file name has been specified in the literal data object contained in the
+	* encrypted packet a file with the name filename.out will be generated in the current working directory.</p>
+    */
+    public sealed class KeyBasedLargeFileProcessor
+    {
+        private KeyBasedLargeFileProcessor()
+        {
+        }
+
+		private static void DecryptFile(
+			string	inputFileName,
+			string	keyFileName,
+			char[]	passwd,
+			string	defaultFileName)
+		{
+			using (Stream input = File.OpenRead(inputFileName),
+			       keyIn = File.OpenRead(keyFileName))
+			{
+				DecryptFile(input, keyIn, passwd, defaultFileName);
+			}
+		}
+
+		/**
+        * decrypt the passed in message stream
+        */
+        private static void DecryptFile(
+            Stream	inputStream,
+            Stream	keyIn,
+			char[]	passwd,
+			string	defaultFileName)
+		{
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            try
+            {
+                PgpObjectFactory        pgpF = new PgpObjectFactory(inputStream);
+                PgpEncryptedDataList    enc;
+
+                PgpObject o = pgpF.NextPgpObject();
+                //
+                // the first object might be a PGP marker packet.
+                //
+                if (o is PgpEncryptedDataList)
+                {
+                    enc = (PgpEncryptedDataList)o;
+                }
+                else
+                {
+                    enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
+                }
+
+                //
+                // find the secret key
+                //
+                PgpPrivateKey sKey = null;
+                PgpPublicKeyEncryptedData pbe = null;
+				PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
+					PgpUtilities.GetDecoderStream(keyIn));
+
+				foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
+                {
+                    sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd);
+
+                    if (sKey != null)
+                    {
+                        pbe = pked;
+                        break;
+                    }
+                }
+
+                if (sKey == null)
+                {
+                    throw new ArgumentException("secret key for message not found.");
+                }
+
+                Stream clear = pbe.GetDataStream(sKey);
+
+                PgpObjectFactory plainFact = new PgpObjectFactory(clear);
+
+                PgpCompressedData cData = (PgpCompressedData) plainFact.NextPgpObject();
+
+                PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream());
+
+                PgpObject message = pgpFact.NextPgpObject();
+
+                if (message is PgpLiteralData)
+                {
+                    PgpLiteralData ld = (PgpLiteralData)message;
+
+					string outFileName = ld.FileName;
+					if (outFileName.Length == 0)
+					{
+						outFileName = defaultFileName;
+					}
+
+					Stream fOut = File.Create(outFileName);
+                    Stream unc = ld.GetInputStream();
+					Streams.PipeAll(unc, fOut);
+					fOut.Close();
+                }
+                else if (message is PgpOnePassSignatureList)
+                {
+                    throw new PgpException("encrypted message contains a signed message - not literal data.");
+                }
+                else
+                {
+                    throw new PgpException("message is not a simple encrypted file - type unknown.");
+                }
+
+                if (pbe.IsIntegrityProtected())
+                {
+                    if (!pbe.Verify())
+                    {
+                        Console.Error.WriteLine("message failed integrity check");
+                    }
+                    else
+                    {
+                        Console.Error.WriteLine("message integrity check passed");
+                    }
+                }
+                else
+                {
+                    Console.Error.WriteLine("no message integrity check");
+                }
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+
+		private static void EncryptFile(
+			string	outputFileName,
+			string	inputFileName,
+			string	encKeyFileName,
+			bool	armor,
+			bool	withIntegrityCheck)
+		{
+			PgpPublicKey encKey = PgpExampleUtilities.ReadPublicKey(encKeyFileName);
+
+			using (Stream output = File.Create(outputFileName))
+			{
+				EncryptFile(output, inputFileName, encKey, armor, withIntegrityCheck);
+			}
+		}
+
+        private static void EncryptFile(
+            Stream			outputStream,
+            string			fileName,
+            PgpPublicKey	encKey,
+            bool			armor,
+            bool			withIntegrityCheck)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+            try
+            {
+                PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
+
+                cPk.AddMethod(encKey);
+
+                Stream cOut = cPk.Open(outputStream, new byte[1 << 16]);
+
+                PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(
+					CompressionAlgorithmTag.Zip);
+
+				PgpUtilities.WriteFileToLiteralData(
+					comData.Open(cOut),
+					PgpLiteralData.Binary,
+					new FileInfo(fileName),
+					new byte[1 << 16]);
+
+				comData.Close();
+
+				cOut.Close();
+
+				if (armor)
+				{
+					outputStream.Close();
+				}
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            if (args.Length == 0)
+            {
+                Console.Error.WriteLine("usage: KeyBasedLargeFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
+                return;
+            }
+
+            if (args[0].Equals("-e"))
+            {
+                if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia"))
+                {
+					EncryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].IndexOf('i') > 0));
+                }
+                else if (args[1].Equals("-i"))
+                {
+					EncryptFile(args[2] + ".bpg", args[2], args[3], false, true);
+                }
+                else
+                {
+					EncryptFile(args[1] + ".bpg", args[1], args[2], false, false);
+                }
+            }
+            else if (args[0].Equals("-d"))
+            {
+				DecryptFile(args[1], args[2], args[3].ToCharArray(), new FileInfo(args[1]).Name + ".out");
+            }
+            else
+            {
+                Console.Error.WriteLine("usage: KeyBasedLargeFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/PbeFileProcessor.cs b/crypto/test/src/openpgp/examples/PbeFileProcessor.cs
new file mode 100644
index 000000000..66b1cc4ed
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/PbeFileProcessor.cs
@@ -0,0 +1,183 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that encrypts/decrypts password based
+    * encryption files.
+    * <p>
+    * To encrypt a file: PBEFileProcessor -e [-ai] fileName passPhrase.<br/>
+    * If -a is specified the output file will be "ascii-armored".<br/>
+    * If -i is specified the output file will be "integrity protected".</p>
+    * <p>
+    * To decrypt: PBEFileProcessor -d fileName passPhrase.</p>
+    * <p>
+    * Note: this example will silently overwrite files, nor does it pay any attention to
+    * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+    * will have been used.</p>
+    */
+    public sealed class PbeFileProcessor
+    {
+        private PbeFileProcessor() {}
+
+		private static void DecryptFile(string inputFileName, char[] passPhrase)
+		{
+			using (Stream input = File.OpenRead(inputFileName))
+			{
+				DecryptFile(input, passPhrase);
+			}
+		}
+
+        /**
+        * decrypt the passed in message stream
+        */
+        private static void DecryptFile(
+            Stream	inputStream,
+            char[]	passPhrase)
+        {
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+			PgpObjectFactory pgpF = new PgpObjectFactory(inputStream);
+            PgpObject o = pgpF.NextPgpObject();
+
+            //
+            // the first object might be a PGP marker packet.
+            //
+			PgpEncryptedDataList enc = o as PgpEncryptedDataList;
+            if (enc == null)
+            {
+                enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
+            }
+
+            PgpPbeEncryptedData pbe = (PgpPbeEncryptedData)enc[0];
+
+            Stream clear = pbe.GetDataStream(passPhrase);
+
+            PgpObjectFactory pgpFact = new PgpObjectFactory(clear);
+
+			//
+			// if we're trying to read a file generated by someone other than us
+			// the data might not be compressed, so we check the return type from
+			// the factory and behave accordingly.
+			//
+			o = pgpFact.NextPgpObject();
+			if (o is PgpCompressedData)
+			{
+				PgpCompressedData cData = (PgpCompressedData) o;
+				pgpFact = new PgpObjectFactory(cData.GetDataStream());
+				o = pgpFact.NextPgpObject();
+			}
+
+			PgpLiteralData ld = (PgpLiteralData) o;
+			Stream unc = ld.GetInputStream();
+            Stream fOut = File.Create(ld.FileName);
+			Streams.PipeAll(unc, fOut);
+			fOut.Close();
+
+			if (pbe.IsIntegrityProtected())
+            {
+                if (!pbe.Verify())
+                {
+                    Console.Error.WriteLine("message failed integrity check");
+                }
+                else
+                {
+                    Console.Error.WriteLine("message integrity check passed");
+                }
+            }
+            else
+            {
+                Console.Error.WriteLine("no message integrity check");
+            }
+        }
+
+		private static void EncryptFile(
+			string	outputFileName,
+			string	inputFileName,
+			char[]	passPhrase,
+			bool	armor,
+			bool	withIntegrityCheck)
+		{
+			using (Stream output = File.Create(outputFileName))
+			{
+				EncryptFile(output, inputFileName, passPhrase, armor, withIntegrityCheck);
+			}
+		}
+
+        private static void EncryptFile(
+            Stream	outputStream,
+            string	fileName,
+            char[]	passPhrase,
+            bool	armor,
+            bool	withIntegrityCheck)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+			try
+            {
+				byte[] compressedData = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip);
+
+				PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(
+					SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
+				encGen.AddMethod(passPhrase);
+
+				Stream encOut = encGen.Open(outputStream, compressedData.Length);
+
+	            encOut.Write(compressedData, 0, compressedData.Length);
+				encOut.Close();
+
+				if (armor)
+				{
+					outputStream.Close();
+				}
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+
+		public static void Main(
+			string[] args)
+        {
+            if (args[0].Equals("-e"))
+            {
+                if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia"))
+                {
+					EncryptFile(args[2] + ".asc", args[2], args[3].ToCharArray(), true, (args[1].IndexOf('i') > 0));
+                }
+                else if (args[1].Equals("-i"))
+                {
+					EncryptFile(args[2] + ".bpg", args[2], args[3].ToCharArray(), false, true);
+                }
+                else
+                {
+					EncryptFile(args[1] + ".bpg", args[1], args[2].ToCharArray(), false, false);
+                }
+            }
+            else if (args[0].Equals("-d"))
+            {
+				DecryptFile(args[1], args[2].ToCharArray());
+            }
+            else
+            {
+                Console.Error.WriteLine("usage: PbeFileProcessor -e [-ai]|-d file passPhrase");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/PgpExampleUtilities.cs b/crypto/test/src/openpgp/examples/PgpExampleUtilities.cs
new file mode 100644
index 000000000..fd371d7af
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/PgpExampleUtilities.cs
@@ -0,0 +1,123 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+	internal class PgpExampleUtilities
+	{
+		internal static byte[] CompressFile(string fileName, CompressionAlgorithmTag algorithm)
+		{
+			MemoryStream bOut = new MemoryStream();
+			PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(algorithm);
+			PgpUtilities.WriteFileToLiteralData(comData.Open(bOut), PgpLiteralData.Binary,
+				new FileInfo(fileName));
+			comData.Close();
+			return bOut.ToArray();
+		}
+
+		/**
+		 * Search a secret key ring collection for a secret key corresponding to keyID if it
+		 * exists.
+		 * 
+		 * @param pgpSec a secret key ring collection.
+		 * @param keyID keyID we want.
+		 * @param pass passphrase to decrypt secret key with.
+		 * @return
+		 * @throws PGPException
+		 * @throws NoSuchProviderException
+		 */
+		internal static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyID, char[] pass)
+		{
+			PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyID);
+
+			if (pgpSecKey == null)
+			{
+				return null;
+			}
+
+			return pgpSecKey.ExtractPrivateKey(pass);
+		}
+
+		internal static PgpPublicKey ReadPublicKey(string fileName)
+		{
+			using (Stream keyIn = File.OpenRead(fileName))
+			{
+				return ReadPublicKey(keyIn);
+			}
+		}
+
+		/**
+		 * A simple routine that opens a key ring file and loads the first available key
+		 * suitable for encryption.
+		 * 
+		 * @param input
+		 * @return
+		 * @throws IOException
+		 * @throws PGPException
+		 */
+		internal static PgpPublicKey ReadPublicKey(Stream input)
+		{
+			PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(
+				PgpUtilities.GetDecoderStream(input));
+
+			//
+			// we just loop through the collection till we find a key suitable for encryption, in the real
+			// world you would probably want to be a bit smarter about this.
+			//
+
+			foreach (PgpPublicKeyRing keyRing in pgpPub.GetKeyRings())
+			{
+				foreach (PgpPublicKey key in keyRing.GetPublicKeys())
+				{
+					if (key.IsEncryptionKey)
+					{
+						return key;
+					}
+				}
+			}
+
+			throw new ArgumentException("Can't find encryption key in key ring.");
+		}
+
+		internal static PgpSecretKey ReadSecretKey(string fileName)
+		{
+			using (Stream keyIn = File.OpenRead(fileName))
+			{
+				return ReadSecretKey(keyIn);
+			}
+		}
+
+		/**
+		 * A simple routine that opens a key ring file and loads the first available key
+		 * suitable for signature generation.
+		 * 
+		 * @param input stream to read the secret key ring collection from.
+		 * @return a secret key.
+		 * @throws IOException on a problem with using the input stream.
+		 * @throws PGPException if there is an issue parsing the input stream.
+		 */
+		internal static PgpSecretKey ReadSecretKey(Stream input)
+		{
+			PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
+				PgpUtilities.GetDecoderStream(input));
+
+			//
+			// we just loop through the collection till we find a key suitable for encryption, in the real
+			// world you would probably want to be a bit smarter about this.
+			//
+
+			foreach (PgpSecretKeyRing keyRing in pgpSec.GetKeyRings())
+			{
+				foreach (PgpSecretKey key in keyRing.GetSecretKeys())
+				{
+					if (key.IsSigningKey)
+					{
+						return key;
+					}
+				}
+			}
+
+			throw new ArgumentException("Can't find signing key in key ring.");
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs b/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs
new file mode 100644
index 000000000..bb6108f2d
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Asn1.Utilities;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * Basic class which just lists the contents of the public key file passed
+    * as an argument. If the file contains more than one "key ring" they are
+    * listed in the order found.
+    */
+    public sealed class PublicKeyRingDump
+    {
+        private PublicKeyRingDump()
+        {
+        }
+
+        public static string GetAlgorithm(
+            PublicKeyAlgorithmTag algId)
+        {
+            switch (algId)
+            {
+                case PublicKeyAlgorithmTag.RsaGeneral:
+                    return "RsaGeneral";
+                case PublicKeyAlgorithmTag.RsaEncrypt:
+                    return "RsaEncrypt";
+                case PublicKeyAlgorithmTag.RsaSign:
+                    return "RsaSign";
+                case PublicKeyAlgorithmTag.ElGamalEncrypt:
+                    return "ElGamalEncrypt";
+                case PublicKeyAlgorithmTag.Dsa:
+                    return "DSA";
+                case PublicKeyAlgorithmTag.EC:
+                    return "EC";
+                case PublicKeyAlgorithmTag.ECDsa:
+                    return "ECDSA";
+                case PublicKeyAlgorithmTag.ElGamalGeneral:
+                    return "ElGamalGeneral";
+                case PublicKeyAlgorithmTag.DiffieHellman:
+                    return "DiffieHellman";
+            }
+
+            return "unknown";
+        }
+
+		public static void Main(
+			string[] args)
+        {
+			Stream fs = File.OpenRead(args[0]);
+
+			//
+            // Read the public key rings
+            //
+            PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(
+                PgpUtilities.GetDecoderStream(fs));
+
+			fs.Close();
+
+			foreach (PgpPublicKeyRing pgpPub in pubRings.GetKeyRings())
+            {
+                try
+                {
+					//PgpPublicKey pubKey =
+					pgpPub.GetPublicKey();
+                }
+                catch (Exception e)
+                {
+                    Console.Error.WriteLine(e.Message);
+                    Console.Error.WriteLine(e.StackTrace);
+                    continue;
+                }
+
+				bool first = true;
+
+				foreach (PgpPublicKey pgpKey in pgpPub.GetPublicKeys())
+                {
+                    if (first)
+                    {
+                        Console.WriteLine("Key ID: " +  pgpKey.KeyId.ToString("X"));
+                        first = false;
+                    }
+                    else
+                    {
+                        Console.WriteLine("Key ID: " + pgpKey.KeyId.ToString("X") + " (subkey)");
+                    }
+
+					Console.WriteLine("            Algorithm: " + GetAlgorithm(pgpKey.Algorithm));
+                    Console.WriteLine("            Fingerprint: " + Hex.ToHexString(pgpKey.GetFingerprint()));
+                }
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs b/crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs
new file mode 100644
index 000000000..284118b99
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs
@@ -0,0 +1,115 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that Generates a RSA PgpPublicKey/PgpSecretKey pair.
+    * <p>
+    * usage: RsaKeyRingGenerator [-a] identity passPhrase</p>
+    * <p>
+    * Where identity is the name to be associated with the public key. The keys are placed
+    * in the files pub.[asc|bpg] and secret.[asc|bpg].</p>
+    */
+    public sealed class RsaKeyRingGenerator
+    {
+        private RsaKeyRingGenerator()
+        {
+        }
+
+		private static void ExportKeyPair(
+            Stream                   secretOut,
+            Stream                   publicOut,
+            AsymmetricKeyParameter   publicKey,
+            AsymmetricKeyParameter   privateKey,
+            string                   identity,
+            char[]                   passPhrase,
+            bool                     armor)
+        {
+			if (armor)
+			{
+				secretOut = new ArmoredOutputStream(secretOut);
+			}
+
+			PgpSecretKey secretKey = new PgpSecretKey(
+                PgpSignature.DefaultCertification,
+                PublicKeyAlgorithmTag.RsaGeneral,
+                publicKey,
+                privateKey,
+                DateTime.UtcNow,
+                identity,
+                SymmetricKeyAlgorithmTag.Cast5,
+                passPhrase,
+                null,
+                null,
+                new SecureRandom()
+                );
+
+            secretKey.Encode(secretOut);
+
+			if (armor)
+            {
+				secretOut.Close();
+				publicOut = new ArmoredOutputStream(publicOut);
+            }
+
+            PgpPublicKey key = secretKey.PublicKey;
+
+            key.Encode(publicOut);
+
+			if (armor)
+			{
+				publicOut.Close();
+			}
+        }
+
+		public static int Main(
+			string[] args)
+        {
+            IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA");
+
+            kpg.Init(new RsaKeyGenerationParameters(
+				BigInteger.ValueOf(0x10001), new SecureRandom(), 1024, 25));
+
+            AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();
+
+            if (args.Length < 2)
+            {
+                Console.WriteLine("RsaKeyPairGenerator [-a] identity passPhrase");
+                return 0;
+            }
+
+			Stream out1, out2;
+            if (args[0].Equals("-a"))
+            {
+                if (args.Length < 3)
+                {
+                    Console.WriteLine("RsaKeyPairGenerator [-a] identity passPhrase");
+					return 0;
+				}
+
+				out1 = File.Create("secret.asc");
+                out2 = File.Create("pub.asc");
+
+                ExportKeyPair(out1, out2, kp.Public, kp.Private, args[1], args[2].ToCharArray(), true);
+            }
+            else
+            {
+                out1 = File.Create("secret.bpg");
+                out2 = File.Create("pub.bpg");
+
+                ExportKeyPair(out1, out2, kp.Public, kp.Private, args[0], args[1].ToCharArray(), false);
+            }
+			out1.Close();
+			out2.Close();
+			return 0;
+		}
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/SignedFileProcessor.cs b/crypto/test/src/openpgp/examples/SignedFileProcessor.cs
new file mode 100644
index 000000000..1ad0d102b
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/SignedFileProcessor.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Collections;
+using System.IO;
+
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that signs and verifies files.
+    * <p>
+    * To sign a file: SignedFileProcessor -s [-a] fileName secretKey passPhrase.<br/>
+    * If -a is specified the output file will be "ascii-armored".</p>
+    * <p>
+    * To decrypt: SignedFileProcessor -v fileName publicKeyFile.</p>
+    * <p>
+    * <b>Note</b>: this example will silently overwrite files, nor does it pay any attention to
+    * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+    * will have been used.</p>
+    * <p>
+    * <b>Note</b>: the example also makes use of PGP compression. If you are having difficulty Getting it
+    * to interoperate with other PGP programs try removing the use of compression first.</p>
+    */
+    public sealed class SignedFileProcessor
+    {
+        private SignedFileProcessor() {}
+
+		/**
+        * verify the passed in file as being correctly signed.
+        */
+        private static void VerifyFile(
+            Stream	inputStream,
+            Stream	keyIn)
+        {
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            PgpObjectFactory			pgpFact = new PgpObjectFactory(inputStream);
+            PgpCompressedData			c1 = (PgpCompressedData) pgpFact.NextPgpObject();
+            pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+            PgpOnePassSignatureList		p1 = (PgpOnePassSignatureList) pgpFact.NextPgpObject();
+            PgpOnePassSignature			ops = p1[0];
+
+            PgpLiteralData				p2 = (PgpLiteralData) pgpFact.NextPgpObject();
+            Stream						dIn = p2.GetInputStream();
+            PgpPublicKeyRingBundle		pgpRing = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(keyIn));
+            PgpPublicKey				key = pgpRing.GetPublicKey(ops.KeyId);
+            Stream						fos = File.Create(p2.FileName);
+
+			ops.InitVerify(key);
+
+			int ch;
+			while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte)ch);
+                fos.WriteByte((byte) ch);
+            }
+            fos.Close();
+
+            PgpSignatureList	p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+			PgpSignature		firstSig = p3[0];
+            if (ops.Verify(firstSig))
+            {
+                Console.Out.WriteLine("signature verified.");
+            }
+            else
+            {
+                Console.Out.WriteLine("signature verification failed.");
+            }
+        }
+
+        /**
+        * Generate an encapsulated signed file.
+        *
+        * @param fileName
+        * @param keyIn
+        * @param outputStream
+        * @param pass
+        * @param armor
+        */
+        private static void SignFile(
+            string	fileName,
+            Stream	keyIn,
+            Stream	outputStream,
+            char[]	pass,
+            bool	armor,
+			bool	compress)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+            PgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn);
+            PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass);
+            PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
+
+            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
+            foreach (string userId in pgpSec.PublicKey.GetUserIds())
+            {
+                PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
+                spGen.SetSignerUserId(false, userId);
+                sGen.SetHashedSubpackets(spGen.Generate());
+                // Just the first one!
+                break;
+            }
+
+            Stream cOut = outputStream;
+			PgpCompressedDataGenerator cGen = null;
+			if (compress)
+			{
+				cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib);
+
+				cOut = cGen.Open(cOut);
+			}
+
+			BcpgOutputStream bOut = new BcpgOutputStream(cOut);
+
+            sGen.GenerateOnePassVersion(false).Encode(bOut);
+
+            FileInfo					file = new FileInfo(fileName);
+            PgpLiteralDataGenerator     lGen = new PgpLiteralDataGenerator();
+            Stream						lOut = lGen.Open(bOut, PgpLiteralData.Binary, file);
+            FileStream					fIn = file.OpenRead();
+            int                         ch = 0;
+
+			while ((ch = fIn.ReadByte()) >= 0)
+            {
+                lOut.WriteByte((byte) ch);
+                sGen.Update((byte)ch);
+            }
+
+			fIn.Close();
+			lGen.Close();
+
+			sGen.Generate().Encode(bOut);
+
+			if (cGen != null)
+			{
+				cGen.Close();
+			}
+
+			if (armor)
+			{
+				outputStream.Close();
+			}
+        }
+
+		public static void Main(
+            string[] args)
+        {
+			// TODO provide command-line option to determine whether to use compression in SignFile
+            if (args[0].Equals("-s"))
+            {
+				Stream keyIn, fos;
+                if (args[1].Equals("-a"))
+                {
+                    keyIn = File.OpenRead(args[3]);
+                    fos = File.Create(args[2] + ".asc");
+
+					SignFile(args[2], keyIn, fos, args[4].ToCharArray(), true, true);
+                }
+                else
+                {
+                    keyIn = File.OpenRead(args[2]);
+                    fos = File.Create(args[1] + ".bpg");
+
+					SignFile(args[1], keyIn, fos, args[3].ToCharArray(), false, true);
+                }
+				keyIn.Close();
+				fos.Close();
+            }
+            else if (args[0].Equals("-v"))
+            {
+				using (Stream fis = File.OpenRead(args[1]),
+                	keyIn = File.OpenRead(args[2]))
+				{
+					VerifyFile(fis, keyIn);
+				}
+			}
+            else
+            {
+                Console.Error.WriteLine("usage: SignedFileProcessor -v|-s [-a] file keyfile [passPhrase]");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/test/AllTests.cs b/crypto/test/src/openpgp/examples/test/AllTests.cs
new file mode 100644
index 000000000..180d2fa80
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/test/AllTests.cs
@@ -0,0 +1,403 @@
+using System;
+using System.IO;
+
+using NUnit.Core;
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples.Tests
+{
+	[TestFixture]
+	public class AllTests
+	{
+		private static readonly byte[] clearSignedPublicKey = Base64.Decode(
+			  "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+"
+			+ "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1"
+			+ "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO"
+			+ "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7"
+			+ "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4"
+			+ "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp"
+			+ "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD"
+			+ "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR"
+			+ "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch"
+			+ "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg"
+			+ "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r"
+			+ "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1"
+			+ "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz"
+			+ "oztls8tuWA0OGHba9XfX9rfgorACAAM=");
+
+		private static readonly string crOnlyMessage =
+			"\r"
+			+ " hello world!\r"
+			+ "\r"
+			+ "- dash\r";
+
+		private static readonly string nlOnlyMessage =
+			"\n"
+			+ " hello world!\n"
+			+ "\n"
+			+ "- dash\n";
+
+		private static readonly string crNlMessage =
+			"\r\n"
+			+ " hello world!\r\n"
+			+ "\r\n"
+			+ "- dash\r\n";
+
+		private static readonly string crNlMessageTrailingWhiteSpace =
+			"\r\n"
+			+ " hello world! \t\r\n"
+			+ "\r\n"
+			+ "\r\n";
+
+		private static readonly string crOnlySignedMessage =
+			"-----BEGIN PGP SIGNED MESSAGE-----\r"
+			+ "Hash: SHA256\r"
+			+ "\r"
+			+ "\r"
+			+ " hello world!\r"
+			+ "\r"
+			+ "- - dash\r"
+			+ "-----BEGIN PGP SIGNATURE-----\r"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r"
+			+ "\r"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r"
+			+ "=84Nd\r"
+			+ "-----END PGP SIGNATURE-----\r";
+
+		private static readonly string nlOnlySignedMessage =
+			"-----BEGIN PGP SIGNED MESSAGE-----\n"
+			+ "Hash: SHA256\n"
+			+ "\n"
+			+ "\n"
+			+ " hello world!\n"
+			+ "\n"
+			+ "- - dash\n"
+			+ "-----BEGIN PGP SIGNATURE-----\n"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\n"
+			+ "\n"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n"
+			+ "=84Nd\n"
+			+ "-----END PGP SIGNATURE-----\n";
+
+		private static readonly string crNlSignedMessage =
+			"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
+			+ "Hash: SHA256\r\n"
+			+ "\r\n"
+			+ "\r\n"
+			+ " hello world!\r\n"
+			+ "\r\n"
+			+ "- - dash\r\n"
+			+ "-----BEGIN PGP SIGNATURE-----\r\n"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
+			+ "\r\n"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
+			+ "=84Nd\r"
+			+ "-----END PGP SIGNATURE-----\r\n";
+
+		private static readonly string crNlSignedMessageTrailingWhiteSpace =
+			"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
+			+ "Hash: SHA256\r\n"
+			+ "\r\n"
+			+ "\r\n"
+			+ " hello world! \t\r\n"
+			+ "\r\n"
+			+ "- - dash\r\n"
+			+ "-----BEGIN PGP SIGNATURE-----\r\n"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
+			+ "\r\n"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
+			+ "=84Nd\r"
+			+ "-----END PGP SIGNATURE-----\r\n";
+
+		private TextWriter _oldOut;
+		private TextWriter _oldErr;
+
+		private MemoryStream _currentOut;
+		private MemoryStream _currentErr;
+
+		[SetUp]
+		public void SetUp()
+		{
+			_oldOut = Console.Out;
+			_oldErr = Console.Error;
+			_currentOut = new MemoryStream();
+			_currentErr = new MemoryStream();
+
+			Console.SetOut(new StreamWriter(_currentOut));
+			Console.SetError(new StreamWriter(_currentErr));
+		}
+
+		[TearDown]
+		public void TearDown()
+		{
+			Console.SetOut(_oldOut);
+			Console.SetError(_oldErr);
+		}
+
+		[Test]
+		public void TestRsaKeyGeneration() 
+		{
+			RsaKeyRingGenerator.Main(new string[] { "test", "password" });
+
+			CreateSmallTestInput();
+			CreateLargeTestInput();
+
+			CheckSigning("bpg");
+			CheckKeyBasedEncryption("bpg");
+			CheckLargeKeyBasedEncryption("bpg");
+
+			RsaKeyRingGenerator.Main(new string[] { "-a", "test", "password" });
+
+			CheckSigning("asc");
+			CheckKeyBasedEncryption("asc");
+			CheckLargeKeyBasedEncryption("asc");
+		}
+
+		[Test]
+		public void TestDsaElGamalKeyGeneration() 
+		{
+			DsaElGamalKeyRingGenerator.Main(new string[] { "test", "password" });
+
+			CreateSmallTestInput();
+			CreateLargeTestInput();
+
+			CheckSigning("bpg");
+			CheckKeyBasedEncryption("bpg");
+			CheckLargeKeyBasedEncryption("bpg");
+
+			DsaElGamalKeyRingGenerator.Main(new string[] { "-a", "test", "password" });
+
+			CheckSigning("asc");
+			CheckKeyBasedEncryption("asc");
+			CheckLargeKeyBasedEncryption("asc");
+		}
+
+		[Test]
+		public void TestPbeEncryption() 
+		{
+			Console.Error.Flush();
+			_currentErr.SetLength(0);
+
+			PbeFileProcessor.Main(new string[] { "-e", "test.txt", "password" });
+
+			PbeFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("no message integrity check", GetLine(_currentErr));
+
+			PbeFileProcessor.Main(new string[] { "-e", "-i", "test.txt", "password" });
+
+			PbeFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+
+			PbeFileProcessor.Main(new string[] { "-e", "-ai", "test.txt", "password" });
+
+			PbeFileProcessor.Main(new string[] { "-d", "test.txt.asc", "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+		}
+
+		[Test]
+		public void TestClearSigned()
+		{
+			CreateTestFile(clearSignedPublicKey, "pub.bpg");
+
+			CheckClearSignedVerify(nlOnlySignedMessage);
+			CheckClearSignedVerify(crOnlySignedMessage);
+			CheckClearSignedVerify(crNlSignedMessage);
+			CheckClearSignedVerify(crNlSignedMessageTrailingWhiteSpace);
+
+			ClearSignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub.bpg" });
+
+			RsaKeyRingGenerator.Main(new string[] { "test", "password" });
+
+			CheckClearSigned(crOnlyMessage);
+			CheckClearSigned(nlOnlyMessage);
+			CheckClearSigned(crNlMessage);
+			CheckClearSigned(crNlMessageTrailingWhiteSpace);
+		}
+
+		[Test]
+		public void TestClearSignedBogusInput()
+		{
+			CreateTestFile(clearSignedPublicKey, "test.txt");
+
+			ClearSignedFileProcessor.Main(new String[] { "-s", "test.txt", "secret.bpg", "password" });
+		}
+
+		private void CheckClearSignedVerify(
+			string message)
+		{
+			CreateTestData(message, "test.txt.asc");
+
+			ClearSignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub.bpg" });
+		}
+
+		private void CheckClearSigned(
+			string message)
+		{
+			CreateTestData(message, "test.txt");
+
+			ClearSignedFileProcessor.Main(new string[] { "-s", "test.txt", "secret.bpg", "password" });
+			ClearSignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub.bpg" });
+		}
+
+		private void CheckSigning(
+			string type) 
+		{
+			Console.Out.Flush();
+			_currentOut.SetLength(0);
+
+			SignedFileProcessor.Main(new string[] { "-s", "test.txt", "secret." + type, "password" });
+			SignedFileProcessor.Main(new string[] { "-v", "test.txt.bpg", "pub." + type });
+
+			Console.Out.Flush();
+			Assert.AreEqual("signature verified.", GetLine(_currentOut));
+
+			SignedFileProcessor.Main(new string[] { "-s", "-a", "test.txt", "secret." + type, "password" });
+			SignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub." + type });
+
+			Console.Out.Flush();
+			Assert.AreEqual("signature verified.", GetLine(_currentOut));
+		}
+
+		private void CheckKeyBasedEncryption(
+			string type) 
+		{
+			Console.Error.Flush();
+			_currentErr.SetLength(0);
+
+			KeyBasedFileProcessor.Main(new string[] { "-e", "test.txt", "pub." + type });
+			KeyBasedFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("no message integrity check", GetLine(_currentErr));
+
+			KeyBasedFileProcessor.Main(new string[] { "-e", "-i", "test.txt", "pub." + type });
+			KeyBasedFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+
+			KeyBasedFileProcessor.Main(new string[] { "-e", "-ai", "test.txt", "pub." + type });
+			KeyBasedFileProcessor.Main(new string[] { "-d", "test.txt.asc", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+		}
+
+		private void CheckLargeKeyBasedEncryption(
+			string type) 
+		{
+			Console.Error.Flush();
+			_currentErr.SetLength(0);
+
+			KeyBasedLargeFileProcessor.Main(new string[] { "-e", "large.txt", "pub." + type });
+			KeyBasedLargeFileProcessor.Main(new string[] { "-d", "large.txt.bpg", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("no message integrity check", GetLine(_currentErr));
+
+			KeyBasedLargeFileProcessor.Main(new string[] { "-e", "-i", "large.txt", "pub." + type });
+			KeyBasedLargeFileProcessor.Main(new string[] { "-d", "large.txt.bpg", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+
+			KeyBasedLargeFileProcessor.Main(new string[] { "-e", "-ai", "large.txt", "pub." + type });
+			KeyBasedLargeFileProcessor.Main(new string[] { "-d", "large.txt.asc", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+		}
+
+		private void CreateSmallTestInput() 
+		{
+			TextWriter bfOut = new StreamWriter(File.Create("test.txt"));
+			bfOut.WriteLine("hello world!");
+			bfOut.Close();
+		}
+
+		private void CreateLargeTestInput() 
+		{
+			TextWriter bfOut = new StreamWriter(File.Create("large.txt"));
+
+			for (int i = 1; i <= 2000; i++)
+			{
+				bfOut.WriteLine("hello to planet " + i + "!");
+			}
+
+			bfOut.Close();
+		}
+
+		private void CreateTestData(
+			string	testData,
+			string	name)
+		{
+			TextWriter bfOut = new StreamWriter(File.Create(name));
+			bfOut.Write(testData);
+			bfOut.Close();
+		}
+
+		private void CreateTestFile(
+			byte[]	keyData,
+			string	name)
+		{
+			FileStream fOut = File.Create(name);
+			fOut.Write(keyData, 0, keyData.Length);
+			fOut.Close();
+		}
+
+		private string GetLine(
+			MemoryStream outStr) 
+		{
+			byte[] b = outStr.ToArray();
+			TextReader bRd = new StreamReader(new MemoryStream(b, false));
+			outStr.SetLength(0);
+			return bRd.ReadLine();
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			//junit.textui.TestRunner.run(suite());
+			EventListener el = new NullListener();
+			suite().Run(el);
+		}
+
+		public static TestSuite suite()
+		{
+			TestSuite suite = new TestSuite("OpenPGP Example Tests");
+
+			suite.Add(new AllTests());
+
+			return suite;
+		}
+
+	}
+}
diff --git a/crypto/test/src/openpgp/test/DSA2Test.cs b/crypto/test/src/openpgp/test/DSA2Test.cs
new file mode 100644
index 000000000..883ae317f
--- /dev/null
+++ b/crypto/test/src/openpgp/test/DSA2Test.cs
@@ -0,0 +1,237 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+	/**
+	* GPG compatability test vectors
+	*/
+	[TestFixture]
+	public class Dsa2Test
+		//extends TestCase
+	{
+		[Test]
+		public void TestK1024H160()
+		{
+			doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-160-sign.gpg");
+		}
+
+		[Test]
+		public void TestK1024H224()
+		{
+			doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-224-sign.gpg");
+		}
+
+		[Test]
+		public void TestK1024H256()
+		{
+			doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-256-sign.gpg");
+		}
+
+		[Test]
+		public void TestK1024H384()
+		{
+			doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-384-sign.gpg");
+		}
+
+		[Test]
+		public void TestK1024H512()
+		{
+			doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-512-sign.gpg");
+		}
+
+		[Test]
+		public void TestK2048H224()
+		{
+			doSigVerifyTest("DSA-2048-224.pub", "dsa-2048-224-sign.gpg");
+		}
+
+		[Test]
+		public void TestK3072H256()
+		{
+			doSigVerifyTest("DSA-3072-256.pub", "dsa-3072-256-sign.gpg");
+		}
+
+		[Test]
+		public void TestK7680H384()
+		{
+			doSigVerifyTest("DSA-7680-384.pub", "dsa-7680-384-sign.gpg");
+		}
+
+		[Test]
+		public void TestK15360H512()
+		{
+			doSigVerifyTest("DSA-15360-512.pub", "dsa-15360-512-sign.gpg");
+		}
+
+		[Test]
+		public void TestGenerateK1024H224()
+		{
+			doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha224);
+		}
+
+		[Test]
+		public void TestGenerateK1024H256()
+		{
+			doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha256);
+		}
+
+		[Test]
+		public void TestGenerateK1024H384()
+		{
+			doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha384);
+		}
+
+		[Test]
+		public void TestGenerateK1024H512()
+		{
+			doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha512);
+		}
+
+		[Test]
+		public void TestGenerateK2048H256()
+		{
+			doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", HashAlgorithmTag.Sha256);
+		}
+
+		[Test]
+		public void TestGenerateK2048H512()
+		{
+			doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", HashAlgorithmTag.Sha512);
+		}
+
+		private void doSigGenerateTest(
+			string				privateKeyFile,
+			string				publicKeyFile,
+			HashAlgorithmTag	digest)
+		{
+			PgpSecretKeyRing		secRing = loadSecretKey(privateKeyFile);
+			PgpPublicKeyRing		pubRing = loadPublicKey(publicKeyFile);
+			string					data = "hello world!";
+			byte[]					dataBytes = Encoding.ASCII.GetBytes(data);
+			MemoryStream			bOut = new MemoryStream();
+			MemoryStream			testIn = new MemoryStream(dataBytes, false);
+			PgpSignatureGenerator	sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, digest);
+
+			sGen.InitSign(PgpSignature.BinaryDocument, secRing.GetSecretKey().ExtractPrivateKey("test".ToCharArray()));
+
+			BcpgOutputStream bcOut = new BcpgOutputStream(bOut);
+
+			sGen.GenerateOnePassVersion(false).Encode(bcOut);
+
+			PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+
+//			Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000);
+			DateTime testDate = new DateTime(
+				(DateTime.UtcNow.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
+
+			Stream lOut = lGen.Open(
+				new UncloseableStream(bcOut),
+				PgpLiteralData.Binary,
+				"_CONSOLE",
+				dataBytes.Length,
+				testDate);
+
+			int ch;
+			while ((ch = testIn.ReadByte()) >= 0)
+			{
+				lOut.WriteByte((byte)ch);
+				sGen.Update((byte)ch);
+			}
+
+			lGen.Close();
+
+			sGen.Generate().Encode(bcOut);
+
+			PgpObjectFactory        pgpFact = new PgpObjectFactory(bOut.ToArray());
+			PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+			PgpOnePassSignature     ops = p1[0];
+
+			Assert.AreEqual(digest, ops.HashAlgorithm);
+			Assert.AreEqual(PublicKeyAlgorithmTag.Dsa, ops.KeyAlgorithm);
+
+			PgpLiteralData          p2 = (PgpLiteralData)pgpFact.NextPgpObject();
+			if (!p2.ModificationTime.Equals(testDate))
+			{
+				Assert.Fail("Modification time not preserved");
+			}
+
+			Stream dIn = p2.GetInputStream();
+
+			ops.InitVerify(pubRing.GetPublicKey());
+
+			while ((ch = dIn.ReadByte()) >= 0)
+			{
+				ops.Update((byte)ch);
+			}
+
+			PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+			PgpSignature sig = p3[0];
+
+			Assert.AreEqual(digest, sig.HashAlgorithm);
+			Assert.AreEqual(PublicKeyAlgorithmTag.Dsa, sig.KeyAlgorithm);
+
+			Assert.IsTrue(ops.Verify(sig));
+		}
+
+		private void doSigVerifyTest(
+			string	publicKeyFile,
+			string	sigFile)
+		{
+			PgpPublicKeyRing publicKey = loadPublicKey(publicKeyFile);
+			PgpObjectFactory pgpFact = loadSig(sigFile);
+
+			PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+			pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+			PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+			PgpOnePassSignature ops = p1[0];
+
+			PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject();
+
+			Stream dIn = p2.GetInputStream();
+
+			ops.InitVerify(publicKey.GetPublicKey());
+
+			int ch;
+			while ((ch = dIn.ReadByte()) >= 0)
+			{
+				ops.Update((byte)ch);
+			}
+
+			PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+
+			Assert.IsTrue(ops.Verify(p3[0]));
+		}
+
+		private PgpObjectFactory loadSig(
+			string sigName)
+		{
+			Stream fIn = SimpleTest.GetTestDataAsStream("openpgp.dsa.sigs." + sigName);
+
+			return new PgpObjectFactory(fIn);
+		}
+
+		private PgpPublicKeyRing loadPublicKey(
+			string keyName)
+		{
+			Stream fIn = SimpleTest.GetTestDataAsStream("openpgp.dsa.keys." + keyName);
+
+			return new PgpPublicKeyRing(fIn);
+		}
+
+		private PgpSecretKeyRing loadSecretKey(
+			string keyName)
+		{
+			Stream fIn = SimpleTest.GetTestDataAsStream("openpgp.dsa.keys." + keyName);
+
+			return new PgpSecretKeyRing(fIn);
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/test/PGPArmoredTest.cs b/crypto/test/src/openpgp/test/PGPArmoredTest.cs
new file mode 100644
index 000000000..aa13477ed
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PGPArmoredTest.cs
@@ -0,0 +1,265 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+	[TestFixture]
+	public class PgpArmoredTest
+		: SimpleTest
+	{
+		private static readonly byte[] sample = Base64.Decode(
+				"mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn"
+			+ "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg"
+			+ "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf"
+			+ "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ"
+			+ "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G"
+			+ "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ"
+			+ "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG"
+			+ "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP"
+			+ "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif"
+			+ "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh"
+			+ "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB"
+			+ "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p"
+			+ "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5"
+			+ "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN"
+			+ "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE"
+			+ "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1"
+			+ "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu"
+			+ "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y"
+			+ "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB"
+			+ "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u"
+			+ "ZJhfg0htdgAfIy8ppm05vLACAAA=");
+
+		private static readonly byte[] marker = Hex.Decode("2d2d2d2d2d454e4420504750205055424c4943204b455920424c4f434b2d2d2d2d2d");
+
+		// Contains "Hello World!" as an armored message
+		// The 'blank line' after the headers contains (legal) whitespace - see RFC2440 6.2
+		private static readonly string blankLineData =
+			  "-----BEGIN PGP MESSAGE-----\n"
+			+ "Version: BCPG v1.32\n"
+			+ "Comment: A dummy message\n"
+			+ " \t \t\n"
+			+ "SGVsbG8gV29ybGQh\n"
+			+ "=d9Xi\n"
+			+ "-----END PGP MESSAGE-----\n";
+
+		private int markerCount(
+			byte[] data)
+		{
+			int ind = 0;
+			int matches = 0;
+
+			while (ind < data.Length)
+			{
+				if (data[ind] == 0x2d)
+				{
+					int count = 0;
+					while (count < marker.Length)
+					{
+						if (data[ind + count] != marker[count])
+						{
+							break;
+						}
+						count++;
+					}
+
+					if (count == marker.Length)
+					{
+						matches++;
+					}
+
+					// TODO Is this correct?
+					ind += count;
+				}
+				else
+				{
+					ind++;
+				}
+			}
+
+			return matches;
+		}
+
+		private void blankLineTest()
+		{
+			byte[] blankLineBytes = Encoding.ASCII.GetBytes(blankLineData);
+			MemoryStream bIn = new MemoryStream(blankLineBytes, false);
+			ArmoredInputStream aIn = new ArmoredInputStream(bIn, true);
+
+			MemoryStream bOut = new MemoryStream();
+			int c;
+			while ((c = aIn.ReadByte()) >= 0)
+			{
+				bOut.WriteByte((byte)c);
+			}
+
+			byte[] expected = Encoding.ASCII.GetBytes("Hello World!");
+
+			if (!Arrays.AreEqual(expected, bOut.ToArray()))
+			{
+				Fail("Incorrect message retrieved in blank line test.");
+			}
+		}
+
+		public override void PerformTest()
+		{
+			//
+			// test immediate close
+			//
+			MemoryStream bOut = new MemoryStream();
+			ArmoredOutputStream aOut = new ArmoredOutputStream(bOut);
+
+			aOut.Close();
+
+			byte[] data = bOut.ToArray();
+
+			if (data.Length != 0)
+			{
+				Fail("No data should have been written");
+			}
+
+			//
+			// multiple close
+			//
+			bOut = new MemoryStream();
+			aOut = new ArmoredOutputStream(bOut);
+
+			aOut.Write(sample, 0, sample.Length);
+
+			aOut.Close();
+			aOut.Close();
+
+			int mc = markerCount(bOut.ToArray());
+
+			if (mc < 1)
+			{
+				Fail("No end marker found");
+			}
+
+			if (mc > 1)
+			{
+				Fail("More than one end marker found");
+			}
+
+			//
+			// writing and reading single objects
+			//
+			bOut = new MemoryStream();
+			aOut = new ArmoredOutputStream(bOut);
+
+			aOut.Write(sample, 0, sample.Length);
+
+			aOut.Close();
+
+			ArmoredInputStream aIn = new ArmoredInputStream(
+				new MemoryStream(bOut.ToArray(), false));
+
+			PgpObjectFactory fact = new PgpObjectFactory(aIn);
+			int count = 0;
+
+			while (fact.NextPgpObject() != null)
+			{
+				count++;
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of objects found: " + count);
+			}
+
+			//
+			// writing and reading multiple objects  - in single block
+			//
+			bOut = new MemoryStream();
+			aOut = new ArmoredOutputStream(bOut);
+
+			aOut.Write(sample, 0, sample.Length);
+			aOut.Write(sample, 0, sample.Length);
+
+			aOut.Close();
+
+			aIn = new ArmoredInputStream(
+				new MemoryStream(bOut.ToArray(), false));
+
+			fact = new PgpObjectFactory(aIn);
+			count = 0;
+
+			while (fact.NextPgpObject() != null)
+			{
+				count++;
+			}
+
+			if (count != 2)
+			{
+				Fail("wrong number of objects found: " + count);
+			}
+
+			//
+			// writing and reading multiple objects  - in single block
+			//
+			bOut = new MemoryStream();
+			aOut = new ArmoredOutputStream(bOut);
+
+			aOut.Write(sample, 0, sample.Length);
+
+			aOut.Close();     // does not close underlying stream
+
+			aOut = new ArmoredOutputStream(bOut);
+
+			aOut.Write(sample, 0, sample.Length);
+
+			aOut.Close();
+
+			aIn = new ArmoredInputStream(
+				new MemoryStream(bOut.ToArray(), false));
+
+			count = 0;
+			bool atLeastOne;
+			do
+			{
+				atLeastOne = false;
+				fact = new PgpObjectFactory(aIn);
+
+				while (fact.NextPgpObject() != null)
+				{
+					atLeastOne = true;
+					count++;
+				}
+			}
+			while (atLeastOne);
+
+			if (count != 2)
+			{
+				Fail("wrong number of objects found: " + count);
+			}
+
+			blankLineTest();
+		}
+
+		public override string Name
+		{
+			get { return "PGPArmoredTest"; }
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new PgpArmoredTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs b/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs
new file mode 100644
index 000000000..668f8cce2
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs
@@ -0,0 +1,445 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+	[TestFixture]
+	public class PgpClearSignedSignatureTest
+		: SimpleTest
+	{
+		private static readonly byte[] publicKey = Base64.Decode(
+			  "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+"
+			+ "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1"
+			+ "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO"
+			+ "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7"
+			+ "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4"
+			+ "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp"
+			+ "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD"
+			+ "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR"
+			+ "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch"
+			+ "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg"
+			+ "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r"
+			+ "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1"
+			+ "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz"
+			+ "oztls8tuWA0OGHba9XfX9rfgorACAAM=");
+
+		private static readonly byte[] secretKey = Base64.Decode(
+			  "lQOWBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+"
+			+ "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1"
+			+ "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO"
+			+ "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7"
+			+ "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4"
+			+ "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp"
+			+ "AAf+JCJJeAXEcrTVHotsrRR5idzmg6RK/1MSQUijwPmP7ZGy1BmpAmYUfbxn"
+			+ "B56GvXyFV3Pbj9PgyJZGS7cY+l0BF4ZqN9USiQtC9OEpCVT5LVMCFXC/lahC"
+			+ "/O3EkjQy0CYK+GwyIXa+Flxcr460L/Hvw2ZEXJZ6/aPdiR+DU1l5h99Zw8V1"
+			+ "Y625MpfwN6ufJfqE0HLoqIjlqCfi1iwcKAK2oVx2SwnT1W0NwUUXjagGhD2s"
+			+ "VzJVpLqhlwmS0A+RE9Niqrf80/zwE7QNDF2DtHxmMHJ3RY/pfu5u1rrFg9YE"
+			+ "lmS60mzOe31CaD8Li0k5YCJBPnmvM9mN3/DWWprSZZKtmQQA96C2/VJF5EWm"
+			+ "+/Yxi5J06dG6Bkz311Ui4p2zHm9/4GvTPCIKNpGx9Zn47YFD3tIg3fIBVPOE"
+			+ "ktG38pEPx++dSSFF9Ep5UgmYFNOKNUVq3yGpatBtCQBXb1LQLAMBJCJ5TQmk"
+			+ "68hMOEaqjMHSOa18cS63INgA6okb/ueAKIHxYQcEAP9DaXu5n9dZQw7pshbN"
+			+ "Nu/T5IP0/D/wqM+W5r+j4P1N7PgiAnfKA4JjKrUgl8PGnI2qM/Qu+g3qK++c"
+			+ "F1ESHasnJPjvNvY+cfti06xnJVtCB/EBOA2UZkAr//Tqa76xEwYAWRBnO2Y+"
+			+ "KIVOT+nMiBFkjPTrNAD6fSr1O4aOueBhBAC6aA35IfjC2h5MYk8+Z+S4io2o"
+			+ "mRxUZ/dUuS+kITvWph2e4DT28Xpycpl2n1Pa5dCDO1lRqe/5JnaDYDKqxfmF"
+			+ "5tTG8GR4d4nVawwLlifXH5Ll7t5NcukGNMCsGuQAHMy0QHuAaOvMdLs5kGHn"
+			+ "8VxfKEVKhVrXsvJSwyXXSBtMtUcRtBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2"
+			+ "BBMBAgAgBQJEIdvsAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ4M/I"
+			+ "er3f9xagdAf/fbKWBjLQM8xR7JkRP4ri8YKOQPhK+VrddGUD59/wzVnvaGyl"
+			+ "9MZE7TXFUeniQq5iXKnm22EQbYchv2Jcxyt2H9yptpzyh4tP6tEHl1C887p2"
+			+ "J4qe7F2ATua9CzVGwXQSUbKtj2fgUZP5SsNp25guhPiZdtkf2sHMeiotmykF"
+			+ "ErzqGMrvOAUThrO63GiYsRk4hF6rcQ01d+EUVpY/sBcCxgNyOiB7a84sDtrx"
+			+ "nX5BTEZDTEj8LvuEyEV3TMUuAjx17Eyd+9JtKzwV4v3hlTaWOvGro9nPS7Ya"
+			+ "PuG+RtufzXCUJPbPfTjTvtGOqvEzoztls8tuWA0OGHba9XfX9rfgorACAAA=");
+
+		private static readonly string crOnlyMessage =
+				"\r"
+			+ " hello world!\r"
+			+ "\r"
+			+ "- dash\r";
+
+		private static readonly string nlOnlyMessage =
+			"\n"
+			+ " hello world!\n"
+			+ "\n"
+			+ "- dash\n";
+
+		private static readonly string crNlMessage =
+			"\r\n"
+			+ " hello world!\r\n"
+			+ "\r\n"
+			+ "- dash\r\n";
+
+		private static readonly string crOnlySignedMessage =
+				"-----BEGIN PGP SIGNED MESSAGE-----\r"
+			+ "Hash: SHA256\r"
+			+ "\r"
+			+ "\r"
+			+ " hello world!\r"
+			+ "\r"
+			+ "- - dash\r"
+			+ "-----BEGIN PGP SIGNATURE-----\r"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r"
+			+ "\r"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r"
+			+ "=84Nd\r"
+			+ "-----END PGP SIGNATURE-----\r";
+
+		private static readonly string nlOnlySignedMessage =
+			"-----BEGIN PGP SIGNED MESSAGE-----\n"
+			+ "Hash: SHA256\n"
+			+ "\n"
+			+ "\n"
+			+ " hello world!\n"
+			+ "\n"
+			+ "- - dash\n"
+			+ "-----BEGIN PGP SIGNATURE-----\n"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\n"
+			+ "\n"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n"
+			+ "=84Nd\n"
+			+ "-----END PGP SIGNATURE-----\n";
+
+		private static readonly string crNlSignedMessage =
+				"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
+			+ "Hash: SHA256\r\n"
+			+ "\r\n"
+			+ "\r\n"
+			+ " hello world!\r\n"
+			+ "\r\n"
+			+ "- - dash\r\n"
+			+ "-----BEGIN PGP SIGNATURE-----\r\n"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
+			+ "\r\n"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
+			+ "=84Nd\r"
+			+ "-----END PGP SIGNATURE-----\r\n";
+
+		private static readonly string crNlSignedMessageTrailingWhiteSpace =
+			"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
+			+ "Hash: SHA256\r\n"
+			+ "\r\n"
+			+ "\r\n"
+			+ " hello world! \t\r\n"
+			+ "\r\n"
+			+ "- - dash\r\n"
+			+ "-----BEGIN PGP SIGNATURE-----\r\n"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
+			+ "\r\n"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
+			+ "=84Nd\r"
+			+ "-----END PGP SIGNATURE-----\r\n";
+
+		public override string Name
+		{
+			get { return "PGPClearSignedSignature"; }
+		}
+
+		private void messageTest(
+			string message,
+			string type)
+		{
+			ArmoredInputStream aIn = new ArmoredInputStream(
+				new MemoryStream(Encoding.ASCII.GetBytes(message)));
+
+			string[] headers = aIn.GetArmorHeaders();
+
+			if (headers == null || headers.Length != 1)
+			{
+				Fail("wrong number of headers found");
+			}
+
+			if (!"Hash: SHA256".Equals(headers[0]))
+			{
+				Fail("header value wrong: " + headers[0]);
+			}
+
+			//
+			// read the input, making sure we ingore the last newline.
+			//
+			MemoryStream bOut = new MemoryStream();
+			int ch;
+
+			while ((ch = aIn.ReadByte()) >= 0 && aIn.IsClearText())
+			{
+				bOut.WriteByte((byte)ch);
+			}
+
+			PgpPublicKeyRingBundle pgpRings = new PgpPublicKeyRingBundle(publicKey);
+
+			PgpObjectFactory	pgpFact = new PgpObjectFactory(aIn);
+			PgpSignatureList	p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+			PgpSignature		sig = p3[0];
+
+			sig.InitVerify(pgpRings.GetPublicKey(sig.KeyId));
+
+			MemoryStream lineOut = new MemoryStream();
+			Stream sigIn = new MemoryStream(bOut.ToArray(), false);
+			int lookAhead = ReadInputLine(lineOut, sigIn);
+
+			ProcessLine(sig, lineOut.ToArray());
+
+			if (lookAhead != -1)
+			{
+				do
+				{
+					lookAhead = ReadInputLine(lineOut, lookAhead, sigIn);
+
+					sig.Update((byte) '\r');
+					sig.Update((byte) '\n');
+
+					ProcessLine(sig, lineOut.ToArray());
+				}
+				while (lookAhead != -1);
+			}
+
+			if (!sig.Verify())
+			{
+				Fail("signature failed to verify m_in " + type);
+			}
+		}
+
+		private PgpSecretKey ReadSecretKey(
+			Stream    inputStream)
+		{
+			PgpSecretKeyRingBundle        pgpSec = new PgpSecretKeyRingBundle(inputStream);
+
+			//
+			// we just loop through the collection till we find a key suitable for encryption, in the real
+			// world you would probably want to be a bit smarter about this.
+			//
+			//
+			// iterate through the key rings.
+			//
+			foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings())
+			{
+				foreach (PgpSecretKey k in kRing.GetSecretKeys())
+				{
+					if (k.IsSigningKey)
+					{
+						return k;
+					}
+				}
+			}
+
+			throw new ArgumentException("Can't find signing key in key ring.");
+		}
+
+		private void generateTest(
+			string message,
+			string type)
+		{
+			PgpSecretKey                    pgpSecKey = ReadSecretKey(new MemoryStream(secretKey));
+			PgpPrivateKey                   pgpPrivKey = pgpSecKey.ExtractPrivateKey("".ToCharArray());
+			PgpSignatureGenerator           sGen = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, HashAlgorithmTag.Sha256);
+			PgpSignatureSubpacketGenerator  spGen = new PgpSignatureSubpacketGenerator();
+
+			sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey);
+
+			IEnumerator    it = pgpSecKey.PublicKey.GetUserIds().GetEnumerator();
+			if (it.MoveNext())
+			{
+				spGen.SetSignerUserId(false, (string)it.Current);
+				sGen.SetHashedSubpackets(spGen.Generate());
+			}
+
+			MemoryStream bOut = new MemoryStream();
+			ArmoredOutputStream aOut = new ArmoredOutputStream(bOut);
+			MemoryStream bIn = new MemoryStream(Encoding.ASCII.GetBytes(message), false);
+
+			aOut.BeginClearText(HashAlgorithmTag.Sha256);
+
+			//
+			// note the last \n m_in the file is ignored
+			//
+			MemoryStream lineOut = new MemoryStream();
+			int lookAhead = ReadInputLine(lineOut, bIn);
+
+			ProcessLine(aOut, sGen, lineOut.ToArray());
+
+			if (lookAhead != -1)
+			{
+				do
+				{
+					lookAhead = ReadInputLine(lineOut, lookAhead, bIn);
+
+					sGen.Update((byte) '\r');
+					sGen.Update((byte) '\n');
+
+					ProcessLine(aOut, sGen, lineOut.ToArray());
+				}
+				while (lookAhead != -1);
+			}
+
+			aOut.EndClearText();
+
+			BcpgOutputStream bcpgOut = new BcpgOutputStream(aOut);
+
+			sGen.Generate().Encode(bcpgOut);
+
+			aOut.Close();
+
+			byte[] bs = bOut.ToArray();
+			messageTest(Encoding.ASCII.GetString(bs, 0, bs.Length), type);
+		}
+
+		private static int ReadInputLine(
+			MemoryStream	bOut,
+			Stream			fIn)
+		{
+			bOut.SetLength(0);
+
+			int lookAhead = -1;
+			int ch;
+
+			while ((ch = fIn.ReadByte()) >= 0)
+			{
+				bOut.WriteByte((byte) ch);
+				if (ch == '\r' || ch == '\n')
+				{
+					lookAhead = ReadPassedEol(bOut, ch, fIn);
+					break;
+				}
+			}
+
+			return lookAhead;
+		}
+
+		private static int ReadInputLine(
+			MemoryStream	bOut,
+			int				lookAhead,
+			Stream			fIn)
+		{
+			bOut.SetLength(0);
+
+			int ch = lookAhead;
+
+			do
+			{
+				bOut.WriteByte((byte) ch);
+				if (ch == '\r' || ch == '\n')
+				{
+					lookAhead = ReadPassedEol(bOut, ch, fIn);
+					break;
+				}
+			}
+			while ((ch = fIn.ReadByte()) >= 0);
+
+			return lookAhead;
+		}
+
+		private static int ReadPassedEol(
+			MemoryStream	bOut,
+			int				lastCh,
+			Stream			fIn)
+		{
+			int lookAhead = fIn.ReadByte();
+
+			if (lastCh == '\r' && lookAhead == '\n')
+			{
+				bOut.WriteByte((byte) lookAhead);
+				lookAhead = fIn.ReadByte();
+			}
+
+			return lookAhead;
+		}
+
+		private static void ProcessLine(
+			PgpSignature	sig,
+			byte[]			line)
+		{
+			int length = GetLengthWithoutWhiteSpace(line);
+			if (length > 0)
+			{
+				sig.Update(line, 0, length);
+			}
+		}
+
+		private static void ProcessLine(
+			Stream					aOut,
+			PgpSignatureGenerator	sGen,
+			byte[]					line)
+		{
+			int length = GetLengthWithoutWhiteSpace(line);
+			if (length > 0)
+			{
+				sGen.Update(line, 0, length);
+			}
+
+			aOut.Write(line, 0, line.Length);
+		}
+
+		private static int GetLengthWithoutWhiteSpace(
+			byte[] line)
+		{
+			int end = line.Length - 1;
+
+			while (end >= 0 && IsWhiteSpace(line[end]))
+			{
+				end--;
+			}
+
+			return end + 1;
+		}
+
+		private static bool IsWhiteSpace(
+			byte b)
+		{
+			return b == '\r' || b == '\n' || b == '\t' || b == ' ';
+		}
+
+		public override void PerformTest()
+		{
+			messageTest(crOnlySignedMessage, "\\r");
+			messageTest(nlOnlySignedMessage, "\\n");
+			messageTest(crNlSignedMessage, "\\r\\n");
+			messageTest(crNlSignedMessageTrailingWhiteSpace, "\\r\\n");
+
+			generateTest(nlOnlyMessage, "\\r");
+			generateTest(crOnlyMessage, "\\n");
+			generateTest(crNlMessage, "\\r\\n");
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new PgpClearSignedSignatureTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/test/PGPCompressionTest.cs b/crypto/test/src/openpgp/test/PGPCompressionTest.cs
new file mode 100644
index 000000000..fdcf7222c
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PGPCompressionTest.cs
@@ -0,0 +1,117 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Utilities;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+	[TestFixture]
+	public class PgpCompressionTest
+		: SimpleTest
+	{
+		private static readonly byte[] Data = Encoding.ASCII.GetBytes("hello world! !dlrow olleh");
+
+		[Test]
+		public void TestUncompressed()
+		{
+			doTestCompression(CompressionAlgorithmTag.Uncompressed);
+		}
+
+		[Test]
+		public void TestZip()
+		{
+			doTestCompression(CompressionAlgorithmTag.Zip);
+		}
+
+		[Test]
+		public void TestZLib()
+		{
+			doTestCompression(CompressionAlgorithmTag.ZLib);
+		}
+
+		[Test]
+		public void TestBZip2()
+		{
+			doTestCompression(CompressionAlgorithmTag.BZip2);
+		}
+
+		public override void PerformTest()
+		{
+			doTestCompression(CompressionAlgorithmTag.Uncompressed);
+			doTestCompression(CompressionAlgorithmTag.Zip);
+			doTestCompression(CompressionAlgorithmTag.ZLib);
+			doTestCompression(CompressionAlgorithmTag.BZip2);
+		}
+
+		private void doTestCompression(
+			CompressionAlgorithmTag type)
+		{
+			doTestCompression(type, true);
+			doTestCompression(type, false);
+		}
+
+		private void doTestCompression(
+			CompressionAlgorithmTag	type,
+			bool					streamClose)
+		{
+			MemoryStream bOut = new MemoryStream();
+			PgpCompressedDataGenerator cPacket = new PgpCompressedDataGenerator(type);
+			Stream os = cPacket.Open(new UncloseableStream(bOut), new byte[Data.Length - 1]);
+			os.Write(Data, 0, Data.Length);
+
+			if (streamClose)
+			{
+				os.Close();
+			}
+			else
+			{
+				cPacket.Close();
+			}
+
+			ValidateData(bOut.ToArray());
+
+			try
+			{
+				os.Close();
+				cPacket.Close();
+			}
+			catch (Exception)
+			{
+				Fail("Redundant Close() should be ignored");
+			}
+		}
+
+		private void ValidateData(
+			byte[] compressed)
+		{
+			PgpObjectFactory pgpFact = new PgpObjectFactory(compressed);
+			PgpCompressedData c1 = (PgpCompressedData) pgpFact.NextPgpObject();
+
+			Stream pIn = c1.GetDataStream();
+			byte[] bytes = Streams.ReadAll(pIn);
+			pIn.Close();
+
+			if (!AreEqual(bytes, Data))
+			{
+				Fail("compression test failed");
+			}
+		}
+
+		public override string Name
+		{
+			get { return "PGPCompressionTest"; }
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new PgpCompressionTest());
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/test/PGPDSAElGamalTest.cs b/crypto/test/src/openpgp/test/PGPDSAElGamalTest.cs
new file mode 100644
index 000000000..b86324954
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PGPDSAElGamalTest.cs
@@ -0,0 +1,492 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+	[TestFixture]
+	public class PgpDsaElGamalTest
+		: SimpleTest
+	{
+		private static readonly byte[] testPubKeyRing = Base64.Decode(
+			  "mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
+			+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
+			+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
+			+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
+			+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
+			+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
+			+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
+			+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
+			+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
+			+ "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv"
+			+ "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH"
+			+ "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK"
+			+ "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2"
+			+ "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH"
+			+ "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB"
+			+ "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2"
+			+ "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN"
+			+ "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+"
+			+ "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC"
+			+ "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk"
+			+ "JVCXP0/Szm05GB+WN+MOCT2wAgAA");
+
+		private static readonly byte[] testPrivKeyRing = Base64.Decode(
+			  "lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
+			+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
+			+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
+			+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
+			+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
+			+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
+			+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
+			+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
+			+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
+			+ "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r"
+			+ "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF"
+			+ "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn"
+			+ "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn"
+			+ "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r"
+			+ "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj"
+			+ "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya"
+			+ "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF"
+			+ "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq"
+			+ "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk"
+			+ "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs"
+			+ "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs"
+			+ "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA"
+			+ "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg"
+			+ "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA");
+
+		private static readonly byte[] encMessage = Base64.Decode(
+			  "hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c"
+			+ "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o"
+			+ "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv"
+			+ "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f"
+			+ "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy"
+			+ "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL"
+			+ "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp"
+			+ "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw==");
+
+		private static readonly byte[] signedAndEncMessage = Base64.Decode(
+			  "hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn"
+			+ "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy"
+			+ "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C"
+			+ "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T"
+			+ "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum"
+			+ "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK"
+			+ "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3"
+			+ "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm"
+			+ "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht"
+			+ "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM=");
+
+		private static readonly char[] pass = "hello world".ToCharArray();
+
+		private static readonly SecureRandom random = new SecureRandom();
+
+		public override void PerformTest()
+		{
+			PgpPublicKey pubKey = null;
+
+			//
+			// Read the public key
+			//
+			PgpObjectFactory pgpFact = new PgpObjectFactory(testPubKeyRing);
+			PgpPublicKeyRing pgpPub = (PgpPublicKeyRing)pgpFact.NextPgpObject();
+
+			pubKey = pgpPub.GetPublicKey();
+
+			if (pubKey.BitStrength != 1024)
+			{
+				Fail("failed - key strength reported incorrectly.");
+			}
+
+			//
+			// Read the private key
+			//
+			PgpSecretKeyRing	sKey = new PgpSecretKeyRing(testPrivKeyRing);
+			PgpSecretKey		secretKey = sKey.GetSecretKey();
+			PgpPrivateKey		pgpPrivKey = secretKey.ExtractPrivateKey(pass);
+
+			//
+			// signature generation
+			//
+			const string data = "hello world!";
+			byte[] dataBytes = Encoding.ASCII.GetBytes(data);
+			MemoryStream bOut = new MemoryStream();
+			MemoryStream testIn = new MemoryStream(dataBytes, false);
+			PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa,
+				HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
+
+			PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(
+				CompressionAlgorithmTag.Zip);
+
+			BcpgOutputStream bcOut = new BcpgOutputStream(
+				cGen.Open(new UncloseableStream(bOut)));
+
+			sGen.GenerateOnePassVersion(false).Encode(bcOut);
+
+			PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+
+			DateTime testDateTime = new DateTime(1973, 7, 27);
+			Stream lOut = lGen.Open(
+				new UncloseableStream(bcOut),
+				PgpLiteralData.Binary,
+				"_CONSOLE",
+				dataBytes.Length,
+				testDateTime);
+
+			int ch;
+			while ((ch = testIn.ReadByte()) >= 0)
+			{
+				lOut.WriteByte((byte) ch);
+				sGen.Update((byte) ch);
+			}
+
+			lGen.Close();
+
+			sGen.Generate().Encode(bcOut);
+
+			cGen.Close();
+
+			//
+			// verify Generated signature
+			//
+			pgpFact = new PgpObjectFactory(bOut.ToArray());
+
+			PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+			pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+			PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+
+			PgpOnePassSignature ops = p1[0];
+
+			PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject();
+			if (!p2.ModificationTime.Equals(testDateTime))
+			{
+				Fail("Modification time not preserved");
+			}
+
+			Stream    dIn = p2.GetInputStream();
+
+			ops.InitVerify(pubKey);
+
+			while ((ch = dIn.ReadByte()) >= 0)
+			{
+				ops.Update((byte)ch);
+			}
+
+			PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+
+			if (!ops.Verify(p3[0]))
+			{
+				Fail("Failed Generated signature check");
+			}
+
+			//
+			// test encryption
+			//
+
+			//
+			// find a key sutiable for encryption
+			//
+			long pgpKeyID = 0;
+			AsymmetricKeyParameter pKey = null;
+
+			foreach (PgpPublicKey pgpKey in pgpPub.GetPublicKeys())
+			{
+				if (pgpKey.Algorithm == PublicKeyAlgorithmTag.ElGamalEncrypt
+					|| pgpKey.Algorithm == PublicKeyAlgorithmTag.ElGamalGeneral)
+				{
+					pKey = pgpKey.GetKey();
+					pgpKeyID = pgpKey.KeyId;
+					if (pgpKey.BitStrength != 1024)
+					{
+						Fail("failed - key strength reported incorrectly.");
+					}
+
+					//
+					// verify the key
+					//
+
+				}
+			}
+
+			IBufferedCipher c = CipherUtilities.GetCipher("ElGamal/None/PKCS1Padding");
+
+			c.Init(true, pKey);
+
+			byte[] inBytes = Encoding.ASCII.GetBytes("hello world");
+			byte[] outBytes = c.DoFinal(inBytes);
+
+			pgpPrivKey = sKey.GetSecretKey(pgpKeyID).ExtractPrivateKey(pass);
+
+			c.Init(false, pgpPrivKey.Key);
+
+			outBytes = c.DoFinal(outBytes);
+
+			if (!Arrays.AreEqual(inBytes, outBytes))
+			{
+				Fail("decryption failed.");
+			}
+
+			//
+			// encrypted message
+			//
+			byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o',
+								(byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' };
+
+			PgpObjectFactory pgpF = new PgpObjectFactory(encMessage);
+
+			PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+			PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0];
+
+			Stream clear = encP.GetDataStream(pgpPrivKey);
+
+			pgpFact = new PgpObjectFactory(clear);
+
+			c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+			pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+			PgpLiteralData ld = (PgpLiteralData)pgpFact.NextPgpObject();
+
+			if (!ld.FileName.Equals("test.txt"))
+			{
+				throw new Exception("wrong filename in packet");
+			}
+
+			Stream inLd = ld.GetDataStream();
+			byte[] bytes = Streams.ReadAll(inLd);
+
+			if (!Arrays.AreEqual(bytes, text))
+			{
+				Fail("wrong plain text in decrypted packet");
+			}
+
+			//
+			// signed and encrypted message
+			//
+			pgpF = new PgpObjectFactory(signedAndEncMessage);
+
+			encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+			encP = (PgpPublicKeyEncryptedData)encList[0];
+
+			clear = encP.GetDataStream(pgpPrivKey);
+
+			pgpFact = new PgpObjectFactory(clear);
+
+			c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+			pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+			p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+
+			ops = p1[0];
+
+			ld = (PgpLiteralData)pgpFact.NextPgpObject();
+
+			bOut = new MemoryStream();
+
+			if (!ld.FileName.Equals("test.txt"))
+			{
+				throw new Exception("wrong filename in packet");
+			}
+
+			inLd = ld.GetDataStream();
+
+			//
+			// note: we use the DSA public key here.
+			//
+			ops.InitVerify(pgpPub.GetPublicKey());
+
+			while ((ch = inLd.ReadByte()) >= 0)
+			{
+				ops.Update((byte) ch);
+				bOut.WriteByte((byte) ch);
+			}
+
+			p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+
+			if (!ops.Verify(p3[0]))
+			{
+				Fail("Failed signature check");
+			}
+
+			if (!Arrays.AreEqual(bOut.ToArray(), text))
+			{
+				Fail("wrong plain text in decrypted packet");
+			}
+
+			//
+			// encrypt
+			//
+			MemoryStream cbOut = new MemoryStream();
+			PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(
+				SymmetricKeyAlgorithmTag.TripleDes, random);
+			PgpPublicKey puK = sKey.GetSecretKey(pgpKeyID).PublicKey;
+
+			cPk.AddMethod(puK);
+
+			Stream cOut = cPk.Open(new UncloseableStream(cbOut), bOut.ToArray().Length);
+
+			cOut.Write(text, 0, text.Length);
+
+			cOut.Close();
+
+			pgpF = new PgpObjectFactory(cbOut.ToArray());
+
+			encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+			encP = (PgpPublicKeyEncryptedData)encList[0];
+
+			pgpPrivKey = sKey.GetSecretKey(pgpKeyID).ExtractPrivateKey(pass);
+
+			clear = encP.GetDataStream(pgpPrivKey);
+			outBytes = Streams.ReadAll(clear);
+
+			if (!Arrays.AreEqual(outBytes, text))
+			{
+				Fail("wrong plain text in Generated packet");
+			}
+
+			//
+			// use of PgpKeyPair
+			//
+			BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
+			BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
+
+			ElGamalParameters elParams = new ElGamalParameters(p, g);
+
+			IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL");
+			kpg.Init(new ElGamalKeyGenerationParameters(random, elParams));
+
+			AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();
+
+			PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalGeneral ,
+				kp.Public, kp.Private, DateTime.UtcNow);
+
+			PgpPublicKey k1 = pgpKp.PublicKey;
+			PgpPrivateKey k2 = pgpKp.PrivateKey;
+
+
+
+
+
+			// Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!)
+			for (int pSize = 257; pSize < 264; ++pSize)
+			{
+				// Generate some parameters of the given size
+				ElGamalParametersGenerator epg = new ElGamalParametersGenerator();
+				epg.Init(pSize, 2, random);
+
+				elParams = epg.GenerateParameters();
+
+				kpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL");
+				kpg.Init(new ElGamalKeyGenerationParameters(random, elParams));
+
+
+				// Run a short encrypt/decrypt test with random key for the given parameters
+				kp = kpg.GenerateKeyPair();
+
+				PgpKeyPair elGamalKeyPair = new PgpKeyPair(
+					PublicKeyAlgorithmTag.ElGamalGeneral, kp, DateTime.UtcNow);
+
+				cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, random);
+
+				puK = elGamalKeyPair.PublicKey;
+
+				cPk.AddMethod(puK);
+
+				cbOut = new MemoryStream();
+
+				cOut = cPk.Open(new UncloseableStream(cbOut), text.Length);
+
+				cOut.Write(text, 0, text.Length);
+
+				cOut.Close();
+
+				pgpF = new PgpObjectFactory(cbOut.ToArray());
+
+				encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+				encP = (PgpPublicKeyEncryptedData)encList[0];
+
+				pgpPrivKey = elGamalKeyPair.PrivateKey;
+
+				// Note: This is where an exception would be expected if the P size causes problems
+				clear = encP.GetDataStream(pgpPrivKey);
+				byte[] decText = Streams.ReadAll(clear);
+
+				if (!Arrays.AreEqual(text, decText))
+				{
+					Fail("decrypted message incorrect");
+				}
+			}
+
+
+			// check sub key encoding
+
+			foreach (PgpPublicKey pgpKey in pgpPub.GetPublicKeys())
+			{
+				if (!pgpKey.IsMasterKey)
+				{
+					byte[] kEnc = pgpKey.GetEncoded();
+
+					PgpObjectFactory objF = new PgpObjectFactory(kEnc);
+
+					// TODO Make PgpPublicKey a PgpObject or return a PgpPublicKeyRing
+//					PgpPublicKey k = (PgpPublicKey)objF.NextPgpObject();
+//
+//					pKey = k.GetKey();
+//					pgpKeyID = k.KeyId;
+//					if (k.BitStrength != 1024)
+//					{
+//						Fail("failed - key strength reported incorrectly.");
+//					}
+//
+//					if (objF.NextPgpObject() != null)
+//					{
+//						Fail("failed - stream not fully parsed.");
+//					}
+                }
+            }
+		}
+
+		public override string Name
+		{
+			get { return "PGPDSAElGamalTest"; }
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new PgpDsaElGamalTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/test/PGPDSATest.cs b/crypto/test/src/openpgp/test/PGPDSATest.cs
new file mode 100644
index 000000000..7808ed6cd
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PGPDSATest.cs
@@ -0,0 +1,597 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+	[TestFixture]
+    public class PgpDsaTest
+		: SimpleTest
+    {
+		private static readonly byte[] testPubKey = Base64.Decode(
+              "mQGiBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ"
+            + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV"
+            + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/"
+            + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug"
+            + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu"
+            + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ"
+            + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz"
+            + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej"
+            + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbLQzRXJpYyBFY2hp"
+            + "ZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExEC"
+            + "ABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j9enEyjRDAlwAn2rrom0s"
+            + "MhufWK5vIRwg7gj5qsLEAJ4vnT5dPBVblofsG+pDoCVeJXGGng==");
+
+		private static readonly byte[] testPrivKey = Base64.Decode(
+			  "lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ"
+            + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV"
+            + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/"
+            + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug"
+            + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu"
+            + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ"
+            + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz"
+            + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej"
+            + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC"
+            + "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu"
+            + "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh"
+            + "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j"
+            + "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD"
+            + "4nXkHg==");
+
+		private static readonly byte[] testPrivKey2 = Base64.Decode(
+              "lQHhBEAnoewRBADRvKgDhbV6pMzqYfUgBsLxSHzmycpuxGbjMrpyKHDOEemj"
+            + "iQb6TyyBKUoR28/pfshFP9R5urtKIT7wjVrDuOkxYkgRhNm+xmPXW2Lw3D++"
+            + "MQrC5VWe8ywBltz6T9msmChsaKo2hDhIiRI/mg9Q6rH9pJKtVGi4R7CgGxM2"
+            + "STQ5fwCgub38qGS1W2O4hUsa+3gva5gaNZUEAItegda4/H4t88XdWxW3D8pv"
+            + "RnFz26/ADdImVaQlBoumD15VmcgYoT1Djizey7X8vfV+pntudESzLbn3GHlI"
+            + "6C09seH4e8eYP63t7KU/qbUCDomlSswd1OgQ/RxfN86q765K2t3K1i3wDSxe"
+            + "EgSRyGKee0VNvOBFOFhuWt+patXaBADE1riNkUxg2P4lBNWwu8tEZRmsl/Ys"
+            + "DBIzXBshoMzZCvS5PnNXMW4G3SAaC9OC9jvKSx9IEWhKjfjs3QcWzXR28mcm"
+            + "5na0bTxeOMlaPPhBdkTCmFl0IITWlH/pFlR2ah9WYoWYhZEL2tqB82wByzxH"
+            + "SkSeD9V5oeSCdCcqiqkEmv4DAwLeNsQ2XGJVRmA4lld+CR5vRxpT/+/2xklp"
+            + "lxVf/nx0+thrHDpro3u/nINIIObk0gh59+zaEEe3APlHqbQVYWFhIGJiYiA8"
+            + "Y2NjQGRkZC5lZWU+iFoEExECABoFAkAnoewFCwcDAgEDFQIDAxYCAQIeAQIX"
+            + "gAAKCRA5nBpCS63az85BAKCbPfU8ATrFvkXhzGNGlc1BJo6DWQCgnK125xVK"
+            + "lWLpt6ZJJ7TXcx3nkm6wAgAAnQFXBEAnoe0QBACsQxPvaeBcv2TkbgU/5Wc/"
+            + "tO222dPE1mxFbXjGTKfb+6ge96iyD8kTRLrKCkEEeVBa8AZqMSoXUVN6tV8j"
+            + "/zD8Bc76o5iJ6wgpg3Mmy2GxInVfsfZN6/G3Y2ukmouz+CDNvQdUw8cTguIb"
+            + "QoV3XhQ03MLbfVmNcHsku9F4CuKNWwADBQP0DSSe8v5PXF9CSCXOIxBDcQ5x"
+            + "RKjyYOveqoH/4lbOV0YNUbIDZq4RaUdotpADuPREFmWf0zTB6KV/WIiag8XU"
+            + "WU9zdDvLKR483Bo6Do5pDBcN+NqfQ+ntGY9WJ7BSFnhQ3+07i1K+NsfFTRfv"
+            + "hf9X3MP75rCf7MxAIWHTabEmUf4DAwLeNsQ2XGJVRmA8DssBUCghogG9n8T3"
+            + "qfBeKsplGyCcF+JjPeQXkKQaoYGJ0aJz36qFP9d8DuWtT9soQcqIxVf6mTa8"
+            + "kN1594hGBBgRAgAGBQJAJ6HtAAoJEDmcGkJLrdrPpMkAnRyjQSKugz0YJqOB"
+            + "yGasMLQLxd2OAKCEIlhtCarlufVQNGZsuWxHVbU8crACAAA=");
+
+		private static readonly byte[] sig1 = Base64.Decode(
+              "owGbwMvMwCR4VvnryyOnTJwZ10gncZSkFpfolVSU2Ltz78hIzcnJVyjPL8pJUeTq"
+            + "sGdmZQCJwpQLMq3ayTA/0Fj3xf4jbwPfK/H3zj55Z9L1n2k/GOapKJrvMZ4tLiCW"
+            + "GtP/XeDqX4fORDUA");
+
+		private static readonly byte[] sig1crc = Base64.Decode("OZa/");
+
+		private static readonly byte[] testPubWithUserAttr = Base64.Decode(
+              "mQGiBD2Rqv0RBADqKCkhVEtB/lEEr/9CubuHEy2oN/yU5j+2GXSdcNdVnRI/rwFy"
+            + "fHEQIk3uU7zHSUKFrC59yDm0sODYyjEdE3BVb0xvEJ5LE/OdndcIMXT1DungZ1vB"
+            + "zIK/3lr33W/PHixYxv9jduH3WrTehBpiKkgMZp8XloSFj2Cnw9LDyfqB7QCg/8K1"
+            + "o2k75NkOd9ZjnA9ye7Ri3bEEAKyr61Mo7viPWBK1joWAEsxG0OBWM+iSlG7kwh31"
+            + "8efgC/7Os6x4Y0jzs8mpcbBjeZtZjS9lRbfp7RinhF269xL0TZ3JxIdtaAV/6yDQ"
+            + "9NXfZY9dskN++HIR/5GCEEgq/qTJZt6ti5k7aV19ZFfO6wiK3NUy08wOrVsdOkVE"
+            + "w9IcBADaplhpcel3201uU3OCboogJtw81R5MJMZ4Y9cKL/ca2jGISn0nA7KrAw9v"
+            + "ShheSixGO4BV9JECkLEbtg7i+W/j/De6S+x2GLNcphuTP3UmgtKbhs0ItRqzW561"
+            + "s6gLkqi6aWmgaFLd8E1pMJcd9DSY95P13EYB9VJIUxFNUopzo7QcUmFsZiBIYXVz"
+            + "ZXIgPGhhdXNlckBhY20ub3JnPokAWAQQEQIAGAUCPZGq/QgLAwkIBwIBCgIZAQUb"
+            + "AwAAAAAKCRAqIBiOh4JvOKg4AJ9j14yygOqqzqiLKeaasIzqT8LCIgCggx14WuLO"
+            + "wOUTUswTaVKMFnU7tseJAJwEEAECAAYFAj2Rqx8ACgkQ9aWTKMpUDFV+9QP/RiWT"
+            + "5FAF5Rgb7beaApsgXsME+Pw7HEYFtqGa6VcXEpbcUXO6rjaXsgMgY90klWlWCF1T"
+            + "HOyKITvj2FdhE+0j8NQn4vaGpiTwORW/zMf/BZ0abdSWQybp10Yjs8gXw30UheO+"
+            + "F1E524MC+s2AeUi2hwHMiS+AVYd4WhxWHmWuBpTRypP/AAALTgEQAAEBAAAAAQAA"
+            + "AAABAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQ"
+            + "Dg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/"
+            + "2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7"
+            + "Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCABqAF0DASIAAhEBAxEB/8QAHwAAAQUB"
+            + "AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID"
+            + "AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0"
+            + "NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT"
+            + "lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl"
+            + "5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL"
+            + "/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB"
+            + "CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpj"
+            + "ZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3"
+            + "uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR"
+            + "AxEAPwD2aiiq9xcxWsRllcKqjOT06E/0oAsVm6jrmm6VGXvLuOPGflz8x+grzXxV"
+            + "8U51u5LXRgBGowZHXknnkc9OQcV51caneXdw9xPOXlckl2AJHY4J6cD1oA9J1z4p"
+            + "TRkrYQhRyQ0hIY5/2QRx7k9ulczN8SvEEshdZkX0UorDrznI759a5Mksckkknqec"
+            + "mkoA7WD4oavEoEttbTepYEZ+mCMVv6H8SLTULhbe/gFozAYkD5Unp3Ax/kV5XRQB"
+            + "9EAhgCDkHkEcgilryTwd4zn0m4WzvpTJZSMBuY5MfbueletKyugZWDKwyCOc/j3o"
+            + "AduyWLDeWB5Ynj8jSUUUAdFXn/xU15dO0RbGGYC5uWwUB6L1Jx+n413F1cJa2stz"
+            + "J92JC5+gGa+bdfvp9S1q4urmRneQg5Yk4HGAPYZoAzySxySSSep5yaSvQvAPhOHU"
+            + "rB7u5iLGUlIwQRx7HPr/AJ9LGsfC+dJGngc+X12gc8nvx1/rQB5rRXS3Xg28t9ye"
+            + "VLvA7Ddj8MDt6Vnx6JKJCsocnBwqqQSOxPH+fWgDKorTl0SaLGXxkZ+ZcZ4z1yfb"
+            + "P1qg0MqLueN1A6kqRigCOvVPh74mF9YjS7tgLi3GIm6b17c+oOfrXlda3haeW38R"
+            + "WjxfeMgBOCcD/PHpzQB7nRRRQBqarZjUNLubPJXz4yhI64PFfO3iDRrnRtdm0+cq"
+            + "0ocEbehzyOv1xX0vXnHxU8Kf2hYf23aRk3VsMTAZO6MZ5x7UAbfga1W00WzjRSF8"
+            + "kbsg5z744HT/ADmuoysikdQSVP8AI1yPgq6il0axk27V8sDcTg5x7V1qSxOcJIrH"
+            + "/ZOaAKV5p8JgJSPJGMr97PNcxqOiRXLiRI8nONoIGO55z/8AqyeldhPcQxwyOzoQ"
+            + "owRkflXH6t4q0nTLjy57mNXfJCA5x+Qx0NAGXd6LD5iiaPYwTAAx07+vXvXOXmiR"
+            + "Qu6u5VTk/MQQV7cdvxPT866KbxTpt7HGR8p7SMw5HuOP8/Ws/ULlb2No0bKMOGBJ"
+            + "BHrjHHXn6D8QDzWZQk8iAYVWIA9K6LwDZNeeJ4sEqsaF2YHBHpz2/wA/WsG+V0vZ"
+            + "kkGGVsEZz9OcntXffC62iiS7vJTsklKxRFuAw6nBP+eKAPRKKKKAOiqOSNJYzHIo"
+            + "ZGGCD0NSUUAeRajIunwzQG4e3tYZTHGsPzOxJ6ADuQcH8Pw5v+19Q0rVJVgl1JG3"
+            + "cxykEj13cnHT1r1C38OQ3l063cIkkhmkZDKSeCfx9R/kVLeeGIRKs7hVVDn5OCx9"
+            + "yeTjqMf0oAo3k1xP4biuJFeKV4w7gDaQcen1/wAjt5gbK81HW41kIiJBZppULe47"
+            + "eoxx+YzivW9Vh/0FAE+XPIJGCOR0rnbPT7eG+LyxlkAG1wQSPXrjvg9MfjQBycNj"
+            + "4hMRZgJkUjETQqAy/UAY6DoO/wCNbVlYTNbSNJbmBlBwoUfM30B7j2/lz20VhbKA"
+            + "wHmZOQWbOfyrO1G3jil8tBhWToOcdu+c/wAvagDzbUdGlu9aRxFiB/vsuBggZOfq"
+            + "cfWujSIR2dnNZTEeXKgMcb4BUHjofbjNKmI5juiabaGGxVJLcdh/nFWtI0oxagsD"
+            + "DIkkWXYp4VQDnOemSfyHbigDtgSQMjBI6HqKKKKAOiopoPXjGKdQBnXLiDUI5SMK"
+            + "VwxHGf8APFUtW1A+YkMKmbnc23njuf6D/ObWquoaNSQCM/rwP1rMYxxTGWR1UsoU"
+            + "biAcdep+o/KgDG1LxdpracIirCVRjaykHr6cHGQe1cv/AGjNcXBW3sntyT/rHcjj"
+            + "Hp6Z+nQdAK6PXIdIvcE3Fv5rEfNgP9eRn8c8d/rgzX2i2sqo1y8745CD5WPseOnH"
+            + "f8aANiz1O9gjiR5FMUhAV1wcH0Ix6jHHSrMsskz7pGy2MZNc8PEEM7xxWsM/lr8r"
+            + "b4jtI9CcHt7nr7Vqi4JuEjB2qse9y2Ace47dRn/OQDMuRMl8RHw7SgDBPGT6jpwf"
+            + "yzXa2NmbYF3IMrDB2kkAe3HP5Vwk99u1hdg3ANuOOOB0z6ZwPz6c8eiAhgCDkHkE"
+            + "cgigBaKKKAOiqJiMEb9mBknjim3LFIGcOU285ArNa8mKIN3QclScn6+/FADL9xOc"
+            + "K2Tj7xAxnAwQPqOmawdSNpeSJBfQyGNXwQpIAPvjqOPyPT12nYsxYnJIGSeMnHP+"
+            + "e9UL7TUumEqOYp1GNw6N/vDv/wDXoA5+70vSbFGlhtopUxkBl3EZ45z7/kKwTdpN"
+            + "cIsOmeSCduUiCnB9cdeg/M/j0v8AbFtY5hu0gjmGSRICT19cdMDt3+lULzxPZGZv"
+            + "LXcBnCrwB6Y4PX+ZoAptMRbiMDAGSSMksf8A9Q6DuKzJtVYs+BvcPgMTkEdOTnrx"
+            + "/KoLzVmvZZQjjaT82DyPbqcdx+GKitLf7TNsLYAGWPfH+TQBcsYJDE0rOyu4wjHk"
+            + "gfQ+p/zzWjpnja5sdSOm6yyK0Z2pMCQjZ+6SM9CCMdhnp3E1hYy393FaW0eXfjAx"
+            + "gAdT26D+X4Vg/EuFLbxOsCYBitkQkEdsgcADsB+lAHplvqUbsu5vlYA5PIB7468e"
+            + "nPf8lfUlDkRRrIvqZNn6EV41o3iO/wBFcCJ/MhBP7pjwD6g9ua7G08b6TcRl7h5L"
+            + "eTPKvGz5+hUH9cUAeo3uFDrt+Y4O7HOOB69Pr/8AXqhUlx/r2/z2qOgBCQoJJwBy"
+            + "SeABXHeIfHVvbXcemaW4luHlVJJlIKxjODgg8nqKq/Em6uItOhWOeVAx5CuRnrXn"
+            + "+jf8hyw/6+Y//QhQB6xrmlxzXc0NyuHVyQcdjnBz379D1BGeK5u88LMJGlt2RlX7"
+            + "qkEsPXn6/pXo/ilVzbttG7DDOOeornqAONbRpI4v3pKOQcAqQD+Y/P6j052NK0p5"
+            + "HWHy3IBPyqrfN6gZz+P4/hpXoGzOOiP/ACNdH4XRftsp2jIBxx70AX9E0pdMtvMm"
+            + "VRNt5xyEGOgPf3NeDeLdVOs+J768zlGkKx+yjgfy/WvoPXeNEvMcfujXzJQAUUUU"
+            + "Af/ZiQBGBBARAgAGBQI9katEAAoJECogGI6Hgm84xz8AoNGz1fJrVPxqkBrUDmWA"
+            + "GsP6qVGYAJ0ZOftw/GfQHzdGR8pOK85DLUPEErQkUmFsZiBIYXVzZXIgPGhhdXNl"
+            + "ckBwcml2YXNwaGVyZS5jb20+iQBGBBARAgAGBQI9katmAAoJECogGI6Hgm84m0oA"
+            + "oJS3CTrgpqRZfhgPtHGtUVjRCJbbAJ9stJgPcbqA2xXEg9yl2TQToWdWxbQkUmFs"
+            + "ZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5vcmc+iQBGBBARAgAGBQI9kauJ"
+            + "AAoJECogGI6Hgm84GfAAnRswktLMzDfIjv6ni76Qp5B850byAJ90I0LEHOLhda7r"
+            + "kqTwZ8rguNssUrQkUmFsZiBIYXVzZXIgPGhhdXNlckBwcml2YXNwaGVyZS5uZXQ+"
+            + "iQBGBBARAgAGBQI9kaubAAoJECogGI6Hgm84zi0An16C4s/B9Z0/AtfoN4ealMh3"
+            + "i3/7AJ9Jg4GOUqGCGRRKUA9Gs5pk8yM8GbQmUmFsZiBDLiBIYXVzZXIgPHJhbGZo"
+            + "YXVzZXJAYmx1ZXdpbi5jaD6JAEYEEBECAAYFAj2Rq8oACgkQKiAYjoeCbzhPOACg"
+            + "iiTohKuIa66FNiI24mQ+XR9nTisAoLmh3lJf16/06qLPsRd9shTkLfmHtB9SYWxm"
+            + "IEhhdXNlciA8cmFsZmhhdXNlckBnbXguY2g+iQBGBBARAgAGBQI9kavvAAoJECog"
+            + "GI6Hgm84ZE8An0RlgL8mPBa/P08S5e/lD35MlDdgAJ99pjCeY46S9+nVyx7ACyKO"
+            + "SZ4OcLQmUmFsZiBIYXVzZXIgPGhhdXNlci5yYWxmQG15c3VucmlzZS5jaD6JAEYE"
+            + "EBECAAYFAj2RrEEACgkQKiAYjoeCbzjz0wCg+q801XrXk+Rf+koSI50MW5OaaKYA"
+            + "oKOVA8SLxE29qSR/bJeuW0ryzRLqtCVSYWxmIEhhdXNlciA8aGF1c2VyLnJhbGZA"
+            + "ZnJlZXN1cmYuY2g+iQBGBBARAgAGBQI9kaxXAAoJECogGI6Hgm848zoAnRBtWH6e"
+            + "fTb3is63s8J2zTfpsyS0AKDxTjl+ZZV0COHLrSCaNLZVcpImFrkEDQQ9kar+EBAA"
+            + "+RigfloGYXpDkJXcBWyHhuxh7M1FHw7Y4KN5xsncegus5D/jRpS2MEpT13wCFkiA"
+            + "tRXlKZmpnwd00//jocWWIE6YZbjYDe4QXau2FxxR2FDKIldDKb6V6FYrOHhcC9v4"
+            + "TE3V46pGzPvOF+gqnRRh44SpT9GDhKh5tu+Pp0NGCMbMHXdXJDhK4sTw6I4TZ5dO"
+            + "khNh9tvrJQ4X/faY98h8ebByHTh1+/bBc8SDESYrQ2DD4+jWCv2hKCYLrqmus2UP"
+            + "ogBTAaB81qujEh76DyrOH3SET8rzF/OkQOnX0ne2Qi0CNsEmy2henXyYCQqNfi3t"
+            + "5F159dSST5sYjvwqp0t8MvZCV7cIfwgXcqK61qlC8wXo+VMROU+28W65Szgg2gGn"
+            + "VqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf3HZSTz09jdvOmeFX"
+            + "klnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2gpXI61Brwv0YAWCvl"
+            + "9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhd"
+            + "ONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r"
+            + "0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVes91hcAAgIQAKD9MGkS8SUD2irI"
+            + "AiwVHU0WXLBnk2CvvueSmT9YtC34UKkIkDPZ7VoeuXDfqTOlbiE6T16zPvArZfbl"
+            + "JGdrU7HhsTdu+ADxRt1dPur0G0ICJ3pBD3ydGWpdLI/94x1BvTY4rsR5mS4YWmpf"
+            + "e2kWc7ZqezhP7Xt9q7m4EK456ddeUZWtkwGU+PKyRAZ+CK82Uhouw+4aW0NjiqmX"
+            + "hfH9/BUhI1P/8R9VkTfAFGPmZzqoHr4AuO5tLRLD2RFSmQCP8nZTiP9nP+wBBvn7"
+            + "vuqKRQsj9PwwPD4V5SM+kpW+rUIWr9TZYl3UqSnlXlpEZFd2Bfl6NloeH0cfU69E"
+            + "gtjcWGvGxYKPS0cg5yhVb4okka6RqIPQiYl6eJgv4tRTKoPRX29o0aUVdqVvDr5u"
+            + "tnFzcINq7jTo8GiO8Ia3cIFWfo0LyQBd1cf1U+eEOz+DleEFqyljaz9VCbDPE4GP"
+            + "o+ALESBlOwn5daUSaah9iU8aVPaSjn45hoQqxOKPwJxnCKKQ01iy0Gir+CDU8JJB"
+            + "7bmbvQN4bke30EGAeED3oi+3VaBHrhjYLv7SHIxP5jtCJKWMJuLRV709HsWJi3kn"
+            + "fGHwH+yCDF8+PDeROAzpXBaD2EFhKgeUTjP5Rgn6ltRf8TQnfbW4qlwyiXMhPOfC"
+            + "x6qNmwaFPKQJpIkVq5VGfRXAERfkiQBMBBgRAgAMBQI9kar+BRsMAAAAAAoJECog"
+            + "GI6Hgm84CDMAoNrNeP4c8XqFJnsLLPcjk5YGLaVIAKCrL5KFuLQVIp7d0Fkscx3/"
+            + "7DGrzw==");
+
+		private static readonly byte[] aesSecretKey = Base64.Decode(
+              "lQHpBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN"
+            + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj"
+            + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA"
+            + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo"
+            + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5"
+            + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN"
+            + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X"
+            + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF"
+            + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV"
+            + "jTxKmrLYnZz5w5qyVpvRyv4JAwKyWlhdblPudWBFXNkW5ydKn0AV2f51wEtj"
+            + "Zy0aLIeutVMSJf1ytLqjFqrnFe6pdJrHO3G00TE8OuFhftWosLGLbEGytDtF"
+            + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gQUVTMjU2KSA8ZXJpY0Bib3Vu"
+            + "Y3ljYXN0bGUub3JnPohZBBMRAgAZBQJAUnSGBAsHAwIDFQIDAxYCAQIeAQIX"
+            + "gAAKCRBYt1NnUiCgeFKaAKCiqtOO+NQES1gJW6XuOGmSkXt8bQCfcuW7SXZH"
+            + "zxK1FfdcG2HEDs3YEVawAgAA");
+
+		private static readonly byte[] aesPublicKey = Base64.Decode(
+              "mQGiBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN"
+            + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj"
+            + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA"
+            + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo"
+            + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5"
+            + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN"
+            + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X"
+            + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF"
+            + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV"
+            + "jTxKmrLYnZz5w5qyVpvRyrQ7RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt"
+            + "IEFFUzI1NikgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ0"
+            + "hgQLBwMCAxUCAwMWAgECHgECF4AACgkQWLdTZ1IgoHhSmgCfU83BLBF2nCua"
+            + "zk2dXB9zO1l6XS8AnA07U4cq5W0GrKM6/kP9HWtPhgOFsAIAAA==");
+
+		private static readonly byte[] twofishSecretKey = Base64.Decode(
+              "lQHpBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc"
+            + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8"
+            + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p"
+            + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/"
+            + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2"
+            + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG"
+            + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK"
+            + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v"
+            + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj"
+            + "KJs01YT3L6f0iIj03hCeV/4KAwLcGrxT3X0qR2CZyZYSVBdjXeNYKXuGBtOf"
+            + "ood26WOtwLw4+l9sHVoiXNv0LomkO58ndJRPGCeZWZEDMVrfkS7rcOlktDxF"
+            + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gdHdvZmlzaCkgPGVyaWNAYm91"
+            + "bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ20gQLBwMCAxUCAwMWAgECHgEC"
+            + "F4AACgkQaCCMaHh9zR2+RQCghcQwlt4B4YmNxp2b3v6rP3E8M0kAn2Gspi4u"
+            + "A/ynoqnC1O8HNlbjPdlVsAIAAA==");
+
+		private static readonly byte[] twofishPublicKey = Base64.Decode(
+              "mQGiBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc"
+            + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8"
+            + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p"
+            + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/"
+            + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2"
+            + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG"
+            + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK"
+            + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v"
+            + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj"
+            + "KJs01YT3L6f0iIj03hCeV7Q8RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt"
+            + "IHR3b2Zpc2gpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkFAkBS"
+            + "dtIECwcDAgMVAgMDFgIBAh4BAheAAAoJEGggjGh4fc0dvkUAn2QGdNk8Wrrd"
+            + "+DvKECrO5+yoPRx3AJ91DhCMme6uMrQorKSDYxHlgc7iT7ACAAA=");
+
+		private static readonly char[] pass = "hello world".ToCharArray();
+
+		/**
+        * Generated signature test
+        *
+        * @param sKey
+        * @param pgpPrivKey
+        * @return test result
+        */
+        public void GenerateTest(
+            PgpSecretKeyRing sKey,
+            PgpPublicKey     pgpPubKey,
+            PgpPrivateKey    pgpPrivKey)
+        {
+            string data = "hello world!";
+            MemoryStream bOut = new MemoryStream();
+
+            byte[] dataBytes = Encoding.ASCII.GetBytes(data);
+            MemoryStream testIn = new MemoryStream(dataBytes, false);
+
+            PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);
+
+            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
+
+            PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
+
+            IEnumerator enumerator = sKey.GetSecretKey().PublicKey.GetUserIds().GetEnumerator();
+            enumerator.MoveNext();
+            string primaryUserId = (string) enumerator.Current;
+
+            spGen.SetSignerUserId(true, primaryUserId);
+
+            sGen.SetHashedSubpackets(spGen.Generate());
+
+            PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(
+                CompressionAlgorithmTag.Zip);
+
+            BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut)));
+
+            sGen.GenerateOnePassVersion(false).Encode(bcOut);
+
+            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+
+			DateTime testDateTime = new DateTime(1973, 7, 27);
+			Stream lOut = lGen.Open(
+				new UncloseableStream(bcOut),
+				PgpLiteralData.Binary,
+				"_CONSOLE",
+				dataBytes.Length,
+				testDateTime);
+
+			int ch;
+            while ((ch = testIn.ReadByte()) >= 0)
+            {
+                lOut.WriteByte((byte) ch);
+                sGen.Update((byte)ch);
+            }
+
+            lGen.Close();
+
+            sGen.Generate().Encode(bcOut);
+
+            cGen.Close();
+
+            PgpObjectFactory pgpFact = new PgpObjectFactory(bOut.ToArray());
+            PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+            pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+			PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+            PgpOnePassSignature ops = p1[0];
+
+            PgpLiteralData p2 = (PgpLiteralData) pgpFact.NextPgpObject();
+			if (!p2.ModificationTime.Equals(testDateTime))
+			{
+				Fail("Modification time not preserved");
+			}
+
+			Stream dIn = p2.GetInputStream();
+
+            ops.InitVerify(pgpPubKey);
+
+			while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte) ch);
+            }
+
+			PgpSignatureList p3 = (PgpSignatureList) pgpFact.NextPgpObject();
+
+			if (!ops.Verify(p3[0]))
+            {
+                Fail("Failed generated signature check");
+            }
+        }
+
+		public override void PerformTest()
+        {
+            PgpPublicKey pubKey = null;
+
+			//
+            // Read the public key
+            //
+            PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey);
+
+			pubKey = pgpPub.GetPublicKey();
+
+            //
+            // Read the private key
+            //
+            PgpSecretKeyRing sKey = new PgpSecretKeyRing(testPrivKey);
+            PgpSecretKey secretKey = sKey.GetSecretKey();
+            PgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey(pass);
+
+            //
+            // test signature message
+            //
+            PgpObjectFactory pgpFact = new PgpObjectFactory(sig1);
+            PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+			pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+            PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+            PgpOnePassSignature ops = p1[0];
+
+            PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject();
+
+            Stream dIn = p2.GetInputStream();
+
+            ops.InitVerify(pubKey);
+
+			int ch;
+			while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte) ch);
+            }
+
+            PgpSignatureList p3 = (PgpSignatureList) pgpFact.NextPgpObject();
+
+            if (!ops.Verify(p3[0]))
+            {
+                Fail("Failed signature check");
+            }
+
+            //
+            // signature generation
+            //
+            GenerateTest(sKey, pubKey, pgpPrivKey);
+
+            //
+            // signature generation - canonical text
+            //
+            const string data = "hello world!";
+            byte[] dataBytes = Encoding.ASCII.GetBytes(data);
+            MemoryStream bOut = new MemoryStream();
+            MemoryStream testIn = new MemoryStream(dataBytes, false);
+            PgpSignatureGenerator sGen = new PgpSignatureGenerator(
+                PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey);
+
+            PgpCompressedDataGenerator  cGen = new PgpCompressedDataGenerator(
+                CompressionAlgorithmTag.Zip);
+
+            BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut)));
+
+            sGen.GenerateOnePassVersion(false).Encode(bcOut);
+
+            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+			DateTime testDateTime = new DateTime(1973, 7, 27);
+			Stream lOut = lGen.Open(
+				new UncloseableStream(bcOut),
+				PgpLiteralData.Text,
+				"_CONSOLE",
+				dataBytes.Length,
+				testDateTime);
+
+			while ((ch = testIn.ReadByte()) >= 0)
+            {
+                lOut.WriteByte((byte) ch);
+                sGen.Update((byte)ch);
+            }
+
+			lGen.Close();
+
+			sGen.Generate().Encode(bcOut);
+
+            cGen.Close();
+
+            //
+            // verify Generated signature - canconical text
+            //
+            pgpFact = new PgpObjectFactory(bOut.ToArray());
+
+            c1 = (PgpCompressedData) pgpFact.NextPgpObject();
+
+            pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+            p1 = (PgpOnePassSignatureList) pgpFact.NextPgpObject();
+
+            ops = p1[0];
+
+            p2 = (PgpLiteralData) pgpFact.NextPgpObject();
+			if (!p2.ModificationTime.Equals(testDateTime))
+			{
+				Fail("Modification time not preserved");
+			}
+
+            dIn = p2.GetInputStream();
+
+            ops.InitVerify(pubKey);
+
+            while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte)ch);
+            }
+
+            p3 = (PgpSignatureList) pgpFact.NextPgpObject();
+
+            if (!ops.Verify(p3[0]))
+            {
+                Fail("Failed generated signature check");
+            }
+
+            //
+            // Read the public key with user attributes
+            //
+            pgpPub = new PgpPublicKeyRing(testPubWithUserAttr);
+
+            pubKey = pgpPub.GetPublicKey();
+
+            int count = 0;
+            foreach (PgpUserAttributeSubpacketVector attributes in pubKey.GetUserAttributes())
+            {
+                int sigCount = 0;
+                foreach (object sigs in pubKey.GetSignaturesForUserAttribute(attributes))
+                {
+					if (sigs == null)
+						Fail("null signature found");
+
+					sigCount++;
+                }
+
+                if (sigCount != 1)
+                {
+                    Fail("Failed user attributes signature check");
+                }
+
+                count++;
+            }
+
+            if (count != 1)
+            {
+                Fail("Failed user attributes check");
+            }
+
+            byte[]  pgpPubBytes = pgpPub.GetEncoded();
+            pgpPub = new PgpPublicKeyRing(pgpPubBytes);
+            pubKey = pgpPub.GetPublicKey();
+            count = 0;
+
+			foreach (object ua in pubKey.GetUserAttributes())
+            {
+				if (ua == null)
+					Fail("null user attribute found");
+
+				count++;
+            }
+
+			if (count != 1)
+            {
+                Fail("Failed user attributes reread");
+            }
+
+            //
+            // reading test extra data - key with edge condition for DSA key password.
+            //
+            char[] passPhrase = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
+
+			sKey = new PgpSecretKeyRing(testPrivKey2);
+            pgpPrivKey = sKey.GetSecretKey().ExtractPrivateKey(passPhrase);
+
+			//
+            // reading test - aes256 encrypted passphrase.
+            //
+            sKey = new PgpSecretKeyRing(aesSecretKey);
+            pgpPrivKey = sKey.GetSecretKey().ExtractPrivateKey(pass);
+
+            //
+            // reading test - twofish encrypted passphrase.
+            //
+            sKey = new PgpSecretKeyRing(twofishSecretKey);
+            pgpPrivKey = sKey.GetSecretKey().ExtractPrivateKey(pass);
+
+			//
+            // use of PgpKeyPair
+            //
+            DsaParametersGenerator pGen = new DsaParametersGenerator();
+            pGen.Init(512, 80, new SecureRandom()); // TODO Is the certainty okay?
+            DsaParameters dsaParams = pGen.GenerateParameters();
+            DsaKeyGenerationParameters kgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams);
+			IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("DSA");
+			kpg.Init(kgp);
+
+
+			AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();
+
+            PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.Dsa,
+                kp.Public, kp.Private, DateTime.UtcNow);
+
+			PgpPublicKey k1 = pgpKp.PublicKey;
+            PgpPrivateKey k2 = pgpKp.PrivateKey;
+        }
+
+		public override string Name
+        {
+			get { return "PGPDSATest"; }
+        }
+
+		public static void Main(
+			string[] args)
+        {
+			RunTest(new PgpDsaTest());
+        }
+
+		[Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/PGPPBETest.cs b/crypto/test/src/openpgp/test/PGPPBETest.cs
new file mode 100644
index 000000000..621cef684
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PGPPBETest.cs
@@ -0,0 +1,384 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    [TestFixture]
+    public class PgpPbeTest
+		: SimpleTest
+    {
+		private static readonly DateTime TestDateTime = new DateTime(2003, 8, 29, 23, 35, 11, 0);
+
+		private static readonly byte[] enc1 = Base64.Decode(
+            "jA0EAwMC5M5wWBP2HBZgySvUwWFAmMRLn7dWiZN6AkQMvpE3b6qwN3SSun7zInw2"
+            + "hxxdgFzVGfbjuB8w");
+//        private static readonly byte[] enc1crc = Base64.Decode("H66L");
+		private static readonly char[] pass = "hello world".ToCharArray();
+
+		/**
+		 * Message with both PBE and symmetric
+		 */
+		private static readonly byte[] testPBEAsym = Base64.Decode(
+			"hQIOA/ZlQEFWB5vuEAf/covEUaBve7NlWWdiO5NZubdtTHGElEXzG9hyBycp9At8" +
+			"nZGi27xOZtEGFQo7pfz4JySRc3O0s6w7PpjJSonFJyNSxuze2LuqRwFWBYYcbS8/" +
+			"7YcjB6PqutrT939OWsozfNqivI9/QyZCjBvFU89pp7dtUngiZ6MVv81ds2I+vcvk" +
+			"GlIFcxcE1XoCIB3EvbqWNaoOotgEPT60unnB2BeDV1KD3lDRouMIYHfZ3SzBwOOI" +
+			"6aK39sWnY5sAK7JjFvnDAMBdueOiI0Fy+gxbFD/zFDt4cWAVSAGTC4w371iqppmT" +
+			"25TM7zAtCgpiq5IsELPlUZZnXKmnYQ7OCeysF0eeVwf+OFB9fyvCEv/zVQocJCg8" +
+			"fWxfCBlIVFNeNQpeGygn/ZmRaILvB7IXDWP0oOw7/F2Ym66IdYYIp2HeEZv+jFwa" +
+			"l41w5W4BH/gtbwGjFQ6CvF/m+lfUv6ZZdzsMIeEOwhP5g7rXBxrbcnGBaU+PXbho" +
+			"gjDqaYzAWGlrmAd6aPSj51AGeYXkb2T1T/yoJ++M3GvhH4C4hvitamDkksh/qRnM" +
+			"M/s8Nku6z1+RXO3M6p5QC1nlAVqieU8esT43945eSoC77K8WyujDNbysDyUCUTzt" +
+			"p/aoQwe/HgkeOTJNelKR9y2W3xinZLFzep0SqpNI/e468yB/2/LGsykIyQa7JX6r" +
+			"BYwuBAIDAkOKfv5rK8v0YDfnN+eFqwhTcrfBj5rDH7hER6nW3lNWcMataUiHEaMg" +
+			"o6Q0OO1vptIGxW8jClTD4N1sCNwNu9vKny8dKYDDHbCjE06DNTv7XYVW3+JqTL5E" +
+			"BnidvGgOmA==");
+
+		/**
+        * decrypt the passed in message stream
+        */
+        private byte[] DecryptMessage(
+            byte[] message)
+        {
+            PgpObjectFactory		pgpF = new PgpObjectFactory(message);
+            PgpEncryptedDataList	enc = (PgpEncryptedDataList) pgpF.NextPgpObject();
+            PgpPbeEncryptedData		pbe = (PgpPbeEncryptedData) enc[0];
+            Stream					clear = pbe.GetDataStream(pass);
+
+			PgpObjectFactory		pgpFact = new PgpObjectFactory(clear);
+            PgpCompressedData		cData = (PgpCompressedData) pgpFact.NextPgpObject();
+            pgpFact = new PgpObjectFactory(cData.GetDataStream());
+
+			PgpLiteralData ld = (PgpLiteralData) pgpFact.NextPgpObject();
+
+            if (!ld.FileName.Equals("test.txt")
+                && !ld.FileName.Equals("_CONSOLE"))
+            {
+                Fail("wrong filename in packet");
+            }
+
+			if (!ld.ModificationTime.Equals(TestDateTime))
+			{
+				Fail("wrong modification time in packet: " + ld.ModificationTime + " vs " + TestDateTime);
+			}
+
+			Stream unc = ld.GetInputStream();
+			byte[] bytes = Streams.ReadAll(unc);
+
+			if (pbe.IsIntegrityProtected() && !pbe.Verify())
+			{
+				Fail("integrity check failed");
+			}
+
+			return bytes;
+        }
+
+		private byte[] DecryptMessageBuffered(
+			byte[] message)
+		{
+			PgpObjectFactory		pgpF = new PgpObjectFactory(message);
+			PgpEncryptedDataList	enc = (PgpEncryptedDataList) pgpF.NextPgpObject();
+			PgpPbeEncryptedData		pbe = (PgpPbeEncryptedData) enc[0];
+
+			Stream clear = pbe.GetDataStream(pass);
+
+			PgpObjectFactory	pgpFact = new PgpObjectFactory(clear);
+			PgpCompressedData	cData = (PgpCompressedData) pgpFact.NextPgpObject();
+
+			pgpFact = new PgpObjectFactory(cData.GetDataStream());
+
+			PgpLiteralData ld = (PgpLiteralData) pgpFact.NextPgpObject();
+
+			MemoryStream bOut = new MemoryStream();
+			if (!ld.FileName.Equals("test.txt")
+				&& !ld.FileName.Equals("_CONSOLE"))
+			{
+				Fail("wrong filename in packet");
+			}
+			if (!ld.ModificationTime.Equals(TestDateTime))
+			{
+				Fail("wrong modification time in packet: " + ld.ModificationTime.Ticks + " " + TestDateTime.Ticks);
+			}
+
+			Stream unc = ld.GetInputStream();
+			byte[] buf = new byte[1024];
+
+			int len;
+			while ((len = unc.Read(buf, 0, buf.Length)) > 0)
+			{
+				bOut.Write(buf, 0, len);
+			}
+
+			if (pbe.IsIntegrityProtected() && !pbe.Verify())
+			{
+				Fail("integrity check failed");
+			}
+
+			return bOut.ToArray();
+		}
+
+		public override void PerformTest()
+        {
+            byte[] data = DecryptMessage(enc1);
+            if (data[0] != 'h' || data[1] != 'e' || data[2] != 'l')
+            {
+                Fail("wrong plain text in packet");
+            }
+
+			//
+            // create a PBE encrypted message and read it back.
+            //
+			byte[] text = Encoding.ASCII.GetBytes("hello world!\n");
+
+			//
+            // encryption step - convert to literal data, compress, encode.
+            //
+            MemoryStream bOut = new UncloseableMemoryStream();
+
+            PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(
+                CompressionAlgorithmTag.Zip);
+
+            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
+			Stream comOut = comData.Open(new UncloseableStream(bOut));
+            Stream ldOut = lData.Open(
+				new UncloseableStream(comOut),
+                PgpLiteralData.Binary,
+                PgpLiteralData.Console,
+                text.Length,
+                TestDateTime);
+
+			ldOut.Write(text, 0, text.Length);
+			ldOut.Close();
+
+			comOut.Close();
+
+			//
+            // encrypt - with stream close
+            //
+            MemoryStream cbOut = new UncloseableMemoryStream();
+            PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(
+				SymmetricKeyAlgorithmTag.Cast5, new SecureRandom());
+
+            cPk.AddMethod(pass);
+
+			byte[] bOutData = bOut.ToArray();
+			Stream cOut = cPk.Open(new UncloseableStream(cbOut), bOutData.Length);
+            cOut.Write(bOutData, 0, bOutData.Length);
+            cOut.Close();
+
+			data = DecryptMessage(cbOut.ToArray());
+            if (!Arrays.AreEqual(data, text))
+            {
+                Fail("wrong plain text in generated packet");
+            }
+
+			//
+			// encrypt - with generator close
+			//
+			cbOut = new UncloseableMemoryStream();
+			cPk = new PgpEncryptedDataGenerator(
+				SymmetricKeyAlgorithmTag.Cast5, new SecureRandom());
+
+			cPk.AddMethod(pass);
+
+			bOutData = bOut.ToArray();
+			cOut = cPk.Open(new UncloseableStream(cbOut), bOutData.Length);
+			cOut.Write(bOutData, 0, bOutData.Length);
+
+			cPk.Close();
+
+			data = DecryptMessage(cbOut.ToArray());
+
+			if (!AreEqual(data, text))
+			{
+				Fail("wrong plain text in generated packet");
+			}
+
+			//
+            // encrypt - partial packet style.
+            //
+            SecureRandom rand = new SecureRandom();
+            byte[] test = new byte[1233];
+
+            rand.NextBytes(test);
+
+			bOut = new UncloseableMemoryStream();
+
+			comData = new PgpCompressedDataGenerator(
+				CompressionAlgorithmTag.Zip);
+			comOut = comData.Open(new UncloseableStream(bOut));
+
+			lData = new PgpLiteralDataGenerator();
+            ldOut = lData.Open(
+				new UncloseableStream(comOut),
+                PgpLiteralData.Binary,
+                PgpLiteralData.Console,
+                TestDateTime,
+                new byte[16]);
+
+            ldOut.Write(test, 0, test.Length);
+            lData.Close();
+
+			comData.Close();
+            cbOut = new UncloseableMemoryStream();
+            cPk = new PgpEncryptedDataGenerator(
+				SymmetricKeyAlgorithmTag.Cast5, rand);
+
+            cPk.AddMethod(pass);
+
+			cOut = cPk.Open(new UncloseableStream(cbOut), new byte[16]);
+            {
+                byte[] tmp = bOut.ToArray();
+                cOut.Write(tmp, 0, tmp.Length);
+            }
+
+			cPk.Close();
+
+			data = DecryptMessage(cbOut.ToArray());
+            if (!Arrays.AreEqual(data, test))
+            {
+                Fail("wrong plain text in generated packet");
+            }
+
+            //
+            // with integrity packet
+            //
+            cbOut = new UncloseableMemoryStream();
+            cPk = new PgpEncryptedDataGenerator(
+				SymmetricKeyAlgorithmTag.Cast5, true, rand);
+
+            cPk.AddMethod(pass);
+
+            cOut = cPk.Open(new UncloseableStream(cbOut), new byte[16]);
+            bOutData = bOut.ToArray();
+            cOut.Write(bOutData, 0, bOutData.Length);
+            cPk.Close();
+
+			data = DecryptMessage(cbOut.ToArray());
+            if (!Arrays.AreEqual(data, test))
+            {
+                Fail("wrong plain text in generated packet");
+            }
+
+			//
+			// decrypt with buffering
+			//
+			data = DecryptMessageBuffered(cbOut.ToArray());
+			if (!AreEqual(data, test))
+			{
+				Fail("wrong plain text in buffer generated packet");
+			}
+
+			//
+			// sample message
+			//
+			PgpObjectFactory pgpFact = new PgpObjectFactory(testPBEAsym);
+
+			PgpEncryptedDataList enc = (PgpEncryptedDataList)pgpFact.NextPgpObject();
+
+			PgpPbeEncryptedData pbe = (PgpPbeEncryptedData) enc[1];
+
+			Stream clear = pbe.GetDataStream("password".ToCharArray());
+
+			pgpFact = new PgpObjectFactory(clear);
+
+			PgpLiteralData ld = (PgpLiteralData) pgpFact.NextPgpObject();
+
+			Stream unc = ld.GetInputStream();
+			byte[] bytes = Streams.ReadAll(unc);
+
+			if (!AreEqual(bytes, Hex.Decode("5361742031302e30322e30370d0a")))
+			{
+				Fail("data mismatch on combined PBE");
+			}
+
+			//
+			// with integrity packet - one byte message
+			//
+			byte[] msg = new byte[1];
+			bOut = new MemoryStream();
+
+			comData = new PgpCompressedDataGenerator(
+				CompressionAlgorithmTag.Zip);
+
+			lData = new PgpLiteralDataGenerator();
+			comOut = comData.Open(new UncloseableStream(bOut));
+			ldOut = lData.Open(
+				new UncloseableStream(comOut),
+				PgpLiteralData.Binary,
+				PgpLiteralData.Console,
+				msg.Length,
+				TestDateTime);
+
+			ldOut.Write(msg, 0, msg.Length);
+
+			ldOut.Close();
+
+			comOut.Close();
+        
+			cbOut = new MemoryStream();
+			cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, true, rand);
+
+			cPk.AddMethod(pass);
+
+			cOut = cPk.Open(new UncloseableStream(cbOut), new byte[16]);
+
+			data = bOut.ToArray();
+			cOut.Write(data, 0, data.Length);
+
+			cOut.Close();
+
+			data = DecryptMessage(cbOut.ToArray());
+			if (!AreEqual(data, msg))
+			{
+				Fail("wrong plain text in generated packet");
+			}
+
+			//
+			// decrypt with buffering
+			//
+			data = DecryptMessageBuffered(cbOut.ToArray());
+			if (!AreEqual(data, msg))
+			{
+				Fail("wrong plain text in buffer generated packet");
+			}
+		}
+
+		private class UncloseableMemoryStream
+			: MemoryStream
+		{
+			public override void Close()
+			{
+				throw new Exception("Close() called on underlying stream");
+			}
+		}
+
+		public override string Name
+        {
+			get { return "PGPPBETest"; }
+        }
+
+		public static void Main(
+			string[] args)
+        {
+			RunTest(new PgpPbeTest());
+        }
+
+		[Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/PGPPacketTest.cs b/crypto/test/src/openpgp/test/PGPPacketTest.cs
new file mode 100644
index 000000000..b82f8526f
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PGPPacketTest.cs
@@ -0,0 +1,80 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    [TestFixture]
+    public class PgpPacketTest
+        : SimpleTest
+    {
+        private static int MAX = 32000;
+
+        private void ReadBackTest(
+            PgpLiteralDataGenerator generator)
+        {
+            Random rand = new Random();
+            byte[] buf = new byte[MAX];
+
+            rand.NextBytes(buf);
+
+            for (int i = 1; i != MAX; i++)
+            {
+                MemoryStream bOut = new MemoryStream();
+
+                Stream outputStream = generator.Open(
+					new UncloseableStream(bOut),
+					PgpLiteralData.Binary,
+					PgpLiteralData.Console,
+					i,
+					DateTime.UtcNow);
+
+				outputStream.Write(buf, 0, i);
+
+                generator.Close();
+
+                PgpObjectFactory fact = new PgpObjectFactory(bOut.ToArray());
+
+                PgpLiteralData data = (PgpLiteralData)fact.NextPgpObject();
+
+                Stream inputStream = data.GetInputStream();
+
+                for (int count = 0; count != i; count++)
+                {
+                    if (inputStream.ReadByte() != (buf[count] & 0xff))
+                    {
+                        Fail("failed readback test - length = " + i);
+                    }
+                }
+            }
+        }
+
+        public override void PerformTest()
+        {
+            ReadBackTest(new PgpLiteralDataGenerator(true));
+			ReadBackTest(new PgpLiteralDataGenerator(false));
+        }
+
+		public override string Name
+        {
+			get { return "PGPPacketTest"; }
+        }
+
+		public static void Main(
+            string[] args)
+        {
+			RunTest(new PgpPacketTest());
+        }
+
+		[Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/PGPRSATest.cs b/crypto/test/src/openpgp/test/PGPRSATest.cs
new file mode 100644
index 000000000..f38aa002f
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PGPRSATest.cs
@@ -0,0 +1,1235 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Bcpg.Attr;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    [TestFixture]
+    public class PgpRsaTest
+        : SimpleTest
+    {
+		private static readonly byte[] testPubKey = Base64.Decode(
+			  "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F"
+			+ "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO"
+			+ "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F"
+			+ "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4"
+			+ "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG"
+			+ "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc"
+			+ "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs"
+			+ "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA==");
+
+		private static readonly byte[] testPrivKey = Base64.Decode(
+			  "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP"
+			+ "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x"
+			+ "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D"
+			+ "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990"
+			+ "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw"
+			+ "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw"
+			+ "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb"
+			+ "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY"
+			+ "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF"
+			+ "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO"
+			+ "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0"
+			+ "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb"
+			+ "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO"
+			+ "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN"
+			+ "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1"
+			+ "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w=");
+
+		private static readonly byte[] testPubKeyV3 = Base64.Decode(
+			  "mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO"
+			+ "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB"
+			+ "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F"
+			+ "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA"
+			+ "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP"
+			+ "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4"
+			+ "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY=");
+
+		private static readonly byte[] testPrivKeyV3 = Base64.Decode(
+			  "lQHfAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO"
+			+ "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB"
+			+ "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F"
+			+ "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR"
+			+ "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/"
+			+ "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY"
+			+ "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+"
+			+ "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF"
+			+ "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm"
+			+ "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS"
+			+ "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE=");
+
+		private static readonly byte[] sig1 = Base64.Decode(
+			  "owGbwMvMwMRoGpHo9vfz52LGNTJJnBmpOTn5eiUVJfb23JvAHIXy/KKcFEWuToap"
+			+ "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95"
+			+ "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ"
+			+ "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2"
+			+ "5Fw9AA==");
+
+//		private static readonly byte[] sig1crc = Base64.Decode("+3i0");
+
+		private static readonly byte[] subKey = Base64.Decode(
+			  "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"
+			+ "CphiUYWnsC0mQ+J15B4=");
+
+		private static readonly byte[] enc1 = Base64.Decode(
+			  "hIwDKwfQexPJboABA/4/7prhYYMORTiQ5avQKx0XYpCLujzGefYjnyuWZnx3Iev8"
+			+ "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw"
+			+ "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ"
+			+ "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J"
+			+ "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4=");
+
+//		private static readonly byte[] enc1crc = Base64.Decode("lv4o");
+
+//        private static readonly byte[] enc2 = Base64.Decode(
+//			  "hIwDKwfQexPJboABBAC62jcJH8xKnKb1neDVmiovYON04+7VQ2v4BmeHwJrdag1g"
+//			+ "Ya++6PeBlQ2Q9lSGBwLobVuJmQ7cOnPUJP727JeSGWlMyFtMbBSHekOaTenT5lj7"
+//			+ "Zk7oRHxMp/hByzlMacIDzOn8LPSh515RHM57eDLCOwqnAxGQwk67GRl8f5dFH9JQ"
+//			+ "Aa7xx8rjCqPbiIQW6t5LqCNvPZOiSCmftll6+se1XJhFEuq8WS4nXtPfTiJ3vib4"
+//			+ "3soJdHzGB6AOs+BQ6aKmmNTVAxa5owhtSt1Z/6dfSSk=");
+
+		private static readonly byte[] subPubKey = Base64.Decode(
+              "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F"
+			+ "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO"
+			+ "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F"
+			+ "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4"
+			+ "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG"
+			+ "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc"
+			+ "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs"
+			+ "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrIhMBBARAgAM"
+			+ "BQI/RxooBYMAemL8AAoJEM0j9enEyjRDiBgAn3RcLK+gq90PvnQFTw2DNqdq7KA0"
+			+ "AKCS0EEIXCzbV1tfTdCUJ3hVh3btF7QkRXJpYyBFY2hpZG5hIDxlcmljQGJvdW5j"
+			+ "eWNhc3RsZS5vcmc+iLgEEwECACIFAj9HFA0CGwMFCQCD1gAECwcDAgMVAgMDFgIB"
+			+ "Ah4BAheAAAoJEDVYYUb98/Nzc7oD/j21cUKKI/y+Dvs5e+eZufM8EDUbqMJFk0/X"
+			+ "Ihe6w6OkerIs3kr2HDqWr+jik2IK6KrfaiyoZFfeW/+cN24lTWSfY7D4jZVyL6iM"
+			+ "xd0IZ0So/Bl+/juMcvBGshQnbY46haw5G2C9J5FR3gjODyOu5oUzu5+vmGuMSXVy"
+			+ "4tbUevwuiEwEEBECAAwFAj9HGigFgwB6YvwACgkQzSP16cTKNEPwBQCdHm0Amwza"
+			+ "NmVmDHm3rmqI7rp2oQ0An2YbiP/H/kmBNnmTeH55kd253QOhuIsEP0ccUAEEANCd"
+			+ "gSHam/CbQxio72Ma47tLqyVVc8iNQpwowKewrS6B0CVEFOz2o51eCXddrpH3KCuz"
+			+ "Ea2mMnUBI8YdjKj6bkICUt3YEFa8Tj2qw0GARa2TXdrWcTo2GpIRK71JkaOslhWs"
+			+ "QocKjIJfF1roATYNQ72vv2HKBkPpcviYOEVmaB/PAAYpiJ8EGAECAAkFAj9HHFAC"
+			+ "GwwACgkQNVhhRv3z83M5hQP8DIOR4TeTZKpo5x1BX3lzV3R85npMsN/EZ7gjCpn3"
+			+ "ONwIg7PhbSetoKUOjxLGReKPUuX8XI1ZN1UoNNFzA7UP9AbCgXORsYSU6uxvv0qH"
+			+ "jON91htfbqEtPuS3/99cDaE56b+p6TmmKXE0Oy/Swp88ABeB9ISTxOm4ZltgjHLB"
+			+ "PyGZAaIEP0cHNREEALOTFEJUYmDn4t30NThemd3gsIqAyrtg5jsaLQSAr3aBtprr"
+			+ "7NChAWrPW23dBSanPdhWSb/MsRIEG0LUAIhcaCBR0UxSvkjzv7UJvq/N58C0a3w3"
+			+ "lVXUX8xe/WAnPgG7ofLEv+dx97vWOw2Fq/SLjICN/Z61YWPnfMrpH46ODkfrAKCk"
+			+ "v3+1dV8Y/xKoW/Ks3/jfsyUVJQQAg3dXqP8xSWXKtmCWu2vb5FYjBGsb8AKasXqF"
+			+ "O6A6XhxDFoNg1ye1duGVOUmz0zGNMffHHPKXKKsLKrsfMYnFnNK3oVN6HUMVjOEn"
+			+ "tC5hHXGtJ0DpjSZS/SLEPkDic8eO6lDlAKocZ5F8UP+gfMPjOoGcmn8Encu9Drps"
+			+ "REmYqXkD/i6PcehXGlvS+/IQ19GooyYYEhLJxjgygfm5Z9vbcV9+xP2v0ovqcniz"
+			+ "IvNpFHSC9xtyORz1nd6kjuCveNOtvh3xY/GwNtP9bW2/1sb8QdrCiYtyKG25RTrx"
+			+ "R6Pr/Bmi3Vcmq7adCWS7nv4z9XZfXLbpUqyKmiU9+Nri7IE47K9stDNFcmljIEVj"
+			+ "aGlkbmEgKERTQSBUZXN0IEtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQT"
+			+ "EQIAGQUCP0cHNQQLBwMCAxUCAwMWAgECHgECF4AACgkQzSP16cTKNEMCXACfauui"
+			+ "bSwyG59Yrm8hHCDuCPmqwsQAni+dPl08FVuWh+wb6kOgJV4lcYae");
+
+//		private static readonly byte[] subPubCrc = Base64.Decode("rikt");
+
+		private static readonly byte[] pgp8Key = Base64.Decode(
+              "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF"
+			+ "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd"
+			+ "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy"
+			+ "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y"
+			+ "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7"
+			+ "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO"
+			+ "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP"
+			+ "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY"
+			+ "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb"
+			+ "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4"
+			+ "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj"
+			+ "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I"
+			+ "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH"
+			+ "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt"
+			+ "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j"
+			+ "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw"
+			+ "AgAA");
+
+		private static readonly char[] pgp8Pass = "2002 Buffalo Sabres".ToCharArray();
+
+		private static readonly char[] pass = "hello world".ToCharArray();
+
+		private static readonly byte[] fingerprintKey = Base64.Decode(
+			  "mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc"
+			+ "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A"
+			+ "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb"
+			+ "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c"
+			+ "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq"
+			+ "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP"
+			+ "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB"
+			+ "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW"
+			+ "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO"
+			+ "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS"
+			+ "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn"
+			+ "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr"
+			+ "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw=");
+
+//		private static readonly byte[] fingerprintCheck = Base64.Decode("CTv2");
+
+		private static readonly byte[] jpegImage = Base64.Decode(
+			  "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");
+
+		private static readonly byte[] embeddedJPEGKey = Base64.Decode(
+			  "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"
+			+ "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw==");
+
+		private void FingerPrintTest()
+        {
+            //
+            // version 3
+            //
+            PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(fingerprintKey);
+
+			PgpPublicKey pubKey = pgpPub.GetPublicKey();
+
+			if (!Arrays.AreEqual(pubKey.GetFingerprint(), Hex.Decode("4FFB9F0884266C715D1CEAC804A3BBFA")))
+            {
+                Fail("version 3 fingerprint test failed");
+            }
+
+			//
+            // version 4
+            //
+            pgpPub = new PgpPublicKeyRing(testPubKey);
+
+            pubKey = pgpPub.GetPublicKey();
+
+            if (!Arrays.AreEqual(pubKey.GetFingerprint(), Hex.Decode("3062363c1046a01a751946bb35586146fdf3f373")))
+            {
+               Fail("version 4 fingerprint test failed");
+            }
+        }
+
+		private void MixedTest(
+			PgpPrivateKey	pgpPrivKey,
+			PgpPublicKey	pgpPubKey)
+		{
+			byte[] text = Encoding.ASCII.GetBytes("hello world!\n");
+
+			//
+			// literal data
+			//
+			MemoryStream bOut = new MemoryStream();
+			PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+			Stream lOut = lGen.Open(
+				bOut,
+				PgpLiteralData.Binary,
+				PgpLiteralData.Console,
+				text.Length,
+				DateTime.UtcNow);
+
+			lOut.Write(text, 0, text.Length);
+
+			lGen.Close();
+
+			byte[] bytes = bOut.ToArray();
+
+			PgpObjectFactory f = new PgpObjectFactory(bytes);
+			CheckLiteralData((PgpLiteralData)f.NextPgpObject(), text);
+
+			MemoryStream bcOut = new MemoryStream();
+
+			PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(
+				SymmetricKeyAlgorithmTag.Aes128,
+				true,
+				new SecureRandom());
+
+			encGen.AddMethod(pgpPubKey);
+
+			encGen.AddMethod("password".ToCharArray());
+
+			Stream cOut = encGen.Open(bcOut, bytes.Length);
+
+			cOut.Write(bytes, 0, bytes.Length);
+
+			cOut.Close();
+
+			byte[] encData = bcOut.ToArray();
+
+			//
+			// asymmetric
+			//
+			PgpObjectFactory pgpF = new PgpObjectFactory(encData);
+
+			PgpEncryptedDataList encList = (PgpEncryptedDataList) pgpF.NextPgpObject();
+
+			PgpPublicKeyEncryptedData  encP = (PgpPublicKeyEncryptedData)encList[0];
+
+			Stream clear = encP.GetDataStream(pgpPrivKey);
+
+			PgpObjectFactory pgpFact = new PgpObjectFactory(clear);
+
+			CheckLiteralData((PgpLiteralData)pgpFact.NextPgpObject(), text);
+
+			//
+			// PBE
+			//
+			pgpF = new PgpObjectFactory(encData);
+
+			encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+			PgpPbeEncryptedData encPbe = (PgpPbeEncryptedData) encList[1];
+
+			clear = encPbe.GetDataStream("password".ToCharArray());
+
+			pgpF = new PgpObjectFactory(clear);
+
+			CheckLiteralData((PgpLiteralData) pgpF.NextPgpObject(), text);
+		}
+
+		private void CheckLiteralData(
+			PgpLiteralData	ld,
+			byte[]			data)
+		{
+			if (!ld.FileName.Equals(PgpLiteralData.Console))
+				throw new Exception("wrong filename in packet");
+
+			Stream inLd = ld.GetDataStream();
+			byte[] bytes = Streams.ReadAll(inLd);
+
+			if (!AreEqual(bytes, data))
+			{
+				Fail("wrong plain text in decrypted packet");
+			}
+		}
+
+		private void ExistingEmbeddedJpegTest()
+		{
+			PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(embeddedJPEGKey);
+
+			PgpPublicKey pubKey = pgpPub.GetPublicKey();
+
+			int count = 0;
+			foreach (PgpUserAttributeSubpacketVector attributes in pubKey.GetUserAttributes())
+			{
+				int sigCount = 0;
+				foreach (PgpSignature sig in pubKey.GetSignaturesForUserAttribute(attributes))
+				{
+					sig.InitVerify(pubKey);
+
+					if (!sig.VerifyCertification(attributes, pubKey))
+					{
+						Fail("signature failed verification");
+					}
+
+					sigCount++;
+				}
+
+				if (sigCount != 1)
+				{
+					Fail("Failed user attributes signature check");
+				}
+				count++;
+			}
+
+			if (count != 1)
+			{
+				Fail("didn't find user attributes");
+			}
+		}
+
+		private void EmbeddedJpegTest()
+		{
+			PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey);
+			PgpSecretKeyRing pgpSec = new PgpSecretKeyRing(testPrivKey);
+
+			PgpPublicKey pubKey = pgpPub.GetPublicKey();
+
+			PgpUserAttributeSubpacketVectorGenerator vGen = new PgpUserAttributeSubpacketVectorGenerator();
+
+			vGen.SetImageAttribute(ImageAttrib.Format.Jpeg, jpegImage);
+
+			PgpUserAttributeSubpacketVector uVec = vGen.Generate();
+
+			PgpSignatureGenerator sGen = new PgpSignatureGenerator(
+				PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.PositiveCertification, pgpSec.GetSecretKey().ExtractPrivateKey(pass));
+
+			PgpSignature sig = sGen.GenerateCertification(uVec, pubKey);
+
+			PgpPublicKey nKey = PgpPublicKey.AddCertification(pubKey, uVec, sig);
+
+			int count = 0;
+			foreach (PgpUserAttributeSubpacketVector attributes in nKey.GetUserAttributes())
+			{
+				int sigCount = 0;
+				foreach (PgpSignature s in nKey.GetSignaturesForUserAttribute(attributes))
+				{
+					s.InitVerify(pubKey);
+
+					if (!s.VerifyCertification(attributes, pubKey))
+					{
+						Fail("added signature failed verification");
+					}
+
+					sigCount++;
+				}
+
+				if (sigCount != 1)
+				{
+					Fail("Failed added user attributes signature check");
+				}
+				count++;
+			}
+
+			if (count != 1)
+			{
+				Fail("didn't find added user attributes");
+			}
+
+			nKey = PgpPublicKey.RemoveCertification(nKey, uVec);
+
+			if (nKey.GetUserAttributes().GetEnumerator().MoveNext())
+			{
+				Fail("found attributes where none expected");
+			}
+		}
+
+		public override void PerformTest()
+        {
+            //
+            // Read the public key
+            //
+            PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey);
+
+			AsymmetricKeyParameter pubKey = pgpPub.GetPublicKey().GetKey();
+
+			IEnumerator enumerator = pgpPub.GetPublicKey().GetUserIds().GetEnumerator();
+            enumerator.MoveNext();
+            string uid = (string) enumerator.Current;
+
+
+            enumerator = pgpPub.GetPublicKey().GetSignaturesForId(uid).GetEnumerator();
+            enumerator.MoveNext();
+            PgpSignature sig = (PgpSignature) enumerator.Current;
+
+			sig.InitVerify(pgpPub.GetPublicKey());
+
+			if (!sig.VerifyCertification(uid, pgpPub.GetPublicKey()))
+            {
+                Fail("failed to verify certification");
+            }
+
+			//
+            // write a public key
+            //
+            MemoryStream bOut = new UncloseableMemoryStream();
+            BcpgOutputStream pOut = new BcpgOutputStream(bOut);
+
+			pgpPub.Encode(pOut);
+
+			if (!Arrays.AreEqual(bOut.ToArray(), testPubKey))
+            {
+                Fail("public key rewrite failed");
+            }
+
+			//
+            // Read the public key
+            //
+            PgpPublicKeyRing pgpPubV3 = new PgpPublicKeyRing(testPubKeyV3);
+            AsymmetricKeyParameter pubKeyV3 = pgpPub.GetPublicKey().GetKey();
+
+			//
+            // write a V3 public key
+            //
+            bOut = new UncloseableMemoryStream();
+            pOut = new BcpgOutputStream(bOut);
+
+			pgpPubV3.Encode(pOut);
+
+			//
+            // Read a v3 private key
+            //
+            char[] passP = "FIXCITY_QA".ToCharArray();
+
+#if INCLUDE_IDEA
+			{
+				PgpSecretKeyRing pgpPriv2 = new PgpSecretKeyRing(testPrivKeyV3);
+				PgpSecretKey pgpPrivSecretKey = pgpPriv2.GetSecretKey();
+				PgpPrivateKey pgpPrivKey2 = pgpPrivSecretKey.ExtractPrivateKey(passP);
+
+				//
+				// write a v3 private key
+				//
+				bOut = new UncloseableMemoryStream();
+				pOut = new BcpgOutputStream(bOut);
+
+				pgpPriv2.Encode(pOut);
+
+				byte[] result = bOut.ToArray();
+				if (!Arrays.AreEqual(result, testPrivKeyV3))
+				{
+					Fail("private key V3 rewrite failed");
+				}
+			}
+#endif
+
+			//
+            // Read the private key
+            //
+            PgpSecretKeyRing pgpPriv = new PgpSecretKeyRing(testPrivKey);
+            PgpPrivateKey pgpPrivKey = pgpPriv.GetSecretKey().ExtractPrivateKey(pass);
+
+			//
+            // write a private key
+            //
+            bOut = new UncloseableMemoryStream();
+            pOut = new BcpgOutputStream(bOut);
+
+			pgpPriv.Encode(pOut);
+
+			if (!Arrays.AreEqual(bOut.ToArray(), testPrivKey))
+            {
+                Fail("private key rewrite failed");
+            }
+
+			//
+            // test encryption
+            //
+            IBufferedCipher c = CipherUtilities.GetCipher("RSA");
+
+//                c.Init(Cipher.ENCRYPT_MODE, pubKey);
+            c.Init(true, pubKey);
+
+			byte[] inBytes = Encoding.ASCII.GetBytes("hello world");
+			byte[] outBytes = c.DoFinal(inBytes);
+
+//                c.Init(Cipher.DECRYPT_MODE, pgpPrivKey.GetKey());
+            c.Init(false, pgpPrivKey.Key);
+
+            outBytes = c.DoFinal(outBytes);
+
+			if (!Arrays.AreEqual(inBytes, outBytes))
+            {
+                Fail("decryption failed.");
+            }
+
+			//
+            // test signature message
+            //
+            PgpObjectFactory pgpFact = new PgpObjectFactory(sig1);
+
+			PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+			pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+			PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+
+			PgpOnePassSignature ops = p1[0];
+
+			PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject();
+
+			Stream dIn = p2.GetInputStream();
+
+			ops.InitVerify(pgpPub.GetPublicKey(ops.KeyId));
+
+			int ch;
+			while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte)ch);
+            }
+
+			PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+
+			if (!ops.Verify(p3[0]))
+            {
+                Fail("Failed signature check");
+            }
+
+			//
+            // encrypted message - read subkey
+            //
+            pgpPriv = new PgpSecretKeyRing(subKey);
+
+			//
+            // encrypted message
+            //
+			byte[] text = Encoding.ASCII.GetBytes("hello world!\n");
+
+			PgpObjectFactory pgpF = new PgpObjectFactory(enc1);
+
+			PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+			PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0];
+
+			pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass);
+
+			Stream clear = encP.GetDataStream(pgpPrivKey);
+
+			pgpFact = new PgpObjectFactory(clear);
+
+			c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+			pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+			PgpLiteralData ld = (PgpLiteralData)pgpFact.NextPgpObject();
+
+			if (!ld.FileName.Equals("test.txt"))
+            {
+                throw new Exception("wrong filename in packet");
+            }
+
+			Stream inLd = ld.GetDataStream();
+			byte[] bytes = Streams.ReadAll(inLd);
+
+			if (!Arrays.AreEqual(bytes, text))
+            {
+                Fail("wrong plain text in decrypted packet");
+            }
+
+			//
+            // encrypt - short message
+            //
+            byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' };
+
+			MemoryStream cbOut = new UncloseableMemoryStream();
+            PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, new SecureRandom());
+            PgpPublicKey puK = pgpPriv.GetSecretKey(encP.KeyId).PublicKey;
+
+			cPk.AddMethod(puK);
+
+			Stream cOut = cPk.Open(new UncloseableStream(cbOut), shortText.Length);
+
+			cOut.Write(shortText, 0, shortText.Length);
+
+			cOut.Close();
+
+			pgpF = new PgpObjectFactory(cbOut.ToArray());
+
+			encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+			encP = (PgpPublicKeyEncryptedData)encList[0];
+
+			pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass);
+
+			if (encP.GetSymmetricAlgorithm(pgpPrivKey) != SymmetricKeyAlgorithmTag.Cast5)
+			{
+				Fail("symmetric algorithm mismatch");
+			}
+
+			clear = encP.GetDataStream(pgpPrivKey);
+			outBytes = Streams.ReadAll(clear);
+
+			if (!Arrays.AreEqual(outBytes, shortText))
+            {
+                Fail("wrong plain text in generated short text packet");
+            }
+
+			//
+            // encrypt
+            //
+            cbOut = new UncloseableMemoryStream();
+            cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, new SecureRandom());
+            puK = pgpPriv.GetSecretKey(encP.KeyId).PublicKey;
+
+			cPk.AddMethod(puK);
+
+			cOut = cPk.Open(new UncloseableStream(cbOut), text.Length);
+
+			cOut.Write(text, 0, text.Length);
+
+			cOut.Close();
+
+			pgpF = new PgpObjectFactory(cbOut.ToArray());
+
+			encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+			encP = (PgpPublicKeyEncryptedData)encList[0];
+
+			pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass);
+
+			clear = encP.GetDataStream(pgpPrivKey);
+			outBytes = Streams.ReadAll(clear);
+
+			if (!Arrays.AreEqual(outBytes, text))
+            {
+                Fail("wrong plain text in generated packet");
+            }
+
+			//
+            // read public key with sub key.
+            //
+            pgpF = new PgpObjectFactory(subPubKey);
+            object o;
+            while ((o = pgpFact.NextPgpObject()) != null)
+            {
+				// TODO Should something be tested here?
+                // Console.WriteLine(o);
+            }
+
+			//
+            // key pair generation - CAST5 encryption
+            //
+            char[] passPhrase = "hello".ToCharArray();
+            IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA");
+            RsaKeyGenerationParameters genParam = new RsaKeyGenerationParameters(
+				BigInteger.ValueOf(0x10001), new SecureRandom(), 1024, 25);
+
+			kpg.Init(genParam);
+
+
+			AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();
+
+			PgpSecretKey secretKey = new PgpSecretKey(
+                PgpSignature.DefaultCertification,
+                PublicKeyAlgorithmTag.RsaGeneral,
+                kp.Public,
+                kp.Private,
+                DateTime.UtcNow,
+                "fred",
+                SymmetricKeyAlgorithmTag.Cast5,
+                passPhrase,
+                null,
+                null,
+                new SecureRandom()
+                );
+
+			PgpPublicKey key = secretKey.PublicKey;
+
+
+			enumerator = key.GetUserIds().GetEnumerator();
+            enumerator.MoveNext();
+            uid = (string) enumerator.Current;
+
+
+            enumerator = key.GetSignaturesForId(uid).GetEnumerator();
+            enumerator.MoveNext();
+            sig = (PgpSignature) enumerator.Current;
+
+            sig.InitVerify(key);
+
+            if (!sig.VerifyCertification(uid, key))
+            {
+                Fail("failed to verify certification");
+            }
+
+            pgpPrivKey = secretKey.ExtractPrivateKey(passPhrase);
+
+            key = PgpPublicKey.RemoveCertification(key, uid, sig);
+
+            if (key == null)
+            {
+                Fail("failed certification removal");
+            }
+
+            byte[] keyEnc = key.GetEncoded();
+
+			key = PgpPublicKey.AddCertification(key, uid, sig);
+
+			keyEnc = key.GetEncoded();
+
+			PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.KeyRevocation, secretKey.ExtractPrivateKey(passPhrase));
+
+			sig = sGen.GenerateCertification(key);
+
+			key = PgpPublicKey.AddCertification(key, sig);
+
+			keyEnc = key.GetEncoded();
+
+			PgpPublicKeyRing tmpRing = new PgpPublicKeyRing(keyEnc);
+
+			key = tmpRing.GetPublicKey();
+
+			IEnumerator sgEnum = key.GetSignaturesOfType(PgpSignature.KeyRevocation).GetEnumerator();
+            sgEnum.MoveNext();
+            sig = (PgpSignature) sgEnum.Current;
+
+			sig.InitVerify(key);
+
+			if (!sig.VerifyCertification(key))
+            {
+                Fail("failed to verify revocation certification");
+            }
+
+			//
+            // use of PgpKeyPair
+            //
+            PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.RsaGeneral,
+				kp.Public, kp.Private, DateTime.UtcNow);
+
+			PgpPublicKey k1 = pgpKp.PublicKey;
+            PgpPrivateKey k2 = pgpKp.PrivateKey;
+
+            k1.GetEncoded();
+
+			MixedTest(k2, k1);
+
+			//
+            // key pair generation - AES_256 encryption.
+            //
+            kp = kpg.GenerateKeyPair();
+
+			secretKey = new PgpSecretKey(PgpSignature.DefaultCertification, PublicKeyAlgorithmTag.RsaGeneral, kp.Public, kp.Private, DateTime.UtcNow, "fred", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, new SecureRandom());
+
+			secretKey.ExtractPrivateKey(passPhrase);
+
+			secretKey.Encode(new UncloseableMemoryStream());
+
+			//
+            // secret key password changing.
+            //
+            const string newPass = "newPass";
+
+			secretKey = PgpSecretKey.CopyWithNewPassword(secretKey, passPhrase, newPass.ToCharArray(), secretKey.KeyEncryptionAlgorithm, new SecureRandom());
+
+			secretKey.ExtractPrivateKey(newPass.ToCharArray());
+
+			secretKey.Encode(new UncloseableMemoryStream());
+
+			key = secretKey.PublicKey;
+
+			key.Encode(new UncloseableMemoryStream());
+
+
+			enumerator = key.GetUserIds().GetEnumerator();
+            enumerator.MoveNext();
+            uid = (string) enumerator.Current;
+
+
+			enumerator = key.GetSignaturesForId(uid).GetEnumerator();
+            enumerator.MoveNext();
+            sig = (PgpSignature) enumerator.Current;
+
+			sig.InitVerify(key);
+
+			if (!sig.VerifyCertification(uid, key))
+            {
+                Fail("failed to verify certification");
+            }
+
+			pgpPrivKey = secretKey.ExtractPrivateKey(newPass.ToCharArray());
+
+			//
+            // signature generation
+            //
+            const string data = "hello world!";
+            byte[] dataBytes = Encoding.ASCII.GetBytes(data);
+
+			bOut = new UncloseableMemoryStream();
+
+			MemoryStream testIn = new MemoryStream(dataBytes, false);
+
+			sGen = new PgpSignatureGenerator(
+				PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
+
+			PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(
+				CompressionAlgorithmTag.Zip);
+
+			BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut)));
+
+			sGen.GenerateOnePassVersion(false).Encode(bcOut);
+
+			PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+
+			DateTime testDateTime = new DateTime(1973, 7, 27);
+			Stream lOut = lGen.Open(new UncloseableStream(bcOut), PgpLiteralData.Binary, "_CONSOLE",
+                dataBytes.Length, testDateTime);
+
+			// TODO Need a stream object to automatically call Update?
+			// (via ISigner implementation of PgpSignatureGenerator)
+			while ((ch = testIn.ReadByte()) >= 0)
+            {
+                lOut.WriteByte((byte)ch);
+                sGen.Update((byte)ch);
+            }
+
+			lOut.Close();
+
+			sGen.Generate().Encode(bcOut);
+
+			bcOut.Close();
+
+			//
+            // verify generated signature
+            //
+            pgpFact = new PgpObjectFactory(bOut.ToArray());
+
+			c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+			pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+			p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+
+			ops = p1[0];
+
+			p2 = (PgpLiteralData)pgpFact.NextPgpObject();
+			if (!p2.ModificationTime.Equals(testDateTime))
+			{
+				Fail("Modification time not preserved");
+			}
+
+			dIn = p2.GetInputStream();
+
+			ops.InitVerify(secretKey.PublicKey);
+
+			// TODO Need a stream object to automatically call Update?
+			// (via ISigner implementation of PgpSignatureGenerator)
+			while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte)ch);
+            }
+
+			p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+
+			if (!ops.Verify(p3[0]))
+            {
+                Fail("Failed generated signature check");
+            }
+
+			//
+            // signature generation - version 3
+            //
+            bOut = new UncloseableMemoryStream();
+
+			testIn = new MemoryStream(dataBytes);
+            PgpV3SignatureGenerator sGenV3 = new PgpV3SignatureGenerator(
+                PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
+
+			cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
+
+			bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut)));
+
+			sGen.GenerateOnePassVersion(false).Encode(bcOut);
+
+			lGen = new PgpLiteralDataGenerator();
+			lOut = lGen.Open(
+				new UncloseableStream(bcOut),
+				PgpLiteralData.Binary,
+				"_CONSOLE",
+				dataBytes.Length,
+				testDateTime);
+
+			// TODO Need a stream object to automatically call Update?
+			// (via ISigner implementation of PgpSignatureGenerator)
+			while ((ch = testIn.ReadByte()) >= 0)
+            {
+                lOut.WriteByte((byte) ch);
+                sGen.Update((byte)ch);
+            }
+
+			lOut.Close();
+
+			sGen.Generate().Encode(bcOut);
+
+			bcOut.Close();
+
+			//
+            // verify generated signature
+            //
+            pgpFact = new PgpObjectFactory(bOut.ToArray());
+
+            c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+            pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+            p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+
+            ops = p1[0];
+
+            p2 = (PgpLiteralData)pgpFact.NextPgpObject();
+			if (!p2.ModificationTime.Equals(testDateTime))
+			{
+				Fail("Modification time not preserved");
+			}
+
+            dIn = p2.GetInputStream();
+
+            ops.InitVerify(secretKey.PublicKey);
+
+			// TODO Need a stream object to automatically call Update?
+			// (via ISigner implementation of PgpSignatureGenerator)
+			while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte)ch);
+            }
+
+            p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+
+            if (!ops.Verify(p3[0]))
+            {
+                Fail("Failed v3 generated signature check");
+            }
+
+			//
+            // extract PGP 8 private key
+            //
+            pgpPriv = new PgpSecretKeyRing(pgp8Key);
+
+			secretKey = pgpPriv.GetSecretKey();
+
+			pgpPrivKey = secretKey.ExtractPrivateKey(pgp8Pass);
+
+			//
+            // other sig tests
+            //
+            PerformTestSig(HashAlgorithmTag.Sha256, secretKey.PublicKey, pgpPrivKey);
+			PerformTestSig(HashAlgorithmTag.Sha384, secretKey.PublicKey, pgpPrivKey);
+			PerformTestSig(HashAlgorithmTag.Sha512, secretKey.PublicKey, pgpPrivKey);
+			FingerPrintTest();
+			ExistingEmbeddedJpegTest();
+			EmbeddedJpegTest();
+		}
+
+		private void PerformTestSig(
+            HashAlgorithmTag	hashAlgorithm,
+            PgpPublicKey		pubKey,
+            PgpPrivateKey		privKey)
+        {
+            const string data = "hello world!";
+            byte[] dataBytes = Encoding.ASCII.GetBytes(data);
+
+			MemoryStream bOut = new UncloseableMemoryStream();
+            MemoryStream testIn = new MemoryStream(dataBytes, false);
+            PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, hashAlgorithm);
+
+			sGen.InitSign(PgpSignature.BinaryDocument, privKey);
+
+			PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
+
+			BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut)));
+
+			sGen.GenerateOnePassVersion(false).Encode(bcOut);
+
+			PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+			DateTime testDateTime = new DateTime(1973, 7, 27);
+			Stream lOut = lGen.Open(
+				new UncloseableStream(bcOut),
+				PgpLiteralData.Binary,
+				"_CONSOLE",
+                dataBytes.Length,
+				testDateTime);
+
+			// TODO Need a stream object to automatically call Update?
+			// (via ISigner implementation of PgpSignatureGenerator)
+			int ch;
+            while ((ch = testIn.ReadByte()) >= 0)
+            {
+                lOut.WriteByte((byte)ch);
+                sGen.Update((byte)ch);
+            }
+
+			lOut.Close();
+
+			sGen.Generate().Encode(bcOut);
+
+			bcOut.Close();
+
+			//
+            // verify generated signature
+            //
+            PgpObjectFactory pgpFact = new PgpObjectFactory(bOut.ToArray());
+
+			PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject();
+
+			pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+			PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+
+			PgpOnePassSignature ops = p1[0];
+
+			PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject();
+			if (!p2.ModificationTime.Equals(testDateTime))
+			{
+				Fail("Modification time not preserved");
+			}
+
+			Stream dIn = p2.GetInputStream();
+
+			ops.InitVerify(pubKey);
+
+			// TODO Need a stream object to automatically call Update?
+			// (via ISigner implementation of PgpSignatureGenerator)
+			while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte)ch);
+            }
+
+			PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+
+			if (!ops.Verify(p3[0]))
+            {
+                Fail("Failed generated signature check - " + hashAlgorithm);
+            }
+        }
+
+		private class UncloseableMemoryStream
+			: MemoryStream
+		{
+			public override void Close()
+			{
+				throw new Exception("Close() called on underlying stream");
+			}
+		}
+
+		public override string Name
+        {
+			get { return "PGPRSATest"; }
+        }
+
+		public static void Main(
+            string[] args)
+        {
+            RunTest(new PgpRsaTest());
+        }
+
+		[Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/PGPSignatureTest.cs b/crypto/test/src/openpgp/test/PGPSignatureTest.cs
new file mode 100644
index 000000000..3aba2c302
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PGPSignatureTest.cs
@@ -0,0 +1,761 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Bcpg.Sig;
+using Org.BouncyCastle.Utilities.Date;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+	[TestFixture]
+	public class PgpSignatureTest
+		: SimpleTest
+	{
+		private const int[] NO_PREFERENCES = null;
+		private static readonly int[] PREFERRED_SYMMETRIC_ALGORITHMS
+			= new int[] { (int)SymmetricKeyAlgorithmTag.Aes128, (int)SymmetricKeyAlgorithmTag.TripleDes };
+		private static readonly int[] PREFERRED_HASH_ALGORITHMS
+			= new int[] { (int)HashAlgorithmTag.Sha1, (int)HashAlgorithmTag.Sha256 };
+		private static readonly int[] PREFERRED_COMPRESSION_ALGORITHMS
+			= new int[] { (int)CompressionAlgorithmTag.ZLib };
+
+		private const int TEST_EXPIRATION_TIME = 10000;
+		private const string TEST_USER_ID = "test user id";
+		private static readonly byte[] TEST_DATA = Encoding.ASCII.GetBytes("hello world!\nhello world!\n");
+		private static readonly byte[] TEST_DATA_WITH_CRLF = Encoding.ASCII.GetBytes("hello world!\r\nhello world!\r\n");
+
+		private static readonly byte[] dsaKeyRing = Base64.Decode(
+			"lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ"
+			+ "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV"
+			+ "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/"
+			+ "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug"
+			+ "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu"
+			+ "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ"
+			+ "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz"
+			+ "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej"
+			+ "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC"
+			+ "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu"
+			+ "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh"
+			+ "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j"
+			+ "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD"
+			+ "4nXkHg==");
+
+		private static readonly char[] dsaPass = "hello world".ToCharArray();
+
+		private static readonly byte[] rsaKeyRing = Base64.Decode(
+			  "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF"
+			+ "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd"
+			+ "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy"
+			+ "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y"
+			+ "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7"
+			+ "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO"
+			+ "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP"
+			+ "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY"
+			+ "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb"
+			+ "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4"
+			+ "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj"
+			+ "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I"
+			+ "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH"
+			+ "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt"
+			+ "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j"
+			+ "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw"
+			+ "AgAA");
+
+		private static readonly char[] rsaPass = "2002 Buffalo Sabres".ToCharArray();
+
+		private static readonly byte[] nullPacketsSubKeyBinding = Base64.Decode(
+			"iDYEGBECAAAAACp9AJ9PlJCrFpi+INwG7z61eku2Wg1HaQCgl33X5Egj+Kf7F9CXIWj2iFCvQDo=");
+
+		public override void PerformTest()
+		{
+			//
+			// RSA tests
+			//
+			PgpSecretKeyRing pgpPriv = new PgpSecretKeyRing(rsaKeyRing);
+			PgpSecretKey secretKey = pgpPriv.GetSecretKey();
+			PgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey(rsaPass);
+
+			try
+			{
+				doTestSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
+
+				Fail("RSA wrong key test failed.");
+			}
+			catch (PgpException)
+			{
+				// expected
+			}
+
+			try
+			{
+				doTestSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
+
+				Fail("RSA V3 wrong key test failed.");
+			}
+			catch (PgpException)
+			{
+				// expected
+			}
+
+			//
+			// certifications
+			//
+			PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.KeyRevocation, pgpPrivKey);
+
+			PgpSignature sig = sGen.GenerateCertification(secretKey.PublicKey);
+
+			sig.InitVerify(secretKey.PublicKey);
+
+			if (!sig.VerifyCertification(secretKey.PublicKey))
+			{
+				Fail("revocation verification failed.");
+			}
+
+			PgpSecretKeyRing pgpDSAPriv = new PgpSecretKeyRing(dsaKeyRing);
+			PgpSecretKey secretDSAKey = pgpDSAPriv.GetSecretKey();
+			PgpPrivateKey pgpPrivDSAKey = secretDSAKey.ExtractPrivateKey(dsaPass);
+
+			sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.SubkeyBinding, pgpPrivDSAKey);
+
+			PgpSignatureSubpacketGenerator    unhashedGen = new PgpSignatureSubpacketGenerator();
+			PgpSignatureSubpacketGenerator    hashedGen = new PgpSignatureSubpacketGenerator();
+
+			hashedGen.SetSignatureExpirationTime(false, TEST_EXPIRATION_TIME);
+			hashedGen.SetSignerUserId(true, TEST_USER_ID);
+			hashedGen.SetPreferredCompressionAlgorithms(false, PREFERRED_COMPRESSION_ALGORITHMS);
+			hashedGen.SetPreferredHashAlgorithms(false, PREFERRED_HASH_ALGORITHMS);
+			hashedGen.SetPreferredSymmetricAlgorithms(false, PREFERRED_SYMMETRIC_ALGORITHMS);
+
+			sGen.SetHashedSubpackets(hashedGen.Generate());
+			sGen.SetUnhashedSubpackets(unhashedGen.Generate());
+
+			sig = sGen.GenerateCertification(secretDSAKey.PublicKey, secretKey.PublicKey);
+
+			byte[] sigBytes = sig.GetEncoded();
+
+			PgpObjectFactory f = new PgpObjectFactory(sigBytes);
+
+			sig = ((PgpSignatureList) f.NextPgpObject())[0];
+
+			sig.InitVerify(secretDSAKey.PublicKey);
+
+			if (!sig.VerifyCertification(secretDSAKey.PublicKey, secretKey.PublicKey))
+			{
+				Fail("subkey binding verification failed.");
+			}
+
+			PgpSignatureSubpacketVector hashedPcks = sig.GetHashedSubPackets();
+			PgpSignatureSubpacketVector unhashedPcks = sig.GetUnhashedSubPackets();
+
+			if (hashedPcks.Count != 6)
+			{
+				Fail("wrong number of hashed packets found.");
+			}
+
+			if (unhashedPcks.Count != 1)
+			{
+				Fail("wrong number of unhashed packets found.");
+			}
+
+			if (!hashedPcks.GetSignerUserId().Equals(TEST_USER_ID))
+			{
+				Fail("test userid not matching");
+			}
+
+			if (hashedPcks.GetSignatureExpirationTime() != TEST_EXPIRATION_TIME)
+			{
+				Fail("test signature expiration time not matching");
+			}
+
+			if (unhashedPcks.GetIssuerKeyId() != secretDSAKey.KeyId)
+			{
+				Fail("wrong issuer key ID found in certification");
+			}
+
+			int[] prefAlgs = hashedPcks.GetPreferredCompressionAlgorithms();
+			preferredAlgorithmCheck("compression", PREFERRED_COMPRESSION_ALGORITHMS, prefAlgs);
+
+			prefAlgs = hashedPcks.GetPreferredHashAlgorithms();
+			preferredAlgorithmCheck("hash", PREFERRED_HASH_ALGORITHMS, prefAlgs);
+
+			prefAlgs = hashedPcks.GetPreferredSymmetricAlgorithms();
+			preferredAlgorithmCheck("symmetric", PREFERRED_SYMMETRIC_ALGORITHMS, prefAlgs);
+
+			SignatureSubpacketTag[] criticalHashed = hashedPcks.GetCriticalTags();
+
+			if (criticalHashed.Length != 1)
+			{
+				Fail("wrong number of critical packets found.");
+			}
+
+			if (criticalHashed[0] != SignatureSubpacketTag.SignerUserId)
+			{
+				Fail("wrong critical packet found in tag list.");
+			}
+
+			//
+			// no packets passed
+			//
+			sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.SubkeyBinding, pgpPrivDSAKey);
+
+			sGen.SetHashedSubpackets(null);
+			sGen.SetUnhashedSubpackets(null);
+
+			sig = sGen.GenerateCertification(TEST_USER_ID, secretKey.PublicKey);
+
+			sig.InitVerify(secretDSAKey.PublicKey);
+
+			if (!sig.VerifyCertification(TEST_USER_ID, secretKey.PublicKey))
+			{
+				Fail("subkey binding verification failed.");
+			}
+
+			hashedPcks = sig.GetHashedSubPackets();
+
+			if (hashedPcks.Count != 1)
+			{
+				Fail("found wrong number of hashed packets");
+			}
+
+			unhashedPcks = sig.GetUnhashedSubPackets();
+
+			if (unhashedPcks.Count != 1)
+			{
+				Fail("found wrong number of unhashed packets");
+			}
+
+			try
+			{
+				sig.VerifyCertification(secretKey.PublicKey);
+
+				Fail("failed to detect non-key signature.");
+			}
+			catch (InvalidOperationException)
+			{
+				// expected
+			}
+
+			//
+			// override hash packets
+			//
+			sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.SubkeyBinding, pgpPrivDSAKey);
+
+			hashedGen = new PgpSignatureSubpacketGenerator();
+
+			DateTime creationTime = new DateTime(1973, 7, 27);
+			hashedGen.SetSignatureCreationTime(false, creationTime);
+
+			sGen.SetHashedSubpackets(hashedGen.Generate());
+
+			sGen.SetUnhashedSubpackets(null);
+
+			sig = sGen.GenerateCertification(TEST_USER_ID, secretKey.PublicKey);
+
+			sig.InitVerify(secretDSAKey.PublicKey);
+
+			if (!sig.VerifyCertification(TEST_USER_ID, secretKey.PublicKey))
+			{
+				Fail("subkey binding verification failed.");
+			}
+
+			hashedPcks = sig.GetHashedSubPackets();
+
+			if (hashedPcks.Count != 1)
+			{
+				Fail("found wrong number of hashed packets in override test");
+			}
+
+			if (!hashedPcks.HasSubpacket(SignatureSubpacketTag.CreationTime))
+			{
+				Fail("hasSubpacket test for creation time failed");
+			}
+
+			DateTime sigCreationTime = hashedPcks.GetSignatureCreationTime();
+			if (!sigCreationTime.Equals(creationTime))
+			{
+				Fail("creation of overridden date failed.");
+			}
+
+			prefAlgs = hashedPcks.GetPreferredCompressionAlgorithms();
+			preferredAlgorithmCheck("compression", NO_PREFERENCES, prefAlgs);
+
+			prefAlgs = hashedPcks.GetPreferredHashAlgorithms();
+			preferredAlgorithmCheck("hash", NO_PREFERENCES, prefAlgs);
+
+			prefAlgs = hashedPcks.GetPreferredSymmetricAlgorithms();
+			preferredAlgorithmCheck("symmetric", NO_PREFERENCES, prefAlgs);
+
+			if (hashedPcks.GetKeyExpirationTime() != 0)
+			{
+				Fail("unexpected key expiration time found");
+			}
+
+			if (hashedPcks.GetSignatureExpirationTime() != 0)
+			{
+				Fail("unexpected signature expiration time found");
+			}
+
+			if (hashedPcks.GetSignerUserId() != null)
+			{
+				Fail("unexpected signer user ID found");
+			}
+
+			criticalHashed = hashedPcks.GetCriticalTags();
+
+			if (criticalHashed.Length != 0)
+			{
+				Fail("critical packets found when none expected");
+			}
+
+			unhashedPcks = sig.GetUnhashedSubPackets();
+
+			if (unhashedPcks.Count != 1)
+			{
+				Fail("found wrong number of unhashed packets in override test");
+			}
+
+			//
+			// general signatures
+			//
+			doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha256, secretKey.PublicKey, pgpPrivKey);
+			doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha384, secretKey.PublicKey, pgpPrivKey);
+			doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha512, secretKey.PublicKey, pgpPrivKey);
+			doTestSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
+			doTestTextSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
+			doTestTextSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
+			doTestTextSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
+			doTestTextSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
+
+			//
+			// DSA Tests
+			//
+			pgpPriv = new PgpSecretKeyRing(dsaKeyRing);
+			secretKey = pgpPriv.GetSecretKey();
+			pgpPrivKey = secretKey.ExtractPrivateKey(dsaPass);
+
+			try
+			{
+				doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
+
+				Fail("DSA wrong key test failed.");
+			}
+			catch (PgpException)
+			{
+				// expected
+			}
+
+			try
+			{
+				doTestSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
+
+				Fail("DSA V3 wrong key test failed.");
+			}
+			catch (PgpException)
+			{
+				// expected
+			}
+
+			doTestSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
+			doTestSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
+			doTestTextSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
+			doTestTextSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
+			doTestTextSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
+			doTestTextSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
+
+			// special cases
+			//
+			doTestMissingSubpackets(nullPacketsSubKeyBinding);
+
+			doTestMissingSubpackets(generateV3BinarySig(pgpPrivKey, PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1));
+
+			// keyflags
+			doTestKeyFlagsValues();
+		}
+
+		private void doTestKeyFlagsValues()
+		{
+			checkValue(KeyFlags.CertifyOther, 0x01);
+			checkValue(KeyFlags.SignData, 0x02);
+			checkValue(KeyFlags.EncryptComms, 0x04);
+			checkValue(KeyFlags.EncryptStorage, 0x08);
+			checkValue(KeyFlags.Split, 0x10);
+			checkValue(KeyFlags.Authentication, 0x20);
+			checkValue(KeyFlags.Shared, 0x80);
+
+			// yes this actually happens
+			checkValue(new byte[] { 4, 0, 0, 0 }, 0x04);
+			checkValue(new byte[] { 4, 0, 0 }, 0x04);
+			checkValue(new byte[] { 4, 0 }, 0x04);
+			checkValue(new byte[] { 4 }, 0x04);
+		}
+
+		private void checkValue(int flag, int val)
+		{
+			KeyFlags f = new KeyFlags(true, flag);
+
+			if (f.Flags != val)
+			{
+				Fail("flag value mismatch");
+			}
+		}
+
+		private void checkValue(byte[] flag, int val)
+		{
+			KeyFlags f = new KeyFlags(true, flag);
+
+			if (f.Flags != val)
+			{
+				Fail("flag value mismatch");
+			}
+		}
+
+		private void doTestMissingSubpackets(byte[] signature)
+		{
+			PgpObjectFactory f = new PgpObjectFactory(signature);
+			object obj = f.NextPgpObject();
+
+			while (!(obj is PgpSignatureList))
+			{
+				obj = f.NextPgpObject();
+				if (obj is PgpLiteralData)
+				{
+					Stream input = ((PgpLiteralData)obj).GetDataStream();
+					Streams.Drain(input);
+				}
+			}
+
+			PgpSignature sig = ((PgpSignatureList)obj)[0];
+
+			if (sig.Version > 3)
+			{
+				PgpSignatureSubpacketVector v = sig.GetHashedSubPackets();
+
+				if (v.GetKeyExpirationTime() != 0)
+				{
+					Fail("key expiration time not zero for missing subpackets");
+				}
+
+				if (!sig.HasSubpackets)
+				{
+					Fail("HasSubpackets property was false with packets");
+				}
+			}
+			else
+			{
+				if (sig.GetHashedSubPackets() != null)
+				{
+					Fail("hashed sub packets found when none expected");
+				}
+
+				if (sig.GetUnhashedSubPackets() != null)
+				{
+					Fail("unhashed sub packets found when none expected");
+				}
+
+				if (sig.HasSubpackets)
+				{
+					Fail("HasSubpackets property was true with no packets");
+				}
+			}
+		}
+
+		private void preferredAlgorithmCheck(
+			string	type,
+			int[]	expected,
+			int[]	prefAlgs)
+		{
+			if (expected == null)
+			{
+				if (prefAlgs != null)
+				{
+					Fail("preferences for " + type + " found when none expected");
+				}
+			}
+			else
+			{
+				if (prefAlgs.Length != expected.Length)
+				{
+					Fail("wrong number of preferred " + type + " algorithms found");
+				}
+
+				for (int i = 0; i != expected.Length; i++)
+				{
+					if (expected[i] != prefAlgs[i])
+					{
+						Fail("wrong algorithm found for " + type + ": expected " + expected[i] + " got " + prefAlgs);
+					}
+				}
+			}
+		}
+
+		private void doTestSig(
+			PublicKeyAlgorithmTag	encAlgorithm,
+			HashAlgorithmTag		hashAlgorithm,
+			PgpPublicKey			pubKey,
+			PgpPrivateKey			privKey)
+		{
+			MemoryStream bOut = new MemoryStream();
+			MemoryStream testIn = new MemoryStream(TEST_DATA, false);
+			PgpSignatureGenerator sGen = new PgpSignatureGenerator(encAlgorithm, hashAlgorithm);
+
+			sGen.InitSign(PgpSignature.BinaryDocument, privKey);
+			sGen.GenerateOnePassVersion(false).Encode(bOut);
+
+			PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+			Stream lOut = lGen.Open(
+				new UncloseableStream(bOut),
+				PgpLiteralData.Binary,
+				"_CONSOLE",
+				TEST_DATA.Length * 2,
+				DateTime.UtcNow);
+
+			int ch;
+			while ((ch = testIn.ReadByte()) >= 0)
+			{
+				lOut.WriteByte((byte)ch);
+				sGen.Update((byte)ch);
+			}
+
+			lOut.Write(TEST_DATA, 0, TEST_DATA.Length);
+			sGen.Update(TEST_DATA);
+
+			lGen.Close();
+
+			sGen.Generate().Encode(bOut);
+
+			verifySignature(bOut.ToArray(), hashAlgorithm, pubKey, TEST_DATA);
+		}
+
+		private void doTestTextSig(
+			PublicKeyAlgorithmTag	encAlgorithm,
+			HashAlgorithmTag		hashAlgorithm,
+			PgpPublicKey			pubKey,
+			PgpPrivateKey			privKey,
+			byte[]					data,
+			byte[]					canonicalData)
+		{
+			PgpSignatureGenerator sGen = new PgpSignatureGenerator(encAlgorithm, HashAlgorithmTag.Sha1);
+			MemoryStream bOut = new MemoryStream();
+			MemoryStream testIn = new MemoryStream(data, false);
+			DateTime creationTime = DateTime.UtcNow;
+
+			sGen.InitSign(PgpSignature.CanonicalTextDocument, privKey);
+			sGen.GenerateOnePassVersion(false).Encode(bOut);
+
+			PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+			Stream lOut = lGen.Open(
+				new UncloseableStream(bOut),
+				PgpLiteralData.Text,
+				"_CONSOLE",
+				data.Length * 2,
+				creationTime);
+
+			int ch;
+			while ((ch = testIn.ReadByte()) >= 0)
+			{
+				lOut.WriteByte((byte)ch);
+				sGen.Update((byte)ch);
+			}
+
+			lOut.Write(data, 0, data.Length);
+			sGen.Update(data);
+
+			lGen.Close();
+
+			PgpSignature sig = sGen.Generate();
+
+			if (sig.CreationTime == DateTimeUtilities.UnixMsToDateTime(0))
+			{
+				Fail("creation time not set in v4 signature");
+			}
+
+			sig.Encode(bOut);
+
+			verifySignature(bOut.ToArray(), hashAlgorithm, pubKey, canonicalData);
+		}
+
+		private void doTestSigV3(
+			PublicKeyAlgorithmTag	encAlgorithm,
+			HashAlgorithmTag		hashAlgorithm,
+			PgpPublicKey			pubKey,
+			PgpPrivateKey			privKey)
+		{
+			byte[] bytes = generateV3BinarySig(privKey, encAlgorithm, hashAlgorithm);
+
+			verifySignature(bytes, hashAlgorithm, pubKey, TEST_DATA);
+		}
+
+		private byte[] generateV3BinarySig(
+			PgpPrivateKey			privKey,
+			PublicKeyAlgorithmTag	encAlgorithm,
+			HashAlgorithmTag		hashAlgorithm)
+		{
+			MemoryStream bOut = new MemoryStream();
+			MemoryStream testIn = new MemoryStream(TEST_DATA, false);
+			PgpV3SignatureGenerator sGen = new PgpV3SignatureGenerator(encAlgorithm, hashAlgorithm);
+
+			sGen.InitSign(PgpSignature.BinaryDocument, privKey);
+			sGen.GenerateOnePassVersion(false).Encode(bOut);
+
+			PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+			Stream lOut = lGen.Open(
+				new UncloseableStream(bOut),
+				PgpLiteralData.Binary,
+				"_CONSOLE",
+				TEST_DATA.Length * 2,
+				DateTime.UtcNow);
+
+			int ch;
+			while ((ch = testIn.ReadByte()) >= 0)
+			{
+				lOut.WriteByte((byte)ch);
+				sGen.Update((byte)ch);
+			}
+
+			lOut.Write(TEST_DATA, 0, TEST_DATA.Length);
+			sGen.Update(TEST_DATA);
+
+			lGen.Close();
+
+			sGen.Generate().Encode(bOut);
+
+			return bOut.ToArray();
+		}
+
+		private void doTestTextSigV3(
+			PublicKeyAlgorithmTag	encAlgorithm,
+			HashAlgorithmTag		hashAlgorithm,
+			PgpPublicKey			pubKey,
+			PgpPrivateKey			privKey,
+			byte[]					data,
+			byte[]					canonicalData)
+		{
+			PgpV3SignatureGenerator sGen = new PgpV3SignatureGenerator(encAlgorithm, HashAlgorithmTag.Sha1);
+			MemoryStream bOut = new MemoryStream();
+			MemoryStream testIn = new MemoryStream(data, false);
+
+			sGen.InitSign(PgpSignature.CanonicalTextDocument, privKey);
+			sGen.GenerateOnePassVersion(false).Encode(bOut);
+
+			PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
+			Stream lOut = lGen.Open(
+				new UncloseableStream(bOut),
+				PgpLiteralData.Text,
+				"_CONSOLE",
+				data.Length * 2,
+				DateTime.UtcNow);
+
+			int ch;
+			while ((ch = testIn.ReadByte()) >= 0)
+			{
+				lOut.WriteByte((byte)ch);
+				sGen.Update((byte)ch);
+			}
+
+			lOut.Write(data, 0, data.Length);
+			sGen.Update(data);
+
+			lGen.Close();
+
+			PgpSignature sig = sGen.Generate();
+
+			if (sig.CreationTime == DateTimeUtilities.UnixMsToDateTime(0))
+			{
+				Fail("creation time not set in v3 signature");
+			}
+
+			sig.Encode(bOut);
+
+			verifySignature(bOut.ToArray(), hashAlgorithm, pubKey, canonicalData);
+		}
+
+		private void verifySignature(
+			byte[] encodedSig,
+			HashAlgorithmTag hashAlgorithm,
+			PgpPublicKey pubKey,
+			byte[] original)
+		{
+			PgpObjectFactory        pgpFact = new PgpObjectFactory(encodedSig);
+			PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
+			PgpOnePassSignature     ops = p1[0];
+			PgpLiteralData          p2 = (PgpLiteralData)pgpFact.NextPgpObject();
+			Stream					dIn = p2.GetInputStream();
+
+			ops.InitVerify(pubKey);
+
+			int ch;
+			while ((ch = dIn.ReadByte()) >= 0)
+			{
+				ops.Update((byte)ch);
+			}
+
+			PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+			PgpSignature sig = p3[0];
+
+			DateTime creationTime = sig.CreationTime;
+
+			// Check creationTime is recent
+			if (creationTime.CompareTo(DateTime.UtcNow) > 0
+				|| creationTime.CompareTo(DateTime.UtcNow.AddMinutes(-10)) < 0)
+			{
+				Fail("bad creation time in signature: " + creationTime);
+			}
+
+			if (sig.KeyId != pubKey.KeyId)
+			{
+				Fail("key id mismatch in signature");
+			}
+
+			if (!ops.Verify(sig))
+			{
+				Fail("Failed generated signature check - " + hashAlgorithm);
+			}
+
+			sig.InitVerify(pubKey);
+
+			for (int i = 0; i != original.Length; i++)
+			{
+				sig.Update(original[i]);
+			}
+
+			sig.Update(original);
+
+			if (!sig.Verify())
+			{
+				Fail("Failed generated signature check against original data");
+			}
+		}
+
+		public override string Name
+		{
+			get { return "PGPSignatureTest"; }
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new PgpSignatureTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
new file mode 100644
index 000000000..b776a0d2a
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
@@ -0,0 +1,2163 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+	[TestFixture]
+	public class PgpKeyRingTest
+		: SimpleTest
+	{
+		private static readonly byte[] pub1 = Base64.Decode(
+			"mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn"
+			+ "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg"
+			+ "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf"
+			+ "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ"
+			+ "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G"
+			+ "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ"
+			+ "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG"
+			+ "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP"
+			+ "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif"
+			+ "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh"
+			+ "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB"
+			+ "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p"
+			+ "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5"
+			+ "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN"
+			+ "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE"
+			+ "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1"
+			+ "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu"
+			+ "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y"
+			+ "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB"
+			+ "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u"
+			+ "ZJhfg0htdgAfIy8ppm05vLACAAA=");
+
+		private static readonly byte[] sec1 = Base64.Decode(
+			"lQHhBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn"
+			+ "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg"
+			+ "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf"
+			+ "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ"
+			+ "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G"
+			+ "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ"
+			+ "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG"
+			+ "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP"
+			+ "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif"
+			+ "IIeLOTI5Dc4XKeV32a+bWv4CAwJ5KgazImo+sGBfMhDiBcBTqyDGhKHNgHic"
+			+ "0Pky9FeRvfXTc2AO+jGmFPjcs8BnTWuDD0/jkQnRZpp1TrQidGVzdCAoVGVz"
+			+ "dCBrZXkpIDx0ZXN0QHViaWNhbGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB"
+			+ "4TOABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEJh8Njfhe8KmGDcAn3XeXDMg"
+			+ "BZgrZzFWU2IKtA/5LG2TAJ0Vf/jjyq0jZNZfGfoqGTvD2MAl0rACAACdAVgE"
+			+ "QDzfARAEAJeUAPvUzJJbKcc55Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj4"
+			+ "7UPAD/tQxwz8VAwJySx82ggNLxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j"
+			+ "2BVqZAaX3q79a3eMiql1T0oEAGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOH"
+			+ "AAQNBACD0mVMlAUgd7REYy/1mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWa"
+			+ "Hz6CN1XptdwpDeSYEOFZ0PSuqH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85e"
+			+ "fMBA9jUv/DeBOzRWMFG6sC6yk8NGG7Swea7EHKeQI40G3jgO/+xANtMyTP4C"
+			+ "AwJ5KgazImo+sGBl2C7CFuI+5KM4ZhbtVie7l+OiTpr5JW2z5VgnV3EX9p04"
+			+ "LcGKfQvD65+ELwli6yh8B2zGcipqTaYk3QoYNIhPBBgRAgAPBQJAPN8BAhsM"
+			+ "BQkB4TOAAAoJEJh8Njfhe8KmG7kAniuRkaFFv1pdCBN8JJXpcorHmyouAJ9L"
+			+ "xxmusffR6OI7WgD3XZ0AL8zUC7ACAAA=");
+
+//		private static readonly char[] pass1 = "qwertzuiop".ToCharArray();
+
+		private static readonly byte[] pub2 = Base64.Decode(
+			"mQGiBEBtfW8RBADfWjTxFedIbGBNVgh064D/OCf6ul7x4PGsCl+BkAyheYkr"
+			+ "mVUsChmBKoeXaY+Fb85wwusXzyM/6JFK58Rg+vEb3Z19pue8Ixxq7cRtCtOA"
+			+ "tOP1eKXLNtTRWJutvLkQmeOa19UZ6ziIq23aWuWKSq+KKMWek2GUnGycnx5M"
+			+ "W0pn1QCg/39r9RKhY9cdKYqRcqsr9b2B/AsD/Ru24Q15Jmrsl9zZ6EC47J49"
+			+ "iNW5sLQx1qf/mgfVWQTmU2j6gq4ND1OuK7+0OP/1yMOUpkjjcqxFgTnDAAoM"
+			+ "hHDTzCv/aZzIzmMvgLsYU3aIMfbz+ojpuASMCMh+te01cEMjiPWwDtdWWOdS"
+			+ "OSyX9ylzhO3PiNDks8R83onsacYpA/9WhTcg4bvkjaj66I7wGZkm3BmTxNSb"
+			+ "pE4b5HZDh31rRYhY9tmrryCfFnU4BS2Enjj5KQe9zFv7pUBCBW2oFo8i8Osn"
+			+ "O6fa1wVN4fBHC6wqWmmpnkFerNPkiC9V75KUFIfeWHmT3r2DVSO3dfdHDERA"
+			+ "jFIAioMLjhaX6DnODF5KQrABh7QmU2FpIFB1bGxhYmhvdGxhIDxwc2FpQG15"
+			+ "amF2YXdvcmxkLmNvbT6wAwP//4kAVwQQEQIAFwUCQG19bwcLCQgHAwIKAhkB"
+			+ "BRsDAAAAAAoJEKXQf/RT99uYmfAAoMKxV5g2owIfmy2w7vSLvOQUpvvOAJ4n"
+			+ "jB6xJot523rPAQW9itPoGGekirABZ7kCDQRAbX1vEAgA9kJXtwh/CBdyorrW"
+			+ "qULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9"
+			+ "ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/"
+			+ "Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4"
+			+ "DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdXQ6MdGGzeMyEs"
+			+ "tSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbTCD1mpF1B"
+			+ "n5x8vYlLIhkmuquiXsNV6TILOwACAgf9F7/nJHDayJ3pBVTTVSq2g5WKUXMg"
+			+ "xxGKTvOahiVRcbO03w0pKAkH85COakVfe56sMYpWRl36adjNoKOxaciow74D"
+			+ "1R5snY/hv/kBXPBkzo4UMkbANIVaZ0IcnLp+rkkXcDVbRCibZf8FfCY1zXbq"
+			+ "d680UtEgRbv1D8wFBqfMt7kLsuf9FnIw6vK4DU06z5ZDg25RHGmswaDyY6Mw"
+			+ "NGCrKGbHf9I/T7MMuhGF/in8UU8hv8uREOjseOqklG3/nsI1hD/MdUC7fzXi"
+			+ "MRO4RvahLoeXOuaDkMYALdJk5nmNuCL1YPpbFGttI3XsK7UrP/Fhd8ND6Nro"
+			+ "wCqrN6keduK+uLABh4kATAQYEQIADAUCQG19bwUbDAAAAAAKCRCl0H/0U/fb"
+			+ "mC/0AJ4r1yvyu4qfOXlDgmVuCsvHFWo63gCfRIrCB2Jv/N1cgpmq0L8LGHM7"
+			+ "G/KwAWeZAQ0EQG19owEIAMnavLYqR7ffaDPbbq+lQZvLCK/3uA0QlyngNyTa"
+			+ "sDW0WC1/ryy2dx7ypOOCicjnPYfg3LP5TkYAGoMjxH5+xzM6xfOR+8/EwK1z"
+			+ "N3A5+X/PSBDlYjQ9dEVKrvvc7iMOp+1K1VMf4Ug8Yah22Ot4eLGP0HRCXiv5"
+			+ "vgdBNsAl/uXnBJuDYQmLrEniqq/6UxJHKHxZoS/5p13Cq7NfKB1CJCuJXaCE"
+			+ "TW2do+cDpN6r0ltkF/r+ES+2L7jxyoHcvQ4YorJoDMlAN6xpIZQ8dNaTYP/n"
+			+ "Mx/pDS3shUzbU+UYPQrreJLMF1pD+YWP5MTKaZTo+U/qPjDFGcadInhPxvh3"
+			+ "1ssAEQEAAbABh7QuU2FuZGh5YSBQdWxsYWJob3RsYSA8cHNhbmRoeWFAbXlq"
+			+ "YXZhd29ybGQuY29tPrADA///iQEtBBABAgAXBQJAbX2jBwsJCAcDAgoCGQEF"
+			+ "GwMAAAAACgkQx87DL9gOvoeVUwgAkQXYiF0CxhKbDnuabAssnOEwJrutgCRO"
+			+ "CJRQvIwTe3fe6hQaWn2Yowt8OQtNFiR8GfAY6EYxyFLKzZbAI/qtq5fHmN3e"
+			+ "RSyNWe6d6e17hqZZL7kf2sVkyGTChHj7Jiuo7vWkdqT2MJN6BW5tS9CRH7Me"
+			+ "D839STv+4mAAO9auGvSvicP6UEQikAyCy/ihoJxLQlspfbSNpi0vrUjCPT7N"
+			+ "tWwfP0qF64i9LYkjzLqihnu+UareqOPhXcWnyFKrjmg4ezQkweNU2pdvCLbc"
+			+ "W24FhT92ivHgpLyWTswXcqjhFjVlRr0+2sIz7v1k0budCsJ7PjzOoH0hJxCv"
+			+ "sJQMlZR/e7ABZ7kBDQRAbX2kAQgAm5j+/LO2M4pKm/VUPkYuj3eefHkzjM6n"
+			+ "KbvRZX1Oqyf+6CJTxQskUWKAtkzzKafPdS5Wg0CMqeXov+EFod4bPEYccszn"
+			+ "cKd1U8NRwacbEpCvvvB84Yl2YwdWpDpkryyyLI4PbCHkeuwx9Dc2z7t4XDB6"
+			+ "FyAJTMAkia7nzYa/kbeUO3c2snDb/dU7uyCsyKtTZyTyhTgtl/f9L03Bgh95"
+			+ "y3mOUz0PimJ0Sg4ANczF4d04BpWkjLNVJi489ifWodPlHm1hag5drYekYpWJ"
+			+ "+3g0uxs5AwayV9BcOkPKb1uU3EoYQw+nn0Kn314Nvx2M1tKYunuVNLEm0PhA"
+			+ "/+B8PTq8BQARAQABsAGHiQEiBBgBAgAMBQJAbX2kBRsMAAAAAAoJEMfOwy/Y"
+			+ "Dr6HkLoH/RBY8lvUv1r8IdTs5/fN8e/MnGeThLl+JrlYF/4t3tjXYIf5xUj/"
+			+ "c9NdjreKYgHfMtrbVM08LlxUVQlkjuF3DIk5bVH9Blq8aXmyiwiM5GrCry+z"
+			+ "WiqkpZze1G577C38mMJbHDwbqNCLALMzo+W2q04Avl5sniNnDNGbGz9EjhRg"
+			+ "o7oS16KkkD6Ls4RnHTEZ0vyZOXodDHu+sk/2kzj8K07kKaM8rvR7aDKiI7HH"
+			+ "1GxJz70fn1gkKuV2iAIIiU25bty+S3wr+5h030YBsUZF1qeKCdGOmpK7e9Of"
+			+ "yv9U7rf6Z5l8q+akjqLZvej9RnxeH2Um7W+tGg2me482J+z6WOawAWc=");
+
+		private static readonly byte[] sec2 = Base64.Decode(
+			"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"
+			+ "Nifs+ljmsAFn");
+
+		private static readonly char[] sec2pass1 = "sandhya".ToCharArray();
+		private static readonly char[] sec2pass2 = "psai".ToCharArray();
+
+		private static readonly byte[] pub3 = Base64.Decode(
+			"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"
+			+ "n3FaE6UZE9GMDmCIAjhI+0X9aH6CsAIAAw==");
+
+		private static readonly byte[] sec3 = Base64.Decode(
+			"lQHhBEB9BH0RBACtYQtE7tna6hgGyGLpq+ds3r2cLC0ISn5dNw7tm9vwiNVF"
+			+ "JA2N37RRrifw4PvgelRSvLaX3M3ZBqC9s1Metg3v4FSlIRtSLWCNpHSvNw7i"
+			+ "X8C2Xy9Hdlbh6Y/50o+iscojLRE14upfR1bIkcCZQGSyvGV52V2wBImUUZjV"
+			+ "s2ZngwCg7mu852vK7+euz4WaL7ERVYtq9CMEAJ5swrljerDpz/RQ4Lhp6KER"
+			+ "KyuI0PUttO57xINGshEINgYlZdGaZHRueHe7uKfI19mb0T4N3NJWaZ0wF+Cn"
+			+ "rixsq0VrTUfiwfZeGluNG73aTCeY45fVXMGTTSYXzS8T0LW100Xn/0g9HRyA"
+			+ "xUpuWo8IazxkMqHJis2uwriYKpAfA/9anvj5BS9p5pfPjp9dGM7GTMIYl5f2"
+			+ "fcP57f+AW1TVR6IZiMJAvAdeWuLtwLnJiFpGlnFz273pfl+sAuqm1yNceImR"
+			+ "2SDDP4+vtyycWy8nZhgEuhZx3W3cWMQz5WyNJSY1JJHh9TCQkCoN8E7XpVP4"
+			+ "zEPboB2GzD93mfD8JLHP+/4DAwIvYrn+YqRaaGAu19XUj895g/GROyP8WEaU"
+			+ "Bd/JNqWc4kE/0guetGnPzq7G3bLVwiKfFd4X7BrgHAo3mrQtVGVzdCBLZXkg"
+			+ "KG5vIGNvbW1lbnQpIDx0ZXN0QGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkF"
+			+ "AkB9BH0ECwcDAgMVAgMDFgIBAh4BAheAAAoJEKnMV8vjZQOpSRQAoKZy6YS1"
+			+ "irF5/Q3JlWiwbkN6dEuLAJ9lldRLOlXsuQ5JW1+SLEc6K9ho4rACAADRwXPB"
+			+ "cQEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQEASABIAAD//gAXQ3Jl"
+			+ "YXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZ"
+			+ "EhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sA"
+			+ "QwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy"
+			+ "MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAFAAUAwEiAAIRAQMRAf/EABoA"
+			+ "AQACAwEAAAAAAAAAAAAAAAAEBQIDBgf/xAAoEAABAgUDBAEFAAAAAAAAAAAB"
+			+ "AgMABBEhMQUSQQYTIiNhFFGBkcH/xAAXAQEAAwAAAAAAAAAAAAAAAAAEAgMF"
+			+ "/8QAJBEAAQQAAwkAAAAAAAAAAAAAAQACERIEIfATMTJBUZGx0fH/2gAMAwEA"
+			+ "AhEDEQA/APMuotJlJVxstqaPo22NlAUp+YsNO0qSUtBcMu6n6EtOHcfPAHHF"
+			+ "I16++oajQtTA3DapK02HFR8UpE9pTbQWtKm2WG2rlxVyQTcfGbn7Qm0OIjL7"
+			+ "7Wrs2NNm9lzTmmSxQ0PX4opSprk5tmESF6syggzGwOLG6gXgHFbZhBixk8Xl"
+			+ "IDcOQLRKt+rX+3qC5ZLTQblpQlvwvxn9CMpZturVGkJHapQJphRH8hCLXbzr"
+			+ "qpYsCx1zC5rtpJNuYQhASc0UAQv/2YhcBBMRAgAcBQJAfQV+AhsDBAsHAwID"
+			+ "FQIDAxYCAQIeAQIXgAAKCRCpzFfL42UDqfa2AJ9hjtEeDTbTEAuuSbzhYFxN"
+			+ "/qc0FACgsmzysdbBpuN65yK01tbEaeIMtqCwAgAAnQEUBEB9BH4QAwCqRuWO"
+			+ "rxm5v/8WWBtPEUZnYuu3WYxefRKn6ON5ka5Ymp4AfKpKqKqn982tjlG13GVE"
+			+ "P2ow11L4yQKGNm+VyVEapm7SpMD0SHg9vsJygAWrfMJnBYWSgE19W6o3ckUR"
+			+ "sWsAAwYDAKDCSiSxC3Z5/POaCehw5iHs/vmVk5Wn831LSZEEwkSohNDbIEry"
+			+ "ia/9tFXSt11AP4stJtZ0MH87/6JBbiIRD4JXcx+zfzchL7Teczr/06QMphSn"
+			+ "sAENupbhLupfpR+BbP4DAwIvYrn+YqRaaGBjvFK1fbxCt7ZM4I2W/3BC0lCX"
+			+ "m/NypKNspGflec8u96uUlA0fNCnxm6f9nbB0jpvoKi0g4iqAf+P2iEYEGBEC"
+			+ "AAYFAkB9BH4ACgkQqcxXy+NlA6mtMgCgvccZA/Sg7BXVpxli47SYhxSHoM4A"
+			+ "oNCOMplSnYTuh5ikKeBWtz36gC1psAIAAA==");
+
+		private static readonly char[] sec3pass1 = "123456".ToCharArray();
+
+		//
+		// GPG comment packets.
+		//
+		private static readonly byte[] sec4 = Base64.Decode(
+			"lQG7BD0PbK8RBAC0cW4Y2MZXmAmqYp5Txyw0kSQsFvwZKHNMFRv996IsN57URVF5"
+			+ "BGMVPRBi9dNucWbjiSYpiYN13wE9IuLZsvVaQojV4XWGRDc+Rxz9ElsXnsYQ3mZU"
+			+ "7H1bNQEofstChk4z+dlvPBN4GFahrIzn/CeVUn6Ut7dVdYbiTqviANqNXwCglfVA"
+			+ "2OEePvqFnGxs1jhJyPSOnTED/RwRvsLH/k43mk6UEvOyN1RIpBXN+Ieqs7h1gFrQ"
+			+ "kB+WMgeP5ZUsotTffVDSUS9UMxRQggVUW1Xml0geGwQsNfkr/ztWMs/T4xp1v5j+"
+			+ "QyJx6OqNlkGdqOsoqkzJx0SQ1zBxdinFyyC4H95SDAb/RQOu5LQmxFG7quexztMs"
+			+ "infEA/9cVc9+qCo92yRAaXRqKNVVQIQuPxeUsGMyVeJQvJBD4An8KTMCdjpF10Cp"
+			+ "qA3t+n1S0zKr5WRUtvS6y60MOONO+EJWVWBNkx8HJDaIMNkfoqQoz3Krn7w6FE/v"
+			+ "/5uwMd6jY3N3yJZn5nDZT9Yzv9Nx3j+BrY+henRlSU0c6xDc9QAAnjJYg0Z83VJG"
+			+ "6HrBcgc4+4K6lHulCqH9JiM6RFNBX2ZhY3RvcjoAAK9hV206agp99GI6x5qE9+pU"
+			+ "vs6O+Ich/SYjOkRTQV9mYWN0b3I6AACvYAfGn2FGrpBYbjnpTuFOHJMS/T5xg/0m"
+			+ "IzpEU0FfZmFjdG9yOgAAr0dAQz6XxMwxWIn8xIZR/v2iN2L9C6O0EkZvbyBCYXIg"
+			+ "PGJhekBxdXV4PohXBBMRAgAXBQI9D2yvBQsHCgMEAxUDAgMWAgECF4AACgkQUGLI"
+			+ "YCIktfoGogCfZiXMJUKrScqozv5tMwzTTk2AaT8AniM5iRr0Du/Y08SL/NMhtF6H"
+			+ "hJ89nO4EPQ9ssRADAI6Ggxj6ZBfoavuXd/ye99osW8HsNlbqhXObu5mCMNySX2wa"
+			+ "HoWyRUEaUkI9eQw+MlHzIwzA32E7y2mU3OQBKdgLcBg4jxtcWVEg8ESKF9MpFXxl"
+			+ "pExxWrr4DFBfCRcsTwAFEQL9G3OvwJuEZXgx2JSS41D3pG4/qiHYICVa0u3p/14i"
+			+ "cq0kXajIk5ZJ6frCIAHIzuQ3n7jjzr05yR8s/qCrNbBA+nlkVNa/samk+jCzxxxa"
+			+ "cR/Dbh2wkvTFuDFFETwQYLuZAADcDck4YGQAmHivVT2NNDCf/aTz0+CJWl+xRc2l"
+			+ "Qw7D/SQjOkVMR19mYWN0b3I6AACbBnv9m5/bb/pjYAm2PtDp0CysQ9X9JCM6RUxH"
+			+ "X2ZhY3RvcjoAAJsFyHnSmaWguTFf6lJ/j39LtUNtmf0kIzpFTEdfZmFjdG9yOgAA"
+			+ "mwfwMD3LxmWtuCWBE9BptWMNH07Z/SQjOkVMR19mYWN0b3I6AACbBdhBrbSiM4UN"
+			+ "y7khDW2Sk0e4v9mIRgQYEQIABgUCPQ9ssQAKCRBQYshgIiS1+jCMAJ9txwHnb1Kl"
+			+ "6i/fSoDs8SkdM7w48wCdFvPEV0sSxE73073YhBgPZtMWbBo=");
+
+		//
+		// PGP freeware version 7
+		//
+		private static readonly byte[] pub5 = Base64.Decode(
+			"mQENBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5"
+			+ "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2"
+			+ "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR"
+			+ "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU"
+			+ "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa"
+			+ "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAG0KXBhbGFzaCBrYXNvZGhh"
+			+ "biA8cGthc29kaGFuQHRpYWEtY3JlZi5vcmc+iQEuBBABAgAYBQJAawROCAsBAwkI"
+			+ "BwIKAhkBBRsDAAAAAAoJEOfelumuiOrYqPEH+wYrdP5Tq5j+E5yN1pyCg1rwbSOt"
+			+ "Dka0y0p7Oq/VIGLk692IWPItLEunnBXQtGBcWqklrvogvlhxtf16FgoyScfLJx1e"
+			+ "1cJa+QQnVuH+VOESN6iS9Gp9lUfVOHv74mEMXw0l2Djfy/lnrkAMBatggyGnF9xF"
+			+ "VXOLk1J2WVFm9KUE23o6qdB7RGkf31pN2eA7SWmkdJSkUH7o/QSFBI+UTRZ/IY5P"
+			+ "ZIJpsdiIOqd9YMG/4RoSZuPqNRR6x7BSs8nQVR9bYs4PPlp4GfdRnOcRonoTeJCZ"
+			+ "83RnsraWJnJTg34gRLBcqumhTuFKc8nuCNK98D6zkQESdcHLLTquCOaF5L+5AQ0E"
+			+ "QGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAGLYsWSUfgaFv2srMiApyBVltf"
+			+ "i6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXOpO9NxYE1eZnel/QB7DtH12ZO"
+			+ "nrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENmkTkaQmPY4gTGymJTUhBbsSRq"
+			+ "2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGOTeqzcKGjr5XMPTs7/YgBpWPP"
+			+ "UxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gumjxOSjKT+jEm+8jACVzymEmc"
+			+ "XRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAYkBIgQYAQIADAUCQGsETwUbDAAA"
+			+ "AAAKCRDn3pbprojq2EynB/4/cEOtKbI5UisUd3vkTzvWOcqWUqGqi5wjjioNtIM5"
+			+ "pur2nFvhQE7SZ+PbAa87HRJU/4WcWMcoLkHD48JrQwHCHOLHSV5muYowb78X4Yh9"
+			+ "epYtSJ0uUahcn4Gp48p4BkhgsPYXkxEImSYzAOWStv21/7WEMqItMYl89BV6Upm8"
+			+ "HyTJx5MPTDbMR7X51hRg3OeQs6po3WTCWRzFIMyGm1rd/VK1L5ZDFPqO3S6YUJ0z"
+			+ "cxecYruvfK0Wp7q834wE8Zkl/PQ3NhfEPL1ZiLr/L00Ty+77/FZqt8SHRCICzOfP"
+			+ "OawcVGI+xHVXW6lijMpB5VaVIH8i2KdBMHXHtduIkPr9");
+
+		private static readonly byte[] sec5 = Base64.Decode(
+			"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");
+
+		private static readonly char[] sec5pass1 = "12345678".ToCharArray();
+
+		//
+		// Werner Koch "odd keys"
+		//
+		private static readonly byte[] pub6 = Base64.Decode(
+			"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"
+			+ "L4Kb7TWkd/OHQScVBO8sTUz0+2g=");
+
+//		private static readonly byte[] pub6check = Base64.Decode("62O9");
+
+		//
+		// revoked sub key
+		//
+		private static readonly byte[] pub7 = Base64.Decode(
+			"mQGiBEFOsIwRBADcjRx7nAs4RaWsQU6p8/ECLZD9sSeYc6CN6UDI96RKj0/hCzMs"
+			+ "qlA0+9fzGZ7ZEJ34nuvDKlhKGC7co5eOiE0a9EijxgcrZU/LClZWa4YfyNg/ri6I"
+			+ "yTyfOfrPQ33GNQt2iImDf3FKp7XKuY9nIxicGQEaW0kkuAmbV3oh0+9q8QCg/+fS"
+			+ "epDEqEE/+nKONULGizKUjMED/RtL6RThRftZ9DOSdBytGYd48z35pca/qZ6HA36K"
+			+ "PVQwi7V77VKQyKFLTOXPLnVyO85hyYB/Nv4DFHN+vcC7/49lfoyYMZlN+LarckHi"
+			+ "NL154wmmzygB/KKysvWBLgkErEBCD0xBDd89iTQNlDtVQAWGORVffl6WWjOAkliG"
+			+ "3dL6A/9A288HfFRnywqi3xddriV6wCPmStC3dkCS4vHk2ofS8uw4ZNoRlp1iEPna"
+			+ "ai2Xa9DX1tkhaGk2k96MqqbBdGpbW8sMA9otJ9xdMjWEm/CgJUFUFQf3zaVy3mkM"
+			+ "S2Lvb6P4Wc2l/diEEIyK8+PqJItSh0OVU3K9oM7ngHwVcalKILQVUkV2b2tlZCA8"
+			+ "UmV2b2tlZEB0ZWQ+iQBOBBARAgAOBQJBTrCMBAsDAgECGQEACgkQvglkcFA/c63+"
+			+ "QgCguh8rsJbPTtbhZcrqBi5Mo1bntLEAoPZQ0Kjmu2knRUpHBeUemHDB6zQeuQIN"
+			+ "BEFOsIwQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz"
+			+ "0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP"
+			+ "xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN"
+			+ "ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD"
+			+ "ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI"
+			+ "PWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/93zriSvSHqsi1FeEmUBo431Jkh"
+			+ "VerIzb6Plb1j6FIq+s3vyvx9K+dMvjotZqylWZj4GXpH+2xLJTjWkrGSfUZVI2Nk"
+			+ "nyOFxUCKLLqaqVBFAQIjULfvQfGEWiGQKk9aRLkdG+D+8Y2N9zYoBXoQ9arvvS/t"
+			+ "4mlOsiuaTe+BZ4x+BXTpF4b9sKZl7V8QP/TkoJWUdydkvxciHdWp7ssqyiKOFRhG"
+			+ "818knDfFQ3cn2w/RnOb+7AF9wDncXDPYLfpPv9b2qZoLrXcyvlLffGDUdWs553ut"
+			+ "1F5AprMURs8BGmY9BnjggfVubHdhTUoA4gVvrdaf+D9NwZAl0xK/5Y/oPuMZiQBG"
+			+ "BBgRAgAGBQJBTrCMAAoJEL4JZHBQP3Ot09gAoMmLKloVDP+WhDXnsM5VikxysZ4+"
+			+ "AKCrJAUO+lYAyPYwEwgK+bKmUGeKrIkARgQoEQIABgUCQU6wpQAKCRC+CWRwUD9z"
+			+ "rQK4AJ98kKFxGU6yhHPr6jYBJPWemTNOXgCfeGB3ox4PXeS4DJDuLy9yllytOjo=");
+
+//		private static readonly byte[] pub7check = Base64.Decode("f/YQ");
+
+		private static readonly byte[] pub8 = Base64.Decode(
+			"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"
+			+ "9Uqz3fUvGoewAWA=");
+
+		private static readonly byte[] sec8 = Base64.Decode(
+			"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");
+
+		private static readonly char[] sec8pass = "qwertyui".ToCharArray();
+
+		private static readonly byte[] sec9 = Base64.Decode(
+			"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"
+			+ "6neEEX/i1Q==");
+
+		public char[] sec9pass = "foo".ToCharArray();
+
+		// version 4 keys with expiry dates
+		private static readonly byte[] pub10 = Base64.Decode(
+			"mQGiBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0"
+			+ "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA"
+			+ "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ"
+			+ "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk"
+			+ "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF"
+			+ "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb"
+			+ "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B"
+			+ "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr"
+			+ "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHLQgdGVzdCBrZXkg"
+			+ "KHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUCQqqJrQIbAwUJACTqAAYL"
+			+ "CQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzLAJ42AeCRIBBjv8r8qw9y"
+			+ "laNj2GZ1sACgiWYHVXMA6B1H9I1kS3YsCd3Oq7qwAgAAuM0EQqqJrhADAKWkix8l"
+			+ "pJN7MMTXob4xFF1TvGll0UD1bDGOMMbes6aeXSbT9QXee/fH3GnijLY7wB+qTPv9"
+			+ "ohubrSpnv3yen3CEBW6Q2YK+NlCskma42Py8YMV2idmYjtJi1ckvHFWt5wADBQL/"
+			+ "fkB5Q5xSGgspMaTZmtmX3zG7ZDeZ0avP8e8mRL8UszCTpqs6vMZrXwyQLZPbtMYv"
+			+ "PQpuRGEeKj0ysimwYRA5rrLQjnRER3nyuuEUUgc4j+aeRxPf9WVsJ/a1FCHtaAP1"
+			+ "iE8EGBECAA8FAkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCfd66H7DL7kFGd"
+			+ "IoS+NIp8JO+noxAAn25si4QAF7og8+4T5YQUuhIhx/NesAIAAA==");
+
+		private static readonly byte[] sec10 = Base64.Decode(
+			"lQHhBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0"
+			+ "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA"
+			+ "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ"
+			+ "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk"
+			+ "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF"
+			+ "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb"
+			+ "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B"
+			+ "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr"
+			+ "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHP4DAwLssmOjVC+d"
+			+ "mWB783Lpzjb9evKzsxisTdx8/jHpUSS+r//6/Guyx3aA/zUw5bbftItW57mhuNNb"
+			+ "JTu7WrQgdGVzdCBrZXkgKHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUC"
+			+ "QqqJrQIbAwUJACTqAAYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzL"
+			+ "AJ0cYPwKeoSReY14LqJtAjnkX7URHACgsRZWfpbalrSyDnq3TtZeGPUqGX+wAgAA"
+			+ "nQEUBEKqia4QAwClpIsfJaSTezDE16G+MRRdU7xpZdFA9WwxjjDG3rOmnl0m0/UF"
+			+ "3nv3x9xp4oy2O8Afqkz7/aIbm60qZ798np9whAVukNmCvjZQrJJmuNj8vGDFdonZ"
+			+ "mI7SYtXJLxxVrecAAwUC/35AeUOcUhoLKTGk2ZrZl98xu2Q3mdGrz/HvJkS/FLMw"
+			+ "k6arOrzGa18MkC2T27TGLz0KbkRhHio9MrIpsGEQOa6y0I50REd58rrhFFIHOI/m"
+			+ "nkcT3/VlbCf2tRQh7WgD9f4DAwLssmOjVC+dmWDXVLRopzxbBGOvodp/LZoSDb56"
+			+ "gNJjDMJ1aXqWW9qTAg1CFjBq73J3oFpVzInXZ8+Q8inxv7bnWiHbiE8EGBECAA8F"
+			+ "AkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCgl2jw5hfk/JsyjulQqe1Nps1q"
+			+ "Lx0AoMdnFMZmTMLHn8scUW2j9XO312tmsAIAAA==");
+
+//		private static readonly char[] sec10pass = "test".ToCharArray();
+
+		private static readonly byte[] subKeyBindingKey = Base64.Decode(
+			"mQGiBDWagYwRBAD7UcH4TAIp7tmUoHBNxVxCVz2ZrNo79M6fV63riOiH2uDxfIpr"
+			+ "IrL0cM4ehEKoqlhngjDhX60eJrOw1nC5BpYZRnDnyDYT4wTWRguxObzGq9pqA1dM"
+			+ "oPTJhkFZVIBgFY99/ULRqaUYIhFGgBtnwS70J8/L/PGVc3DmWRLMkTDjSQCg/5Nh"
+			+ "MCjMK++MdYMcMl/ziaKRT6EEAOtw6PnU9afdohbpx9CK4UvCCEagfbnUtkSCQKSk"
+			+ "6cUp6VsqyzY0pai/BwJ3h4apFMMMpVrtBAtchVgqo4xTr0Sve2j0k+ase6FSImiB"
+			+ "g+AR7hvTUTcBjwtIExBc8TuCTqmn4GG8F7UMdl5Z0AZYj/FfAQYaRVZYP/pRVFNx"
+			+ "Lw65BAC/Fi3qgiGCJFvXnHIckTfcAmZnKSEXWY9NJ4YQb4+/nH7Vsw0wR/ZObUHR"
+			+ "bWgTc9Vw1uZIMe0XVj6Yk1dhGRehUnrm3mE7UJxu7pgkBCbFECFSlSSqP4MEJwZV"
+			+ "09YP/msu50kjoxyoTpt+16uX/8B4at24GF1aTHBxwDLd8X0QWrQsTWVycmlsbCBM"
+			+ "eW5jaCBDTEVBUiBzeXN0ZW0gREggPGNsZWFyQG1sLmNvbT6JAEsEEBECAAsFAjWa"
+			+ "gYwECwMBAgAKCRDyAGjiP47/XanfAKCs6BPURWVQlGh635VgL+pdkUVNUwCdFcNa"
+			+ "1isw+eAcopXPMj6ACOapepu5Ag0ENZqBlBAIAPZCV7cIfwgXcqK61qlC8wXo+VMR"
+			+ "OU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf"
+			+ "3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2g"
+			+ "pXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPA"
+			+ "Q/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQD"
+			+ "GcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIH"
+			+ "/RYtVo+HROZ6jrNjrATEwQm1fUQrk6n5+2dniN881lF0CNkB4NkHw1Xxz4Ejnu/0"
+			+ "iLg8fkOAsmanOsKpOkRtqUnVpsVL5mLJpFEyCY5jbcfj+KY9/25bs0ga7kLHNZia"
+			+ "zbCxJdF+W179z3nudQxRaXG/0XISIH7ziZbSVni69sKc1osk1+OoOMbSuZ86z535"
+			+ "Pln4fXclkFE927HxfbWoO+60hkOLKh7x+8fC82b3x9vCETujEaxrscO2xS7/MYXP"
+			+ "8t1ffriTDmhuIuQS2q4fLgeWdqrODrMhrD8Dq7e558gzp30ZCqpiS7EmKGczL7B8"
+			+ "gXxbBCVSTxYMJheXt2xMXsuJAD8DBRg1moGU8gBo4j+O/10RAgWdAKCPhaFIXuC8"
+			+ "/cdiNMxTDw9ug3De5QCfYXmDzRSFUu/nrCi8yz/l09wsnxo=");
+
+//		private static readonly byte[] subKeyBindingCheckSum = Base64.Decode("3HU+");
+
+		//
+		// PGP8 with SHA1 checksum.
+		//
+		private static readonly byte[] rewrapKey = Base64.Decode(
+			"lQOWBEUPOQgBCADdjPTtl8oOwqJFA5WU8p7oDK5KRWfmXeXUZr+ZJipemY5RSvAM"
+			+ "rxqsM47LKYbmXOJznXCQ8+PPa+VxXAsI1CXFHIFqrXSwvB/DUmb4Ec9EuvNd18Zl"
+			+ "hJAybzmV2KMkaUp9oG/DUvxZJqkpUddNfwqZu0KKKZWF5gwW5Oy05VCpaJxQVXFS"
+			+ "whdbRfwEENJiNx4RB3OlWhIjY2p+TgZfgQjiGB9i15R+37sV7TqzBUZF4WWcnIRQ"
+			+ "DnpUfxHgxQ0wO/h/aooyRHSpIx5i4oNpMYq9FNIyakEx/Bomdbs5hW9dFxhrE8Es"
+			+ "UViAYITgTsyROxmgGatGG09dcmVDJVYF4i7JAAYpAAf/VnVyUDs8HrxYTOIt4rYY"
+			+ "jIHToBsV0IiLpA8fEA7k078L1MwSwERVVe6oHVTjeR4A9OxE52Vroh2eOLnF3ftf"
+			+ "6QThVVZr+gr5qeG3yvQ36N7PXNEVOlkyBzGmFQNe4oCA+NR2iqnAIspnekVmwJV6"
+			+ "xVvPCjWw/A7ZArDARpfthspwNcJAp4SWfoa2eKzvUTznTyqFu2PSS5fwQZUgOB0P"
+			+ "Y2FNaKeqV8vEZu4SUWwLOqXBQIZXiaLvdKNgwFvUe3kSHdCNsrVzW7SYxFwaEog2"
+			+ "o6YLKPVPqjlGX1cMOponGp+7n9nDYkQjtEsGSSMQkQRDAcBdSVJmLO07kFOQSOhL"
+			+ "WQQA49BcgTZyhyH6TnDBMBHsGCYj43FnBigypGT9FrQHoWybfX47yZaZFROAaaMa"
+			+ "U6man50YcYZPwzDzXHrK2MoGALY+DzB3mGeXVB45D/KYtlMHPLgntV9T5b14Scbc"
+			+ "w1ES2OUtsSIUs0zelkoXqjLuKnSIYK3mMb67Au7AEp6LXM8EAPj2NypvC86VEnn+"
+			+ "FH0QHvUwBpmDw0EZe25xQs0brvAG00uIbiZnTH66qsIfRhXV/gbKK9J5DTGIqQ15"
+			+ "DuPpz7lcxg/n2+SmjQLNfXCnG8hmtBjhTe+udXAUrmIcfafXyu68SAtebgm1ga56"
+			+ "zUfqsgN3FFuMUffLl3myjyGsg5DnA/oCFWL4WCNClOgL6A5VkNIUait8QtSdCACT"
+			+ "Y7jdSOguSNXfln0QT5lTv+q1AjU7zjRl/LsFNmIJ5g2qdDyK937FOXM44FEEjZty"
+			+ "/4P2dzYpThUI4QUohIj8Qi9f2pZQueC5ztH6rpqANv9geZKcciAeAbZ8Md0K2TEU"
+			+ "RD3Lh+RSBzILtBtUZXN0IEtleSA8dGVzdEBleGFtcGxlLmNvbT6JATYEEwECACAF"
+			+ "AkUPOQgCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRDYpknHeQaskD9NB/9W"
+			+ "EbFuLaqZAl3yjLU5+vb75BdvcfL1lUs44LZVwobNp3/0XbZdY76xVPNZURtU4u3L"
+			+ "sJfGlaF+EqZDE0Mqc+vs5SIb0OnCzNJ00KaUFraUtkByRV32T5ECHK0gMBjCs5RT"
+			+ "I0vVv+Qmzl4+X1Y2bJ2mlpBejHIrOzrBD5NTJimTAzyfnNfipmbqL8p/cxXKKzS+"
+			+ "OM++ZFNACj6lRM1W9GioXnivBRC88gFSQ4/GXc8yjcrMlKA27JxV+SZ9kRWwKH2f"
+			+ "6o6mojUQxnHr+ZFKUpo6ocvTgBDlC57d8IpwJeZ2TvqD6EdA8rZ0YriVjxGMDrX1"
+			+ "8esfw+iLchfEwXtBIRwS");
+
+		private static readonly char[] rewrapPass = "voltage123".ToCharArray();
+
+		private static readonly byte[] pubWithX509 = Base64.Decode(
+			  "mQENBERabjABCACtmfyo6Nph9MQjv4nmCWjZrRYnhXbivomAdIwYkLZUj1bjqE+j"
+			+ "uaLzjZV8xSI59odZvrmOiqlzOc4txitQ1OX7nRgbOJ7qku0dvwjtIn46+HQ+cAFn"
+			+ "2mTi81RyXEpO2uiZXfsNTxUtMi+ZuFLufiMc2kdk27GZYWEuasdAPOaPJnA+wW6i"
+			+ "ZHlt0NfXIGNz864gRwhD07fmBIr1dMFfATWxCbgMd/rH7Z/j4rvceHD2n9yrhPze"
+			+ "YN7W4Nuhsr2w/Ft5Cm9xO7vXT/cpto45uxn8f7jERep6bnUwNOhH8G+6xLQgTLD0"
+			+ "qFBGVSIneK3lobs6+xn6VaGN8W0tH3UOaxA1ABEBAAG0D0NOPXFhLWRlZXBzaWdo"
+			+ "dIkFDgQQZAIFAQUCRFpuMAUDCWdU0gMF/3gCGwPELGQBAQQwggTkMIIDzKADAgEC"
+			+ "AhBVUMV/M6rIiE+IzmnPheQWMA0GCSqGSIb3DQEBBQUAMG4xEzARBgoJkiaJk/Is"
+			+ "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt"
+			+ "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo"
+			+ "dDAeFw0wNjA1MDQyMTEyMTZaFw0xMTA1MDQyMTIwMDJaMG4xEzARBgoJkiaJk/Is"
+			+ "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt"
+			+ "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo"
+			+ "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2Z/Kjo2mH0xCO/ieYJ"
+			+ "aNmtFieFduK+iYB0jBiQtlSPVuOoT6O5ovONlXzFIjn2h1m+uY6KqXM5zi3GK1DU"
+			+ "5fudGBs4nuqS7R2/CO0ifjr4dD5wAWfaZOLzVHJcSk7a6Jld+w1PFS0yL5m4Uu5+"
+			+ "IxzaR2TbsZlhYS5qx0A85o8mcD7BbqJkeW3Q19cgY3PzriBHCEPTt+YEivV0wV8B"
+			+ "NbEJuAx3+sftn+Piu9x4cPaf3KuE/N5g3tbg26GyvbD8W3kKb3E7u9dP9ym2jjm7"
+			+ "Gfx/uMRF6npudTA06Efwb7rEtCBMsPSoUEZVIid4reWhuzr7GfpVoY3xbS0fdQ5r"
+			+ "EDUCAwEAAaOCAXwwggF4MAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G"
+			+ "A1UdDgQWBBSmFTRv5y65DHtTYae48zl0ExNWZzCCASUGA1UdHwSCARwwggEYMIIB"
+			+ "FKCCARCgggEMhoHFbGRhcDovLy9DTj1xYS1kZWVwc2lnaHQsQ049cWEtd3VtYW4x"
+			+ "LWRjLENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNl"
+			+ "cyxDTj1Db25maWd1cmF0aW9uLERDPVdlYmZlLERDPXRtczAxLERDPXFhLERDPWNv"
+			+ "bT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JM"
+			+ "RGlzdHJpYnV0aW9uUG9pbnSGQmh0dHA6Ly9xYS13dW1hbjEtZGMud2ViZmUudG1z"
+			+ "MDEucWEuY29tL0NlcnRFbnJvbGwvcWEtZGVlcHNpZ2h0LmNybDAQBgkrBgEEAYI3"
+			+ "FQEEAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAfuZCW3XlB7Eok35zQbvYt9rhAndT"
+			+ "DNw3wPNI4ZzD1nXoYWnwhNNvWRpsOt4ExOSNdaHErfgDXAMyyg66Sro0TkAx8eAj"
+			+ "fPQsyRAh0nm0glzFmJN6TdOZbj7hqGZjc4opQ6nZo8h/ULnaEwMIUW4gcSkZt0ww"
+			+ "CuErl5NUrN3DpkREeCG/fVvQZ8ays3ibQ5ZCZnYBkLYq/i0r3NLW34WfYhjDY48J"
+			+ "oQWtvFSAxvRfz2NGmqnrCHPQZxqlfdta97kDa4VQ0zSeBaC70gZkLmD1GJMxWoXW"
+			+ "6tmEcgPY5SghInUf+L2u52V55MjyAFzVp7kTK2KY+p7qw35vzckrWkwu8AAAAAAA"
+			+ "AQE=");
+
+		private static readonly byte[] secWithPersonalCertificate = Base64.Decode(
+			"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"
+			+ "0/vPdYWSaQIAwYeo2Ce+b7M5ifbGMDWYBisEvGISg5xfvbe6qApmHS4QVQzE"
+			+ "Ym81rdJJ8OfvgSbHcgn37S3OBXIQvNdejF4BWqM9sAGHtCBIeW5lay1JbnRy"
+			+ "YW5ldCA8aHluZWtAYWxzb2Z0LmN6PrADA///iQDrBBABAgBVBQJIxi2bBQkB"
+			+ "mgKAMBSAAAAAACAAB3ByZWZlcnJlZC1lbWFpbC1lbmNvZGluZ0BwZ3AuY29t"
+			+ "cGdwbWltZQULBwgJAgIZAQUbAQAAAAUeAQAAAAIVAgAKCRDlTa3BE84gWVKW"
+			+ "BACcoCFKvph9r9QiHT1Z3N4wZH36Uxqu/059EFALnBkEdVudX/p6S9mynGRk"
+			+ "EfhmWFC1O6dMpnt+ZBEed/4XyFWVSLPwirML+6dxfXogdUsdFF1NCRHc3QGc"
+			+ "txnNUT/zcZ9IRIQjUhp6RkIvJPHcyfTXKSbLviI+PxzHU2Padq8pV7ABZ7kA"
+			+ "jQRIfg8tAQQAutJR/aRnfZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr"
+			+ "5dg50wq3I4HOamRxUwHpdPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO"
+			+ "8LUJ2VTbfPxoLFp539SQ0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0Ft"
+			+ "JycAEQEAAbABj4kEzQQYAQIENwUCSMYtnAUJAeEzgMLFFAAAAAAAFwNleDUw"
+			+ "OWNlcnRpZmljYXRlQHBncC5jb20wggNhMIICyqADAgECAgkA1AoCoRKJCgsw"
+			+ "DQYJKoZIhvcNAQEFBQAwgakxCzAJBgNVBAYTAkNaMRcwFQYDVQQIEw5DemVj"
+			+ "aCBSZXB1YmxpYzESMBAGA1UEChQJQSYmTCBzb2Z0MSAwHgYDVQQLExdJbnRl"
+			+ "cm5hbCBEZXZlbG9wbWVudCBDQTEqMCgGA1UEAxQhQSYmTCBzb2Z0IEludGVy"
+			+ "bmFsIERldmVsb3BtZW50IENBMR8wHQYJKoZIhvcNAQkBFhBrYWRsZWNAYWxz"
+			+ "b2Z0LmN6MB4XDTA4MDcxNjE1MDkzM1oXDTA5MDcxNjE1MDkzM1owaTELMAkG"
+			+ "A1UEBhMCQ1oxFzAVBgNVBAgTDkN6ZWNoIFJlcHVibGljMRIwEAYDVQQKFAlB"
+			+ "JiZMIHNvZnQxFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5IeW5l"
+			+ "ay1JbnRyYW5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAutJR/aRn"
+			+ "fZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr5dg50wq3I4HOamRxUwHp"
+			+ "dPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO8LUJ2VTbfPxoLFp539SQ"
+			+ "0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0FtJycCAwEAAaOBzzCBzDAJ"
+			+ "BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD"
+			+ "ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNaw7A6r10PtYZzAvr9CrSKeRYJgwHwYD"
+			+ "VR0jBBgwFoAUmqSRM8rN3+T1+tkGiqef8S5suYgwGgYDVR0RBBMwEYEPaHlu"
+			+ "ZWtAYWxzb2Z0LmN6MCgGA1UdHwQhMB8wHaAboBmGF2h0dHA6Ly9wZXRyazIv"
+			+ "Y2EvY2EuY3JsMAsGA1UdDwQEAwIF4DANBgkqhkiG9w0BAQUFAAOBgQCUdOWd"
+			+ "7mBLWj1/GSiYgfwgdTrgk/VZOJvMKBiiFyy1iFEzldz6Xx+mAexnFJKfZXZb"
+			+ "EMEGWHfWPmgJzAtuTT0Jz6tUwDmeLH3MP4m8uOZtmyUJ2aq41kciV3rGxF0G"
+			+ "BVlZ/bWTaOzHdm6cjylt6xxLt6MJzpPBA/9ZfybSBh1DaAUbDgAAAJ0gBBkB"
+			+ "AgAGBQJIxi2bAAoJEAdYkEWLb2R2fJED/RK+JErZ98uGo3Z81cHkdP3rk8is"
+			+ "DUL/PR3odBPFH2SIA5wrzklteLK/ZXmBUzcvxqHEgI1F7goXbsBgeTuGgZdx"
+			+ "pINErxkNpcMl9FTldWKGiapKrhkZ+G8knDizF/Y7Lg6uGd2nKVxzutLXdHJZ"
+			+ "pU89Q5nzq6aJFAZo5TBIcchQAAoJEOVNrcETziBZXvQD/1mvFqBfWqwXxoj3"
+			+ "8fHUuFrE2pcp32y3ciO2i+uNVEkNDoaVVNw5eHQaXXWpllI/Pe6LnBl4vkyc"
+			+ "n3pjONa4PKrePkEsCUhRbIySqXIHuNwZumDOlKzZHDpCUw72LaC6S6zwuoEf"
+			+ "ucOcxTeGIUViANWXyTIKkHfo7HfigixJIL8nsAFn");
+
+		[Test]
+		public void PerformTest1()
+		{
+			PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(pub1);
+
+			int count = 0;
+
+			foreach (PgpPublicKeyRing pgpPub1 in pubRings.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+				byte[] bytes = pgpPub1.GetEncoded();
+
+				PgpPublicKeyRing pgpPub2 = new PgpPublicKeyRing(bytes);
+
+				foreach (PgpPublicKey pubKey in pgpPub2.GetPublicKeys())
+				{
+					keyCount++;
+
+					foreach (PgpSignature sig in pubKey.GetSignatures())
+					{
+						if (sig == null)
+							Fail("null signature found");
+					}
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of public keys");
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of public keyrings");
+			}
+
+			//
+			// exact match
+			//
+			count = 0;
+			foreach (PgpPublicKeyRing pgpPub3 in pubRings.GetKeyRings("test (Test key) <test@ubicall.com>"))
+			{
+				if (pgpPub3 == null)
+					Fail("null keyring found");
+
+				count++;
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of public keyrings on exact match");
+			}
+
+			//
+			// partial match 1 expected
+			//
+			count = 0;
+			foreach (PgpPublicKeyRing pgpPub4 in pubRings.GetKeyRings("test", true))
+			{
+				if (pgpPub4 == null)
+					Fail("null keyring found");
+
+				count++;
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of public keyrings on partial match 1");
+			}
+
+			//
+			// partial match 0 expected
+			//
+			count = 0;
+			foreach (PgpPublicKeyRing pgpPub5 in pubRings.GetKeyRings("XXX", true))
+			{
+				if (pgpPub5 == null)
+					Fail("null keyring found");
+
+				count++;
+			}
+
+			if (count != 0)
+			{
+				Fail("wrong number of public keyrings on partial match 0");
+			}
+
+			//
+			// case-insensitive partial match
+			//
+			count = 0;
+			foreach (PgpPublicKeyRing pgpPub6 in pubRings.GetKeyRings("TEST@ubicall.com", true, true))
+			{
+				if (pgpPub6 == null)
+					Fail("null keyring found");
+
+				count++;
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of public keyrings on case-insensitive partial match");
+			}
+
+			PgpSecretKeyRingBundle secretRings = new PgpSecretKeyRingBundle(sec1);
+			count = 0;
+
+			foreach (PgpSecretKeyRing pgpSec1 in secretRings.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpSec1.GetEncoded();
+
+				PgpSecretKeyRing pgpSec2 = new PgpSecretKeyRing(bytes);
+
+				foreach (PgpSecretKey k in pgpSec2.GetSecretKeys())
+				{
+					keyCount++;
+					PgpPublicKey pk = k.PublicKey;
+
+					pk.GetSignatures();
+
+					byte[] pkBytes = pk.GetEncoded();
+
+					PgpPublicKeyRing pkR = new PgpPublicKeyRing(pkBytes);
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of secret keys");
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of secret keyrings");
+			}
+
+			//
+			// exact match
+			//
+			count = 0;
+			foreach (PgpSecretKeyRing o1 in secretRings.GetKeyRings("test (Test key) <test@ubicall.com>"))
+			{
+				if (o1 == null)
+					Fail("null keyring found");
+
+				count++;
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of secret keyrings on exact match");
+			}
+
+			//
+			// partial match 1 expected
+			//
+			count = 0;
+			foreach (PgpSecretKeyRing o2 in secretRings.GetKeyRings("test", true))
+			{
+				if (o2 == null)
+					Fail("null keyring found");
+
+				count++;
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of secret keyrings on partial match 1");
+			}
+
+			//
+			// exact match 0 expected
+			//
+			count = 0;
+			foreach (PgpSecretKeyRing o3 in secretRings.GetKeyRings("test", false))
+			{
+				if (o3 == null)
+					Fail("null keyring found");
+
+				count++;
+			}
+
+			if (count != 0)
+			{
+				Fail("wrong number of secret keyrings on partial match 0");
+			}
+
+			//
+			// case-insensitive partial match
+			//
+			count = 0;
+			foreach (PgpSecretKeyRing o4 in secretRings.GetKeyRings("TEST@ubicall.com", true, true))
+			{
+				if (o4 == null)
+					Fail("null keyring found");
+
+				count++;
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of secret keyrings on case-insensitive partial match");
+			}
+		}
+
+		[Test]
+		public void PerformTest2()
+		{
+			PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(pub2);
+
+			int count = 0;
+
+			byte[] encRing = pubRings.GetEncoded();
+
+			pubRings = new PgpPublicKeyRingBundle(encRing);
+
+			foreach (PgpPublicKeyRing pgpPub1 in pubRings.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpPub1.GetEncoded();
+
+				PgpPublicKeyRing pgpPub2 = new PgpPublicKeyRing(bytes);
+
+				foreach (PgpPublicKey pk in pgpPub2.GetPublicKeys())
+				{
+					byte[] pkBytes = pk.GetEncoded();
+
+					PgpPublicKeyRing pkR = new PgpPublicKeyRing(pkBytes);
+
+					keyCount++;
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of public keys");
+				}
+			}
+
+			if (count != 2)
+			{
+				Fail("wrong number of public keyrings");
+			}
+
+			PgpSecretKeyRingBundle secretRings2 = new PgpSecretKeyRingBundle(sec2);
+
+			count = 0;
+
+
+			encRing = secretRings2.GetEncoded();
+			PgpSecretKeyRingBundle secretRings = new PgpSecretKeyRingBundle(encRing);
+
+			foreach (PgpSecretKeyRing pgpSec1 in secretRings2.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpSec1.GetEncoded();
+
+				PgpSecretKeyRing pgpSec2 = new PgpSecretKeyRing(bytes);
+
+				foreach (PgpSecretKey k in pgpSec2.GetSecretKeys())
+				{
+					keyCount++;
+					PgpPublicKey pk = k.PublicKey;
+
+					if (pk.KeyId == -1413891222336124627L)
+					{
+						int sCount = 0;
+
+						foreach (PgpSignature pgpSignature in pk.GetSignaturesOfType(PgpSignature.SubkeyBinding))
+						{
+							int type = pgpSignature.SignatureType;
+							if (type != PgpSignature.SubkeyBinding)
+							{
+								Fail("failed to return correct signature type");
+							}
+							sCount++;
+						}
+
+						if (sCount != 1)
+						{
+							Fail("failed to find binding signature");
+						}
+					}
+
+					pk.GetSignatures();
+
+					if (k.KeyId == -4049084404703773049L
+						|| k.KeyId == -1413891222336124627L)
+					{
+						k.ExtractPrivateKey(sec2pass1);
+					}
+					else if (k.KeyId == -6498553574938125416L
+						|| k.KeyId == 59034765524361024L)
+					{
+						k.ExtractPrivateKey(sec2pass2);
+					}
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of secret keys");
+				}
+			}
+
+			if (count != 2)
+			{
+				Fail("wrong number of secret keyrings");
+			}
+		}
+
+		[Test]
+		public void PerformTest3()
+		{
+			PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(pub3);
+
+			int count = 0;
+
+			byte[] encRing = pubRings.GetEncoded();
+
+			pubRings = new PgpPublicKeyRingBundle(encRing);
+
+			foreach (PgpPublicKeyRing pgpPub1 in pubRings.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpPub1.GetEncoded();
+
+				PgpPublicKeyRing pgpPub2 = new PgpPublicKeyRing(bytes);
+
+				foreach (PgpPublicKey pubK in pgpPub2.GetPublicKeys())
+				{
+					keyCount++;
+					pubK.GetSignatures();
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of public keys");
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of public keyrings");
+			}
+
+			PgpSecretKeyRingBundle secretRings2 = new PgpSecretKeyRingBundle(sec3);
+
+			count = 0;
+
+			encRing = secretRings2.GetEncoded();
+
+			PgpSecretKeyRingBundle secretRings = new PgpSecretKeyRingBundle(encRing);
+
+			foreach (PgpSecretKeyRing pgpSec1 in secretRings2.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpSec1.GetEncoded();
+
+				PgpSecretKeyRing pgpSec2 = new PgpSecretKeyRing(bytes);
+
+				foreach (PgpSecretKey k in pgpSec2.GetSecretKeys())
+				{
+					keyCount++;
+					k.ExtractPrivateKey(sec3pass1);
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of secret keys");
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of secret keyrings");
+			}
+		}
+
+		[Test]
+		public void PerformTest4()
+		{
+			PgpSecretKeyRingBundle secretRings1 = new PgpSecretKeyRingBundle(sec4);
+			int count = 0;
+
+
+			byte[] encRing = secretRings1.GetEncoded();
+
+			PgpSecretKeyRingBundle secretRings2 = new PgpSecretKeyRingBundle(encRing);
+
+			foreach (PgpSecretKeyRing pgpSec1 in secretRings1.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpSec1.GetEncoded();
+
+				PgpSecretKeyRing pgpSec2 = new PgpSecretKeyRing(bytes);
+
+				foreach (PgpSecretKey k in pgpSec2.GetSecretKeys())
+				{
+					keyCount++;
+					k.ExtractPrivateKey(sec3pass1);
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of secret keys");
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of secret keyrings");
+			}
+		}
+
+		[Test]
+		public void PerformTest5()
+		{
+			PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(pub5);
+
+			int count = 0;
+
+			byte[] encRing = pubRings.GetEncoded();
+
+			pubRings = new PgpPublicKeyRingBundle(encRing);
+
+			foreach (PgpPublicKeyRing pgpPub1 in pubRings.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpPub1.GetEncoded();
+
+				PgpPublicKeyRing pgpPub2 = new PgpPublicKeyRing(bytes);
+
+				foreach (PgpPublicKey o in pgpPub2.GetPublicKeys())
+				{
+					if (o == null)
+						Fail("null keyring found");
+
+					keyCount++;
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of public keys");
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of public keyrings");
+			}
+
+#if INCLUDE_IDEA
+			PgpSecretKeyRingBundle secretRings1 = new PgpSecretKeyRingBundle(sec5);
+
+			count = 0;
+
+			encRing = secretRings1.GetEncoded();
+
+			PgpSecretKeyRingBundle secretRings2 = new PgpSecretKeyRingBundle(encRing);
+
+			foreach (PgpSecretKeyRing pgpSec1 in secretRings1.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpSec1.GetEncoded();
+
+				PgpSecretKeyRing pgpSec2 = new PgpSecretKeyRing(bytes);
+
+				foreach (PgpSecretKey k in pgpSec2.GetSecretKeys())
+				{
+					keyCount++;
+					k.ExtractPrivateKey(sec5pass1);
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of secret keys");
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of secret keyrings");
+			}
+#endif
+		}
+
+		[Test]
+		public void PerformTest6()
+		{
+			PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(pub6);
+
+			foreach (PgpPublicKeyRing pgpPub in pubRings.GetKeyRings())
+			{
+				foreach (PgpPublicKey k in pgpPub.GetPublicKeys())
+				{
+					if (k.KeyId == 0x5ce086b5b5a18ff4L)
+					{
+						int count = 0;
+
+						foreach (PgpSignature sig in k.GetSignaturesOfType(PgpSignature.SubkeyRevocation))
+						{
+							if (sig == null)
+								Fail("null signature found");
+
+							count++;
+						}
+
+						if (count != 1)
+						{
+							Fail("wrong number of revocations in test6.");
+						}
+					}
+				}
+			}
+
+			byte[] encRing = pubRings.GetEncoded();
+		}
+
+		[Test, Explicit]
+		public void PerformTest7()
+		{
+			PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(pub7);
+			PgpPublicKey masterKey = null;
+
+			foreach (PgpPublicKey k in pgpPub.GetPublicKeys())
+			{
+				if (k.IsMasterKey)
+				{
+					masterKey = k;
+					continue;
+				}
+
+				int count = 0;
+				PgpSignature sig = null;
+
+				foreach (PgpSignature sigTemp in k.GetSignaturesOfType(PgpSignature.SubkeyRevocation))
+				{
+					sig = sigTemp;
+					count++;
+				}
+
+				if (count != 1)
+				{
+					Fail("wrong number of revocations in test7.");
+				}
+
+				sig.InitVerify(masterKey);
+
+				if (!sig.VerifyCertification(k))
+				{
+					Fail("failed to verify revocation certification");
+				}
+			}
+		}
+
+		[Test]
+		public void PerformTest8()
+		{
+			PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(pub8);
+
+			int count = 0;
+
+			byte[] encRing = pubRings.GetEncoded();
+
+			pubRings = new PgpPublicKeyRingBundle(encRing);
+
+			foreach (PgpPublicKeyRing pgpPub1 in pubRings.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpPub1.GetEncoded();
+
+				PgpPublicKeyRing pgpPub2 = new PgpPublicKeyRing(bytes);
+
+				foreach (PgpPublicKey o in pgpPub2.GetPublicKeys())
+				{
+					if (o == null)
+						Fail("null key found");
+
+					keyCount++;
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of public keys");
+				}
+			}
+
+			if (count != 2)
+			{
+				Fail("wrong number of public keyrings");
+			}
+
+			PgpSecretKeyRingBundle secretRings1 = new PgpSecretKeyRingBundle(sec8);
+
+			count = 0;
+
+			encRing = secretRings1.GetEncoded();
+
+			PgpSecretKeyRingBundle secretRings2 = new PgpSecretKeyRingBundle(encRing);
+
+			foreach (PgpSecretKeyRing pgpSec1 in secretRings1.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpSec1.GetEncoded();
+
+				PgpSecretKeyRing pgpSec2 = new PgpSecretKeyRing(bytes);
+
+				foreach (PgpSecretKey k in pgpSec2.GetSecretKeys())
+				{
+					keyCount++;
+					k.ExtractPrivateKey(sec8pass);
+				}
+
+				if (keyCount != 2)
+				{
+					Fail("wrong number of secret keys");
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of secret keyrings");
+			}
+		}
+
+		[Test]
+		public void PerformTest9()
+		{
+			PgpSecretKeyRingBundle secretRings1 = new PgpSecretKeyRingBundle(sec9);
+
+			int count = 0;
+
+			byte[] encRing = secretRings1.GetEncoded();
+
+			PgpSecretKeyRingBundle secretRings2 = new PgpSecretKeyRingBundle(encRing);
+
+			foreach (PgpSecretKeyRing pgpSec1 in secretRings1.GetKeyRings())
+			{
+				count++;
+
+				int keyCount = 0;
+
+				byte[] bytes = pgpSec1.GetEncoded();
+
+				PgpSecretKeyRing pgpSec2 = new PgpSecretKeyRing(bytes);
+
+				foreach (PgpSecretKey k in pgpSec2.GetSecretKeys())
+				{
+					keyCount++;
+
+					PgpPrivateKey pKey = k.ExtractPrivateKey(sec9pass);
+					if (keyCount == 1 && pKey != null)
+					{
+						Fail("primary secret key found, null expected");
+					}
+				}
+
+				if (keyCount != 3)
+				{
+					Fail("wrong number of secret keys");
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("wrong number of secret keyrings");
+			}
+		}
+
+		[Test]
+		public void PerformTest10()
+		{
+			PgpSecretKeyRing secretRing = new PgpSecretKeyRing(sec10);
+
+			foreach (PgpSecretKey secretKey in secretRing.GetSecretKeys())
+			{
+				PgpPublicKey pubKey = secretKey.PublicKey;
+
+				if (pubKey.ValidDays != 28)
+				{
+					Fail("days wrong on secret key ring");
+				}
+
+				if (pubKey.GetValidSeconds() != 28 * 24 * 60 * 60)
+				{
+					Fail("seconds wrong on secret key ring");
+				}
+			}
+
+			PgpPublicKeyRing publicRing = new PgpPublicKeyRing(pub10);
+
+			foreach (PgpPublicKey pubKey in publicRing.GetPublicKeys())
+			{
+				if (pubKey.ValidDays != 28)
+				{
+					Fail("days wrong on public key ring");
+				}
+
+				if (pubKey.GetValidSeconds() != 28 * 24 * 60 * 60)
+				{
+					Fail("seconds wrong on public key ring");
+				}
+			}
+		}
+
+		[Test]
+		public void PerformTest11()
+		{
+			PgpPublicKeyRing pubRing = new PgpPublicKeyRing(subKeyBindingKey);
+
+			foreach (PgpPublicKey key in pubRing.GetPublicKeys())
+			{
+				if (key.GetValidSeconds() != 0)
+				{
+					Fail("expiration time non-zero");
+				}
+			}
+		}
+
+		[Test]
+		public void GenerateTest()
+		{
+			char[] passPhrase = "hello".ToCharArray();
+			DsaParametersGenerator pGen = new DsaParametersGenerator();
+			pGen.Init(512, 80, new SecureRandom());
+			DsaParameters dsaParams = pGen.GenerateParameters();
+			DsaKeyGenerationParameters dsaKgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams);
+			IAsymmetricCipherKeyPairGenerator dsaKpg = GeneratorUtilities.GetKeyPairGenerator("DSA");
+			dsaKpg.Init(dsaKgp);
+
+
+			//
+			// this takes a while as the key generator has to Generate some DSA parameters
+			// before it Generates the key.
+			//
+			AsymmetricCipherKeyPair dsaKp = dsaKpg.GenerateKeyPair();
+			IAsymmetricCipherKeyPairGenerator elgKpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL");
+
+			BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
+			BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
+
+			ElGamalParameters elParams = new ElGamalParameters(p, g);
+			ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(new SecureRandom(), elParams);
+			elgKpg.Init(elKgp);
+
+			//
+			// this is quicker because we are using preGenerated parameters.
+			//
+			AsymmetricCipherKeyPair elgKp = elgKpg.GenerateKeyPair();
+			PgpKeyPair dsaKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.Dsa, dsaKp, DateTime.UtcNow);
+			PgpKeyPair elgKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalEncrypt, elgKp, DateTime.UtcNow);
+
+			PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, dsaKeyPair,
+				"test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, new SecureRandom());
+
+			keyRingGen.AddSubKey(elgKeyPair);
+
+			PgpSecretKeyRing keyRing = keyRingGen.GenerateSecretKeyRing();
+
+			keyRing.GetSecretKey().ExtractPrivateKey(passPhrase);
+
+			PgpPublicKeyRing pubRing = keyRingGen.GeneratePublicKeyRing();
+
+			PgpPublicKey vKey = null;
+			PgpPublicKey sKey = null;
+
+			foreach (PgpPublicKey pk in pubRing.GetPublicKeys())
+			{
+				if (pk.IsMasterKey)
+				{
+					vKey = pk;
+				}
+				else
+				{
+					sKey = pk;
+				}
+			}
+
+			foreach (PgpSignature sig in sKey.GetSignatures())
+			{
+				if (sig.KeyId == vKey.KeyId
+					&& sig.SignatureType == PgpSignature.SubkeyBinding)
+				{
+					sig.InitVerify(vKey);
+
+					if (!sig.VerifyCertification(vKey, sKey))
+					{
+						Fail("failed to verify sub-key signature.");
+					}
+				}
+			}
+		}
+
+		[Test]
+		public void InsertMasterTest()
+		{
+			SecureRandom random = new SecureRandom();
+
+			char[] passPhrase = "hello".ToCharArray();
+			IAsymmetricCipherKeyPairGenerator rsaKpg = GeneratorUtilities.GetKeyPairGenerator("RSA");
+
+			rsaKpg.Init(new KeyGenerationParameters(random, 512));
+
+			//
+			// this is quicker because we are using pregenerated parameters.
+			//
+			AsymmetricCipherKeyPair rsaKp = rsaKpg.GenerateKeyPair();
+			PgpKeyPair rsaKeyPair1 = new PgpKeyPair(PublicKeyAlgorithmTag.RsaGeneral, rsaKp, DateTime.UtcNow);
+
+			rsaKp = rsaKpg.GenerateKeyPair();
+			PgpKeyPair rsaKeyPair2 = new PgpKeyPair(PublicKeyAlgorithmTag.RsaGeneral, rsaKp, DateTime.UtcNow);
+
+			PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification,
+				rsaKeyPair1, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, random);
+			PgpSecretKeyRing secRing1 = keyRingGen.GenerateSecretKeyRing();
+			PgpPublicKeyRing pubRing1 = keyRingGen.GeneratePublicKeyRing();
+
+			keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification,
+				rsaKeyPair2, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, random);
+			PgpSecretKeyRing secRing2 = keyRingGen.GenerateSecretKeyRing();
+			PgpPublicKeyRing pubRing2 = keyRingGen.GeneratePublicKeyRing();
+
+			try
+			{
+				PgpPublicKeyRing.InsertPublicKey(pubRing1, pubRing2.GetPublicKey());
+				Fail("adding second master key (public) should throw an ArgumentException");
+			}
+			catch (ArgumentException e)
+			{
+				if (!e.Message.Equals("cannot add a master key to a ring that already has one"))
+				{
+					Fail("wrong message in public test");
+				}
+			}
+
+			try
+			{
+				PgpSecretKeyRing.InsertSecretKey(secRing1, secRing2.GetSecretKey());
+				Fail("adding second master key (secret) should throw an ArgumentException");
+			}
+			catch (ArgumentException e)
+			{
+				if (!e.Message.Equals("cannot add a master key to a ring that already has one"))
+				{
+					Fail("wrong message in secret test");
+				}
+			}
+		}
+
+		[Test]
+		public void GenerateSha1Test()
+		{
+			char[] passPhrase = "hello".ToCharArray();
+
+			IAsymmetricCipherKeyPairGenerator dsaKpg = GeneratorUtilities.GetKeyPairGenerator("DSA");
+			DsaParametersGenerator pGen = new DsaParametersGenerator();
+			pGen.Init(512, 80, new SecureRandom());
+			DsaParameters dsaParams = pGen.GenerateParameters();
+			DsaKeyGenerationParameters kgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams);
+			dsaKpg.Init(kgp);
+
+			//
+			// this takes a while as the key generator has to generate some DSA params
+			// before it generates the key.
+			//
+			AsymmetricCipherKeyPair dsaKp = dsaKpg.GenerateKeyPair();
+
+
+			IAsymmetricCipherKeyPairGenerator elgKpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL");
+
+			BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
+			BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
+
+			ElGamalParameters elParams = new ElGamalParameters(p, g);
+			ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(new SecureRandom(), elParams);
+			elgKpg.Init(elKgp);
+
+			//
+			// this is quicker because we are using preGenerated parameters.
+			//
+			AsymmetricCipherKeyPair elgKp = elgKpg.GenerateKeyPair();
+
+
+			PgpKeyPair dsaKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.Dsa, dsaKp, DateTime.UtcNow);
+			PgpKeyPair elgKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalEncrypt, elgKp, DateTime.UtcNow);
+
+			PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, dsaKeyPair,
+				"test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, true, null, null, new SecureRandom());
+
+			keyRingGen.AddSubKey(elgKeyPair);
+
+			PgpSecretKeyRing keyRing = keyRingGen.GenerateSecretKeyRing();
+
+			keyRing.GetSecretKey().ExtractPrivateKey(passPhrase);
+
+			PgpPublicKeyRing pubRing = keyRingGen.GeneratePublicKeyRing();
+
+			PgpPublicKey vKey = null;
+			PgpPublicKey sKey = null;
+
+			foreach (PgpPublicKey pk in pubRing.GetPublicKeys())
+			{
+				if (pk.IsMasterKey)
+				{
+					vKey = pk;
+				}
+				else
+				{
+					sKey = pk;
+				}
+			}
+
+			foreach (PgpSignature sig in sKey.GetSignatures())
+			{
+				if (sig.KeyId == vKey.KeyId
+					&& sig.SignatureType == PgpSignature.SubkeyBinding)
+				{
+					sig.InitVerify(vKey);
+
+					if (!sig.VerifyCertification(vKey, sKey))
+					{
+						Fail("failed to verify sub-key signature.");
+					}
+				}
+			}
+		}
+
+		[Test]
+		public void RewrapTest()
+		{
+			SecureRandom rand = new SecureRandom();
+
+			// Read the secret key rings
+			PgpSecretKeyRingBundle privRings = new PgpSecretKeyRingBundle(
+				new MemoryStream(rewrapKey, false));
+
+			foreach (PgpSecretKeyRing pgpPrivEnum in privRings.GetKeyRings())
+			{
+				foreach (PgpSecretKey pgpKeyEnum in pgpPrivEnum.GetSecretKeys())
+				{
+					// re-encrypt the key with an empty password
+					PgpSecretKeyRing pgpPriv = PgpSecretKeyRing.RemoveSecretKey(pgpPrivEnum, pgpKeyEnum);
+					PgpSecretKey pgpKey = PgpSecretKey.CopyWithNewPassword(
+						pgpKeyEnum,
+						rewrapPass,
+						null,
+						SymmetricKeyAlgorithmTag.Null,
+						rand);
+					pgpPriv = PgpSecretKeyRing.InsertSecretKey(pgpPriv, pgpKey);
+
+					// this should succeed
+					PgpPrivateKey privTmp = pgpKey.ExtractPrivateKey(null);
+				}
+			}
+		}
+
+		[Test]
+		public void PublicKeyRingWithX509Test()
+		{
+			checkPublicKeyRingWithX509(pubWithX509);
+
+			PgpPublicKeyRing pubRing = new PgpPublicKeyRing(pubWithX509);
+
+			checkPublicKeyRingWithX509(pubRing.GetEncoded());
+		}
+
+		[Test]
+		public void SecretKeyRingWithPersonalCertificateTest()
+		{
+			checkSecretKeyRingWithPersonalCertificate(secWithPersonalCertificate);
+			PgpSecretKeyRingBundle secRing = new PgpSecretKeyRingBundle(secWithPersonalCertificate);
+			checkSecretKeyRingWithPersonalCertificate(secRing.GetEncoded());
+		}
+
+		private void checkSecretKeyRingWithPersonalCertificate(
+			byte[] keyRing)
+		{
+			PgpSecretKeyRingBundle secCol = new PgpSecretKeyRingBundle(keyRing);
+
+			int count = 0;
+
+			foreach (PgpSecretKeyRing ring in secCol.GetKeyRings())
+			{
+				IEnumerator e = ring.GetExtraPublicKeys().GetEnumerator();
+				while (e.MoveNext())
+				{
+					++count;
+				}
+			}
+
+			if (count != 1)
+			{
+				Fail("personal certificate data subkey not found - count = " + count);
+			}
+		}
+
+		private void checkPublicKeyRingWithX509(
+			byte[] keyRing)
+		{
+			PgpPublicKeyRing pubRing = new PgpPublicKeyRing(keyRing);
+			IEnumerator en = pubRing.GetPublicKeys().GetEnumerator();
+
+			if (en.MoveNext())
+			{
+				PgpPublicKey key = (PgpPublicKey) en.Current;
+
+				IEnumerator sEn = key.GetSignatures().GetEnumerator();
+
+				if (sEn.MoveNext())
+				{
+					PgpSignature sig = (PgpSignature) sEn.Current;
+					if (sig.KeyAlgorithm != PublicKeyAlgorithmTag.Experimental_1)
+					{
+						Fail("experimental signature not found");
+					}
+					if (!AreEqual(sig.GetSignature(), Hex.Decode("000101")))
+					{
+						Fail("experimental encoding check failed");
+					}
+				}
+				else
+				{
+					Fail("no signature found");
+				}
+			}
+			else
+			{
+				Fail("no key found");
+			}
+		}
+
+		public override void PerformTest()
+		{
+			PerformTest1();
+			PerformTest2();
+			PerformTest3();
+			PerformTest4();
+			PerformTest5();
+			PerformTest6();
+
+			// NB: This was commented out in the original Java source
+			//PerformTest7();
+
+			PerformTest8();
+			PerformTest9();
+			PerformTest10();
+			PerformTest11();
+
+			GenerateTest();
+			GenerateSha1Test();
+			RewrapTest();
+			PublicKeyRingWithX509Test();
+			SecretKeyRingWithPersonalCertificateTest();
+			InsertMasterTest();
+		}
+
+		public override string Name
+		{
+			get { return "PgpKeyRingTest"; }
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new PgpKeyRingTest());
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/test/PgpMarkerTest.cs b/crypto/test/src/openpgp/test/PgpMarkerTest.cs
new file mode 100644
index 000000000..89be7cd52
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PgpMarkerTest.cs
@@ -0,0 +1,102 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    [TestFixture]
+    public class PgpMarkerTest
+        : SimpleTest
+    {
+        private static readonly byte[] message1 = Base64.Decode(
+            "qANQR1DBwU4DdrlXatQSHgoQCADWlhY3bWWaOTm4t2espRWPFQmETeinnieHce64"
+            + "lmEIFzaryEWeSdQc8XGfDzcb7sxq7b5b9Hm6OrACcCbSp2KGEJNG5kJmo2A16UPq"
+            + "JdK4xNelpJRh3KcJPv+N/9VJrMdj4C+DRnGNFg1hTQf3RKsX+ms2V0OBC5vGlOZY"
+            + "zX+XZz/7hl1PXVLN23u4npZI/1xETI2VtRoM76S6oykGXxMtT3+sGU1fAVEKVS45"
+            + "pyQHWbBqApkWrURq0xBqpVfDwOgGw09dJxt2igW9hjvNAd9tJiMGrMF5o2OLlub7"
+            + "c7FiK+dWLLcw+nx7Hl6FQmo9E8qyW8x1Cb78HjR/JXMgH/ngB/4gba6xX+s5TJkW"
+            + "H2Wpp5ePTw39EqHosUMrm05R+C0ha3EyyaJIvKj2WWmImKu5PWo1t37Pi6KHFNC3"
+            + "wsYJMRKnnNtd34luMTOgLpDcdgClzfp2p6EqHMoB7Uj3etlLmbN+vpGgz9qkLBRV"
+            + "7MpR1yE9qrZNeGgbkry6N31w5E7HoAHu5JNcwxgzbJoj2lI8uvs6Gf7fEoQOuAPE"
+            + "W/SGlfR2BdBPiJ1yErMElc2O8LVS0wTwwifHpEsMV+1ntl1EC5d052lo+6q7zNqD"
+            + "uYt1/2if6h9W9fe+S9mzr0ZAtxIN2ZGOFJJRnqzjDQ4siB9nnwr6YgvUVRSr/lQB"
+            + "hDTd0bmjyWacCt0PPMJWchO6A5tzqKUpTWSYibpdks80kLQogQHsJTZd/kpS0I6f"
+            + "gD0HYYlMssZwhg2J2TWwXDpDTgQ6mzFKbGSdOSk/deTJj2+EubzxaZcxZEocCJA8"
+            + "bppCj4kLBnCj1LjYx7A=");
+
+        private static readonly byte[] message2 = Base64.Decode(
+            "qANQR1DBwU4DZlTzKj+E4aMQCADruFAojUIlHGcnswLIekvhbVnaHnbCt6Kp"
+            + "IL2zppmEIYJ9n1xCO1k+3Y5j9vNATbqCVWs1HD0aAL3PRI1eZ1l8GkIBCd2z"
+            + "tcZpSI/uyI/JCzVW2stCH0gpP2V7zcjk8HaIuBz4ZsyU9m7v6LwCDPB4CTrb"
+            + "Z5nn5Jm3eowonQsRL/3TpJtG+IjTaw29NbCBNNX8quM5LwfIsfWovqNv28r1"
+            + "aX8FsqoTRsWEfQ7dMV/swVGqv0PgKxqErdnZVJ2yOJqjLk+lBJT6zhqPijGV"
+            + "10pc68hdZxxLU1KZq25DAjS12xcAgagjRkOmYE/H1oEjGZlXfS4y/xQ7skHa"
+            + "HI+b04vECACTpQPwCXhxYiNWnf4XhJPONIGyrsXVtsTNwzOShFPmeUvpipP4"
+            + "HknakBkBuUY49xcffQogW/NlGCZnQOulDLE6fCH/krkSmI8WVP5Vhf6bM1Qm"
+            + "92dHZFoTrrcQ9NVGaCNHHWf7KXkNfKdTkE23LdggoVrVAzO4WcdqVc6s/or7"
+            + "jQYP9zXLeu8+GGFMxe/9FCtoIWbujGQHsdDEkCK4h+D44EVDPzbvWj39ZB4w"
+            + "hHoab8RLHd7njcrPeoCPdYkFVCKOSuLdxxYZDbbmgpISaafrafwefkkESeGu"
+            + "JzbNhmyS8zfOiejWzndaLYWUSE/sqISK9Pg+xKundnFPk04+AhIRyYEoUjG3"
+            + "LgGVyM49mrM8E7QwAGU0m/VCJLoOu+N74Z1rp1wFdA5yCllFlONNM4Czhd1D"
+            + "ZMyLFqGXiKlyVCPlUTN2uVisYQGr6iNGYSPxpKjwiAzdeeQBPOETG0vd3nTO"
+            + "MN4BMKcG+kRJd5FU72SRfmbGwPPjd1gts9xFvtj4Tvpkam8=");
+
+		public override void PerformTest()
+        {
+            //
+            // test encrypted message
+            //
+            PgpObjectFactory pgpFact = new PgpObjectFactory(message1);
+
+            if (pgpFact.NextPgpObject() is PgpMarker)
+            {
+                if (pgpFact.NextPgpObject() is PgpEncryptedDataList)
+                {
+                    return;
+                }
+                else
+                {
+                    Fail("error processing after marker.");
+                }
+            }
+
+			// TODO Does this even get called?
+			pgpFact = new PgpObjectFactory(message2);
+
+            if (pgpFact.NextPgpObject() is PgpMarker)
+            {
+                if (!(pgpFact.NextPgpObject() is PgpEncryptedDataList))
+                {
+                    return;
+                }
+                else
+                {
+                    Fail("error processing after marker.");
+                }
+            }
+        }
+
+		public override string Name
+        {
+			get { return "PgpMarkerTest"; }
+        }
+
+		public static void Main(
+            string[] args)
+        {
+            RunTest(new PgpMarkerTest());
+        }
+
+		[Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/RegressionTest.cs b/crypto/test/src/openpgp/test/RegressionTest.cs
new file mode 100644
index 000000000..d74c5d483
--- /dev/null
+++ b/crypto/test/src/openpgp/test/RegressionTest.cs
@@ -0,0 +1,34 @@
+using System;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    public class RegressionTest
+    {
+        public static ITest[] tests =
+		{
+            new PgpKeyRingTest(),
+            new PgpRsaTest(),
+            new PgpDsaTest(),
+            new PgpDsaElGamalTest(),
+            new PgpPbeTest(),
+            new PgpMarkerTest(),
+            new PgpPacketTest(),
+			new PgpArmoredTest(),
+			new PgpSignatureTest(),
+			new PgpClearSignedSignatureTest(),
+            new PgpCompressionTest()
+        };
+
+		public static void Main(
+			string[] args)
+        {
+			foreach (ITest test in tests)
+			{
+				ITestResult result = test.Perform();
+                Console.WriteLine(result);
+            }
+        }
+    }
+}