summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2015-03-09 16:05:24 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2015-03-09 16:05:24 +0700
commitec1991b40df8748b6c436807ce9d9ea5f146b13c (patch)
tree53204a26b6db0aaaf2f5854996d99d5abd7c4a39 /crypto/src
parentRefactor TLS ciphersuite processing (diff)
downloadBouncyCastle.NET-ed25519-ec1991b40df8748b6c436807ce9d9ea5f146b13c.tar.xz
Port X931Signer and tests from Java
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/crypto/signers/DsaDigestSigner.cs14
-rw-r--r--crypto/src/crypto/signers/ECGOST3410Signer.cs8
-rw-r--r--crypto/src/crypto/signers/ECNRSigner.cs8
-rw-r--r--crypto/src/crypto/signers/GOST3410DigestSigner.cs14
-rw-r--r--crypto/src/crypto/signers/GOST3410Signer.cs8
-rw-r--r--crypto/src/crypto/signers/GenericSigner.cs14
-rw-r--r--crypto/src/crypto/signers/Iso9796d2PssSigner.cs4
-rw-r--r--crypto/src/crypto/signers/Iso9796d2Signer.cs6
-rw-r--r--crypto/src/crypto/signers/PssSigner.cs2
-rw-r--r--crypto/src/crypto/signers/RsaDigestSigner.cs15
-rw-r--r--crypto/src/crypto/signers/X931Signer.cs235
11 files changed, 281 insertions, 47 deletions
diff --git a/crypto/src/crypto/signers/DsaDigestSigner.cs b/crypto/src/crypto/signers/DsaDigestSigner.cs
index aee713450..086601481 100644
--- a/crypto/src/crypto/signers/DsaDigestSigner.cs
+++ b/crypto/src/crypto/signers/DsaDigestSigner.cs
@@ -26,12 +26,12 @@ namespace Org.BouncyCastle.Crypto.Signers
 			this.dsaSigner = signer;
 		}
 
-		public string AlgorithmName
+		public virtual string AlgorithmName
 		{
 			get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; }
 		}
 
