summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs59
-rw-r--r--crypto/src/crypto/digests/SkeinEngine.cs1584
-rw-r--r--crypto/src/crypto/engines/ThreefishEngine.cs3
-rw-r--r--crypto/src/crypto/parameters/SkeinParameters.cs6
-rw-r--r--crypto/src/math/ec/ECCurve.cs3
-rw-r--r--crypto/src/math/ec/abc/Tnaf.cs2
-rw-r--r--crypto/src/security/PublicKeyFactory.cs2
-rw-r--r--crypto/src/util/IMemoable.cs2
-rw-r--r--crypto/src/util/MemoableResetException.cs40
-rw-r--r--crypto/test/src/crypto/test/OCBTest.cs4
-rw-r--r--crypto/test/src/test/CertTest.cs4
-rw-r--r--crypto/test/src/test/GOST3410Test.cs505
-rw-r--r--crypto/test/src/test/PKCS10CertRequestTest.cs2
13 files changed, 1104 insertions, 1112 deletions
diff --git a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs
index 998e0e06f..b3f55236c 100644
--- a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs
+++ b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs
@@ -15,9 +15,9 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
     */
     public sealed class ECGost3410NamedCurves
     {
-		private ECGost3410NamedCurves()
-		{
-		}
+        private ECGost3410NamedCurves()
+        {
+        }
 
         internal static readonly IDictionary objIds = Platform.CreateHashtable();
         internal static readonly IDictionary parameters = Platform.CreateHashtable();
@@ -35,13 +35,12 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
 
             ECDomainParameters ecParams = new ECDomainParameters(
                 curve,
-				curve.CreatePoint(
-					BigInteger.One, // x
-					new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"), // y
-					false),
+                curve.CreatePoint(
+                    BigInteger.One, // x
+                    new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y
                 mod_q);
 
-			parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = ecParams;
+            parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = ecParams;
 
             mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319");
             mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323");
@@ -53,10 +52,9 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
 
             ecParams = new ECDomainParameters(
                 curve,
-				curve.CreatePoint(
-					BigInteger.One, // x
-					new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"), // y
-					false),
+                curve.CreatePoint(
+                    BigInteger.One, // x
+                    new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y
                 mod_q);
 
             parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA] = ecParams;
@@ -72,9 +70,8 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             ecParams = new ECDomainParameters(
                 curve,
                 curve.CreatePoint(
-					BigInteger.One, // x
-					new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124"), // y
-					false),
+                    BigInteger.One, // x
+                    new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124")), // y
                 mod_q); // q
 
             parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProB] = ecParams;
@@ -90,9 +87,8 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             ecParams = new ECDomainParameters(
                 curve,
                 curve.CreatePoint(
-					BigInteger.Zero, // x
-					new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"), // y
-					false),
+                    BigInteger.Zero, // x
+                    new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), // y
                 mod_q);
 
             parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB] = ecParams;
@@ -107,12 +103,11 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             ecParams = new ECDomainParameters(
                 curve,
                 curve.CreatePoint(
-					BigInteger.Zero, // x
-					new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"), // y
-					false),
+                    BigInteger.Zero, // x
+                    new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), // y
                 mod_q); // q
 
-			parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = ecParams;
+            parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = ecParams;
 
             objIds["GostR3410-2001-CryptoPro-A"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProA;
             objIds["GostR3410-2001-CryptoPro-B"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProB;
@@ -139,14 +134,14 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             return (ECDomainParameters) parameters[oid];
         }
 
-		/**
-		 * returns an enumeration containing the name strings for curves
-		 * contained in this structure.
-		 */
-		public static IEnumerable Names
-		{
-			get { return new EnumerableProxy(objIds.Keys); }
-		}
+        /**
+         * returns an enumeration containing the name strings for curves
+         * contained in this structure.
+         */
+        public static IEnumerable Names
+        {
+            get { return new EnumerableProxy(objIds.Keys); }
+        }
 
         public static ECDomainParameters GetByName(
             string name)
@@ -170,8 +165,8 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
             return (string) names[oid];
         }
 
-		public static DerObjectIdentifier GetOid(
-			string name)
+        public static DerObjectIdentifier GetOid(
+            string name)
         {
             return (DerObjectIdentifier) objIds[name];
         }
