<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.1" />

ECDHCBasicAgreement

using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using System; namespace Org.BouncyCastle.Crypto.Agreement { public class ECDHCBasicAgreement : IBasicAgreement { private 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("ECDHCBasicAgreement 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("ECDHC public key has wrong domain parameters"); BigInteger b = parameters.H.Multiply(privKey.D).Mod(parameters.N); ECPoint eCPoint = ECAlgorithms.CleanPoint(parameters.Curve, eCPublicKeyParameters.Q); if (eCPoint.IsInfinity) throw new InvalidOperationException("Infinity is not a valid public key for ECDHC"); ECPoint eCPoint2 = eCPoint.Multiply(b).Normalize(); if (eCPoint2.IsInfinity) throw new InvalidOperationException("Infinity is not a valid agreement value for ECDHC"); return eCPoint2.AffineXCoord.ToBigInteger(); } } }