-		public void Init(
+        public virtual void Init(
 			bool							forSigning,
 			ICipherParameters	parameters)
 		{
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		/**
 		 * update the internal digest with the byte b
 		 */
-		public void Update(
+        public virtual void Update(
 			byte input)
 		{
 			digest.Update(input);
@@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		/**
 		 * update the internal digest with the byte array in
 		 */
-		public void BlockUpdate(
+        public virtual void BlockUpdate(
 			byte[]	input,
 			int			inOff,
 			int			length)
@@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		 * Generate a signature for the message we've been loaded with using
 		 * the key we were initialised with.
      */
-		public byte[] GenerateSignature()
+        public virtual byte[] GenerateSignature()
 		{
 			if (!forSigning)
 				throw new InvalidOperationException("DSADigestSigner not initialised for signature generation.");
@@ -97,7 +97,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		}
 
 		/// <returns>true if the internal state represents the signature described in the passed in array.</returns>
-		public bool VerifySignature(
+        public virtual bool VerifySignature(
 			byte[] signature)
 		{
 			if (forSigning)
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		}
 
 		/// <summary>Reset the internal state</summary>
-		public void Reset()
+        public virtual void Reset()
 		{
 			digest.Reset();
 		}
diff --git a/crypto/src/crypto/signers/ECGOST3410Signer.cs b/crypto/src/crypto/signers/ECGOST3410Signer.cs
index 6027aa9b9..28ab79c1c 100644
--- a/crypto/src/crypto/signers/ECGOST3410Signer.cs
+++ b/crypto/src/crypto/signers/ECGOST3410Signer.cs
@@ -18,12 +18,12 @@ namespace Org.BouncyCastle.Crypto.Signers
         private ECKeyParameters key;
         private SecureRandom random;
 
-        public string AlgorithmName
+        public virtual string AlgorithmName
         {
             get { return "ECGOST3410"; }
         }
 
-        public void Init(
+        public virtual void Init(
             bool				forSigning,
             ICipherParameters	parameters)
         {
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Signers
          *
          * @param message the message that will be verified later.
          */
-        public BigInteger[] GenerateSignature(
+        public virtual BigInteger[] GenerateSignature(
             byte[] message)
         {
             byte[] mRev = new byte[message.Length]; // conversion is little-endian
@@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Signers
          * the passed in message (for standard GOST3410 the message should be
          * a GOST3411 hash of the real message to be verified).
          */
-        public bool VerifySignature(
+        public virtual bool VerifySignature(
             byte[]		message,
             BigInteger	r,
             BigInteger	s)
diff --git a/crypto/src/crypto/signers/ECNRSigner.cs b/crypto/src/crypto/signers/ECNRSigner.cs
index cae15bdbf..bb21a4994 100644
--- a/crypto/src/crypto/signers/ECNRSigner.cs
+++ b/crypto/src/crypto/signers/ECNRSigner.cs
@@ -19,12 +19,12 @@ namespace Org.BouncyCastle.Crypto.Signers
         private ECKeyParameters	key;
         private SecureRandom	random;
 
-        public string AlgorithmName
+        public virtual string AlgorithmName
         {
             get { return "ECNR"; }
         }
 
-        public void Init(
+        public virtual void Init(
             bool				forSigning,
             ICipherParameters	parameters)
         {
@@ -68,7 +68,7 @@ namespace Org.BouncyCastle.Crypto.Signers
          * @param digest  the digest to be signed.
          * @exception DataLengthException if the digest is longer than the key allows
          */
-        public BigInteger[] GenerateSignature(
+        public virtual BigInteger[] GenerateSignature(
             byte[] message)
         {
             if (!this.forSigning)
@@ -134,7 +134,7 @@ namespace Org.BouncyCastle.Crypto.Signers
          * @param s       the s value of the signature.
          * @exception DataLengthException if the digest is longer than the key allows
          */
-        public bool VerifySignature(
+        public virtual bool VerifySignature(
             byte[]		message,
             BigInteger	r,
             BigInteger	s)
diff --git a/crypto/src/crypto/signers/GOST3410DigestSigner.cs b/crypto/src/crypto/signers/GOST3410DigestSigner.cs
index 58aefa368..bc32808df 100644
--- a/crypto/src/crypto/signers/GOST3410DigestSigner.cs
+++ b/crypto/src/crypto/signers/GOST3410DigestSigner.cs
@@ -26,12 +26,12 @@ namespace Org.BouncyCastle.Crypto.Signers
 			this.digest = digest;
 		}
 
-		public string AlgorithmName
+        public virtual string AlgorithmName
 		{
 			get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; }
 		}
 
-		public void Init(
+        public virtual void Init(
 			bool				forSigning,
 			ICipherParameters	parameters)
 		{
@@ -65,7 +65,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		/**
 		 * update the internal digest with the byte b
 		 */
-		public void Update(
+        public virtual void Update(
 			byte input)
 		{
 			digest.Update(input);
@@ -74,7 +74,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		/**
 		 * update the internal digest with the byte array in
 		 */
-		public void BlockUpdate(
+        public virtual void BlockUpdate(
 			byte[]	input,
 			int		inOff,
 			int		length)
@@ -86,7 +86,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		 * Generate a signature for the message we've been loaded with using
 		 * the key we were initialised with.
 		 */
-		public byte[] GenerateSignature()
+        public virtual byte[] GenerateSignature()
 		{
 			if (!forSigning)
 				throw new InvalidOperationException("GOST3410DigestSigner not initialised for signature generation.");
@@ -113,7 +113,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		}
 
 		/// <returns>true if the internal state represents the signature described in the passed in array.</returns>
-		public bool VerifySignature(
+        public virtual bool VerifySignature(
 			byte[] signature)
 		{
 			if (forSigning)
@@ -137,7 +137,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		}
 
 		/// <summary>Reset the internal state</summary>
-		public void Reset()
+        public virtual void Reset()
 		{
 			digest.Reset();
 		}
diff --git a/crypto/src/crypto/signers/GOST3410Signer.cs b/crypto/src/crypto/signers/GOST3410Signer.cs
index 375eeb5cc..f1832ae37 100644
--- a/crypto/src/crypto/signers/GOST3410Signer.cs
+++ b/crypto/src/crypto/signers/GOST3410Signer.cs
@@ -15,12 +15,12 @@ namespace Org.BouncyCastle.Crypto.Signers
 		private Gost3410KeyParameters key;
 		private SecureRandom random;
 
-		public string AlgorithmName
+        public virtual string AlgorithmName
 		{
 			get { return "GOST3410"; }
 		}
 
-		public void Init(
+        public virtual void Init(
 			bool				forSigning,
 			ICipherParameters	parameters)
 		{
@@ -59,7 +59,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		 *
 		 * @param message the message that will be verified later.
 		 */
-		public BigInteger[] GenerateSignature(
+        public virtual BigInteger[] GenerateSignature(
 			byte[] message)
 		{
 			byte[] mRev = new byte[message.Length]; // conversion is little-endian
@@ -92,7 +92,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 		 * the passed in message for standard Gost3410 the message should be a
 		 * Gost3411 hash of the real message to be verified.
 		 */
-		public bool VerifySignature(
+        public virtual bool VerifySignature(
 			byte[]		message,
 			BigInteger	r,
 			BigInteger	s)
diff --git a/crypto/src/crypto/signers/GenericSigner.cs b/crypto/src/crypto/signers/GenericSigner.cs
index 5035b454d..a5512176f 100644
--- a/crypto/src/crypto/signers/GenericSigner.cs
+++ b/crypto/src/crypto/signers/GenericSigner.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Signers
             this.digest = digest;
         }
 
-        public string AlgorithmName
+        public virtual string AlgorithmName
         {
             get { return "Generic(" + engine.AlgorithmName + "/" + digest.AlgorithmName + ")"; }
         }
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         * @param parameters
         *            necessary parameters.
         */
-        public void Init(bool forSigning, ICipherParameters parameters)
+        public virtual void Init(bool forSigning, ICipherParameters parameters)
         {
             this.forSigning = forSigning;
 
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         /**
         * update the internal digest with the byte b
         */
-        public void Update(byte input)
+        public virtual void Update(byte input)
         {
             digest.Update(input);
         }
@@ -70,7 +70,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         /**
         * update the internal digest with the byte array in
         */
-        public void BlockUpdate(byte[] input, int inOff, int length)
+        public virtual void BlockUpdate(byte[] input, int inOff, int length)
         {
             digest.BlockUpdate(input, inOff, length);
         }
@@ -79,7 +79,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         * Generate a signature for the message we've been loaded with using the key
         * we were initialised with.
         */
-        public byte[] GenerateSignature()
+        public virtual byte[] GenerateSignature()
         {
             if (!forSigning)
                 throw new InvalidOperationException("GenericSigner not initialised for signature generation.");
@@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         * return true if the internal state represents the signature described in
         * the passed in array.
         */
-        public bool VerifySignature(byte[] signature)
+        public virtual bool VerifySignature(byte[] signature)
         {
             if (forSigning)
                 throw new InvalidOperationException("GenericSigner not initialised for verification");
@@ -122,7 +122,7 @@ namespace Org.BouncyCastle.Crypto.Signers
             }
         }
 
-        public void Reset()
+        public virtual void Reset()
         {
             digest.Reset();
         }
diff --git a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs
index d4f6c5522..1486656bd 100644
--- a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs
+++ b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs
@@ -120,7 +120,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         {
         }
 
-        public string AlgorithmName
+        public virtual string AlgorithmName
         {
             get { return digest.AlgorithmName + "with" + "ISO9796-2S2"; }
         }
@@ -365,7 +365,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         /// <summary> Generate a signature for the loaded message using the key we were
         /// initialised with.
         /// </summary>
-        public byte[] GenerateSignature()
+        public virtual byte[] GenerateSignature()
         {
             int digSize = digest.GetDigestSize();
             byte[] m2Hash = new byte[digSize];
diff --git a/crypto/src/crypto/signers/Iso9796d2Signer.cs b/crypto/src/crypto/signers/Iso9796d2Signer.cs
index cfb8942e6..4bb4d17a6 100644
--- a/crypto/src/crypto/signers/Iso9796d2Signer.cs
+++ b/crypto/src/crypto/signers/Iso9796d2Signer.cs
@@ -105,7 +105,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         {
         }
 
-        public string AlgorithmName
+        public virtual string AlgorithmName
         {
             get { return digest.AlgorithmName + "with" + "ISO9796-2S1"; }
         }
@@ -252,7 +252,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         }
 
         /// <summary> update the internal digest with the byte b</summary>
-        public void Update(
+        public virtual void Update(
             byte input)
         {
             digest.Update(input);
@@ -266,7 +266,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         }
 
         /// <summary> update the internal digest with the byte array in</summary>
-        public void BlockUpdate(
+        public virtual void BlockUpdate(
             byte[]	input,
             int		inOff,
             int		length)
diff --git a/crypto/src/crypto/signers/PssSigner.cs b/crypto/src/crypto/signers/PssSigner.cs
index 6900224f3..03890902b 100644
--- a/crypto/src/crypto/signers/PssSigner.cs
+++ b/crypto/src/crypto/signers/PssSigner.cs
@@ -115,7 +115,7 @@ namespace Org.BouncyCastle.Crypto.Signers
 			this.trailer = trailer;
 		}
 
-		public string AlgorithmName
+        public virtual string AlgorithmName
 		{
 			get { return mgfDigest.AlgorithmName + "withRSAandMGF1"; }
 		}
diff --git a/crypto/src/crypto/signers/RsaDigestSigner.cs b/crypto/src/crypto/signers/RsaDigestSigner.cs
index 9af4e7145..d9b19cf6b 100644
--- a/crypto/src/crypto/signers/RsaDigestSigner.cs
+++ b/crypto/src/crypto/signers/RsaDigestSigner.cs
@@ -64,8 +64,7 @@ namespace Org.BouncyCastle.Crypto.Signers
             this.algId = algId;
         }
 
-        [Obsolete]
-        public string AlgorithmName
+        public virtual string AlgorithmName
         {
             get { return digest.AlgorithmName + "withRSA"; }
         }
@@ -76,7 +75,7 @@ namespace Org.BouncyCastle.Crypto.Signers
          * @param forSigning true if for signing, false otherwise
          * @param param necessary parameters.
          */
-        public void Init(
+        public virtual void Init(
             bool				forSigning,
             ICipherParameters	parameters)
         {
@@ -106,7 +105,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         /**
          * update the internal digest with the byte b
          */
-        public void Update(
+        public virtual void Update(
             byte input)
         {
             digest.Update(input);
@@ -115,7 +114,7 @@ namespace Org.BouncyCastle.Crypto.Signers
         /**
          * update the internal digest with the byte array in
          */
-        public void BlockUpdate(
+        public virtual void BlockUpdate(
             byte[]	input,
             int		inOff,
             int		length)
@@ -127,7 +126,7 @@ namespace Org.BouncyCastle.Crypto.Signers
          * Generate a signature for the message we've been loaded with using
          * the key we were initialised with.
          */
-        public byte[] GenerateSignature()
+        public virtual byte[] GenerateSignature()
         {
             if (!forSigning)
                 throw new InvalidOperationException("RsaDigestSigner not initialised for signature generation.");
@@ -143,7 +142,7 @@ namespace Org.BouncyCastle.Crypto.Signers
          * return true if the internal state represents the signature described
          * in the passed in array.
          */
-        public bool VerifySignature(
+        public virtual bool VerifySignature(
             byte[] signature)
         {
             if (forSigning)
@@ -197,7 +196,7 @@ namespace Org.BouncyCastle.Crypto.Signers
             }
         }
 
-        public void Reset()
+        public virtual void Reset()
         {
             digest.Reset();
         }
diff --git a/crypto/src/crypto/signers/X931Signer.cs b/crypto/src/crypto/signers/X931Signer.cs
new file mode 100644
index 000000000..cc3292159
--- /dev/null
+++ b/crypto/src/crypto/signers/X931Signer.cs
@@ -0,0 +1,235 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Signers
+{
+    /**
+     * X9.31-1998 - signing using a hash.
+     * <p>
+     * The message digest hash, H, is encapsulated to form a byte string as follows
+     * </p>
+     * <pre>
+     * EB = 06 || PS || 0xBA || H || TRAILER
+     * </pre>
+     * where PS is a string of bytes all of value 0xBB of length such that |EB|=|n|, and TRAILER is the ISO/IEC 10118 part number† for the digest. The byte string, EB, is converted to an integer value, the message representative, f.
+     */
+    public class X931Signer
+        :   ISigner
+    {
+        public const int TRAILER_IMPLICIT    = 0xBC;
+        public const int TRAILER_RIPEMD160   = 0x31CC;
+        public const int TRAILER_RIPEMD128   = 0x32CC;
+        public const int TRAILER_SHA1        = 0x33CC;
+        public const int TRAILER_SHA256      = 0x34CC;
+        public const int TRAILER_SHA512      = 0x35CC;
+        public const int TRAILER_SHA384      = 0x36CC;
+        public const int TRAILER_WHIRLPOOL   = 0x37CC;
+        public const int TRAILER_SHA224      = 0x38CC;
+
+        private static readonly IDictionary trailerMap = Platform.CreateHashtable();
+
+        static X931Signer()
+        {
+            trailerMap.Add("RIPEMD128", TRAILER_RIPEMD128);
+            trailerMap.Add("RIPEMD160", TRAILER_RIPEMD160);
+
+            trailerMap.Add("SHA-1", TRAILER_SHA1);
+            trailerMap.Add("SHA-224", TRAILER_SHA224);
+            trailerMap.Add("SHA-256", TRAILER_SHA256);
+            trailerMap.Add("SHA-384", TRAILER_SHA384);
+            trailerMap.Add("SHA-512", TRAILER_SHA512);
+
+            trailerMap.Add("Whirlpool", TRAILER_WHIRLPOOL);
+        }
+
+        private IDigest                     digest;
+        private IAsymmetricBlockCipher      cipher;
+        private RsaKeyParameters            kParam;
+
+        private int         trailer;
+        private int         keyBits;
+        private byte[]      block;
+
+        /**
+         * Generate a signer for the with either implicit or explicit trailers
+         * for ISO9796-2.
+         *
+         * @param cipher base cipher to use for signature creation/verification
+         * @param digest digest to use.
+         * @param implicit whether or not the trailer is implicit or gives the hash.
+         */
+        public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit)
+        {
+            this.cipher = cipher;
+            this.digest = digest;
+
+            if (isImplicit)
+            {
+                trailer = TRAILER_IMPLICIT;
+            }
+            else
+            {
+                string name = digest.AlgorithmName;
+                if (!trailerMap.Contains(name))
+                    throw new ArgumentException("no valid trailer", "digest");
+
+                trailer = (int)trailerMap[name];
+            }
+        }
+
+        [Obsolete]
+        public virtual string AlgorithmName
+        {
+            get { return digest.AlgorithmName + "withX931"; }
+        }
+
+        /**
+         * Constructor for a signer with an explicit digest trailer.
+         *
+         * @param cipher cipher to use.
+         * @param digest digest to sign with.
+         */
+        public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest)
+            :   this(cipher, digest, false)
+        {
+        }
+
+        public virtual void Init(bool forSigning, ICipherParameters parameters)
+        {
+            kParam = (RsaKeyParameters)parameters;
+
+            cipher.Init(forSigning, kParam);
+
+            keyBits = kParam.Modulus.BitLength;
+
+            block = new byte[(keyBits + 7) / 8];
+
+            Reset();
+        }
+
+        /// <summary> clear possible sensitive data</summary>
+        private void ClearBlock(byte[] block)
+        {
+            Array.Clear(block, 0, block.Length);
+        }
+
+        /**
+         * update the internal digest with the byte b
+         */
+        public virtual void Update(byte b)
+        {
+            digest.Update(b);
+        }
+
+        /**
+         * update the internal digest with the byte array in
+         */
+        public virtual void BlockUpdate(byte[] input, int off, int len)
+        {
+            digest.BlockUpdate(input, off, len);
+        }
+
+        /**
+         * reset the internal state
+         */
+        public virtual void Reset()
+        {
+            digest.Reset();
+        }
+
+        /**
+         * generate a signature for the loaded message using the key we were
+         * initialised with.
+         */
+        public virtual byte[] GenerateSignature()
+        {
+            CreateSignatureBlock();
+
+            BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
+            ClearBlock(block);
+
+            t = t.Min(kParam.Modulus.Subtract(t));
+
+            return BigIntegers.AsUnsignedByteArray((kParam.Modulus.BitLength + 7) / 8, t);
+        }
+
+        private void CreateSignatureBlock()
+        {
+            int digSize = digest.GetDigestSize();
+
+            int delta;
+
+            if (trailer == TRAILER_IMPLICIT)
+            {
+                delta = block.Length - digSize - 1;
+                digest.DoFinal(block, delta);
+                block[block.Length - 1] = (byte)TRAILER_IMPLICIT;
+            }
+            else
+            {
+                delta = block.Length - digSize - 2;
+                digest.DoFinal(block, delta);
+                block[block.Length - 2] = (byte)(trailer >> 8);
+                block[block.Length - 1] = (byte)trailer;
+            }
+
+            block[0] = 0x6b;
+            for (int i = delta - 2; i != 0; i--)
+            {
+                block[i] = (byte)0xbb;
+            }
+            block[delta - 1] = (byte)0xba;
+        }
+
+        /**
+         * return true if the signature represents a ISO9796-2 signature
+         * for the passed in message.
+         */
+        public virtual bool VerifySignature(byte[] signature)
+        {
+            try
+            {
+                block = cipher.ProcessBlock(signature, 0, signature.Length);
+            }
+            catch (Exception)
+            {
+                return false;
+            }
+
+            BigInteger t = new BigInteger(block);
+            BigInteger f;
+
+            if ((t.IntValue & 15) == 12)
+            {
+                 f = t;
+            }
+            else
+            {
+                t = kParam.Modulus.Subtract(t);
+                if ((t.IntValue & 15) == 12)
+                {
+                     f = t;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+
+            CreateSignatureBlock();
+
+            byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
+
+            bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
+
+            ClearBlock(block);
+            ClearBlock(fBlock);
+
+            return rv;
+        }
+    }
+}