summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Stedfast <jeff@xamarin.com>2015-10-19 10:45:20 -0400
committerJeffrey Stedfast <jeff@xamarin.com>2015-10-19 10:45:20 -0400
commit9bb283017763ea21484dd7ece2a9b6f32e926ede (patch)
tree6ef7d0f0e1c7d1e565bbd9e92aafdff786a56835
parentUpdated Visual Studio 2010 project files (diff)
parentSigOutputStream removed from the other-platform path too. (diff)
downloadBouncyCastle.NET-ed25519-9bb283017763ea21484dd7ece2a9b6f32e926ede.tar.xz
Merge branch 'master' into vs2010
-rw-r--r--crypto/NBuild.build2
-rw-r--r--crypto/src/AssemblyInfo.cs2
-rw-r--r--crypto/src/asn1/Asn1Exception.cs2
-rw-r--r--crypto/src/asn1/Asn1ParsingException.cs2
-rw-r--r--crypto/src/asn1/DerGeneralizedTime.cs2
-rw-r--r--crypto/src/asn1/DerUTCTime.cs4
-rw-r--r--crypto/src/asn1/cms/AttributeTable.cs4
-rw-r--r--crypto/src/asn1/cms/Time.cs17
-rw-r--r--crypto/src/asn1/smime/SMIMECapabilities.cs2
-rw-r--r--crypto/src/asn1/util/Dump.cs4
-rw-r--r--crypto/src/asn1/x509/AttributeTable.cs4
-rw-r--r--crypto/src/asn1/x509/ExtendedKeyUsage.cs4
-rw-r--r--crypto/src/asn1/x509/NameConstraints.cs2
-rw-r--r--crypto/src/asn1/x509/PolicyMappings.cs2
-rw-r--r--crypto/src/asn1/x509/SubjectDirectoryAttributes.cs2
-rw-r--r--crypto/src/asn1/x509/Time.cs18
-rw-r--r--crypto/src/asn1/x509/X509Extensions.cs2
-rw-r--r--crypto/src/asn1/x509/X509Name.cs6
-rw-r--r--crypto/src/bcpg/ArmoredOutputStream.cs12
-rw-r--r--crypto/src/cms/CMSAttributeTableGenerationException.cs2
-rw-r--r--crypto/src/cms/CMSException.cs2
-rw-r--r--crypto/src/cms/CMSProcessableByteArray.cs10
-rw-r--r--crypto/src/cms/CMSProcessableFile.cs21
-rw-r--r--crypto/src/cms/CMSProcessableInputStream.cs22
-rw-r--r--crypto/src/cms/CMSReadable.cs2
-rw-r--r--crypto/src/cms/CMSSignedDataGenerator.cs4
-rw-r--r--crypto/src/cms/CMSStreamException.cs2
-rw-r--r--crypto/src/cms/CMSTypedStream.cs2
-rw-r--r--crypto/src/cms/DefaultSignedAttributeTableGenerator.cs2
-rw-r--r--crypto/src/crypto/CryptoException.cs2
-rw-r--r--crypto/src/crypto/DataLengthException.cs2
-rw-r--r--crypto/src/crypto/InvalidCipherTextException.cs2
-rw-r--r--crypto/src/crypto/MaxBytesExceededException.cs2
-rw-r--r--crypto/src/crypto/OutputLengthException.cs2
-rw-r--r--crypto/src/crypto/PbeParametersGenerator.cs4
-rw-r--r--crypto/src/crypto/engines/NaccacheSternEngine.cs84
-rw-r--r--crypto/src/crypto/generators/NaccacheSternKeyPairGenerator.cs77
-rw-r--r--crypto/src/crypto/modes/CcmBlockCipher.cs20
-rw-r--r--crypto/src/crypto/modes/SicBlockCipher.cs51
-rw-r--r--crypto/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs49
-rw-r--r--crypto/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs4
-rw-r--r--crypto/src/crypto/parameters/SkeinParameters.cs3
-rw-r--r--crypto/src/crypto/prng/CryptoApiRandomGenerator.cs2
-rw-r--r--crypto/src/crypto/prng/ThreadedSeedGenerator.cs8
-rw-r--r--crypto/src/math/BigInteger.cs10
-rw-r--r--crypto/src/math/ec/ECCurve.cs3
-rw-r--r--crypto/src/math/ec/ECFieldElement.cs3
-rw-r--r--crypto/src/math/raw/Mod.cs6
-rw-r--r--crypto/src/ocsp/BasicOCSPRespGenerator.cs73
-rw-r--r--crypto/src/ocsp/OCSPException.cs2
-rw-r--r--crypto/src/openpgp/PgpDataValidationException.cs2
-rw-r--r--crypto/src/openpgp/PgpEncryptedDataGenerator.cs5
-rw-r--r--crypto/src/openpgp/PgpException.cs2
-rw-r--r--crypto/src/openpgp/PgpKeyValidationException.cs2
-rw-r--r--crypto/src/openpgp/PgpLiteralDataGenerator.cs2
-rw-r--r--crypto/src/openpgp/PgpSecretKey.cs112
-rw-r--r--crypto/src/openpgp/PgpUtilities.cs15
-rw-r--r--crypto/src/openssl/EncryptionException.cs2
-rw-r--r--crypto/src/openssl/PEMException.cs2
-rw-r--r--crypto/src/openssl/PasswordException.cs2
-rw-r--r--crypto/src/pkcs/AsymmetricKeyEntry.cs2
-rw-r--r--crypto/src/pkcs/X509CertificateEntry.cs2
-rw-r--r--crypto/src/pkix/PkixCertPath.cs4
-rw-r--r--crypto/src/pkix/PkixCertPathBuilderException.cs2
-rw-r--r--crypto/src/pkix/PkixCertPathValidatorException.cs2
-rw-r--r--crypto/src/pkix/PkixNameConstraintValidator.cs7
-rw-r--r--crypto/src/pkix/PkixNameConstraintValidatorException.cs2
-rw-r--r--crypto/src/security/DotNetUtilities.cs2
-rw-r--r--crypto/src/security/GeneralSecurityException.cs2
-rw-r--r--crypto/src/security/InvalidKeyException.cs2
-rw-r--r--crypto/src/security/InvalidParameterException.cs2
-rw-r--r--crypto/src/security/KeyException.cs2
-rw-r--r--crypto/src/security/MacUtilities.cs8
-rw-r--r--crypto/src/security/NoSuchAlgorithmException.cs2
-rw-r--r--crypto/src/security/SecureRandom.cs2
-rw-r--r--crypto/src/security/SecurityUtilityException.cs2
-rw-r--r--crypto/src/security/SignatureException.cs2
-rw-r--r--crypto/src/security/cert/CertificateEncodingException.cs2
-rw-r--r--crypto/src/security/cert/CertificateException.cs2
-rw-r--r--crypto/src/security/cert/CertificateExpiredException.cs2
-rw-r--r--crypto/src/security/cert/CertificateNotYetValidException.cs2
-rw-r--r--crypto/src/security/cert/CertificateParsingException.cs2
-rw-r--r--crypto/src/security/cert/CrlException.cs2
-rw-r--r--crypto/src/tsp/TSPException.cs2
-rw-r--r--crypto/src/tsp/TSPValidationException.cs2
-rw-r--r--crypto/src/util/Enums.cs4
-rw-r--r--crypto/src/util/Platform.cs16
-rw-r--r--crypto/src/util/Strings.cs6
-rw-r--r--crypto/src/util/io/StreamOverflowException.cs2
-rw-r--r--crypto/src/util/io/pem/PemGenerationException.cs2
-rw-r--r--crypto/src/x509/X509Certificate.cs2
-rw-r--r--crypto/src/x509/X509Crl.cs2
-rw-r--r--crypto/src/x509/store/IX509Selector.cs4
-rw-r--r--crypto/src/x509/store/NoSuchStoreException.cs2
-rw-r--r--crypto/src/x509/store/X509StoreException.cs2
-rw-r--r--crypto/test/src/asn1/test/CertificateTest.cs2
-rw-r--r--crypto/test/src/crypto/test/GOST3411DigestTest.cs22
-rw-r--r--crypto/test/src/openpgp/examples/test/AllTests.cs4
-rw-r--r--crypto/test/src/openpgp/test/PgpKeyRingTest.cs170
-rw-r--r--crypto/test/src/test/BlockCipherTest.cs1
-rw-r--r--crypto/test/src/util/test/TestFailedException.cs2
101 files changed, 587 insertions, 436 deletions
diff --git a/crypto/NBuild.build b/crypto/NBuild.build
index 64ea07545..8d2c027b1 100644
--- a/crypto/NBuild.build
+++ b/crypto/NBuild.build
@@ -16,7 +16,7 @@
   <property name="dist-path" value="./dist"/>
 
   <!-- Version -->
-  <property name="version" value="1.8.0-RC.1"/>
+  <property name="version" value="1.8.0-RC.2"/>
   <property name="name" value="BouncyCastle.Crypto"/>
 
   <property name="OPTIONAL_STRONG_NAME" value="" />
diff --git a/crypto/src/AssemblyInfo.cs b/crypto/src/AssemblyInfo.cs
index caabbc55c..ce2ff713c 100644
--- a/crypto/src/AssemblyInfo.cs
+++ b/crypto/src/AssemblyInfo.cs
@@ -32,7 +32,9 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyVersion("1.8.*")]
 
 [assembly: CLSCompliant(true)]
+#if !PORTABLE
 [assembly: ComVisible(false)]
+#endif
 
 // Start with no permissions
 //[assembly: PermissionSet(SecurityAction.RequestOptional, Unrestricted=false)]
