DsaDigitalSignature
Implements DSA digital signature algorithm.
using Renci.SshNet.Common;
using System;
using System.Security.Cryptography;
namespace Renci.SshNet.Security.Cryptography
{
public class DsaDigitalSignature : DigitalSignature, IDisposable
{
private HashAlgorithm _hash;
private readonly DsaKey _key;
private bool _isDisposed;
public DsaDigitalSignature(DsaKey key)
{
if (key == null)
throw new ArgumentNullException("key");
_key = key;
_hash = HashAlgorithmFactory.CreateSHA1();
}
public override bool Verify(byte[] input, byte[] signature)
{
byte[] array = _hash.ComputeHash(input);
BigInteger left = new BigInteger(array.Reverse().Concat(new byte[1]));
if (signature.Length != 40)
throw new InvalidOperationException("Invalid signature.");
byte[] array2 = new byte[21];
byte[] array3 = new byte[21];
int num = 0;
int num2 = 20;
while (num < 20) {
array2[num] = signature[num2 - 1];
array3[num] = signature[num2 + 20 - 1];
num++;
num2--;
}
BigInteger bigInteger = new BigInteger(array2);
BigInteger bigInteger2 = new BigInteger(array3);
if (bigInteger <= 0 || bigInteger >= _key.Q)
return false;
if (bigInteger2 <= 0 || bigInteger2 >= _key.Q)
return false;
BigInteger right = BigInteger.ModInverse(bigInteger2, _key.Q);
BigInteger exponent = left * right % _key.Q;
BigInteger exponent2 = bigInteger * right % _key.Q;
exponent = BigInteger.ModPow(_key.G, exponent, _key.P);
exponent2 = BigInteger.ModPow(_key.Y, exponent2, _key.P);
return exponent * exponent2 % _key.P % _key.Q == bigInteger;
}
public override byte[] Sign(byte[] input)
{
byte[] array = _hash.ComputeHash(input);
BigInteger left = new BigInteger(array.Reverse().Concat(new byte[1]));
BigInteger right;
BigInteger bigInteger2;
do {
BigInteger bigInteger = BigInteger.Zero;
do {
int bitLength = _key.Q.BitLength;
if (_key.Q < BigInteger.Zero)
throw new SshException("Invalid DSA key.");
while (bigInteger <= 0 || bigInteger >= _key.Q) {
bigInteger = BigInteger.Random(bitLength);
}
right = BigInteger.ModPow(_key.G, bigInteger, _key.P) % _key.Q;
} while (right.IsZero);
bigInteger = BigInteger.ModInverse(bigInteger, _key.Q) * (left + _key.X * right);
bigInteger2 = bigInteger % _key.Q;
} while (bigInteger2.IsZero);
byte[] array2 = new byte[40];
byte[] array3 = right.ToByteArray().Reverse().TrimLeadingZeros();
Array.Copy(array3, 0, array2, 20 - array3.Length, array3.Length);
byte[] array4 = bigInteger2.ToByteArray().Reverse().TrimLeadingZeros();
Array.Copy(array4, 0, array2, 40 - array4.Length, array4.Length);
return array2;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed && disposing) {
HashAlgorithm hash = _hash;
if (hash != null) {
Renci.SshNet.Common.Extensions.Dispose(hash);
_hash = null;
}
_isDisposed = true;
}
}
~DsaDigitalSignature()
{
Dispose(false);
}
}
}