123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters
- {
- public class DHPublicKeyParameters
- : DHKeyParameters
- {
- private static BigInteger Validate(BigInteger y, DHParameters dhParams)
- {
- if (y == null)
- throw new ArgumentNullException("y");
- BigInteger p = dhParams.P;
- // TLS check
- if (y.CompareTo(BigInteger.Two) < 0 || y.CompareTo(p.Subtract(BigInteger.Two)) > 0)
- throw new ArgumentException("invalid DH public key", "y");
- BigInteger q = dhParams.Q;
- // We can't validate without Q.
- if (q == null)
- return y;
- if (p.TestBit(0)
- && p.BitLength - 1 == q.BitLength
- && p.ShiftRight(1).Equals(q))
- {
- // Safe prime case
- if (1 == Legendre(y, p))
- return y;
- }
- else
- {
- if (BigInteger.One.Equals(y.ModPow(q, p)))
- return y;
- }
- throw new ArgumentException("value does not appear to be in correct group", "y");
- }
- private readonly BigInteger y;
- public DHPublicKeyParameters(
- BigInteger y,
- DHParameters parameters)
- : base(false, parameters)
- {
- this.y = Validate(y, parameters);
- }
- public DHPublicKeyParameters(
- BigInteger y,
- DHParameters parameters,
- DerObjectIdentifier algorithmOid)
- : base(false, parameters, algorithmOid)
- {
- this.y = Validate(y, parameters);
- }
- public virtual BigInteger Y
- {
- get { return y; }
- }
- public override bool Equals(
- object obj)
- {
- if (obj == this)
- return true;
- DHPublicKeyParameters other = obj as DHPublicKeyParameters;
- if (other == null)
- return false;
- return Equals(other);
- }
- protected bool Equals(
- DHPublicKeyParameters other)
- {
- return y.Equals(other.y) && base.Equals(other);
- }
- public override int GetHashCode()
- {
- return y.GetHashCode() ^ base.GetHashCode();
- }
- private static int Legendre(BigInteger a, BigInteger b)
- {
- //int r = 0, bits = b.IntValue;
- //for (;;)
- //{
- // int lowestSetBit = a.GetLowestSetBit();
- // a = a.ShiftRight(lowestSetBit);
- // r ^= (bits ^ (bits >> 1)) & (lowestSetBit << 1);
- // int cmp = a.CompareTo(b);
- // if (cmp == 0)
- // break;
- // if (cmp < 0)
- // {
- // BigInteger t = a; a = b; b = t;
- // int oldBits = bits;
- // bits = b.IntValue;
- // r ^= oldBits & bits;
- // }
- // a = a.Subtract(b);
- //}
- //return BigInteger.One.Equals(b) ? (1 - (r & 2)) : 0;
- int bitLength = b.BitLength;
- uint[] A = Nat.FromBigInteger(bitLength, a);
- uint[] B = Nat.FromBigInteger(bitLength, b);
- int r = 0;
- int len = B.Length;
- for (;;)
- {
- while (A[0] == 0)
- {
- Nat.ShiftDownWord(len, A, 0);
- }
- int shift = Integers.NumberOfTrailingZeros((int)A[0]);
- if (shift > 0)
- {
- Nat.ShiftDownBits(len, A, shift, 0);
- int bits = (int)B[0];
- r ^= (bits ^ (bits >> 1)) & (shift << 1);
- }
- int cmp = Nat.Compare(len, A, B);
- if (cmp == 0)
- break;
- if (cmp < 0)
- {
- r ^= (int)(A[0] & B[0]);
- uint[] t = A; A = B; B = t;
- }
- while (A[len - 1] == 0)
- {
- len = len - 1;
- }
- Nat.Sub(len, A, B, A);
- }
- return Nat.IsOne(len, B) ? (1 - (r & 2)) : 0;
- }
- }
- }
- #pragma warning restore
- #endif
|