ECKeyPairGenerator.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Sec;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.TeleTrust;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X9;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.EC;
  11. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  12. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  13. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
  14. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
  15. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  16. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  17. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
  18. {
  19. public class ECKeyPairGenerator
  20. : IAsymmetricCipherKeyPairGenerator
  21. {
  22. private readonly string algorithm;
  23. private ECDomainParameters parameters;
  24. private DerObjectIdentifier publicKeyParamSet;
  25. private SecureRandom random;
  26. public ECKeyPairGenerator()
  27. : this("EC")
  28. {
  29. }
  30. public ECKeyPairGenerator(
  31. string algorithm)
  32. {
  33. if (algorithm == null)
  34. throw new ArgumentNullException("algorithm");
  35. this.algorithm = ECKeyParameters.VerifyAlgorithmName(algorithm);
  36. }
  37. public void Init(
  38. KeyGenerationParameters parameters)
  39. {
  40. if (parameters is ECKeyGenerationParameters)
  41. {
  42. ECKeyGenerationParameters ecP = (ECKeyGenerationParameters) parameters;
  43. this.publicKeyParamSet = ecP.PublicKeyParamSet;
  44. this.parameters = ecP.DomainParameters;
  45. }
  46. else
  47. {
  48. DerObjectIdentifier oid;
  49. switch (parameters.Strength)
  50. {
  51. case 192:
  52. oid = X9ObjectIdentifiers.Prime192v1;
  53. break;
  54. case 224:
  55. oid = SecObjectIdentifiers.SecP224r1;
  56. break;
  57. case 239:
  58. oid = X9ObjectIdentifiers.Prime239v1;
  59. break;
  60. case 256:
  61. oid = X9ObjectIdentifiers.Prime256v1;
  62. break;
  63. case 384:
  64. oid = SecObjectIdentifiers.SecP384r1;
  65. break;
  66. case 521:
  67. oid = SecObjectIdentifiers.SecP521r1;
  68. break;
  69. default:
  70. throw new InvalidParameterException("unknown key size.");
  71. }
  72. X9ECParameters ecps = FindECCurveByOid(oid);
  73. this.publicKeyParamSet = oid;
  74. this.parameters = new ECDomainParameters(
  75. ecps.Curve, ecps.G, ecps.N, ecps.H, ecps.GetSeed());
  76. }
  77. this.random = parameters.Random;
  78. if (this.random == null)
  79. {
  80. this.random = new SecureRandom();
  81. }
  82. }
  83. /**
  84. * Given the domain parameters this routine generates an EC key
  85. * pair in accordance with X9.62 section 5.2.1 pages 26, 27.
  86. */
  87. public AsymmetricCipherKeyPair GenerateKeyPair()
  88. {
  89. BigInteger n = parameters.N;
  90. BigInteger d;
  91. int minWeight = n.BitLength >> 2;
  92. for (;;)
  93. {
  94. d = new BigInteger(n.BitLength, random);
  95. if (d.CompareTo(BigInteger.One) < 0 || d.CompareTo(n) >= 0)
  96. continue;
  97. if (WNafUtilities.GetNafWeight(d) < minWeight)
  98. continue;
  99. break;
  100. }
  101. ECPoint q = CreateBasePointMultiplier().Multiply(parameters.G, d);
  102. if (publicKeyParamSet != null)
  103. {
  104. return new AsymmetricCipherKeyPair(
  105. new ECPublicKeyParameters(algorithm, q, publicKeyParamSet),
  106. new ECPrivateKeyParameters(algorithm, d, publicKeyParamSet));
  107. }
  108. return new AsymmetricCipherKeyPair(
  109. new ECPublicKeyParameters(algorithm, q, parameters),
  110. new ECPrivateKeyParameters(algorithm, d, parameters));
  111. }
  112. protected virtual ECMultiplier CreateBasePointMultiplier()
  113. {
  114. return new FixedPointCombMultiplier();
  115. }
  116. internal static X9ECParameters FindECCurveByOid(DerObjectIdentifier oid)
  117. {
  118. // TODO ECGost3410NamedCurves support (returns ECDomainParameters though)
  119. X9ECParameters ecP = CustomNamedCurves.GetByOid(oid);
  120. if (ecP == null)
  121. {
  122. ecP = ECNamedCurveTable.GetByOid(oid);
  123. }
  124. return ecP;
  125. }
  126. internal static ECPublicKeyParameters GetCorrespondingPublicKey(
  127. ECPrivateKeyParameters privKey)
  128. {
  129. ECDomainParameters ec = privKey.Parameters;
  130. ECPoint q = new FixedPointCombMultiplier().Multiply(ec.G, privKey.D);
  131. if (privKey.PublicKeyParamSet != null)
  132. {
  133. return new ECPublicKeyParameters(privKey.AlgorithmName, q, privKey.PublicKeyParamSet);
  134. }
  135. return new ECPublicKeyParameters(privKey.AlgorithmName, q, ec);
  136. }
  137. }
  138. }
  139. #pragma warning restore
  140. #endif