<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />

DsaSigner

public class DsaSigner : IDsa
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Signers { public class DsaSigner : IDsa { protected readonly IDsaKCalculator kCalculator; protected DsaKeyParameters key; protected SecureRandom random; 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) { ParametersWithRandom parametersWithRandom = parameters as ParametersWithRandom; if (parametersWithRandom != null) { provided = parametersWithRandom.Random; parameters = parametersWithRandom.Parameters; } DsaPrivateKeyParameters dsaPrivateKeyParameters = parameters as DsaPrivateKeyParameters; if (dsaPrivateKeyParameters == null) throw new InvalidKeyException("DSA private key required for signing"); key = dsaPrivateKeyParameters; } else { DsaPublicKeyParameters dsaPublicKeyParameters = parameters as DsaPublicKeyParameters; if (dsaPublicKeyParameters == null) throw new InvalidKeyException("DSA public key required for verification"); key = dsaPublicKeyParameters; } 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 = BigIntegers.ModOddInverse(q, bigInteger2).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 = BigIntegers.ModOddInverseVar(q, s); 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); return e.Multiply(e2).Mod(p).Mod(q) .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) return CryptoServicesRegistrar.GetSecureRandom(provided); return null; } } }