diff --git a/crypto/src/asn1/Asn1Exception.cs b/crypto/src/asn1/Asn1Exception.cs
index 806cc95d5..1dfe1732c 100644
--- a/crypto/src/asn1/Asn1Exception.cs
+++ b/crypto/src/asn1/Asn1Exception.cs
@@ -3,7 +3,7 @@ using System.IO;
 
 namespace Org.BouncyCastle.Asn1
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class Asn1Exception
diff --git a/crypto/src/asn1/Asn1ParsingException.cs b/crypto/src/asn1/Asn1ParsingException.cs
index 40e5da480..84cdb780d 100644
--- a/crypto/src/asn1/Asn1ParsingException.cs
+++ b/crypto/src/asn1/Asn1ParsingException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Asn1
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class Asn1ParsingException
diff --git a/crypto/src/asn1/DerGeneralizedTime.cs b/crypto/src/asn1/DerGeneralizedTime.cs
index 548a268e1..6700b9016 100644
--- a/crypto/src/asn1/DerGeneralizedTime.cs
+++ b/crypto/src/asn1/DerGeneralizedTime.cs
@@ -159,7 +159,7 @@ namespace Org.BouncyCastle.Asn1
             char sign = '+';
             DateTime time = ToDateTime();
 
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
             long offset = time.Ticks - time.ToUniversalTime().Ticks;
             if (offset < 0)
             {
diff --git a/crypto/src/asn1/DerUTCTime.cs b/crypto/src/asn1/DerUTCTime.cs
index 56fabeb47..ab8ca792d 100644
--- a/crypto/src/asn1/DerUTCTime.cs
+++ b/crypto/src/asn1/DerUTCTime.cs
@@ -86,10 +86,10 @@ namespace Org.BouncyCastle.Asn1
         public DerUtcTime(
             DateTime time)
         {
-            this.time = time.ToString("yyMMddHHmmss") + "Z";
+            this.time = time.ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z";
         }
 
-		internal DerUtcTime(
+        internal DerUtcTime(
             byte[] bytes)
         {
             //
diff --git a/crypto/src/asn1/cms/AttributeTable.cs b/crypto/src/asn1/cms/AttributeTable.cs
index 8a3ee5d0e..8d357f1a6 100644
--- a/crypto/src/asn1/cms/AttributeTable.cs
+++ b/crypto/src/asn1/cms/AttributeTable.cs
@@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Asn1.Cms
     {
         private readonly IDictionary attributes;
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete]
         public AttributeTable(
             Hashtable attrs)
@@ -168,7 +168,7 @@ namespace Org.BouncyCastle.Asn1.Cms
             return Platform.CreateHashtable(attributes);
         }
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete("Use 'ToDictionary' instead")]
 		public Hashtable ToHashtable()
         {
diff --git a/crypto/src/asn1/cms/Time.cs b/crypto/src/asn1/cms/Time.cs
index d113bfa2e..e5730245e 100644
--- a/crypto/src/asn1/cms/Time.cs
+++ b/crypto/src/asn1/cms/Time.cs
@@ -1,8 +1,6 @@
 using System;
 using System.Globalization;
 
-using Org.BouncyCastle.Asn1;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class Time
@@ -20,13 +18,12 @@ namespace Org.BouncyCastle.Asn1.Cms
 		public Time(
             Asn1Object time)
         {
-            if (!(time is DerUtcTime)
-                && !(time is DerGeneralizedTime))
-            {
+            if (time == null)
+                throw new ArgumentNullException("time");
+            if (!(time is DerUtcTime) && !(time is DerGeneralizedTime))
                 throw new ArgumentException("unknown object passed to Time");
-            }
 
-			this.time = time;
+            this.time = time;
         }
 
 		/**
@@ -37,7 +34,7 @@ namespace Org.BouncyCastle.Asn1.Cms
         public Time(
             DateTime date)
         {
-            string d = date.ToString("yyyyMMddHHmmss") + "Z";
+            string d = date.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + "Z";
 
 			int year = int.Parse(d.Substring(0, 4));
 
@@ -56,14 +53,12 @@ namespace Org.BouncyCastle.Asn1.Cms
         {
             if (obj == null || obj is Time)
                 return (Time)obj;
-
 			if (obj is DerUtcTime)
                 return new Time((DerUtcTime)obj);
-
 			if (obj is DerGeneralizedTime)
                 return new Time((DerGeneralizedTime)obj);
 
-			throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
+            throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
         }
 
 		public string TimeString
diff --git a/crypto/src/asn1/smime/SMIMECapabilities.cs b/crypto/src/asn1/smime/SMIMECapabilities.cs
index 5fb67dde1..6435caf68 100644
--- a/crypto/src/asn1/smime/SMIMECapabilities.cs
+++ b/crypto/src/asn1/smime/SMIMECapabilities.cs
@@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Asn1.Smime
             capabilities = seq;
         }
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete("Use 'GetCapabilitiesForOid' instead")]
         public ArrayList GetCapabilities(
             DerObjectIdentifier capability)
diff --git a/crypto/src/asn1/util/Dump.cs b/crypto/src/asn1/util/Dump.cs
index 27c87f127..99ced5836 100644
--- a/crypto/src/asn1/util/Dump.cs
+++ b/crypto/src/asn1/util/Dump.cs
@@ -1,5 +1,4 @@
-using Org.BouncyCastle.Asn1;
-
+#if !PORTABLE
 using System;
 using System.IO;
 
@@ -26,3 +25,4 @@ namespace Org.BouncyCastle.Asn1.Utilities
         }
     }
 }
+#endif
diff --git a/crypto/src/asn1/x509/AttributeTable.cs b/crypto/src/asn1/x509/AttributeTable.cs
index ffe0ea935..33faad64a 100644
--- a/crypto/src/asn1/x509/AttributeTable.cs
+++ b/crypto/src/asn1/x509/AttributeTable.cs
@@ -16,7 +16,7 @@ namespace Org.BouncyCastle.Asn1.X509
             this.attributes = Platform.CreateHashtable(attrs);
         }
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete]
         public AttributeTable(
             Hashtable attrs)
@@ -57,7 +57,7 @@ namespace Org.BouncyCastle.Asn1.X509
             return (AttributeX509) attributes[oid];
         }
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete("Use 'ToDictionary' instead")]
 		public Hashtable ToHashtable()
         {
diff --git a/crypto/src/asn1/x509/ExtendedKeyUsage.cs b/crypto/src/asn1/x509/ExtendedKeyUsage.cs
index a5b11f210..9b1400db9 100644
--- a/crypto/src/asn1/x509/ExtendedKeyUsage.cs
+++ b/crypto/src/asn1/x509/ExtendedKeyUsage.cs
@@ -70,7 +70,7 @@ namespace Org.BouncyCastle.Asn1.X509
             }
         }
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete]
         public ExtendedKeyUsage(
             ArrayList usages)
@@ -101,7 +101,7 @@ namespace Org.BouncyCastle.Asn1.X509
             return usageTable.Contains(keyPurposeId);
         }
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete("Use 'GetAllUsages'")]
         public ArrayList GetUsages()
         {
diff --git a/crypto/src/asn1/x509/NameConstraints.cs b/crypto/src/asn1/x509/NameConstraints.cs
index 8374ff60a..c178f5b45 100644
--- a/crypto/src/asn1/x509/NameConstraints.cs
+++ b/crypto/src/asn1/x509/NameConstraints.cs
@@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Asn1.X509
 			}
 		}
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         public NameConstraints(
             ArrayList permitted,
             ArrayList excluded)
diff --git a/crypto/src/asn1/x509/PolicyMappings.cs b/crypto/src/asn1/x509/PolicyMappings.cs
index 3ad351107..928ad134d 100644
--- a/crypto/src/asn1/x509/PolicyMappings.cs
+++ b/crypto/src/asn1/x509/PolicyMappings.cs
@@ -29,7 +29,7 @@ namespace Org.BouncyCastle.Asn1.X509
 			this.seq = seq;
 		}
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         public PolicyMappings(
             Hashtable mappings)
             : this((IDictionary)mappings)
diff --git a/crypto/src/asn1/x509/SubjectDirectoryAttributes.cs b/crypto/src/asn1/x509/SubjectDirectoryAttributes.cs
index fcb30290d..c76d94d78 100644
--- a/crypto/src/asn1/x509/SubjectDirectoryAttributes.cs
+++ b/crypto/src/asn1/x509/SubjectDirectoryAttributes.cs
@@ -78,7 +78,7 @@ namespace Org.BouncyCastle.Asn1.X509
 			}
 		}
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete]
         public SubjectDirectoryAttributes(
             ArrayList attributes)
diff --git a/crypto/src/asn1/x509/Time.cs b/crypto/src/asn1/x509/Time.cs
index 0f2511e6d..8350339bb 100644
--- a/crypto/src/asn1/x509/Time.cs
+++ b/crypto/src/asn1/x509/Time.cs
@@ -1,11 +1,12 @@
 using System;
+using System.Globalization;
 
 namespace Org.BouncyCastle.Asn1.X509
 {
     public class Time
         : Asn1Encodable, IAsn1Choice
     {
-        internal Asn1Object time;
+        private readonly Asn1Object time;
 
         public static Time GetInstance(
             Asn1TaggedObject	obj,
@@ -19,11 +20,8 @@ namespace Org.BouncyCastle.Asn1.X509
         {
             if (time == null)
                 throw new ArgumentNullException("time");
-
             if (!(time is DerUtcTime) && !(time is DerGeneralizedTime))
-            {
                 throw new ArgumentException("unknown object passed to Time");
-            }
 
             this.time = time;
         }
@@ -36,9 +34,9 @@ namespace Org.BouncyCastle.Asn1.X509
         public Time(
             DateTime date)
         {
-            string d = date.ToString("yyyyMMddHHmmss") + "Z";
+            string d = date.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + "Z";
 
-            int year = Int32.Parse(d.Substring(0, 4));
+            int year = int.Parse(d.Substring(0, 4));
 
             if (year < 1950 || year > 2049)
             {
@@ -54,13 +52,11 @@ namespace Org.BouncyCastle.Asn1.X509
             object obj)
         {
             if (obj == null || obj is Time)
-                return (Time) obj;
-
+                return (Time)obj;
             if (obj is DerUtcTime)
-                return new Time((DerUtcTime) obj);
-
+                return new Time((DerUtcTime)obj);
             if (obj is DerGeneralizedTime)
-                return new Time((DerGeneralizedTime) obj);
+                return new Time((DerGeneralizedTime)obj);
 
             throw new ArgumentException("unknown object in factory: " + obj.GetType().Name, "obj");
         }
diff --git a/crypto/src/asn1/x509/X509Extensions.cs b/crypto/src/asn1/x509/X509Extensions.cs
index 5dce5622d..1896450f5 100644
--- a/crypto/src/asn1/x509/X509Extensions.cs
+++ b/crypto/src/asn1/x509/X509Extensions.cs
@@ -278,7 +278,7 @@ namespace Org.BouncyCastle.Asn1.X509
             }
         }
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
 		/**
          * constructor from a table of extensions.
          * <p>
diff --git a/crypto/src/asn1/x509/X509Name.cs b/crypto/src/asn1/x509/X509Name.cs
index c183e5798..fb404a3ec 100644
--- a/crypto/src/asn1/x509/X509Name.cs
+++ b/crypto/src/asn1/x509/X509Name.cs
@@ -3,7 +3,7 @@ using System.Collections;
 using System.IO;
 using System.Text;
 
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
 using System.Collections.Generic;
 #endif
 
@@ -203,7 +203,7 @@ namespace Org.BouncyCastle.Asn1.X509
 
         private static readonly bool[] defaultReverse = { false };
 
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
         /**
         * default look up table translating OID values into their common symbols following
         * the convention in RFC 2253 with a few extras
@@ -1027,7 +1027,7 @@ namespace Org.BouncyCastle.Asn1.X509
             bool		reverse,
             IDictionary oidSymbols)
         {
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
             List<object> components = new List<object>();
 #else
             ArrayList components = new ArrayList();
diff --git a/crypto/src/bcpg/ArmoredOutputStream.cs b/crypto/src/bcpg/ArmoredOutputStream.cs
index 5d4b6b5a7..fb1f6eb29 100644
--- a/crypto/src/bcpg/ArmoredOutputStream.cs
+++ b/crypto/src/bcpg/ArmoredOutputStream.cs
@@ -5,6 +5,10 @@ using System.IO;
 using System.Reflection;
 using System.Text;
 
+#if PORTABLE
+using System.Linq;
+#endif
+
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.IO;
 
@@ -98,7 +102,15 @@ namespace Org.BouncyCastle.Bcpg
         private static readonly string    footerTail = "-----";
 
         private static readonly string version = "BCPG C# v"
+#if PORTABLE
+            + Assembly.GetExecutingAssembly()
+                .GetCustomAttributes(typeof(AssemblyVersionAttribute), true)
+                .Cast<AssemblyVersionAttribute>()
+                .First()
+                .Version;
+#else
             + Assembly.GetExecutingAssembly().GetName().Version;
+#endif
 
         private readonly IDictionary headers;
 
diff --git a/crypto/src/cms/CMSAttributeTableGenerationException.cs b/crypto/src/cms/CMSAttributeTableGenerationException.cs
index 31b06d6dd..87dad9929 100644
--- a/crypto/src/cms/CMSAttributeTableGenerationException.cs
+++ b/crypto/src/cms/CMSAttributeTableGenerationException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Cms
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CmsAttributeTableGenerationException
diff --git a/crypto/src/cms/CMSException.cs b/crypto/src/cms/CMSException.cs
index 5a6e33502..29fe0a6c0 100644
--- a/crypto/src/cms/CMSException.cs
+++ b/crypto/src/cms/CMSException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Cms
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CmsException
diff --git a/crypto/src/cms/CMSProcessableByteArray.cs b/crypto/src/cms/CMSProcessableByteArray.cs
index 4bee4f8bd..a6ab9b6a2 100644
--- a/crypto/src/cms/CMSProcessableByteArray.cs
+++ b/crypto/src/cms/CMSProcessableByteArray.cs
@@ -11,23 +11,23 @@ namespace Org.BouncyCastle.Cms
 	{
 		private readonly byte[] bytes;
 
-		public CmsProcessableByteArray(
-			byte[] bytes)
+        public CmsProcessableByteArray(byte[] bytes)
 		{
 			this.bytes = bytes;
 		}
 
-		public Stream GetInputStream()
+        public virtual Stream GetInputStream()
 		{
 			return new MemoryStream(bytes, false);
 		}
 
-		public virtual void Write(Stream zOut)
+        public virtual void Write(Stream zOut)
 		{
 			zOut.Write(bytes, 0, bytes.Length);
 		}
 
-		/// <returns>A clone of the byte array</returns>
+        /// <returns>A clone of the byte array</returns>
+        [Obsolete]
 		public virtual object GetContent()
 		{
 			return bytes.Clone();
diff --git a/crypto/src/cms/CMSProcessableFile.cs b/crypto/src/cms/CMSProcessableFile.cs
index cbc74f44b..764d138f0 100644
--- a/crypto/src/cms/CMSProcessableFile.cs
+++ b/crypto/src/cms/CMSProcessableFile.cs
@@ -1,3 +1,4 @@
+#if !PORTABLE
 using System;
 using System.IO;
 
@@ -13,38 +14,33 @@ namespace Org.BouncyCastle.Cms
 	{
 		private const int DefaultBufSize = 32 * 1024;
 
-		private readonly FileInfo	_file;
+        private readonly FileInfo	_file;
 		private readonly int		_bufSize;
 
-		public CmsProcessableFile(
-			FileInfo file)
+        public CmsProcessableFile(FileInfo file)
 			: this(file, DefaultBufSize)
 		{
 		}
 
-		public CmsProcessableFile(
-			FileInfo	file,
-			int			bufSize)
+        public CmsProcessableFile(FileInfo file, int bufSize)
 		{
 			_file = file;
 			_bufSize = bufSize;
 		}
 
-		public virtual Stream GetInputStream()
+        public virtual Stream GetInputStream()
 		{
-			return new FileStream(
-				_file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, _bufSize);
+			return new FileStream(_file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, _bufSize);
 		}
 
-		public virtual void Write(
-			Stream zOut)
+        public virtual void Write(Stream zOut)
 		{
 			Stream inStr = GetInputStream();
 			Streams.PipeAll(inStr, zOut);
 			inStr.Close();
 		}
 
-		/// <returns>The file handle</returns>
+        /// <returns>The file handle</returns>
 		[Obsolete]
 		public virtual object GetContent()
 		{
@@ -52,3 +48,4 @@ namespace Org.BouncyCastle.Cms
 		}
 	}
 }
+#endif
diff --git a/crypto/src/cms/CMSProcessableInputStream.cs b/crypto/src/cms/CMSProcessableInputStream.cs
index 7fdd1dfef..6dff7c212 100644
--- a/crypto/src/cms/CMSProcessableInputStream.cs
+++ b/crypto/src/cms/CMSProcessableInputStream.cs
@@ -8,23 +8,23 @@ namespace Org.BouncyCastle.Cms
 	public class CmsProcessableInputStream
 		: CmsProcessable, CmsReadable
 	{
-		private Stream input;
-		private bool used = false;
+		private readonly Stream input;
 
-		public CmsProcessableInputStream(
-			Stream input)
+        private bool used = false;
+
+        public CmsProcessableInputStream(Stream input)
 		{
 			this.input = input;
 		}
 
-		public Stream GetInputStream()
+        public virtual Stream GetInputStream()
 		{
 			CheckSingleUsage();
 
-			return input;
+            return input;
 		}
 
-		public void Write(Stream output)
+        public virtual void Write(Stream output)
 		{
 			CheckSingleUsage();
 
@@ -32,20 +32,20 @@ namespace Org.BouncyCastle.Cms
 			input.Close();
 		}
 
-		[Obsolete]
-		public object GetContent()
+        [Obsolete]
+		public virtual object GetContent()
 		{
 			return GetInputStream();
 		}
 
-		private void CheckSingleUsage()
+        protected virtual void CheckSingleUsage()
 		{
 			lock (this)
 			{
 				if (used)
 					throw new InvalidOperationException("CmsProcessableInputStream can only be used once");
 
-				used = true;
+                used = true;
 			}
 		}
 	}
diff --git a/crypto/src/cms/CMSReadable.cs b/crypto/src/cms/CMSReadable.cs
index 9507b920c..ad83ba068 100644
--- a/crypto/src/cms/CMSReadable.cs
+++ b/crypto/src/cms/CMSReadable.cs
@@ -3,7 +3,7 @@ using System.IO;
 
 namespace Org.BouncyCastle.Cms
 {
-	internal interface CmsReadable
+	public interface CmsReadable
 	{
 		Stream GetInputStream();
 	}
diff --git a/crypto/src/cms/CMSSignedDataGenerator.cs b/crypto/src/cms/CMSSignedDataGenerator.cs
index 201cfc5c4..e0caca9ff 100644
--- a/crypto/src/cms/CMSSignedDataGenerator.cs
+++ b/crypto/src/cms/CMSSignedDataGenerator.cs
@@ -136,8 +136,8 @@ namespace Org.BouncyCastle.Cms
 
                 IStreamCalculator calculator = sigCalc.CreateCalculator();
 
-#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT
-				Stream sigStr = new SigOutputStream(calculator.Stream);
+#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE
+				Stream sigStr = calculator.Stream;
 #else
 				Stream sigStr = new BufferedStream(calculator.Stream);
 #endif
diff --git a/crypto/src/cms/CMSStreamException.cs b/crypto/src/cms/CMSStreamException.cs
index bf0a6adf4..68a8be017 100644
--- a/crypto/src/cms/CMSStreamException.cs
+++ b/crypto/src/cms/CMSStreamException.cs
@@ -3,7 +3,7 @@ using System.IO;
 
 namespace Org.BouncyCastle.Cms
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CmsStreamException
diff --git a/crypto/src/cms/CMSTypedStream.cs b/crypto/src/cms/CMSTypedStream.cs
index d04846ee1..b7b390c4c 100644
--- a/crypto/src/cms/CMSTypedStream.cs
+++ b/crypto/src/cms/CMSTypedStream.cs
@@ -32,7 +32,7 @@ namespace Org.BouncyCastle.Cms
 			int		bufSize)
 		{
 			_oid = oid;
-#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT
+#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE
 			_in = new FullReaderStream(inStream);
 #else
 			_in = new FullReaderStream(new BufferedStream(inStream, bufSize));
diff --git a/crypto/src/cms/DefaultSignedAttributeTableGenerator.cs b/crypto/src/cms/DefaultSignedAttributeTableGenerator.cs
index 055de8957..925a98a3c 100644
--- a/crypto/src/cms/DefaultSignedAttributeTableGenerator.cs
+++ b/crypto/src/cms/DefaultSignedAttributeTableGenerator.cs
@@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Cms
 			}
 		}
 
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
 		/**
 		 * Create a standard attribute table from the passed in parameters - this will
 		 * normally include contentType, signingTime, and messageDigest. If the constructor
diff --git a/crypto/src/crypto/CryptoException.cs b/crypto/src/crypto/CryptoException.cs
index 67f0d86f2..73d450be1 100644
--- a/crypto/src/crypto/CryptoException.cs
+++ b/crypto/src/crypto/CryptoException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Crypto
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CryptoException
diff --git a/crypto/src/crypto/DataLengthException.cs b/crypto/src/crypto/DataLengthException.cs
index e9efc0bd3..447ff2a17 100644
--- a/crypto/src/crypto/DataLengthException.cs
+++ b/crypto/src/crypto/DataLengthException.cs
@@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Crypto
      * insufficient input. In general this exception will Get thrown rather
      * than an ArrayOutOfBounds exception.
      */
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class DataLengthException
diff --git a/crypto/src/crypto/InvalidCipherTextException.cs b/crypto/src/crypto/InvalidCipherTextException.cs
index 4d2252654..0fe540d96 100644
--- a/crypto/src/crypto/InvalidCipherTextException.cs
+++ b/crypto/src/crypto/InvalidCipherTextException.cs
@@ -6,7 +6,7 @@ namespace Org.BouncyCastle.Crypto
      * this exception is thrown whenever we find something we don't expect in a
      * message.
      */
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class InvalidCipherTextException
diff --git a/crypto/src/crypto/MaxBytesExceededException.cs b/crypto/src/crypto/MaxBytesExceededException.cs
index be078cb13..8992c45da 100644
--- a/crypto/src/crypto/MaxBytesExceededException.cs
+++ b/crypto/src/crypto/MaxBytesExceededException.cs
@@ -6,7 +6,7 @@ namespace Org.BouncyCastle.Crypto
 	/// This exception is thrown whenever a cipher requires a change of key, iv
 	/// or similar after x amount of bytes enciphered
 	/// </summary>
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class MaxBytesExceededException
diff --git a/crypto/src/crypto/OutputLengthException.cs b/crypto/src/crypto/OutputLengthException.cs
index e1cf44925..437589f47 100644
--- a/crypto/src/crypto/OutputLengthException.cs
+++ b/crypto/src/crypto/OutputLengthException.cs
@@ -2,7 +2,7 @@
 
 namespace Org.BouncyCastle.Crypto
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class OutputLengthException
diff --git a/crypto/src/crypto/PbeParametersGenerator.cs b/crypto/src/crypto/PbeParametersGenerator.cs
index 21679d45e..97d23df90 100644
--- a/crypto/src/crypto/PbeParametersGenerator.cs
+++ b/crypto/src/crypto/PbeParametersGenerator.cs
@@ -130,7 +130,7 @@ namespace Org.BouncyCastle.Crypto
             if (password == null)
                 return new byte[0];
 
-            return Strings.ToAsciiByteArray(password);
+            return Strings.ToByteArray(password);
         }
 
         [Obsolete("Use version taking 'char[]' instead")]
@@ -140,7 +140,7 @@ namespace Org.BouncyCastle.Crypto
             if (password == null)
                 return new byte[0];
 
-            return Strings.ToAsciiByteArray(password);
+            return Strings.ToByteArray(password);
         }
 
         /**
diff --git a/crypto/src/crypto/engines/NaccacheSternEngine.cs b/crypto/src/crypto/engines/NaccacheSternEngine.cs
index e547e0caf..64665c1d4 100644
--- a/crypto/src/crypto/engines/NaccacheSternEngine.cs
+++ b/crypto/src/crypto/engines/NaccacheSternEngine.cs
@@ -20,9 +20,7 @@ namespace Org.BouncyCastle.Crypto.Engines
 
 		private IList[] lookup = null;
 
-		private bool debug = false;
-
-		public string AlgorithmName
+        public string AlgorithmName
 		{
 			get { return "NaccacheStern"; }
 		}
@@ -49,10 +47,6 @@ namespace Org.BouncyCastle.Crypto.Engines
 			// construct lookup table for faster decryption if necessary
 			if (!this.forEncryption)
 			{
-				if (debug)
-				{
-					Console.WriteLine("Constructing lookup Array");
-				}
 				NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key;
 				IList primes = priv.SmallPrimesList;
 				lookup = new IList[primes.Count];
@@ -64,11 +58,6 @@ namespace Org.BouncyCastle.Crypto.Engines
 					lookup[i] = Platform.CreateArrayList(actualPrimeValue);
 					lookup[i].Add(BigInteger.One);
 
-					if (debug)
-					{
-						Console.WriteLine("Constructing lookup ArrayList for " + actualPrimeValue);
-					}
-
 					BigInteger accJ = BigInteger.Zero;
 
 					for (int j = 1; j < actualPrimeValue; j++)
@@ -83,12 +72,13 @@ namespace Org.BouncyCastle.Crypto.Engines
 			}
 		}
 
+        [Obsolete("Remove: no longer used")]
         public virtual bool Debug
 		{
-			set { this.debug = value; }
+			set {}
 		}
 
-		/**
+        /**
 		* Returns the input block size of this algorithm.
 		*
 		* @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetInputBlockSize()
@@ -156,11 +146,6 @@ namespace Org.BouncyCastle.Crypto.Engines
 			// transform input into BigInteger
 			BigInteger input = new BigInteger(1, inBytes, inOff, length);
 
-			if (debug)
-			{
-				Console.WriteLine("input as BigInteger: " + input);
-			}
-
 			byte[] output;
 			if (forEncryption)
 			{
@@ -178,10 +163,6 @@ namespace Org.BouncyCastle.Crypto.Engines
 					IList al = lookup[i];
 					if (lookup[i].Count != ((BigInteger)primes[i]).IntValue)
 					{
-						if (debug)
-						{
-							Console.WriteLine("Prime is " + primes[i] + ", lookup table has size " + al.Count);
-						}
 						throw new InvalidCipherTextException("Error in lookup Array for "
 										+ ((BigInteger)primes[i]).IntValue
 										+ ": Size mismatch. Expected ArrayList with length "
@@ -192,18 +173,6 @@ namespace Org.BouncyCastle.Crypto.Engines
 
 					if (lookedup == -1)
 					{
-						if (debug)
-						{
-							Console.WriteLine("Actual prime is " + primes[i]);
-							Console.WriteLine("Decrypted value is " + exp);
-
-							Console.WriteLine("LookupList for " + primes[i] + " with size " + lookup[i].Count
-											+ " is: ");
-							for (int j = 0; j < lookup[i].Count; j++)
-							{
-								Console.WriteLine(lookup[i][j]);
-							}
-						}
 						throw new InvalidCipherTextException("Lookup failed");
 					}
 					plain.Add(BigInteger.ValueOf(lookedup));
@@ -218,16 +187,9 @@ namespace Org.BouncyCastle.Crypto.Engines
 				// to guess them. But as stated in the paper, this is not a security
 				// breach. So we can just work with the correct sigma.
 
-				// if (debug) {
-				//      Console.WriteLine("Decryption is " + test);
-				// }
 				// if ((key.G.ModPow(test, key.Modulus)).Equals(input)) {
 				//      output = test.ToByteArray();
 				// } else {
-				//      if(debug){
-				//          Console.WriteLine("Engine seems to be used as an oracle,
-				//          returning null");
-				//      }
 				//      output = null;
 				// }
 
@@ -256,10 +218,6 @@ namespace Org.BouncyCastle.Crypto.Engines
 
 			byte[] tmp = key.G.ModPow(plain, key.Modulus).ToByteArray();
 			Array.Copy(tmp, 0, output, output.Length - tmp.Length, tmp.Length);
-			if (debug)
-			{
-				Console.WriteLine("Encrypted value is:  " + new BigInteger(output));
-			}
 			return output;
 		}
 
@@ -302,14 +260,8 @@ namespace Org.BouncyCastle.Crypto.Engines
 			BigInteger m2Crypt = new BigInteger(1, block2);
 			BigInteger m1m2Crypt = m1Crypt.Multiply(m2Crypt);
 			m1m2Crypt = m1m2Crypt.Mod(key.Modulus);
-			if (debug)
-			{
-				Console.WriteLine("c(m1) as BigInteger:....... " + m1Crypt);
-				Console.WriteLine("c(m2) as BigInteger:....... " + m2Crypt);
-				Console.WriteLine("c(m1)*c(m2)%n = c(m1+m2)%n: " + m1m2Crypt);
-			}
 
-			//byte[] output = key.Modulus.ToByteArray();
+            //byte[] output = key.Modulus.ToByteArray();
 			//Array.Clear(output, 0, output.Length);
 			byte[] output = new byte[key.Modulus.BitLength / 8 + 1];
 
@@ -332,20 +284,10 @@ namespace Org.BouncyCastle.Crypto.Engines
         public virtual byte[] ProcessData(
 			byte[] data)
 		{
-			if (debug)
-			{
-				Console.WriteLine();
-			}
 			if (data.Length > GetInputBlockSize())
 			{
 				int inBlocksize = GetInputBlockSize();
 				int outBlocksize = GetOutputBlockSize();
-				if (debug)
-				{
-					Console.WriteLine("Input blocksize is:  " + inBlocksize + " bytes");
-					Console.WriteLine("Output blocksize is: " + outBlocksize + " bytes");
-					Console.WriteLine("Data has length:.... " + data.Length + " bytes");
-				}
 				int datapos = 0;
 				int retpos = 0;
 				byte[] retval = new byte[(data.Length / inBlocksize + 1) * outBlocksize];
@@ -362,10 +304,6 @@ namespace Org.BouncyCastle.Crypto.Engines
 						tmp = ProcessBlock(data, datapos, data.Length - datapos);
 						datapos += data.Length - datapos;
 					}
-					if (debug)
-					{
-						Console.WriteLine("new datapos is " + datapos);
-					}
 					if (tmp != null)
 					{
 						tmp.CopyTo(retval, retpos);
@@ -373,27 +311,15 @@ namespace Org.BouncyCastle.Crypto.Engines
 					}
 					else
 					{
-						if (debug)
-						{
-							Console.WriteLine("cipher returned null");
-						}
 						throw new InvalidCipherTextException("cipher returned null");
 					}
 				}
 				byte[] ret = new byte[retpos];
 				Array.Copy(retval, 0, ret, 0, retpos);
-				if (debug)
-				{
-					Console.WriteLine("returning " + ret.Length + " bytes");
-				}
 				return ret;
 			}
 			else
 			{
-				if (debug)
-				{
-					Console.WriteLine("data size is less then input block size, processing directly");
-				}
 				return ProcessBlock(data, 0, data.Length);
 			}
 		}
diff --git a/crypto/src/crypto/generators/NaccacheSternKeyPairGenerator.cs b/crypto/src/crypto/generators/NaccacheSternKeyPairGenerator.cs
index 7011cf253..afc566d87 100644
--- a/crypto/src/crypto/generators/NaccacheSternKeyPairGenerator.cs
+++ b/crypto/src/crypto/generators/NaccacheSternKeyPairGenerator.cs
@@ -51,14 +51,8 @@ namespace Org.BouncyCastle.Crypto.Generators
 			int strength = param.Strength;
 			SecureRandom rand = param.Random;
 			int certainty = param.Certainty;
-			bool debug = param.IsDebug;
 
-			if (debug)
-			{
-				Console.WriteLine("Fetching first " + param.CountSmallPrimes + " primes.");
-			}
-
-			IList smallPrimes = findFirstPrimes(param.CountSmallPrimes);
+            IList smallPrimes = findFirstPrimes(param.CountSmallPrimes);
 
 			smallPrimes = permuteList(smallPrimes, rand);
 
@@ -92,12 +86,8 @@ namespace Org.BouncyCastle.Crypto.Generators
 			BigInteger q;
 
 			long tries = 0;
-			if (debug)
-			{
-				Console.WriteLine("generating p and q");
-			}
 
-			BigInteger _2au = a.Multiply(u).ShiftLeft(1);
+            BigInteger _2au = a.Multiply(u).ShiftLeft(1);
 			BigInteger _2bv = b.Multiply(v).ShiftLeft(1);
 
 			for (;;)
@@ -126,36 +116,23 @@ namespace Org.BouncyCastle.Crypto.Generators
 
 				if (!sigma.Gcd(_p.Multiply(_q)).Equals(BigInteger.One))
 				{
-					Console.WriteLine("sigma.gcd(_p.mult(_q)) != 1!\n _p: " + _p +"\n _q: "+ _q );
+                    //Console.WriteLine("sigma.gcd(_p.mult(_q)) != 1!\n _p: " + _p +"\n _q: "+ _q );
 					continue;
 				}
 
 				if (p.Multiply(q).BitLength < strength)
 				{
-					if (debug)
-					{
-						Console.WriteLine("key size too small. Should be " + strength + " but is actually "
-							+ p.Multiply(q).BitLength);
-					}
 					continue;
 				}
 				break;
 			}
 
-			if (debug)
-			{
-				Console.WriteLine("needed " + tries + " tries to generate p and q.");
-			}
-
 			BigInteger n = p.Multiply(q);
 			BigInteger phi_n = p.Subtract(BigInteger.One).Multiply(q.Subtract(BigInteger.One));
 			BigInteger g;
 			tries = 0;
-			if (debug)
-			{
-				Console.WriteLine("generating g");
-			}
-			for (;;)
+
+            for (;;)
 			{
 				// TODO After the first loop, just regenerate one randomly-selected gPart each time?
 				IList gParts = Platform.CreateArrayList();
@@ -191,10 +168,6 @@ namespace Org.BouncyCastle.Crypto.Generators
 				{
 					if (g.ModPow(phi_n.Divide((BigInteger)smallPrimes[i]), n).Equals(BigInteger.One))
 					{
-						if (debug)
-						{
-							Console.WriteLine("g has order phi(n)/" + smallPrimes[i] + "\n g: " + g);
-						}
 						divisible = true;
 						break;
 					}
@@ -210,67 +183,29 @@ namespace Org.BouncyCastle.Crypto.Generators
 				//if (g.ModPow(phi_n.Divide(BigInteger.ValueOf(4)), n).Equals(BigInteger.One))
 				if (g.ModPow(phi_n.ShiftRight(2), n).Equals(BigInteger.One))
 				{
-					if (debug)
-					{
-						Console.WriteLine("g has order phi(n)/4\n g:" + g);
-					}
 					continue;
 				}
 
 				if (g.ModPow(phi_n.Divide(_p), n).Equals(BigInteger.One))
 				{
-					if (debug)
-					{
-						Console.WriteLine("g has order phi(n)/p'\n g: " + g);
-					}
 					continue;
 				}
 				if (g.ModPow(phi_n.Divide(_q), n).Equals(BigInteger.One))
 				{
-					if (debug)
-					{
-						Console.WriteLine("g has order phi(n)/q'\n g: " + g);
-					}
 					continue;
 				}
 				if (g.ModPow(phi_n.Divide(a), n).Equals(BigInteger.One))
 				{
-					if (debug)
-					{
-						Console.WriteLine("g has order phi(n)/a\n g: " + g);
-					}
 					continue;
 				}
 				if (g.ModPow(phi_n.Divide(b), n).Equals(BigInteger.One))
 				{
-					if (debug)
-					{
-						Console.WriteLine("g has order phi(n)/b\n g: " + g);
-					}
 					continue;
 				}
 				break;
 			}
-			if (debug)
-			{
-				Console.WriteLine("needed " + tries + " tries to generate g");
-				Console.WriteLine();
-				Console.WriteLine("found new NaccacheStern cipher variables:");
-				Console.WriteLine("smallPrimes: " + CollectionUtilities.ToString(smallPrimes));
-				Console.WriteLine("sigma:...... " + sigma + " (" + sigma.BitLength + " bits)");
-				Console.WriteLine("a:.......... " + a);
-				Console.WriteLine("b:.......... " + b);
-				Console.WriteLine("p':......... " + _p);
-				Console.WriteLine("q':......... " + _q);
-				Console.WriteLine("p:.......... " + p);
-				Console.WriteLine("q:.......... " + q);
-				Console.WriteLine("n:.......... " + n);
-				Console.WriteLine("phi(n):..... " + phi_n);
-				Console.WriteLine("g:.......... " + g);
-				Console.WriteLine();
-			}
 
-			return new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, g, n, sigma.BitLength),
+            return new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, g, n, sigma.BitLength),
 				new NaccacheSternPrivateKeyParameters(g, n, sigma.BitLength, smallPrimes, phi_n));
 		}
 
diff --git a/crypto/src/crypto/modes/CcmBlockCipher.cs b/crypto/src/crypto/modes/CcmBlockCipher.cs
index 19e273d7c..4de40d58e 100644
--- a/crypto/src/crypto/modes/CcmBlockCipher.cs
+++ b/crypto/src/crypto/modes/CcmBlockCipher.cs
@@ -148,7 +148,15 @@ namespace Org.BouncyCastle.Crypto.Modes
             byte[]	outBytes,
             int		outOff)
         {
-            int len = ProcessPacket(data.GetBuffer(), 0, (int)data.Position, outBytes, outOff);
+#if PORTABLE
+            byte[] input = data.ToArray();
+            int inLen = input.Length;
+#else
+            byte[] input = data.GetBuffer();
+            int inLen = (int)data.Position;
+#endif
+
+            int len = ProcessPacket(input, 0, inLen, outBytes, outOff);
 
             Reset();
 
@@ -399,7 +407,15 @@ namespace Org.BouncyCastle.Crypto.Modes
                 }
                 if (associatedText.Position > 0)
                 {
-                    cMac.BlockUpdate(associatedText.GetBuffer(), 0, (int)associatedText.Position);
+#if PORTABLE
+                    byte[] input = associatedText.ToArray();
+                    int len = input.Length;
+#else
+                    byte[] input = associatedText.GetBuffer();
+                    int len = (int)associatedText.Position;
+#endif
+
+                    cMac.BlockUpdate(input, 0, len);
                 }
 
                 extra = (extra + textLength) % 16;
diff --git a/crypto/src/crypto/modes/SicBlockCipher.cs b/crypto/src/crypto/modes/SicBlockCipher.cs
index da7ed7859..239f99478 100644
--- a/crypto/src/crypto/modes/SicBlockCipher.cs
+++ b/crypto/src/crypto/modes/SicBlockCipher.cs
@@ -3,6 +3,8 @@ using System;
 using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Math;
 
+using Org.BouncyCastle.Utilities;
+
 namespace Org.BouncyCastle.Crypto.Modes
 {
     /**
@@ -14,9 +16,9 @@ namespace Org.BouncyCastle.Crypto.Modes
     {
         private readonly IBlockCipher cipher;
         private readonly int blockSize;
-        private readonly byte[] IV;
         private readonly byte[] counter;
         private readonly byte[] counterOut;
+        private byte[] IV;
 
         /**
         * Basic constructor.
@@ -27,9 +29,9 @@ namespace Org.BouncyCastle.Crypto.Modes
         {
             this.cipher = cipher;
             this.blockSize = cipher.GetBlockSize();
-            this.IV = new byte[blockSize];
             this.counter = new byte[blockSize];
             this.counterOut = new byte[blockSize];
+            this.IV = new byte[blockSize];
         }
 
         /**
@@ -37,51 +39,51 @@ namespace Org.BouncyCastle.Crypto.Modes
         *
         * @return the underlying block cipher that we are wrapping.
         */