diff --git a/crypto/src/crypto/digests/SkeinEngine.cs b/crypto/src/crypto/digests/SkeinEngine.cs
index 43381e7cf..7e93138ac 100644
--- a/crypto/src/crypto/digests/SkeinEngine.cs
+++ b/crypto/src/crypto/digests/SkeinEngine.cs
@@ -8,797 +8,797 @@ using Org.BouncyCastle.Utilities;
 namespace Org.BouncyCastle.Crypto.Digests
 {
 
-	/// <summary>
-	/// Implementation of the Skein family of parameterised hash functions in 256, 512 and 1024 bit block
-	/// sizes, based on the <see cref="Org.BouncyCastle.Crypto.Engines.ThreefishEngine">Threefish</see> tweakable block cipher.
-	/// </summary>
-	/// <remarks>
-	/// This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3
-	/// competition in October 2010.
-	/// <p/>
-	/// Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir
-	/// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker.
-	/// <p/>
-	/// This implementation is the basis for <see cref="Org.BouncyCastle.Crypto.Digests.SkeinDigest"/> and <see cref="Org.BouncyCastle.Crypto.Macs.SkeinMac"/>, implementing the
-	/// parameter based configuration system that allows Skein to be adapted to multiple applications. <br>
-	/// Initialising the engine with <see cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> allows standard and arbitrary parameters to
-	/// be applied during the Skein hash function.
-	/// <p/>
-	/// Implemented:
-	/// <ul>
-	/// <li>256, 512 and 1024 bit internal states.</li>
-	/// <li>Full 96 bit input length.</li>
-	/// <li>Parameters defined in the Skein specification, and arbitrary other pre and post message
-	/// parameters.</li>
-	/// <li>Arbitrary output size in 1 byte intervals.</li>
-	/// </ul>
-	/// <p/>
-	/// Not implemented:
-	/// <ul>
-	/// <li>Sub-byte length input (bit padding).</li>
-	/// <li>Tree hashing.</li>
-	/// </ul>
-	/// </remarks>
-	/// <seealso cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/>
-	public class SkeinEngine
-		: IMemoable
-	{
-		/// <summary>
-		/// 256 bit block size - Skein-256
-		/// </summary>
-		public const int SKEIN_256 = ThreefishEngine.BLOCKSIZE_256;
-		/// <summary>
-		/// 512 bit block size - Skein-512
-		/// </summary>
-		public const int SKEIN_512 = ThreefishEngine.BLOCKSIZE_512;
-		/// <summary>
-		/// 1024 bit block size - Skein-1024
-		/// </summary>
-		public const int SKEIN_1024 = ThreefishEngine.BLOCKSIZE_1024;
-
-		// Minimal at present, but more complex when tree hashing is implemented
-		private class Configuration
-		{
-			private byte[] bytes = new byte[32];
-
-			public Configuration(long outputSizeBits)
-			{
-				// 0..3 = ASCII SHA3
-				bytes[0] = (byte)'S';
-				bytes[1] = (byte)'H';
-				bytes[2] = (byte)'A';
-				bytes[3] = (byte)'3';
-
-				// 4..5 = version number in LSB order
-				bytes[4] = 1;
-				bytes[5] = 0;
-
-				// 8..15 = output length
-				ThreefishEngine.WordToBytes((ulong)outputSizeBits, bytes, 8);
-			}
-
-			public byte[] Bytes
-			{
-				get { return bytes; }
-			}
-
-		}
-
-		public class Parameter
-		{
-			private int type;
-			private byte[] value;
-
-			public Parameter(int type, byte[] value)
-			{
-				this.type = type;
-				this.value = value;
-			}
-
-			public int Type
-			{
-				get { return type; }
-			}
-
-			public byte[] Value
-			{
-				get { return value; }
-			}
-
-		}
-
-		/**
-	     * The parameter type for the Skein key.
-	     */
-		private const int PARAM_TYPE_KEY = 0;
-
-		/**
-	     * The parameter type for the Skein configuration block.
-	     */
-		private const int PARAM_TYPE_CONFIG = 4;
-
-		/**
-	     * The parameter type for the message.
-	     */
-		private const int PARAM_TYPE_MESSAGE = 48;
-
-		/**
-	     * The parameter type for the output transformation.
-	     */
-		private const int PARAM_TYPE_OUTPUT = 63;
-
-		/**
-	     * Precalculated UBI(CFG) states for common state/output combinations without key or other
-	     * pre-message params.
-	     */
-		private static readonly IDictionary INITIAL_STATES = Platform.CreateHashtable();
-
-		static SkeinEngine()
-		{
-			// From Appendix C of the Skein 1.3 NIST submission
-			InitialState(SKEIN_256, 128, new ulong[]{
-				0xe1111906964d7260UL,
-				0x883daaa77c8d811cUL,
-				0x10080df491960f7aUL,
-				0xccf7dde5b45bc1c2UL});
-
-			InitialState(SKEIN_256, 160, new ulong[]{
-				0x1420231472825e98UL,
-				0x2ac4e9a25a77e590UL,
-				0xd47a58568838d63eUL,
-				0x2dd2e4968586ab7dUL});
-
-			InitialState(SKEIN_256, 224, new ulong[]{
-				0xc6098a8c9ae5ea0bUL,
-				0x876d568608c5191cUL,
-				0x99cb88d7d7f53884UL,
-				0x384bddb1aeddb5deUL});
-
-			InitialState(SKEIN_256, 256, new ulong[]{
-				0xfc9da860d048b449UL,
-				0x2fca66479fa7d833UL,
-				0xb33bc3896656840fUL,
-				0x6a54e920fde8da69UL});
-
-			InitialState(SKEIN_512, 128, new ulong[]{
-				0xa8bc7bf36fbf9f52UL,
-				0x1e9872cebd1af0aaUL,
-				0x309b1790b32190d3UL,
-				0xbcfbb8543f94805cUL,
-				0x0da61bcd6e31b11bUL,
-				0x1a18ebead46a32e3UL,
-				0xa2cc5b18ce84aa82UL,
-				0x6982ab289d46982dUL});
-
-			InitialState(SKEIN_512, 160, new ulong[]{
-				0x28b81a2ae013bd91UL,
-				0xc2f11668b5bdf78fUL,
-				0x1760d8f3f6a56f12UL,
-				0x4fb747588239904fUL,
-				0x21ede07f7eaf5056UL,
-				0xd908922e63ed70b8UL,
-				0xb8ec76ffeccb52faUL,
-				0x01a47bb8a3f27a6eUL});
-
-			InitialState(SKEIN_512, 224, new ulong[]{
-				0xccd0616248677224UL,
-				0xcba65cf3a92339efUL,
-				0x8ccd69d652ff4b64UL,
-				0x398aed7b3ab890b4UL,
-				0x0f59d1b1457d2bd0UL,
-				0x6776fe6575d4eb3dUL,
-				0x99fbc70e997413e9UL,
-				0x9e2cfccfe1c41ef7UL});
-
-			InitialState(SKEIN_512, 384, new ulong[]{
-				0xa3f6c6bf3a75ef5fUL,
-				0xb0fef9ccfd84faa4UL,
-				0x9d77dd663d770cfeUL,
-				0xd798cbf3b468fddaUL,
-				0x1bc4a6668a0e4465UL,
-				0x7ed7d434e5807407UL,
-				0x548fc1acd4ec44d6UL,
-				0x266e17546aa18ff8UL});
-
-			InitialState(SKEIN_512, 512, new ulong[]{
-				0x4903adff749c51ceUL,
-				0x0d95de399746df03UL,
-				0x8fd1934127c79bceUL,
-				0x9a255629ff352cb1UL,
-				0x5db62599df6ca7b0UL,
-				0xeabe394ca9d5c3f4UL,
-				0x991112c71a75b523UL,
-				0xae18a40b660fcc33UL});
-		}
-
-		private static void InitialState(int blockSize, int outputSize, ulong[] state)
-		{
-			INITIAL_STATES.Add(VariantIdentifier(blockSize / 8, outputSize / 8), state);
-		}
-
-		private static int VariantIdentifier(int blockSizeBytes, int outputSizeBytes)
-		{
-			return (outputSizeBytes << 16) | blockSizeBytes;
-		}
-
-		private class UbiTweak
-		{
-			/**
-	         * Point at which position might overflow long, so switch to add with carry logic
-	         */
-			private const ulong LOW_RANGE = UInt64.MaxValue - UInt32.MaxValue;
-
-			/**
-	         * Bit 127 = final
-	         */
-			private const ulong T1_FINAL = 1UL << 63;
-
-			/**
-	         * Bit 126 = first
-	         */
-			private const ulong T1_FIRST = 1UL << 62;
-
-			/**
-	         * UBI uses a 128 bit tweak
-	         */
-			private ulong[] tweak = new ulong[2];
-
-			/**
-	         * Whether 64 bit position exceeded
-	         */
-			private bool extendedPosition;
-
-			public UbiTweak()
-			{
-				Reset();
-			}
-
-			public void Reset(UbiTweak tweak)
-			{
-				this.tweak = Arrays.Clone(tweak.tweak, this.tweak);
-				this.extendedPosition = tweak.extendedPosition;
-			}
-
-			public void Reset()
-			{
-				tweak[0] = 0;
-				tweak[1] = 0;
-				extendedPosition = false;
-				First = true;
-			}
-
-			public uint Type 
-			{
-				get 
-				{
-					return (uint)((tweak[1] >> 56) & 0x3FUL);
-				}
-
-				set 
-				{
-					// Bits 120..125 = type
-					tweak[1] = (tweak[1] & 0xFFFFFFC000000000UL) | ((value & 0x3FUL) << 56);
-				}
-			}
-
-			public bool First
-			{
-				get
-				{
-					return ((tweak[1] & T1_FIRST) != 0);
-				}
-				set
-				{
-					if (value)
-					{
-						tweak[1] |= T1_FIRST;
-					}
-					else
-					{
-						tweak[1] &= ~T1_FIRST;
-					}
-				}
-			}
-
-			public bool Final
-			{
-				get
-				{
-					return ((tweak[1] & T1_FINAL) != 0);
-				}
-				set
-				{
-					if (value)
-					{
-						tweak[1] |= T1_FINAL;
-					}
-					else
-					{
-						tweak[1] &= ~T1_FINAL;
-					}
-				}
-			}
-
-			/**
-	         * Advances the position in the tweak by the specified value.
-	         */
-			public void AdvancePosition(int advance)
-			{
-				// Bits 0..95 = position
-				if (extendedPosition)
-				{
-					ulong[] parts = new ulong[3];
-					parts[0] = tweak[0] & 0xFFFFFFFFUL;
-					parts[1] = (tweak[0] >> 32) & 0xFFFFFFFFUL;
-					parts[2] = tweak[1] & 0xFFFFFFFFUL;
-
-					ulong carry = (ulong)advance;
-					for (int i = 0; i < parts.Length; i++)
-					{
-						carry += parts[i];
-						parts[i] = carry;
-						carry >>= 32;
-					}
-					tweak[0] = ((parts[1] & 0xFFFFFFFFUL) << 32) | (parts[0] & 0xFFFFFFFFUL);
-					tweak[1] = (tweak[1] & 0xFFFFFFFF00000000UL) | (parts[2] & 0xFFFFFFFFUL);
-				}
-				else
-				{
-					ulong position = tweak[0];
-					position += (uint)advance;
-					tweak[0] = position;
-					if (position > LOW_RANGE)
-					{
-						extendedPosition = true;
-					}
-				}
-			}
-
-			public ulong[] GetWords()
-			{
-				return tweak;
-			}
-
-			public override string ToString()
-			{
-				return Type + " first: " + First + ", final: " + Final;
-			}
-
-		}
-
-		/**
-	     * The Unique Block Iteration chaining mode.
-	     */
-		// TODO: This might be better as methods...
-		private class UBI
-		{
-			private readonly UbiTweak tweak = new UbiTweak();
-
-			private readonly SkeinEngine engine;
-
-			/**
-	         * Buffer for the current block of message data
-	         */
-			private byte[] currentBlock;
-
-			/**
-	         * Offset into the current message block
-	         */
-			private int currentOffset;
-
-			/**
-	         * Buffer for message words for feedback into encrypted block
-	         */
-			private ulong[] message;
-
-			public UBI(SkeinEngine engine, int blockSize)
-			{
-				this.engine = engine;
-				currentBlock = new byte[blockSize];
-				message = new ulong[currentBlock.Length / 8];
-			}
-
-			public void Reset(UBI ubi)
-			{
-				currentBlock = Arrays.Clone(ubi.currentBlock, currentBlock);
-				currentOffset = ubi.currentOffset;
-				message = Arrays.Clone(ubi.message, this.message);
-				tweak.Reset(ubi.tweak);
-			}
-
-			public void Reset(int type)
-			{
-				tweak.Reset();
-				tweak.Type = (uint)type;
-				currentOffset = 0;
-			}
-
-			public void Update(byte[] value, int offset, int len, ulong[] output)
-			{
-				/*
-	             * Buffer complete blocks for the underlying Threefish cipher, only flushing when there
-	             * are subsequent bytes (last block must be processed in doFinal() with final=true set).
-	             */
-				int copied = 0;
-				while (len > copied)
-				{
-					if (currentOffset == currentBlock.Length)
-					{
-						ProcessBlock(output);
-						tweak.First = false;
-						currentOffset = 0;
-					}
-
-					int toCopy = System.Math.Min((len - copied), currentBlock.Length - currentOffset);
-					Array.Copy(value, offset + copied, currentBlock, currentOffset, toCopy);
-					copied += toCopy;
-					currentOffset += toCopy;
-					tweak.AdvancePosition(toCopy);
-				}
-			}
-
-			private void ProcessBlock(ulong[] output)
-			{
-				engine.threefish.Init(true, engine.chain, tweak.GetWords());
-				for (int i = 0; i < message.Length; i++)
-				{
-					message[i] = ThreefishEngine.BytesToWord(currentBlock, i * 8);
-				}
-
-				engine.threefish.ProcessBlock(message, output);
-
-				for (int i = 0; i < output.Length; i++)
-				{
-					output[i] ^= message[i];
-				}
-			}
-
-			public void DoFinal(ulong[] output)
-			{
-				// Pad remainder of current block with zeroes
-				for (int i = currentOffset; i < currentBlock.Length; i++)
-				{
-					currentBlock[i] = 0;
-				}
-
-				tweak.Final = true;
-				ProcessBlock(output);
-			}
-
-		}
-
-		/**
-	     * Underlying Threefish tweakable block cipher
-	     */
-		private readonly ThreefishEngine threefish;
-
-		/**
-	     * Size of the digest output, in bytes
-	     */
-		private readonly int outputSizeBytes;
-
-		/**
-	     * The current chaining/state value
-	     */
-		private ulong[] chain;
-
-		/**
-	     * The initial state value
-	     */
-		private ulong[] initialState;
-
-		/**
-	     * The (optional) key parameter
-	     */
-		private byte[] key;
-
-		/**
-	     * Parameters to apply prior to the message
-	     */
-		private Parameter[] preMessageParameters;
-
-		/**
-	     * Parameters to apply after the message, but prior to output
-	     */
-		private Parameter[] postMessageParameters;
-
-		/**
-	     * The current UBI operation
-	     */
-		private readonly UBI ubi;
-
-		/**
-	     * Buffer for single byte update method
-	     */
-		private readonly byte[] singleByte = new byte[1];
-
-		/// <summary>
-		/// Constructs a Skein digest with an internal state size and output size.
-		/// </summary>
-		/// <param name="stateSizeBits">the internal state size in bits - one of <see cref="SKEIN_256"/> <see cref="SKEIN_512"/> or
-		///                       <see cref="SKEIN_1024"/>.</param>
-		/// <param name="outputSizeBits">the output/digest size to produce in bits, which must be an integral number of
-		///                      bytes.</param>
-		public SkeinEngine(int blockSizeBits, int outputSizeBits)
-		{
-			if (outputSizeBits % 8 != 0)
-			{
-				throw new ArgumentException("Output size must be a multiple of 8 bits. :" + outputSizeBits);
-			}
-			// TODO: Prevent digest sizes > block size?
-			this.outputSizeBytes = outputSizeBits / 8;
-
-			this.threefish = new ThreefishEngine(blockSizeBits);
-			this.ubi = new UBI(this,threefish.GetBlockSize());
-		}
-
-		/// <summary>
-		/// Creates a SkeinEngine as an exact copy of an existing instance.
-		/// </summary>
-		public SkeinEngine(SkeinEngine engine)
-			: this(engine.BlockSize * 8, engine.OutputSize * 8)
-		{
-			CopyIn(engine);
-		}
-
-		private void CopyIn(SkeinEngine engine)
-		{
-			this.ubi.Reset(engine.ubi);
-			this.chain = Arrays.Clone(engine.chain, this.chain);
-			this.initialState = Arrays.Clone(engine.initialState, this.initialState);
-			this.key = Arrays.Clone(engine.key, this.key);
-			this.preMessageParameters = Clone(engine.preMessageParameters, this.preMessageParameters);
-			this.postMessageParameters = Clone(engine.postMessageParameters, this.postMessageParameters);
-		}
-
-		private static Parameter[] Clone(Parameter[] data, Parameter[] existing)
-		{
-			if (data == null)
-			{
-				return null;
-			}
-			if ((existing == null) || (existing.Length != data.Length))
-			{
-				existing = new Parameter[data.Length];
-			}
-			Array.Copy(data, 0, existing, 0, existing.Length);
-			return existing;
-		}
-
-		public IMemoable Copy()
-		{
-			return new SkeinEngine(this);
-		}
-
-		public void Reset(IMemoable other)
-		{
-			SkeinEngine s = (SkeinEngine)other;
-			if ((BlockSize != s.BlockSize) || (outputSizeBytes != s.outputSizeBytes))
-			{
-				throw new MemoableResetException("Incompatible parameters in provided SkeinEngine.");
-			}
-			CopyIn(s);
-		}
-
-		public int OutputSize
-		{
-			get { return outputSizeBytes; }
-		}
-
-		public int BlockSize
-		{
-			get { return threefish.GetBlockSize (); }
-		}
-
-		/// <summary>
-		/// Initialises the Skein engine with the provided parameters. See <see cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> for
-		/// details on the parameterisation of the Skein hash function.
-		/// </summary>
-		/// <param name="parameters">the parameters to apply to this engine, or <code>null</code> to use no parameters.</param>
-		public void Init(SkeinParameters parameters)
-		{
-			this.chain = null;
-			this.key = null;
-			this.preMessageParameters = null;
-			this.postMessageParameters = null;
-
-			if (parameters != null)
-			{
-				byte[] key = parameters.GetKey();
-				if (key.Length < 16)
-				{
-					throw new ArgumentException("Skein key must be at least 128 bits.");
-				}
-				InitParams(parameters.GetParameters());
-			}
-			CreateInitialState();
-
-			// Initialise message block
-			UbiInit(PARAM_TYPE_MESSAGE);
-		}
-
-		private void InitParams(IDictionary parameters)
-		{
-			IEnumerator keys = parameters.Keys.GetEnumerator();
-			IList pre = Platform.CreateArrayList();
-			IList post = Platform.CreateArrayList();
-
-			while (keys.MoveNext())
-			{
-				int type = (int)keys.Current;
-				byte[] value = (byte[])parameters[type];
-
-				if (type == PARAM_TYPE_KEY)
-				{
-					this.key = value;
-				}
-				else if (type < PARAM_TYPE_MESSAGE)
-				{
-					pre.Add(new Parameter(type, value));
-				}
-				else
-				{
-					post.Add(new Parameter(type, value));
-				}
-			}
-			preMessageParameters = new Parameter[pre.Count];
-			pre.CopyTo(preMessageParameters, 0);
-			Array.Sort(preMessageParameters);
-
-			postMessageParameters = new Parameter[post.Count];
-			post.CopyTo(postMessageParameters, 0);
-			Array.Sort(postMessageParameters);
-		}
-
-		/**
-	     * Calculate the initial (pre message block) chaining state.
-	     */
-		private void CreateInitialState()
-		{
-			ulong[] precalc = (ulong[])INITIAL_STATES[VariantIdentifier(BlockSize, OutputSize)];
-			if ((key == null) && (precalc != null))
-			{
-				// Precalculated UBI(CFG)
-				chain = Arrays.Clone(precalc);
-			}
-			else
-			{
-				// Blank initial state
-				chain = new ulong[BlockSize / 8];
-
-				// Process key block
-				if (key != null)
-				{
-					UbiComplete(SkeinParameters.PARAM_TYPE_KEY, key);
-				}
-
-				// Process configuration block
-				UbiComplete(PARAM_TYPE_CONFIG, new Configuration(outputSizeBytes * 8).Bytes);
-			}
-
-			// Process additional pre-message parameters
-			if (preMessageParameters != null)
-			{
-				for (int i = 0; i < preMessageParameters.Length; i++)
-				{
-					Parameter param = preMessageParameters[i];
-					UbiComplete(param.Type, param.Value);
-				}
-			}
-			initialState = Arrays.Clone(chain);
-		}
-
-		/// <summary>
-		/// Reset the engine to the initial state (with the key and any pre-message parameters , ready to
-		/// accept message input.
-		/// </summary>
-		public void Reset()
-		{
-			Array.Copy(initialState, 0, chain, 0, chain.Length);
-
-			UbiInit(PARAM_TYPE_MESSAGE);
-		}
-
-		private void UbiComplete(int type, byte[] value)
-		{
-			UbiInit(type);
-			this.ubi.Update(value, 0, value.Length, chain);
-			UbiFinal();
-		}
-
-		private void UbiInit(int type)
-		{
-			this.ubi.Reset(type);
-		}
-
-		private void UbiFinal()
-		{
-			ubi.DoFinal(chain);
-		}
-
-		private void CheckInitialised()
-		{
-			if (this.ubi == null)
-			{
-				throw new ArgumentException("Skein engine is not initialised.");
-			}
-		}
-
-		public void Update(byte inByte)
-		{
-			singleByte[0] = inByte;
-			Update(singleByte, 0, 1);
-		}
-
-		public void Update(byte[] inBytes, int inOff, int len)
-		{
-			CheckInitialised();
-			ubi.Update(inBytes, inOff, len, chain);
-		}
-
-		public int DoFinal(byte[] outBytes, int outOff)
-		{
-			CheckInitialised();
-			if (outBytes.Length < (outOff + outputSizeBytes))
-			{
-				throw new DataLengthException("Output buffer is too short to hold output of " + outputSizeBytes + " bytes");
-			}
-
-			// Finalise message block
-			UbiFinal();
-
-			// Process additional post-message parameters
-			if (postMessageParameters != null)
-			{
-				for (int i = 0; i < postMessageParameters.Length; i++)
-				{
-					Parameter param = postMessageParameters[i];
-					UbiComplete(param.Type, param.Value);
-				}
-			}
-
-			// Perform the output transform
-			int blockSize = BlockSize;
-			int blocksRequired = ((outputSizeBytes + blockSize - 1) / blockSize);
-			for (int i = 0; i < blocksRequired; i++)
-			{
-				int toWrite = System.Math.Min(blockSize, outputSizeBytes - (i * blockSize));
-				Output((ulong)i, outBytes, outOff + (i * blockSize), toWrite);
-			}
-
-			Reset();
-
-			return outputSizeBytes;
-		}
-
-		private void Output(ulong outputSequence, byte[] outBytes, int outOff, int outputBytes)
-		{
-			byte[] currentBytes = new byte[8];
-			ThreefishEngine.WordToBytes(outputSequence, currentBytes, 0);
-
-			// Output is a sequence of UBI invocations all of which use and preserve the pre-output
-			// state
-			ulong[] outputWords = new ulong[chain.Length];
-			UbiInit(PARAM_TYPE_OUTPUT);
-			this.ubi.Update(currentBytes, 0, currentBytes.Length, outputWords);
-			ubi.DoFinal(outputWords);
-
-			int wordsRequired = ((outputBytes + 8 - 1) / 8);
-			for (int i = 0; i < wordsRequired; i++)
-			{
-				int toWrite = System.Math.Min(8, outputBytes - (i * 8));
-				if (toWrite == 8)
-				{
-					ThreefishEngine.WordToBytes(outputWords[i], outBytes, outOff + (i * 8));
-				}
-				else
-				{
-					ThreefishEngine.WordToBytes(outputWords[i], currentBytes, 0);
-					Array.Copy(currentBytes, 0, outBytes, outOff + (i * 8), toWrite);
-				}
-			}
-		}
-
-	}
+    /// <summary>
+    /// Implementation of the Skein family of parameterised hash functions in 256, 512 and 1024 bit block
+    /// sizes, based on the <see cref="Org.BouncyCastle.Crypto.Engines.ThreefishEngine">Threefish</see> tweakable block cipher.
+    /// </summary>
+    /// <remarks>
+    /// This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3
+    /// competition in October 2010.
+    /// <p/>
+    /// Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir
+    /// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker.
+    /// <p/>
+    /// This implementation is the basis for <see cref="Org.BouncyCastle.Crypto.Digests.SkeinDigest"/> and <see cref="Org.BouncyCastle.Crypto.Macs.SkeinMac"/>, implementing the
+    /// parameter based configuration system that allows Skein to be adapted to multiple applications. <br/>
+    /// Initialising the engine with <see cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> allows standard and arbitrary parameters to
+    /// be applied during the Skein hash function.
+    /// <p/>
+    /// Implemented:
+    /// <ul>
+    /// <li>256, 512 and 1024 bit internal states.</li>
+    /// <li>Full 96 bit input length.</li>
+    /// <li>Parameters defined in the Skein specification, and arbitrary other pre and post message
+    /// parameters.</li>
+    /// <li>Arbitrary output size in 1 byte intervals.</li>
+    /// </ul>
+    /// <p/>
+    /// Not implemented:
+    /// <ul>
+    /// <li>Sub-byte length input (bit padding).</li>
+    /// <li>Tree hashing.</li>
+    /// </ul>
+    /// </remarks>
+    /// <seealso cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/>
+    public class SkeinEngine
+        : IMemoable
+    {
+        /// <summary>
+        /// 256 bit block size - Skein-256
+        /// </summary>
+        public const int SKEIN_256 = ThreefishEngine.BLOCKSIZE_256;
+        /// <summary>
+        /// 512 bit block size - Skein-512
+        /// </summary>
+        public const int SKEIN_512 = ThreefishEngine.BLOCKSIZE_512;
+        /// <summary>
+        /// 1024 bit block size - Skein-1024
+        /// </summary>
+        public const int SKEIN_1024 = ThreefishEngine.BLOCKSIZE_1024;
+
+        // Minimal at present, but more complex when tree hashing is implemented
+        private class Configuration
+        {
+            private byte[] bytes = new byte[32];
+
+            public Configuration(long outputSizeBits)
+            {
+                // 0..3 = ASCII SHA3
+                bytes[0] = (byte)'S';
+                bytes[1] = (byte)'H';
+                bytes[2] = (byte)'A';
+                bytes[3] = (byte)'3';
+
+                // 4..5 = version number in LSB order
+                bytes[4] = 1;
+                bytes[5] = 0;
+
+                // 8..15 = output length
+                ThreefishEngine.WordToBytes((ulong)outputSizeBits, bytes, 8);
+            }
+
+            public byte[] Bytes
+            {
+                get { return bytes; }
+            }
+
+        }
+
+        public class Parameter
+        {
+            private int type;
+            private byte[] value;
+
+            public Parameter(int type, byte[] value)
+            {
+                this.type = type;
+                this.value = value;
+            }
+
+            public int Type
+            {
+                get { return type; }
+            }
+
+            public byte[] Value
+            {
+                get { return value; }
+            }
+
+        }
+
+        /**
+         * The parameter type for the Skein key.
+         */
+        private const int PARAM_TYPE_KEY = 0;
+
+        /**
+         * The parameter type for the Skein configuration block.
+         */
+        private const int PARAM_TYPE_CONFIG = 4;
+
+        /**
+         * The parameter type for the message.
+         */
+        private const int PARAM_TYPE_MESSAGE = 48;
+
+        /**
+         * The parameter type for the output transformation.
+         */
+        private const int PARAM_TYPE_OUTPUT = 63;
+
+        /**
+         * Precalculated UBI(CFG) states for common state/output combinations without key or other
+         * pre-message params.
+         */
+        private static readonly IDictionary INITIAL_STATES = Platform.CreateHashtable();
+
+        static SkeinEngine()
+        {
+            // From Appendix C of the Skein 1.3 NIST submission
+            InitialState(SKEIN_256, 128, new ulong[]{
+                0xe1111906964d7260UL,
+                0x883daaa77c8d811cUL,
+                0x10080df491960f7aUL,
+                0xccf7dde5b45bc1c2UL});
+
+            InitialState(SKEIN_256, 160, new ulong[]{
+                0x1420231472825e98UL,
+                0x2ac4e9a25a77e590UL,
+                0xd47a58568838d63eUL,
+                0x2dd2e4968586ab7dUL});
+
+            InitialState(SKEIN_256, 224, new ulong[]{
+                0xc6098a8c9ae5ea0bUL,
+                0x876d568608c5191cUL,
+                0x99cb88d7d7f53884UL,
+                0x384bddb1aeddb5deUL});
+
+            InitialState(SKEIN_256, 256, new ulong[]{
+                0xfc9da860d048b449UL,
+                0x2fca66479fa7d833UL,
+                0xb33bc3896656840fUL,
+                0x6a54e920fde8da69UL});
+
+            InitialState(SKEIN_512, 128, new ulong[]{
+                0xa8bc7bf36fbf9f52UL,
+                0x1e9872cebd1af0aaUL,
+                0x309b1790b32190d3UL,
+                0xbcfbb8543f94805cUL,
+                0x0da61bcd6e31b11bUL,
+                0x1a18ebead46a32e3UL,
+                0xa2cc5b18ce84aa82UL,
+                0x6982ab289d46982dUL});
+
+            InitialState(SKEIN_512, 160, new ulong[]{
+                0x28b81a2ae013bd91UL,
+                0xc2f11668b5bdf78fUL,
+                0x1760d8f3f6a56f12UL,
+                0x4fb747588239904fUL,
+                0x21ede07f7eaf5056UL,
+                0xd908922e63ed70b8UL,
+                0xb8ec76ffeccb52faUL,
+                0x01a47bb8a3f27a6eUL});
+
+            InitialState(SKEIN_512, 224, new ulong[]{
+                0xccd0616248677224UL,
+                0xcba65cf3a92339efUL,
+                0x8ccd69d652ff4b64UL,
+                0x398aed7b3ab890b4UL,
+                0x0f59d1b1457d2bd0UL,
+                0x6776fe6575d4eb3dUL,
+                0x99fbc70e997413e9UL,
+                0x9e2cfccfe1c41ef7UL});
+
+            InitialState(SKEIN_512, 384, new ulong[]{
+                0xa3f6c6bf3a75ef5fUL,
+                0xb0fef9ccfd84faa4UL,
+                0x9d77dd663d770cfeUL,
+                0xd798cbf3b468fddaUL,
+                0x1bc4a6668a0e4465UL,
+                0x7ed7d434e5807407UL,
+                0x548fc1acd4ec44d6UL,
+                0x266e17546aa18ff8UL});
+
+            InitialState(SKEIN_512, 512, new ulong[]{
+                0x4903adff749c51ceUL,
+                0x0d95de399746df03UL,
+                0x8fd1934127c79bceUL,
+                0x9a255629ff352cb1UL,
+                0x5db62599df6ca7b0UL,
+                0xeabe394ca9d5c3f4UL,
+                0x991112c71a75b523UL,
+                0xae18a40b660fcc33UL});
+        }
+
+        private static void InitialState(int blockSize, int outputSize, ulong[] state)
+        {
+            INITIAL_STATES.Add(VariantIdentifier(blockSize / 8, outputSize / 8), state);
+        }
+
+        private static int VariantIdentifier(int blockSizeBytes, int outputSizeBytes)
+        {
+            return (outputSizeBytes << 16) | blockSizeBytes;
+        }
+
+        private class UbiTweak
+        {
+            /**
+             * Point at which position might overflow long, so switch to add with carry logic
+             */
+            private const ulong LOW_RANGE = UInt64.MaxValue - UInt32.MaxValue;
+
+            /**
+             * Bit 127 = final
+             */
+            private const ulong T1_FINAL = 1UL << 63;
+
+            /**
+             * Bit 126 = first
+             */
+            private const ulong T1_FIRST = 1UL << 62;
+
+            /**
+             * UBI uses a 128 bit tweak
+             */
+            private ulong[] tweak = new ulong[2];
+
+            /**
+             * Whether 64 bit position exceeded
+             */
+            private bool extendedPosition;
+
+            public UbiTweak()
+            {
+                Reset();
+            }
+
+            public void Reset(UbiTweak tweak)
+            {
+                this.tweak = Arrays.Clone(tweak.tweak, this.tweak);
+                this.extendedPosition = tweak.extendedPosition;
+            }
+
+            public void Reset()
+            {
+                tweak[0] = 0;
+                tweak[1] = 0;
+                extendedPosition = false;
+                First = true;
+            }
+
+            public uint Type 
+            {
+                get 
+                {
+                    return (uint)((tweak[1] >> 56) & 0x3FUL);
+                }
+
+                set 
+                {
+                    // Bits 120..125 = type
+                    tweak[1] = (tweak[1] & 0xFFFFFFC000000000UL) | ((value & 0x3FUL) << 56);
+                }
+            }
+
+            public bool First
+            {
+                get
+                {
+                    return ((tweak[1] & T1_FIRST) != 0);
+                }
+                set
+                {
+                    if (value)
+                    {
+                        tweak[1] |= T1_FIRST;
+                    }
+                    else
+                    {
+                        tweak[1] &= ~T1_FIRST;
+                    }
+                }
+            }
+
+            public bool Final
+            {
+                get
+                {
+                    return ((tweak[1] & T1_FINAL) != 0);
+                }
+                set
+                {
+                    if (value)
+                    {
+                        tweak[1] |= T1_FINAL;
+                    }
+                    else
+                    {
+                        tweak[1] &= ~T1_FINAL;
+                    }
+                }
+            }
+
+            /**
+             * Advances the position in the tweak by the specified value.
+             */
+            public void AdvancePosition(int advance)
+            {
+                // Bits 0..95 = position
+                if (extendedPosition)
+                {
+                    ulong[] parts = new ulong[3];
+                    parts[0] = tweak[0] & 0xFFFFFFFFUL;
+                    parts[1] = (tweak[0] >> 32) & 0xFFFFFFFFUL;
+                    parts[2] = tweak[1] & 0xFFFFFFFFUL;
+
+                    ulong carry = (ulong)advance;
+                    for (int i = 0; i < parts.Length; i++)
+                    {
+                        carry += parts[i];
+                        parts[i] = carry;
+                        carry >>= 32;
+                    }
+                    tweak[0] = ((parts[1] & 0xFFFFFFFFUL) << 32) | (parts[0] & 0xFFFFFFFFUL);
+                    tweak[1] = (tweak[1] & 0xFFFFFFFF00000000UL) | (parts[2] & 0xFFFFFFFFUL);
+                }
+                else
+                {
+                    ulong position = tweak[0];
+                    position += (uint)advance;
+                    tweak[0] = position;
+                    if (position > LOW_RANGE)
+                    {
+                        extendedPosition = true;
+                    }
+                }
+            }
+
+            public ulong[] GetWords()
+            {
+                return tweak;
+            }
+
+            public override string ToString()
+            {
+                return Type + " first: " + First + ", final: " + Final;
+            }
+
+        }
+
+        /**
+         * The Unique Block Iteration chaining mode.
+         */
+        // TODO: This might be better as methods...
+        private class UBI
+        {
+            private readonly UbiTweak tweak = new UbiTweak();
+
+            private readonly SkeinEngine engine;
+
+            /**
+             * Buffer for the current block of message data
+             */
+            private byte[] currentBlock;
+
+            /**
+             * Offset into the current message block
+             */
+            private int currentOffset;
+
+            /**
+             * Buffer for message words for feedback into encrypted block
+             */
+            private ulong[] message;
+
+            public UBI(SkeinEngine engine, int blockSize)
+            {
+                this.engine = engine;
+                currentBlock = new byte[blockSize];
+                message = new ulong[currentBlock.Length / 8];
+            }
+
+            public void Reset(UBI ubi)
+            {
+                currentBlock = Arrays.Clone(ubi.currentBlock, currentBlock);
+                currentOffset = ubi.currentOffset;
+                message = Arrays.Clone(ubi.message, this.message);
+                tweak.Reset(ubi.tweak);
+            }
+
+            public void Reset(int type)
+            {
+                tweak.Reset();
+                tweak.Type = (uint)type;
+                currentOffset = 0;
+            }
+
+            public void Update(byte[] value, int offset, int len, ulong[] output)
+            {
+                /*
+                 * Buffer complete blocks for the underlying Threefish cipher, only flushing when there
+                 * are subsequent bytes (last block must be processed in doFinal() with final=true set).
+                 */
+                int copied = 0;
+                while (len > copied)
+                {
+                    if (currentOffset == currentBlock.Length)
+                    {
+                        ProcessBlock(output);
+                        tweak.First = false;
+                        currentOffset = 0;
+                    }
+
+                    int toCopy = System.Math.Min((len - copied), currentBlock.Length - currentOffset);
+                    Array.Copy(value, offset + copied, currentBlock, currentOffset, toCopy);
+                    copied += toCopy;
+                    currentOffset += toCopy;
+                    tweak.AdvancePosition(toCopy);
+                }
+            }
+
+            private void ProcessBlock(ulong[] output)
+            {
+                engine.threefish.Init(true, engine.chain, tweak.GetWords());
+                for (int i = 0; i < message.Length; i++)
+                {
+                    message[i] = ThreefishEngine.BytesToWord(currentBlock, i * 8);
+                }
+
+                engine.threefish.ProcessBlock(message, output);
+
+                for (int i = 0; i < output.Length; i++)
+                {
+                    output[i] ^= message[i];
+                }
+            }
+
+            public void DoFinal(ulong[] output)
+            {
+                // Pad remainder of current block with zeroes
+                for (int i = currentOffset; i < currentBlock.Length; i++)
+                {
+                    currentBlock[i] = 0;
+                }
+
+                tweak.Final = true;
+                ProcessBlock(output);
+            }
+
+        }
+
+        /**
+         * Underlying Threefish tweakable block cipher
+         */
+        private readonly ThreefishEngine threefish;
+
+        /**
+         * Size of the digest output, in bytes
+         */
+        private readonly int outputSizeBytes;
+
+        /**
+         * The current chaining/state value
+         */
+        private ulong[] chain;
+
+        /**
+         * The initial state value
+         */
+        private ulong[] initialState;
+
+        /**
+         * The (optional) key parameter
+         */
+        private byte[] key;
+
+        /**
+         * Parameters to apply prior to the message
+         */
+        private Parameter[] preMessageParameters;
+
+        /**
+         * Parameters to apply after the message, but prior to output
+         */
+        private Parameter[] postMessageParameters;
+
+        /**
+         * The current UBI operation
+         */
+        private readonly UBI ubi;
+
+        /**
+         * Buffer for single byte update method
+         */
+        private readonly byte[] singleByte = new byte[1];
+
+        /// <summary>
+        /// Constructs a Skein digest with an internal state size and output size.
+        /// </summary>
+        /// <param name="blockSizeBits">the internal state size in bits - one of <see cref="SKEIN_256"/> <see cref="SKEIN_512"/> or
+        ///                       <see cref="SKEIN_1024"/>.</param>
+        /// <param name="outputSizeBits">the output/digest size to produce in bits, which must be an integral number of
+        ///                      bytes.</param>
+        public SkeinEngine(int blockSizeBits, int outputSizeBits)
+        {
+            if (outputSizeBits % 8 != 0)
+            {
+                throw new ArgumentException("Output size must be a multiple of 8 bits. :" + outputSizeBits);
+            }
+            // TODO: Prevent digest sizes > block size?
+            this.outputSizeBytes = outputSizeBits / 8;
+
+            this.threefish = new ThreefishEngine(blockSizeBits);
+            this.ubi = new UBI(this,threefish.GetBlockSize());
+        }
+
+        /// <summary>
+        /// Creates a SkeinEngine as an exact copy of an existing instance.
+        /// </summary>
+        public SkeinEngine(SkeinEngine engine)
+            : this(engine.BlockSize * 8, engine.OutputSize * 8)
+        {
+            CopyIn(engine);
+        }
+
+        private void CopyIn(SkeinEngine engine)
+        {
+            this.ubi.Reset(engine.ubi);
+            this.chain = Arrays.Clone(engine.chain, this.chain);
+            this.initialState = Arrays.Clone(engine.initialState, this.initialState);
+            this.key = Arrays.Clone(engine.key, this.key);
+            this.preMessageParameters = Clone(engine.preMessageParameters, this.preMessageParameters);
+            this.postMessageParameters = Clone(engine.postMessageParameters, this.postMessageParameters);
+        }
+
+        private static Parameter[] Clone(Parameter[] data, Parameter[] existing)
+        {
+            if (data == null)
+            {
+                return null;
+            }
+            if ((existing == null) || (existing.Length != data.Length))
+            {
+                existing = new Parameter[data.Length];
+            }
+            Array.Copy(data, 0, existing, 0, existing.Length);
+            return existing;
+        }
+
+        public IMemoable Copy()
+        {
+            return new SkeinEngine(this);
+        }
+
+        public void Reset(IMemoable other)
+        {
+            SkeinEngine s = (SkeinEngine)other;
+            if ((BlockSize != s.BlockSize) || (outputSizeBytes != s.outputSizeBytes))
+            {
+                throw new MemoableResetException("Incompatible parameters in provided SkeinEngine.");
+            }
+            CopyIn(s);
+        }
+
+        public int OutputSize
+        {
+            get { return outputSizeBytes; }
+        }
+
+        public int BlockSize
+        {
+            get { return threefish.GetBlockSize (); }
+        }
+
+        /// <summary>
+        /// Initialises the Skein engine with the provided parameters. See <see cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> for
+        /// details on the parameterisation of the Skein hash function.
+        /// </summary>
+        /// <param name="parameters">the parameters to apply to this engine, or <code>null</code> to use no parameters.</param>
+        public void Init(SkeinParameters parameters)
+        {
+            this.chain = null;
+            this.key = null;
+            this.preMessageParameters = null;
+            this.postMessageParameters = null;
+
+            if (parameters != null)
+            {
+                byte[] key = parameters.GetKey();
+                if (key.Length < 16)
+                {
+                    throw new ArgumentException("Skein key must be at least 128 bits.");
+                }
+                InitParams(parameters.GetParameters());
+            }
+            CreateInitialState();
+
+            // Initialise message block
+            UbiInit(PARAM_TYPE_MESSAGE);
+        }
+
+        private void InitParams(IDictionary parameters)
+        {
+            IEnumerator keys = parameters.Keys.GetEnumerator();
+            IList pre = Platform.CreateArrayList();
+            IList post = Platform.CreateArrayList();
+
+            while (keys.MoveNext())
+            {
+                int type = (int)keys.Current;
+                byte[] value = (byte[])parameters[type];
+
+                if (type == PARAM_TYPE_KEY)
+                {
+                    this.key = value;
+                }
+                else if (type < PARAM_TYPE_MESSAGE)
+                {
+                    pre.Add(new Parameter(type, value));
+                }
+                else
+                {
+                    post.Add(new Parameter(type, value));
+                }
+            }
+            preMessageParameters = new Parameter[pre.Count];
+            pre.CopyTo(preMessageParameters, 0);
+            Array.Sort(preMessageParameters);
+
+            postMessageParameters = new Parameter[post.Count];
+            post.CopyTo(postMessageParameters, 0);
+            Array.Sort(postMessageParameters);
+        }
+
+        /**
+         * Calculate the initial (pre message block) chaining state.
+         */
+        private void CreateInitialState()
+        {
+            ulong[] precalc = (ulong[])INITIAL_STATES[VariantIdentifier(BlockSize, OutputSize)];
+            if ((key == null) && (precalc != null))
+            {
+                // Precalculated UBI(CFG)
+                chain = Arrays.Clone(precalc);
+            }
+            else
+            {
+                // Blank initial state
+                chain = new ulong[BlockSize / 8];
+
+                // Process key block
+                if (key != null)
+                {
+                    UbiComplete(SkeinParameters.PARAM_TYPE_KEY, key);
+                }
+
+                // Process configuration block
+                UbiComplete(PARAM_TYPE_CONFIG, new Configuration(outputSizeBytes * 8).Bytes);
+            }
+
+            // Process additional pre-message parameters
+            if (preMessageParameters != null)
+            {
+                for (int i = 0; i < preMessageParameters.Length; i++)
+                {
+                    Parameter param = preMessageParameters[i];
+                    UbiComplete(param.Type, param.Value);
+                }
+            }
+            initialState = Arrays.Clone(chain);
+        }
+
+        /// <summary>
+        /// Reset the engine to the initial state (with the key and any pre-message parameters , ready to
+        /// accept message input.
+        /// </summary>
+        public void Reset()
+        {
+            Array.Copy(initialState, 0, chain, 0, chain.Length);
+
+            UbiInit(PARAM_TYPE_MESSAGE);
+        }
+
+        private void UbiComplete(int type, byte[] value)
+        {
+            UbiInit(type);
+            this.ubi.Update(value, 0, value.Length, chain);
+            UbiFinal();
+        }
+
+        private void UbiInit(int type)
+        {
+            this.ubi.Reset(type);
+        }
+
+        private void UbiFinal()
+        {
+            ubi.DoFinal(chain);
+        }
+
+        private void CheckInitialised()
+        {
+            if (this.ubi == null)
+            {
+                throw new ArgumentException("Skein engine is not initialised.");
+            }
+        }
+
+        public void Update(byte inByte)
+        {
+            singleByte[0] = inByte;
+            Update(singleByte, 0, 1);
+        }
+
+        public void Update(byte[] inBytes, int inOff, int len)
+        {
+            CheckInitialised();
+            ubi.Update(inBytes, inOff, len, chain);
+        }
+
+        public int DoFinal(byte[] outBytes, int outOff)
+        {
+            CheckInitialised();
+            if (outBytes.Length < (outOff + outputSizeBytes))
+            {
+                throw new DataLengthException("Output buffer is too short to hold output of " + outputSizeBytes + " bytes");
+            }
+
+            // Finalise message block
+            UbiFinal();
+
+            // Process additional post-message parameters
+            if (postMessageParameters != null)
+            {
+                for (int i = 0; i < postMessageParameters.Length; i++)
+                {
+                    Parameter param = postMessageParameters[i];
+                    UbiComplete(param.Type, param.Value);
+                }
+            }
+
+            // Perform the output transform
+            int blockSize = BlockSize;
+            int blocksRequired = ((outputSizeBytes + blockSize - 1) / blockSize);
+            for (int i = 0; i < blocksRequired; i++)
+            {
+                int toWrite = System.Math.Min(blockSize, outputSizeBytes - (i * blockSize));
+                Output((ulong)i, outBytes, outOff + (i * blockSize), toWrite);
+            }
+
+            Reset();
+
+            return outputSizeBytes;
+        }
+
+        private void Output(ulong outputSequence, byte[] outBytes, int outOff, int outputBytes)
+        {
+            byte[] currentBytes = new byte[8];
+            ThreefishEngine.WordToBytes(outputSequence, currentBytes, 0);
+
+            // Output is a sequence of UBI invocations all of which use and preserve the pre-output
+            // state
+            ulong[] outputWords = new ulong[chain.Length];
+            UbiInit(PARAM_TYPE_OUTPUT);
+            this.ubi.Update(currentBytes, 0, currentBytes.Length, outputWords);
+            ubi.DoFinal(outputWords);
+
+            int wordsRequired = ((outputBytes + 8 - 1) / 8);
+            for (int i = 0; i < wordsRequired; i++)
+            {
+                int toWrite = System.Math.Min(8, outputBytes - (i * 8));
+                if (toWrite == 8)
+                {
+                    ThreefishEngine.WordToBytes(outputWords[i], outBytes, outOff + (i * 8));
+                }
+                else
+                {
+                    ThreefishEngine.WordToBytes(outputWords[i], currentBytes, 0);
+                    Array.Copy(currentBytes, 0, outBytes, outOff + (i * 8), toWrite);
+                }
+            }
+        }
+
+    }
 }
 
