
org.spongycastle.crypto.agreement.ECMQVBasicAgreement Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
Spongy Castle is a package-rename (org.bouncycastle.* to org.spongycastle.*) of Bouncy Castle
intended for the Android platform. Android unfortunately ships with a stripped-down version of
Bouncy Castle, which prevents easy upgrades - Spongy Castle overcomes this and provides a full,
up-to-date version of the Bouncy Castle cryptographic libs.
The newest version!
package org.spongycastle.crypto.agreement;
import java.math.BigInteger;
import org.spongycastle.crypto.BasicAgreement;
import org.spongycastle.crypto.CipherParameters;
import org.spongycastle.crypto.params.ECDomainParameters;
import org.spongycastle.crypto.params.ECPrivateKeyParameters;
import org.spongycastle.crypto.params.ECPublicKeyParameters;
import org.spongycastle.crypto.params.MQVPrivateParameters;
import org.spongycastle.crypto.params.MQVPublicParameters;
import org.spongycastle.math.ec.ECAlgorithms;
import org.spongycastle.math.ec.ECConstants;
import org.spongycastle.math.ec.ECCurve;
import org.spongycastle.math.ec.ECPoint;
import org.spongycastle.util.Properties;
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)
{
if (Properties.isOverrideSet("org.spongycastle.ec.disable_mqv"))
{
throw new IllegalStateException("ECMQV explicitly disabled");
}
MQVPublicParameters pubParams = (MQVPublicParameters)pubKey;
ECPrivateKeyParameters staticPrivateKey = privParams.getStaticPrivateKey();
ECDomainParameters parameters = staticPrivateKey.getParameters();
if (!parameters.equals(pubParams.getStaticPublicKey().getParameters()))
{
throw new IllegalStateException("ECMQV public key components have wrong domain parameters");
}
ECPoint agreement = calculateMqvAgreement(parameters, staticPrivateKey,
privParams.getEphemeralPrivateKey(), privParams.getEphemeralPublicKey(),
pubParams.getStaticPublicKey(), pubParams.getEphemeralPublicKey()).normalize();
if (agreement.isInfinity())
{
throw new IllegalStateException("Infinity is not a valid agreement value for MQV");
}
return agreement.getAffineXCoord().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);
ECCurve curve = parameters.getCurve();
ECPoint[] points = new ECPoint[]{
// The Q2U public key is optional - but will be calculated for us if it wasn't present
ECAlgorithms.importPoint(curve, Q2U.getQ()),
ECAlgorithms.importPoint(curve, Q1V.getQ()),
ECAlgorithms.importPoint(curve, Q2V.getQ())
};
curve.normalizeAll(points);
ECPoint q2u = points[0], q1v = points[1], q2v = points[2];
BigInteger x = q2u.getAffineXCoord().toBigInteger();
BigInteger xBar = x.mod(powE);
BigInteger Q2UBar = xBar.setBit(e);
BigInteger s = d1U.getD().multiply(Q2UBar).add(d2U.getD()).mod(n);
BigInteger xPrime = q2v.getAffineXCoord().toBigInteger();
BigInteger xPrimeBar = xPrime.mod(powE);
BigInteger Q2VBar = xPrimeBar.setBit(e);
BigInteger hs = parameters.getH().multiply(s).mod(n);
return ECAlgorithms.sumOfTwoMultiplies(
q1v, Q2VBar.multiply(hs).mod(n), q2v, hs);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy