X9Curve.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using Org.BouncyCastle.Math;
  4. using Org.BouncyCastle.Math.EC;
  5. using Org.BouncyCastle.Utilities;
  6. namespace Org.BouncyCastle.Asn1.X9
  7. {
  8. /**
  9. * ASN.1 def for Elliptic-Curve Curve structure. See
  10. * X9.62, for further details.
  11. */
  12. public class X9Curve
  13. : Asn1Encodable
  14. {
  15. private readonly ECCurve curve;
  16. private readonly byte[] seed;
  17. private readonly DerObjectIdentifier fieldIdentifier;
  18. public X9Curve(
  19. ECCurve curve)
  20. : this(curve, null)
  21. {
  22. }
  23. public X9Curve(
  24. ECCurve curve,
  25. byte[] seed)
  26. {
  27. if (curve == null)
  28. throw new ArgumentNullException("curve");
  29. this.curve = curve;
  30. this.seed = Arrays.Clone(seed);
  31. if (ECAlgorithms.IsFpCurve(curve))
  32. {
  33. this.fieldIdentifier = X9ObjectIdentifiers.PrimeField;
  34. }
  35. else if (ECAlgorithms.IsF2mCurve(curve))
  36. {
  37. this.fieldIdentifier = X9ObjectIdentifiers.CharacteristicTwoField;
  38. }
  39. else
  40. {
  41. throw new ArgumentException("This type of ECCurve is not implemented");
  42. }
  43. }
  44. public X9Curve(
  45. X9FieldID fieldID,
  46. Asn1Sequence seq)
  47. {
  48. if (fieldID == null)
  49. throw new ArgumentNullException("fieldID");
  50. if (seq == null)
  51. throw new ArgumentNullException("seq");
  52. this.fieldIdentifier = fieldID.Identifier;
  53. if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField))
  54. {
  55. BigInteger q = ((DerInteger) fieldID.Parameters).Value;
  56. X9FieldElement x9A = new X9FieldElement(q, (Asn1OctetString) seq[0]);
  57. X9FieldElement x9B = new X9FieldElement(q, (Asn1OctetString) seq[1]);
  58. curve = new FpCurve(q, x9A.Value.ToBigInteger(), x9B.Value.ToBigInteger());
  59. }
  60. else
  61. {
  62. if (fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField))
  63. {
  64. // Characteristic two field
  65. DerSequence parameters = (DerSequence)fieldID.Parameters;
  66. int m = ((DerInteger)parameters[0]).Value.IntValue;
  67. DerObjectIdentifier representation
  68. = (DerObjectIdentifier)parameters[1];
  69. int k1 = 0;
  70. int k2 = 0;
  71. int k3 = 0;
  72. if (representation.Equals(X9ObjectIdentifiers.TPBasis))
  73. {
  74. // Trinomial basis representation
  75. k1 = ((DerInteger)parameters[2]).Value.IntValue;
  76. }
  77. else
  78. {
  79. // Pentanomial basis representation
  80. DerSequence pentanomial = (DerSequence) parameters[2];
  81. k1 = ((DerInteger) pentanomial[0]).Value.IntValue;
  82. k2 = ((DerInteger) pentanomial[1]).Value.IntValue;
  83. k3 = ((DerInteger) pentanomial[2]).Value.IntValue;
  84. }
  85. X9FieldElement x9A = new X9FieldElement(m, k1, k2, k3, (Asn1OctetString)seq[0]);
  86. X9FieldElement x9B = new X9FieldElement(m, k1, k2, k3, (Asn1OctetString)seq[1]);
  87. // TODO Is it possible to get the order (n) and cofactor(h) too?
  88. curve = new F2mCurve(m, k1, k2, k3, x9A.Value.ToBigInteger(), x9B.Value.ToBigInteger());
  89. }
  90. }
  91. if (seq.Count == 3)
  92. {
  93. seed = ((DerBitString) seq[2]).GetBytes();
  94. }
  95. }
  96. public ECCurve Curve
  97. {
  98. get { return curve; }
  99. }
  100. public byte[] GetSeed()
  101. {
  102. return Arrays.Clone(seed);
  103. }
  104. /**
  105. * Produce an object suitable for an Asn1OutputStream.
  106. * <pre>
  107. * Curve ::= Sequence {
  108. * a FieldElement,
  109. * b FieldElement,
  110. * seed BIT STRING OPTIONAL
  111. * }
  112. * </pre>
  113. */
  114. public override Asn1Object ToAsn1Object()
  115. {
  116. Asn1EncodableVector v = new Asn1EncodableVector();
  117. if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField)
  118. || fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField))
  119. {
  120. v.Add(new X9FieldElement(curve.A).ToAsn1Object());
  121. v.Add(new X9FieldElement(curve.B).ToAsn1Object());
  122. }
  123. if (seed != null)
  124. {
  125. v.Add(new DerBitString(seed));
  126. }
  127. return new DerSequence(v);
  128. }
  129. }
  130. }
  131. #endif