diff --git a/crypto/src/crypto/engines/ThreefishEngine.cs b/crypto/src/crypto/engines/ThreefishEngine.cs
index 3d4ee8835..954470345 100644
--- a/crypto/src/crypto/engines/ThreefishEngine.cs
+++ b/crypto/src/crypto/engines/ThreefishEngine.cs
@@ -6,7 +6,6 @@ using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Crypto.Engines
 {
-
 	/// <summary>
 	/// Implementation of the Threefish tweakable large block cipher in 256, 512 and 1024 bit block
 	/// sizes.
@@ -19,7 +18,7 @@ namespace Org.BouncyCastle.Crypto.Engines
 	/// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker.
 	/// <p/>
 	/// This implementation inlines all round functions, unrolls 8 rounds, and uses 1.2k of static tables
-	/// to speed up key schedule injection. <br>
+	/// to speed up key schedule injection. <br/>
 	/// 2 x block size state is retained by each cipher instance.
 	/// </remarks>
 	public class ThreefishEngine
diff --git a/crypto/src/crypto/parameters/SkeinParameters.cs b/crypto/src/crypto/parameters/SkeinParameters.cs
index bbd25e0e0..a4e3e8e2a 100644
--- a/crypto/src/crypto/parameters/SkeinParameters.cs
+++ b/crypto/src/crypto/parameters/SkeinParameters.cs
@@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
 	/// Parameterised Skein can be used for:
 	/// <ul> 
 	/// <li>MAC generation, by providing a <see cref="SkeinParameters.Builder.SetKey(byte[])">key</see>.</li>
-	/// <li>Randomised hashing, by providing a <see cref="SkeinParameters.Builder.SetNoce(byte[])">nonce</see>.</li>
+	/// <li>Randomised hashing, by providing a <see cref="SkeinParameters.Builder.SetNonce(byte[])">nonce</see>.</li>
 	/// <li>A hash function for digital signatures, associating a
 	/// <see cref="SkeinParameters.Builder.SetPublicKey(byte[])">public key</see> with the message digest.</li>
 	/// <li>A key derivation function, by providing a
@@ -120,7 +120,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
 		}
 
 		/// <summary>