-        public IBlockCipher GetUnderlyingCipher()
+        public virtual IBlockCipher GetUnderlyingCipher()
         {
             return cipher;
         }
 
-        public void Init(
+        public virtual void Init(
             bool				forEncryption, //ignored by this CTR mode
             ICipherParameters	parameters)
         {
-            if (parameters is ParametersWithIV)
-            {
-                ParametersWithIV ivParam = (ParametersWithIV) parameters;
-                byte[] iv = ivParam.GetIV();
-                Array.Copy(iv, 0, IV, 0, IV.Length);
+            ParametersWithIV ivParam = parameters as ParametersWithIV;
+            if (ivParam == null)
+                throw new ArgumentException("CTR/SIC mode requires ParametersWithIV", "parameters");
 
-                Reset();
+            this.IV = Arrays.Clone(ivParam.GetIV());
 
-                // if null it's an IV changed only.
-                if (ivParam.Parameters != null)
-                {
-                    cipher.Init(true, ivParam.Parameters);
-                }
-            }
-            else
+            if (blockSize < IV.Length)
+                throw new ArgumentException("CTR/SIC mode requires IV no greater than: " + blockSize + " bytes.");
+            if (blockSize - IV.Length > 8)
+                throw new ArgumentException("CTR/SIC mode requires IV of at least: " + (blockSize - 8) + " bytes.");
+
+            Reset();
+
+            // if null it's an IV changed only.
+            if (ivParam.Parameters != null)
             {
-                throw new ArgumentException("SIC mode requires ParametersWithIV", "parameters");
+                cipher.Init(true, ivParam.Parameters);
             }
         }
 
-        public string AlgorithmName
+        public virtual string AlgorithmName
         {
             get { return cipher.AlgorithmName + "/SIC"; }
         }
 
-        public bool IsPartialBlockOkay
+        public virtual bool IsPartialBlockOkay
         {
             get { return true; }
         }
 
-        public int GetBlockSize()
+        public virtual int GetBlockSize()
         {
             return cipher.GetBlockSize();
         }
 
-        public int ProcessBlock(
+        public virtual int ProcessBlock(
             byte[]	input,
             int		inOff,
             byte[]	output,
@@ -106,9 +108,10 @@ namespace Org.BouncyCastle.Crypto.Modes
             return counter.Length;
         }
 
-        public void Reset()
+        public virtual void Reset()
         {
-            Array.Copy(IV, 0, counter, 0, counter.Length);
+            Arrays.Fill(counter, (byte)0);
+            Array.Copy(IV, 0, counter, 0, IV.Length);
             cipher.Reset();
         }
     }
diff --git a/crypto/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs b/crypto/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs
index 5b4052505..44fc906b5 100644
--- a/crypto/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs
+++ b/crypto/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs
@@ -17,9 +17,8 @@ namespace Org.BouncyCastle.Crypto.Parameters
 		// private BigInteger publicExponent;
 		private readonly int certainty;
 		private readonly int countSmallPrimes;
-		private bool debug;
 
-		/**
+        /**
 		 * Parameters for generating a NaccacheStern KeyPair.
 		 *
 		 * @param random
@@ -37,9 +36,16 @@ namespace Org.BouncyCastle.Crypto.Parameters
 			int				strength,
 			int				certainty,
 			int				countSmallPrimes)
-			: this(random, strength, certainty, countSmallPrimes, false)
-		{
-		}
+            : base(random, strength)
+        {
+            if (countSmallPrimes % 2 == 1)
+                throw new ArgumentException("countSmallPrimes must be a multiple of 2");
+            if (countSmallPrimes < 30)
+                throw new ArgumentException("countSmallPrimes must be >= 30 for security reasons");
+
+            this.certainty = certainty;
+            this.countSmallPrimes = countSmallPrimes;
+        }
 
 		/**
 		 * Parameters for a NaccacheStern KeyPair.
@@ -54,27 +60,17 @@ namespace Org.BouncyCastle.Crypto.Parameters
 		 * @param cntSmallPrimes
 		 *            How many small key factors are desired
 		 * @param debug
-		 *            Turn debugging on or off (reveals secret information, use with
-		 *            caution)
+         *            Ignored
 		 */
-		public NaccacheSternKeyGenerationParameters(SecureRandom random,
-			int		strength,
-			int		certainty,
-			int		countSmallPrimes,
-			bool	debug)
-			: base(random, strength)
+        [Obsolete("Use version without 'debug' parameter")]
+		public NaccacheSternKeyGenerationParameters(
+            SecureRandom    random,
+			int             strength,
+			int             certainty,
+			int             countSmallPrimes,
+			bool            debug)
+			: this(random, strength, certainty, countSmallPrimes)
 		{
-			if (countSmallPrimes % 2 == 1)
-			{
-				throw new ArgumentException("countSmallPrimes must be a multiple of 2");
-			}
-			if (countSmallPrimes < 30)
-			{
-				throw new ArgumentException("countSmallPrimes must be >= 30 for security reasons");
-			}
-			this.certainty = certainty;
-			this.countSmallPrimes = countSmallPrimes;
-			this.debug = debug;
 		}
 
 		/**
@@ -93,9 +89,10 @@ namespace Org.BouncyCastle.Crypto.Parameters
 			get { return countSmallPrimes; }
 		}
 
-		public bool IsDebug
+        [Obsolete("Remove: always false")]
+        public bool IsDebug
 		{
-			get { return debug; }
+			get { return false; }
 		}
 	}
 }
diff --git a/crypto/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs b/crypto/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs
index 0e1fe14b7..42a0454a1 100644
--- a/crypto/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs
+++ b/crypto/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs
@@ -16,7 +16,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
 		private readonly BigInteger phiN;
 		private readonly IList smallPrimes;
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete]
         public NaccacheSternPrivateKeyParameters(
             BigInteger g,
@@ -63,7 +63,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
 			get { return phiN; }
 		}
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete("Use 'SmallPrimesList' instead")]
         public ArrayList SmallPrimes
 		{
diff --git a/crypto/src/crypto/parameters/SkeinParameters.cs b/crypto/src/crypto/parameters/SkeinParameters.cs
index a4e3e8e2a..9e621c09d 100644
--- a/crypto/src/crypto/parameters/SkeinParameters.cs
+++ b/crypto/src/crypto/parameters/SkeinParameters.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections;
+using System.Globalization;
 using System.IO;
 
 using Org.BouncyCastle.Utilities;
@@ -234,7 +235,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
 				{
 					MemoryStream bout = new MemoryStream();
 					StreamWriter outBytes = new StreamWriter(bout, System.Text.Encoding.UTF8);
-					outBytes.Write(date.ToString("YYYYMMDD"));
+					outBytes.Write(date.ToString("YYYYMMDD", CultureInfo.InvariantCulture));
 					outBytes.Write(" ");
 					outBytes.Write(emailAddress);
 					outBytes.Write(" ");
diff --git a/crypto/src/crypto/prng/CryptoApiRandomGenerator.cs b/crypto/src/crypto/prng/CryptoApiRandomGenerator.cs
index 521fae33e..fa5f523d3 100644
--- a/crypto/src/crypto/prng/CryptoApiRandomGenerator.cs
+++ b/crypto/src/crypto/prng/CryptoApiRandomGenerator.cs
@@ -1,4 +1,4 @@
-#if !NETCF_1_0
+#if !(NETCF_1_0 || PORTABLE)
 
 using System;
 using System.Security.Cryptography;
diff --git a/crypto/src/crypto/prng/ThreadedSeedGenerator.cs b/crypto/src/crypto/prng/ThreadedSeedGenerator.cs
index c29ad2c9a..f6a6b3c54 100644
--- a/crypto/src/crypto/prng/ThreadedSeedGenerator.cs
+++ b/crypto/src/crypto/prng/ThreadedSeedGenerator.cs
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Crypto.Prng
 				int		numBytes,
 				bool	fast)
 			{
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
                 return DoGenerateSeed(numBytes, fast);
 #else
                 ThreadPriority originalPriority = Thread.CurrentThread.Priority;
@@ -69,7 +69,11 @@ namespace Org.BouncyCastle.Crypto.Prng
 					{
 						try
 						{
-							Thread.Sleep(1);
+#if PORTABLE
+                            new AutoResetEvent(false).WaitOne(1);
+#else
+ 							Thread.Sleep(1);
+#endif
 						}
 						catch (Exception)
 						{
diff --git a/crypto/src/math/BigInteger.cs b/crypto/src/math/BigInteger.cs
index f302f077e..ebeb78788 100644
--- a/crypto/src/math/BigInteger.cs
+++ b/crypto/src/math/BigInteger.cs
@@ -4,11 +4,12 @@ using System.Diagnostics;
 using System.Globalization;
 using System.Text;
 
+using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Math
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class BigInteger
@@ -179,7 +180,7 @@ namespace Org.BouncyCastle.Math
         private const int chunk2 = 1, chunk8 = 1, chunk10 = 19, chunk16 = 16;
         private static readonly BigInteger radix2, radix2E, radix8, radix8E, radix10, radix10E, radix16, radix16E;
 
-        private static readonly Random RandomSource = new Random();
+        private static readonly SecureRandom RandomSource = new SecureRandom();
 
         /*
          * These are the threshold bit-lengths (of an exponent) where we increase the window size.
@@ -246,6 +247,11 @@ namespace Org.BouncyCastle.Math
             return (nBits + BitsPerByte - 1) / BitsPerByte;
         }
 
+        internal static BigInteger Arbitrary(int sizeInBits)
+        {
+            return new BigInteger(sizeInBits, RandomSource);
+        }
+
         private BigInteger(
             int		signum,
             int[]	mag,
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs
index 40b46ce72..fa2c72570 100644
--- a/crypto/src/math/ec/ECCurve.cs
+++ b/crypto/src/math/ec/ECCurve.cs
@@ -760,10 +760,9 @@ namespace Org.BouncyCastle.Math.EC
             ECFieldElement gamma, z, zeroElement = FromBigInteger(BigInteger.Zero);
 
             int m = FieldSize;
-            Random rand = new Random();
             do
             {
-                ECFieldElement t = FromBigInteger(new BigInteger(m, rand));
+                ECFieldElement t = FromBigInteger(BigInteger.Arbitrary(m));
                 z = zeroElement;
                 ECFieldElement w = beta;
                 for (int i = 1; i < m; i++)
diff --git a/crypto/src/math/ec/ECFieldElement.cs b/crypto/src/math/ec/ECFieldElement.cs
index 4d4fb3e4d..d0e008aab 100644
--- a/crypto/src/math/ec/ECFieldElement.cs
+++ b/crypto/src/math/ec/ECFieldElement.cs
@@ -306,13 +306,12 @@ namespace Org.BouncyCastle.Math.EC
             BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One);
 
             BigInteger U, V;
-            Random rand = new Random();
             do
             {
                 BigInteger P;
                 do
                 {
-                    P = new BigInteger(q.BitLength, rand);
+                    P = BigInteger.Arbitrary(q.BitLength);
                 }
                 while (P.CompareTo(q) >= 0
                     || !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne));
diff --git a/crypto/src/math/raw/Mod.cs b/crypto/src/math/raw/Mod.cs
index 63467e668..8d9e8fd21 100644
--- a/crypto/src/math/raw/Mod.cs
+++ b/crypto/src/math/raw/Mod.cs
@@ -2,12 +2,15 @@
 using System.Diagnostics;
 
 using Org.BouncyCastle.Crypto.Utilities;
+using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Math.Raw
 {
     internal abstract class Mod
     {
+        private static readonly SecureRandom RandomSource = new SecureRandom();
+
         public static void Invert(uint[] p, uint[] x, uint[] z)
         {
             int len = p.Length;
@@ -77,7 +80,6 @@ namespace Org.BouncyCastle.Math.Raw
         public static uint[] Random(uint[] p)
         {
             int len = p.Length;
-            Random rand = new Random();
             uint[] s = Nat.Create(len);
 
             uint m = p[len - 1];
@@ -90,7 +92,7 @@ namespace Org.BouncyCastle.Math.Raw
             do
             {
                 byte[] bytes = new byte[len << 2];
-                rand.NextBytes(bytes);
+                RandomSource.NextBytes(bytes);
                 Pack.BE_To_UInt32(bytes, 0, s);
                 s[len - 1] &= m;
             }
diff --git a/crypto/src/ocsp/BasicOCSPRespGenerator.cs b/crypto/src/ocsp/BasicOCSPRespGenerator.cs
index 5ff4bd9cc..a7d5f3da5 100644
--- a/crypto/src/ocsp/BasicOCSPRespGenerator.cs
+++ b/crypto/src/ocsp/BasicOCSPRespGenerator.cs
@@ -6,11 +6,11 @@ using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Ocsp;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
-using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Security.Certificates;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.X509;
+using Org.BouncyCastle.Crypto.Operators;
 
 namespace Org.BouncyCastle.Ocsp
 {
@@ -185,21 +185,12 @@ namespace Org.BouncyCastle.Ocsp
 		}
 
 		private BasicOcspResp GenerateResponse(
-			string					signatureName,
-			AsymmetricKeyParameter	privateKey,
+			ISignatureCalculator    signatureCalculator,
 			X509Certificate[]		chain,
-			DateTime				producedAt,
-			SecureRandom			random)
+			DateTime				producedAt)
 		{
-			DerObjectIdentifier signingAlgorithm;
-			try
-			{
-				signingAlgorithm = OcspUtilities.GetAlgorithmOid(signatureName);
-			}
-			catch (Exception e)
-			{
-				throw new ArgumentException("unknown signing algorithm specified", e);
-			}
+            AlgorithmIdentifier signingAlgID = (AlgorithmIdentifier)signatureCalculator.AlgorithmDetails;
+            DerObjectIdentifier signingAlgorithm = signingAlgID.Algorithm;
 
 			Asn1EncodableVector responses = new Asn1EncodableVector();
 
@@ -216,35 +207,19 @@ namespace Org.BouncyCastle.Ocsp
 			}
 
 			ResponseData tbsResp = new ResponseData(responderID.ToAsn1Object(), new DerGeneralizedTime(producedAt), new DerSequence(responses), responseExtensions);
-
-			ISigner sig = null;
+			DerBitString bitSig = null;
 
 			try
 			{
-				sig = SignerUtilities.GetSigner(signatureName);
+                IStreamCalculator streamCalculator = signatureCalculator.CreateCalculator();
 
-				if (random != null)
-				{
-					sig.Init(true, new ParametersWithRandom(privateKey, random));
-				}
-				else
-				{
-					sig.Init(true, privateKey);
-				}
-			}
-			catch (Exception e)
-			{
-				throw new OcspException("exception creating signature: " + e, e);
-			}
+				byte[] encoded = tbsResp.GetDerEncoded();
 
-			DerBitString bitSig = null;
+                streamCalculator.Stream.Write(encoded, 0, encoded.Length);
 
-			try
-			{
-				byte[] encoded = tbsResp.GetDerEncoded();
-				sig.BlockUpdate(encoded, 0, encoded.Length);
+                streamCalculator.Stream.Close();
 
-				bitSig = new DerBitString(sig.GenerateSignature());
+                bitSig = new DerBitString(((IBlockResult)streamCalculator.GetResult()).DoFinal());
 			}
 			catch (Exception e)
 			{
@@ -302,15 +277,35 @@ namespace Org.BouncyCastle.Ocsp
 				throw new ArgumentException("no signing algorithm specified");
 			}
 
-			return GenerateResponse(signingAlgorithm, privateKey, chain, producedAt, random);
+			return GenerateResponse(new Asn1SignatureCalculator(signingAlgorithm, privateKey, random), chain, producedAt);
 		}
 
-		/**
+        /// <summary>
+        /// Generate the signed response using the passed in signature calculator.
+        /// </summary>
+        /// <param name="signatureCalculator">Implementation of signing calculator.</param>
+        /// <param name="chain">The certificate chain associated with the response signer.</param>
+        /// <param name="producedAt">"produced at" date.</param>
+        /// <returns></returns>
+        public BasicOcspResp Generate(
+            ISignatureCalculator signatureCalculator,
+            X509Certificate[] chain,
+            DateTime producedAt)
+        {
+            if (signatureCalculator == null)
+            {
+                throw new ArgumentException("no signature calculator specified");
+            }
+
+            return GenerateResponse(signatureCalculator, chain, producedAt);
+        }
+
+        /**
 		 * Return an IEnumerable of the signature names supported by the generator.
 		 *
 		 * @return an IEnumerable containing recognised names.
 		 */
-		public IEnumerable SignatureAlgNames
+        public IEnumerable SignatureAlgNames
 		{
 			get { return OcspUtilities.AlgNames; }
 		}
diff --git a/crypto/src/ocsp/OCSPException.cs b/crypto/src/ocsp/OCSPException.cs
index db53e559a..d7b14ddc7 100644
--- a/crypto/src/ocsp/OCSPException.cs
+++ b/crypto/src/ocsp/OCSPException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Ocsp
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class OcspException
diff --git a/crypto/src/openpgp/PgpDataValidationException.cs b/crypto/src/openpgp/PgpDataValidationException.cs
index aab5165b2..d06833c16 100644
--- a/crypto/src/openpgp/PgpDataValidationException.cs
+++ b/crypto/src/openpgp/PgpDataValidationException.cs
@@ -5,7 +5,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 	/// <remarks>
 	/// Thrown if the IV at the start of a data stream indicates the wrong key is being used.
 	/// </remarks>
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class PgpDataValidationException
diff --git a/crypto/src/openpgp/PgpEncryptedDataGenerator.cs b/crypto/src/openpgp/PgpEncryptedDataGenerator.cs
index 06868eab1..014281b24 100644
--- a/crypto/src/openpgp/PgpEncryptedDataGenerator.cs
+++ b/crypto/src/openpgp/PgpEncryptedDataGenerator.cs
@@ -311,10 +311,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 
         internal void DoAddMethod(byte[] rawPassPhrase, bool clearPassPhrase, HashAlgorithmTag s2kDigest)
         {
-            byte[] iv = new byte[8];
-            rand.NextBytes(iv);
-
-            S2k s2k = new S2k(s2kDigest, iv, 0x60);
+            S2k s2k = PgpUtilities.GenerateS2k(s2kDigest, 0x60, rand);
 
             methods.Add(new PbeMethod(defAlgorithm, s2k, PgpUtilities.DoMakeKeyFromPassPhrase(defAlgorithm, s2k, rawPassPhrase, clearPassPhrase)));
         }
diff --git a/crypto/src/openpgp/PgpException.cs b/crypto/src/openpgp/PgpException.cs
index 378b16a56..230dab86e 100644
--- a/crypto/src/openpgp/PgpException.cs
+++ b/crypto/src/openpgp/PgpException.cs
@@ -3,7 +3,7 @@ using System;
 namespace Org.BouncyCastle.Bcpg.OpenPgp
 {
 	/// <remarks>Generic exception class for PGP encoding/decoding problems.</remarks>
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class PgpException
diff --git a/crypto/src/openpgp/PgpKeyValidationException.cs b/crypto/src/openpgp/PgpKeyValidationException.cs
index d6419b27b..383ae57a2 100644
--- a/crypto/src/openpgp/PgpKeyValidationException.cs
+++ b/crypto/src/openpgp/PgpKeyValidationException.cs
@@ -5,7 +5,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 	/// <remarks>
 	/// Thrown if the key checksum is invalid.
 	/// </remarks>
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class PgpKeyValidationException
diff --git a/crypto/src/openpgp/PgpLiteralDataGenerator.cs b/crypto/src/openpgp/PgpLiteralDataGenerator.cs
index 3b1f2fe74..17a6eeef2 100644
--- a/crypto/src/openpgp/PgpLiteralDataGenerator.cs
+++ b/crypto/src/openpgp/PgpLiteralDataGenerator.cs
@@ -141,6 +141,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 			return new WrappedGeneratorStream(this, pkOut);
 		}
 
+#if !PORTABLE
 		/// <summary>
 		/// <p>
 		/// Open a literal data packet for the passed in <c>FileInfo</c> object, returning
@@ -162,6 +163,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
         {
 			return Open(outStr, format, file.Name, file.Length, file.LastWriteTime);
         }
+#endif
 
 		/// <summary>
 		/// Close the literal data packet - this is equivalent to calling Close()
diff --git a/crypto/src/openpgp/PgpSecretKey.cs b/crypto/src/openpgp/PgpSecretKey.cs
index 0f472c1a4..d3811c44c 100644
--- a/crypto/src/openpgp/PgpSecretKey.cs
+++ b/crypto/src/openpgp/PgpSecretKey.cs
@@ -97,12 +97,11 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                     byte[] encData;
                     if (pub.Version >= 4)
                     {
-                        encData = EncryptKeyData(keyData, encAlgorithm, rawPassPhrase, clearPassPhrase, rand, out s2k, out iv);
+                        encData = EncryptKeyDataV4(keyData, encAlgorithm, HashAlgorithmTag.Sha1, rawPassPhrase, clearPassPhrase, rand, out s2k, out iv);
                     }
                     else
                     {
-                        // TODO v3 RSA key encryption
-                        throw Platform.CreateNotImplementedException("v3 RSA");
+                        encData = EncryptKeyDataV3(keyData, encAlgorithm, rawPassPhrase, clearPassPhrase, rand, out s2k, out iv);
                     }
 
                     int s2kUsage = useSha1
@@ -461,6 +460,18 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             get { return pub.KeyId; }
         }
 
