diff options
author | David Hook <dgh@cryptoworkshop.com> | 2013-05-31 11:07:45 +0400 |
---|---|---|
committer | David Hook <dgh@cryptoworkshop.com> | 2013-05-31 11:07:45 +0400 |
commit | 2b976f5364cfdbc37d3086019d93483c983eb80b (patch) | |
tree | cb846af3fd1d43f9c2562a1fb2d06b997ad8f229 /core/src/main/java/org/bouncycastle/crypto/agreement/ECMQVBasicAgreement.java | |
parent | 5f714bd92fbd780d22406f4bc3681be005f6f04a (diff) |
initial reshuffle
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.java | 91 |
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; + } +} |