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/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java')
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java91
1 files changed, 91 insertions, 0 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java b/core/src/main/java/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java
new file mode 100644
index 00000000..da88b4ac
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java
@@ -0,0 +1,91 @@
+package org.bouncycastle.crypto.agreement;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.crypto.BasicAgreement;
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import org.bouncycastle.crypto.params.MQVPrivateParameters;
+import org.bouncycastle.crypto.params.MQVPublicParameters;
+import org.bouncycastle.math.ec.ECAlgorithms;
+import org.bouncycastle.math.ec.ECConstants;
+import org.bouncycastle.math.ec.ECPoint;
+
+public class ECMQVBasicAgreement
+ implements BasicAgreement
+{
+ MQVPrivateParameters privParams;
+
+ public void init(
+ CipherParameters key)
+ {
+ this.privParams = (MQVPrivateParameters)key;
+ }
+
+ public int getFieldSize()
+ {
+ return (privParams.getStaticPrivateKey().getParameters().getCurve().getFieldSize() + 7) / 8;
+ }
+
+ public BigInteger calculateAgreement(CipherParameters pubKey)
+ {
+ MQVPublicParameters pubParams = (MQVPublicParameters)pubKey;
+
+ ECPrivateKeyParameters staticPrivateKey = privParams.getStaticPrivateKey();
+
+ ECPoint agreement = calculateMqvAgreement(staticPrivateKey.getParameters(), staticPrivateKey,
+ privParams.getEphemeralPrivateKey(), privParams.getEphemeralPublicKey(),
+ pubParams.getStaticPublicKey(), pubParams.getEphemeralPublicKey());
+
+ return agreement.getX().toBigInteger();
+ }
+
+ // The ECMQV Primitive as described in SEC-1, 3.4
+ private ECPoint calculateMqvAgreement(
+ ECDomainParameters parameters,
+ ECPrivateKeyParameters d1U,
+ ECPrivateKeyParameters d2U,
+ ECPublicKeyParameters Q2U,
+ ECPublicKeyParameters Q1V,
+ ECPublicKeyParameters Q2V)
+ {
+ BigInteger n = parameters.getN();
+ int e = (n.bitLength() + 1) / 2;
+ BigInteger powE = ECConstants.ONE.shiftLeft(e);
+
+ // The Q2U public key is optional
+ ECPoint q;
+ if (Q2U == null)
+ {
+ q = parameters.getG().multiply(d2U.getD());
+ }
+ else
+ {
+ q = Q2U.getQ();
+ }
+
+ BigInteger x = q.getX().toBigInteger();
+ BigInteger xBar = x.mod(powE);
+ BigInteger Q2UBar = xBar.setBit(e);
+ BigInteger s = d1U.getD().multiply(Q2UBar).mod(n).add(d2U.getD()).mod(n);
+
+ BigInteger xPrime = Q2V.getQ().getX().toBigInteger();
+ BigInteger xPrimeBar = xPrime.mod(powE);
+ BigInteger Q2VBar = xPrimeBar.setBit(e);
+
+ BigInteger hs = parameters.getH().multiply(s).mod(n);
+
+// ECPoint p = Q1V.getQ().multiply(Q2VBar).add(Q2V.getQ()).multiply(hs);
+ ECPoint p = ECAlgorithms.sumOfTwoMultiplies(
+ Q1V.getQ(), Q2VBar.multiply(hs).mod(n), Q2V.getQ(), hs);
+
+ if (p.isInfinity())
+ {
+ throw new IllegalStateException("Infinity is not a valid agreement value for MQV");
+ }
+
+ return p;
+ }
+}