+        /// <summary>Return the S2K usage associated with this key.</summary>
+        public int S2kUsage
+        {
+            get { return secret.S2kUsage; }
+        }
+
+        /// <summary>Return the S2K used to process this key.</summary>
+        public S2k S2k
+        {
+            get { return secret.S2k; }
+        }
+
         /// <summary>The public key associated with this key.</summary>
         public PgpPublicKey PublicKey
         {
@@ -904,12 +915,11 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 {
                     if (pubKeyPacket.Version >= 4)
                     {
-                        keyData = EncryptKeyData(rawKeyData, newEncAlgorithm, rawNewPassPhrase, clearPassPhrase, rand, out s2k, out iv);
+                        keyData = EncryptKeyDataV4(rawKeyData, newEncAlgorithm, HashAlgorithmTag.Sha1, rawNewPassPhrase, clearPassPhrase, rand, out s2k, out iv);
                     }
                     else
                     {
-                        // TODO v3 RSA key encryption
-                        throw Platform.CreateNotImplementedException("v3 RSA");
+                        keyData = EncryptKeyDataV3(rawKeyData, newEncAlgorithm, rawNewPassPhrase, clearPassPhrase, rand, out s2k, out iv);
                     }
                 }
                 catch (PgpException e)
@@ -950,7 +960,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             return new PgpSecretKey(secretKey.secret, publicKey);
         }
 
