ECDHBasicAgreement
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using System;
namespace Org.BouncyCastle.Crypto.Agreement
{
public class ECDHBasicAgreement : IBasicAgreement
{
protected internal ECPrivateKeyParameters privKey;
public virtual void Init(ICipherParameters parameters)
{
ParametersWithRandom parametersWithRandom = parameters as ParametersWithRandom;
if (parametersWithRandom != null)
parameters = parametersWithRandom.Parameters;
ECPrivateKeyParameters eCPrivateKeyParameters = parameters as ECPrivateKeyParameters;
if (eCPrivateKeyParameters == null)
throw new ArgumentException("ECDHBasicAgreement expects ECPrivateKeyParameters");
privKey = eCPrivateKeyParameters;
}
public virtual int GetFieldSize()
{
return privKey.Parameters.Curve.FieldElementEncodingLength;
}
public virtual BigInteger CalculateAgreement(ICipherParameters pubKey)
{
ECPublicKeyParameters eCPublicKeyParameters = (ECPublicKeyParameters)pubKey;
ECDomainParameters parameters = privKey.Parameters;
if (!parameters.Equals(eCPublicKeyParameters.Parameters))
throw new InvalidOperationException("ECDH public key has wrong domain parameters");
BigInteger bigInteger = privKey.D;
ECPoint eCPoint = ECAlgorithms.CleanPoint(parameters.Curve, eCPublicKeyParameters.Q);
if (eCPoint.IsInfinity)
throw new InvalidOperationException("Infinity is not a valid public key for ECDH");
BigInteger h = parameters.H;
if (!h.Equals(BigInteger.One)) {
bigInteger = parameters.HInv.Multiply(bigInteger).Mod(parameters.N);
eCPoint = ECAlgorithms.ReferenceMultiply(eCPoint, h);
}
ECPoint eCPoint2 = eCPoint.Multiply(bigInteger).Normalize();
if (eCPoint2.IsInfinity)
throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH");
return eCPoint2.AffineXCoord.ToBigInteger();
}
}
}