You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
3.3 KiB
90 lines
3.3 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC; |
|
|
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement |
|
{ |
|
public class ECMqvBasicAgreement |
|
: IBasicAgreement |
|
{ |
|
protected internal MqvPrivateParameters privParams; |
|
|
|
public virtual void Init( |
|
ICipherParameters parameters) |
|
{ |
|
if (parameters is ParametersWithRandom) |
|
{ |
|
parameters = ((ParametersWithRandom)parameters).Parameters; |
|
} |
|
|
|
this.privParams = (MqvPrivateParameters)parameters; |
|
} |
|
|
|
public virtual int GetFieldSize() |
|
{ |
|
return (privParams.StaticPrivateKey.Parameters.Curve.FieldSize + 7) / 8; |
|
} |
|
|
|
public virtual BigInteger CalculateAgreement( |
|
ICipherParameters pubKey) |
|
{ |
|
MqvPublicParameters pubParams = (MqvPublicParameters)pubKey; |
|
|
|
ECPrivateKeyParameters staticPrivateKey = privParams.StaticPrivateKey; |
|
ECDomainParameters parameters = staticPrivateKey.Parameters; |
|
|
|
if (!parameters.Equals(pubParams.StaticPublicKey.Parameters)) |
|
throw new InvalidOperationException("ECMQV public key components have wrong domain parameters"); |
|
|
|
ECPoint agreement = CalculateMqvAgreement(parameters, staticPrivateKey, |
|
privParams.EphemeralPrivateKey, privParams.EphemeralPublicKey, |
|
pubParams.StaticPublicKey, pubParams.EphemeralPublicKey).Normalize(); |
|
|
|
if (agreement.IsInfinity) |
|
throw new InvalidOperationException("Infinity is not a valid agreement value for MQV"); |
|
|
|
return agreement.AffineXCoord.ToBigInteger(); |
|
} |
|
|
|
// The ECMQV Primitive as described in SEC-1, 3.4 |
|
private static ECPoint CalculateMqvAgreement( |
|
ECDomainParameters parameters, |
|
ECPrivateKeyParameters d1U, |
|
ECPrivateKeyParameters d2U, |
|
ECPublicKeyParameters Q2U, |
|
ECPublicKeyParameters Q1V, |
|
ECPublicKeyParameters Q2V) |
|
{ |
|
BigInteger n = parameters.N; |
|
int e = (n.BitLength + 1) / 2; |
|
BigInteger powE = BigInteger.One.ShiftLeft(e); |
|
|
|
ECCurve curve = parameters.Curve; |
|
|
|
ECPoint q2u = ECAlgorithms.CleanPoint(curve, Q2U.Q); |
|
ECPoint q1v = ECAlgorithms.CleanPoint(curve, Q1V.Q); |
|
ECPoint q2v = ECAlgorithms.CleanPoint(curve, Q2V.Q); |
|
|
|
BigInteger x = q2u.AffineXCoord.ToBigInteger(); |
|
BigInteger xBar = x.Mod(powE); |
|
BigInteger Q2UBar = xBar.SetBit(e); |
|
BigInteger s = d1U.D.Multiply(Q2UBar).Add(d2U.D).Mod(n); |
|
|
|
BigInteger xPrime = q2v.AffineXCoord.ToBigInteger(); |
|
BigInteger xPrimeBar = xPrime.Mod(powE); |
|
BigInteger Q2VBar = xPrimeBar.SetBit(e); |
|
|
|
BigInteger hs = parameters.H.Multiply(s).Mod(n); |
|
|
|
return ECAlgorithms.SumOfTwoMultiplies( |
|
q1v, Q2VBar.Multiply(hs).Mod(n), q2v, hs); |
|
} |
|
} |
|
} |
|
#pragma warning restore |
|
#endif
|
|
|