ECMqvBasicAgreement.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement
  9. {
  10. public class ECMqvBasicAgreement
  11. : IBasicAgreement
  12. {
  13. protected internal MqvPrivateParameters privParams;
  14. public virtual void Init(
  15. ICipherParameters parameters)
  16. {
  17. if (parameters is ParametersWithRandom)
  18. {
  19. parameters = ((ParametersWithRandom)parameters).Parameters;
  20. }
  21. this.privParams = (MqvPrivateParameters)parameters;
  22. }
  23. public virtual int GetFieldSize()
  24. {
  25. return (privParams.StaticPrivateKey.Parameters.Curve.FieldSize + 7) / 8;
  26. }
  27. public virtual BigInteger CalculateAgreement(
  28. ICipherParameters pubKey)
  29. {
  30. MqvPublicParameters pubParams = (MqvPublicParameters)pubKey;
  31. ECPrivateKeyParameters staticPrivateKey = privParams.StaticPrivateKey;
  32. ECDomainParameters parameters = staticPrivateKey.Parameters;
  33. if (!parameters.Equals(pubParams.StaticPublicKey.Parameters))
  34. throw new InvalidOperationException("ECMQV public key components have wrong domain parameters");
  35. ECPoint agreement = CalculateMqvAgreement(parameters, staticPrivateKey,
  36. privParams.EphemeralPrivateKey, privParams.EphemeralPublicKey,
  37. pubParams.StaticPublicKey, pubParams.EphemeralPublicKey).Normalize();
  38. if (agreement.IsInfinity)
  39. throw new InvalidOperationException("Infinity is not a valid agreement value for MQV");
  40. return agreement.AffineXCoord.ToBigInteger();
  41. }
  42. // The ECMQV Primitive as described in SEC-1, 3.4
  43. private static ECPoint CalculateMqvAgreement(
  44. ECDomainParameters parameters,
  45. ECPrivateKeyParameters d1U,
  46. ECPrivateKeyParameters d2U,
  47. ECPublicKeyParameters Q2U,
  48. ECPublicKeyParameters Q1V,
  49. ECPublicKeyParameters Q2V)
  50. {
  51. BigInteger n = parameters.N;
  52. int e = (n.BitLength + 1) / 2;
  53. BigInteger powE = BigInteger.One.ShiftLeft(e);
  54. ECCurve curve = parameters.Curve;
  55. ECPoint q2u = ECAlgorithms.CleanPoint(curve, Q2U.Q);
  56. ECPoint q1v = ECAlgorithms.CleanPoint(curve, Q1V.Q);
  57. ECPoint q2v = ECAlgorithms.CleanPoint(curve, Q2V.Q);
  58. BigInteger x = q2u.AffineXCoord.ToBigInteger();
  59. BigInteger xBar = x.Mod(powE);
  60. BigInteger Q2UBar = xBar.SetBit(e);
  61. BigInteger s = d1U.D.Multiply(Q2UBar).Add(d2U.D).Mod(n);
  62. BigInteger xPrime = q2v.AffineXCoord.ToBigInteger();
  63. BigInteger xPrimeBar = xPrime.Mod(powE);
  64. BigInteger Q2VBar = xPrimeBar.SetBit(e);
  65. BigInteger hs = parameters.H.Multiply(s).Mod(n);
  66. return ECAlgorithms.SumOfTwoMultiplies(
  67. q1v, Q2VBar.Multiply(hs).Mod(n), q2v, hs);
  68. }
  69. }
  70. }
  71. #pragma warning restore
  72. #endif