-		/// Obtains the value of the <see cref="PARAM_TYPE_KEY_IDENTIFIER key identifier parameter</see>, or
+		/// Obtains the value of the <see cref="PARAM_TYPE_KEY_IDENTIFIER">key identifier parameter</see>, or
 		/// <code>null</code> if not set.
 		/// </summary>
 		public byte[] GetKeyIdentifier()
@@ -129,7 +129,7 @@ namespace Org.BouncyCastle.Crypto.Parameters
 		}
 
 		/// <summary>
-		/// Obtains the value of the <see cref="PARAM_TYPE_NONCE nonce parameter</see>, or <code>null</code> if
+		/// Obtains the value of the <see cref="PARAM_TYPE_NONCE">nonce parameter</see>, or <code>null</code> if
 		/// not set.
 		/// </summary>
 		public byte[] GetNonce()
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs
index 0c150848a..82cf1367b 100644
--- a/crypto/src/math/ec/ECCurve.cs
+++ b/crypto/src/math/ec/ECCurve.cs
@@ -340,7 +340,7 @@ namespace Org.BouncyCastle.Math.EC
                     BigInteger X1 = new BigInteger(1, encoded, 1, expectedLength);
                     BigInteger Y1 = new BigInteger(1, encoded, 1 + expectedLength, expectedLength);
 
