ECDHBasicAgreement.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement
  9. {
  10. /**
  11. * P1363 7.2.1 ECSVDP-DH
  12. *
  13. * ECSVDP-DH is Elliptic Curve Secret Value Derivation Primitive,
  14. * Diffie-Hellman version. It is based on the work of [DH76], [Mil86],
  15. * and [Kob87]. This primitive derives a shared secret value from one
  16. * party's private key and another party's public key, where both have
  17. * the same set of EC domain parameters. If two parties correctly
  18. * execute this primitive, they will produce the same output. This
  19. * primitive can be invoked by a scheme to derive a shared secret key;
  20. * specifically, it may be used with the schemes ECKAS-DH1 and
  21. * DL/ECKAS-DH2. It assumes that the input keys are valid (see also
  22. * Section 7.2.2).
  23. */
  24. public class ECDHBasicAgreement
  25. : IBasicAgreement
  26. {
  27. protected internal ECPrivateKeyParameters privKey;
  28. public virtual void Init(
  29. ICipherParameters parameters)
  30. {
  31. if (parameters is ParametersWithRandom)
  32. {
  33. parameters = ((ParametersWithRandom)parameters).Parameters;
  34. }
  35. this.privKey = (ECPrivateKeyParameters)parameters;
  36. }
  37. public virtual int GetFieldSize()
  38. {
  39. return (privKey.Parameters.Curve.FieldSize + 7) / 8;
  40. }
  41. public virtual BigInteger CalculateAgreement(
  42. ICipherParameters pubKey)
  43. {
  44. ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey;
  45. ECDomainParameters dp = privKey.Parameters;
  46. if (!dp.Equals(pub.Parameters))
  47. throw new InvalidOperationException("ECDH public key has wrong domain parameters");
  48. BigInteger d = privKey.D;
  49. // Always perform calculations on the exact curve specified by our private key's parameters
  50. ECPoint Q = ECAlgorithms.CleanPoint(dp.Curve, pub.Q);
  51. if (Q.IsInfinity)
  52. throw new InvalidOperationException("Infinity is not a valid public key for ECDH");
  53. BigInteger h = dp.H;
  54. if (!h.Equals(BigInteger.One))
  55. {
  56. d = dp.HInv.Multiply(d).Mod(dp.N);
  57. Q = ECAlgorithms.ReferenceMultiply(Q, h);
  58. }
  59. ECPoint P = Q.Multiply(d).Normalize();
  60. if (P.IsInfinity)
  61. throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH");
  62. return P.AffineXCoord.ToBigInteger();
  63. }
  64. }
  65. }
  66. #pragma warning restore
  67. #endif