-        private static byte[] EncryptKeyData(
+        private static byte[] EncryptKeyDataV3(
             byte[]						rawKeyData,
             SymmetricKeyAlgorithmTag	encAlgorithm,
             byte[]						rawPassPhrase,
@@ -959,6 +969,78 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             out S2k						s2k,
             out byte[]					iv)
         {
+            // Version 2 or 3 - RSA Keys only
+
+            s2k = null;
+            iv = null;
+
+            KeyParameter encKey = PgpUtilities.DoMakeKeyFromPassPhrase(encAlgorithm, s2k, rawPassPhrase, clearPassPhrase);
+
+            byte[] keyData = new byte[rawKeyData.Length];
+
+            //
+            // process 4 numbers
+            //
+            int pos = 0;
+            for (int i = 0; i != 4; i++)
+            {
+                int encLen = (((rawKeyData[pos] << 8) | (rawKeyData[pos + 1] & 0xff)) + 7) / 8;
+
+                keyData[pos] = rawKeyData[pos];
+                keyData[pos + 1] = rawKeyData[pos + 1];
+
+                byte[] tmp;
+                if (i == 0)
+                {
+                    tmp = EncryptData(encAlgorithm, encKey, rawKeyData, pos + 2, encLen, random, ref iv);
+                }
+                else
+                {
+                    byte[] tmpIv = Arrays.CopyOfRange(keyData, pos - iv.Length, pos);
+
+                    tmp = EncryptData(encAlgorithm, encKey, rawKeyData, pos + 2, encLen, random, ref tmpIv);
+                }
+
+                Array.Copy(tmp, 0, keyData, pos + 2, tmp.Length);
+                pos += 2 + encLen;
+            }
+
+            //
+            // copy in checksum.
+            //
+            keyData[pos] = rawKeyData[pos];
+            keyData[pos + 1] = rawKeyData[pos + 1];
+
+            return keyData;
+        }
+
+        private static byte[] EncryptKeyDataV4(
+            byte[]						rawKeyData,
+            SymmetricKeyAlgorithmTag	encAlgorithm,
+            HashAlgorithmTag            hashAlgorithm,
+            byte[]						rawPassPhrase,
+            bool                        clearPassPhrase,
+            SecureRandom				random,
+            out S2k						s2k,
+            out byte[]					iv)
+        {
+            s2k = PgpUtilities.GenerateS2k(hashAlgorithm, 0x60, random);
+
+            KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase(encAlgorithm, s2k, rawPassPhrase, clearPassPhrase);
+
+            iv = null;
+            return EncryptData(encAlgorithm, key, rawKeyData, 0, rawKeyData.Length, random, ref iv);
+        }
+
+        private static byte[] EncryptData(
+            SymmetricKeyAlgorithmTag	encAlgorithm,
+            KeyParameter                key,
+            byte[]						data,
+            int                         dataOff,
+            int                         dataLen,
+            SecureRandom				random,
+            ref byte[]                  iv)
+        {
             IBufferedCipher c;
             try
             {
@@ -970,18 +1052,14 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 throw new PgpException("Exception creating cipher", e);
             }
 
-            byte[] s2kIV = new byte[8];
-            random.NextBytes(s2kIV);
-            s2k = new S2k(HashAlgorithmTag.Sha1, s2kIV, 0x60);
-
-            KeyParameter kp = PgpUtilities.DoMakeKeyFromPassPhrase(encAlgorithm, s2k, rawPassPhrase, clearPassPhrase);
-
-            iv = new byte[c.GetBlockSize()];
-            random.NextBytes(iv);
+            if (iv == null)
+            {
+                iv = PgpUtilities.GenerateIV(c.GetBlockSize(), random);
+            }
 
-            c.Init(true, new ParametersWithRandom(new ParametersWithIV(kp, iv), random));
+            c.Init(true, new ParametersWithRandom(new ParametersWithIV(key, iv), random));
 
-            return c.DoFinal(rawKeyData);
+            return c.DoFinal(data, dataOff, dataLen);
         }
 
         /// <summary>
diff --git a/crypto/src/openpgp/PgpUtilities.cs b/crypto/src/openpgp/PgpUtilities.cs
index 65c07b2e2..f982ae459 100644
--- a/crypto/src/openpgp/PgpUtilities.cs
+++ b/crypto/src/openpgp/PgpUtilities.cs
@@ -347,6 +347,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
             return MakeKey(algorithm, keyBytes);
         }
 
