summary refs log tree commit diff
path: root/Crypto/src/crypto/engines/RSABlindingEngine.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/crypto/engines/RSABlindingEngine.cs')
-rw-r--r--Crypto/src/crypto/engines/RSABlindingEngine.cs139
1 files changed, 139 insertions, 0 deletions
diff --git a/Crypto/src/crypto/engines/RSABlindingEngine.cs b/Crypto/src/crypto/engines/RSABlindingEngine.cs
new file mode 100644
index 000000000..76b57a3f7
--- /dev/null
+++ b/Crypto/src/crypto/engines/RSABlindingEngine.cs
@@ -0,0 +1,139 @@
+using System;
+
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Crypto.Engines
+{
+	/**
+	* This does your basic RSA Chaum's blinding and unblinding as outlined in
+	* "Handbook of Applied Cryptography", page 475. You need to use this if you are
+	* trying to get another party to generate signatures without them being aware
+	* of the message they are signing.
+	*/
+	public class RsaBlindingEngine
+		: IAsymmetricBlockCipher
+	{
+		private readonly RsaCoreEngine core = new RsaCoreEngine();
+
+		private RsaKeyParameters key;
+		private BigInteger blindingFactor;
+
+		private bool forEncryption;
+
+		public string AlgorithmName
+		{
+			get { return "RSA"; }
+		}
+
+		/**
+		* Initialise the blinding engine.
+		*
+		* @param forEncryption true if we are encrypting (blinding), false otherwise.
+		* @param param         the necessary RSA key parameters.
+		*/
+		public void Init(
+			bool				forEncryption,
+			ICipherParameters	param)
+		{
+			RsaBlindingParameters p;
+
+			if (param is ParametersWithRandom)
+			{
+				ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+				p = (RsaBlindingParameters)rParam.Parameters;
+			}
+			else
+			{
+				p = (RsaBlindingParameters)param;
+			}
+
+			core.Init(forEncryption, p.PublicKey);
+
+			this.forEncryption = forEncryption;
+			this.key = p.PublicKey;
+			this.blindingFactor = p.BlindingFactor;
+		}
+
+		/**
+		* Return the maximum size for an input block to this engine.
+		* For RSA this is always one byte less than the key size on
+		* encryption, and the same length as the key size on decryption.
+		*
+		* @return maximum size for an input block.
+		*/
+		public int GetInputBlockSize()
+		{
+			return core.GetInputBlockSize();
+		}
+
+		/**
+		* Return the maximum size for an output block to this engine.
+		* For RSA this is always one byte less than the key size on
+		* decryption, and the same length as the key size on encryption.
+		*
+		* @return maximum size for an output block.
+		*/
+		public int GetOutputBlockSize()
+		{
+			return core.GetOutputBlockSize();
+		}
+
+		/**
+		* Process a single block using the RSA blinding algorithm.
+		*
+		* @param in    the input array.
+		* @param inOff the offset into the input buffer where the data starts.
+		* @param inLen the length of the data to be processed.
+		* @return the result of the RSA process.
+		* @throws DataLengthException the input block is too large.
+		*/
+		public byte[] ProcessBlock(
+			byte[]	inBuf,
+			int		inOff,
+			int		inLen)
+		{
+			BigInteger msg = core.ConvertInput(inBuf, inOff, inLen);
+
+			if (forEncryption)
+			{
+				msg = BlindMessage(msg);
+			}
+			else
+			{
+				msg = UnblindMessage(msg);
+			}
+
+			return core.ConvertOutput(msg);
+		}
+
+		/*
+		* Blind message with the blind factor.
+		*/
+		private BigInteger BlindMessage(
+			BigInteger msg)
+		{
+			BigInteger blindMsg = blindingFactor;
+			blindMsg = msg.Multiply(blindMsg.ModPow(key.Exponent, key.Modulus));
+			blindMsg = blindMsg.Mod(key.Modulus);
+
+			return blindMsg;
+		}
+
+		/*
+		* Unblind the message blinded with the blind factor.
+		*/
+		private BigInteger UnblindMessage(
+			BigInteger blindedMsg)
+		{
+			BigInteger m = key.Modulus;
+			BigInteger msg = blindedMsg;
+			BigInteger blindFactorInverse = blindingFactor.ModInverse(m);
+			msg = msg.Multiply(blindFactorInverse);
+			msg = msg.Mod(m);
+
+			return msg;
+		}
+	}
+}