JPakePrimeOrderGroup.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.JPake
  6. {
  7. /// <summary>
  8. /// A pre-computed prime order group for use during a J-PAKE exchange.
  9. ///
  10. /// Typically a Schnorr group is used. In general, J-PAKE can use any prime order group
  11. /// that is suitable for public key cryptography, including elliptic curve cryptography.
  12. ///
  13. /// See JPakePrimeOrderGroups for convenient standard groups.
  14. ///
  15. /// NIST <a href="http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/DSA2_All.pdf">publishes</a>
  16. /// many groups that can be used for the desired level of security.
  17. /// </summary>
  18. public class JPakePrimeOrderGroup
  19. {
  20. private readonly BigInteger p;
  21. private readonly BigInteger q;
  22. private readonly BigInteger g;
  23. /// <summary>
  24. /// Constructs a new JPakePrimeOrderGroup.
  25. ///
  26. /// In general, you should use one of the pre-approved groups from
  27. /// JPakePrimeOrderGroups, rather than manually constructing one.
  28. ///
  29. /// The following basic checks are performed:
  30. ///
  31. /// p-1 must be evenly divisible by q
  32. /// g must be in [2, p-1]
  33. /// g^q mod p must equal 1
  34. /// p must be prime (within reasonably certainty)
  35. /// q must be prime (within reasonably certainty)
  36. ///
  37. /// The prime checks are performed using BigInteger#isProbablePrime(int),
  38. /// and are therefore subject to the same probability guarantees.
  39. ///
  40. /// These checks prevent trivial mistakes.
  41. /// However, due to the small uncertainties if p and q are not prime,
  42. /// advanced attacks are not prevented.
  43. /// Use it at your own risk.
  44. ///
  45. /// Throws NullReferenceException if any argument is null. Throws
  46. /// InvalidOperationException is any of the above validations fail.
  47. /// </summary>
  48. public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g)
  49. : this(p, q, g, false)
  50. {
  51. // Don't skip the checks on user-specified groups.
  52. }
  53. /// <summary>
  54. /// Constructor used by the pre-approved groups in JPakePrimeOrderGroups.
  55. /// These pre-approved groups can avoid the expensive checks.
  56. /// User-specified groups should not use this constructor.
  57. /// </summary>
  58. public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, bool skipChecks)
  59. {
  60. JPakeUtilities.ValidateNotNull(p, "p");
  61. JPakeUtilities.ValidateNotNull(q, "q");
  62. JPakeUtilities.ValidateNotNull(g, "g");
  63. if (!skipChecks)
  64. {
  65. if (!p.Subtract(JPakeUtilities.One).Mod(q).Equals(JPakeUtilities.Zero))
  66. throw new ArgumentException("p-1 must be evenly divisible by q");
  67. if (g.CompareTo(BigInteger.Two) == -1 || g.CompareTo(p.Subtract(JPakeUtilities.One)) == 1)
  68. throw new ArgumentException("g must be in [2, p-1]");
  69. if (!g.ModPow(q, p).Equals(JPakeUtilities.One))
  70. throw new ArgumentException("g^q mod p must equal 1");
  71. // Note these checks do not guarantee that p and q are prime.
  72. // We just have reasonable certainty that they are prime.
  73. if (!p.IsProbablePrime(20))
  74. throw new ArgumentException("p must be prime");
  75. if (!q.IsProbablePrime(20))
  76. throw new ArgumentException("q must be prime");
  77. }
  78. this.p = p;
  79. this.q = q;
  80. this.g = g;
  81. }
  82. public virtual BigInteger P
  83. {
  84. get { return p; }
  85. }
  86. public virtual BigInteger Q
  87. {
  88. get { return q; }
  89. }
  90. public virtual BigInteger G
  91. {
  92. get { return g; }
  93. }
  94. }
  95. }
  96. #pragma warning restore
  97. #endif