+#if !PORTABLE
         /// <summary>Write out the passed in file as a literal data packet.</summary>
         public static void WriteFileToLiteralData(
             Stream		output,
@@ -384,6 +385,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
 			pOut.Close();
 			inputStream.Close();
 		}
+#endif
 
 		private const int ReadAhead = 60;
 
@@ -488,5 +490,18 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
                 throw new PgpException("unknown wrap algorithm: " + encAlgorithm);
             }
         }
+
+        internal static byte[] GenerateIV(int length, SecureRandom random)
+        {
+            byte[] iv = new byte[length];
+            random.NextBytes(iv);
+            return iv;
+        }
+
+        internal static S2k GenerateS2k(HashAlgorithmTag hashAlgorithm, int s2kCount, SecureRandom random)
+        {
+            byte[] iv = GenerateIV(8, random);
+            return new S2k(hashAlgorithm, iv, s2kCount);
+        }
     }
 }
diff --git a/crypto/src/openssl/EncryptionException.cs b/crypto/src/openssl/EncryptionException.cs
index c4a6ec02f..043e90234 100644
--- a/crypto/src/openssl/EncryptionException.cs
+++ b/crypto/src/openssl/EncryptionException.cs
@@ -3,7 +3,7 @@ using System.IO;
 
 namespace Org.BouncyCastle.Security
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class EncryptionException
diff --git a/crypto/src/openssl/PEMException.cs b/crypto/src/openssl/PEMException.cs
index 4d33a2a1f..6b3e51065 100644
--- a/crypto/src/openssl/PEMException.cs
+++ b/crypto/src/openssl/PEMException.cs
@@ -3,7 +3,7 @@ using System.IO;
 
 namespace Org.BouncyCastle.OpenSsl
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class PemException
diff --git a/crypto/src/openssl/PasswordException.cs b/crypto/src/openssl/PasswordException.cs
index fba958aa0..38e679bb1 100644
--- a/crypto/src/openssl/PasswordException.cs
+++ b/crypto/src/openssl/PasswordException.cs
@@ -3,7 +3,7 @@ using System.IO;
 
 namespace Org.BouncyCastle.Security
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class PasswordException
diff --git a/crypto/src/pkcs/AsymmetricKeyEntry.cs b/crypto/src/pkcs/AsymmetricKeyEntry.cs
index 1c37631d5..6da3ade3e 100644
--- a/crypto/src/pkcs/AsymmetricKeyEntry.cs
+++ b/crypto/src/pkcs/AsymmetricKeyEntry.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Pkcs
             this.key = key;
         }
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete]
         public AsymmetricKeyEntry(
             AsymmetricKeyParameter key,
diff --git a/crypto/src/pkcs/X509CertificateEntry.cs b/crypto/src/pkcs/X509CertificateEntry.cs
index a621619fb..2f81dd87b 100644
--- a/crypto/src/pkcs/X509CertificateEntry.cs
+++ b/crypto/src/pkcs/X509CertificateEntry.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Pkcs
             this.cert = cert;
         }
 
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
         [Obsolete]
         public X509CertificateEntry(
             X509Certificate	cert,
diff --git a/crypto/src/pkix/PkixCertPath.cs b/crypto/src/pkix/PkixCertPath.cs
index e3d3ea7fe..23a53c396 100644
--- a/crypto/src/pkix/PkixCertPath.cs
+++ b/crypto/src/pkix/PkixCertPath.cs
@@ -208,12 +208,12 @@ namespace Org.BouncyCastle.Pkix
 			string	encoding)
 //			: base("X.509")
 		{
-            string upper = encoding.ToUpper();
+            string upper = Platform.ToUpperInvariant(encoding);
 
             IList certs;
 			try
 			{
-				if (upper.Equals("PkiPath".ToUpper()))
+				if (upper.Equals(Platform.ToUpperInvariant("PkiPath")))
 				{
 					Asn1InputStream derInStream = new Asn1InputStream(inStream);
 					Asn1Object derObject = derInStream.ReadObject();
diff --git a/crypto/src/pkix/PkixCertPathBuilderException.cs b/crypto/src/pkix/PkixCertPathBuilderException.cs
index 5a4944dd8..0f10179dd 100644
--- a/crypto/src/pkix/PkixCertPathBuilderException.cs
+++ b/crypto/src/pkix/PkixCertPathBuilderException.cs
@@ -7,7 +7,7 @@ namespace Org.BouncyCastle.Pkix
 	/// <summary>
 	/// Summary description for PkixCertPathBuilderException.
 	/// </summary>
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class PkixCertPathBuilderException : GeneralSecurityException
diff --git a/crypto/src/pkix/PkixCertPathValidatorException.cs b/crypto/src/pkix/PkixCertPathValidatorException.cs
index 35522c6f8..a477f7dc4 100644
--- a/crypto/src/pkix/PkixCertPathValidatorException.cs
+++ b/crypto/src/pkix/PkixCertPathValidatorException.cs
@@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Pkix
 	 *
 	 * @see CertPathValidator
 	 **/
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class PkixCertPathValidatorException
diff --git a/crypto/src/pkix/PkixNameConstraintValidator.cs b/crypto/src/pkix/PkixNameConstraintValidator.cs
index 535f95174..cf944beae 100644
--- a/crypto/src/pkix/PkixNameConstraintValidator.cs
+++ b/crypto/src/pkix/PkixNameConstraintValidator.cs
@@ -638,7 +638,7 @@ namespace Org.BouncyCastle.Pkix
             // a particular mailbox
             if (constraint.IndexOf('@') != -1)
             {
-                if (email.ToUpper().Equals(constraint.ToUpper()))
+                if (Platform.ToUpperInvariant(email).Equals(Platform.ToUpperInvariant(constraint)))
                 {
                     return true;
                 }
@@ -646,7 +646,7 @@ namespace Org.BouncyCastle.Pkix
             // on particular host
             else if (!(constraint[0].Equals('.')))
             {
-                if (sub.ToUpper().Equals(constraint.ToUpper()))
+                if (Platform.ToUpperInvariant(sub).Equals(Platform.ToUpperInvariant(constraint)))
                 {
                     return true;
                 }
@@ -708,7 +708,8 @@ namespace Org.BouncyCastle.Pkix
                 String str = ((String)it.Current);
 
                 // is sub domain
-                if (WithinDomain(dns, str) || dns.ToUpper().Equals(str.ToUpper()))
+                if (WithinDomain(dns, str)
+                    || Platform.ToUpperInvariant(dns).Equals(Platform.ToUpperInvariant(str)))
                 {
                     return;
                 }
diff --git a/crypto/src/pkix/PkixNameConstraintValidatorException.cs b/crypto/src/pkix/PkixNameConstraintValidatorException.cs
index 432d7bd6b..b187525e0 100644
--- a/crypto/src/pkix/PkixNameConstraintValidatorException.cs
+++ b/crypto/src/pkix/PkixNameConstraintValidatorException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Pkix
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class PkixNameConstraintValidatorException
diff --git a/crypto/src/security/DotNetUtilities.cs b/crypto/src/security/DotNetUtilities.cs
index 732b5e075..69322b549 100644
--- a/crypto/src/security/DotNetUtilities.cs
+++ b/crypto/src/security/DotNetUtilities.cs
@@ -1,4 +1,4 @@
-#if !(NETCF_1_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || SILVERLIGHT || PORTABLE)
 
 using System;
 using System.Security.Cryptography;
diff --git a/crypto/src/security/GeneralSecurityException.cs b/crypto/src/security/GeneralSecurityException.cs
index 2c3f2a555..d4ab38cae 100644
--- a/crypto/src/security/GeneralSecurityException.cs
+++ b/crypto/src/security/GeneralSecurityException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class GeneralSecurityException
diff --git a/crypto/src/security/InvalidKeyException.cs b/crypto/src/security/InvalidKeyException.cs
index 4d4488ef2..ebad9e32f 100644
--- a/crypto/src/security/InvalidKeyException.cs
+++ b/crypto/src/security/InvalidKeyException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class InvalidKeyException : KeyException
diff --git a/crypto/src/security/InvalidParameterException.cs b/crypto/src/security/InvalidParameterException.cs
index 57a912d03..48172f470 100644
--- a/crypto/src/security/InvalidParameterException.cs
+++ b/crypto/src/security/InvalidParameterException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class InvalidParameterException : KeyException
diff --git a/crypto/src/security/KeyException.cs b/crypto/src/security/KeyException.cs
index 9304c1c4d..e19fa8961 100644
--- a/crypto/src/security/KeyException.cs
+++ b/crypto/src/security/KeyException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class KeyException : GeneralSecurityException
diff --git a/crypto/src/security/MacUtilities.cs b/crypto/src/security/MacUtilities.cs
index d1f8c89b4..d7fe91142 100644
--- a/crypto/src/security/MacUtilities.cs
+++ b/crypto/src/security/MacUtilities.cs
@@ -230,6 +230,14 @@ namespace Org.BouncyCastle.Security
             return (string) algorithms[oid.Id];
         }
 
+        public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[] input)
+        {
+            IMac mac = GetMac(algorithm);
+            mac.Init(cp);
+            mac.BlockUpdate(input, 0, input.Length);
+            return DoFinal(mac);
+        }
+
         public static byte[] DoFinal(IMac mac)
         {
             byte[] b = new byte[mac.GetMacSize()];
diff --git a/crypto/src/security/NoSuchAlgorithmException.cs b/crypto/src/security/NoSuchAlgorithmException.cs
index d120c5f77..c56ec651e 100644
--- a/crypto/src/security/NoSuchAlgorithmException.cs
+++ b/crypto/src/security/NoSuchAlgorithmException.cs
@@ -3,7 +3,7 @@ using System;
 namespace Org.BouncyCastle.Security
 {
 	[Obsolete("Never thrown")]
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class NoSuchAlgorithmException : GeneralSecurityException
diff --git a/crypto/src/security/SecureRandom.cs b/crypto/src/security/SecureRandom.cs
index 137a471c1..5bad57a14 100644
--- a/crypto/src/security/SecureRandom.cs
+++ b/crypto/src/security/SecureRandom.cs
@@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Security
     {
         private static long counter = Times.NanoTime();
 
-#if NETCF_1_0
+#if NETCF_1_0 || PORTABLE
         private static object counterLock = new object();
         private static long NextCounterValue()
         {
diff --git a/crypto/src/security/SecurityUtilityException.cs b/crypto/src/security/SecurityUtilityException.cs
index 02a3e806e..8a1953008 100644
--- a/crypto/src/security/SecurityUtilityException.cs
+++ b/crypto/src/security/SecurityUtilityException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class SecurityUtilityException
diff --git a/crypto/src/security/SignatureException.cs b/crypto/src/security/SignatureException.cs
index cea3c59cd..3ad617dfd 100644
--- a/crypto/src/security/SignatureException.cs
+++ b/crypto/src/security/SignatureException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class SignatureException : GeneralSecurityException
diff --git a/crypto/src/security/cert/CertificateEncodingException.cs b/crypto/src/security/cert/CertificateEncodingException.cs
index a2909b0d5..ab9024fc7 100644
--- a/crypto/src/security/cert/CertificateEncodingException.cs
+++ b/crypto/src/security/cert/CertificateEncodingException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CertificateEncodingException : CertificateException
diff --git a/crypto/src/security/cert/CertificateException.cs b/crypto/src/security/cert/CertificateException.cs
index 441c598e4..4bbaccfc1 100644
--- a/crypto/src/security/cert/CertificateException.cs
+++ b/crypto/src/security/cert/CertificateException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CertificateException : GeneralSecurityException
diff --git a/crypto/src/security/cert/CertificateExpiredException.cs b/crypto/src/security/cert/CertificateExpiredException.cs
index c893c07ee..864fb85c1 100644
--- a/crypto/src/security/cert/CertificateExpiredException.cs
+++ b/crypto/src/security/cert/CertificateExpiredException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CertificateExpiredException : CertificateException
diff --git a/crypto/src/security/cert/CertificateNotYetValidException.cs b/crypto/src/security/cert/CertificateNotYetValidException.cs
index a0081ce23..02112be98 100644
--- a/crypto/src/security/cert/CertificateNotYetValidException.cs
+++ b/crypto/src/security/cert/CertificateNotYetValidException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CertificateNotYetValidException : CertificateException
diff --git a/crypto/src/security/cert/CertificateParsingException.cs b/crypto/src/security/cert/CertificateParsingException.cs
index 8d8ed1e92..ae909ca40 100644
--- a/crypto/src/security/cert/CertificateParsingException.cs
+++ b/crypto/src/security/cert/CertificateParsingException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CertificateParsingException : CertificateException
diff --git a/crypto/src/security/cert/CrlException.cs b/crypto/src/security/cert/CrlException.cs
index 0df007b1e..fe9807e79 100644
--- a/crypto/src/security/cert/CrlException.cs
+++ b/crypto/src/security/cert/CrlException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Security.Certificates
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class CrlException : GeneralSecurityException
diff --git a/crypto/src/tsp/TSPException.cs b/crypto/src/tsp/TSPException.cs
index 3917e96a7..0f29b1299 100644
--- a/crypto/src/tsp/TSPException.cs
+++ b/crypto/src/tsp/TSPException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Tsp
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class TspException
diff --git a/crypto/src/tsp/TSPValidationException.cs b/crypto/src/tsp/TSPValidationException.cs
index 8ef2ec6cf..80f64203b 100644
--- a/crypto/src/tsp/TSPValidationException.cs
+++ b/crypto/src/tsp/TSPValidationException.cs
@@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Tsp
 	 * If a failure code is associated with the exception it can be retrieved using
 	 * the getFailureCode() method.</p>
 	 */
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class TspValidationException
diff --git a/crypto/src/util/Enums.cs b/crypto/src/util/Enums.cs
index 8bd9c4053..25b218667 100644
--- a/crypto/src/util/Enums.cs
+++ b/crypto/src/util/Enums.cs
@@ -1,7 +1,7 @@
 using System;
 using System.Text;
 
-#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT
+#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE
 using System.Collections;
 using System.Reflection;
 #endif
@@ -42,7 +42,7 @@ namespace Org.BouncyCastle.Utilities
             if (!enumType.IsEnum)
                 throw new ArgumentException("Not an enumeration type", "enumType");
 
-#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT
+#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE
             IList result = Platform.CreateArrayList();
             FieldInfo[] fields = enumType.GetFields(BindingFlags.Static | BindingFlags.Public);
             foreach (FieldInfo field in fields)
diff --git a/crypto/src/util/Platform.cs b/crypto/src/util/Platform.cs
index 99d3982ea..bfed0950a 100644
--- a/crypto/src/util/Platform.cs
+++ b/crypto/src/util/Platform.cs
@@ -3,7 +3,7 @@ using System.Globalization;
 using System.IO;
 using System.Text;
 
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
 using System.Collections.Generic;
 #else
 using System.Collections;
@@ -34,12 +34,14 @@ namespace Org.BouncyCastle.Utilities
         {
 #if SILVERLIGHT
             return String.Compare(a, b, StringComparison.InvariantCultureIgnoreCase);
+#elif PORTABLE
+            return String.Compare(a, b, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase);
 #else
             return String.Compare(a, b, true);
 #endif
         }
 
-#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT
+#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE
         internal static string GetEnvironmentVariable(
             string variable)
         {
@@ -83,7 +85,7 @@ namespace Org.BouncyCastle.Utilities
         }
 #endif
 
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
         internal static System.Collections.IList CreateArrayList()
         {
             return new List<object>();
@@ -165,12 +167,20 @@ namespace Org.BouncyCastle.Utilities
 
         internal static string ToLowerInvariant(string s)
         {
+#if PORTABLE
+            return s.ToLowerInvariant();
+#else
             return s.ToLower(CultureInfo.InvariantCulture);
+#endif
         }
 
         internal static string ToUpperInvariant(string s)
         {
+#if PORTABLE
+            return s.ToUpperInvariant();
+#else
             return s.ToUpper(CultureInfo.InvariantCulture);
+#endif
         }
 
         internal static readonly string NewLine = GetNewLine();
diff --git a/crypto/src/util/Strings.cs b/crypto/src/util/Strings.cs
index a6080f427..3937a087f 100644
--- a/crypto/src/util/Strings.cs
+++ b/crypto/src/util/Strings.cs
@@ -52,7 +52,7 @@ namespace Org.BouncyCastle.Utilities
         public static string FromAsciiByteArray(
             byte[] bytes)
         {
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
             // TODO Check for non-ASCII bytes in input?
             return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
 #else
@@ -63,7 +63,7 @@ namespace Org.BouncyCastle.Utilities
         public static byte[] ToAsciiByteArray(
             char[] cs)
         {
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
             // TODO Check for non-ASCII characters in input?
             return Encoding.UTF8.GetBytes(cs);
 #else
@@ -74,7 +74,7 @@ namespace Org.BouncyCastle.Utilities
         public static byte[] ToAsciiByteArray(
             string s)
         {
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
             // TODO Check for non-ASCII characters in input?
             return Encoding.UTF8.GetBytes(s);
 #else
diff --git a/crypto/src/util/io/StreamOverflowException.cs b/crypto/src/util/io/StreamOverflowException.cs
index d8fcb558c..36d21e23e 100644
--- a/crypto/src/util/io/StreamOverflowException.cs
+++ b/crypto/src/util/io/StreamOverflowException.cs
@@ -3,7 +3,7 @@ using System.IO;
 
 namespace Org.BouncyCastle.Utilities.IO
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class StreamOverflowException
diff --git a/crypto/src/util/io/pem/PemGenerationException.cs b/crypto/src/util/io/pem/PemGenerationException.cs
index b8edc622b..6b3958577 100644
--- a/crypto/src/util/io/pem/PemGenerationException.cs
+++ b/crypto/src/util/io/pem/PemGenerationException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Utilities.IO.Pem
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class PemGenerationException
diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs
index 4487232f0..c323fc8f1 100644
--- a/crypto/src/x509/X509Certificate.cs
+++ b/crypto/src/x509/X509Certificate.cs
@@ -376,7 +376,7 @@ namespace Org.BouncyCastle.X509
 
 		protected override X509Extensions GetX509Extensions()
 		{
-			return c.Version == 3
+			return c.Version >= 3
 				?	c.TbsCertificate.Extensions
 				:	null;
 		}
diff --git a/crypto/src/x509/X509Crl.cs b/crypto/src/x509/X509Crl.cs
index 1746960fb..0679cb240 100644
--- a/crypto/src/x509/X509Crl.cs
+++ b/crypto/src/x509/X509Crl.cs
@@ -64,7 +64,7 @@ namespace Org.BouncyCastle.X509
 
 		protected override X509Extensions GetX509Extensions()
 		{
-			return Version == 2
+			return c.Version >= 2
 				?	c.TbsCertList.Extensions
 				:	null;
 		}
diff --git a/crypto/src/x509/store/IX509Selector.cs b/crypto/src/x509/store/IX509Selector.cs
index 09f6f1849..75358cbbf 100644
--- a/crypto/src/x509/store/IX509Selector.cs
+++ b/crypto/src/x509/store/IX509Selector.cs
@@ -3,11 +3,11 @@ using System;
 namespace Org.BouncyCastle.X509.Store
 {
 	public interface IX509Selector
-#if !SILVERLIGHT
+#if !(SILVERLIGHT || PORTABLE)
 		: ICloneable
 #endif
 	{
-#if SILVERLIGHT
+#if SILVERLIGHT || PORTABLE
         object Clone();
 #endif
         bool Match(object obj);
diff --git a/crypto/src/x509/store/NoSuchStoreException.cs b/crypto/src/x509/store/NoSuchStoreException.cs
index 02c593245..28b18892a 100644
--- a/crypto/src/x509/store/NoSuchStoreException.cs
+++ b/crypto/src/x509/store/NoSuchStoreException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.X509.Store
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class NoSuchStoreException
diff --git a/crypto/src/x509/store/X509StoreException.cs b/crypto/src/x509/store/X509StoreException.cs
index f781291e2..ea7e51e79 100644
--- a/crypto/src/x509/store/X509StoreException.cs
+++ b/crypto/src/x509/store/X509StoreException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.X509.Store
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class X509StoreException
diff --git a/crypto/test/src/asn1/test/CertificateTest.cs b/crypto/test/src/asn1/test/CertificateTest.cs
index 532e81aba..7fcb1fffa 100644
--- a/crypto/test/src/asn1/test/CertificateTest.cs
+++ b/crypto/test/src/asn1/test/CertificateTest.cs
@@ -212,7 +212,7 @@ namespace Org.BouncyCastle.Asn1.Tests
 					+ " got " + tbsCert.Subject.ToString());
 			}
 
-			if (tbsCert.Version == 3)
+			if (tbsCert.Version >= 3)
 			{
 				X509Extensions ext = tbsCert.Extensions;
 				if (ext != null)
diff --git a/crypto/test/src/crypto/test/GOST3411DigestTest.cs b/crypto/test/src/crypto/test/GOST3411DigestTest.cs
index 1826b28c9..329a158d6 100644
--- a/crypto/test/src/crypto/test/GOST3411DigestTest.cs
+++ b/crypto/test/src/crypto/test/GOST3411DigestTest.cs
@@ -4,7 +4,13 @@ using NUnit.Framework;
 
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Macs;
+using Org.BouncyCastle.Crypto.Parameters;
 
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.Utilities.Test;
 
 namespace Org.BouncyCastle.Crypto.Tests
@@ -40,7 +46,7 @@ namespace Org.BouncyCastle.Crypto.Tests
 //		};
 
 		// 1 million 'a'
-		static private string  million_a_digest = "8693287aa62f9478f7cb312ec0866b6c4e4a0f11160441e8f4ffcd2715dd554f";
+		static private string million_a_digest = "8693287aa62f9478f7cb312ec0866b6c4e4a0f11160441e8f4ffcd2715dd554f";
 
 		public Gost3411DigestTest()
 			: base(new Gost3411Digest(), messages, digests)
@@ -52,9 +58,19 @@ namespace Org.BouncyCastle.Crypto.Tests
 			base.PerformTest();
 
 			millionATest(million_a_digest);
-		}
 
-		protected override IDigest CloneDigest(IDigest digest)
+            byte[] data = Strings.ToUtf8ByteArray("fred");
+
+            KeyParameter key = new KeyParameter(Pkcs5S1ParametersGenerator.Pkcs5PasswordToUtf8Bytes("1".ToCharArray()));
+            byte[] mac = MacUtilities.CalculateMac("HMAC/GOST3411", key, data);
+
+            if (!Arrays.AreEqual(Hex.Decode("e9f98610cfc80084462b175a15d2b4ec10b2ab892eae5a6179d572d9b1db6b72"), mac))
+            {
+                Fail("mac calculation failed.");
+            }
+        }
+
+        protected override IDigest CloneDigest(IDigest digest)
 		{
 			return new Gost3411Digest((Gost3411Digest)digest);
 		}
diff --git a/crypto/test/src/openpgp/examples/test/AllTests.cs b/crypto/test/src/openpgp/examples/test/AllTests.cs
index c20b599d7..9a515ea15 100644
--- a/crypto/test/src/openpgp/examples/test/AllTests.cs
+++ b/crypto/test/src/openpgp/examples/test/AllTests.cs
@@ -249,6 +249,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples.Tests
 		{
 			CreateTestFile(clearSignedPublicKey, "test.txt");
 
+            RsaKeyRingGenerator.Main(new string[]{ "test", "password" });
+
 			ClearSignedFileProcessor.Main(new string[]{ "-s", "test.txt", "secret.bpg", "password" });
 		}
 
@@ -258,6 +260,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples.Tests
             CreateTestData("This is a test payload!" + Environment.NewLine, "test.txt");
             CreateTestData("This is a test payload!" + Environment.NewLine, "test.bak");
 
+            RsaKeyRingGenerator.Main(new string[]{ "test", "password" });
+
             ClearSignedFileProcessor.Main(new string[]{"-s", "test.txt", "secret.bpg", "password"});
             ClearSignedFileProcessor.Main(new string[]{"-v", "test.txt.asc", "pub.bpg"});
 
diff --git a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
index 43aef5afa..6c52ca8ba 100644
--- a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
+++ b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
@@ -18,6 +18,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
     public class PgpKeyRingTest
         : SimpleTest
     {
+        private static readonly SecureRandom Random = new SecureRandom();
+
         private static readonly byte[] pub1 = Base64.Decode(
             "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn"
             + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg"
@@ -1061,6 +1063,47 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             + "n3pjONa4PKrePkEsCUhRbIySqXIHuNwZumDOlKzZHDpCUw72LaC6S6zwuoEf"
             + "ucOcxTeGIUViANWXyTIKkHfo7HfigixJIL8nsAFn");
 
+        // Key from http://www.angelfire.com/pr/pgpf/pgpoddities.html
+        private static readonly char[] v3KeyPass = "test@key.test".ToCharArray();
+
+        private static readonly byte[] pubv3 = Base64.Decode(
+            "mQENAzroPPgAAAEIANnTx/gHfag7qRMG6cVUnYZJjLcsdF6JSaVs+PUDCZ8l2+Z2" +
+            "V9tgxByp26bymIlq5qFFeoA5vCiKc8qzYiEVLJVVIIDjw/id2gq/TgmxoLAwiDQM" +
+            "TUKdCFa6pmR/uaxyrnJxfUA7+Qh0R0OjoCxNlrmyO3eiKstsJGqSUFIQq7GhcHc4" +
+            "nbV59zHhEWnH7DX7sDa9CgF11WxM3sjWp15iOoP1nixhmchDtQ7foUxLsCF36G/4" +
+            "ijcbN2NjiCDYMFburN8fXgrQzYHAIIiVFE0J+fbXNfPRmnbhQdaC8rIdiQ3tExBb" +
+            "N0qWhGPT9M4JOZd1yPdFMb9gbntd8VZkiPd6/3sABRG0FHRlc3QgPHRlc3RAa2V5" +
+            "LnRlc3Q+iQEVAwUQOug8+PFWZIj3ev97AQH7NQgAo3sH+KcsPtAbyp5U02J9h3Ro" +
+            "aiKpAYxg3rfUVo/RH6hmCWT/AlPHLPZZC/tKiPkuIm2V3Xqyum530N0sBYxNzgNp" +
+            "us8mK9QurYj2omKzf1ltN+uNHR8vjB8s7jEd/CDCARu81PqNoVq2b9JRFGpGbAde" +
+            "7kQ/a0r2/IsJ8fz0iSpCH0geoHt3sBk9MyEem4uG0e2NzlH2wBz4H8l8BNHRHBq0" +
+            "6tGH4h11ZhH3FiNzJWibT2AvzLCqar2qK+6pohKSvIp8zEP7Y/iQzCvkuOfHsUOH" +
+            "4Utgg85k09hRDZ3pRRL/4R+Z+/1uXb+n6yKbOmpmi7U7wc9IwZxtTlGXsNIf+Q=="
+        );
+
+        private static readonly byte[] privv3 = Base64.Decode(
+            "lQOgAzroPPgAAAEIANnTx/gHfag7qRMG6cVUnYZJjLcsdF6JSaVs+PUDCZ8l2+Z2" +
+            "V9tgxByp26bymIlq5qFFeoA5vCiKc8qzYiEVLJVVIIDjw/id2gq/TgmxoLAwiDQM" +
+            "TUKdCFa6pmR/uaxyrnJxfUA7+Qh0R0OjoCxNlrmyO3eiKstsJGqSUFIQq7GhcHc4" +
+            "nbV59zHhEWnH7DX7sDa9CgF11WxM3sjWp15iOoP1nixhmchDtQ7foUxLsCF36G/4" +
+            "ijcbN2NjiCDYMFburN8fXgrQzYHAIIiVFE0J+fbXNfPRmnbhQdaC8rIdiQ3tExBb" +
+            "N0qWhGPT9M4JOZd1yPdFMb9gbntd8VZkiPd6/3sABREDXB5zk3GNdSkH/+/447Kq" +
+            "hR9uM+UnZz7wDkzmt+7xbNg9F2pr/tghVCM7D0PO1YjH4DBpU1ZRO+v1t/eBB/Jd" +
+            "3lJYdlWYHOefJkBi44gNAafZ8ysPOJk6OGOjas/sr+JRFiX9Mgzrs2IDiejmuA98" +
+            "DLuSuNtzFKbE2/DDdOBEizYUjqPLlCdn5sVEt+0WKWJiAv7YonCGguWS3RKfTaYk" +
+            "9IE9SbI+qph9JsuyTD22GLv+gTMvwCkC1DVaHIVgzURpdnlyYyz4DBh3pAgg0nh6" +
+            "gpUTsjnUmrvdh+r8qj3oXH7WBMhs6qKYvU1Go5iV3S1Cu4H/Z/+s6XUFgQShevVe" +
+            "VCy0QtmWSFeySekEACHLJIdBDa8K4dcM2wvccz587D4PtKvMG5j71raOcgVY+r1k" +
+            "e6au/fa0ACqLNvn6+vFHG+Rurn8RSKV31YmTpx7J5ixTOsB+wVcwTYbrw8uNlBWc" +
+            "+IkqPwHrtdK95GIYQykfPW95PRudsOBdxwQW4Ax/WCst3fbjo0SZww0Os+3WBADJ" +
+            "/Nv0mjikXRmqJIzfuI2yxxX4Wm6vqXJkPF7LGtSMB3VEJ3qPsysoai5TYboxA8C1" +
+            "4rQjIoQjA+87gxZ44PUVxrxBonITCLXJ3GsvDQ2PNhS6WQ9Cf89vtYW1vLW65Nex" +
+            "+7AuVRepKhx6Heqdf7S03m6UYliIglrEzgEWM1XrOwP/gLMsme4h0LjLgKfd0LBk" +
+            "qSMdu21VSl60TMTjxav149AdutzuCVa/yPBM/zLQdlvQoGYg2IbN4+7gDHKURcSx" +
+            "DgOAzCcEZxdMvRk2kaOI5RRf5gV9e+ErvEMzJ/xT8xWsi+aLOhaDMbwq2LLiK2L+" +
+            "tXV/Z3H/Ot4u3E7H+6fHPElFYbQUdGVzdCA8dGVzdEBrZXkudGVzdD4="
+        );
+
         [Test]
         public void PerformTest1()
         {
@@ -1815,9 +1858,9 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
         {
             char[] passPhrase = "hello".ToCharArray();
             DsaParametersGenerator pGen = new DsaParametersGenerator();
-            pGen.Init(512, 80, new SecureRandom());
+            pGen.Init(512, 80, Random);
             DsaParameters dsaParams = pGen.GenerateParameters();
-            DsaKeyGenerationParameters dsaKgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams);
+            DsaKeyGenerationParameters dsaKgp = new DsaKeyGenerationParameters(Random, dsaParams);
             IAsymmetricCipherKeyPairGenerator dsaKpg = GeneratorUtilities.GetKeyPairGenerator("DSA");
             dsaKpg.Init(dsaKgp);
 
@@ -1833,7 +1876,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
 
             ElGamalParameters elParams = new ElGamalParameters(p, g);
-            ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(new SecureRandom(), elParams);
+            ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(Random, elParams);
             elgKpg.Init(elKgp);
 
             //
@@ -1844,7 +1887,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             PgpKeyPair elgKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalEncrypt, elgKp, DateTime.UtcNow);
 
             PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, dsaKeyPair,
-                "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, false, null, null, new SecureRandom());
+                "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, false, null, null, Random);
 
             keyRingGen.AddSubKey(elgKeyPair);
 
@@ -1887,12 +1930,10 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
         [Test]
         public void InsertMasterTest()
         {
-            SecureRandom random = new SecureRandom();
-
             char[] passPhrase = "hello".ToCharArray();
             IAsymmetricCipherKeyPairGenerator rsaKpg = GeneratorUtilities.GetKeyPairGenerator("RSA");
 
-            rsaKpg.Init(new KeyGenerationParameters(random, 512));
+            rsaKpg.Init(new KeyGenerationParameters(Random, 512));
 
             //
             // this is quicker because we are using pregenerated parameters.
@@ -1904,12 +1945,12 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             PgpKeyPair rsaKeyPair2 = new PgpKeyPair(PublicKeyAlgorithmTag.RsaGeneral, rsaKp, DateTime.UtcNow);
 
             PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification,
-                rsaKeyPair1, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, false, null, null, random);
+                rsaKeyPair1, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, false, null, null, Random);
             PgpSecretKeyRing secRing1 = keyRingGen.GenerateSecretKeyRing();
             PgpPublicKeyRing pubRing1 = keyRingGen.GeneratePublicKeyRing();
 
             keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification,
-                rsaKeyPair2, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, false, null, null, random);
+                rsaKeyPair2, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, false, null, null, Random);
             PgpSecretKeyRing secRing2 = keyRingGen.GenerateSecretKeyRing();
             PgpPublicKeyRing pubRing2 = keyRingGen.GeneratePublicKeyRing();
 
@@ -1947,9 +1988,9 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
 
             IAsymmetricCipherKeyPairGenerator dsaKpg = GeneratorUtilities.GetKeyPairGenerator("DSA");
             DsaParametersGenerator pGen = new DsaParametersGenerator();
-            pGen.Init(512, 80, new SecureRandom());
+            pGen.Init(512, 80, Random);
             DsaParameters dsaParams = pGen.GenerateParameters();
-            DsaKeyGenerationParameters kgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams);
+            DsaKeyGenerationParameters kgp = new DsaKeyGenerationParameters(Random, dsaParams);
             dsaKpg.Init(kgp);
 
             //
@@ -1965,7 +2006,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
 
             ElGamalParameters elParams = new ElGamalParameters(p, g);
-            ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(new SecureRandom(), elParams);
+            ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(Random, elParams);
             elgKpg.Init(elKgp);
 
             //
@@ -1978,7 +2019,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             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());
+                "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, true, null, null, Random);
 
             keyRingGen.AddSubKey(elgKeyPair);
 
@@ -2021,28 +2062,121 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
         [Test]
         public void RewrapTest()
         {
-            SecureRandom rand = new SecureRandom();
-
             // Read the secret key rings
             PgpSecretKeyRingBundle privRings = new PgpSecretKeyRingBundle(
                 new MemoryStream(rewrapKey, false));
 
+            char[] newPass = "fred".ToCharArray();
+
             foreach (PgpSecretKeyRing pgpPrivEnum in privRings.GetKeyRings())
             {
-                foreach (PgpSecretKey pgpKeyEnum in pgpPrivEnum.GetSecretKeys())
+                PgpSecretKeyRing pgpPriv = pgpPrivEnum;
+
+                foreach (PgpSecretKey pgpKeyEnum in pgpPriv.GetSecretKeys())
                 {
+                    long oldKeyID = pgpKeyEnum.KeyId;
+
                     // re-encrypt the key with an empty password
-                    PgpSecretKeyRing pgpPriv = PgpSecretKeyRing.RemoveSecretKey(pgpPrivEnum, pgpKeyEnum);
+                    pgpPriv = PgpSecretKeyRing.RemoveSecretKey(pgpPriv, pgpKeyEnum);
                     PgpSecretKey pgpKey = PgpSecretKey.CopyWithNewPassword(
                         pgpKeyEnum,
                         rewrapPass,
                         null,
                         SymmetricKeyAlgorithmTag.Null,
-                        rand);
+                        Random);
                     pgpPriv = PgpSecretKeyRing.InsertSecretKey(pgpPriv, pgpKey);
 
                     // this should succeed
                     PgpPrivateKey privTmp = pgpKey.ExtractPrivateKey(null);
+
+                    if (pgpKey.KeyId != oldKeyID || pgpKey.S2kUsage != SecretKeyPacket.UsageNone)
+                    {
+                        Fail("usage/key ID mismatch");
+                    }
+                }
+
+                foreach (PgpSecretKey pgpKeyEnum in pgpPriv.GetSecretKeys())
+                {
+                    long oldKeyID = pgpKeyEnum.KeyId;
+
+                    // re-encrypt the key with an empty password
+                    pgpPriv = PgpSecretKeyRing.RemoveSecretKey(pgpPriv, pgpKeyEnum);
+                    PgpSecretKey pgpKey = PgpSecretKey.CopyWithNewPassword(
+                        pgpKeyEnum,
+                        null,
+                        newPass,
+                        SymmetricKeyAlgorithmTag.Cast5,
+                        Random);
+                    pgpPriv = PgpSecretKeyRing.InsertSecretKey(pgpPriv, pgpKey);
+
+                    // this should succeed
+                    PgpPrivateKey privTmp = pgpKey.ExtractPrivateKey(newPass);
+
+                    if (pgpKey.KeyId != oldKeyID || pgpKey.S2kUsage != SecretKeyPacket.UsageChecksum)
+                    {
+                        Fail("usage/key ID mismatch");
+                    }
+                }
+            }
+        }
+
+        [Test]
+        public void RewrapTestV3()
+        {
+            // Read the secret key rings
+            PgpSecretKeyRingBundle privRings = new PgpSecretKeyRingBundle(
+                new MemoryStream(privv3, false));
+
+            char[] newPass = "fred".ToCharArray();
+
+            foreach (PgpSecretKeyRing pgpPrivEnum in privRings.GetKeyRings())
+            {
+                PgpSecretKeyRing pgpPriv = pgpPrivEnum;
+
+                foreach (PgpSecretKey pgpKeyEnum in pgpPriv.GetSecretKeys())
+                {
+                    long oldKeyID = pgpKeyEnum.KeyId;
+
+                    // re-encrypt the key with an empty password
+                    pgpPriv = PgpSecretKeyRing.RemoveSecretKey(pgpPriv, pgpKeyEnum);
+                    PgpSecretKey pgpKey = PgpSecretKey.CopyWithNewPassword(
+                        pgpKeyEnum,
+                        v3KeyPass,
+                        null,
+                        SymmetricKeyAlgorithmTag.Null,
+                        Random);
+                    pgpPriv = PgpSecretKeyRing.InsertSecretKey(pgpPriv, pgpKey);
+
+                    // this should succeed
+                    PgpPrivateKey privTmp = pgpKey.ExtractPrivateKey(null);
+
+                    if (pgpKey.KeyId != oldKeyID)
+                    {
+                        Fail("key ID mismatch");
+                    }
+                }
+
+                foreach (PgpSecretKey pgpKeyEnum in pgpPriv.GetSecretKeys())
+                {
+                    long oldKeyID = pgpKeyEnum.KeyId;
+
+                    // re-encrypt the key with an empty password
+                    pgpPriv = PgpSecretKeyRing.RemoveSecretKey(pgpPriv, pgpKeyEnum);
+                    PgpSecretKey pgpKey = PgpSecretKey.CopyWithNewPassword(
+                        pgpKeyEnum,
+                        null,
+                        newPass,
+                        SymmetricKeyAlgorithmTag.Cast5,
+                        Random);
+                    pgpPriv = PgpSecretKeyRing.InsertSecretKey(pgpPriv, pgpKey);
+
+                    // this should succeed
+                    PgpPrivateKey privTmp = pgpKey.ExtractPrivateKey(newPass);
+
+                    if (pgpKey.KeyId != oldKeyID)
+                    {
+                        Fail("key ID mismatch");
+                    }
                 }
             }
         }
diff --git a/crypto/test/src/test/BlockCipherTest.cs b/crypto/test/src/test/BlockCipherTest.cs
index 2e8e8b0b8..93cf2b0a5 100644
--- a/crypto/test/src/test/BlockCipherTest.cs
+++ b/crypto/test/src/test/BlockCipherTest.cs
@@ -438,6 +438,7 @@ namespace Org.BouncyCastle.Tests
                 {
                     // TODO Examine short IV handling for these FIPS-compliant modes in Java build
                     if (mode.StartsWith("CFB")
+                        || mode.StartsWith("CTR")
                         || mode.StartsWith("GOFB")
                         || mode.StartsWith("OFB")
                         || mode.StartsWith("OPENPGPCFB"))
diff --git a/crypto/test/src/util/test/TestFailedException.cs b/crypto/test/src/util/test/TestFailedException.cs
index ecd7e7d7a..54dc840bc 100644
--- a/crypto/test/src/util/test/TestFailedException.cs
+++ b/crypto/test/src/util/test/TestFailedException.cs
@@ -2,7 +2,7 @@ using System;
 
 namespace Org.BouncyCastle.Utilities.Test
 {
-#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT)
+#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
     [Serializable]
 #endif
     public class TestFailedException