<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

Gost3410DigestSigner

public class Gost3410DigestSigner : ISigner
using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Signers { public class Gost3410DigestSigner : ISigner { private readonly IDsa m_dsa; private readonly IDigest m_digest; private readonly int m_digestSize; private bool m_forSigning; public virtual string AlgorithmName => m_digest.AlgorithmName + "with" + m_dsa.AlgorithmName; public Gost3410DigestSigner(IDsa signer, IDigest digest) { if (signer == null) throw new ArgumentNullException("signer"); m_dsa = signer; if (digest == null) throw new ArgumentNullException("digest"); m_digest = digest; m_digestSize = digest.GetDigestSize(); } public virtual void Init(bool forSigning, ICipherParameters parameters) { m_forSigning = forSigning; AsymmetricKeyParameter asymmetricKeyParameter = (AsymmetricKeyParameter)ParameterUtilities.IgnoreRandom(parameters); if (forSigning && !asymmetricKeyParameter.IsPrivate) throw new InvalidKeyException("Signing requires private key."); if (!forSigning && asymmetricKeyParameter.IsPrivate) throw new InvalidKeyException("Verification requires public key."); Reset(); m_dsa.Init(forSigning, parameters); } public virtual void Update(byte input) { m_digest.Update(input); } public virtual void BlockUpdate(byte[] input, int inOff, int inLen) { m_digest.BlockUpdate(input, inOff, inLen); } public virtual void BlockUpdate(ReadOnlySpan<byte> input) { m_digest.BlockUpdate(input); } public virtual int GetMaxSignatureSize() { return m_digestSize * 2; } public virtual byte[] GenerateSignature() { if (m_forSigning) { byte[] message = DigestUtilities.DoFinal(m_digest); try { BigInteger[] array = m_dsa.GenerateSignature(message); int digestSize = m_digestSize; byte[] array2 = new byte[digestSize * 2]; BigIntegers.AsUnsignedByteArray(array[1], array2, 0, digestSize); BigIntegers.AsUnsignedByteArray(array[0], array2, digestSize, digestSize); return array2; } catch (Exception ex) { throw new SignatureException(ex.Message, ex); } } throw new InvalidOperationException("GOST3410DigestSigner not initialised for signature generation."); } public virtual bool VerifySignature(byte[] signature) { if (m_forSigning) throw new InvalidOperationException("GOST3410DigestSigner not initialised for verification"); byte[] message = DigestUtilities.DoFinal(m_digest); BigInteger r; BigInteger s; try { int digestSize = m_digestSize; r = new BigInteger(1, signature, digestSize, digestSize); s = new BigInteger(1, signature, 0, digestSize); } catch (Exception innerException) { throw new SignatureException("error decoding signature bytes.", innerException); } return m_dsa.VerifySignature(message, r, s); } public virtual void Reset() { m_digest.Reset(); } } }