-                    p = CreatePoint(X1, Y1, false);
+                    p = CreatePoint(X1, Y1);
                     break;
                 }
 
@@ -777,6 +777,7 @@ namespace Org.BouncyCastle.Math.EC
             return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, x);
         }
 
+        [Obsolete("Per-point compression property will be removed")]
         public override ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression)
         {
             ECFieldElement X = FromBigInteger(x), Y = FromBigInteger(y);
diff --git a/crypto/src/math/ec/abc/Tnaf.cs b/crypto/src/math/ec/abc/Tnaf.cs
index 0ba414e68..9f16886f5 100644
--- a/crypto/src/math/ec/abc/Tnaf.cs
+++ b/crypto/src/math/ec/abc/Tnaf.cs
@@ -534,7 +534,7 @@ namespace Org.BouncyCastle.Math.EC.Abc
             int m = curve.M;
             int a = curve.A.ToBigInteger().IntValue;
             sbyte mu = curve.GetMu();
-            int h = curve.H.IntValue;
+            int h = curve.Cofactor.IntValue;
             int index = m + 3 - a;
             BigInteger[] ui = GetLucas(mu, index, false);
 
diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs
index b0fc98b03..8c0be4f70 100644
--- a/crypto/src/security/PublicKeyFactory.cs
+++ b/crypto/src/security/PublicKeyFactory.cs
@@ -187,7 +187,7 @@ namespace Org.BouncyCastle.Security
                 if (ecP == null)
                     return null;
 
-                ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y), false);
+                ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y));
 
                 return new ECPublicKeyParameters("ECGOST3410", q, gostParams.PublicKeyParamSet);
             }
