Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/spongycastle/crypto/engines/RSABlindedEngine.java')
-rw-r--r--core/src/main/java/org/spongycastle/crypto/engines/RSABlindedEngine.java126
1 files changed, 126 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/crypto/engines/RSABlindedEngine.java b/core/src/main/java/org/spongycastle/crypto/engines/RSABlindedEngine.java
new file mode 100644
index 00000000..d254f1c6
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/crypto/engines/RSABlindedEngine.java
@@ -0,0 +1,126 @@
+package org.spongycastle.crypto.engines;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import org.spongycastle.crypto.AsymmetricBlockCipher;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.DataLengthException;
+import org.spongycastle.crypto.params.ParametersWithRandom;
+import org.spongycastle.crypto.params.RSAKeyParameters;
+import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import org.spongycastle.util.BigIntegers;
+
+/**
+ * this does your basic RSA algorithm with blinding
+ */
+public class RSABlindedEngine
+ implements AsymmetricBlockCipher
+{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
+ private RSACoreEngine core = new RSACoreEngine();
+ private RSAKeyParameters key;
+ private SecureRandom random;
+
+ /**
+ * initialise the RSA engine.
+ *
+ * @param forEncryption true if we are encrypting, false otherwise.
+ * @param param the necessary RSA key parameters.
+ */
+ public void init(
+ boolean forEncryption,
+ CipherParameters param)
+ {
+ core.init(forEncryption, param);
+
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ key = (RSAKeyParameters)rParam.getParameters();
+ random = rParam.getRandom();
+ }
+ else
+ {
+ key = (RSAKeyParameters)param;
+ random = new SecureRandom();
+ }
+ }
+
+ /**
+ * 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 basic RSA 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.
+ * @exception DataLengthException the input block is too large.
+ */
+ public byte[] processBlock(
+ byte[] in,
+ int inOff,
+ int inLen)
+ {
+ if (key == null)
+ {
+ throw new IllegalStateException("RSA engine not initialised");
+ }
+
+ BigInteger input = core.convertInput(in, inOff, inLen);
+
+ BigInteger result;
+ if (key instanceof RSAPrivateCrtKeyParameters)
+ {
+ RSAPrivateCrtKeyParameters k = (RSAPrivateCrtKeyParameters)key;
+
+ BigInteger e = k.getPublicExponent();
+ if (e != null) // can't do blinding without a public exponent
+ {
+ BigInteger m = k.getModulus();
+ BigInteger r = BigIntegers.createRandomInRange(ONE, m.subtract(ONE), random);
+
+ BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m);
+ BigInteger blindedResult = core.processBlock(blindedInput);
+
+ BigInteger rInv = r.modInverse(m);
+ result = blindedResult.multiply(rInv).mod(m);
+ }
+ else
+ {
+ result = core.processBlock(input);
+ }
+ }
+ else
+ {
+ result = core.processBlock(input);
+ }
+
+ return core.convertOutput(result);
+ }
+}