123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.JPake
- {
- /// <summary>
- /// A pre-computed prime order group for use during a J-PAKE exchange.
- ///
- /// Typically a Schnorr group is used. In general, J-PAKE can use any prime order group
- /// that is suitable for public key cryptography, including elliptic curve cryptography.
- ///
- /// See JPakePrimeOrderGroups for convenient standard groups.
- ///
- /// NIST <a href="http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/DSA2_All.pdf">publishes</a>
- /// many groups that can be used for the desired level of security.
- /// </summary>
- public class JPakePrimeOrderGroup
- {
- private readonly BigInteger p;
- private readonly BigInteger q;
- private readonly BigInteger g;
- /// <summary>
- /// Constructs a new JPakePrimeOrderGroup.
- ///
- /// In general, you should use one of the pre-approved groups from
- /// JPakePrimeOrderGroups, rather than manually constructing one.
- ///
- /// The following basic checks are performed:
- ///
- /// p-1 must be evenly divisible by q
- /// g must be in [2, p-1]
- /// g^q mod p must equal 1
- /// p must be prime (within reasonably certainty)
- /// q must be prime (within reasonably certainty)
- ///
- /// The prime checks are performed using BigInteger#isProbablePrime(int),
- /// and are therefore subject to the same probability guarantees.
- ///
- /// These checks prevent trivial mistakes.
- /// However, due to the small uncertainties if p and q are not prime,
- /// advanced attacks are not prevented.
- /// Use it at your own risk.
- ///
- /// Throws NullReferenceException if any argument is null. Throws
- /// InvalidOperationException is any of the above validations fail.
- /// </summary>
- public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g)
- : this(p, q, g, false)
- {
- // Don't skip the checks on user-specified groups.
- }
- /// <summary>
- /// Constructor used by the pre-approved groups in JPakePrimeOrderGroups.
- /// These pre-approved groups can avoid the expensive checks.
- /// User-specified groups should not use this constructor.
- /// </summary>
- public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, bool skipChecks)
- {
- JPakeUtilities.ValidateNotNull(p, "p");
- JPakeUtilities.ValidateNotNull(q, "q");
- JPakeUtilities.ValidateNotNull(g, "g");
- if (!skipChecks)
- {
- if (!p.Subtract(JPakeUtilities.One).Mod(q).Equals(JPakeUtilities.Zero))
- throw new ArgumentException("p-1 must be evenly divisible by q");
- if (g.CompareTo(BigInteger.Two) == -1 || g.CompareTo(p.Subtract(JPakeUtilities.One)) == 1)
- throw new ArgumentException("g must be in [2, p-1]");
- if (!g.ModPow(q, p).Equals(JPakeUtilities.One))
- throw new ArgumentException("g^q mod p must equal 1");
- // Note these checks do not guarantee that p and q are prime.
- // We just have reasonable certainty that they are prime.
- if (!p.IsProbablePrime(20))
- throw new ArgumentException("p must be prime");
- if (!q.IsProbablePrime(20))
- throw new ArgumentException("q must be prime");
- }
- this.p = p;
- this.q = q;
- this.g = g;
- }
- public virtual BigInteger P
- {
- get { return p; }
- }
- public virtual BigInteger Q
- {
- get { return q; }
- }
- public virtual BigInteger G
- {
- get { return g; }
- }
- }
- }
- #pragma warning restore
- #endif
|