diff --git a/crypto/src/util/IMemoable.cs b/crypto/src/util/IMemoable.cs
index befc10fbf..cc8a2e55b 100644
--- a/crypto/src/util/IMemoable.cs
+++ b/crypto/src/util/IMemoable.cs
@@ -20,7 +20,7 @@ namespace Org.BouncyCastle.Utilities
 		/// Implementations of this method <em>should</em> try to avoid or minimise memory allocation to perform the reset.
 		/// </remarks>
 		/// <param name="other">an object originally {@link #copy() copied} from an object of the same type as this instance.</param>
-		/// <exception cref="ClassCastException">if the provided object is not of the correct type.</exception>
+		/// <exception cref="InvalidCastException">if the provided object is not of the correct type.</exception>
 		/// <exception cref="MemoableResetException">if the <b>other</b> parameter is in some other way invalid.</exception>
 		void Reset(IMemoable other);
 	}
diff --git a/crypto/src/util/MemoableResetException.cs b/crypto/src/util/MemoableResetException.cs
index d9542dab2..99554f6c2 100644
--- a/crypto/src/util/MemoableResetException.cs
+++ b/crypto/src/util/MemoableResetException.cs
@@ -2,26 +2,26 @@ using System;
 
 namespace Org.BouncyCastle.Utilities
 {
-	/**
-	 * Exception to be thrown on a failure to reset an object implementing Memoable.
-	 * <p>
-	 * The exception extends ClassCastException to enable users to have a single handling case,
-	 * only introducing specific handling of this one if required.
-	 * </p>
-	 */
-	public class MemoableResetException
-		: InvalidCastException
-	{
-		/**
-	     * Basic Constructor.
-	     *
-	     * @param msg message to be associated with this exception.
-	     */
-		public MemoableResetException(string msg)
-			: base(msg)
-		{
-		}
-	}
+    /**
+     * Exception to be thrown on a failure to reset an object implementing Memoable.
+     * <p>
+     * The exception extends InvalidCastException to enable users to have a single handling case,
+     * only introducing specific handling of this one if required.
+     * </p>
+     */
+    public class MemoableResetException
+        : InvalidCastException
+    {
+        /**
+         * Basic Constructor.
+         *
+         * @param msg message to be associated with this exception.
+         */
+        public MemoableResetException(string msg)
+            : base(msg)
+        {
+        }
+    }
 
 }
 
diff --git a/crypto/test/src/crypto/test/OCBTest.cs b/crypto/test/src/crypto/test/OCBTest.cs
index f4c9f3e48..a28e6c3f1 100644
--- a/crypto/test/src/crypto/test/OCBTest.cs
+++ b/crypto/test/src/crypto/test/OCBTest.cs
@@ -108,7 +108,7 @@ namespace Org.BouncyCastle.Crypto.Tests
                 ocb = new OcbBlockCipher(new DesEngine(), new DesEngine());
                 Fail("incorrect block size not picked up");
             }
-            catch (ArgumentException e)
+            catch (ArgumentException)
             {
                 // expected
             }
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Crypto.Tests
                 ocb.Init(false, new KeyParameter(new byte[16]));
                 Fail("illegal argument not picked up");
             }
-            catch (ArgumentException e)
+            catch (ArgumentException)
             {
                 // expected
             }
diff --git a/crypto/test/src/test/CertTest.cs b/crypto/test/src/test/CertTest.cs
index 2aef010d0..9bb4df7d1 100644
--- a/crypto/test/src/test/CertTest.cs
+++ b/crypto/test/src/test/CertTest.cs
@@ -1490,7 +1490,7 @@ namespace Org.BouncyCastle.Tests
                 ECPoint q = pubKey.Q.Normalize();
                 pubKey = new ECPublicKeyParameters(
                     pubKey.AlgorithmName,
-                    q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger(), false),
+                    q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()),
                     pubKey.Parameters);
 
                 certGen.SetPublicKey(pubKey);
@@ -1614,7 +1614,7 @@ namespace Org.BouncyCastle.Tests
             ECPoint q = pubKey.Q.Normalize();
             pubKey = new ECPublicKeyParameters(
                 pubKey.AlgorithmName,
-                q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger(), false),
+                q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()),
                 pubKey.Parameters);
 
             certGen.SetPublicKey(pubKey);
