Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/Crypto/Signers/DsaSigner.cs
2025-10-09 09:57:24 +09:00

121 lines
3.1 KiB
C#

using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Signers;
public class DsaSigner : IDsaExt, IDsa
{
protected readonly IDsaKCalculator kCalculator;
protected DsaKeyParameters key = null;
protected SecureRandom random = null;
public virtual string AlgorithmName => "DSA";
public virtual BigInteger Order => key.Parameters.Q;
public DsaSigner()
{
kCalculator = new RandomDsaKCalculator();
}
public DsaSigner(IDsaKCalculator kCalculator)
{
this.kCalculator = kCalculator;
}
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
SecureRandom provided = null;
if (forSigning)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
provided = parametersWithRandom.Random;
parameters = parametersWithRandom.Parameters;
}
if (!(parameters is DsaPrivateKeyParameters))
{
throw new InvalidKeyException("DSA private key required for signing");
}
key = (DsaPrivateKeyParameters)parameters;
}
else
{
if (!(parameters is DsaPublicKeyParameters))
{
throw new InvalidKeyException("DSA public key required for verification");
}
key = (DsaPublicKeyParameters)parameters;
}
random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, provided);
}
public virtual BigInteger[] GenerateSignature(byte[] message)
{
DsaParameters parameters = key.Parameters;
BigInteger q = parameters.Q;
BigInteger bigInteger = CalculateE(q, message);
BigInteger x = ((DsaPrivateKeyParameters)key).X;
if (kCalculator.IsDeterministic)
{
kCalculator.Init(q, x, message);
}
else
{
kCalculator.Init(q, random);
}
BigInteger bigInteger2 = kCalculator.NextK();
BigInteger bigInteger3 = parameters.G.ModPow(bigInteger2, parameters.P).Mod(q);
bigInteger2 = bigInteger2.ModInverse(q).Multiply(bigInteger.Add(x.Multiply(bigInteger3)));
BigInteger bigInteger4 = bigInteger2.Mod(q);
return new BigInteger[2] { bigInteger3, bigInteger4 };
}
public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
{
DsaParameters parameters = key.Parameters;
BigInteger q = parameters.Q;
BigInteger bigInteger = CalculateE(q, message);
if (r.SignValue <= 0 || q.CompareTo(r) <= 0)
{
return false;
}
if (s.SignValue <= 0 || q.CompareTo(s) <= 0)
{
return false;
}
BigInteger val = s.ModInverse(q);
BigInteger e = bigInteger.Multiply(val).Mod(q);
BigInteger e2 = r.Multiply(val).Mod(q);
BigInteger p = parameters.P;
e = parameters.G.ModPow(e, p);
e2 = ((DsaPublicKeyParameters)key).Y.ModPow(e2, p);
BigInteger bigInteger2 = e.Multiply(e2).Mod(p).Mod(q);
return bigInteger2.Equals(r);
}
protected virtual BigInteger CalculateE(BigInteger n, byte[] message)
{
int length = System.Math.Min(message.Length, n.BitLength / 8);
return new BigInteger(1, message, 0, length);
}
protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided)
{
if (needed)
{
if (provided == null)
{
return new SecureRandom();
}
return provided;
}
return null;
}
}