ECDHCBasicAgreement.cs 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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.Security;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  9. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement
  10. {
  11. /**
  12. * P1363 7.2.2 ECSVDP-DHC
  13. *
  14. * ECSVDP-DHC is Elliptic Curve Secret Value Derivation Primitive,
  15. * Diffie-Hellman version with cofactor multiplication. It is based on
  16. * the work of [DH76], [Mil86], [Kob87], [LMQ98] and [Kal98a]. This
  17. * primitive derives a shared secret value from one party's private key
  18. * and another party's public key, where both have the same set of EC
  19. * domain parameters. If two parties correctly execute this primitive,
  20. * they will produce the same output. This primitive can be invoked by a
  21. * scheme to derive a shared secret key; specifically, it may be used
  22. * with the schemes ECKAS-DH1 and DL/ECKAS-DH2. It does not assume the
  23. * validity of the input public key (see also Section 7.2.1).
  24. * <p>
  25. * Note: As stated P1363 compatibility mode with ECDH can be preset, and
  26. * in this case the implementation doesn't have a ECDH compatibility mode
  27. * (if you want that just use ECDHBasicAgreement and note they both implement
  28. * BasicAgreement!).</p>
  29. */
  30. public class ECDHCBasicAgreement
  31. : IBasicAgreement
  32. {
  33. private ECPrivateKeyParameters privKey;
  34. public virtual void Init(
  35. ICipherParameters parameters)
  36. {
  37. if (parameters is ParametersWithRandom)
  38. {
  39. parameters = ((ParametersWithRandom) parameters).Parameters;
  40. }
  41. this.privKey = (ECPrivateKeyParameters)parameters;
  42. }
  43. public virtual int GetFieldSize()
  44. {
  45. return (privKey.Parameters.Curve.FieldSize + 7) / 8;
  46. }
  47. public virtual BigInteger CalculateAgreement(
  48. ICipherParameters pubKey)
  49. {
  50. ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey;
  51. ECDomainParameters dp = privKey.Parameters;
  52. if (!dp.Equals(pub.Parameters))
  53. throw new InvalidOperationException("ECDHC public key has wrong domain parameters");
  54. BigInteger hd = dp.H.Multiply(privKey.D).Mod(dp.N);
  55. // Always perform calculations on the exact curve specified by our private key's parameters
  56. ECPoint pubPoint = ECAlgorithms.CleanPoint(dp.Curve, pub.Q);
  57. if (pubPoint.IsInfinity)
  58. throw new InvalidOperationException("Infinity is not a valid public key for ECDHC");
  59. ECPoint P = pubPoint.Multiply(hd).Normalize();
  60. if (P.IsInfinity)
  61. throw new InvalidOperationException("Infinity is not a valid agreement value for ECDHC");
  62. return P.AffineXCoord.ToBigInteger();
  63. }
  64. }
  65. }
  66. #pragma warning restore
  67. #endif