diff --git a/crypto/test/src/test/GOST3410Test.cs b/crypto/test/src/test/GOST3410Test.cs
index e8c2c1c76..db232c5a1 100644
--- a/crypto/test/src/test/GOST3410Test.cs
+++ b/crypto/test/src/test/GOST3410Test.cs
@@ -16,273 +16,270 @@ using Org.BouncyCastle.X509;
 
 namespace Org.BouncyCastle.Tests
 {
-	[TestFixture]
-	public class Gost3410Test
-		: SimpleTest
-	{
-		private void ecGOST3410Test()
-		{
-			BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395");
-			BigInteger s = new BigInteger("46959264877825372965922731380059061821746083849389763294914877353246631700866");
+    [TestFixture]
+    public class Gost3410Test
+        : SimpleTest
+    {
+        private void ecGOST3410Test()
+        {
+            BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395");
+            BigInteger s = new BigInteger("46959264877825372965922731380059061821746083849389763294914877353246631700866");
 
-			byte[] kData = new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395").ToByteArrayUnsigned();
+            byte[] kData = new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395").ToByteArrayUnsigned();
 
-			SecureRandom k = FixedSecureRandom.From(kData);
+            SecureRandom k = FixedSecureRandom.From(kData);
 
-			BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
+            BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
 
-			ECCurve curve = new FpCurve(
-				mod_p, // p
-				new BigInteger("7"), // a
-				new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
+            ECCurve curve = new FpCurve(
+                mod_p, // p
+                new BigInteger("7"), // a
+                new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
 
-			ECDomainParameters spec = new ECDomainParameters(
-				curve,
-				curve.CreatePoint(
-					new BigInteger("2"),
-					new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"),
-					false),
-				new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
+            ECDomainParameters spec = new ECDomainParameters(
+                curve,
+                curve.CreatePoint(
+                    new BigInteger("2"),
+                    new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280")),
+                new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
 
-			ECPrivateKeyParameters sKey = new ECPrivateKeyParameters(
-				"ECGOST3410",
-				new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d
-				spec);
+            ECPrivateKeyParameters sKey = new ECPrivateKeyParameters(
+                "ECGOST3410",
+                new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d
+                spec);
 
-			ECPublicKeyParameters vKey = new ECPublicKeyParameters(
-				"ECGOST3410",
-				curve.CreatePoint(
-					new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403"),
-					new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994"),
-					false),	
-				spec);
+            ECPublicKeyParameters vKey = new ECPublicKeyParameters(
+                "ECGOST3410",
+                curve.CreatePoint(
+                    new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403"),
+                    new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994")),
+                spec);
 
-			ISigner sgr = SignerUtilities.GetSigner("ECGOST3410");
+            ISigner sgr = SignerUtilities.GetSigner("ECGOST3410");
 
-			sgr.Init(true, new ParametersWithRandom(sKey, k));
+            sgr.Init(true, new ParametersWithRandom(sKey, k));
 
-			byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' };
+            byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' };
 
-			sgr.BlockUpdate(message, 0, message.Length);
+            sgr.BlockUpdate(message, 0, message.Length);
 
-			byte[] sigBytes = sgr.GenerateSignature();
+            byte[] sigBytes = sgr.GenerateSignature();
 
-			sgr.Init(false, vKey);
+            sgr.Init(false, vKey);
 
-			sgr.BlockUpdate(message, 0, message.Length);
+            sgr.BlockUpdate(message, 0, message.Length);
 
-			if (!sgr.VerifySignature(sigBytes))
-			{
-				Fail("ECGOST3410 verification failed");
-			}
+            if (!sgr.VerifySignature(sigBytes))
+            {
+                Fail("ECGOST3410 verification failed");
+            }
 
-			BigInteger[] sig = decode(sigBytes);
+            BigInteger[] sig = decode(sigBytes);
 
-			if (!r.Equals(sig[0]))
-			{
-				Fail(
-					": r component wrong." + SimpleTest.NewLine
-					+ " expecting: " + r + SimpleTest.NewLine
-					+ " got      : " + sig[0]);
-			}
+            if (!r.Equals(sig[0]))
+            {
+                Fail(
+                    ": r component wrong." + SimpleTest.NewLine
+                    + " expecting: " + r + SimpleTest.NewLine
+                    + " got      : " + sig[0]);
+            }
 
-			if (!s.Equals(sig[1]))
-			{
-				Fail(
-					": s component wrong." + SimpleTest.NewLine
-					+ " expecting: " + s + SimpleTest.NewLine
-					+ " got      : " + sig[1]);
-			}
-		}
+            if (!s.Equals(sig[1]))
+            {
+                Fail(
+                    ": s component wrong." + SimpleTest.NewLine
+                    + " expecting: " + s + SimpleTest.NewLine
+                    + " got      : " + sig[1]);
+            }
+        }
 
-		private void generationTest()
-		{
-			byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
-			ISigner s = SignerUtilities.GetSigner("GOST3410");
+        private void generationTest()
+        {
+            byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+            ISigner s = SignerUtilities.GetSigner("GOST3410");
 
-			IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410");
-			g.Init(
-				new Gost3410KeyGenerationParameters(
-					new SecureRandom(),
-					CryptoProObjectIdentifiers.GostR3410x94CryptoProA));
+            IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410");
+            g.Init(
+                new Gost3410KeyGenerationParameters(
+                    new SecureRandom(),
+                    CryptoProObjectIdentifiers.GostR3410x94CryptoProA));
 
-			AsymmetricCipherKeyPair p = g.GenerateKeyPair();
+            AsymmetricCipherKeyPair p = g.GenerateKeyPair();
 
-			AsymmetricKeyParameter sKey = p.Private;
-			AsymmetricKeyParameter vKey = p.Public;
+            AsymmetricKeyParameter sKey = p.Private;
+            AsymmetricKeyParameter vKey = p.Public;
 
-			s.Init(true, sKey);
+            s.Init(true, sKey);
 
-			s.BlockUpdate(data, 0, data.Length);
+            s.BlockUpdate(data, 0, data.Length);
 
-			byte[] sigBytes = s.GenerateSignature();
+            byte[] sigBytes = s.GenerateSignature();
 
-			s = SignerUtilities.GetSigner("GOST3410");
+            s = SignerUtilities.GetSigner("GOST3410");
 
-			s.Init(false, vKey);
+            s.Init(false, vKey);
 
-			s.BlockUpdate(data, 0, data.Length);
+            s.BlockUpdate(data, 0, data.Length);
 
-			if (!s.VerifySignature(sigBytes))
-			{
-				Fail("GOST3410 verification failed");
-			}
+            if (!s.VerifySignature(sigBytes))
+            {
+                Fail("GOST3410 verification failed");
+            }
 
-			//
-			// default initialisation test
-			//
-			s = SignerUtilities.GetSigner("GOST3410");
-			g = GeneratorUtilities.GetKeyPairGenerator("GOST3410");
+            //
+            // default initialisation test
+            //
+            s = SignerUtilities.GetSigner("GOST3410");
+            g = GeneratorUtilities.GetKeyPairGenerator("GOST3410");
 
-			// TODO This is supposed to be a 'default initialisation' test, but don't have a factory
-			// These values are defaults from JCE provider
-			g.Init(
-				new Gost3410KeyGenerationParameters(
-					new SecureRandom(),
-					CryptoProObjectIdentifiers.GostR3410x94CryptoProA));
+            // TODO This is supposed to be a 'default initialisation' test, but don't have a factory
+            // These values are defaults from JCE provider
+            g.Init(
+                new Gost3410KeyGenerationParameters(
+                    new SecureRandom(),
+                    CryptoProObjectIdentifiers.GostR3410x94CryptoProA));
 
-			p = g.GenerateKeyPair();
+            p = g.GenerateKeyPair();
 
-			sKey = p.Private;
-			vKey = p.Public;
+            sKey = p.Private;
+            vKey = p.Public;
 
-			s.Init(true, sKey);
+            s.Init(true, sKey);
 
-			s.BlockUpdate(data, 0, data.Length);
+            s.BlockUpdate(data, 0, data.Length);
 
-			sigBytes = s.GenerateSignature();
+            sigBytes = s.GenerateSignature();
 
-			s = SignerUtilities.GetSigner("GOST3410");
+            s = SignerUtilities.GetSigner("GOST3410");
 
-			s.Init(false, vKey);
+            s.Init(false, vKey);
 
-			s.BlockUpdate(data, 0, data.Length);
+            s.BlockUpdate(data, 0, data.Length);
 
-			if (!s.VerifySignature(sigBytes))
-			{
-				Fail("GOST3410 verification failed");
-			}
+            if (!s.VerifySignature(sigBytes))
+            {
+                Fail("GOST3410 verification failed");
+            }
 
-			//
-			// encoded test
-			//
-			//KeyFactory f = KeyFactory.getInstance("GOST3410");
-			//X509EncodedKeySpec  x509s = new X509EncodedKeySpec(vKey.GetEncoded());
-			//Gost3410PublicKeyParameters k1 = (Gost3410PublicKeyParameters)f.generatePublic(x509s);
-			byte[] vKeyEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(vKey).GetDerEncoded();
-			Gost3410PublicKeyParameters k1 = (Gost3410PublicKeyParameters)
-				PublicKeyFactory.CreateKey(vKeyEnc);
+            //
+            // encoded test
+            //
+            //KeyFactory f = KeyFactory.getInstance("GOST3410");
+            //X509EncodedKeySpec  x509s = new X509EncodedKeySpec(vKey.GetEncoded());
+            //Gost3410PublicKeyParameters k1 = (Gost3410PublicKeyParameters)f.generatePublic(x509s);
+            byte[] vKeyEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(vKey).GetDerEncoded();
+            Gost3410PublicKeyParameters k1 = (Gost3410PublicKeyParameters)
+                PublicKeyFactory.CreateKey(vKeyEnc);
 
-			if (!k1.Y.Equals(((Gost3410PublicKeyParameters)vKey).Y))
-			{
-				Fail("public number not decoded properly");
-			}
+            if (!k1.Y.Equals(((Gost3410PublicKeyParameters)vKey).Y))
+            {
+                Fail("public number not decoded properly");
+            }
 
-			//PKCS8EncodedKeySpec  pkcs8 = new PKCS8EncodedKeySpec(sKey.GetEncoded());
-			//Gost3410PrivateKeyParameters k2 = (Gost3410PrivateKeyParameters)f.generatePrivate(pkcs8);
-			byte[] sKeyEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(sKey).GetDerEncoded();
-			Gost3410PrivateKeyParameters k2 = (Gost3410PrivateKeyParameters)
-				PrivateKeyFactory.CreateKey(sKeyEnc);
+            //PKCS8EncodedKeySpec  pkcs8 = new PKCS8EncodedKeySpec(sKey.GetEncoded());
+            //Gost3410PrivateKeyParameters k2 = (Gost3410PrivateKeyParameters)f.generatePrivate(pkcs8);
+            byte[] sKeyEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(sKey).GetDerEncoded();
+            Gost3410PrivateKeyParameters k2 = (Gost3410PrivateKeyParameters)
+                PrivateKeyFactory.CreateKey(sKeyEnc);
 
-			if (!k2.X.Equals(((Gost3410PrivateKeyParameters)sKey).X))
-			{
-				Fail("private number not decoded properly");
-			}
+            if (!k2.X.Equals(((Gost3410PrivateKeyParameters)sKey).X))
+            {
+                Fail("private number not decoded properly");
+            }
 
-			//
-			// ECGOST3410 generation test
-			//
-			s = SignerUtilities.GetSigner("ECGOST3410");
-			g = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410");
+            //
+            // ECGOST3410 generation test
+            //
+            s = SignerUtilities.GetSigner("ECGOST3410");
+            g = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410");
 
-			BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
+            BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
 
-			ECCurve curve = new FpCurve(
-				mod_p, // p
-				new BigInteger("7"), // a
-				new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
+            ECCurve curve = new FpCurve(
+                mod_p, // p
+                new BigInteger("7"), // a
+                new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
 
-			ECDomainParameters ecSpec = new ECDomainParameters(
-				curve,
-				curve.CreatePoint(
-					new BigInteger("2"),
-					new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"),
-					false),
-				new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
+            ECDomainParameters ecSpec = new ECDomainParameters(
+                curve,
+                curve.CreatePoint(
+                    new BigInteger("2"),
+                    new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280")),
+                new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
 
-			g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom()));
+            g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom()));
 
-			p = g.GenerateKeyPair();
+            p = g.GenerateKeyPair();
 
-			sKey = p.Private;
-			vKey = p.Public;
+            sKey = p.Private;
+            vKey = p.Public;
 
-			s.Init(true, sKey);
+            s.Init(true, sKey);
 
-			s.BlockUpdate(data, 0, data.Length);
+            s.BlockUpdate(data, 0, data.Length);
 
-			sigBytes = s.GenerateSignature();
+            sigBytes = s.GenerateSignature();
 
-			s = SignerUtilities.GetSigner("ECGOST3410");
+            s = SignerUtilities.GetSigner("ECGOST3410");
 
-			s.Init(false, vKey);
+            s.Init(false, vKey);
 
-			s.BlockUpdate(data, 0, data.Length);
+            s.BlockUpdate(data, 0, data.Length);
 
-			if (!s.VerifySignature(sigBytes))
-			{
-				Fail("ECGOST3410 verification failed");
-			}
-		}
+            if (!s.VerifySignature(sigBytes))
+            {
+                Fail("ECGOST3410 verification failed");
+            }
+        }
 
-	    private void keyStoreTest(
-			AsymmetricKeyParameter	sKey,
-			AsymmetricKeyParameter	vKey)
+        private void keyStoreTest(
+            AsymmetricKeyParameter	sKey,
+            AsymmetricKeyParameter	vKey)
 //	        throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, UnrecoverableKeyException
-	    {
-	        //
-	        // keystore test
-	        //
+        {
+            //
+            // keystore test
+            //
 //			KeyStore ks = KeyStore.GetInstance("JKS");
 //			ks.Load(null, null);
-	        Pkcs12StoreBuilder ksBuilder = new Pkcs12StoreBuilder();
-			Pkcs12Store ks = ksBuilder.Build();
-	
-	        //
-	        // create the certificate - version 3
-	        //
-	        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
-	
-	        certGen.SetSerialNumber(BigInteger.One);
-	        certGen.SetIssuerDN(new X509Name("CN=Test"));
-	        certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50));
-	        certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50));
-	        certGen.SetSubjectDN(new X509Name("CN=Test"));
-	        certGen.SetPublicKey(vKey);
-	        certGen.SetSignatureAlgorithm("GOST3411withGOST3410");
-	
-	        X509Certificate cert = certGen.Generate(sKey);
-			X509CertificateEntry certEntry = new X509CertificateEntry(cert);
+            Pkcs12StoreBuilder ksBuilder = new Pkcs12StoreBuilder();
+            Pkcs12Store ks = ksBuilder.Build();
+    
+            //
+            // create the certificate - version 3
+            //
+            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
+    
+            certGen.SetSerialNumber(BigInteger.One);
+            certGen.SetIssuerDN(new X509Name("CN=Test"));
+            certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50));
+            certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50));
+            certGen.SetSubjectDN(new X509Name("CN=Test"));
+            certGen.SetPublicKey(vKey);
+            certGen.SetSignatureAlgorithm("GOST3411withGOST3410");
+    
+            X509Certificate cert = certGen.Generate(sKey);
+            X509CertificateEntry certEntry = new X509CertificateEntry(cert);
 
 //	        ks.SetKeyEntry("gost", sKey, "gost".ToCharArray(), new X509Certificate[] { cert });
-	        ks.SetKeyEntry("gost", new AsymmetricKeyEntry(sKey), new X509CertificateEntry[] { certEntry });
-	
-	        MemoryStream bOut = new MemoryStream();
-	
-	        ks.Save(bOut, "gost".ToCharArray(), new SecureRandom());
-	
+            ks.SetKeyEntry("gost", new AsymmetricKeyEntry(sKey), new X509CertificateEntry[] { certEntry });
+    
+            MemoryStream bOut = new MemoryStream();
+    
+            ks.Save(bOut, "gost".ToCharArray(), new SecureRandom());
+    
 //	        ks = KeyStore.getInstance("JKS");
-			ks = ksBuilder.Build();
+            ks = ksBuilder.Build();
 
-	        ks.Load(new MemoryStream(bOut.ToArray(), false), "gost".ToCharArray());
+            ks.Load(new MemoryStream(bOut.ToArray(), false), "gost".ToCharArray());
 
 //	        AsymmetricKeyParameter gKey = (AsymmetricKeyParameter)ks.GetKey("gost", "gost".ToCharArray());
 //	        AsymmetricKeyEntry gKeyEntry = (AsymmetricKeyEntry)
-				ks.GetKey("gost");
-	    }
-		
-		private void parametersTest()
-		{
+                ks.GetKey("gost");
+        }
+        
+        private void parametersTest()
+        {
 //	        AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("GOST3410");
 //	        a.init(512, random);
 //	        AlgorithmParameters params = a.generateParameters();
@@ -303,81 +300,81 @@ namespace Org.BouncyCastle.Tests
 //			GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(
 //				CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_B.getId());
 //			g.initialize(gost3410P, new SecureRandom());
-			IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410");
-			g.Init(
-				new Gost3410KeyGenerationParameters(
-					new SecureRandom(),
-					CryptoProObjectIdentifiers.GostR3410x94CryptoProB));
+            IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410");
+            g.Init(
+                new Gost3410KeyGenerationParameters(
+                    new SecureRandom(),
+                    CryptoProObjectIdentifiers.GostR3410x94CryptoProB));
 
-			AsymmetricCipherKeyPair p = g.GenerateKeyPair();
+            AsymmetricCipherKeyPair p = g.GenerateKeyPair();
 
-			AsymmetricKeyParameter sKey = p.Private;
-			AsymmetricKeyParameter vKey = p.Public;
+            AsymmetricKeyParameter sKey = p.Private;
+            AsymmetricKeyParameter vKey = p.Public;
 
-			ISigner s = SignerUtilities.GetSigner("GOST3410");
-			byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+            ISigner s = SignerUtilities.GetSigner("GOST3410");
+            byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
 
-			s.Init(true, sKey);
+            s.Init(true, sKey);
 
-			s.BlockUpdate(data, 0, data.Length);
+            s.BlockUpdate(data, 0, data.Length);
 
-			byte[] sigBytes = s.GenerateSignature();
+            byte[] sigBytes = s.GenerateSignature();
 
-			s = SignerUtilities.GetSigner("GOST3410");
+            s = SignerUtilities.GetSigner("GOST3410");
 
-			s.Init(false, vKey);
+            s.Init(false, vKey);
 
-			s.BlockUpdate(data, 0, data.Length);
+            s.BlockUpdate(data, 0, data.Length);
 
-			if (!s.VerifySignature(sigBytes))
-			{
-				Fail("GOST3410 verification failed");
-			}
+            if (!s.VerifySignature(sigBytes))
+            {
+                Fail("GOST3410 verification failed");
+            }
 
-        	keyStoreTest(sKey, vKey);
-		}
+            keyStoreTest(sKey, vKey);
+        }
 
-		private BigInteger[] decode(
-			byte[]  encoding)
-		{
-			byte[] r = new byte[32];
-			byte[] s = new byte[32];
+        private BigInteger[] decode(
+            byte[]  encoding)
+        {
+            byte[] r = new byte[32];
+            byte[] s = new byte[32];
 
-			Array.Copy(encoding, 0, s, 0, 32);
-			Array.Copy(encoding, 32, r, 0, 32);
+            Array.Copy(encoding, 0, s, 0, 32);
+            Array.Copy(encoding, 32, r, 0, 32);
 
-			BigInteger[] sig = new BigInteger[2];
+            BigInteger[] sig = new BigInteger[2];
 
-			sig[0] = new BigInteger(1, r);
-			sig[1] = new BigInteger(1, s);
+            sig[0] = new BigInteger(1, r);
+            sig[1] = new BigInteger(1, s);
 
-			return sig;
-		}
+            return sig;
+        }
 
-		public override string Name
-		{
-			get { return "GOST3410/ECGOST3410"; }
-		}
+        public override string Name
+        {
+            get { return "GOST3410/ECGOST3410"; }
+        }
 
-		public override void PerformTest()
-		{
-			ecGOST3410Test();
-			generationTest();
-			parametersTest();
-		}
+        public override void PerformTest()
+        {
+            ecGOST3410Test();
+            generationTest();
+            parametersTest();
+        }
 
-		public static void Main(
-			string[]	args)
-		{
-			RunTest(new Gost3410Test());
-		}
+        public static void Main(
+            string[]	args)
+        {
+            RunTest(new Gost3410Test());
+        }
 
-		[Test]
-		public void TestFunction()
-		{
-			string resultText = Perform().ToString();
+        [Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
 
-			Assert.AreEqual(Name + ": Okay", resultText);
-		}
-	}
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
 }
diff --git a/crypto/test/src/test/PKCS10CertRequestTest.cs b/crypto/test/src/test/PKCS10CertRequestTest.cs
index 8af43b2e4..819439cd8 100644
--- a/crypto/test/src/test/PKCS10CertRequestTest.cs
+++ b/crypto/test/src/test/PKCS10CertRequestTest.cs
@@ -177,7 +177,7 @@ namespace Org.BouncyCastle.Tests
             ECPoint q = pubKey.Q.Normalize();
             pubKey = new ECPublicKeyParameters(
                 pubKey.AlgorithmName,
-                q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger(), false),
+                q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()),
                 pubKey.Parameters);
 
             req = new Pkcs10CertificationRequest(