DHPublicKeyParameters
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.Raw;
using Org.BouncyCastle.Utilities;
using System;
namespace Org.BouncyCastle.Crypto.Parameters
{
public class DHPublicKeyParameters : DHKeyParameters
{
private readonly BigInteger m_y;
public virtual BigInteger Y => m_y;
private static BigInteger Validate(BigInteger y, DHParameters dhParams)
{
if (y == null)
throw new ArgumentNullException("y");
BigInteger p = dhParams.P;
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;
if (q == null)
return y;
if (p.TestBit(0) && p.BitLength - 1 == q.BitLength && p.ShiftRight(1).Equals(q)) {
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");
}
public DHPublicKeyParameters(BigInteger y, DHParameters parameters)
: base(false, parameters)
{
m_y = Validate(y, parameters);
}
public DHPublicKeyParameters(BigInteger y, DHParameters parameters, DerObjectIdentifier algorithmOid)
: base(false, parameters, algorithmOid)
{
m_y = Validate(y, parameters);
}
public override bool Equals(object obj)
{
if (obj == this)
return true;
DHPublicKeyParameters dHPublicKeyParameters = obj as DHPublicKeyParameters;
if (dHPublicKeyParameters == null)
return false;
return Equals(dHPublicKeyParameters);
}
protected bool Equals(DHPublicKeyParameters other)
{
if (m_y.Equals(other.m_y))
return Equals((DHKeyParameters)other);
return false;
}
public override int GetHashCode()
{
return m_y.GetHashCode() ^ base.GetHashCode();
}
private static int Legendre(BigInteger a, BigInteger b)
{
int bitLength = b.BitLength;
int num = Nat.GetLengthForBits(bitLength);
uint[] array = Nat.FromBigInteger(bitLength, a);
uint[] array2 = Nat.FromBigInteger(bitLength, b);
int num2 = 0;
while (true) {
if (array[0] == 0)
Nat.ShiftDownWord(num, array, 0);
else {
int num3 = Integers.NumberOfTrailingZeros((int)array[0]);
if (num3 > 0) {
Nat.ShiftDownBits(num, array, num3, 0);
int num4 = (int)array2[0];
num2 ^= ((num4 ^ (num4 >> 1)) & (num3 << 1));
}
int num5 = Nat.Compare(num, array, array2);
if (num5 == 0)
break;
if (num5 < 0) {
num2 ^= (int)(array[0] & array2[0]);
uint[] array3 = array;
array = array2;
array2 = array3;
}
while (array[num - 1] == 0) {
num--;
}
Nat.Sub(num, array, array2, array);
}
}
if (!Nat.IsOne(num, array2))
return 0;
return 1 - (num2 & 2);
}
}
}